Difference between revisions of "Org.simantics.browsing.ui"

From Developer Documents
Jump to navigation Jump to search
m
m
Line 25: Line 25:
  
 
== Basic Usage ==
 
== Basic Usage ==
 
'''TODO:''' explain better
 
 
 
# Use <code>org.simantics.browsing.ui.GraphExplorerFactory</code> to construct new instances of the SWT-based GraphExplorer control.
 
# Use <code>org.simantics.browsing.ui.GraphExplorerFactory</code> to construct new instances of the SWT-based GraphExplorer control.
 
# Setup layouts for the GraphExplorer control as you normally would in SWT
 
# Setup layouts for the GraphExplorer control as you normally would in SWT
Line 36: Line 33:
  
 
=== Query System ===
 
=== Query System ===
 
 
The explorer content production process is based solely on ''queries''. Abstractly speaking, a query is just a request for an answer to a question.
 
The explorer content production process is based solely on ''queries''. Abstractly speaking, a query is just a request for an answer to a question.
 
Each potentially visible element in a GraphExplorer will have its own ''node context'' (see [[svn:foundation/browsing/trunk/org.simantics.browsing.ui/src/org/simantics/browsing/ui/NodeContext.java|NodeContext]]). Queries are always performed on a single node context.
 
Each potentially visible element in a GraphExplorer will have its own ''node context'' (see [[svn:foundation/browsing/trunk/org.simantics.browsing.ui/src/org/simantics/browsing/ui/NodeContext.java|NodeContext]]). Queries are always performed on a single node context.

Revision as of 10:11, 29 September 2010

There exists a more tutorial like manual.

Concepts

Query Key
An object that identifies the query to be performed. Query keys are capable of identifying the query processor to be used for actually performing the query. See the base class for all keys:
    /**
     * Do not implement this directly, look at {@link PrimitiveQueryKey} and
     * {@link QueryKey} instead.
     */
    public static interface CacheKey<T> {
        /**
         * This method must return a unique object that is used to decide which
         * QueryProcessor is used to calculate the query result.
         * 
         * The returned value is compared only using object identity (==), not
         * equals.
         * 
         * @return the identifier of this processor
         */
        Object processorIdenfitier();
    }

Basic Usage

  1. Use org.simantics.browsing.ui.GraphExplorerFactory to construct new instances of the SWT-based GraphExplorer control.
  2. Setup layouts for the GraphExplorer control as you normally would in SWT
  3. Initialize data sources (DataSourceProvider) for the graph explorer (GraphExplorer.setDataSource(DataSourceProvider))
    • For example, the graph database is one possible data source.
  4. Initialize suitable query processors for your purposes (GraphExplorer.setProcessor(NodeQueryProcessor), GraphExplorer.setPrimitiveProcessor(PrimitiveQueryProcessor))
  5. Set root input (GraphExplorer.setRoot(Object))

Query System

The explorer content production process is based solely on queries. Abstractly speaking, a query is just a request for an answer to a question. Each potentially visible element in a GraphExplorer will have its own node context (see NodeContext). Queries are always performed on a single node context.

Producing content for the visualized graph is generally a matter of doing the following things:

  1. Finding the children of an element that can be shown
  2. Possibly filtering the children
  3. Possibly sorting the children
  4. Producing labels and images for visible elements

All of these steps are done through different named queries. All queries are identified by query keys. Keys can be either singleton instances or parametrized classes. For example the query BuiltinKeys.SELECTED_VIEWPOINT is used to find out the selected viewpoint for an input context that is used to produce the child node contexts of the specified input context. Queries are performed using this interface:

<source lang="java"> public interface NodeQueryManager {

   <T> T query(INodeContext context, QueryKey<T> key) throws NoQueryProcessorException;
   <T> T query(INodeContext context, PrimitiveQueryKey<T> key) throws NoQueryProcessorException;

} </source>

The most important things to know about the query system are:

  1. The query system automatically generates and keeps track of dependencies between queries.
  2. Query results can be updated by the result producer. Updates potentially causes the results of all dependent queries to be updated too. The query manager will propagate these changes automatically and update the UI where necessary.
  3. The whole query system runs in the single UI control thread (SWT thread). Therefore by implementing potentially blocking queries you will also potentially block the UI. This does not differ in any way from standard SWT/JFace.
  4. Contrary to the basic JFace framework, the query system provides support for implementing non-blocking primitive queries by making their completion asynchronous. The goal is to perform the real work in background threads. Asynchronously completing queries will always return a placeholder result immediately and update the query result later once the background thread complete their work. The query system will ensure for you that any queries depending on the particular primitive query result will also be updated.

Internally a GraphExplorer implementation shall also bind certain top-level queries to actual UI elements. If such queries with bound UI elements are updated, the UI elements shall be updated also. For example in the case of a tree this implies updating the label or image of the tree node.

Visualization of Basic Query hierarchy

Visual query order representation

Selection handling

A GraphExplorer is an IPostSelectionProvider. Adapt a GraphExplorer into ISelectionProvider or IPostSelectionProvider through GraphExplorer.getAdapter(ISelectionProvider.class).

The selections produced by it will always contain NodeContext instances. These are produced by Viewpoints. The basic implementations of NodeContext are constructed by NodeContextBuilder. A NodeContext must always contain an object value for the BuiltinKeys.INPUT key (see NodeContext.getConstant(ConstantKey<T>)). Note that NodeContext extends IAdaptable which takes all possible measures to adapt the INPUT value into the desired object class.

Resource selection example

<source lang="Java"> ISelectionProvider provider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class); if (provider != null) {

   ISelection selection = provider.getSelection();
   Resource object = ISelectionUtils.getSinglePossibleKey(selection, SelectionHints.KEY_MAIN, Resource.class);

} </source>

See also