Bladeren bron

Issue statecharteditor prototype (#1740)

* first prototype of statecharteditor with separate specificationarea

* changes to show/hide behaviour

* improved expand/collapse of specificationarea.

* improved expand/collapse of specificationarea.

* removed saving of textControl width

* updated oxygen target

* Added clipboard support (workaround) for inlined definition section in StatechartDiagramEditor. changes behaviour of collapsing/expanding definition section. Added boolean flag to notationmodel (inlineDefinitionSection) to decide if the definition section should be displayed inline or attached.

* Added decorator and icon to statechart diagram controls to pin / unpin the definition section of a statechart diagram.

* fixed npe on first start when trying to pin the definition section

* Stabilized the pinning/inling feature of the definition section for statecharts in StatechartDiagramEditor. Added disabling/enabling of the pinning/inlining icon for different diagramtypes.

* removed unnecessary focusListener for the xtextControl in StatechartDiagramEditor. removed not necessary deselection for the graphical viewer of the current diagram in StatechartDiagramEditor

* changed listener handling for ImageIconlabel

* removed unused imports

* Update StatechartDiagramEditor.java

* StatechartDiagramEditor now remembers the expand/collapsed state of the definition section

* added hand cursor to the expand/collapse button for the new pinned definition section in statechartdiagrameditor

* Added hand cursor and tooltip text on hover for vertical bar of collapsed definition section

* fixed problem, where the saving into the memento lead to invalid character error for non-word-characters when the name of the statechart or state containing those characters.

* Added documentation for the usage of the new statechart diagram definition section.

* fixed typo in tooltip and correspnding documentation image

* Review the documentation somewhat. However, essential questions remain.

* added preference for enabling/disabling definition section pinning.

* Refactored StyledTextCellEditor to use verifyKeyListener with getter method
Robert Rudi 7 jaren geleden
bovenliggende
commit
7467bd775d
22 gewijzigde bestanden met toevoegingen van 1165 en 59 verwijderingen
  1. 33 2
      plugins/org.yakindu.base.xtext.utils.jface/src/org/yakindu/base/utils/jface/viewers/StyledTextCellEditor.java
  2. 9 3
      plugins/org.yakindu.base.xtext.utils.jface/src/org/yakindu/base/xtext/utils/jface/viewers/StyledTextXtextAdapter.java
  3. 38 1
      plugins/org.yakindu.sct.doc.user/src/user-guide/editing_statecharts.textile
  4. BIN
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/docu_editor_definition_section_collapse.png
  5. BIN
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/docu_editor_definition_section_expand.png
  6. BIN
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/docu_editor_definition_section_inline.png
  7. BIN
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/docu_editor_definition_section_name_edit.png
  8. BIN
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/docu_editor_definition_section_pin.png
  9. BIN
      plugins/org.yakindu.sct.ui.editor/icons/obj16/arrow_left.png
  10. BIN
      plugins/org.yakindu.sct.ui.editor/icons/obj16/arrow_right.png
  11. BIN
      plugins/org.yakindu.sct.ui.editor/icons/obj16/pin-view.gif
  12. 13 1
      plugins/org.yakindu.sct.ui.editor/plugin.xml
  13. 9 4
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/StatechartImages.java
  14. 193 0
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/decoratorprovider/DefinitionSectionDecorationProvider.java
  15. 619 7
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/editor/StatechartDiagramEditor.java
  16. 55 20
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/editparts/StatechartTextEditPart.java
  17. 13 0
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/factories/StatechartDiagramViewFactory.java
  18. 151 21
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/partitioning/DiagramPartitioningEditor.java
  19. 21 0
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/partitioning/DiagramPartitioningUtil.java
  20. 2 0
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/preferences/PreferenceInitializer.java
  21. 8 0
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/preferences/StatechartAppearancePreferencePage.java
  22. 1 0
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/preferences/StatechartPreferenceConstants.java

+ 33 - 2
plugins/org.yakindu.base.xtext.utils.jface/src/org/yakindu/base/utils/jface/viewers/StyledTextCellEditor.java

@@ -19,6 +19,7 @@ import org.eclipse.jface.viewers.CellEditor;
 import org.eclipse.jface.viewers.TextCellEditor;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.custom.VerifyKeyListener;
 import org.eclipse.swt.events.FocusAdapter;
 import org.eclipse.swt.events.FocusEvent;
 import org.eclipse.swt.events.KeyAdapter;
@@ -31,6 +32,7 @@ import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.events.TraverseEvent;
 import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.events.VerifyEvent;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Text;
@@ -61,6 +63,8 @@ public class StyledTextCellEditor extends CellEditor {
 
 	private boolean isSelectable = false;
 
+	private VerifyKeyListener verifyKeyListener;
+
 	/**
 	 * Creates a new text string cell editor with no control The cell editor
 	 * value is the string itself, which is initially the empty string.
@@ -136,8 +140,7 @@ public class StyledTextCellEditor extends CellEditor {
 		});
 		text.addTraverseListener(new TraverseListener() {
 			public void keyTraversed(TraverseEvent e) {
-				if (e.detail == SWT.TRAVERSE_ESCAPE
-						|| e.detail == SWT.TRAVERSE_RETURN) {
+				if (e.detail == SWT.TRAVERSE_ESCAPE || e.detail == SWT.TRAVERSE_RETURN) {
 					e.doit = false;
 				}
 			}
@@ -158,13 +161,41 @@ public class StyledTextCellEditor extends CellEditor {
 				StyledTextCellEditor.this.focusLost();
 			}
 		});
+
 		text.setFont(parent.getFont());
 		text.setBackground(parent.getBackground());
 		text.setText("");//$NON-NLS-1$
 		text.addModifyListener(getModifyListener());
+		text.addVerifyKeyListener(getVerifyKeyListener());
 		return text;
 	}
 
+	protected VerifyKeyListener getVerifyKeyListener() {
+		if (verifyKeyListener == null) {
+			verifyKeyListener = new VerifyKeyListener() {
+
+				@Override
+				public void verifyKey(VerifyEvent event) {
+					if (event.stateMask == SWT.CTRL) {
+						switch (event.character) {
+							case '\u0003' : // copy action
+								performCopy();
+								break;
+							case '\u0018' : // cut action
+								performCut();
+								break;
+							case '\u0001' : // selectAll action
+								performSelectAll();
+								break;
+						}
+						event.doit = true;
+					}
+				}
+			};
+		}
+		return verifyKeyListener;
+	}
+
 	/**
 	 * Hook changing creation of Control
 	 * 

+ 9 - 3
plugins/org.yakindu.base.xtext.utils.jface/src/org/yakindu/base/xtext/utils/jface/viewers/StyledTextXtextAdapter.java

@@ -103,12 +103,12 @@ public class StyledTextXtextAdapter {
 
 	private ValidationJob validationJob;
 
-
 	private StyledText styledText;
 
 	private ControlDecoration decoration;
 
 	private SourceViewerDecorationSupport decorationSupport;
+	private IWorkbenchPartSite site;
 
 	public StyledTextXtextAdapter(Injector injector, IXtextFakeContextResourcesProvider contextFakeResourceProvider) {
 		this.contextFakeResourceProvider = contextFakeResourceProvider;
@@ -122,6 +122,11 @@ public class StyledTextXtextAdapter {
 		this(injector, IXtextFakeContextResourcesProvider.NULL_CONTEXT_PROVIDER);
 	}
 
+	public StyledTextXtextAdapter(Injector inject, IWorkbenchPartSite site) {
+		this(inject);
+		this.site = site;
+	}
+
 	public void adapt(StyledText styledText) {
 		this.styledText = styledText;
 
@@ -181,8 +186,9 @@ public class StyledTextXtextAdapter {
 		// Overrides the editors selection provider to provide the text
 		// selection if opened within an editor context
 		try {
-			IWorkbenchPartSite site = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
-					.getActiveEditor().getSite();
+			if (this.site == null) {
+				site = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getSite();
+			}
 			XtextStyledTextSelectionProvider xtextStyledTextSelectionProvider = new XtextStyledTextSelectionProvider();
 			ChangeSelectionProviderOnFocusGain listener = new ChangeSelectionProviderOnFocusGain(site,
 					xtextStyledTextSelectionProvider);

+ 38 - 1
plugins/org.yakindu.sct.doc.user/src/user-guide/editing_statecharts.textile

@@ -57,7 +57,7 @@ YAKINDU Statechart Tools comes with a *statechart editor*. This section explains
 
 
 
-h3(#edit_sc_modeling_perspective). _SC Modeling_ perspective
+h3(#edit_the_sc_modeling_perspective). The _SC Modeling_ perspective
 
 _SC Modeling_ is an Eclipse perspective supporting the modeling of statecharts. The perspective defines the following views and their positions:
 * _Project Explorer_ (left): This view displays your workspace and projects, folders, and files contained therein. You can also use the _Project Explorer_ to inspect the internal structure of your statechart models.
@@ -287,6 +287,43 @@ p=. Subdiagram editor
 Using the "inlining subdiagram refactoring":#edit_inlining_subdiagram, you can turn a subdiagram back into the composite state.
 
 
+h2(#edit_using_the_definition_section). Using the definition section
+
+###. I (Rainer) don't understand why the definition section's UI must be so complicated. In the new concept, it can be in a "legacy" or in a "pinned" state, where the "pinned" state is a composite state consisting of "visible" or "hidden". Why not simply have the definition section either visible or hidden? As a user, I don't grasp this.
+
+By default, a statechart's "definition section":../user-guide/statechart_language.html#sclang_definition_section is positioned at the left-hand side of the "canvas":#edit_canvas.
+
+The definition section comes with an option to pin it to the left-hand side of the view. In order to pin the definition section you simply have to click the small decorator icon in the upper-left corner of the area.
+
+The pinned section also provides a small decorator icon in the upper-right corner, to restore the inlined state again. Please note that the inline option is not available for "subdiagrams":#edit_using_subdiagrams. The option to pin/inline makes changes to the model of the statechart diagram, so you have to save these changes to keep them.
+
+!images/docu_editor_definition_section_pin.png(Pinning the statechart diagram definition section)!
+
+p=. Pinning the statechart diagram definition section
+
+!images/docu_editor_definition_section_inline.png(Inlining the statechart diagram definition section)!
+
+p=. Inlining the statechart diagram definition section
+
+You can decide whether you want the pinned definition section's contents to be visible or not. For this, the pinned definition section comes with a small decorator icon in the upper-left corner. Click on it to collapse or expand the definition section.
+
+In the collapsed state, the definition section can also be expanded by clicking on the vertical bar labeled "Definition section". By default, the pinned definition section takes 20% of the canvas' view, but you can resize it as you like.
+
+!images/docu_editor_definition_section_collapse.png(Collapsing the pinned definition section)!
+
+p=. Collapsing the pinned definition section
+
+!images/docu_editor_definition_section_expand.png(Expanding the pinned definition section)!
+
+p=. Expanding the pinned definition section
+
+In the pinned definition section, the name of the statechart can be edited by changing the displayed text in the top-center of the section. When changing the name in the definition section within a subdiagram, the corresponding state in the parent diagram will also be updated with the new value. The value will be applied when the focus changes.
+
+!images/docu_editor_definition_section_name_edit.png(Changing the name of statechart diagram/subdiagram)!
+
+p=. Changing the name of statechart diagram/subdiagram
+
+
 
 
 h2(#edit_refactorings). Refactorings

BIN
plugins/org.yakindu.sct.doc.user/src/user-guide/images/docu_editor_definition_section_collapse.png


BIN
plugins/org.yakindu.sct.doc.user/src/user-guide/images/docu_editor_definition_section_expand.png


BIN
plugins/org.yakindu.sct.doc.user/src/user-guide/images/docu_editor_definition_section_inline.png


BIN
plugins/org.yakindu.sct.doc.user/src/user-guide/images/docu_editor_definition_section_name_edit.png


BIN
plugins/org.yakindu.sct.doc.user/src/user-guide/images/docu_editor_definition_section_pin.png


BIN
plugins/org.yakindu.sct.ui.editor/icons/obj16/arrow_left.png


BIN
plugins/org.yakindu.sct.ui.editor/icons/obj16/arrow_right.png


BIN
plugins/org.yakindu.sct.ui.editor/icons/obj16/pin-view.gif


+ 13 - 1
plugins/org.yakindu.sct.ui.editor/plugin.xml

@@ -478,7 +478,12 @@
 		<decoratorProvider class="org.yakindu.sct.ui.editor.submachine.SubmachineDecorationProvider"> 
 			<Priority name="Lowest" />
  		</decoratorProvider> 
- </extension> 
+ 	</extension> 
+ 	<extension point="org.eclipse.gmf.runtime.diagram.ui.decoratorProviders"> 
+		<decoratorProvider class="org.yakindu.sct.ui.editor.decoratorprovider.DefinitionSectionDecorationProvider"> 
+			<Priority name="Lowest" />
+ 		</decoratorProvider> 
+	 </extension>
  <extension point="org.eclipse.gmf.runtime.diagram.ui.decoratorProviders"> 
 		<decoratorProvider class="org.yakindu.sct.ui.editor.providers.TransitionPriorityDecorationProvider"> 
 			<Priority name="Lowest" />
@@ -872,4 +877,11 @@
             priority="medium">
       </factory>
    </extension>
+ <extension
+       point="org.eclipse.ui.elementFactories">
+    <factory
+          class="org.yakindu.sct.ui.editor.DiagramEditorInputFactory"
+          id="org.yakindu.sct.ui.editor.DiagramEditorInputFactory">
+    </factory>
+ </extension>
 </plugin>

+ 9 - 4
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/StatechartImages.java

@@ -23,13 +23,18 @@ public enum StatechartImages {
 	SUB_STATECHART_PICTOGRAM("icons/obj16/Statechart-Pictogram-16.png"),
 
 	LOGO("icons/obj16/logo-16.png"),
-	
+
 	PRO_LOGO("icons/obj16/logopro-16.png"),
-	
+
 	PRO_EDITION("images/pro.png"),
+
+	MENU("icons/obj16/Menu-16.png"),
+
+	EXPAND("icons/obj16/arrow_right.png"),
+
+	COLLAPSE("icons/obj16/arrow_left.png"),
 	
-	MENU("icons/obj16/Menu-16.png");
-	
+	PIN("icons/obj16/pin-view.gif");
 
 	private final String path;
 

+ 193 - 0
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/decoratorprovider/DefinitionSectionDecorationProvider.java

@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2017 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.ui.editor.decoratorprovider;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.Label;
+import org.eclipse.draw2d.LineBorder;
+import org.eclipse.draw2d.MarginBorder;
+import org.eclipse.draw2d.MouseMotionListener;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IPrimaryEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.services.decorator.Decoration;
+import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorProvider;
+import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorTarget;
+import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorTarget.Direction;
+import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorPart;
+import org.yakindu.base.gmf.runtime.decorators.AbstractDecoratorProvider;
+import org.yakindu.base.gmf.runtime.decorators.InteractiveDecorator;
+import org.yakindu.base.xtext.utils.jface.viewers.util.ActiveEditorTracker;
+import org.yakindu.sct.model.sgraph.SpecificationElement;
+import org.yakindu.sct.ui.editor.DiagramActivator;
+import org.yakindu.sct.ui.editor.StatechartImages;
+import org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor;
+import org.yakindu.sct.ui.editor.editparts.StatechartTextEditPart;
+import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil;
+import org.yakindu.sct.ui.editor.preferences.StatechartPreferenceConstants;
+import org.yakindu.sct.ui.editor.utils.GMFNotationUtil;
+
+/**
+ * 
+ * @author robert rudi - Initial contribution and API
+ * 
+ */
+public class DefinitionSectionDecorationProvider extends AbstractDecoratorProvider implements IDecoratorProvider {
+
+	protected static final String DECORATOR_KEY = DefinitionSectionDecorator.class.getSimpleName();
+
+	public void createDecorators(IDecoratorTarget decoratorTarget) {
+		Object adapter = decoratorTarget.getAdapter(EObject.class);
+		if (adapter instanceof SpecificationElement)
+			decoratorTarget.installDecorator(DECORATOR_KEY, new DefinitionSectionDecorator(decoratorTarget));
+	}
+
+	public static class DefinitionSectionDecorator extends InteractiveDecorator {
+
+		private static final Insets HIGHLIGHTING_BORDER_INSETS = new Insets(1, 1, 1, 1);
+		private static final String TOOLTIP_TEXT = "Pin statechart definition section";
+		protected static final IPreferenceStore preferenceStore = DiagramActivator.getDefault().getPreferenceStore();
+
+		public DefinitionSectionDecorator(IDecoratorTarget decoratorTarget) {
+			super(decoratorTarget);
+		}
+
+		@Override
+		protected Direction getDecoratorPosition() {
+			return IDecoratorTarget.Direction.NORTH_WEST;
+		}
+
+		@Override
+		protected Image getDecorationImage(EObject element) {
+			return StatechartImages.PIN.image();
+		}
+
+		@Override
+		protected boolean shouldDecorate(EObject element) {
+			if (preferenceStore.getBoolean(StatechartPreferenceConstants.PREF_DEFINITION_SECTION)) {
+				if (getDecoratorTarget().getAdapter(IPrimaryEditPart.class) instanceof StatechartTextEditPart) {
+					StatechartTextEditPart adapter = (StatechartTextEditPart) getDecoratorTarget()
+							.getAdapter(IPrimaryEditPart.class);
+					BooleanValueStyle style = GMFNotationUtil.getBooleanValueStyle(adapter.getNotationView(),
+							DiagramPartitioningUtil.INLINE_DEFINITION_SECTION_STYLE);
+					return style == null ? true : style.isBooleanValue();
+				}
+			}
+			return false;
+		}
+
+		@Override
+		protected Decoration createDecoration(EObject semanticElement) {
+			Decoration decoration = super.createDecoration(semanticElement);
+			installIconHighlighting(decoration, semanticElement);
+			return decoration;
+		}
+
+		protected void installIconHighlighting(Decoration decoration, final EObject semanticElement) {
+			decoration.getBounds().expand(HIGHLIGHTING_BORDER_INSETS);
+			decoration.addMouseMotionListener(new MouseMotionListener() {
+
+				@Override
+				public void mouseDragged(org.eclipse.draw2d.MouseEvent me) {
+				}
+
+				@Override
+				public void mouseEntered(org.eclipse.draw2d.MouseEvent me) {
+					decoration.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_HAND));
+					decoration.setBorder(new LineBorder(ColorConstants.lightGray));
+				}
+
+				@Override
+				public void mouseExited(org.eclipse.draw2d.MouseEvent me) {
+					decoration.setBorder(new MarginBorder(HIGHLIGHTING_BORDER_INSETS));
+				}
+
+				@Override
+				public void mouseHover(org.eclipse.draw2d.MouseEvent me) {
+				}
+
+				@Override
+				public void mouseMoved(org.eclipse.draw2d.MouseEvent me) {
+				}
+			});
+		}
+
+		@Override
+		protected void mousePressed(Decoration decoration, EObject element) {
+			if (getDecoratorTarget().getAdapter(IPrimaryEditPart.class) instanceof StatechartTextEditPart) {
+				StatechartTextEditPart editPart = (StatechartTextEditPart) getDecoratorTarget()
+						.getAdapter(IPrimaryEditPart.class);
+				Diagram diagramReference = getDiagramReference(editPart);
+				BooleanValueStyle inlineStyle = GMFNotationUtil.getBooleanValueStyle(diagramReference,
+						DiagramPartitioningUtil.INLINE_DEFINITION_SECTION_STYLE);
+				TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(diagramReference);
+				if (inlineStyle == null) {
+					inlineStyle = DiagramPartitioningUtil.createInlineDefinitionSectionStyle();
+					inlineStyle.setBooleanValue(true);
+					// add boolean value view style if no one exists
+					AddCommand command = addBooleanValueStyle(editPart, inlineStyle, domain);
+					domain.getCommandStack().execute(command);
+				}
+				// set the new value for the boolean value style
+				SetCommand command = setBooleanValueStyle(inlineStyle, domain);
+				domain.getCommandStack().execute(command);
+				editPart.refresh();
+				updateActiveEditor();
+			}
+		}
+
+		protected Diagram getDiagramReference(EditPart editPart) {
+			return ((View) editPart.getRoot().getContents().getModel()).getDiagram();
+		}
+
+		protected void updateActiveEditor() {
+			IEditorPart lastActiveEditor = ActiveEditorTracker.getLastActiveEditor();
+			if (lastActiveEditor instanceof StatechartDiagramEditor) {
+				((StatechartDiagramEditor) lastActiveEditor).toggleDefinitionSection();
+			}
+		}
+
+		protected SetCommand setBooleanValueStyle(BooleanValueStyle inlineStyle, TransactionalEditingDomain domain) {
+			SetCommand command = new SetCommand(domain, inlineStyle,
+					NotationPackage.Literals.BOOLEAN_VALUE_STYLE__BOOLEAN_VALUE, !inlineStyle.isBooleanValue());
+			return command;
+		}
+
+		protected AddCommand addBooleanValueStyle(EditPart editPart, BooleanValueStyle inlineStyle,
+				TransactionalEditingDomain domain) {
+			AddCommand command = new AddCommand(domain, getDiagramReference(editPart),
+					NotationPackage.Literals.VIEW__STYLES, inlineStyle);
+			return command;
+		}
+
+		@Override
+		protected IFigure getToolTipFigure(EObject element) {
+			return new Label(TOOLTIP_TEXT);
+		}
+
+	}
+
+}

+ 619 - 7
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/editor/StatechartDiagramEditor.java

@@ -13,14 +13,24 @@ package org.yakindu.sct.ui.editor.editor;
 import java.util.ArrayList;
 import java.util.Optional;
 
+import org.eclipse.core.databinding.UpdateValueStrategy;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.databinding.IEMFValueProperty;
+import org.eclipse.emf.databinding.edit.EMFEditProperties;
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.SetCommand;
 import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
 import org.eclipse.gef.KeyHandler;
 import org.eclipse.gef.KeyStroke;
 import org.eclipse.gef.editparts.ZoomManager;
@@ -31,32 +41,84 @@ import org.eclipse.gmf.runtime.common.ui.services.marker.MarkerNavigationService
 import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
 import org.eclipse.gmf.runtime.diagram.ui.internal.parts.DiagramGraphicalViewerKeyHandler;
 import org.eclipse.gmf.runtime.gef.ui.internal.editparts.AnimatableZoomManager;
+import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.View;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
 import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseTrackAdapter;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Canvas;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorReference;
 import org.eclipse.ui.IEditorSite;
 import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IWorkbenchPartSite;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.XMLMemento;
 import org.eclipse.ui.help.IWorkbenchHelpSystem;
 import org.eclipse.ui.ide.IGotoMarker;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
 import org.eclipse.xtext.EcoreUtil2;
 import org.eclipse.xtext.ui.XtextProjectHelper;
+import org.yakindu.base.base.BasePackage;
 import org.yakindu.base.base.DomainElement;
 import org.yakindu.base.xtext.utils.gmf.resource.DirtyStateListener;
+import org.yakindu.base.xtext.utils.jface.fieldassist.CompletionProposalAdapter;
+import org.yakindu.base.xtext.utils.jface.viewers.FilteringMenuManager;
+import org.yakindu.base.xtext.utils.jface.viewers.StyledTextXtextAdapter;
 import org.yakindu.sct.domain.extension.DomainRegistry;
 import org.yakindu.sct.domain.extension.DomainStatus;
 import org.yakindu.sct.domain.extension.DomainStatus.Severity;
 import org.yakindu.sct.domain.extension.IDomain;
+import org.yakindu.sct.model.sgraph.SGraphPackage;
+import org.yakindu.sct.model.sgraph.Statechart;
+import org.yakindu.sct.model.sgraph.util.ContextElementAdapter;
+import org.yakindu.sct.model.sgraph.util.ContextElementAdapter.IContextElementProvider;
 import org.yakindu.sct.ui.editor.DiagramActivator;
+import org.yakindu.sct.ui.editor.StatechartImages;
 import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningEditor;
 import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil;
+import org.yakindu.sct.ui.editor.preferences.StatechartPreferenceConstants;
+import org.yakindu.sct.ui.editor.propertysheets.ValidatingEMFDatabindingContext;
 import org.yakindu.sct.ui.editor.proposals.ContentProposalViewerKeyHandler;
 import org.yakindu.sct.ui.editor.providers.ISCTOutlineFactory;
 import org.yakindu.sct.ui.editor.utils.HelpContextIds;
@@ -70,18 +132,42 @@ import com.google.inject.Key;
 /**
  * @author andreas muelder - Initial contribution and API
  * @author martin esser
+ * @author robert rudi
  */
 @SuppressWarnings("restriction")
-public class StatechartDiagramEditor extends DiagramPartitioningEditor implements IGotoMarker {
+public class StatechartDiagramEditor extends DiagramPartitioningEditor implements IGotoMarker, IContextElementProvider, IPropertyChangeListener {
 
-	private static final int INITIAL_PALETTE_SIZE = 175;
 	public static final String ID = "org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor";
 
-	private KeyHandler keyHandler;
+	protected static final String ROTATED_LABEL_TEXT = "Definition section";
+	protected static final String CANNOT_INLINE_SECTION_TOOLTIP = "Cannot be inlined for subdiagrams";
+	protected static final String INLINE_SECTION_TOOLTIP = "Inline statechart definition section";
+	protected static final String EXPAND_TOOLTIP = "Show statechart definition section";
+	protected static final String COLLAPSE_TOOLTIP = "Hide statechart definition section";
+	protected final Image EXPAND_IMAGE = StatechartImages.EXPAND.image();
+	protected final Image COLLAPSE_IMAGE = StatechartImages.COLLAPSE.image();
+
+	protected static final int TEXT_CONTROL_HORIZONTAL_MARGIN = 10;
+	protected static final int INITIAL_PALETTE_SIZE = 175;
+	protected static final int[] MIN_CONTROL_SIZE = {11, 21};
+	protected static final int BORDERWIDTH = 2;
+	protected static boolean imageLabelHasFocus = false;
+	protected int[] previousWidths = DEFAULT_WEIGHTS;
 
+	private KeyHandler keyHandler;
 	private DirtyStateListener domainAdapter;
 	private LiveValidationListener validationListener;
 	private IValidationIssueStore issueStore;
+	private SwitchListener switchListener;
+	private ResizeListener resizeListener;
+	private boolean isDefinitionSectionExpanded = true;
+
+	private ImageLabelMouseListener imageLabelMouseListener;
+	private ImageLabelMouseTrackListener imageLabelMouseTrackListener;
+	private ImageLabelPaintListener imageLabelPaintListener;
+
+	private StyledText xtextControl;
+	private Button switchControl;
 
 	public StatechartDiagramEditor() {
 		super(true);
@@ -103,7 +189,7 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 			return domainStatus;
 		}
 		return null;
-	};
+	}
 
 	@Override
 	protected void createBreadcrumbViewer(Composite parent) {
@@ -136,6 +222,11 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 		super.init(site, input);
 		checkXtextNature();
 		registerValidationListener();
+		registerPropertyChangeListener();
+	}
+
+	protected void registerPropertyChangeListener() {
+		DiagramActivator.getDefault().getPreferenceStore().addPropertyChangeListener(this);
 	}
 
 	protected void registerValidationListener() {
@@ -150,8 +241,7 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 	protected IValidationIssueStore getIssueStore() {
 		Optional<IEditorPart> editorWithSameResource = getEditorWithSameResource();
 		if (editorWithSameResource.isPresent()) {
-			IValidationIssueStore sharedStore = editorWithSameResource.get()
-					.getAdapter(IValidationIssueStore.class);
+			IValidationIssueStore sharedStore = editorWithSameResource.get().getAdapter(IValidationIssueStore.class);
 			return sharedStore;
 		} else {
 			IValidationIssueStore newStore = getEditorInjector().getInstance(IValidationIssueStore.class);
@@ -185,6 +275,11 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 		return injector;
 	}
 
+	protected Injector getEmbeddedStatechartSpecificationInjector() {
+		IDomain domain = DomainRegistry.getDomain(getDiagram().getElement());
+		return domain.getInjector(IDomain.FEATURE_EDITOR, Statechart.class.getName());
+	}
+
 	protected void checkXtextNature() {
 		IFileEditorInput editorInput = (IFileEditorInput) getEditorInput();
 		IProject project = editorInput.getFile().getProject();
@@ -230,7 +325,6 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 		super.createGraphicalViewer(parent);
 		IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem();
 		helpSystem.setHelp(getGraphicalViewer().getControl(), HelpContextIds.SC_EDITOR_GRAPHICAL_VIEWER);
-
 	}
 
 	@Override
@@ -238,6 +332,7 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 		super.configureGraphicalViewer();
 		disableAnimatedZoom();
 		createContentProposalViewerKeyHandler();
+		super.constructPaletteViewer();
 	}
 
 	// Disable the animated zoom, it is too slow for bigger models
@@ -326,8 +421,16 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 		return ID;
 	}
 
+	@Override
+	public String getFactoryId() {
+		return getEditorInput().getPersistable().getFactoryId();
+	}
+
 	@Override
 	public void dispose() {
+		saveState(getMemento());
+		
+		removepropertyChangeListener();
 		if (validationListener != null) {
 			validationListener.dispose();
 		}
@@ -338,9 +441,42 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 		getEditingDomain().removeResourceSetListener(domainAdapter);
 		if (domainAdapter != null)
 			domainAdapter.dispose();
+
+		disposeDefinitionSectionControls();
+
 		super.dispose();
 	}
 
+	protected void removepropertyChangeListener() {
+		DiagramActivator.getDefault().getPreferenceStore().removePropertyChangeListener(this);
+	}
+
+	protected void disposeDefinitionSectionControls() {
+		if (switchListener != null && switchControl != null && !switchControl.isDisposed())
+			switchControl.removeSelectionListener(switchListener);
+
+		if (resizeListener != null && getSash() != null && !getSash().isDisposed())
+			getSash().removeControlListener(resizeListener);
+
+		if (resizeListener != null && xtextControl != null && !xtextControl.isDisposed())
+			xtextControl.removeControlListener(resizeListener);
+
+		if (xtextControl != null && !xtextControl.isDisposed()) {
+			xtextControl.dispose();
+			xtextControl = null;
+		}
+
+		if (switchControl != null && !switchControl.isDisposed()) {
+			switchControl.dispose();
+			switchControl = null;
+		}
+
+		switchListener = null;
+		resizeListener = null;
+		imageLabelMouseListener = null;
+		imageLabelMouseTrackListener = null;
+		imageLabelPaintListener = null;
+	}
 
 	@Override
 	protected int getInitialPaletteSize() {
@@ -353,7 +489,483 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 			return createOutline(type);
 		} else if (IValidationIssueStore.class.equals(type)) {
 			return issueStore;
+		} else if (DiagramPartitioningEditor.class.equals(type)) {
+			return super.getAdapter(type);
 		}
 		return super.getAdapter(type);
 	}
+
+	@Override
+	protected void createTextEditor(Composite parent) {
+		Composite definitionSection = new Composite(parent, SWT.BORDER);
+		GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(definitionSection);
+
+		switchControl = createExpandControl(definitionSection);
+		createDefinitionSectionLabels(definitionSection);
+		xtextControl = createXtextControl(definitionSection);
+
+		switchListener = new SwitchListener(parent);
+		resizeListener = new ResizeListener(parent, definitionSection);
+
+		parent.addControlListener(resizeListener);
+		switchControl.addSelectionListener(switchListener);
+		xtextControl.addControlListener(resizeListener);
+	}
+
+	/*
+	 * Need hook into part creation lifecycle because the Xtext controls depends on
+	 * the selection provider of IWorkbenchPartSite, so the Xtext enabling cannot be
+	 * done before or while the part is created.
+	 * 
+	 * @see org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningEditor#
+	 * createPartControl(org.eclipse.swt.widgets.Composite)
+	 */
+	@Override
+	public void createPartControl(Composite parent) {
+		super.createPartControl(parent);
+		toggleDefinitionSection();
+		restoreSashWidths(getSash(), getMemento());
+		enableXtext(xtextControl);
+		reloadFromPreferences();
+	}
+
+	protected void reloadFromPreferences() {
+		boolean pinningActivated = DiagramActivator.getDefault().getPreferenceStore()
+				.getBoolean(StatechartPreferenceConstants.PREF_DEFINITION_SECTION);
+		if (!isDefinitionSectionInlined() && !pinningActivated) {
+			// set the new value for the boolean value style
+			TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(getDiagram());
+			BooleanValueStyle inlineStyle = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(getDiagram());
+
+			SetCommand command = setBooleanValueStyle(inlineStyle, domain);
+			domain.getCommandStack().execute(command);
+
+			toggleDefinitionSection();
+			refreshDiagramEditPartChildren();
+		}
+	}
+
+	protected void enableXtext(StyledText xtextControl) {
+		final StyledTextXtextAdapter xtextAdapter = new StyledTextXtextAdapter(
+				getEmbeddedStatechartSpecificationInjector(), getSite());
+		xtextAdapter.getFakeResourceContext().getFakeResource().eAdapters().add(new ContextElementAdapter(this));
+		xtextAdapter.adapt((StyledText) xtextControl);
+		initContextMenu(xtextControl);
+		CompletionProposalAdapter adapter = new CompletionProposalAdapter(xtextControl,
+				xtextAdapter.getContentAssistant(),
+				org.eclipse.jface.bindings.keys.KeyStroke.getInstance(SWT.CTRL, SWT.SPACE), null);
+		IEMFValueProperty modelProperty = EMFEditProperties.value(getEditingDomain(),
+				SGraphPackage.Literals.SPECIFICATION_ELEMENT__SPECIFICATION);
+
+		ISWTObservableValue uiProperty = WidgetProperties.text(new int[]{SWT.FocusOut, SWT.Modify})
+				.observe(xtextControl);
+		ValidatingEMFDatabindingContext context = new ValidatingEMFDatabindingContext(this, getSite().getShell());
+		context.bindValue(uiProperty, modelProperty.observe(
+				EcoreUtil.getObjectByType(getDiagram().eResource().getContents(), SGraphPackage.Literals.STATECHART)),
+				null, new UpdateValueStrategy() {
+					@Override
+					protected IStatus doSet(IObservableValue observableValue, Object value) {
+						if (adapter != null && !adapter.isProposalPopupOpen())
+							return super.doSet(observableValue, value);
+						return Status.OK_STATUS;
+					}
+				});
+	}
+
+	protected StyledText createXtextControl(Composite definitionSection) {
+		StyledText textControl = new StyledText(definitionSection, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP);
+		GridDataFactory.fillDefaults().grab(true, true).indent(TEXT_CONTROL_HORIZONTAL_MARGIN, 0).applyTo(textControl);
+		textControl.setAlwaysShowScrollBars(false);
+		textControl.setBackground(ColorConstants.white);
+		textControl.addKeyListener(new KeyListener() {
+
+			@Override
+			public void keyReleased(KeyEvent e) {
+				if (e.stateMask == SWT.CTRL && e.keyCode == 'a') {
+					textControl.selectAll();
+				}
+			}
+
+			@Override
+			public void keyPressed(KeyEvent e) {
+			}
+		});
+		return textControl;
+	}
+
+	protected Composite createDefinitionSectionLabels(Composite definitionSection) {
+		Composite labelComposite = new Composite(definitionSection, SWT.NONE);
+		GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(labelComposite);
+		GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(labelComposite);
+		createDefinitionSectionNameLabel(labelComposite);
+		createDefinitionSectionImageLabel(labelComposite);
+		createSeparator(definitionSection);
+		createRotatedLabel(definitionSection);
+		return labelComposite;
+	}
+
+	protected void createDefinitionSectionImageLabel(Composite labelComposite) {
+		Label statechartImageLabel = new Label(labelComposite, SWT.FILL);
+		statechartImageLabel.setImage(StatechartImages.PIN.image());
+		statechartImageLabel.setToolTipText(INLINE_SECTION_TOOLTIP);
+		statechartImageLabel.setEnabled(getContextObject() instanceof Statechart);
+		labelComposite.setToolTipText(getTooltipText());
+		GridDataFactory.fillDefaults().applyTo(statechartImageLabel);
+		imageLabelMouseListener = new ImageLabelMouseListener();
+		imageLabelMouseTrackListener = new ImageLabelMouseTrackListener(statechartImageLabel);
+		imageLabelPaintListener = new ImageLabelPaintListener(statechartImageLabel);
+		statechartImageLabel.addMouseListener(imageLabelMouseListener);
+		statechartImageLabel.addMouseTrackListener(imageLabelMouseTrackListener);
+		statechartImageLabel.addPaintListener(imageLabelPaintListener);
+	}
+
+	protected String getTooltipText() {
+		return (getContextObject() instanceof Statechart) ? INLINE_SECTION_TOOLTIP : CANNOT_INLINE_SECTION_TOOLTIP;
+	}
+
+	protected SetCommand setBooleanValueStyle(BooleanValueStyle inlineStyle, TransactionalEditingDomain domain) {
+		SetCommand command = new SetCommand(domain, inlineStyle,
+				NotationPackage.Literals.BOOLEAN_VALUE_STYLE__BOOLEAN_VALUE, !inlineStyle.isBooleanValue());
+		return command;
+	}
+
+	protected AddCommand addBooleanValueStyle(View view, BooleanValueStyle inlineStyle,
+			TransactionalEditingDomain domain) {
+		AddCommand command = new AddCommand(domain, view, NotationPackage.Literals.VIEW__STYLES, inlineStyle);
+		return command;
+	}
+
+	protected void createDefinitionSectionNameLabel(Composite labelComposite) {
+		Text statechartNameLabel = new Text(labelComposite, SWT.SINGLE | SWT.NORMAL);
+		GridDataFactory.fillDefaults().indent(5, 1).grab(true, false).align(SWT.FILL, SWT.CENTER)
+				.applyTo(statechartNameLabel);
+		statechartNameLabel.setText(this.getTitle());
+		statechartNameLabel.addModifyListener(new ModifyListener() {
+
+			@Override
+			public void modifyText(ModifyEvent e) {
+				statechartNameLabel.update();
+				statechartNameLabel.redraw();
+				statechartNameLabel.getParent().layout();
+			}
+		});
+
+		observeStatechartName(statechartNameLabel);
+	}
+
+	protected void observeStatechartName(Text statechartNameLabel) {
+		ValidatingEMFDatabindingContext context = new ValidatingEMFDatabindingContext(this, this.getSite().getShell());
+		IEMFValueProperty property = EMFEditProperties.value(TransactionUtil.getEditingDomain(getContextObject()),
+				BasePackage.Literals.NAMED_ELEMENT__NAME);
+		ISWTObservableValue observe = WidgetProperties.text(new int[]{SWT.FocusOut, SWT.DefaultSelection})
+				.observe(statechartNameLabel);
+		context.bindValue(observe, property.observe(this.getContextObject()));
+	}
+
+	protected void createSeparator(Composite definitionSection) {
+		Label separator = new Label(definitionSection, SWT.SEPARATOR | SWT.HORIZONTAL);
+		GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(separator);
+	}
+
+	protected void createRotatedLabel(Composite definitionSection) {
+		RotatedLabel rotatedLabel = new RotatedLabel(definitionSection, SWT.NONE);
+		rotatedLabel.setText(ROTATED_LABEL_TEXT, new Font(Display.getDefault(), "Segoe UI", 8, SWT.NORMAL));
+		rotatedLabel.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseUp(MouseEvent e) {
+				if (!isDefinitionSectionExpanded)
+					switchListener.handleSelection();
+			}
+		});
+		rotatedLabel.addMouseTrackListener(new MouseTrackAdapter() {
+			@Override
+			public void mouseEnter(MouseEvent e) {
+				rotatedLabel.setCursor(new Cursor(Display.getDefault(),
+						(!isDefinitionSectionExpanded) ? SWT.CURSOR_HAND : SWT.CURSOR_ARROW));
+				rotatedLabel.setToolTipText((!isDefinitionSectionExpanded) ? EXPAND_TOOLTIP : null);
+			}
+		});
+		GridDataFactory.fillDefaults().grab(false, false)
+				.hint(MIN_CONTROL_SIZE[0], definitionSection.getBounds().height).applyTo(rotatedLabel);
+	}
+
+	protected Button createExpandControl(Composite definitionSection) {
+		Button expandButton = new Button(definitionSection, SWT.PUSH | SWT.BORDER_SOLID);
+		expandButton.setToolTipText(COLLAPSE_TOOLTIP);
+		expandButton.setImage(
+				isDefinitionSectionExpanded ? StatechartImages.COLLAPSE.image() : StatechartImages.EXPAND.image());
+		expandButton.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_HAND));
+		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).indent(-1, 0)
+				.hint(MIN_CONTROL_SIZE[0], MIN_CONTROL_SIZE[1]).applyTo(expandButton);
+		return expandButton;
+	}
+
+	@Override
+	public EObject getContextObject() {
+		return getDiagram().getElement();
+	}
+
+	protected void initContextMenu(Control control) {
+		MenuManager menuManager = new FilteringMenuManager();
+		Menu contextMenu = menuManager.createContextMenu(control);
+		control.setMenu(contextMenu);
+		IWorkbenchPartSite site = getSite();
+		if (site != null)
+			site.registerContextMenu("org.yakindu.base.xtext.utils.jface.viewers.StyledTextXtextAdapterContextMenu",
+					menuManager, site.getSelectionProvider());
+	}
+
+	protected void collapseDefinitionSection(Composite parent) {
+		int width = parent.getBounds().width;
+		((SashForm) parent).setWeights(new int[]{switchControl.getBounds().width + BORDERWIDTH, width});
+		updateSwitchControl(EXPAND_TOOLTIP, EXPAND_IMAGE);
+	}
+
+	protected void expandDefinitionSection(Composite parent) {
+		((SashForm) parent).setWeights(previousWidths);
+		updateSwitchControl(COLLAPSE_TOOLTIP, COLLAPSE_IMAGE);
+	}
+
+	/**
+	 * Updates the tooltip text and the image for the prominent switchControl.
+	 * 
+	 * @param tooltipText
+	 *            The tooltip text for the switchControl
+	 * @param image
+	 *            The image for the controls
+	 */
+	protected void updateSwitchControl(String tooltipText, Image image) {
+		switchControl.setToolTipText(tooltipText);
+		switchControl.setImage(image);
+	}
+
+	protected class ImageLabelMouseListener extends MouseAdapter {
+
+		@Override
+		public void mouseUp(MouseEvent e) {
+			TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(getDiagram());
+			BooleanValueStyle inlineStyle = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(getDiagram());
+			if (inlineStyle == null) {
+				inlineStyle = DiagramPartitioningUtil.createInlineDefinitionSectionStyle();
+				AddCommand command = addBooleanValueStyle(getDiagram(), inlineStyle, domain);
+				domain.getCommandStack().execute(command);
+			}
+			// set the new value for the boolean value style
+			SetCommand command = setBooleanValueStyle(inlineStyle, domain);
+			domain.getCommandStack().execute(command);
+
+			toggleDefinitionSection();
+			refreshDiagramEditPartChildren();
+		}
+
+	}
+
+	protected class ImageLabelMouseTrackListener extends MouseTrackAdapter {
+		private final Label statechartImageLabel;
+		protected ImageLabelMouseTrackListener(Label statechartImageLabel) {
+			this.statechartImageLabel = statechartImageLabel;
+		}
+		@Override
+		public void mouseEnter(MouseEvent e) {
+			statechartImageLabel.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_HAND));
+			imageLabelHasFocus = true;
+			statechartImageLabel.redraw();
+		}
+		@Override
+		public void mouseExit(MouseEvent e) {
+			imageLabelHasFocus = false;
+			statechartImageLabel.redraw();
+		}
+
+	}
+
+	protected class ImageLabelPaintListener implements PaintListener {
+		private final Label statechartImageLabel;
+
+		protected ImageLabelPaintListener(Label statechartImageLabel) {
+			this.statechartImageLabel = statechartImageLabel;
+		}
+
+		@Override
+		public void paintControl(PaintEvent e) {
+			if (imageLabelHasFocus) {
+				drawIconBorder(statechartImageLabel, e.gc);
+			}
+		}
+		protected void drawIconBorder(Label statechartImageLabel, GC gc) {
+			Rectangle rect = new Rectangle(0, 0, statechartImageLabel.getBounds().width - 1,
+					statechartImageLabel.getBounds().height - 1);
+			Transform t = new Transform(Display.getDefault());
+			gc.setTransform(t);
+			gc.setForeground(ColorConstants.lightGray);
+			gc.drawRectangle(0, 0, rect.width, rect.height);
+		}
+
+	}
+
+	/**
+	 * @author robert rudi - Initial contribution and API
+	 * 
+	 */
+	protected class ResizeListener extends ControlAdapter {
+
+		private final Composite parent;
+		private final Composite definitionSection;
+
+		protected ResizeListener(Composite parent, Composite definitionSection) {
+			this.parent = parent;
+			this.definitionSection = definitionSection;
+		}
+
+		@Override
+		public void controlResized(ControlEvent e) {
+			handleControlChanged();
+		}
+
+		@Override
+		public void controlMoved(ControlEvent e) {
+			handleControlChanged();
+		}
+
+		protected void handleControlChanged() {
+			if (isDefinitionSectionExpanded) {
+				previousWidths = ((SashForm) parent).getWeights();
+			} else {
+				if (definitionSection.getBounds().width != switchControl.getBounds().width) {
+					collapseDefinitionSection(parent);
+				}
+			}
+		}
+	}
+
+	/**
+	 * @author robert rudi - Initial contribution and API
+	 * 
+	 */
+	protected class SwitchListener extends SelectionAdapter {
+
+		protected final Composite parent;
+
+		protected SwitchListener(Composite parent) {
+			this.parent = parent;
+		}
+
+		@Override
+		public void widgetSelected(SelectionEvent e) {
+			handleSelection();
+		}
+
+		protected void handleSelection() {
+			parent.setRedraw(false);
+			xtextControl.setVisible(!xtextControl.isVisible());
+			isDefinitionSectionExpanded = !isDefinitionSectionExpanded;
+			if (xtextControl.isVisible()) {
+				expandDefinitionSection(parent);
+			} else {
+				if (isDefinitionSectionExpanded) {
+					// needed to restore previous widths of sashcontrols if definition section is
+					// collapsed and editor has been reopened
+					xtextControl.setVisible(!xtextControl.isVisible());
+					expandDefinitionSection(parent);
+				} else {
+					collapseDefinitionSection(parent);
+				}
+			}
+			parent.setRedraw(true);
+		}
+	}
+
+	@Override
+	protected boolean isDefinitionSectionInlined() {
+		BooleanValueStyle style = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(getDiagram());
+		return style != null ? style.isBooleanValue() : true;
+	}
+
+	/**
+	 * @author robert rudi - Initial contribution and API
+	 * 
+	 */
+	protected class RotatedLabel extends Canvas {
+
+		private String text;
+		float rotatingAngle = -90f;
+
+		public RotatedLabel(Composite parent, int style) {
+			super(parent, style);
+
+			this.addPaintListener(new PaintListener() {
+				public void paintControl(PaintEvent e) {
+					paint(e);
+				}
+			});
+			this.addListener(SWT.MouseDown, new Listener() {
+
+				@Override
+				public void handleEvent(Event event) {
+					if (switchListener != null && !isDefinitionSectionExpanded)
+						switchListener.handleSelection();
+				}
+			});
+		}
+
+		public void setText(String string, Font font) {
+			this.text = string;
+			setFont(font);
+			redraw();
+			update();
+		}
+
+		public void setText(String string) {
+			this.text = string;
+			redraw();
+			update();
+		}
+
+		public void paint(PaintEvent e) {
+			Transform tr = null;
+			tr = new Transform(e.display);
+			int w = e.width;
+			int h = e.height;
+			tr.translate(w / 2, h / 3);
+			tr.rotate(rotatingAngle);
+			e.gc.setTransform(tr);
+			int drawHeight = -((w / 3) * 2);
+			e.gc.drawString(isDefinitionSectionExpanded ? "" : text, 0,
+					(drawHeight % 2) != 0 ? drawHeight - 1 : drawHeight);
+		}
+
+	}
+
+	@Override
+	public void saveState(IMemento memento) {
+		if (memento == null) {
+			memento = XMLMemento.createWriteRoot(getFactoryId());
+		}
+
+		memento.putInteger(FIRST_SASH_CONTROL_WEIGHT, previousWidths[0]);
+		memento.putInteger(SECOND_SASH_CONTROL_WEIGHT, previousWidths[1]);
+		rememberExpandState(memento);
+
+		super.setMemento(memento);
+	}
+
+	@Override
+	public void restoreState(IMemento memento) {
+		if (getSash() != null && memento != null && memento.getInteger(FIRST_SASH_CONTROL_WEIGHT) != null
+				&& memento.getInteger(SECOND_SASH_CONTROL_WEIGHT) != null) {
+			getSash().setWeights(new int[]{memento.getInteger(FIRST_SASH_CONTROL_WEIGHT),
+					memento.getInteger(SECOND_SASH_CONTROL_WEIGHT)});
+			previousWidths = getSash().getWeights();
+			isDefinitionSectionExpanded = getExpandState(memento);
+		}
+		super.setMemento(memento);
+	}
+
+	@Override
+	public void propertyChange(PropertyChangeEvent event) {
+		if(StatechartPreferenceConstants.PREF_DEFINITION_SECTION.equals(event.getProperty())) {
+			reloadFromPreferences();
+		}
+	}
+
 }

+ 55 - 20
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/editparts/StatechartTextEditPart.java

@@ -22,9 +22,15 @@ import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles;
 import org.eclipse.gmf.runtime.diagram.ui.editpolicies.SemanticEditPolicy;
 import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyRequest;
 import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure;
+import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
 import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.yakindu.sct.ui.editor.DiagramActivator;
 import org.yakindu.sct.ui.editor.editor.figures.StatechartTextFigure;
+import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil;
 import org.yakindu.sct.ui.editor.policies.PreferredSizeHandlerEditPolicy;
+import org.yakindu.sct.ui.editor.preferences.StatechartPreferenceConstants;
 import org.yakindu.sct.ui.editor.providers.SemanticHints;
 
 /**
@@ -32,8 +38,7 @@ import org.yakindu.sct.ui.editor.providers.SemanticHints;
  * @author andreas muelder - Initial contribution and API
  * 
  */
-public class StatechartTextEditPart extends ShapeNodeEditPart implements
-		IPrimaryEditPart {
+public class StatechartTextEditPart extends ShapeNodeEditPart implements IPrimaryEditPart, IPropertyChangeListener {
 
 	public StatechartTextEditPart(View view) {
 		super(view);
@@ -48,44 +53,51 @@ public class StatechartTextEditPart extends ShapeNodeEditPart implements
 		return figure;
 	}
 
+	@Override
+	public void activate() {
+		super.activate();
+		DiagramActivator.getDefault().getPreferenceStore().addPropertyChangeListener(this);
+	}
+
+	@Override
+	public void deactivate() {
+		super.deactivate();
+		DiagramActivator.getDefault().getPreferenceStore().removePropertyChangeListener(this);
+	}
+
 	@Override
 	protected void createDefaultEditPolicies() {
 		super.createDefaultEditPolicies();
 
 		// Disables deletion of the text compartment view if additional elements
 		// are selected too
-		installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE,
-				new SemanticEditPolicy() {
-					@Override
-					protected boolean shouldProceed(
-							DestroyRequest destroyRequest) {
-						return false;
-					}
-				});
+		installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new SemanticEditPolicy() {
+			@Override
+			protected boolean shouldProceed(DestroyRequest destroyRequest) {
+				return false;
+			}
+		});
 
 		// Disables deletion of the text compartment view via keyboard
-		installEditPolicy(EditPolicy.COMPONENT_ROLE,
-				new RootComponentEditPolicy());
+		installEditPolicy(EditPolicy.COMPONENT_ROLE, new RootComponentEditPolicy());
 		removeEditPolicy(EditPolicyRoles.CONNECTION_HANDLES_ROLE);
-		installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE,
-				new PreferredSizeHandlerEditPolicy(){
+		installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, new PreferredSizeHandlerEditPolicy() {
 			@Override
 			protected IFigure getPreferredSizeFigure() {
 				return getChildBySemanticHint(SemanticHints.STATECHART_NAME).getFigure();
 			}
+
 		});
 	}
 
 	@Override
 	protected void addChildVisual(EditPart childEditPart, int index) {
 		if (childEditPart instanceof StatechartNameEditPart) {
-			((StatechartNameEditPart) childEditPart).setLabel(getPrimaryShape()
-					.getName());
+			((StatechartNameEditPart) childEditPart).setLabel(getPrimaryShape().getName());
 		} else if (childEditPart instanceof StatechartTextExpressionEditPart) {
 			IFigure pane = getPrimaryShape().getCompartment();
 			pane.setLayoutManager(new StackLayout());
-			IFigure compartmentFigure = ((StatechartTextExpressionEditPart) childEditPart)
-					.getFigure();
+			IFigure compartmentFigure = ((StatechartTextExpressionEditPart) childEditPart).getFigure();
 			pane.add(compartmentFigure);
 		} else
 			super.addChildVisual(childEditPart, index);
@@ -95,14 +107,37 @@ public class StatechartTextEditPart extends ShapeNodeEditPart implements
 	protected void removeChildVisual(EditPart childEditPart) {
 		if (childEditPart instanceof StatechartTextExpressionEditPart) {
 			IFigure pane = getPrimaryShape().getCompartment();
-			IFigure compartmentFigure = ((StatechartTextExpressionEditPart) childEditPart)
-					.getFigure();
+			IFigure compartmentFigure = ((StatechartTextExpressionEditPart) childEditPart).getFigure();
 			pane.remove(compartmentFigure);
 		} else
 			super.removeChildVisual(childEditPart);
 	}
 
+	@Override
+	protected void refreshVisibility() {
+		setVisibility(isDefinitionSectionInlined());
+	}
+
+	@Override
+	public void refresh() {
+		refreshVisibility();
+		super.refresh();
+	}
+
+	protected boolean isDefinitionSectionInlined() {
+		BooleanValueStyle style = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(getDiagramView());
+		return style != null ? style.isBooleanValue() : true;
+	}
+
 	private StatechartTextFigure getPrimaryShape() {
 		return (StatechartTextFigure) getFigure().getChildren().get(0);
 	}
+
+	@Override
+	public void propertyChange(PropertyChangeEvent event) {
+		if (StatechartPreferenceConstants.PREF_DEFINITION_SECTION.equals(event.getProperty())) {
+			refresh();
+		}
+
+	}
 }

+ 13 - 0
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/factories/StatechartDiagramViewFactory.java

@@ -10,8 +10,13 @@
  */
 package org.yakindu.sct.ui.editor.factories;
 
+import java.util.List;
+
 import org.eclipse.gmf.runtime.diagram.ui.view.factories.DiagramViewFactory;
+import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
 import org.eclipse.gmf.runtime.notation.MeasurementUnit;
+import org.eclipse.gmf.runtime.notation.View;
+import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil;
 
 /**
  * 
@@ -24,4 +29,12 @@ public class StatechartDiagramViewFactory extends DiagramViewFactory {
 	protected MeasurementUnit getMeasurementUnit() {
 		return MeasurementUnit.PIXEL_LITERAL;
 	}
+
+	@SuppressWarnings({"rawtypes", "unchecked"})
+	@Override
+	protected List createStyles(View view) {
+		BooleanValueStyle inlineDefinitionSectionStyle = DiagramPartitioningUtil.createInlineDefinitionSectionStyle();
+		view.getStyles().add(inlineDefinitionSectionStyle);
+		return super.createStyles(view);
+	}
 }

+ 151 - 21
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/partitioning/DiagramPartitioningEditor.java

@@ -17,11 +17,13 @@ import java.util.Collection;
 import java.util.List;
 
 import org.eclipse.core.resources.IFile;
+import org.eclipse.draw2d.ColorConstants;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.edit.domain.IEditingDomainProvider;
 import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
 import org.eclipse.emf.transaction.TransactionalEditingDomain;
 import org.eclipse.gef.ContextMenuProvider;
+import org.eclipse.gef.EditPart;
 import org.eclipse.gef.EditPartViewer;
 import org.eclipse.gef.GraphicalViewer;
 import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
@@ -44,15 +46,20 @@ import org.eclipse.jface.viewers.TreePath;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerLabel;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorReference;
 import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistableEditor;
+import org.eclipse.ui.IPersistableElement;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.XMLMemento;
 import org.eclipse.ui.ide.FileStoreEditorInput;
 import org.eclipse.xtext.util.Arrays;
 import org.yakindu.base.base.NamedElement;
@@ -65,14 +72,31 @@ import org.yakindu.sct.ui.editor.StatechartImages;
  * {@link DiagramPartitioningBreadcrumbViewer} to the top.
  * 
  * @author andreas muelder - Initial contribution and API
+ * @author robert rudi - added pinnable sash form for new diagrams
  * 
  */
-public abstract class DiagramPartitioningEditor extends DiagramDocumentEditor implements ISelectionChangedListener,
-		IEditingDomainProvider {
+public abstract class DiagramPartitioningEditor extends DiagramDocumentEditor
+		implements
+			ISelectionChangedListener,
+			IEditingDomainProvider,
+			IPersistableEditor,
+			IPersistableElement {
+
+	private static final String REGEX_NO_WORD_NO_WHITESPACE = "[^\\w[\\s+_]]";
+	protected static final String IS_DEFINITION_SECTION_EXPANDED = "DefinitionSectionIsExpanded";
+	protected static final String FIRST_SASH_CONTROL_WEIGHT = "FirstSashControlWeight";
+	protected static final String SECOND_SASH_CONTROL_WEIGHT = "SecondSashControlWeight";
+	protected static final int[] DEFAULT_WEIGHTS = new int[]{2, 10};
+	protected static final int MAXIMIZED_CONTROL_INDEX = 1;
 
 	private DiagramPartitioningBreadcrumbViewer viewer;
 
 	private DiagramPartitioningDocumentProvider documentProvider;
+	private SashForm sash;
+
+	private static IMemento memento;
+
+	protected abstract void createTextEditor(Composite parent);
 
 	public DiagramPartitioningEditor(boolean hasFlyoutPalette) {
 		super(hasFlyoutPalette);
@@ -88,24 +112,116 @@ public abstract class DiagramPartitioningEditor extends DiagramDocumentEditor im
 	public IDocumentProvider getDocumentProvider() {
 		return documentProvider;
 	}
-	
+
 	@Override
 	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
-		if(input instanceof FileStoreEditorInput) {
-			throw new PartInitException(
-					"An error occured while opening the file.\n\n"
+		if (input instanceof FileStoreEditorInput) {
+			throw new PartInitException("An error occured while opening the file.\n\n"
 					+ "This might have happened because you tried to open a statechart with File->Open File.\n"
-            		+ "This is not supported. Please import the file into a project instead."
-	            		);
+					+ "This is not supported. Please import the file into a project instead.");
 		}
 		super.init(site, input);
 	}
 
+	@SuppressWarnings("rawtypes")
+	@Override
+	public Object getAdapter(Class type) {
+		if (DiagramPartitioningEditor.class.equals(type)) {
+			return this;
+		}
+		return super.getAdapter(type);
+	}
+
 	@Override
 	public void createPartControl(Composite parent) {
 		GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(parent);
 		createBreadcrumbViewer(parent);
-		super.createPartControl(parent);
+		sash = (SashForm) createParentSash(parent);
+		createTextEditor(sash);
+		super.createPartControl(sash);
+	}
+
+	public void toggleDefinitionSection() {
+		if (getContextObject() instanceof Statechart)
+			sash.setMaximizedControl(
+					!isDefinitionSectionInlined() ? null : sash.getChildren()[MAXIMIZED_CONTROL_INDEX]);
+	}
+
+	protected abstract EObject getContextObject();
+
+	public void restoreSashWidths(SashForm sash, IMemento memento) {
+		if (memento == null) {
+			setDefaultSashWeights(sash);
+			memento = XMLMemento.createWriteRoot(getFactoryId());
+			memento.putInteger(FIRST_SASH_CONTROL_WEIGHT, DEFAULT_WEIGHTS[0]);
+			memento.putInteger(SECOND_SASH_CONTROL_WEIGHT, DEFAULT_WEIGHTS[1]);
+			rememberExpandState(memento);
+			setMemento(memento);
+		} else {
+			restoreState(memento);
+		}
+	}
+
+	protected void rememberExpandState(IMemento memento) {
+		if (getContextObject() != null) {
+			if (getContextObject() instanceof NamedElement) {
+				NamedElement element = (NamedElement) getContextObject();
+				if (element != null)
+					memento.putBoolean(stripElementName(element.getName()) + IS_DEFINITION_SECTION_EXPANDED, true);
+			}
+		}
+	}
+
+	protected boolean getExpandState(IMemento memento) {
+		Object expandState = null;
+		if (getContextObject() instanceof NamedElement) {
+			NamedElement element = (NamedElement) getContextObject();
+			if (element != null)
+				expandState = memento.getBoolean(stripElementName(element.getName()) + IS_DEFINITION_SECTION_EXPANDED);
+		}
+		return expandState != null ? ((Boolean) expandState).booleanValue() : true;
+	}
+
+	protected String stripElementName(String name) {
+		if (name != null)
+			return name.replaceAll(REGEX_NO_WORD_NO_WHITESPACE, "");
+		return "";
+	}
+
+	public SashForm getSash() {
+		return sash;
+	}
+
+	protected void setDefaultSashWeights(SashForm sash) {
+		sash.setWeights(DEFAULT_WEIGHTS);
+	}
+
+	@Override
+	public abstract void restoreState(IMemento memento);
+
+	@Override
+	public abstract void saveState(IMemento memento);
+
+	public IMemento getMemento() {
+		return memento;
+	}
+
+	public void setMemento(IMemento memento) {
+		DiagramPartitioningEditor.memento = memento;
+	}
+
+	@Override
+	public abstract String getFactoryId();
+
+	protected abstract boolean isDefinitionSectionInlined();
+
+	protected Composite createParentSash(Composite parent) {
+		GridDataFactory.fillDefaults().grab(false, true).applyTo(parent);
+		SashForm sash = new SashForm(parent, SWT.HORIZONTAL | SWT.SMOOTH);
+		sash.setBackground(ColorConstants.white);
+		GridDataFactory.fillDefaults().grab(true, true).applyTo(sash);
+		GridLayoutFactory.fillDefaults().applyTo(sash);
+		return sash;
 	}
 
 	@SuppressWarnings("restriction")
@@ -148,11 +264,13 @@ public abstract class DiagramPartitioningEditor extends DiagramDocumentEditor im
 	}
 
 	protected void createBreadcrumbViewer(Composite parent) {
-		viewer = new DiagramPartitioningBreadcrumbViewer(parent, SWT.READ_ONLY);
-		viewer.addSelectionChangedListener(this);
-		viewer.setContentProvider(new BreadcrumbViewerContentProvider());
-		viewer.setLabelProvider(new BreadcrumbViewerLabelProvider());
-		viewer.setInput(DiagramPartitioningUtil.getDiagramContainerHierachy(getDiagram()));
+		if (viewer == null) {
+			viewer = new DiagramPartitioningBreadcrumbViewer(parent, SWT.READ_ONLY);
+			viewer.addSelectionChangedListener(this);
+			viewer.setContentProvider(new BreadcrumbViewerContentProvider());
+			viewer.setLabelProvider(new BreadcrumbViewerLabelProvider());
+			viewer.setInput(DiagramPartitioningUtil.getDiagramContainerHierachy(getDiagram()));
+		}
 		parent.pack(true);
 	}
 
@@ -209,7 +327,17 @@ public abstract class DiagramPartitioningEditor extends DiagramDocumentEditor im
 		}
 	}
 
-	public static final class BreadcrumbViewerLabelProvider extends BaseLabelProvider implements ITreePathLabelProvider {
+	protected void refreshDiagramEditPartChildren() {
+		((List<?>) getDiagramEditPart().getChildren()).forEach(part -> {
+			if (part instanceof EditPart) {
+				((EditPart) part).refresh();
+			}
+		});
+	}
+
+	public static final class BreadcrumbViewerLabelProvider extends BaseLabelProvider
+			implements
+				ITreePathLabelProvider {
 
 		public void updateLabel(ViewerLabel label, TreePath elementPath) {
 			Diagram lastSegment = (Diagram) elementPath.getLastSegment();
@@ -227,13 +355,15 @@ public abstract class DiagramPartitioningEditor extends DiagramDocumentEditor im
 
 	public static class FilteringDiagramContextMenuProvider extends DiagramContextMenuProvider {
 		// Default context menu items that should be suppressed
-		protected String[] exclude = new String[] { "addNoteLinkAction", "properties",
-				"org.eclipse.mylyn.context.ui.commands.attachment.retrieveContext","org.eclipse.jst.ws.atk.ui.webservice.category.popupMenu",
-		        "org.eclipse.tptp.platform.analysis.core.ui.internal.actions.MultiAnalysisActionDelegate", "org.eclipse.debug.ui.contextualLaunch.debug.submenu", 
-		        "org.eclipse.debug.ui.contextualLaunch.profile.submenu",
+		protected String[] exclude = new String[]{"addNoteLinkAction", "properties",
+				"org.eclipse.mylyn.context.ui.commands.attachment.retrieveContext",
+				"org.eclipse.jst.ws.atk.ui.webservice.category.popupMenu",
+				"org.eclipse.tptp.platform.analysis.core.ui.internal.actions.MultiAnalysisActionDelegate",
+				"org.eclipse.debug.ui.contextualLaunch.debug.submenu",
+				"org.eclipse.debug.ui.contextualLaunch.profile.submenu",
 				"org.eclipse.mylyn.resources.ui.ui.interest.remove.element", "formatMenu", "filtersMenu", "addGroup",
-				"navigateGroup", "toolbarArrangeAllAction", "selectMenu", "diagramAddMenu", "navigateMenu",
-				"viewGroup", "viewMenu" };
+				"navigateGroup", "toolbarArrangeAllAction", "selectMenu", "diagramAddMenu", "navigateMenu", "viewGroup",
+				"viewMenu"};
 
 		protected FilteringDiagramContextMenuProvider(IWorkbenchPart part, EditPartViewer viewer) {
 			super(part, viewer);

+ 21 - 0
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/partitioning/DiagramPartitioningUtil.java

@@ -58,6 +58,7 @@ public class DiagramPartitioningUtil {
 
 	/** GMFs notation {@link Style} id **/
 	public static final String INLINE_STYLE = "isInline";
+	public static final String INLINE_DEFINITION_SECTION_STYLE = "inlineDefinitionSection";
 
 	private static final String DOMAIN_ID = "org.yakindu.sct.domain";
 
@@ -72,6 +73,16 @@ public class DiagramPartitioningUtil {
 		BooleanValueStyle result = GMFNotationUtil.getBooleanValueStyle(view, INLINE_STYLE);
 		return result;
 	}
+	
+	/**
+	 * returns the style for diagram inlining
+	 * 
+	 */
+	public static BooleanValueStyle getInlineDefinitionSectionStyle(View view) {
+		BooleanValueStyle result = GMFNotationUtil.getBooleanValueStyle(view, INLINE_DEFINITION_SECTION_STYLE);
+		return result;
+	}
+
 
 	/**
 	 * creates a new style for diagam inlining
@@ -82,6 +93,16 @@ public class DiagramPartitioningUtil {
 		result.setBooleanValue(true);
 		return result;
 	}
+	
+	/**
+	 * creates a new style for diagam inlining
+	 */
+	public static BooleanValueStyle createInlineDefinitionSectionStyle() {
+		BooleanValueStyle result = NotationFactory.eINSTANCE.createBooleanValueStyle();
+		result.setName(INLINE_DEFINITION_SECTION_STYLE);
+		result.setBooleanValue(true);
+		return result;
+	}
 
 	/**
 	 * Returns the Shared Editing Domain that is used for all Editors acting on the

+ 2 - 0
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/preferences/PreferenceInitializer.java

@@ -68,6 +68,8 @@ public class PreferenceInitializer extends DiagramPreferenceInitializer implemen
 		getPreferenceStore().setDefault(StatechartPreferenceConstants.PREF_LIVE_VALIDATION, true);
 		// Syntax coloring
 		getPreferenceStore().setDefault(StatechartPreferenceConstants.PREF_SYNTAX_COLORING, false);
+		// Definition section pinning
+		getPreferenceStore().setDefault(StatechartPreferenceConstants.PREF_DEFINITION_SECTION, false);
 
 	}
 

+ 8 - 0
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/preferences/StatechartAppearancePreferencePage.java

@@ -51,6 +51,7 @@ public class StatechartAppearancePreferencePage extends FieldEditorPreferencePag
 		createLineStyleEditors(main);
 		createDefaultFontEditor(main);
 		createSyntaxColoringLabelEditor(main);
+		createPinnableStatechartDefinitionEditor(main);
 		createPriorityLabelEditor(main);
 		createLiveValidationEditor(main);
 	}
@@ -81,6 +82,13 @@ public class StatechartAppearancePreferencePage extends FieldEditorPreferencePag
 				"Enable syntax coloring", composite);
 		addField(editor);
 	}
+	
+	protected void createPinnableStatechartDefinitionEditor(Composite main) {
+		Composite composite = createGroupComposite(main, "Definition section");
+		BooleanFieldEditor editor = new BooleanFieldEditor(StatechartPreferenceConstants.PREF_DEFINITION_SECTION,
+				"Enable pinning of statechart definition section", composite);
+		addField(editor);
+	}
 
 	protected void createLineStyleEditors(Composite parent) {
 		Composite composite = createGroupComposite(parent, "Line styles");

+ 1 - 0
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/preferences/StatechartPreferenceConstants.java

@@ -26,4 +26,5 @@ public interface StatechartPreferenceConstants extends IPreferenceConstants {
 	String PREF_PRIORITY_LABELS = "Appearance.transition.priority";
 	String PREF_LIVE_VALIDATION = "Appearance.live.validation";
 	String PREF_SYNTAX_COLORING = "Appearance.diagram.syntaxcoloring";
+	String PREF_DEFINITION_SECTION = "Appearance.diagram.definitionsection";
 }