Difference between revisions of "Selection View"

From Developer Documents
Jump to navigation Jump to search
 
(57 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
The Selection View is a standard Simantics view, which shows tabbed configuration views about the current workbench selection.
 
The Selection View is a standard Simantics view, which shows tabbed configuration views about the current workbench selection.
  
== Basic implementation ==
+
== Quick Summary ==
  
Selection view displays content for the workbench selection, which is produced by the active workbench part. The main implementation of the Selection View is also contributed by the active workbench part.
+
* To use the standard selection view facilities you need to make your WorkbenchPart adaptable to [[#Standard property page|StandardPropertyPage]].
 +
* [[#Standard property page|StandardPropertyPage]] will create [[#Standard property page|StandardProperties]] as the property page control and use [[#Modelled Selection Processor|StandardSelectionProcessor]] to process all incoming selections.
 +
* Model your desired tab contributions in your ontologies ([[#Modelled Selection Processor]])
 +
* Make sure that Dependencies-relation indexing scans the ontologies containing your tab contributions (see [[Project_Development#Optional_Step:_Using_ready-made_project_features|project features]])
  
The implementation class is org.simantics.ui.workbench.IPropertyPage.
+
=== Example 1: standard parameter property table ===
  
The standard implementation is org.simantics.selectionview.StandardPropertyPage (needs refactoring).
+
This example describes the simplest possible way to utilize a standard 3-column table (property, value, unit) for viewing and editing properties of a selected model entity. This contribution works with selection containing EX.Model type Resources.
 +
 
 +
* Define your own tab contribution (''EX.ModelTabContribution'') and use the standard modelled property table as the UI (''SEL_UI.StandardProperties'').
 +
* Make sure EX.Model has properties that are instantiated from ''SEL.GenericParameterType''. If a label is defined for the property, it is used in the UI instead of the name.
 +
 
 +
<pre>
 +
// Import namespaces
 +
EX = <http://www.simantics.org/Example-1.0>
 +
    @L0.new
 +
SIMU = <http://www.simantics.org/Simulation-1.0>
 +
SEL = <http://www.simantics.org/SelectionView-1.1>
 +
SEL_UI = <http://www.simantics.org/SelectionViewUI-1.0>
 +
 
 +
// Define type EX.Model with a single parameter
 +
EX.Model <T SIMU.Model
 +
    >-- EX.Model.parameter --> L0.String <R L0.HasProperty : SEL.GenericParameterType
 +
        L0.HasLabel "Parameter"
 +
 
 +
// Define selection view tab contribution for EX.Model selections
 +
EX.ModelTabContribution : SEL.TypedVariableTabContribution
 +
    SEL.TypedVariableTabContribution.HasType EX.Model
 +
    SEL.VariableTabContribution.HasView SEL_UI.StandardProperties
 +
    // Use priorities to order tab contributions
 +
    SEL.VariableTabContribution.HasPriority 1
 +
    L0.HasLabel "Properties"
 +
</pre>
 +
 
 +
* Make sure that the following namespaces are in your model's indexing search path:
 +
** http://www.simantics.org/SelectionView-1.1
 +
** http://www.simantics.org/Example-1.0
 +
This allows the indexing system to find the standard Simantics selection view contributions and your own contributions. To achieve this you must make sure that your model contains unidirectional '''L0.IsLinkedTo''' statements to the resource appointed by these URI.
 +
 
 +
TODO: need better instructions for indexing setup to provide a point of reference for these cases
 +
 
 +
== Selection View ==
 +
 
 +
The Selection View is contributed in '''org.simantics.browsing.ui.platform/plugin.xml'''. The selection view implementation is in class <code>org.simantics.browsing.ui.platform.PropertyPageView</code>.
 +
 
 +
Selection View displays content for the '''active workbench selection'''.
 +
 
 +
Selection View listens to the '''active workbench part''' and tries to obtain '''org.simantics.ui.workbench.IPropertyPage''' via '''IAdaptable.getAdapter''' for displaying selections from the part.
 +
 
 +
Most Simantics workbench part implementations adapt into the standard property page implementation described next.
 +
 
 +
== Standard property page ==
 +
 
 +
The ''standard property page'' ([[svn:foundation/browsing/trunk/org.simantics.selectionview/src/org/simantics/selectionview/StandardPropertyPage.java|StandardPropertyPage]]) displays a tab folder ([[svn:foundation/browsing/trunk/org.simantics.selectionview/src/org/simantics/selectionview/StandardProperties.java|StandardProperties]]), which contains a number of tabs contributed by a set of ''selection processors'' ([[svn:foundation/browsing/trunk/org.simantics.selectionview/src/org/simantics/selectionview/SelectionProcessor.java|SelectionProcessor]]).
  
 
== Selection processing ==
 
== Selection processing ==
  
StandardPropertyPage uses org.simantics.browsing.ui.SelectionProcessor for computing an ordered set of tabs from the given workbench selection. The tabs are implementations of org.simantics.browsing.ui.swt.ComparableTabContributor.
+
<pre>
 +
/**
 +
* A selection processor is an interface for encapsulating the conversion from a
 +
* UI selection into a collection of input objects. Minimally a selection
 +
* processor must simply transfer the incoming selection's contents into a
 +
* collection. The point of having this interface is to allow contribution-based
 +
* preprocessing of UI selections into proper domain-specific model objects that
 +
* the domain-specific UI components can take as their inputs.
 +
*
 +
* <p>
 +
* This interface is used in conjunction with UI components that are meant to
 +
* react to external inputs/UI selections. A tabbed selection view is an example
 +
* of such a UI component. One or more tabs are created for each preprocessed
 +
* input object. A selection processor in a tabbed property table is the party
 +
* that decides how to process/adapt a new workbench selection before sending it
 +
* on to property contributors for resolving all potential property tab
 +
* contributors.
 +
*
 +
* @author Tuukka Lehtonen
 +
*
 +
* @param <S>
 +
* @param <B>
 +
*/
 +
public interface SelectionProcessor<S, B> {
 +
 
 +
    /**
 +
    * @param selection the incoming selection to process
 +
    * @param backend for providing back-end access to the processor
 +
    * @return an ordered set of
 +
    *        <code>org.simantics.browsing.ui.swt.ComparableTabContributor</code>
 +
    *        instances representing the property tabs to be contributed to the
 +
    *        selection view. The processor must not return <code>null</code>,
 +
    *        return an empty collection instead.
 +
    */
 +
    Collection<?> process(S selection, B backend);
 +
 
 +
}
 +
</pre>
 +
 
 +
* ''Selection'' is the '''workbench selection'''.
 +
* ''Backend'' is normally ReadGraph (could be something else if custom property pages are used).
 +
* Selection processors are contributed by:
 +
*# Extending <code>StandardPropertyPage</code> and overriding method <code>getSelectionProcessor</code>
 +
*# Constructing <code>StandardPropertyPage</code> with a set of '''browse contexts''' for which selection processors can be contributed via extension point '''org.simantics.browsing.ui.common.selectionProcessorBinding'''
 +
* The obtained set of <code>ComparableTabContributors</code> are sorted and used to create tabs for the tabbed folder.
 +
 
 +
 
 +
A modelled implementation of the ''SelectionProcessor'' interface is described next.
 +
 
 +
=== Modelled Selection Processor ===
 +
 
 +
The implementation of modelled selection processor ([[svn:foundation/browsing/trunk/org.simantics.selectionview/src/org/simantics/selectionview/StandardSelectionProcessor.java|StandardSelectionProcessor]]) performs the following procedure:
 +
 
 +
<ol>
 +
<li>Try to get a model resource from the '''workbench selection'''.</li>
 +
<pre>
 +
private Resource getModel(ReadGraph graph, Object selection) throws DatabaseException {
 +
    Variable variable = ISelectionUtils.filterSingleSelection(selection, Variable.class);
 +
    if (variable != null)
 +
        return Variables.getModel(graph, variable);
 +
 
 +
    Resource model = ISelectionUtils.getSinglePossibleKey(selection,
 +
            SelectionHints.KEY_MODEL, Resource.class);
 +
    if (model == null) {
 +
        Resource r = ISelectionUtils.getSinglePossibleKey(selection,
 +
                SelectionHints.KEY_MAIN, Resource.class);
 +
        if (r != null)
 +
            model = graph.sync(new PossibleModel(r));
 +
    }
 +
    return model != null
 +
            && graph.isInstanceOf(model, SimulationResource.getInstance(graph).Model)
 +
            ? model
 +
            : null;
 +
}
 +
</pre>
 +
<li>Seek all instances of http://www.simantics.org/SelectionView-0.0/TabContribution from model dependencies and adapt (ReadGraph.adapt) them to org.simantics.selectionview.TabContribution.</li>
 +
<pre>
 +
SEL.VariableTabContribution <T SEL.TabContribution
 +
  >-- SEL.VariableTabContribution.HasTest <R L0.DependsOn
 +
  >-- SEL.VariableTabContribution.HasView <R L0.DependsOn
 +
  >-- SEL.VariableTabContribution.HasPriority <R L0.DependsOn
  
A modelled implementation of the SelectionProcessor interface is org.simantics.views.swt.StandardSelectionProcessor.
+
SEL.TypedVariableTabContribution <T SEL.VariableTabContribution
 +
  >-- SEL.TypedVariableTabContribution.HasType <R L0.DependsOn
 +
</pre>
 +
<pre>
 +
public interface TabContribution<T> {
 +
    void contribute(ReadGraph graph, T selection, Collection<ComparableTabContributor> result)
 +
            throws DatabaseException;
 +
}
 +
</pre>
  
StandardSelectionProcessor seeks all instances of http://www.simantics.org/Views-1.0/TabContribution and adapts them to org.simantics.views.swt.TabContribution.
+
(SEL.VariableTabContribution.HasView refers to a Modelled View configuration for describing the contents of the tab.)
  
StandardSelectionProcessor seeks all instances of http://www.simantics.org/Views-1.0/SelectionTransformation (which are also L0X.Function) and applies them to obtain a set of inputs, which is then feed to all TabContributions.
+
<li>Seek all instances of http://www.simantics.org/SelectionView-0.0/SelectionTransformation (which are also L0.Function) and apply them (org.simantics.db.common.utils.Functions#exec) as long as needed to obtain a closure of inputs, i.e. as long as new inputs are generated from existing ones.</li>
 +
 
 +
<li>Feed all inputs to the found TabContributions to obtain a set of tabs.</li>
 +
</ol>
  
 
== Tab implementation ==
 
== Tab implementation ==
  
The standard way of implementing a tab is a Simantics Modelled View. Generic modelled selection view tabs include
+
The standard way of implementing a tab is a [[Org.simantics.views|Simantics Modelled View]].
 +
 
 +
Generic configurations for modelled tabs can be found in the ontology http://www.simantics.org/SelectionViewUI-1.0.
 +
 
 +
The standard modelled property tab is http://www.simantics.org/SelectionViewUI-1.0/StandardProperties
 +
 
 +
<pre style="white-space: pre-wrap">
 +
SEL.StandardPropertiesBase <T VIEW.Explorer
 +
  @L0.assert VIEW.Control.layoutData
 +
    _ : VIEW.GridLayout.GridData
 +
      VIEW.GridLayout.GridData.horizontalGrab true
 +
      VIEW.GridLayout.GridData.verticalGrab true
 +
  @L0.assert VIEW.Control.style
 +
    _ : VIEW.Control.Style
 +
      VIEW.Control.Style.HasConstant VIEW.Control.Style.Constant.Multi
 +
      VIEW.Control.Style.HasConstant VIEW.Control.Style.Constant.FullSelection
 +
  @L0.assert VIEW.Explorer.columns
 +
    _ : VIEW.Explorer.ColumnList
 +
      @L0.list
 +
        SEL.PropertyColumn
 +
        SEL.ValueColumn
 +
        SEL.UnitColumn
 +
  @L0.assert VIEW.Explorer.input MOD.Functions.singleVariableSelection
 +
  @L0.assert VIEW.Explorer.browseContext
 +
    _ : VIEW.ResourceURI
 +
      VIEW.ResourceURI.HasResource
 +
        SEL.StandardPropertiesBase.BrowseContext : SEL.StandardProperties.BrowseContextStandardChildren
 +
 
 +
SEL.StandardProperties : SEL.StandardPropertiesBase
 +
</pre>
 +
 
 +
where input is obtained from modelled view runtime state
 +
 
 +
<pre>
 +
    @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")
 +
    public static Variable singleVariableSelection(ReadGraph graph, Resource resource, Variable context)
 +
            throws DatabaseException {
 +
    return ScenegraphLoaderUtils.getVariableSelection(graph, context);
 +
    }
 +
</pre>
 +
 
 +
and browsing rules are defined by
 +
 
 +
<pre>
 +
 
 +
SEL.StandardProperties.BrowseContextStandardChildren <T SEL.StandardProperties.BrowseContextWithoutChildren
 +
  @L0.assert VP.BrowseContext.HasChildContribution
 +
    _ : VP.ChildContribution
 +
      VP.ChildContribution.HasParentNodeType MOD.ModelingBrowseContext.Variable
 +
      VP.ChildContribution.HasChildNodeType MOD.ModelingBrowseContext.Variable
 +
      VP.ChildContribution.HasRule _ : MOD.ModelingBrowseContext.VariablePropertyRule
 +
        MOD.ModelingBrowseContext.VariablePropertyRule.RequireProperty "HasStandardPropertyInfo"
 +
  @L0.assert VP.BrowseContext.HasChildContribution
 +
    _ : VP.ChildContribution
 +
      VP.ChildContribution.HasParentNodeType MOD.ModelingBrowseContext.Variable
 +
      VP.ChildContribution.HasChildNodeType SEL.CategoryNode
 +
      VP.ChildContribution.HasRule _ : SEL.VariablePropertyCategoryRule
 +
 
 +
SEL.StandardProperties.BrowseContextWithoutChildren <T VP.BrowseContext
 +
  @L0.assert VP.BrowseContext.HasVisualsContribution
 +
    _ : VP.VisualsContribution
 +
      VP.VisualsContribution.HasNodeType MOD.ModelingBrowseContext.Variable
 +
      VP.VisualsContribution.HasRule SEL.VariablePropertyLabelRule
 +
  @L0.assert VP.BrowseContext.HasVisualsContribution
 +
    _ : VP.VisualsContribution
 +
      VP.VisualsContribution.HasNodeType SEL.CategoryNode
 +
      VP.VisualsContribution.HasRule SEL.CategoryNodeLabelRule
 +
  @L0.assert VP.BrowseContext.HasVisualsContribution
 +
    _ : VP.VisualsContribution
 +
      VP.VisualsContribution.HasNodeType MOD.ModelingBrowseContext.Variable
 +
      VP.VisualsContribution.HasRule SEL.StandardPropertySorterRule
 +
  @L0.assert VP.BrowseContext.HasVisualsContribution
 +
    _ : VP.VisualsContribution
 +
      VP.VisualsContribution.HasNodeType MOD.ModelingBrowseContext.Variable
 +
      VP.VisualsContribution.HasRule SEL.VariablePropertyModifierRule
 +
  @L0.assert VP.BrowseContext.HasVisualsContribution
 +
    _ : VP.VisualsContribution
 +
      VP.VisualsContribution.HasNodeType MOD.ModelingBrowseContext.Variable
 +
      VP.VisualsContribution.HasRule SEL.VariableDecorationRule
 +
  @L0.assert VP.BrowseContext.HasVisualsContribution
 +
    _ : VP.VisualsContribution
 +
      VP.VisualsContribution.HasNodeType SEL.CategoryNode
 +
      VP.VisualsContribution.HasRule SEL.CategoryDecorationRule
 +
 
 +
</pre>
 +
 
 +
The rules of the standard browse context are as follows:
 +
 
 +
* '''MOD.ModelingBrowseContext.VariablePropertyRule''' returns all properties (Variable.browseProperties) such that
 +
** All results contain all properties defined by VariablePropertyRule.RequireProperty
 +
* '''SEL.VariablePropertyCategoryRule''' returns a set of categories collected from all suitable properties (as above)
 +
** categories are identified by
 +
*** var#HasStandardPropertyInfo#CategoryName
 +
*** var#HasStandardPropertyInfo#CategorySortingName
 +
** hidden categories are not shown
 +
*** see var#HasStandardPropertyInfo#IsHidden
 +
* '''SEL.VariablePropertyLabelRule''' collects a String->String map by searching properties var where
 +
** key is the value of (var#HasDisplayColumn)
 +
** value is the (Bindings.STRING) value of var
 +
* '''SEL.CategoryNodeLabelRule''' returns the map "HasDisplayProperty" -> ((CategoryNode)content).getName()
 +
* '''SEL.StandardPropertySorterRule''' sorts properties and categories by sorting name where sorting name is
 +
** (p#SortingName) or if absent (p#HasDisplayProperty) for a variable p
 +
** ((CategoryNode)content).getSortingName() for categories
 +
* '''SEL.VariablePropertyModifierRule''' returns org.simantics.browsing.ui.content.Labeler.Modifier by
 +
** finding the column property (by var#HasDisplayColumn)
 +
** trying to obtain a custom modifier (var#HasCustomModifier)
 +
** trying to obtain an enumeration modifier by listing (var#HasEnumerationValues) and returning '''org.simantics.browsing.ui.graph.impl.EnumerationVariableModifier3'''
 +
** returning '''org.simantics.browsing.ui.model.modifiers.VariableModifier2'''
 +
* '''SEL.VariableDecorationRule''' offsets the property name column of properties by one
 +
* '''SEL.CategoryDecorationRule''' displays categories as bold
 +
 
 +
The standard implementation can be customised by e.g.
 +
 
 +
* Introducing more columns
 +
* Applying property filtering (RequiresProperty)
 +
* Adding decorations
 +
 
 +
Some other notable points
 +
 
 +
* Modifier uses the property 'HasInputValidator' for getting a validator
 +
* Modifier writes with Bindings.STRING into the label property.
 +
* The labels may apply transformations such as unit conversion or formatting i.e. they can not be used for obtaining raw property data.
 +
 
 +
== Selection View Title ==
 +
 
 +
By default the selection view title is set to '''Selection'''. However it is possible for tab contributions to customize the title text. On the low-level customization happens through the '''org.simantics.selectionview.IPropertyTab2''' interface which tab contributions can implement.
 +
<pre>
 +
public interface IPropertyTab2 extends IPropertyTab {
 +
 
 +
    /**
 +
    * @param updateCallback a callback that <em>can be</em> invoked by
 +
    *        getPartName if it wishes to change the part name. If the page does
 +
    *        not wish to change the part name, it does not have to invoke the
 +
    *        updateCallback. A <code>null</code> value indicates that the part
 +
    *        name should be returned to its default value. The method should
 +
    *        use the selection received by
 +
    *        {@link #setInput(org.simantics.db.management.ISessionContext, ISelection, boolean)}
 +
    *        as input for constructing the part title.
 +
    */
 +
    void updatePartName(Callback<String> updateCallback);
 +
 
 +
}
 +
</pre>
 +
 
 +
Contributing custom title logic is not yet possible through modelling, only by implementing your own custom '''org.simantics.selectionview.PropertyTabContributor''', e.g. by customizing '''org.simantics.selectionview.ModelledTabContributor''' or '''org.simantics.selectionview.PropertyTabContributorImpl'''.
 +
 
 +
== Future developments ==
 +
 
 +
Some generic Variable properties should be used in rules. These properties include
 +
 
 +
* #classifications
 +
* #valid
 +
* #validator
 +
* #expression
 +
* #required
 +
* #default
 +
* #readOnly
  
=== StandardProperties (http://www.simantics.org/Modeling-1.0/StandardProperties) ===
+
The Variable model includes a generic model for connections, which should also be supported in the standard properties
  
* StandardProperties is an Explorer view which expects a single Variable as input.
+
Selection view title logic modelling shall be added.
* The view has the columns 'Property', 'Value' and 'Unit'
 
* Children are obtained using variable.browseProperties such that the property contains a property named 'StandardProperty'
 
* Labels are obtained using the properties 'PredicateLabel', 'HasLabel', 'DisplayUnit'
 
* Modifier uses 'HasInputValidator' for getting the validator
 
* Modifier writes into property 'HasLabel'
 
* Categories?
 
* Required, Default?
 

Latest revision as of 06:17, 16 April 2021

The Selection View is a standard Simantics view, which shows tabbed configuration views about the current workbench selection.

Quick Summary

Example 1: standard parameter property table

This example describes the simplest possible way to utilize a standard 3-column table (property, value, unit) for viewing and editing properties of a selected model entity. This contribution works with selection containing EX.Model type Resources.

  • Define your own tab contribution (EX.ModelTabContribution) and use the standard modelled property table as the UI (SEL_UI.StandardProperties).
  • Make sure EX.Model has properties that are instantiated from SEL.GenericParameterType. If a label is defined for the property, it is used in the UI instead of the name.
// Import namespaces
EX = <http://www.simantics.org/Example-1.0>
    @L0.new
SIMU = <http://www.simantics.org/Simulation-1.0>
SEL = <http://www.simantics.org/SelectionView-1.1>
SEL_UI = <http://www.simantics.org/SelectionViewUI-1.0>

// Define type EX.Model with a single parameter
EX.Model <T SIMU.Model
    >-- EX.Model.parameter --> L0.String <R L0.HasProperty : SEL.GenericParameterType
        L0.HasLabel "Parameter"

// Define selection view tab contribution for EX.Model selections
EX.ModelTabContribution : SEL.TypedVariableTabContribution
    SEL.TypedVariableTabContribution.HasType EX.Model
    SEL.VariableTabContribution.HasView SEL_UI.StandardProperties
    // Use priorities to order tab contributions
    SEL.VariableTabContribution.HasPriority 1
    L0.HasLabel "Properties"

This allows the indexing system to find the standard Simantics selection view contributions and your own contributions. To achieve this you must make sure that your model contains unidirectional L0.IsLinkedTo statements to the resource appointed by these URI.

TODO: need better instructions for indexing setup to provide a point of reference for these cases

Selection View

The Selection View is contributed in org.simantics.browsing.ui.platform/plugin.xml. The selection view implementation is in class org.simantics.browsing.ui.platform.PropertyPageView.

Selection View displays content for the active workbench selection.

Selection View listens to the active workbench part and tries to obtain org.simantics.ui.workbench.IPropertyPage via IAdaptable.getAdapter for displaying selections from the part.

Most Simantics workbench part implementations adapt into the standard property page implementation described next.

Standard property page

The standard property page (StandardPropertyPage) displays a tab folder (StandardProperties), which contains a number of tabs contributed by a set of selection processors (SelectionProcessor).

Selection processing

/**
 * A selection processor is an interface for encapsulating the conversion from a
 * UI selection into a collection of input objects. Minimally a selection
 * processor must simply transfer the incoming selection's contents into a
 * collection. The point of having this interface is to allow contribution-based
 * preprocessing of UI selections into proper domain-specific model objects that
 * the domain-specific UI components can take as their inputs.
 * 
 * <p>
 * This interface is used in conjunction with UI components that are meant to
 * react to external inputs/UI selections. A tabbed selection view is an example
 * of such a UI component. One or more tabs are created for each preprocessed
 * input object. A selection processor in a tabbed property table is the party
 * that decides how to process/adapt a new workbench selection before sending it
 * on to property contributors for resolving all potential property tab
 * contributors.
 * 
 * @author Tuukka Lehtonen
 * 
 * @param <S>
 * @param <B>
 */
public interface SelectionProcessor<S, B> {

    /**
     * @param selection the incoming selection to process
     * @param backend for providing back-end access to the processor
     * @return an ordered set of
     *         <code>org.simantics.browsing.ui.swt.ComparableTabContributor</code>
     *         instances representing the property tabs to be contributed to the
     *         selection view. The processor must not return <code>null</code>,
     *         return an empty collection instead.
     */
    Collection<?> process(S selection, B backend);

}
  • Selection is the workbench selection.
  • Backend is normally ReadGraph (could be something else if custom property pages are used).
  • Selection processors are contributed by:
    1. Extending StandardPropertyPage and overriding method getSelectionProcessor
    2. Constructing StandardPropertyPage with a set of browse contexts for which selection processors can be contributed via extension point org.simantics.browsing.ui.common.selectionProcessorBinding
  • The obtained set of ComparableTabContributors are sorted and used to create tabs for the tabbed folder.


A modelled implementation of the SelectionProcessor interface is described next.

Modelled Selection Processor

The implementation of modelled selection processor (StandardSelectionProcessor) performs the following procedure:

  1. Try to get a model resource from the workbench selection.
  2. private Resource getModel(ReadGraph graph, Object selection) throws DatabaseException {
        Variable variable = ISelectionUtils.filterSingleSelection(selection, Variable.class);
        if (variable != null)
            return Variables.getModel(graph, variable);
    
        Resource model = ISelectionUtils.getSinglePossibleKey(selection,
                SelectionHints.KEY_MODEL, Resource.class);
        if (model == null) {
            Resource r = ISelectionUtils.getSinglePossibleKey(selection,
                    SelectionHints.KEY_MAIN, Resource.class);
            if (r != null)
                model = graph.sync(new PossibleModel(r));
        }
        return model != null
                && graph.isInstanceOf(model, SimulationResource.getInstance(graph).Model)
                ? model
                : null;
    }
    
  3. Seek all instances of http://www.simantics.org/SelectionView-0.0/TabContribution from model dependencies and adapt (ReadGraph.adapt) them to org.simantics.selectionview.TabContribution.
  4. SEL.VariableTabContribution <T SEL.TabContribution
      >-- SEL.VariableTabContribution.HasTest <R L0.DependsOn
      >-- SEL.VariableTabContribution.HasView <R L0.DependsOn
      >-- SEL.VariableTabContribution.HasPriority <R L0.DependsOn
    
    SEL.TypedVariableTabContribution <T SEL.VariableTabContribution
      >-- SEL.TypedVariableTabContribution.HasType <R L0.DependsOn
    
    public interface TabContribution<T> {
        void contribute(ReadGraph graph, T selection, Collection<ComparableTabContributor> result)
                throws DatabaseException;	
    }
    

    (SEL.VariableTabContribution.HasView refers to a Modelled View configuration for describing the contents of the tab.)

  5. Seek all instances of http://www.simantics.org/SelectionView-0.0/SelectionTransformation (which are also L0.Function) and apply them (org.simantics.db.common.utils.Functions#exec) as long as needed to obtain a closure of inputs, i.e. as long as new inputs are generated from existing ones.
  6. Feed all inputs to the found TabContributions to obtain a set of tabs.

Tab implementation

The standard way of implementing a tab is a Simantics Modelled View.

Generic configurations for modelled tabs can be found in the ontology http://www.simantics.org/SelectionViewUI-1.0.

The standard modelled property tab is http://www.simantics.org/SelectionViewUI-1.0/StandardProperties

SEL.StandardPropertiesBase <T VIEW.Explorer
  @L0.assert VIEW.Control.layoutData
    _ : VIEW.GridLayout.GridData
      VIEW.GridLayout.GridData.horizontalGrab true
      VIEW.GridLayout.GridData.verticalGrab true
  @L0.assert VIEW.Control.style 
    _ : VIEW.Control.Style
      VIEW.Control.Style.HasConstant VIEW.Control.Style.Constant.Multi
      VIEW.Control.Style.HasConstant VIEW.Control.Style.Constant.FullSelection
  @L0.assert VIEW.Explorer.columns 
    _ : VIEW.Explorer.ColumnList
      @L0.list
        SEL.PropertyColumn
        SEL.ValueColumn
        SEL.UnitColumn
  @L0.assert VIEW.Explorer.input MOD.Functions.singleVariableSelection
  @L0.assert VIEW.Explorer.browseContext
    _ : VIEW.ResourceURI
      VIEW.ResourceURI.HasResource
        SEL.StandardPropertiesBase.BrowseContext : SEL.StandardProperties.BrowseContextStandardChildren

SEL.StandardProperties : SEL.StandardPropertiesBase

where input is obtained from modelled view runtime state

    @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")
    public static Variable singleVariableSelection(ReadGraph graph, Resource resource, Variable context)
            throws DatabaseException {
    	return ScenegraphLoaderUtils.getVariableSelection(graph, context);
    }

and browsing rules are defined by


SEL.StandardProperties.BrowseContextStandardChildren <T SEL.StandardProperties.BrowseContextWithoutChildren
  @L0.assert VP.BrowseContext.HasChildContribution 
    _ : VP.ChildContribution
      VP.ChildContribution.HasParentNodeType MOD.ModelingBrowseContext.Variable
      VP.ChildContribution.HasChildNodeType MOD.ModelingBrowseContext.Variable
      VP.ChildContribution.HasRule _ : MOD.ModelingBrowseContext.VariablePropertyRule
        MOD.ModelingBrowseContext.VariablePropertyRule.RequireProperty "HasStandardPropertyInfo"
  @L0.assert VP.BrowseContext.HasChildContribution 
    _ : VP.ChildContribution
      VP.ChildContribution.HasParentNodeType MOD.ModelingBrowseContext.Variable
      VP.ChildContribution.HasChildNodeType SEL.CategoryNode
      VP.ChildContribution.HasRule _ : SEL.VariablePropertyCategoryRule

SEL.StandardProperties.BrowseContextWithoutChildren <T VP.BrowseContext
  @L0.assert VP.BrowseContext.HasVisualsContribution
    _ : VP.VisualsContribution
      VP.VisualsContribution.HasNodeType MOD.ModelingBrowseContext.Variable
      VP.VisualsContribution.HasRule SEL.VariablePropertyLabelRule
  @L0.assert VP.BrowseContext.HasVisualsContribution
    _ : VP.VisualsContribution
      VP.VisualsContribution.HasNodeType SEL.CategoryNode
      VP.VisualsContribution.HasRule SEL.CategoryNodeLabelRule
  @L0.assert VP.BrowseContext.HasVisualsContribution
    _ : VP.VisualsContribution
      VP.VisualsContribution.HasNodeType MOD.ModelingBrowseContext.Variable
      VP.VisualsContribution.HasRule SEL.StandardPropertySorterRule
  @L0.assert VP.BrowseContext.HasVisualsContribution
    _ : VP.VisualsContribution
      VP.VisualsContribution.HasNodeType MOD.ModelingBrowseContext.Variable
      VP.VisualsContribution.HasRule SEL.VariablePropertyModifierRule
  @L0.assert VP.BrowseContext.HasVisualsContribution
    _ : VP.VisualsContribution
      VP.VisualsContribution.HasNodeType MOD.ModelingBrowseContext.Variable
      VP.VisualsContribution.HasRule SEL.VariableDecorationRule
  @L0.assert VP.BrowseContext.HasVisualsContribution
    _ : VP.VisualsContribution
      VP.VisualsContribution.HasNodeType SEL.CategoryNode
      VP.VisualsContribution.HasRule SEL.CategoryDecorationRule

The rules of the standard browse context are as follows:

  • MOD.ModelingBrowseContext.VariablePropertyRule returns all properties (Variable.browseProperties) such that
    • All results contain all properties defined by VariablePropertyRule.RequireProperty
  • SEL.VariablePropertyCategoryRule returns a set of categories collected from all suitable properties (as above)
    • categories are identified by
      • var#HasStandardPropertyInfo#CategoryName
      • var#HasStandardPropertyInfo#CategorySortingName
    • hidden categories are not shown
      • see var#HasStandardPropertyInfo#IsHidden
  • SEL.VariablePropertyLabelRule collects a String->String map by searching properties var where
    • key is the value of (var#HasDisplayColumn)
    • value is the (Bindings.STRING) value of var
  • SEL.CategoryNodeLabelRule returns the map "HasDisplayProperty" -> ((CategoryNode)content).getName()
  • SEL.StandardPropertySorterRule sorts properties and categories by sorting name where sorting name is
    • (p#SortingName) or if absent (p#HasDisplayProperty) for a variable p
    • ((CategoryNode)content).getSortingName() for categories
  • SEL.VariablePropertyModifierRule returns org.simantics.browsing.ui.content.Labeler.Modifier by
    • finding the column property (by var#HasDisplayColumn)
    • trying to obtain a custom modifier (var#HasCustomModifier)
    • trying to obtain an enumeration modifier by listing (var#HasEnumerationValues) and returning org.simantics.browsing.ui.graph.impl.EnumerationVariableModifier3
    • returning org.simantics.browsing.ui.model.modifiers.VariableModifier2
  • SEL.VariableDecorationRule offsets the property name column of properties by one
  • SEL.CategoryDecorationRule displays categories as bold

The standard implementation can be customised by e.g.

  • Introducing more columns
  • Applying property filtering (RequiresProperty)
  • Adding decorations

Some other notable points

  • Modifier uses the property 'HasInputValidator' for getting a validator
  • Modifier writes with Bindings.STRING into the label property.
  • The labels may apply transformations such as unit conversion or formatting i.e. they can not be used for obtaining raw property data.

Selection View Title

By default the selection view title is set to Selection. However it is possible for tab contributions to customize the title text. On the low-level customization happens through the org.simantics.selectionview.IPropertyTab2 interface which tab contributions can implement.

public interface IPropertyTab2 extends IPropertyTab {

    /**
     * @param updateCallback a callback that <em>can be</em> invoked by
     *        getPartName if it wishes to change the part name. If the page does
     *        not wish to change the part name, it does not have to invoke the
     *        updateCallback. A <code>null</code> value indicates that the part
     *        name should be returned to its default value. The method should
     *        use the selection received by
     *        {@link #setInput(org.simantics.db.management.ISessionContext, ISelection, boolean)}
     *        as input for constructing the part title.
     */
    void updatePartName(Callback<String> updateCallback);

}

Contributing custom title logic is not yet possible through modelling, only by implementing your own custom org.simantics.selectionview.PropertyTabContributor, e.g. by customizing org.simantics.selectionview.ModelledTabContributor or org.simantics.selectionview.PropertyTabContributorImpl.

Future developments

Some generic Variable properties should be used in rules. These properties include

  • #classifications
  • #valid
  • #validator
  • #expression
  • #required
  • #default
  • #readOnly

The Variable model includes a generic model for connections, which should also be supported in the standard properties

Selection view title logic modelling shall be added.