...
Add the following feature class to your plugin, adapting references to meta model elements to your Turing Machine definition:
Code Block theme Eclipse language java import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.features.context.ICreateContext; import org.eclipse.graphiti.features.impl.AbstractCreateFeature; import org.eclipse.graphiti.mm.pictograms.Diagram; import de.cau.cs.rtprak.login.turingmodel.State; import de.cau.cs.rtprak.login.turingmodel.TuringFactory; import de.cau.cs.rtprak.login.turingmodel.TuringMachine; /** * A create feature for Turing Machine states. * * @author msp */ public class StateCreateFeature extends AbstractCreateFeature { /** * Constructor for a state create feature. * * @param fp the feature provider for which the feature is created */ public StateCreateFeature(IFeatureProvider fp) { super(fp, "State", "Create a State"); } /** * {@inheritDoc} */ public boolean canCreate(ICreateContext context) { return context.getTargetContainer() instanceof Diagram; } /** * {@inheritDoc} */ public Object[] create(ICreateContext context) { // get the container business element List<EObject> containerObjects = context.getTargetContainer().getLink().getBusinessObjects(); if (containerObjects.isEmpty() || !(containerObjects.get(0) instanceof TuringMachine)) { throw new IllegalStateException("The diagram does not contain a Turing Machine."); } TuringMachine machine = (TuringMachine) containerObjects.get(0); // create a new state State state = TuringFactory.eINSTANCE.createState(); machine.getStates().add(state); // add the corresponding graphical representation addGraphicalRepresentation(context, state); return new Object[] { state }; } }
Add the following method to
TuringFeatureProvider
, defining the content of the diagram editor's palette:Code Block theme Eclipse language java /** * {@inheritDoc} */ @Override public ICreateFeature[] getCreateFeatures() { return new ICreateFeature[] { new StateCreateFeature(this) }; }
Add the following feature class to your plugin and implement the
add
method at the TODO note:Code Block theme Eclipse language java import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.features.context.IAddContext; import org.eclipse.graphiti.features.impl.AbstractAddShapeFeature; import org.eclipse.graphiti.mm.pictograms.ContainerShape; import org.eclipse.graphiti.mm.pictograms.Diagram; import org.eclipse.graphiti.mm.pictograms.PictogramElement; import org.eclipse.graphiti.services.Graphiti; import org.eclipse.graphiti.services.IGaService; import de.cau.cs.rtprak.login.turingmodel.State; /** * An add feature for Turing Machine states. * * @author msp */ public class StateAddFeature extends AbstractAddShapeFeature { /** * Constructor for a state add feature. * * @param fp the feature provider for which the feature is created */ public StateAddFeature(IFeatureProvider fp) { super(fp); } /** * {@inheritDoc} */ public boolean canAdd(IAddContext context) { return context.getNewObject() instanceof State && context.getTargetContainer() instanceof Diagram; } /** * {@inheritDoc} */ public PictogramElement add(IAddContext context) { // create a pictogram element for the state ContainerShape containerShape = Graphiti.getPeCreateService().createContainerShape( context.getTargetContainer(), true); // TODO specify the concrete representation by adding at least one graphics algorithm to the shape Graphiti.getPeCreateService().createChopboxAnchor(containerShape); link(containerShape, context.getNewObject()); return containerShape; } }
Use
Graphiti.getGaService()
to get a service class for creating graphics algorithms and modifying their properties. You are free to design your model elements as you like. Find more information on how to solve this task in the official Graphiti Tutorial.Add the following method to
TuringFeatureProvider
:Code Block theme Eclipse language java private IAddFeature stateAddFeature = new StateAddFeature(this); /** * {@inheritDoc} */ @Override public IAddFeature getAddFeature(IAddContext context) { if (stateAddFeature.canAdd(context)) { return stateAddFeature; } return super.getAddFeature(context); }
- Test the features in the diagram editor. You should now be able to select "State" in the editor's palette. Use this to create a few states. Note that if you create a state and later change the graphical representation in
StateAddFeature
, the previously created state will still look the same, since the add feature code is only applied to new states created from the palette.
...
- Add a
Text
element to states in theStateAddFeature
in order to display the name of each state. - Create a new class
StateDirectEditingFeature
extendingAbstractDirectEditingFeature
and register it by overridinggetDirectEditingFeature
in theTuringFeatureProvider
. This new feature is responsible for connecting the name attribute of states with the in-diagram text editing box, i.e. retrieving the current text from the attribute and updating it after the user has entered a new value. - Create a new class
StateUpdateFeature
extendingAbstractUpdateFeature
and register it by overridinggetUpdateFeature
in theTuringFeatureProvider
. This new feature is responsible for updating the displayed text when the corresponding attribute in the domain model is changed outside the Graphiti editor. For example you could open the Turing Machine model with the Sample Reflective Ecore Model Editor in order to modify attributes. You can activate automatic updates of the diagram by extendingisAutoUpdateAtRuntime
(resp.Startup
/Reset
) in theTuringDiagramTypeProvider
and returningtrue
. The update feature can be invoked explicitly in other features by calling the superclass methodupdatePictogramElement
. - Create a new class
StateLayoutFeature
extendingAbstractLayoutFeature
and register it by overridinggetLayoutFeature
in theTuringFeatureProvider
. This new feature is responsible for updating the position and size of graphics algorithms of a state when the state is resized in the graphical editor or when the displayed text for the state name is updated. The layout feature can be invoked explicitly in other features by calling the superclass methodlayoutPictogramElement
.
Implement all created feature classes such that the editor behaves correctly when state names are modified or states are resized. You should aim for a good look-and-feel of your Turing Machine editor. If you like, you may also implement transition labels for displaying triggers and actions of transitions (not required for finishing the tutorial).