Changes for page Configuring Automatic Layout
Last modified by Alexander Schulz-Rosengarten on 2023/07/11 10:33
Summary
-
Page properties (1 modified, 0 added, 0 removed)
-
Objects (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -36,7 +36,7 @@ 36 36 </extension> 37 37 {{/code}} 38 38 39 -(% style="line-height: 1.4285715;" %)Let's walk through the attributes available for layout options (not every available attribute appears in the example above): 39 +(% style="line-height: 1.4285715;" %)Such declarations are provided by layout algorithm developers, but not by tool developers who merely want to connect the layout infrastructure to their diagram viewers. Let's walk through the attributes available for layout options (not every available attribute appears in the example above): 40 40 41 41 * (% style="line-height: 1.4285715;" %){{code language="none"}}id{{/code}} – A unique identifier for this layout option. It is recommended that the identifier be prefixed by the plug-in name, to guarantee uniqueness.(%%)\\ 42 42 * {{code language="none"}}type{{/code}} – Defines the data type of this option; must be either {{code language="none"}}boolean{{/code}}, {{code language="none"}}string{{/code}}, {{code language="none"}}int{{/code}}, {{code language="none"}}float{{/code}}, {{code language="none"}}enum{{/code}}, {{code language="none"}}enumset{{/code}}, or {{code language="none"}}object{{/code}}. The types {{code language="none"}}enum{{/code}}, {{code language="none"}}enumset{{/code}}, and {{code language="none"}}object{{/code}} require the {{code language="none"}}class{{/code}} attribute to be set. ... ... @@ -72,11 +72,11 @@ 72 72 73 73 (% style="line-height: 1.4285715;" %)This tells KIML that the defined layout algorithm supports the border spacing option. And even more, it overrides the default value declared by the layout option and sets it to 20. 74 74 75 -= (% style="line-height: 1.4285715;" %)The Layout Option sManager(%%) =75 += (% style="line-height: 1.4285715;" %)The Layout Option Manager(%%) = 76 76 77 -(% style="line-height: 1.4285715;" %)By now, we have an idea of what layout options do and why they are important in the first place. However, we haven't looked at how layout options end up on [[KGraph>>doc:KGraph Meta Model]] elements yet. This is where the [[{{code language="none"}}LayoutOption sManager{{/code}}>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.ui/src/de/cau/cs/kieler/kiml/ui/service/LayoutOptionManager.java||shape="rect"]] comes in.77 +(% style="line-height: 1.4285715;" %)By now, we have an idea of what layout options do and why they are important in the first place. However, we haven't looked at how layout options end up on [[KGraph>>doc:KGraph Meta Model]] elements yet. This is where the [[{{code language="none"}}LayoutOptionManager{{/code}}>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.service/src/de/cau/cs/kieler/kiml/service/LayoutOptionManager.java||shape="rect"]] comes in. If you are not interested in the internal details, but want to configure automatic layout for your diagram viewer or editor, you may skip this section and proceed to [[programmatically setting layout options>>doc:||anchor="programmatic-config"]]. 78 78 79 -(% style="line-height: 1.4285715;" %)After a diagram layout manager has finished turning a given diagram into its KGraph representation, the layout option smanager is asked to enrich the KGraph elements with layout options. The option values can come from different sources: the user might have set some using the layout view; there might be some defaults for certain kinds of diagrams; or the programmer might have decided to attach some layout options to certain elements for just this one layout run. Whatever the source, the options manager is in charge of collecting all these layout option values and making sure they find their way to the correct KGraph element. To start off with a clean plate, it first makes sure there are no layout options attached to the KGraph elements. It then does two things: collect every eligible source of layout options, and transfer values of layout options to the associated KGraph elements. Sounds easy enough.79 +(% style="line-height: 1.4285715;" %)After a diagram layout manager has finished turning a given diagram into its KGraph representation, the layout option manager is asked to enrich the KGraph elements with layout options. The option values can come from different sources: the user might have set some using the layout view; there might be some defaults for certain kinds of diagrams; or the programmer might have decided to attach some layout options to certain elements for just this one layout run. Whatever the source, the options manager is in charge of collecting all these layout option values and making sure they find their way to the correct KGraph element. To start off with a clean plate, it first makes sure there are no layout options attached to the KGraph elements. It then does two things: collect every eligible source of layout options, and transfer values of layout options to the associated KGraph elements. Sounds easy enough. 80 80 81 81 (% style="line-height: 1.4285715;" %)The question remains how the layout options sources work. Each source is represented by a class that implements the [[{{code language="none"}}ILayoutConfig{{/code}}>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/ILayoutConfig.java||shape="rect"]] interface, called a //layout configurator//. KIML currently provides the following layout configurators, each representing a particular source of layout options, listed here in order of increasing priority: 82 82 ... ... @@ -88,47 +88,113 @@ 88 88 89 89 The options manager collects all available and applicable layout configurators and sorts them by priority. For every graph element, each configurator is asked to provide layout options, starting with the one with lowest priority and working through the priority chain. Hereby configurators with higher priority are able to override values set by those with lower priority. 90 90 91 -== A Few Details on Layout Configurat ions ==91 +== A Few Details on Layout Configurators == 92 92 93 -What we just learned is a bit of a simplification of what happens. Before we look at the details, let's take a look at the methods each layout configurat ionprovides:93 +What we just learned is a bit of a simplification of what happens. Before we look at the details, let's take a look at the methods each layout configurator provides: 94 94 95 95 {{code language="java"}} 96 96 public interface ILayoutConfig { 97 97 int getPriority(); 98 - voidenrich(LayoutContext context);99 - ObjectgetValue(LayoutOptionData<?>optionData,LayoutContext context);100 - voidtransferValues(KLayoutData layoutData, LayoutContext context);98 + Object getOptionValue(LayoutOptionData optionData, LayoutContext context); 99 + Collection<IProperty<?>> getAffectedOptions(LayoutContext context); 100 + Object getContextValue(IProperty<?> property, LayoutContext context); 101 101 } 102 102 {{/code}} 103 103 104 -It is not hard to guess what {{code language="none"}}getPriority(){{/code}} does: it returns the priority a given layout configuration has. If two layout configurations set a layout option to different values on a given graph element, the value set by the configuration with higher priority wins. The other three methods look a bit more obscure, so we have to provide more details on what the options manager does, exactly.104 +It is not hard to guess what {{code language="none"}}getPriority(){{/code}} does: it returns the priority a given layout configuration has. If two layout configurations set a layout option to different values on a given graph element, the value set by the configuration with higher priority wins. 105 105 106 -E NRICHING(+WHAT ISALAYOUT CONTEXT)106 +The interface discerns between //option// values and //context// values. Option values are what we have been talking about all the time, values assigned to layout options. Which particular values the configurator should apply depends on the given [[LayoutContext>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/LayoutContext.java||shape="rect"]], which is a property holder with references to the diagram element currently in focus. For instance, the object representing an element in the diagram viewer is accessed with {{code language="none"}}context.getProperty(LayoutContext.DIAGRAM_PART){{/code}}. Similarly, the corresponding KGraph element is mapped to the property {{code language="none"}}LayoutContext.GRAPH_ELEM{{/code}}, and the domain model element is mapped to {{code language="none"}}LayoutContext.DOMAIN_MODEL{{/code}}. Each configurator is free to put additional information into the context, caching it for faster access and enabling to communicate it to other configurators. {{code language="none"}}getAffectedOptions(LayoutContext){{/code}} should return a collection of layout options for which the configurator yields non-null values with respect to the given context. The options can be referenced either with [[LayoutOptionData>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/LayoutOptionData.java||shape="rect"]] instances obtained from the [[LayoutMetaDataService>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/LayoutMetaDataService.java||shape="rect"]] or with [[Property>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.core/src/de/cau/cs/kieler/core/properties/Property.java||shape="rect"]] instances from the constants defined in [[LayoutOptions>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/options/LayoutOptions.java||shape="rect"]]. The actual value for a layout option is queried with {{code language="none"}}getOptionValue(LayoutOptionData, LayoutContext){{/code}}. The method {{code language="none"}}getContextValue(IProperty, LayoutContext){{/code}}, in contrast, is used to obtain more detailed information on the given context. For instance, the context may contain a reference to an element of the diagram viewer; only a specialized configurator made for that diagram viewer knows how to extract a reference to the corresponding domain model element from the given diagram element, so it can encode this knowledge in {{code language="none"}}getContextValue(…){{/code}} by returning the domain model element when the given property corresponds to LayoutContext.DOMAIN_MODEL. 107 107 108 -Th e {{codelanguage="none"}}transferValues(...){{/code}}methodisthemainworkhorse of theinterface.Thisis where a KGraph element,identifiedbythe given layout context,isequipped with thelayout optionvalues alayoutconfigurationdeems necessary.Itthusbecomesthe mostimportant partofalayout configurationthatyouabsolutelyhaveto implement,noexcuses. If forexample every{{codelanguage="none"}}KNode{{/code}}should havetsportconstraints setto {{codelanguage="none"}}FIXED_POS{{/code}},thisistheplace todoit.108 +This may seem complicated, and it is, but the good news is that the vast majority of developers will not need to dig that deep into the layout configuration infrastructure. There are easier ways to specify configurations, as described in the following section. 109 109 110 - Withallthese layoutconfigurations active, it's byno means clear whichlayout optionvalues KGraphlements will end up with duringthe layoutprocess.Enterthe {{code language="none"}}getValue(...){{/code}} method. Forgiven elementand layoutoption, it returns the value it wouldsetonthe elementif {{code language="none"}}transferValues(...){{/code}}was called. This method is mainly used by theLayoutview to inform the user about the layout optionvaluesof whatever graph element he(or she)has clicked on. It is also the method you can safely neglect to implement if your final product won't include the layout view anyway.110 += (% style="line-height: 1.4285715;" %)Programmatically Setting Layout Options(%%) = 111 111 112 - ==(% style="line-height: 1.4285715;" %)Implementing a Layout Configuration(%%) ==112 +{{id name="programmatic-config"/}} 113 113 114 -{{warning title="ToDo"}} 115 -deciding what options are applicable depending on the context object; setting the options; 116 -{{/warning}} 114 +(% style="line-height: 1.4285715;" %)So with all these layout configurators available, how do you actually go about setting values for layout options programmatically? Well, as always: it depends. 117 117 118 -(% style="line-height: 1.4285715;" %) 116 +== (% style="line-height: 1.4285715;" %)Using the Extension Point(%%) == 119 119 118 +(% style="line-height: 1.4285715;" %)The recommended way to configure your layout is to use the {{code language="none"}}layoutConfigs{{/code}} extension point. It offers three different kinds of configurations, explained in the following. 120 120 121 -= (% style="line-height: 1.4285715;" %) Programmatically Setting Layout Options(%%) =120 +=== (% style="line-height: 1.4285715;" %)staticConfig(%%) === 122 122 123 -(% style="line-height: 1.4285715;" %) Sowith all theselayouturationsavailable,howdoyouactuallygoabout settinglayout optionsprogrammatically?Well,as always:it depends.122 +(% style="line-height: 1.4285715;" %)A {{code language="none"}}staticConfig{{/code}} element can set one value for one layout option in the context of a particular diagram element type. Let's see an example: 124 124 124 +{{code language="xml"}} 125 + <staticConfig 126 + class="org.eclipse.emf.ecore.EReference" 127 + option="de.cau.cs.kieler.edgeType" 128 + value="ASSOCIATION"> 129 + </staticConfig> 130 +{{/code}} 125 125 126 -(% style="line-height: 1.4285715;" %) 132 +(% style="line-height: 1.4285715;" %)Here {{code language="none"}}class{{/code}} refers to a domain model class, in this case the {{code language="none"}}EReference{{/code}} class from the Ecore meta model defined by EMF, and {{code language="none"}}option{{/code}} refers to a layout option through its identifier. The meaning of this declaration is that whenever automatic layout is requested for an Ecore class diagram, the {{code language="none"}}edgeType{{/code}} option is set to {{code language="none"}}ASSOCIATION{{/code}}(%%) for all edges linked to instances of {{code language="none"}}EReference{{/code}}. Since the domain model (//abstract syntax//) is independent of the specific diagram viewer (//concrete syntax//), this configuration is applied to all diagram viewers that use the Ecore meta model. 127 127 134 +Alternatively to domain model elements, {{code language="none"}}staticConfig{{/code}} may also reference concrete syntax elements: 128 128 129 -{{warning title="ToDo"}} 130 -Write this section. This will be about when to use the different kinds of layout configurations, mainly {{code language="none"}}SemanticLayoutConfig{{/code}} and {{code language="none"}}VolatileLayoutConfig{{/code}}. 131 -{{/warning}} 136 +{{code language="xml"}} 137 + <staticConfig 138 + class="org.eclipse.emf.ecoretools.diagram.edit.parts.EClassESuperTypesEditPart" 139 + option="de.cau.cs.kieler.edgeType" 140 + value="GENERALIZATION"> 141 + </staticConfig> 142 +{{/code}} 132 132 133 - (%style="line-height:1.4285715;"%)144 +This layout option value is applied only to edges linked to instances of {{code language="none"}}EClassESuperTypesEditPart{{/code}}, which is a concrete syntax element of the Ecore Tools class diagram editor. Other Ecore meta model editors are not affected by this declaration. This distinction is particularly useful for meta models that are accessed with multiple different editors, as is often the case for UML tools. 134 134 146 +A third variant is the use of //diagram types//, as in this example: 147 + 148 +{{code language="xml"}} 149 + <diagramType 150 + id="de.cau.cs.kieler.layout.diagrams.classDiagram" 151 + name="Class Diagram"> 152 + </diagramType> 153 + <staticConfig 154 + class="org.eclipse.emf.ecore.EPackage" 155 + option="de.cau.cs.kieler.diagramType" 156 + value="de.cau.cs.kieler.layout.diagrams.classDiagram"> 157 + </staticConfig> 158 + <staticConfig 159 + class="de.cau.cs.kieler.layout.diagrams.classDiagram" 160 + option="de.cau.cs.kieler.edgeRouting" 161 + value="SPLINES"> 162 + </staticConfig> 163 +{{/code}} 164 + 165 +A diagram type can be declared with a {{code language="none"}}diagramType{{/code}} element and can be associated with an abstract syntax or concrete syntax class using the {{code language="none"}}diagramType{{/code}} option, as shown in the first {{code language="none"}}staticConfig{{/code}} declaration in the example above. The second {{code language="none"}}staticConfig{{/code}} sets an option for the declared diagram type by using its identifier in the {{code language="none"}}class{{/code}} attribute. This kind of indirection is very useful when you have //n// model classes and you want to set //m// layout options for each of those classes. Instead of writing //n// × //m// static declarations, you assign a diagram type //t// to each of the //n// classes and then declare the //m// layout options for //t//, resulting in //n// + //m// option declarations (in many cases //n// + //m// < //n// × //m//). 166 + 167 +A further use of diagram types is for the selection of layout algorithms: a layout algorithm may declare that is is especially suited to process diagrams of certain type //t//. If the diagram type //t// is assigned to a diagram viewer, the most suitable layout algorithm is chosen automatically for that viewer. 168 + 169 +=== semanticConfig === 170 + 171 +A {{code language="none"}}semanticConfig{{/code}} element registers a subclass of [[SemanticLayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/SemanticLayoutConfig.java||shape="rect"]]: 172 + 173 +{{code language="xml"}} 174 + <semanticOption 175 + class="de.cau.cs.kieler.synccharts.Scope" 176 + config="de.cau.cs.kieler.synccharts.diagram.custom.AnnotationsLayoutConfig"> 177 + </semanticOption> 178 +{{/code}} 179 + 180 +Similarly to {{code language="none"}}staticConfig{{/code}} entries, the {{code language="none"}}class{{/code}} attribute refers to which model elements the configuration is applied. However, only domain model (a.k.a. //semantic// model) classes may be referenced. The {{code language="none"}}config{{/code}} attribute names a concrete implementation of the semantic layout configurator. 181 + 182 +The advantage of this kind of configuration compared to {{code language="none"}}staticConfig{{/code}} declarations is that it may perform arbitrary analyses of the domain model. For instance, different option values may be computed depending on certain properties of the domain model elements. This approach can be used to enable annotations of domain model elements. When the domain model is stored with a textual format, e.g. defined with [[Xtext>>url:http://www.eclipse.org/Xtext/||shape="rect"]], such annotations can be written in the source file that specifies the model: 183 + 184 +{{code}} 185 +@portConstraints FIXED_SIDE 186 +@minWidth 20.0 187 +@minHeight 15.0 188 +entity IdentityActor 189 +{ 190 + @portSide WEST 191 + port Input; 192 + 193 + @portSide EAST 194 + port Output; 195 +} 196 +{{/code}} 197 + 198 +The source file annotations can be translated to KIML layout options with a semantic layout configurator, which is registered to each domain model class where annotations can occur. 199 + 200 +
- Confluence.Code.ConfluencePageClass[0]
-
- Id
-
... ... @@ -1,1 +1,1 @@ 1 -94699 791 +9469995 - URL
-
... ... @@ -1,1 +1,1 @@ 1 -https://rtsys.informatik.uni-kiel.de/confluence//wiki/spaces/KIELER/pages/94699 79/Configuring Automatic Layout1 +https://rtsys.informatik.uni-kiel.de/confluence//wiki/spaces/KIELER/pages/9469995/Configuring Automatic Layout