Difference between revisions of "Graphical Modeling Framework/Tutorial/Part 3"

From Eclipsepedia

Jump to: navigation, search
m (Generation)
 
(17 intermediate revisions by 4 users not shown)
Line 1: Line 1:
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram.  The complete solution to this tutorial is maintained in CVS [http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.gmf/examples/?root=Modeling_Project here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.
+
{{GMF}}
  
== New Icons ==
+
= Advanced customization =
A quick way to get a polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;-)  The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/ folder. 
+
  
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model.  For example, delete the 'Default Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Bundle to org.eclipse.gmf.examples.mindmap.edit and its Path property to /icons/full/obj16/Subtopic.gif.  Regenerate and the palette will display the new icon.  Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.
+
This third part is dedicated to customization that you cannot make using the generation models. This is where you'll have to code to customize your process. But don't worry, GMF Runtime provides a lot of stuff to make it easier.  The complete solution to this tutorial is maintained in CVS [http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.gmp/org.eclipse.gmf.tooling/examples/?root=Modeling_Project here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.
 
+
Finally, take a look in the mindmap.gmfgen for properties to set for the default wizard and diagram file icons.  While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.
+
 
+
Below is an image of our diagram and palette using some new images.
+
 
+
[[Image:new_icons.png]]
+
<br style="clear:both;"/>
+
 
+
== Composite Figures ==
+
[[Image:resource.png|frame|right]]
+
What we'd like to do is have an actor-style representation for our resources added to our diagram.  These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.
+
<br style="clear:both;"/>
+
=== Graphical Definition ===
+
[[Image:resource_figure.png|frame|right]]
+
Open up your graphical definition again and add a new Figure Descriptor and Rectangle named 'ResourceFigure' to your Figure Gallery.  Set its Outline property to false, along with its Fill.  As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure.  Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements.  Rather than go through all of the gory details of these, the figure code is found below.  Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.
+
 
+
To our Canvas, add a new Node named Resource and assign our ResourceFigure as its Figure.  Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively.  Note that the Label for our Resource is not a child element of its figure.  We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.
+
<br style="clear:both;"/>
+
 
+
<pre>
+
  <descriptors
+
        name="ResourceFigure">
+
      <actualFigure
+
          xsi:type="gmfgraph:Rectangle"
+
          name="ResourceFigure"
+
          outline="false"
+
          fill="false">
+
          <layout xsi:type="gmfgraph:XYLayout"/>
+
      <children xsi:type="gmfgraph:Ellipse" name="Head">
+
        <foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/>
+
        <backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/>
+
        <size x="40" y="20"/>
+
      </children>
+
      <children xsi:type="gmfgraph:Polygon" name="Body">
+
        <foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/>
+
        <backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/>
+
        <template x="23" y="19"/>
+
        <template x="23" y="24"/>
+
        <template x="39" y="24"/>
+
        <template x="39" y="29"/>
+
        <template x="23" y="29"/>
+
        <template x="23" y="36"/>
+
        <template x="39" y="48"/>
+
        <template x="39" y="53"/>
+
        <template x="20" y="42"/>
+
        <template x="1" y="53"/>
+
        <template x="1" y="48"/>
+
        <template x="17" y="36"/>
+
        <template x="17" y="29"/>
+
        <template x="1" y="29"/>
+
        <template x="1" y="24"/>
+
        <template x="17" y="24"/>
+
        <template x="17" y="19"/>
+
      </children>
+
      <maximumSize dx="40" dy="60"/>
+
      <minimumSize dx="40" dy="60"/>
+
      <preferredSize dx="40" dy="60"/>
+
      <size x="40" y="60"/>
+
      </actualFigure>
+
    </descriptors>
+
</pre>
+
 
+
<blockquote>
+
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. To get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looksThen, move this information back into your gmfgraph model.  Of course, when the WYSIWYG features of GMF become more mature, none of this should be necessary.
+
</blockquote>
+
<br style="clear:both;"/>
+
 
+
=== Tooling Definition ===
+
[[Image:resource_tool.png|frame|right]]
+
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.
+
<br style="clear:both;"/>
+
 
+
=== Mapping Definition ===
+
 
+
[[Image:resource_map.png|frame|right]]
+
First, we'll need to add a new Top Node Reference to our Mapping definition.  Set the Containment Feature to our 'resources : Resource' attribute of our Map class.  Add a child Node Mapping element to this Top Node Reference and select our 'Resource' for the Domain meta information Element property.  Of course, we'll select our Resource node for the Diagram Node and our Resource creation tool for the palette.
+
 
+
Now, to add our Feature Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model.  Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'.  To allow for the proper parsing of what's entered into the direct edit field, we will define an edit and view pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes.  Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.
+
 
+
=== Generation ===
+
After generation, a slight tweak will need to be made to the generated figure until [https://bugs.eclipse.org/bugs/show_bug.cgi?id=142010 bug 142010] is resolved. In the generated org.eclipse.gmf.examples.mindmap.diagram.edit.parts.ResourceEditPart$ResourceFigure class, set the attribute private boolean myUseLocalCoordinates = true;  You might want to set the comment above it to @generated NOT in order to preserve this change. Without doing this the polygon used for the figure's body will not be visible.
+
 
+
Run the diagram and check the operation of the label, as well as the look of the figure.  It should look similar to the one above.  Resources added to the diagram are now available in the properties view for topic assignments, thread authoring, etc.  To add the ability to create links from other elements to a Resource, follow steps similar to how links are used to represent subtopics. This exercise is left to the reader ;-)
+
  
 
== Creating a Customization Plug-in ==
 
== Creating a Customization Plug-in ==
 
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in.  For this purpose, create a new plug-in project named org.eclipse.gmf.examples.mindmap.diagram.custom to your workspace.  Use the default settings, although no Activator class is needed, nor is the use of any of the templates provided in the wizard.
 
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in.  For this purpose, create a new plug-in project named org.eclipse.gmf.examples.mindmap.diagram.custom to your workspace.  Use the default settings, although no Activator class is needed, nor is the use of any of the templates provided in the wizard.
  
== Custom Actions ==
+
=== Custom Actions ===
 
[[Image:insert_subtopic.png|frame|right]]
 
[[Image:insert_subtopic.png|frame|right]]
 
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic.  Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or some combination) and have the new Topic created, including the link, and with the in-place editor active on the new Topic.  In this section, we will explore how to accomplish just this.
 
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic.  Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or some combination) and have the new Topic created, including the link, and with the in-place editor active on the new Topic.  In this section, we will explore how to accomplish just this.
Line 98: Line 14:
 
To begin, we know that the org.eclipse.ui.bindings can be used to assign a Ctrl+I key combination to our action (as seen on the image, though for OS X).  This is easily accomplished by contributing to the extension-point in our new *.diagram.custom plugin.xml file.  Note that this is a simplistic example that does not declare a context, as you would probably expect to create for your diagram and potentially extend a default GMF diagram context (if one existed ;-).
 
To begin, we know that the org.eclipse.ui.bindings can be used to assign a Ctrl+I key combination to our action (as seen on the image, though for OS X).  This is easily accomplished by contributing to the extension-point in our new *.diagram.custom plugin.xml file.  Note that this is a simplistic example that does not declare a context, as you would probably expect to create for your diagram and potentially extend a default GMF diagram context (if one existed ;-).
  
<pre>
+
<source lang="xml">
 
<extension point="org.eclipse.ui.bindings">
 
<extension point="org.eclipse.ui.bindings">
 
<key commandId="org.eclipse.gmf.examples.mindmap.insertSubtopic" sequence="M1+I" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
 
<key commandId="org.eclipse.gmf.examples.mindmap.insertSubtopic" sequence="M1+I" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
 
</extension>
 
</extension>
</pre>
+
</source>
  
 
Now, for the command, we'll contribute to the org.eclipse.ui.commands extension-point, as seen below.  When you run your diagram, you will see this command category and the shortcut listed in the General | Keys preference page.
 
Now, for the command, we'll contribute to the org.eclipse.ui.commands extension-point, as seen below.  When you run your diagram, you will see this command category and the shortcut listed in the General | Keys preference page.
  
<pre>
+
<source lang="xml">
 
<extension point="org.eclipse.ui.commands">
 
<extension point="org.eclipse.ui.commands">
 
<category name="Mindmap" description="Commands related to Mindmap diagrams." id="org.eclipse.gmf.category.mindmap"/>
 
<category name="Mindmap" description="Commands related to Mindmap diagrams." id="org.eclipse.gmf.category.mindmap"/>
Line 112: Line 28:
 
</command>
 
</command>
 
</extension>
 
</extension>
</pre>
+
</source>
  
 
Now, for the popup menu.  We'd like to have a series of potential menu items to insert elements on our diagram (i.e. subtopics, threads, etc.), so our contribution to org.eclipse.ui.popupMenus will define an 'Insert | Subtopic' menu and link it to our binding above through the defintionId:
 
Now, for the popup menu.  We'd like to have a series of potential menu items to insert elements on our diagram (i.e. subtopics, threads, etc.), so our contribution to org.eclipse.ui.popupMenus will define an 'Insert | Subtopic' menu and link it to our binding above through the defintionId:
  
<pre>
+
<source lang="xml">
 
<extension point="org.eclipse.ui.popupMenus">
 
<extension point="org.eclipse.ui.popupMenus">
 
       <objectContribution
 
       <objectContribution
Line 138: Line 54:
 
       </objectContribution>                     
 
       </objectContribution>                     
 
</extension>
 
</extension>
</pre>
+
</source>
  
 
Now, for the fun part... to define the declared MindmapCreateSubtopicAction class.  To begin, we know that similar functionality exists in the connection handles feature provided by the runtime (see image below).
 
Now, for the fun part... to define the declared MindmapCreateSubtopicAction class.  To begin, we know that similar functionality exists in the connection handles feature provided by the runtime (see image below).
Line 145: Line 61:
  
 
After some investigation, it seems the CreateViewAndOptionallyElementCommand class gives us a hint at how to implement what we want (thanks to Cherie for providing a simplied version of the original tutorial code below, which leverages the DeferredCreateConnectionViewAndElementCommand).   
 
After some investigation, it seems the CreateViewAndOptionallyElementCommand class gives us a hint at how to implement what we want (thanks to Cherie for providing a simplied version of the original tutorial code below, which leverages the DeferredCreateConnectionViewAndElementCommand).   
<pre>
+
<source lang="java">
 
public void run(IAction action) {
 
public void run(IAction action) {
 
CompoundCommand cc = new CompoundCommand("Create Subtopic and Link");
 
CompoundCommand cc = new CompoundCommand("Create Subtopic and Link");
Line 188: Line 104:
 
}
 
}
 
}
 
}
</pre>
+
</source>
 
Rather than type in the code, simply copy the MindmapCreateSubtopicAction class into your project from the solution in CVS.  If you observe any Access Restriction errors, add the required packages to the Exported Packages list on the Runtime of the *.diagram plugin.  The basic concepts are outlined next.
 
Rather than type in the code, simply copy the MindmapCreateSubtopicAction class into your project from the solution in CVS.  If you observe any Access Restriction errors, add the required packages to the Exported Packages list on the Runtime of the *.diagram plugin.  The basic concepts are outlined next.
  
Line 199: Line 115:
 
<br style="clear:both;"/>
 
<br style="clear:both;"/>
  
== Custom Layout ==
+
=== Custom Layout ===
Clearly, the default layout provided is not appropriate for a mindmap.  What we are about to add is also less than optimal, but will indicate what is necessary to add a custom layout to your diagram.  As described in the [http://help.eclipse.org/help32/topic/org.eclipse.gmf.doc/examples-guide/diagram/layoutServiceExample.html Layout Service Example], we will contribute an extension to the runtime's layoutProviders extension-point.
+
Clearly, the default layout provided is not appropriate for a mindmap.  What we are about to add is also less than optimal, but will indicate what is necessary to add a custom layout to your diagram.  As described in the [http://help.eclipse.org/help33/topic/org.eclipse.gmf.doc/examples-guide/diagram/layoutServiceExample.html Layout Service Example], we will contribute an extension to the runtime's layoutProviders extension-point.
  
 
We'll try two layouts: one that extends org.eclipse.gmf.runtime.diagram.ui.providers.LeftRightProvider; the other, extending org.eclipse.gmf.runtime.diagram.ui.providers.internal.RadialProvider ''(To access these class you need to include org.eclipse.gmf.runtime.diagram.ui.providers in your project dependancies)''. For each, add the appropriate extension in your plugin.xml file, setting the Priority higher for the one you'd like to take precedence.  For example:
 
We'll try two layouts: one that extends org.eclipse.gmf.runtime.diagram.ui.providers.LeftRightProvider; the other, extending org.eclipse.gmf.runtime.diagram.ui.providers.internal.RadialProvider ''(To access these class you need to include org.eclipse.gmf.runtime.diagram.ui.providers in your project dependancies)''. For each, add the appropriate extension in your plugin.xml file, setting the Priority higher for the one you'd like to take precedence.  For example:
<pre>
+
<source lang="xml">
 
<extension point="org.eclipse.gmf.runtime.diagram.ui.layoutProviders">
 
<extension point="org.eclipse.gmf.runtime.diagram.ui.layoutProviders">
 
   <layoutProvider class="org.eclipse.gmf.examples.mindmap.diagram.layout.MindmapDefaultLayoutProvider">
 
   <layoutProvider class="org.eclipse.gmf.examples.mindmap.diagram.layout.MindmapDefaultLayoutProvider">
Line 209: Line 125:
 
   </layoutProvider>
 
   </layoutProvider>
 
</extension>
 
</extension>
</pre>
+
</source>
  
 
The code for the LeftRightProvider is below:
 
The code for the LeftRightProvider is below:
<pre>
+
<source lang="java">
 
public class MindmapDefaultLayoutProvider
 
public class MindmapDefaultLayoutProvider
 
     extends LeftRightProvider {
 
     extends LeftRightProvider {
Line 240: Line 156:
  
 
}
 
}
</pre>
+
</source>
  
If you run the diagram using both providers, it's clear that the radial is more well-suited for a mindmap, although some adjustments would be necessary to make it more usable.
+
If you run the diagram using both providers, it's clear that the left-right layout is more well-suited for a mindmap, although some adjustments would be necessary to make it more usable.
  
== Removing Tools from the Palette ==
+
=== Removing Tools from the Palette ===
 
Let's say you don't want to see the Notes stack and Zoom tool on your palette.  To remove them, you need to contribute to the paletteProvider extension-point using the predefinedEntry IDs and remove="true" attribute.  For these contributions to not impact all editors, add an editor element with your diagram's ID to the paletteProvider, as seen below:
 
Let's say you don't want to see the Notes stack and Zoom tool on your palette.  To remove them, you need to contribute to the paletteProvider extension-point using the predefinedEntry IDs and remove="true" attribute.  For these contributions to not impact all editors, add an editor element with your diagram's ID to the paletteProvider, as seen below:
  
<pre>
+
<source lang="xml">
 
<extension point="org.eclipse.gmf.runtime.diagram.ui.paletteProviders">  
 
<extension point="org.eclipse.gmf.runtime.diagram.ui.paletteProviders">  
 
   <paletteProvider class="org.eclipse.gmf.runtime.diagram.ui.providers.DefaultPaletteProvider">
 
   <paletteProvider class="org.eclipse.gmf.runtime.diagram.ui.providers.DefaultPaletteProvider">
Line 262: Line 178:
 
   </paletteProvider>
 
   </paletteProvider>
 
</extension>
 
</extension>
</pre>
+
</source>
  
== Summary ==
+
This contribution is added to the org.eclipse.gmf.examples.mindmap.custom plugin.xml file in [http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.gmf/examples/org.eclipse.gmf.examples.mindmap.diagram.custom/plugin.xml?view=log&root=Modeling_Project&pathrev=HEAD CVS].
 +
 
 +
=== Customization Extension points reference ===
 +
 
 +
Here is the list of extension point you can use in your customization plugins to improve the diagram without modifying the generated code: http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.gmf.doc/reference/extension-points/index.html
 +
 
 +
== Customizing generation templates ==
 +
 
 +
GMF Tooling uses XPT templates to generate your diagram code. But it offers the way to use alternative template if you have to tweak directly generated code.
 +
 
 +
=== Set it up ===
 +
 
 +
See http://www.bonitasoft.org/blog/eclipse/customize-your-gmf-editor-by-customizing-templates/
 +
 
 +
=== Overriding templates ===
 +
 
 +
See http://www.bonitasoft.org/blog/eclipse/customize-your-gmf-editor-by-customizing-templates/
 +
 
 +
=== Using aspects ===
 +
 
 +
http://www.bonitasoft.org/blog/eclipse/customize-your-gmf-editor-by-customizing-templates/
 +
 
 +
= Summary =
 
In this section of the tutorial, we saw how to add a composite figure, create a custom action and layout provider contained within a new extension plug-in.  In the next section, we will look at using the dashboard, and generating an RCP-based mindmap with the "lite" runtime: [[GMF_Tutorial_Part_4|GMF Tutorial Part 4]]
 
In this section of the tutorial, we saw how to add a composite figure, create a custom action and layout provider contained within a new extension plug-in.  In the next section, we will look at using the dashboard, and generating an RCP-based mindmap with the "lite" runtime: [[GMF_Tutorial_Part_4|GMF Tutorial Part 4]]
 +
 +
= Following the tutorial =
 +
 +
* [[../Part 1 | GMF Tutorial Part 1 - Get Started with GMF]]
 +
* [[../Part 2 | GMF Tutorial Part 2 - How to configure your editor]]
 +
* [[../Part 3 | GMF Tutorial Part 3 - Advanced customization]]
 +
* [[../Part 4 | GMF Tutorial Part 4]]
 +
 +
= References =
 +
* [http://www.eclipse.org/modeling/gmp/ Graphical Modeling Project Website]
 +
 +
* [[Graphical Modeling Framework/Documentation | GMF Documentation]]
 +
 +
* [[../Part 1 | GMF Tutorial Part 1 - Get Started with GMF]]
 +
 +
* [[../Part 2 | GMF Tutorial Part 2 - How to configure your editor]]
 +
 +
* [[../Part 3 | GMF Tutorial Part 3 - Advanced customization]]
 +
 +
* [[../Part 4 | GMF Tutorial Part 4]]

Latest revision as of 08:56, 16 December 2011



GMF
Website
Download
Dev Builds
Update Site releases milestones
Community
Mailing ListNewsgroupIRC
Bugzilla
Open
Help Wanted
Bug Day
Source
GMF Notation: View CVS repo

GMF Runtime: View CVS repo
GMF Tooling: View Git Repo, GitHub


Contents

[edit] Advanced customization

This third part is dedicated to customization that you cannot make using the generation models. This is where you'll have to code to customize your process. But don't worry, GMF Runtime provides a lot of stuff to make it easier. The complete solution to this tutorial is maintained in CVS here. Viewlets will be available after appropriate sections below to focus their content and keep them short.

[edit] Creating a Customization Plug-in

Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in. For this purpose, create a new plug-in project named org.eclipse.gmf.examples.mindmap.diagram.custom to your workspace. Use the default settings, although no Activator class is needed, nor is the use of any of the templates provided in the wizard.

[edit] Custom Actions

Insert subtopic.png

The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or some combination) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.

To begin, we know that the org.eclipse.ui.bindings can be used to assign a Ctrl+I key combination to our action (as seen on the image, though for OS X). This is easily accomplished by contributing to the extension-point in our new *.diagram.custom plugin.xml file. Note that this is a simplistic example that does not declare a context, as you would probably expect to create for your diagram and potentially extend a default GMF diagram context (if one existed ;-).

<extension point="org.eclipse.ui.bindings">
	<key commandId="org.eclipse.gmf.examples.mindmap.insertSubtopic" sequence="M1+I" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
</extension>

Now, for the command, we'll contribute to the org.eclipse.ui.commands extension-point, as seen below. When you run your diagram, you will see this command category and the shortcut listed in the General | Keys preference page.

<extension point="org.eclipse.ui.commands">
	<category name="Mindmap" description="Commands related to Mindmap diagrams." id="org.eclipse.gmf.category.mindmap"/>
	<command categoryId="org.eclipse.gmf.category.mindmap" description="Inserts a new subtopic" id="org.eclipse.gmf.examples.mindmap.insertSubtopic" name="Insert Subtopic">
	</command>
</extension>

Now, for the popup menu. We'd like to have a series of potential menu items to insert elements on our diagram (i.e. subtopics, threads, etc.), so our contribution to org.eclipse.ui.popupMenus will define an 'Insert | Subtopic' menu and link it to our binding above through the defintionId:

<extension point="org.eclipse.ui.popupMenus">
      <objectContribution
            adaptable="false"
            id="org.eclipse.gmf.examples.mindmap.diagram.ui.objectContribution.TopicEditPart1"
            objectClass="org.eclipse.gmf.examples.mindmap.diagram.edit.parts.TopicEditPart">
         <menu 
            id="MindmapInsert" 
            label="&amp;Insert" 
            path="additions"> 
            <separator name="group1"/>
         </menu>
         <action
               class="org.eclipse.gmf.examples.mindmap.diagram.part.MindmapCreateSubtopicAction"
               definitionId="org.eclipse.gmf.examples.mindmap.insertSubtopic"
               enablesFor="1"
               id="org.eclipse.gmf.examples.mindmap.popup.MindmapCreateSubtopicActionID"
               label="&amp;Subtopic"
               menubarPath="MindmapInsert/group1">
         </action>
      </objectContribution>                    
</extension>

Now, for the fun part... to define the declared MindmapCreateSubtopicAction class. To begin, we know that similar functionality exists in the connection handles feature provided by the runtime (see image below).

Connection handle.png


After some investigation, it seems the CreateViewAndOptionallyElementCommand class gives us a hint at how to implement what we want (thanks to Cherie for providing a simplied version of the original tutorial code below, which leverages the DeferredCreateConnectionViewAndElementCommand).

public void run(IAction action) {
	CompoundCommand cc = new CompoundCommand("Create Subtopic and Link");
 
	// Create the new topic for the other end.
	CreateViewRequest topicRequest = CreateViewRequestFactory.getCreateShapeRequest(MindmapElementTypes.Topic_2001, selectedElement.getDiagramPreferencesHint());
 
	Point p = selectedElement.getFigure().getBounds().getTopRight().getCopy();
	selectedElement.getFigure().translateToAbsolute(p);
	int edgeCount = selectedElement.getNotationView().getSourceEdges().size();
	// A quick hack to get subtopics to layout to the right, from top to bottom
	int offset = (edgeCount * 50) - 100;
	topicRequest.setLocation(p.translate(100, offset));
 
	MapEditPart mapEditPart = (MapEditPart) selectedElement.getParent();
	Command createTopicCmd = mapEditPart.getCommand(topicRequest);
	IAdaptable topicViewAdapter = (IAdaptable) ((List) topicRequest.getNewObject()).get(0);
 
	cc.add(createTopicCmd);
 
	// create the subtopics link command
	ICommand createSubTopicsCmd = new DeferredCreateConnectionViewAndElementCommand(new CreateConnectionViewAndElementRequest(MindmapElementTypes.TopicSubtopics_4001,
				((IHintedType) MindmapElementTypes.TopicSubtopics_4001).getSemanticHint(), selectedElement.getDiagramPreferencesHint()), new EObjectAdapter((EObject) selectedElement.getModel()),
				topicViewAdapter, selectedElement.getViewer());
 
	cc.add(new ICommandProxy(createSubTopicsCmd));
 
	selectedElement.getDiagramEditDomain().getDiagramCommandStack().execute(cc);
 
	// put the new topic in edit mode
	final EditPartViewer viewer = selectedElement.getViewer();
	final EditPart elementPart = (EditPart) viewer.getEditPartRegistry().get(topicViewAdapter.getAdapter(View.class));
	if (elementPart != null) {
		Display.getCurrent().asyncExec(new Runnable() {
 
			public void run() {
					viewer.setSelection(new StructuredSelection(elementPart));
					Request der = new Request(RequestConstants.REQ_DIRECT_EDIT);
					elementPart.performRequest(der);
				}
		});
	}
}

Rather than type in the code, simply copy the MindmapCreateSubtopicAction class into your project from the solution in CVS. If you observe any Access Restriction errors, add the required packages to the Exported Packages list on the Runtime of the *.diagram plugin. The basic concepts are outlined next.

Our action will implement IObjectActionDelegate, with its run method performing the following:

  • create and initialize a CreateConnectionRequest
  • create and execute a CompoundCommand, containing a DeferredCreateConnectionViewAndElementCommand
  • create and perform a direct edit request on the new subtopic
Inserted subtopic.png

Run the diagram and test the functionality using the keyboard combination (Ctrl+I) or right-click menu. Note that the subtopic is created above and to the right of the parent with direct editing enabled for you to give it a name. As you can see, the code to determine the position is a temporary hack (layout will be covered in another installment of the tutorial).

[edit] Custom Layout

Clearly, the default layout provided is not appropriate for a mindmap. What we are about to add is also less than optimal, but will indicate what is necessary to add a custom layout to your diagram. As described in the Layout Service Example, we will contribute an extension to the runtime's layoutProviders extension-point.

We'll try two layouts: one that extends org.eclipse.gmf.runtime.diagram.ui.providers.LeftRightProvider; the other, extending org.eclipse.gmf.runtime.diagram.ui.providers.internal.RadialProvider (To access these class you need to include org.eclipse.gmf.runtime.diagram.ui.providers in your project dependancies). For each, add the appropriate extension in your plugin.xml file, setting the Priority higher for the one you'd like to take precedence. For example:

<extension point="org.eclipse.gmf.runtime.diagram.ui.layoutProviders">
   <layoutProvider class="org.eclipse.gmf.examples.mindmap.diagram.layout.MindmapDefaultLayoutProvider">
       <Priority name="Medium"/>
   </layoutProvider>
</extension>

The code for the LeftRightProvider is below:

public class MindmapDefaultLayoutProvider
    extends LeftRightProvider {
 
    public static String DEFAULT_LAYOUT = "Default";
 
    public boolean provides(IOperation operation) {
        // enable this provider only on mindmap diagrams
        if (operation instanceof ILayoutNodeOperation) {
            Iterator nodes = ((ILayoutNodeOperation) operation)
                .getLayoutNodes().listIterator();
            if (nodes.hasNext()) {
                View node = ((ILayoutNode) nodes.next()).getNode();
                Diagram container = node.getDiagram();
                if (container == null
                    || !(container.getType().equals("Mindmap"))) //$NON-NLS-1$
                    return false;
            }
        } else {
            return false;
        }
        IAdaptable layoutHint = ((ILayoutNodeOperation) operation)
            .getLayoutHint();
        String layoutType = (String) layoutHint.getAdapter(String.class);
        return LayoutType.DEFAULT.equals(layoutType);
    }
 
}

If you run the diagram using both providers, it's clear that the left-right layout is more well-suited for a mindmap, although some adjustments would be necessary to make it more usable.

[edit] Removing Tools from the Palette

Let's say you don't want to see the Notes stack and Zoom tool on your palette. To remove them, you need to contribute to the paletteProvider extension-point using the predefinedEntry IDs and remove="true" attribute. For these contributions to not impact all editors, add an editor element with your diagram's ID to the paletteProvider, as seen below:

<extension point="org.eclipse.gmf.runtime.diagram.ui.paletteProviders"> 
  <paletteProvider class="org.eclipse.gmf.runtime.diagram.ui.providers.DefaultPaletteProvider">
    <Priority name="High"/>
      <contribution>
     	<predefinedEntry id="standardGroup/zoomTool" remove="true"/>
     	<predefinedEntry id="standardGroup/noteStack/noteTool" remove="true"/> 
	<predefinedEntry id="standardGroup/noteStack/textTool" remove="true"/> 
	<predefinedEntry id="standardGroup/noteStack/noteattachmentTool" remove="true"/>
      </contribution>
      <editor
            id="org.eclipse.gmf.examples.mindmap.diagram.part.MindmapDiagramEditorID">
      </editor>
  </paletteProvider>
</extension>

This contribution is added to the org.eclipse.gmf.examples.mindmap.custom plugin.xml file in CVS.

[edit] Customization Extension points reference

Here is the list of extension point you can use in your customization plugins to improve the diagram without modifying the generated code: http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.gmf.doc/reference/extension-points/index.html

[edit] Customizing generation templates

GMF Tooling uses XPT templates to generate your diagram code. But it offers the way to use alternative template if you have to tweak directly generated code.

[edit] Set it up

See http://www.bonitasoft.org/blog/eclipse/customize-your-gmf-editor-by-customizing-templates/

[edit] Overriding templates

See http://www.bonitasoft.org/blog/eclipse/customize-your-gmf-editor-by-customizing-templates/

[edit] Using aspects

http://www.bonitasoft.org/blog/eclipse/customize-your-gmf-editor-by-customizing-templates/

[edit] Summary

In this section of the tutorial, we saw how to add a composite figure, create a custom action and layout provider contained within a new extension plug-in. In the next section, we will look at using the dashboard, and generating an RCP-based mindmap with the "lite" runtime: GMF Tutorial Part 4

[edit] Following the tutorial

[edit] References

  • GMF Tutorial Part 3 - Advanced customization