]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.g2d/src/org/simantics/g2d/example/TestCanvas.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / example / TestCanvas.java
index e8138c2c4694469b7d98b84bd4918612c4e169b2..8172782ae5463999c79ca49113a3b6e362a58eb1 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g2d.example;\r
-\r
-import java.awt.Color;\r
-import java.awt.Shape;\r
-import java.awt.geom.Ellipse2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.simantics.g2d.canvas.Hints;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.canvas.impl.CanvasContext;\r
-import org.simantics.g2d.diagram.DiagramClass;\r
-import org.simantics.g2d.diagram.DiagramHints;\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.diagram.handler.Topology;\r
-import org.simantics.g2d.diagram.handler.Validator;\r
-import org.simantics.g2d.diagram.handler.Topology.Terminal;\r
-import org.simantics.g2d.diagram.handler.Validator.Issue;\r
-import org.simantics.g2d.diagram.handler.Validator.Suggestion;\r
-import org.simantics.g2d.diagram.impl.Diagram;\r
-import org.simantics.g2d.diagram.impl.DummyDiagramMutator;\r
-import org.simantics.g2d.diagram.participant.DiagramParticipant;\r
-import org.simantics.g2d.diagram.participant.ElementHeartbeater;\r
-import org.simantics.g2d.diagram.participant.ElementInteractor;\r
-import org.simantics.g2d.diagram.participant.ElementPainter;\r
-import org.simantics.g2d.diagram.participant.Selection;\r
-import org.simantics.g2d.diagram.participant.TerminalPainter;\r
-import org.simantics.g2d.diagram.participant.ZOrderHandler;\r
-import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;\r
-import org.simantics.g2d.element.ElementClass;\r
-import org.simantics.g2d.element.ElementClassProviders;\r
-import org.simantics.g2d.element.ElementHints;\r
-import org.simantics.g2d.element.ElementUtils;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.FillColor;\r
-import org.simantics.g2d.element.handler.Move;\r
-import org.simantics.g2d.element.handler.ParentTransform;\r
-import org.simantics.g2d.element.handler.Resize;\r
-import org.simantics.g2d.element.handler.TerminalTopology;\r
-import org.simantics.g2d.element.handler.Text;\r
-import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\r
-import org.simantics.g2d.element.handler.impl.ElementParentTransform;\r
-import org.simantics.g2d.element.impl.Element;\r
-import org.simantics.g2d.elementclass.BoxClass;\r
-import org.simantics.g2d.elementclass.FilmClass;\r
-import org.simantics.g2d.elementclass.FlagClass;\r
-import org.simantics.g2d.elementclass.ImageClass;\r
-import org.simantics.g2d.elementclass.LabelClass;\r
-import org.simantics.g2d.elementclass.ShapeClass;\r
-import org.simantics.g2d.elementclass.button.ButtonClass;\r
-import org.simantics.g2d.elementclass.button.ToggleButtonClass;\r
-import org.simantics.g2d.elementclass.canvas.CanvasClass;\r
-import org.simantics.g2d.elementclass.canvas.ElementViewport;\r
-import org.simantics.g2d.elementclass.connection.EdgeClass;\r
-import org.simantics.g2d.elementclass.slider.SliderClass;\r
-import org.simantics.g2d.elementclass.valve.ValveClass;\r
-import org.simantics.g2d.elementclass.wheel.WheelClass;\r
-import org.simantics.g2d.image.DefaultImages;\r
-import org.simantics.g2d.image.Image;\r
-import org.simantics.g2d.multileveldiagram.LayerComposition;\r
-import org.simantics.g2d.multileveldiagram.TransitionFunction;\r
-import org.simantics.g2d.multileveldiagram.ZoomTransitionParticipant;\r
-import org.simantics.g2d.multileveldiagram.LayerComposition.LayerInfo;\r
-import org.simantics.g2d.participant.BackgroundPainter;\r
-import org.simantics.g2d.participant.CanvasBoundsParticipant;\r
-import org.simantics.g2d.participant.CanvasGrab;\r
-import org.simantics.g2d.participant.GridPainter;\r
-import org.simantics.g2d.participant.KeyToCommand;\r
-import org.simantics.g2d.participant.KeyUtil;\r
-import org.simantics.g2d.participant.MouseUtil;\r
-import org.simantics.g2d.participant.PanZoomRotateHandler;\r
-import org.simantics.g2d.participant.PointerPainter;\r
-import org.simantics.g2d.participant.RulerPainter;\r
-import org.simantics.g2d.participant.SymbolUtil;\r
-import org.simantics.g2d.participant.TimeParticipant;\r
-import org.simantics.g2d.participant.TransformUtil;\r
-import org.simantics.g2d.tooltip.EditableTextTooltipProvider2;\r
-import org.simantics.g2d.tooltip.TextTooltipProvider;\r
-import org.simantics.g2d.tooltip.TooltipParticipant;\r
-import org.simantics.scenegraph.g2d.events.command.CommandKeyBinding;\r
-import org.simantics.utils.datastructures.hints.IHintContext;\r
-import org.simantics.utils.threads.IThreadWorkQueue;\r
-\r
-\r
-\r
-/**\r
- * @author Toni Kalajainen\r
- */\r
-public class TestCanvas {\r
-\r
-    public static final Color C1 = new Color(0.7f, 0.7f, 0.7f);\r
-    public static final Color C2 = new Color(0.8f, 0.8f, 0.8f);\r
-    public static final Color C3 = new Color(0.9f, 0.9f, 0.9f);\r
-    public static final Color C4 = new Color(1.0f, 1.0f, 1.0f);\r
-\r
-\r
-    public static CanvasContext createDefaultCanvas(IThreadWorkQueue thread)\r
-    {\r
-        // Create canvas context and a layer of interactors\r
-        CanvasContext canvasContext = new CanvasContext(thread);\r
-        IHintContext h = canvasContext.getDefaultHintContext();\r
-\r
-        canvasContext.add( new PanZoomRotateHandler() ); // Must be before TransformUtil\r
-\r
-        // Support & Util Participants\r
-        canvasContext.add( new TransformUtil() );\r
-        canvasContext.add( new MouseUtil() );\r
-        canvasContext.add( new KeyUtil() );\r
-        canvasContext.add( new CanvasGrab() );\r
-        canvasContext.add( new SymbolUtil() );\r
-        canvasContext.add( new TimeParticipant() );\r
-\r
-        // Debug participant(s)\r
-        //canvasContext.add( new PointerPainter() );\r
-//        canvasContext.add( new HandPainter() );\r
-        h.setHint(PointerPainter.KEY_PAINT_POINTER, true);\r
-\r
-        // Pan & Zoom & Rotate\r
-        //canvasContext.add( new MousePanZoomInteractor() );\r
-        //canvasContext.add( new MultitouchPanZoomRotateInteractor() );\r
-        //canvasContext.add( new OrientationRestorer() );\r
-\r
-        // Grid & Ruler & Background\r
-        canvasContext.add( new GridPainter() );\r
-        canvasContext.add( new RulerPainter() );\r
-        canvasContext.add( new BackgroundPainter() );\r
-\r
-        h.setHint(Hints.KEY_GRID_COLOR, new Color(0.95f, 0.95f, 0.95f));\r
-        h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.WHITE);\r
-        h.setHint(RulerPainter.KEY_RULER_BACKGROUND_COLOR, new Color(0.9f, 0.9f, 0.9f, 0.75f));\r
-        h.setHint(RulerPainter.KEY_RULER_TEXT_COLOR, Color.BLACK);\r
-\r
-        // Key bindings\r
-        canvasContext.add( new KeyToCommand( CommandKeyBinding.DEFAULT_BINDINGS ) );\r
-\r
-        ////// Diagram Participants //////\r
-        // FIXME: PointerInteractor must be given a provider for all element classes defined in class ElementClasses !!\r
-        canvasContext.add( new PointerInteractor(true, true, true, false, true, ElementClassProviders.staticProvider(EdgeClass.STRAIGHT)) );\r
-        canvasContext.add( new ElementInteractor() );\r
-        canvasContext.add( new Selection() );\r
-        canvasContext.add( new DiagramParticipant() );\r
-        canvasContext.add( new ElementPainter() );\r
-        canvasContext.add( new TerminalPainter(true, true, false, true) );\r
-        canvasContext.add( new ElementHeartbeater() );\r
-        canvasContext.add( new ZOrderHandler() );\r
-        canvasContext.add( new ZoomTransitionParticipant(TransitionFunction.SIGMOID) );\r
-        canvasContext.add(new CanvasBoundsParticipant());\r
-\r
-        canvasContext.add( new TooltipParticipant());\r
-\r
-        h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);\r
-\r
-\r
-        return canvasContext;\r
-    }\r
-\r
-    public static IDiagram createMultilevelDiagram(ICanvasContext ctx)\r
-    {\r
-        IDiagram loading = LoadingMessageDiagram.createLoadingDiagram();\r
-        IDiagram d1 = createDiagram1();\r
-        IDiagram d2 = createDiagram2();\r
-        IDiagram d3 = createDiagram3();\r
-        validate(d1, ctx);\r
-        validate(d2, ctx);\r
-        validate(d3, ctx);\r
-\r
-        LayerComposition composition = new LayerComposition();\r
-        composition.addLayer(d1, null, 2.0);\r
-        composition.addLayer(d2, 5.0, 7.0);\r
-        composition.addLayer(d3, 10.0, null);\r
-        List<LayerInfo> lis = composition.buildMorphLayers();\r
-        loading.setHint(DiagramHints.KEY_LAYER_COMPOSITION, lis);\r
-        return loading;\r
-    }\r
-\r
-    /**\r
-     * Create diagram editor\r
-     * \r
-     * @param thread\r
-     * @param resource\r
-     * @param localSession\r
-     * @return\r
-     */\r
-    public static CanvasContext createTestCanvas(IThreadWorkQueue thread)\r
-    {\r
-        // Create canvas context and a layer of interactors\r
-        CanvasContext canvasContext = createDefaultCanvas(thread);\r
-        IHintContext h = canvasContext.getDefaultHintContext();\r
-        h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);\r
-\r
-        ////// CREATE DIAGRAM //////\r
-        IDiagram wd = createWidgetsDiagram();\r
-//        IDiagram d1 = createDiagram1();\r
-//        IDiagram d2 = createDiagram2();\r
-//        IDiagram d3 = createDiagram3();\r
-//        IDiagram od = createOperationSymbolsDiagram();\r
-//        IDiagram uid = createUIDiagram(ElementUtils.getByData(od, "BoilerBtn"));\r
-        IDiagram uid = createUIDiagram();\r
-//        IDiagram loading = LoadingMessageDiagram.createLoadingDiagram();\r
-\r
-//        validate(d1, canvasContext);\r
-//        validate(d2, canvasContext);\r
-//        validate(d3, canvasContext);\r
-\r
-        /*\r
-        LayerComposition composition = new LayerComposition();\r
-        composition.addLayer(d1, null, 2.0);\r
-        composition.addLayer(d2, 5.0, 7.0);\r
-        composition.addLayer(d3, 10.0, null);\r
-        List<LayerInfo> lis = composition.buildMorphLayers();\r
-        canvasContext.add( new ZoomTransitionParticipant(lis, TransitionFunction.SIGMOID) );\r
-         */\r
-\r
-//        IDiagram d = loading;\r
-        //h.setHint(DiagramHints.KEY_DIAGRAM, d);\r
-        h.setHint(DiagramHints.KEY_DIAGRAM, uid);\r
-\r
-        /*\r
-        final IElement button = ElementUtils.getByData(wd, "button");\r
-        System.out.println(button.getDiagram());\r
-               ElementUtils.addClickListener(button, canvasContext, new ClickListener() {\r
-                       @Override\r
-                       public void onClick(IElement e, ICanvasContext ctx) {\r
-                               Point2D pos = ElementUtils.getPos(button);\r
-                               pos = new Point2D.Double(pos.getX()+10, pos.getY());\r
-                               ElementUtils.setPos(e, pos);\r
-                       }});\r
-         */\r
-\r
-        // Draw UI Layer on top of the diagram\r
-\r
-        /*\r
-               ICanvasContext subCanvas = createDefaultCanvas(canvasContext.getThreadAccess());\r
-               subCanvas.remove( subCanvas.getSingleItem(RulerPainter.class) );\r
-               subCanvas.remove( subCanvas.getSingleItem(BackgroundPainter.class) );\r
-               subCanvas.remove( subCanvas.getSingleItem(GridPainter.class) );\r
-               subCanvas.remove( subCanvas.getSingleItem(TimeParticipant.class) );\r
-               subCanvas.add( new KeepZoomToFit() );\r
-               subCanvas.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, uid);\r
-               subCanvas.getDefaultHintContext().setHint(PanZoomRotateHandler.KEY_ZOOM_TO_FIT_MARGINS, MarginUtils.MARINGS5);\r
-               canvasContext.add( new SubCanvas(subCanvas, 10000, RulerPainter.PAINT_PRIORITY + 100, 10000) );\r
-         */\r
-//        ElementDiagram ed = new ElementDiagram(canvasContext) {\r
-//            @Override\r
-//            public ICanvasContext createCanvas(IThreadWorkQueue thread) {\r
-//                ICanvasContext subCanvas = createDefaultCanvas(thread);\r
-//                subCanvas.remove( subCanvas.getSingleItem(RulerPainter.class) );\r
-//                subCanvas.remove( subCanvas.getSingleItem(BackgroundPainter.class) );\r
-//                subCanvas.remove( subCanvas.getSingleItem(GridPainter.class) );\r
-//                subCanvas.remove( subCanvas.getSingleItem(TimeParticipant.class) );\r
-//                subCanvas.add( new KeepZoomToFit() );\r
-//                subCanvas.getDefaultHintContext().setHint(DiagramHints.KEY_MARGINS, MarginUtils.MARGINS5);\r
-//                return subCanvas;\r
-//            }\r
-//        };\r
-//        ed.setDiagram(uid);\r
-\r
-        return canvasContext;\r
-    }\r
-\r
-    public static IDiagram createUIDiagram(IElement forElement)\r
-    {\r
-        String name = "User Interface Diagram";\r
-        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);\r
-        d.setHint(DiagramHints.KEY_TEXT, name);\r
-\r
-        IElement film = Element.spawnNew(FilmClass.FILM_CLASS);\r
-        ElementUtils.fitToRectangle(film, new Rectangle2D.Double(0, 10, 200, 160));\r
-        d.addElement(film);\r
-\r
-        IElement preview = Element.spawnNew(CanvasClass.ELEMENT_VIEWPORT_CLASS);\r
-        preview.setHint(ElementViewport.KEY_ELEMENT, forElement);\r
-        d.addElement(preview);\r
-        ElementUtils.fitToRectangle(preview, new Rectangle2D.Double(10, 20, 60, 60));\r
-        ElementUtils.setBorderColor(preview, Color.WHITE);\r
-\r
-        IElement       cancel  = createButton(d, 10 , 140, 50, 20, "Cancel", "Cancel");\r
-        IElement       apply   = createButton(d, 74 , 140, 50, 20, "Apply", "Apply");\r
-        IElement       ok              = createButton(d, 134, 140, 50, 20, "OK", "OK");\r
-        IElement    toggle  = createToggleButton(d, 10, 110, 50, 20, "Toggle", "Toggle");\r
-\r
-        String         eleName = "?";\r
-        Text           text    = forElement.getElementClass().getAtMostOneItemOfClass(Text.class);\r
-        if (text!=null) eleName = text.getText(forElement);\r
-        IElement       nameLbl = createLabel(d, 10, 90, "nameLbl", eleName);\r
-        ElementUtils.setTextColor(nameLbl, Color.WHITE);\r
-\r
-        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));\r
-\r
-        return d;\r
-    }\r
-\r
-    public static IDiagram createUIDiagram()\r
-    {\r
-        String name = "User Interface Diagram";\r
-        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);\r
-        d.setHint(DiagramHints.KEY_TEXT, name);\r
-\r
-        IElement film = Element.spawnNew(FilmClass.FILM_CLASS);\r
-        ElementUtils.fitToRectangle(film, new Rectangle2D.Double(0, 10, 200, 160));\r
-        d.addElement(film);\r
-\r
-//        IElement preview = Element.spawnNew(CanvasClass.ELEMENT_VIEWPORT_CLASS);\r
-//        preview.setHint(ElementViewport.KEY_ELEMENT, forElement);\r
-//        d.addElement(preview);\r
-//        ElementUtils.fitToRectangle(preview, new Rectangle2D.Double(10, 20, 60, 60));\r
-//        ElementUtils.setBorderColor(preview, Color.WHITE);\r
-\r
-        IElement       cancel  = createButton(d, 10 , 140, 50, 20, "Cancel", "Cancel");\r
-        IElement       apply   = createButton(d, 74 , 140, 50, 20, "Apply", "Apply");\r
-        IElement       ok              = createButton(d, 134, 140, 50, 20, "OK", "OK");\r
-        IElement    toggle  = createToggleButton(d, 10, 110, 50, 20, "Toggle", "Toggle");\r
-\r
-//        String               eleName = "?";\r
-//        Text         text    = forElement.getElementClass().getAtMostOneItemOfClass(Text.class);\r
-//        if (text!=null) eleName = text.getText(forElement);\r
-//        IElement     nameLbl = createLabel(d, 10, 90, "nameLbl", eleName);\r
-//        ElementUtils.setTextColor(nameLbl, Color.WHITE);\r
-        toggle.setHint(TooltipParticipant.TOOLTIP_KEY, new TextTooltipProvider() {\r
-\r
-            @Override\r
-            public String getTooltipText(IElement element) {\r
-                return element.toString();\r
-            }\r
-        });\r
-        apply.setHint(TooltipParticipant.TOOLTIP_KEY, new EditableTextTooltipProvider2() {\r
-\r
-            @Override\r
-            public void setText(IElement element, String text) {\r
-                ElementUtils.setText(element, text);\r
-            }\r
-\r
-            @Override\r
-            public String getTooltipText(IElement element) {\r
-                return ElementUtils.getText(element);\r
-            }\r
-        });\r
-\r
-        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));\r
-\r
-        return d;\r
-    }\r
-\r
-    public static IDiagram createConnectTestDiagram()\r
-    {\r
-        String name = "Diagram";\r
-        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);\r
-        d.setHint(DiagramHints.KEY_TEXT, name);\r
-\r
-        IElement box1 = createBox(d, 0, 0, 70, 70, C4, "1");\r
-        IElement box2 = createBox(d, 120, 0, 80, 70, C4, "2");\r
-        connect(d, box1, 4, box2, 8);\r
-        createLabel(d, 50, 90, "label", name);\r
-\r
-        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));\r
-\r
-        return d;\r
-    }\r
-\r
-    public static IDiagram createAnchorTestDiagram()\r
-    {\r
-        String name = "Diagram";\r
-        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);\r
-        d.setHint(DiagramHints.KEY_TEXT, name);\r
-\r
-        IElement box1 = createBox(d, 0, 0, 70, 70, C4, "1");\r
-        IElement box2 = createBox(d, 120, 0, 80, 70, C4, "2");\r
-        IElement box3 = createBox(d, 30, 90, 40, 40, C3, "3");\r
-\r
-        ElementParentTransform pt = (ElementParentTransform)box3.getElementClass().getSingleItem(ParentTransform.class);\r
-        pt.setParent(box3, box2);\r
-\r
-        connect(d, box1, 4, box2, 8);\r
-        createLabel(d, 50, 90, "label", name);\r
-\r
-        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));\r
-\r
-        return d;\r
-    }\r
-\r
-\r
-    public static IDiagram createFlagTestDiagram()\r
-    {\r
-        String name = "Diagram";\r
-        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);\r
-        d.setHint(DiagramHints.KEY_TEXT, name);\r
-\r
-        IElement e1 = createFlag(d, -100, 0, 0, FlagClass.Type.In, C4, "I3", "From Z");\r
-        IElement e2 = createFlag(d, -80, 20, 90, FlagClass.Type.In, C4, "I2", "From Y");\r
-        IElement e3 = createFlag(d, -100, 40, 180, FlagClass.Type.Out, C4, "I1", "To X");\r
-        IElement e4 = createFlag(d, -120, 20, 270, FlagClass.Type.Out, C4, "I4", "To W");\r
-        IElement e5 = createFlag(d, -120, 120, 270, FlagClass.Type.Out, C4, "I5", "To P");\r
-\r
-        e1.setHint(FlagClass.KEY_FLAG_TEXT, new String[]{"THIS" });\r
-        e2.setHint(FlagClass.KEY_FLAG_TEXT, new String[]{"THIS", "is"});\r
-        e3.setHint(FlagClass.KEY_FLAG_TEXT, new String[]{"THIS", "is", "DEBUG"});\r
-        e4.setHint(FlagClass.KEY_FLAG_TEXT, new String[]{"THIS", "is", "DEBUG", "INFO"});\r
-        e5.setHint(FlagClass.KEY_FLAG_TEXT, new String[]{"THIS", "is", "DEBUG", "INFO", "FOO!"});\r
-\r
-//        createFlag(d, 300, 40, 0, FlagClass.Type.Out, C3, "O3", "To Z", FlagClass.Mode.Minimized);\r
-//        createFlag(d, 280, 20, 90, FlagClass.Type.Out, C3, "O4", "To W", FlagClass.Mode.Minimized);\r
-//        createFlag(d, 300, 00, 180, FlagClass.Type.Out, C3, "O1", "To X", FlagClass.Mode.Minimized);\r
-//        createFlag(d, 320, 20, 270, FlagClass.Type.Out, C3, "O2", "To Y", FlagClass.Mode.Minimized);\r
-\r
-        createFlag(d, 100, 50, 0, FlagClass.Type.Out, C2, "J1O", "O", FlagClass.Mode.Internal);\r
-        createFlag(d, 100, 100, 0, FlagClass.Type.Out, C2, "J2O", "Oy", FlagClass.Mode.Internal);\r
-        createFlag(d, 100, 150, 90, FlagClass.Type.Out, C2, "J3O", "OAAAA", FlagClass.Mode.Internal);\r
-        createFlag(d, 150, 50, 0, FlagClass.Type.In, C2, "J1I", "I", FlagClass.Mode.Internal);\r
-        createFlag(d, 150, 100, 0, FlagClass.Type.In, C2, "J2I", "Iy", FlagClass.Mode.Internal);\r
-        createFlag(d, 150, 150, 90, FlagClass.Type.In, C2, "J3I", "IAAAA", FlagClass.Mode.Internal);\r
-\r
-        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));\r
-\r
-        return d;\r
-    }\r
-\r
-    public static IDiagram createDiagram1()\r
-    {\r
-        String name = "Diagram Level 1";\r
-        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);\r
-        d.setHint(DiagramHints.KEY_TEXT, name);\r
-\r
-        IElement box1 = createBox(d, 0, 0, 70, 70, C4, "1");\r
-        IElement box2 = createBox(d, 120, 0, 80, 70, C4, "2");\r
-        connect(d, box1, 4, box2, 8);\r
-        createLabel(d, 50, 90, "label", name);\r
-\r
-        IElement slider = createSlider(d, 600, 0, 100, 28, "slider");\r
-        IElement valve = createValve (d, 800, 0, "valve");\r
-        //IElement wheel =  createWheel (d, 500, 100, 100, 100, "wheel");\r
-        IElement button = createButton(d, 800, 100, 100, 28, "button", "button");\r
-\r
-        IElement image = createImage(d, 400, 400, DefaultImages.UNKNOWN.get());\r
-\r
-        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));\r
-\r
-        return d;\r
-    }\r
-\r
-\r
-    public static IDiagram createDiagram2()\r
-    {\r
-        String name = "Diagram Level 2";\r
-        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);\r
-        d.setHint(DiagramHints.KEY_TEXT, name);\r
-\r
-        IElement box1  = createBox(d, 0, 30, 70, 10, C3, "1");\r
-        IElement box1_1 = createBox(d, 20, 0, 50, 20, C2, "1.1");\r
-        IElement box1_2 = createBox(d, 0, 50, 70, 20, C2, "1.2");\r
-        IElement box2  = createBox(d, 120, 0, 20, 70, C3, "2");\r
-        IElement box2_2 = createBox(d, 150, 0, 50, 20, C2, "2.2");\r
-        IElement box2_3 = createBox(d, 150, 30, 50, 40, C2, "2.3");\r
-        connect(d, box1, 4, box2, 8);\r
-        connect(d, box1, 2, box1_1, 6);\r
-        connect(d, box1, 6, box1_2, 2);\r
-        connect(d, box2, 4, box2_2, 8);\r
-        connect(d, box2, 4, box2_3, 8);\r
-        createLabel(d, 50, 90, "label", name);\r
-\r
-        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));\r
-\r
-        return d;\r
-    }\r
-\r
-    public static IDiagram createDiagram3()\r
-    {\r
-        String name = "Diagram Level 3";\r
-        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);\r
-        d.setHint(DiagramHints.KEY_TEXT, name);\r
-\r
-        IElement box1          = createBox(d, 0, 30, 70, 10, C3, "1");\r
-        IElement box1_1        = createBox(d, 30, 0, 40, 20, C2, "1.1");\r
-        IElement box1_1_1      = createBox(d, 00, 0, 20, 20, C2, "1.1.1");\r
-        IElement box1_2        = createBox(d, 30, 50, 40, 20, C2, "1.2");\r
-        IElement box1_2_1      = createBox(d, 0, 50, 20, 20, C1, "1.2.1");\r
-        IElement box2          = createBox(d, 120, 30, 20, 40, C3, "2");\r
-        IElement box2_1        = createBox(d, 120, 0, 20, 20, C2, "2.1");\r
-        IElement box2_2        = createBox(d, 150, 0, 20, 20, C2, "2.2");\r
-        IElement box2_2_1      = createBox(d, 180, 0, 20, 20, C1, "2.2.1");\r
-        IElement box2_3        = createBox(d, 150, 30, 20, 20, C2, "2.3");\r
-        IElement box2_3_1      = createBox(d, 180, 30, 20, 20, C1, "2.3.1");\r
-        IElement box2_3_2      = createBox(d, 180, 60, 20, 20, C1, "2.3.2");\r
-        connect(d, box1, 4, box2, 8);\r
-        connect(d, box1, 2, box1_1, 6);\r
-        connect(d, box1_1, 8, box1_1_1, 4);\r
-        connect(d, box1, 6, box1_2, 2);\r
-        connect(d, box1_2, 8, box1_2_1, 4);\r
-        connect(d, box2, 2, box2_1, 6);\r
-        connect(d, box2, 3, box2_2, 7);\r
-        connect(d, box2_2, 4, box2_2_1, 8);\r
-        connect(d, box2, 4, box2_3, 8);\r
-        connect(d, box2_3, 4, box2_3_1, 8);\r
-        connect(d, box2_3, 5, box2_3_2, 1);\r
-        createLabel(d, 50, 90, "label", name);\r
-\r
-        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));\r
-\r
-        return d;\r
-    }\r
-\r
-    public static IDiagram createWidgetsDiagram()\r
-    {\r
-        String name = "Test Diagram";\r
-        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);\r
-        d.setHint(DiagramHints.KEY_TEXT, name);\r
-\r
-        //IElement slider = createSlider(d, 0, 100, 100, 28, "slider");\r
-        IElement valve = createValve (d, 0, 0, "valve");\r
-        //IElement wheel = createWheel(d, 0, 0, 100, 100, "wheel");\r
-        //IElement button = createButton(d, 0, 0, 100, 28, "button", "button");\r
-\r
-        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));\r
-\r
-        return d;\r
-    }\r
-\r
-    public static IDiagram createOperationSymbolsDiagram()\r
-    {\r
-        String name = "Operation Symbols Diagram";\r
-        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);\r
-        d.setHint(DiagramHints.KEY_TEXT, name);\r
-        /*\r
-               createSymbol(d, OperationClasses.BOILER_CLASS, 0, 0, "Boiler");\r
-               createSymbol(d, OperationClasses.COMPRESSOR_CLASS, 50, 0, "Compressor");\r
-               createSymbol(d, OperationClasses.CONTROLVALVE_CLASS, 100, 0, "Control Valve");\r
-               createSymbol(d, OperationClasses.HEATEXCHANGER_CLASS, 0, 50, "HeatExchanger");\r
-               createSymbol(d, OperationClasses.PUMP_CLASS, 50, 50, "Pump");\r
-               createSymbol(d, OperationClasses.SHUTOFFVALVE_CLASS, 100, 50, "Shutoff Valve");\r
-               createSymbol(d, OperationClasses.SWITCH_CLASS, 0, 100, "Switch");\r
-               createSymbol(d, OperationClasses.TURBINE_CLASS, 50, 100, "Turbine");\r
-               createSymbol(d, OperationClasses.VOLTAGETRANSFORMER_CLASS, 100, 100, "Voltage Transformer");\r
-\r
-               createSymbol(d, OperationClasses.BOILER_BUTTON_CLASS, 0, 200, "BoilerBtn");\r
-               createSymbol(d, OperationClasses.COMPRESSOR_BUTTON_CLASS, 50, 200, "CompressorBtn");\r
-               createSymbol(d, OperationClasses.CONTROLVALVE_BUTTON_CLASS, 100, 200, "Control ValveBtn");\r
-               createSymbol(d, OperationClasses.HEATEXCHANGER_BUTTON_CLASS, 0, 250, "HeatExchangerBtn");\r
-               createSymbol(d, OperationClasses.PUMP_BUTTON_CLASS, 50, 250, "Pump");\r
-               createSymbol(d, OperationClasses.SHUTOFFVALVE_BUTTON_CLASS, 100, 250, "Shutoff ValveBtn");\r
-               createSymbol(d, OperationClasses.SWITCH_BUTTON_CLASS, 0, 300, "SwitchBtn");\r
-               createSymbol(d, OperationClasses.TURBINE_BUTTON_CLASS, 50, 300, "TurbineBtn");\r
-               createSymbol(d, OperationClasses.VOLTAGETRANSFORMER_BUTTON_CLASS, 100, 300, "Voltage TransformerBtn");\r
-         */\r
-        createShape(d, new Ellipse2D.Double(-10, -10, 20, 20), -50, 0, Color.RED, "circle");\r
-\r
-        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));\r
-\r
-        return d;\r
-    }\r
-\r
-    public static IElement createSymbol(IDiagram d, ElementClass clazz, double x, double y, Object dada)\r
-    {\r
-        IElement box = Element.spawnNew( clazz );\r
-        d.addElement(box);\r
-        Move m = box.getElementClass().getSingleItem(Move.class);\r
-        m.moveTo(box, x, y);\r
-        box.setHint(ElementHints.KEY_TEXT, dada.toString());\r
-        box.setHint(ElementHints.KEY_OBJECT, dada);\r
-        return box;\r
-    }\r
-\r
-\r
-    public static IElement createBox(IDiagram d, double x, double y, double width, double height, Color color, Object dada)\r
-    {\r
-        IElement box = Element.spawnNew( BoxClass.BOXCLASS.newClassWith(ElementParentTransform.INSTANCE) );\r
-        d.addElement(box);\r
-        Move m = box.getElementClass().getSingleItem(Move.class);\r
-        Resize s = box.getElementClass().getSingleItem(Resize.class);\r
-        FillColor ch = box.getElementClass().getSingleItem(FillColor.class);\r
-        ch.setFillColor(box, color);\r
-        m.moveTo(box, x, y);\r
-        s.resize(box, new Rectangle2D.Double(0,0,width, height));\r
-        box.setHint(ElementHints.KEY_TEXT, dada.toString());\r
-        box.setHint(ElementHints.KEY_OBJECT, dada);\r
-        return box;\r
-    }\r
-\r
-    private static IElement createImage(IDiagram d, int x, int y, Image image) {\r
-        IElement result = Element.spawnNew( ImageClass.INSTANCE );\r
-        d.addElement(result);\r
-        ElementUtils.setPos(result, x, y);\r
-        result.setHint(ElementHints.KEY_IMAGE, image);\r
-        return result;\r
-    }\r
-\r
-    public static IElement createShape(IDiagram d, Shape shape, double x, double y, Color color, Object dada)\r
-    {\r
-        IElement box = Element.spawnNew( ShapeClass.CIRCLE_CLASS );\r
-        d.addElement(box);\r
-        Move m = box.getElementClass().getSingleItem(Move.class);\r
-        FillColor ch = box.getElementClass().getSingleItem(FillColor.class);\r
-        ch.setFillColor(box, color);\r
-        m.moveTo(box, x, y);\r
-        box.setHint(ElementHints.KEY_TEXT, dada.toString());\r
-        box.setHint(ElementHints.KEY_OBJECT, dada);\r
-        return box;\r
-    }\r
-\r
-    public static IElement createSlider(IDiagram d, double x, double y, double width, double height, Object dada)\r
-    {\r
-        IElement e = Element.spawnNew( SliderClass.SLIDER );\r
-        d.addElement(e);\r
-        Move m = e.getElementClass().getSingleItem(Move.class);\r
-        Resize s = e.getElementClass().getSingleItem(Resize.class);\r
-        m.moveTo(e, x, y);\r
-        s.resize(e, new Rectangle2D.Double(0,0,width, height));\r
-        e.setHint(ElementHints.KEY_OBJECT, dada);\r
-        return e;\r
-    }\r
-\r
-    public static IElement createValve(IDiagram d, double x, double y, Object dada)\r
-    {\r
-        IElement e = Element.spawnNew( ValveClass.INSTANCE );\r
-        d.addElement(e);\r
-        Move m = e.getElementClass().getSingleItem(Move.class);\r
-        m.moveTo(e, x, y);\r
-        e.setHint(ElementHints.KEY_OBJECT, dada);\r
-        return e;\r
-    }\r
-\r
-    public static IElement createWheel(IDiagram d, double x, double y, double width, double height, Object dada)\r
-    {\r
-        IElement e = Element.spawnNew( WheelClass.WHEEL );\r
-        d.addElement(e);\r
-\r
-        ElementUtils.fitToRectangle(e, new Rectangle2D.Double(x, y, width, height));\r
-\r
-        //Move m = e.getElementClass().getSingleItem(Move.class);\r
-        //Scale s = e.getElementClass().getSingleItem(Scale.class);\r
-        //m.move(e, new Point2D.Double(x, y));\r
-        //Point2D s.getScale(e)\r
-        //s.setScale(e, newScale)\r
-        e.setHint(ElementHints.KEY_OBJECT, dada);\r
-        return e;\r
-    }\r
-\r
-    public static IElement createLabel(IDiagram d, double x, double y, Object dada, String label)\r
-    {\r
-        IElement e = Element.spawnNew( LabelClass.CLASS );\r
-        d.addElement(e);\r
-        Move m = e.getElementClass().getSingleItem(Move.class);\r
-        m.moveTo(e, x, y);\r
-\r
-        ElementUtils.setText(e, label);\r
-\r
-        e.setHint(ElementHints.KEY_OBJECT, dada);\r
-        return e;\r
-    }\r
-\r
-    public static IElement createButton(IDiagram d, double x, double y, double width, double height, Object dada, String label)\r
-    {\r
-        IElement e = Element.spawnNew( ButtonClass.BUTTON_CLASS );\r
-        d.addElement(e);\r
-        Move m = e.getElementClass().getSingleItem(Move.class);\r
-        m.moveTo(e, x, y);\r
-        Resize s = e.getElementClass().getSingleItem(Resize.class);\r
-        s.resize(e, new Rectangle2D.Double(0,0,width, height));\r
-        Text t = e.getElementClass().getSingleItem(Text.class);\r
-        t.setText(e, label);\r
-        e.setHint(ElementHints.KEY_OBJECT, dada);\r
-        return e;\r
-    }\r
-\r
-    public static IElement createFlag(IDiagram d, double x, double y, double dir, FlagClass.Type type, Color color, Object dada, String label)\r
-    {\r
-        return createFlag(d, x, y, dir, type, color, dada, label, FlagClass.Mode.External);\r
-    }\r
-\r
-    public static IElement createFlag(IDiagram d, double x, double y, double dir, FlagClass.Type type, Color color, Object dada, String label, FlagClass.Mode mode)\r
-    {\r
-        IElement f = Element.spawnNew( FlagClass.FLAGCLASS );\r
-        d.addElement(f);\r
-        Move m = f.getElementClass().getSingleItem(Move.class);\r
-        FillColor ch = f.getElementClass().getSingleItem(FillColor.class);\r
-        ch.setFillColor(f, color);\r
-        m.moveTo(f, x, y);\r
-        Text t = f.getElementClass().getSingleItem(Text.class);\r
-        t.setText(f, label);\r
-        f.setHint(ElementHints.KEY_OBJECT, dada);\r
-        f.setHint(FlagClass.KEY_FLAG_TYPE, type);\r
-        f.setHint(FlagClass.KEY_FLAG_MODE, mode);\r
-        return f;\r
-    }\r
-\r
-    public static IElement createToggleButton(IDiagram d, double x, double y, double width, double height, Object dada, String label)\r
-    {\r
-        IElement e = Element.spawnNew( ToggleButtonClass.BUTTON_CLASS );\r
-        d.addElement(e);\r
-        Move m = e.getElementClass().getSingleItem(Move.class);\r
-        m.moveTo(e, x, y);\r
-        Resize s = e.getElementClass().getSingleItem(Resize.class);\r
-        s.resize(e, new Rectangle2D.Double(0,0,width, height));\r
-        Text t = e.getElementClass().getSingleItem(Text.class);\r
-        t.setText(e, label);\r
-        e.setHint(ElementHints.KEY_OBJECT, dada);\r
-        return e;\r
-    }\r
-\r
-    public static IElement connect(IDiagram d, IElement e1, int t1, IElement e2, int t2)\r
-    {\r
-        List<Terminal> boxTerminals = new ArrayList<Terminal>();\r
-        TerminalTopology boxNodeHandler = e1.getElementClass().getSingleItem(TerminalTopology.class);\r
-        boxNodeHandler.getTerminals(e1, boxTerminals);\r
-        Terminal _t1 = boxTerminals.get(t1);\r
-\r
-        boxTerminals.clear();\r
-        boxNodeHandler = e2.getElementClass().getSingleItem(TerminalTopology.class);\r
-        boxNodeHandler.getTerminals(e2, boxTerminals);\r
-        Terminal _t2 = boxTerminals.get(t2);\r
-\r
-        IElement edge = Element.spawnNew(EdgeClass.STRAIGHT);\r
-        d.addElement(edge);\r
-\r
-        Object e1dada = e1.getHint(ElementHints.KEY_OBJECT);\r
-        Object e2dada = e2.getHint(ElementHints.KEY_OBJECT);\r
-        if (e1dada!=null && e2dada!=null)\r
-            edge.setHint(ElementHints.KEY_OBJECT, e1dada +" to "+e2dada);\r
-\r
-        Topology topology = d.getDiagramClass().getSingleItem(Topology.class);\r
-        topology.connect(edge, EdgeEnd.Begin, e1, _t1);\r
-        topology.connect(edge, EdgeEnd.End, e2, _t2);\r
-        return edge;\r
-    }\r
-\r
-    public static void validate(IDiagram d, ICanvasContext ctx)\r
-    {\r
-        // Validate\r
-        ArrayList<Issue> issues = new ArrayList<Issue>();\r
-        for (Validator v : d.getDiagramClass().getItemsByClass(Validator.class))\r
-        {\r
-            v.validate(d, ctx, issues);\r
-        }\r
-        List<Suggestion> suggestions = new ArrayList<Suggestion>();\r
-        for (Issue i : issues)\r
-        {\r
-            suggestions.clear();\r
-            i.addSuggestions(d, ctx, suggestions);\r
-            if (suggestions.size()==0) continue;\r
-            suggestions.get(0).fix(d, ctx);\r
-        }\r
-\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * 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:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g2d.example;
+
+import java.awt.Color;
+import java.awt.Shape;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.simantics.g2d.canvas.Hints;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.canvas.impl.CanvasContext;
+import org.simantics.g2d.diagram.DiagramClass;
+import org.simantics.g2d.diagram.DiagramHints;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.Topology;
+import org.simantics.g2d.diagram.handler.Validator;
+import org.simantics.g2d.diagram.handler.Topology.Terminal;
+import org.simantics.g2d.diagram.handler.Validator.Issue;
+import org.simantics.g2d.diagram.handler.Validator.Suggestion;
+import org.simantics.g2d.diagram.impl.Diagram;
+import org.simantics.g2d.diagram.impl.DummyDiagramMutator;
+import org.simantics.g2d.diagram.participant.DiagramParticipant;
+import org.simantics.g2d.diagram.participant.ElementHeartbeater;
+import org.simantics.g2d.diagram.participant.ElementInteractor;
+import org.simantics.g2d.diagram.participant.ElementPainter;
+import org.simantics.g2d.diagram.participant.Selection;
+import org.simantics.g2d.diagram.participant.TerminalPainter;
+import org.simantics.g2d.diagram.participant.ZOrderHandler;
+import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;
+import org.simantics.g2d.element.ElementClass;
+import org.simantics.g2d.element.ElementClassProviders;
+import org.simantics.g2d.element.ElementHints;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.handler.FillColor;
+import org.simantics.g2d.element.handler.Move;
+import org.simantics.g2d.element.handler.ParentTransform;
+import org.simantics.g2d.element.handler.Resize;
+import org.simantics.g2d.element.handler.TerminalTopology;
+import org.simantics.g2d.element.handler.Text;
+import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;
+import org.simantics.g2d.element.handler.impl.ElementParentTransform;
+import org.simantics.g2d.element.impl.Element;
+import org.simantics.g2d.elementclass.BoxClass;
+import org.simantics.g2d.elementclass.FilmClass;
+import org.simantics.g2d.elementclass.FlagClass;
+import org.simantics.g2d.elementclass.ImageClass;
+import org.simantics.g2d.elementclass.LabelClass;
+import org.simantics.g2d.elementclass.ShapeClass;
+import org.simantics.g2d.elementclass.button.ButtonClass;
+import org.simantics.g2d.elementclass.button.ToggleButtonClass;
+import org.simantics.g2d.elementclass.canvas.CanvasClass;
+import org.simantics.g2d.elementclass.canvas.ElementViewport;
+import org.simantics.g2d.elementclass.connection.EdgeClass;
+import org.simantics.g2d.elementclass.slider.SliderClass;
+import org.simantics.g2d.elementclass.valve.ValveClass;
+import org.simantics.g2d.elementclass.wheel.WheelClass;
+import org.simantics.g2d.image.DefaultImages;
+import org.simantics.g2d.image.Image;
+import org.simantics.g2d.multileveldiagram.LayerComposition;
+import org.simantics.g2d.multileveldiagram.TransitionFunction;
+import org.simantics.g2d.multileveldiagram.ZoomTransitionParticipant;
+import org.simantics.g2d.multileveldiagram.LayerComposition.LayerInfo;
+import org.simantics.g2d.participant.BackgroundPainter;
+import org.simantics.g2d.participant.CanvasBoundsParticipant;
+import org.simantics.g2d.participant.CanvasGrab;
+import org.simantics.g2d.participant.GridPainter;
+import org.simantics.g2d.participant.KeyToCommand;
+import org.simantics.g2d.participant.KeyUtil;
+import org.simantics.g2d.participant.MouseUtil;
+import org.simantics.g2d.participant.PanZoomRotateHandler;
+import org.simantics.g2d.participant.PointerPainter;
+import org.simantics.g2d.participant.RulerPainter;
+import org.simantics.g2d.participant.SymbolUtil;
+import org.simantics.g2d.participant.TimeParticipant;
+import org.simantics.g2d.participant.TransformUtil;
+import org.simantics.g2d.tooltip.EditableTextTooltipProvider2;
+import org.simantics.g2d.tooltip.TextTooltipProvider;
+import org.simantics.g2d.tooltip.TooltipParticipant;
+import org.simantics.scenegraph.g2d.events.command.CommandKeyBinding;
+import org.simantics.utils.datastructures.hints.IHintContext;
+import org.simantics.utils.threads.IThreadWorkQueue;
+
+
+
+/**
+ * @author Toni Kalajainen
+ */
+public class TestCanvas {
+
+    public static final Color C1 = new Color(0.7f, 0.7f, 0.7f);
+    public static final Color C2 = new Color(0.8f, 0.8f, 0.8f);
+    public static final Color C3 = new Color(0.9f, 0.9f, 0.9f);
+    public static final Color C4 = new Color(1.0f, 1.0f, 1.0f);
+
+
+    public static CanvasContext createDefaultCanvas(IThreadWorkQueue thread)
+    {
+        // Create canvas context and a layer of interactors
+        CanvasContext canvasContext = new CanvasContext(thread);
+        IHintContext h = canvasContext.getDefaultHintContext();
+
+        canvasContext.add( new PanZoomRotateHandler() ); // Must be before TransformUtil
+
+        // Support & Util Participants
+        canvasContext.add( new TransformUtil() );
+        canvasContext.add( new MouseUtil() );
+        canvasContext.add( new KeyUtil() );
+        canvasContext.add( new CanvasGrab() );
+        canvasContext.add( new SymbolUtil() );
+        canvasContext.add( new TimeParticipant() );
+
+        // Debug participant(s)
+        //canvasContext.add( new PointerPainter() );
+//        canvasContext.add( new HandPainter() );
+        h.setHint(PointerPainter.KEY_PAINT_POINTER, true);
+
+        // Pan & Zoom & Rotate
+        //canvasContext.add( new MousePanZoomInteractor() );
+        //canvasContext.add( new MultitouchPanZoomRotateInteractor() );
+        //canvasContext.add( new OrientationRestorer() );
+
+        // Grid & Ruler & Background
+        canvasContext.add( new GridPainter() );
+        canvasContext.add( new RulerPainter() );
+        canvasContext.add( new BackgroundPainter() );
+
+        h.setHint(Hints.KEY_GRID_COLOR, new Color(0.95f, 0.95f, 0.95f));
+        h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.WHITE);
+        h.setHint(RulerPainter.KEY_RULER_BACKGROUND_COLOR, new Color(0.9f, 0.9f, 0.9f, 0.75f));
+        h.setHint(RulerPainter.KEY_RULER_TEXT_COLOR, Color.BLACK);
+
+        // Key bindings
+        canvasContext.add( new KeyToCommand( CommandKeyBinding.DEFAULT_BINDINGS ) );
+
+        ////// Diagram Participants //////
+        // FIXME: PointerInteractor must be given a provider for all element classes defined in class ElementClasses !!
+        canvasContext.add( new PointerInteractor(true, true, true, false, true, ElementClassProviders.staticProvider(EdgeClass.STRAIGHT)) );
+        canvasContext.add( new ElementInteractor() );
+        canvasContext.add( new Selection() );
+        canvasContext.add( new DiagramParticipant() );
+        canvasContext.add( new ElementPainter() );
+        canvasContext.add( new TerminalPainter(true, true, false, true) );
+        canvasContext.add( new ElementHeartbeater() );
+        canvasContext.add( new ZOrderHandler() );
+        canvasContext.add( new ZoomTransitionParticipant(TransitionFunction.SIGMOID) );
+        canvasContext.add(new CanvasBoundsParticipant());
+
+        canvasContext.add( new TooltipParticipant());
+
+        h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);
+
+
+        return canvasContext;
+    }
+
+    public static IDiagram createMultilevelDiagram(ICanvasContext ctx)
+    {
+        IDiagram loading = LoadingMessageDiagram.createLoadingDiagram();
+        IDiagram d1 = createDiagram1();
+        IDiagram d2 = createDiagram2();
+        IDiagram d3 = createDiagram3();
+        validate(d1, ctx);
+        validate(d2, ctx);
+        validate(d3, ctx);
+
+        LayerComposition composition = new LayerComposition();
+        composition.addLayer(d1, null, 2.0);
+        composition.addLayer(d2, 5.0, 7.0);
+        composition.addLayer(d3, 10.0, null);
+        List<LayerInfo> lis = composition.buildMorphLayers();
+        loading.setHint(DiagramHints.KEY_LAYER_COMPOSITION, lis);
+        return loading;
+    }
+
+    /**
+     * Create diagram editor
+     * 
+     * @param thread
+     * @param resource
+     * @param localSession
+     * @return
+     */
+    public static CanvasContext createTestCanvas(IThreadWorkQueue thread)
+    {
+        // Create canvas context and a layer of interactors
+        CanvasContext canvasContext = createDefaultCanvas(thread);
+        IHintContext h = canvasContext.getDefaultHintContext();
+        h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);
+
+        ////// CREATE DIAGRAM //////
+        IDiagram wd = createWidgetsDiagram();
+//        IDiagram d1 = createDiagram1();
+//        IDiagram d2 = createDiagram2();
+//        IDiagram d3 = createDiagram3();
+//        IDiagram od = createOperationSymbolsDiagram();
+//        IDiagram uid = createUIDiagram(ElementUtils.getByData(od, "BoilerBtn"));
+        IDiagram uid = createUIDiagram();
+//        IDiagram loading = LoadingMessageDiagram.createLoadingDiagram();
+
+//        validate(d1, canvasContext);
+//        validate(d2, canvasContext);
+//        validate(d3, canvasContext);
+
+        /*
+        LayerComposition composition = new LayerComposition();
+        composition.addLayer(d1, null, 2.0);
+        composition.addLayer(d2, 5.0, 7.0);
+        composition.addLayer(d3, 10.0, null);
+        List<LayerInfo> lis = composition.buildMorphLayers();
+        canvasContext.add( new ZoomTransitionParticipant(lis, TransitionFunction.SIGMOID) );
+         */
+
+//        IDiagram d = loading;
+        //h.setHint(DiagramHints.KEY_DIAGRAM, d);
+        h.setHint(DiagramHints.KEY_DIAGRAM, uid);
+
+        /*
+        final IElement button = ElementUtils.getByData(wd, "button");
+        System.out.println(button.getDiagram());
+               ElementUtils.addClickListener(button, canvasContext, new ClickListener() {
+                       @Override
+                       public void onClick(IElement e, ICanvasContext ctx) {
+                               Point2D pos = ElementUtils.getPos(button);
+                               pos = new Point2D.Double(pos.getX()+10, pos.getY());
+                               ElementUtils.setPos(e, pos);
+                       }});
+         */
+
+        // Draw UI Layer on top of the diagram
+
+        /*
+               ICanvasContext subCanvas = createDefaultCanvas(canvasContext.getThreadAccess());
+               subCanvas.remove( subCanvas.getSingleItem(RulerPainter.class) );
+               subCanvas.remove( subCanvas.getSingleItem(BackgroundPainter.class) );
+               subCanvas.remove( subCanvas.getSingleItem(GridPainter.class) );
+               subCanvas.remove( subCanvas.getSingleItem(TimeParticipant.class) );
+               subCanvas.add( new KeepZoomToFit() );
+               subCanvas.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, uid);
+               subCanvas.getDefaultHintContext().setHint(PanZoomRotateHandler.KEY_ZOOM_TO_FIT_MARGINS, MarginUtils.MARINGS5);
+               canvasContext.add( new SubCanvas(subCanvas, 10000, RulerPainter.PAINT_PRIORITY + 100, 10000) );
+         */
+//        ElementDiagram ed = new ElementDiagram(canvasContext) {
+//            @Override
+//            public ICanvasContext createCanvas(IThreadWorkQueue thread) {
+//                ICanvasContext subCanvas = createDefaultCanvas(thread);
+//                subCanvas.remove( subCanvas.getSingleItem(RulerPainter.class) );
+//                subCanvas.remove( subCanvas.getSingleItem(BackgroundPainter.class) );
+//                subCanvas.remove( subCanvas.getSingleItem(GridPainter.class) );
+//                subCanvas.remove( subCanvas.getSingleItem(TimeParticipant.class) );
+//                subCanvas.add( new KeepZoomToFit() );
+//                subCanvas.getDefaultHintContext().setHint(DiagramHints.KEY_MARGINS, MarginUtils.MARGINS5);
+//                return subCanvas;
+//            }
+//        };
+//        ed.setDiagram(uid);
+
+        return canvasContext;
+    }
+
+    public static IDiagram createUIDiagram(IElement forElement)
+    {
+        String name = "User Interface Diagram";
+        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);
+        d.setHint(DiagramHints.KEY_TEXT, name);
+
+        IElement film = Element.spawnNew(FilmClass.FILM_CLASS);
+        ElementUtils.fitToRectangle(film, new Rectangle2D.Double(0, 10, 200, 160));
+        d.addElement(film);
+
+        IElement preview = Element.spawnNew(CanvasClass.ELEMENT_VIEWPORT_CLASS);
+        preview.setHint(ElementViewport.KEY_ELEMENT, forElement);
+        d.addElement(preview);
+        ElementUtils.fitToRectangle(preview, new Rectangle2D.Double(10, 20, 60, 60));
+        ElementUtils.setBorderColor(preview, Color.WHITE);
+
+        IElement       cancel  = createButton(d, 10 , 140, 50, 20, "Cancel", "Cancel");
+        IElement       apply   = createButton(d, 74 , 140, 50, 20, "Apply", "Apply");
+        IElement       ok              = createButton(d, 134, 140, 50, 20, "OK", "OK");
+        IElement    toggle  = createToggleButton(d, 10, 110, 50, 20, "Toggle", "Toggle");
+
+        String         eleName = "?";
+        Text           text    = forElement.getElementClass().getAtMostOneItemOfClass(Text.class);
+        if (text!=null) eleName = text.getText(forElement);
+        IElement       nameLbl = createLabel(d, 10, 90, "nameLbl", eleName);
+        ElementUtils.setTextColor(nameLbl, Color.WHITE);
+
+        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));
+
+        return d;
+    }
+
+    public static IDiagram createUIDiagram()
+    {
+        String name = "User Interface Diagram";
+        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);
+        d.setHint(DiagramHints.KEY_TEXT, name);
+
+        IElement film = Element.spawnNew(FilmClass.FILM_CLASS);
+        ElementUtils.fitToRectangle(film, new Rectangle2D.Double(0, 10, 200, 160));
+        d.addElement(film);
+
+//        IElement preview = Element.spawnNew(CanvasClass.ELEMENT_VIEWPORT_CLASS);
+//        preview.setHint(ElementViewport.KEY_ELEMENT, forElement);
+//        d.addElement(preview);
+//        ElementUtils.fitToRectangle(preview, new Rectangle2D.Double(10, 20, 60, 60));
+//        ElementUtils.setBorderColor(preview, Color.WHITE);
+
+        IElement       cancel  = createButton(d, 10 , 140, 50, 20, "Cancel", "Cancel");
+        IElement       apply   = createButton(d, 74 , 140, 50, 20, "Apply", "Apply");
+        IElement       ok              = createButton(d, 134, 140, 50, 20, "OK", "OK");
+        IElement    toggle  = createToggleButton(d, 10, 110, 50, 20, "Toggle", "Toggle");
+
+//        String               eleName = "?";
+//        Text         text    = forElement.getElementClass().getAtMostOneItemOfClass(Text.class);
+//        if (text!=null) eleName = text.getText(forElement);
+//        IElement     nameLbl = createLabel(d, 10, 90, "nameLbl", eleName);
+//        ElementUtils.setTextColor(nameLbl, Color.WHITE);
+        toggle.setHint(TooltipParticipant.TOOLTIP_KEY, new TextTooltipProvider() {
+
+            @Override
+            public String getTooltipText(IElement element) {
+                return element.toString();
+            }
+        });
+        apply.setHint(TooltipParticipant.TOOLTIP_KEY, new EditableTextTooltipProvider2() {
+
+            @Override
+            public void setText(IElement element, String text) {
+                ElementUtils.setText(element, text);
+            }
+
+            @Override
+            public String getTooltipText(IElement element) {
+                return ElementUtils.getText(element);
+            }
+        });
+
+        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));
+
+        return d;
+    }
+
+    public static IDiagram createConnectTestDiagram()
+    {
+        String name = "Diagram";
+        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);
+        d.setHint(DiagramHints.KEY_TEXT, name);
+
+        IElement box1 = createBox(d, 0, 0, 70, 70, C4, "1");
+        IElement box2 = createBox(d, 120, 0, 80, 70, C4, "2");
+        connect(d, box1, 4, box2, 8);
+        createLabel(d, 50, 90, "label", name);
+
+        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));
+
+        return d;
+    }
+
+    public static IDiagram createAnchorTestDiagram()
+    {
+        String name = "Diagram";
+        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);
+        d.setHint(DiagramHints.KEY_TEXT, name);
+
+        IElement box1 = createBox(d, 0, 0, 70, 70, C4, "1");
+        IElement box2 = createBox(d, 120, 0, 80, 70, C4, "2");
+        IElement box3 = createBox(d, 30, 90, 40, 40, C3, "3");
+
+        ElementParentTransform pt = (ElementParentTransform)box3.getElementClass().getSingleItem(ParentTransform.class);
+        pt.setParent(box3, box2);
+
+        connect(d, box1, 4, box2, 8);
+        createLabel(d, 50, 90, "label", name);
+
+        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));
+
+        return d;
+    }
+
+
+    public static IDiagram createFlagTestDiagram()
+    {
+        String name = "Diagram";
+        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);
+        d.setHint(DiagramHints.KEY_TEXT, name);
+
+        IElement e1 = createFlag(d, -100, 0, 0, FlagClass.Type.In, C4, "I3", "From Z");
+        IElement e2 = createFlag(d, -80, 20, 90, FlagClass.Type.In, C4, "I2", "From Y");
+        IElement e3 = createFlag(d, -100, 40, 180, FlagClass.Type.Out, C4, "I1", "To X");
+        IElement e4 = createFlag(d, -120, 20, 270, FlagClass.Type.Out, C4, "I4", "To W");
+        IElement e5 = createFlag(d, -120, 120, 270, FlagClass.Type.Out, C4, "I5", "To P");
+
+        e1.setHint(FlagClass.KEY_FLAG_TEXT, new String[]{"THIS" });
+        e2.setHint(FlagClass.KEY_FLAG_TEXT, new String[]{"THIS", "is"});
+        e3.setHint(FlagClass.KEY_FLAG_TEXT, new String[]{"THIS", "is", "DEBUG"});
+        e4.setHint(FlagClass.KEY_FLAG_TEXT, new String[]{"THIS", "is", "DEBUG", "INFO"});
+        e5.setHint(FlagClass.KEY_FLAG_TEXT, new String[]{"THIS", "is", "DEBUG", "INFO", "FOO!"});
+
+//        createFlag(d, 300, 40, 0, FlagClass.Type.Out, C3, "O3", "To Z", FlagClass.Mode.Minimized);
+//        createFlag(d, 280, 20, 90, FlagClass.Type.Out, C3, "O4", "To W", FlagClass.Mode.Minimized);
+//        createFlag(d, 300, 00, 180, FlagClass.Type.Out, C3, "O1", "To X", FlagClass.Mode.Minimized);
+//        createFlag(d, 320, 20, 270, FlagClass.Type.Out, C3, "O2", "To Y", FlagClass.Mode.Minimized);
+
+        createFlag(d, 100, 50, 0, FlagClass.Type.Out, C2, "J1O", "O", FlagClass.Mode.Internal);
+        createFlag(d, 100, 100, 0, FlagClass.Type.Out, C2, "J2O", "Oy", FlagClass.Mode.Internal);
+        createFlag(d, 100, 150, 90, FlagClass.Type.Out, C2, "J3O", "OAAAA", FlagClass.Mode.Internal);
+        createFlag(d, 150, 50, 0, FlagClass.Type.In, C2, "J1I", "I", FlagClass.Mode.Internal);
+        createFlag(d, 150, 100, 0, FlagClass.Type.In, C2, "J2I", "Iy", FlagClass.Mode.Internal);
+        createFlag(d, 150, 150, 90, FlagClass.Type.In, C2, "J3I", "IAAAA", FlagClass.Mode.Internal);
+
+        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));
+
+        return d;
+    }
+
+    public static IDiagram createDiagram1()
+    {
+        String name = "Diagram Level 1";
+        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);
+        d.setHint(DiagramHints.KEY_TEXT, name);
+
+        IElement box1 = createBox(d, 0, 0, 70, 70, C4, "1");
+        IElement box2 = createBox(d, 120, 0, 80, 70, C4, "2");
+        connect(d, box1, 4, box2, 8);
+        createLabel(d, 50, 90, "label", name);
+
+        IElement slider = createSlider(d, 600, 0, 100, 28, "slider");
+        IElement valve = createValve (d, 800, 0, "valve");
+        //IElement wheel =  createWheel (d, 500, 100, 100, 100, "wheel");
+        IElement button = createButton(d, 800, 100, 100, 28, "button", "button");
+
+        IElement image = createImage(d, 400, 400, DefaultImages.UNKNOWN.get());
+
+        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));
+
+        return d;
+    }
+
+
+    public static IDiagram createDiagram2()
+    {
+        String name = "Diagram Level 2";
+        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);
+        d.setHint(DiagramHints.KEY_TEXT, name);
+
+        IElement box1  = createBox(d, 0, 30, 70, 10, C3, "1");
+        IElement box1_1 = createBox(d, 20, 0, 50, 20, C2, "1.1");
+        IElement box1_2 = createBox(d, 0, 50, 70, 20, C2, "1.2");
+        IElement box2  = createBox(d, 120, 0, 20, 70, C3, "2");
+        IElement box2_2 = createBox(d, 150, 0, 50, 20, C2, "2.2");
+        IElement box2_3 = createBox(d, 150, 30, 50, 40, C2, "2.3");
+        connect(d, box1, 4, box2, 8);
+        connect(d, box1, 2, box1_1, 6);
+        connect(d, box1, 6, box1_2, 2);
+        connect(d, box2, 4, box2_2, 8);
+        connect(d, box2, 4, box2_3, 8);
+        createLabel(d, 50, 90, "label", name);
+
+        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));
+
+        return d;
+    }
+
+    public static IDiagram createDiagram3()
+    {
+        String name = "Diagram Level 3";
+        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);
+        d.setHint(DiagramHints.KEY_TEXT, name);
+
+        IElement box1          = createBox(d, 0, 30, 70, 10, C3, "1");
+        IElement box1_1        = createBox(d, 30, 0, 40, 20, C2, "1.1");
+        IElement box1_1_1      = createBox(d, 00, 0, 20, 20, C2, "1.1.1");
+        IElement box1_2        = createBox(d, 30, 50, 40, 20, C2, "1.2");
+        IElement box1_2_1      = createBox(d, 0, 50, 20, 20, C1, "1.2.1");
+        IElement box2          = createBox(d, 120, 30, 20, 40, C3, "2");
+        IElement box2_1        = createBox(d, 120, 0, 20, 20, C2, "2.1");
+        IElement box2_2        = createBox(d, 150, 0, 20, 20, C2, "2.2");
+        IElement box2_2_1      = createBox(d, 180, 0, 20, 20, C1, "2.2.1");
+        IElement box2_3        = createBox(d, 150, 30, 20, 20, C2, "2.3");
+        IElement box2_3_1      = createBox(d, 180, 30, 20, 20, C1, "2.3.1");
+        IElement box2_3_2      = createBox(d, 180, 60, 20, 20, C1, "2.3.2");
+        connect(d, box1, 4, box2, 8);
+        connect(d, box1, 2, box1_1, 6);
+        connect(d, box1_1, 8, box1_1_1, 4);
+        connect(d, box1, 6, box1_2, 2);
+        connect(d, box1_2, 8, box1_2_1, 4);
+        connect(d, box2, 2, box2_1, 6);
+        connect(d, box2, 3, box2_2, 7);
+        connect(d, box2_2, 4, box2_2_1, 8);
+        connect(d, box2, 4, box2_3, 8);
+        connect(d, box2_3, 4, box2_3_1, 8);
+        connect(d, box2_3, 5, box2_3_2, 1);
+        createLabel(d, 50, 90, "label", name);
+
+        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));
+
+        return d;
+    }
+
+    public static IDiagram createWidgetsDiagram()
+    {
+        String name = "Test Diagram";
+        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);
+        d.setHint(DiagramHints.KEY_TEXT, name);
+
+        //IElement slider = createSlider(d, 0, 100, 100, 28, "slider");
+        IElement valve = createValve (d, 0, 0, "valve");
+        //IElement wheel = createWheel(d, 0, 0, 100, 100, "wheel");
+        //IElement button = createButton(d, 0, 0, 100, 28, "button", "button");
+
+        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));
+
+        return d;
+    }
+
+    public static IDiagram createOperationSymbolsDiagram()
+    {
+        String name = "Operation Symbols Diagram";
+        IDiagram d = Diagram.spawnNew(DiagramClass.DEFAULT);
+        d.setHint(DiagramHints.KEY_TEXT, name);
+        /*
+               createSymbol(d, OperationClasses.BOILER_CLASS, 0, 0, "Boiler");
+               createSymbol(d, OperationClasses.COMPRESSOR_CLASS, 50, 0, "Compressor");
+               createSymbol(d, OperationClasses.CONTROLVALVE_CLASS, 100, 0, "Control Valve");
+               createSymbol(d, OperationClasses.HEATEXCHANGER_CLASS, 0, 50, "HeatExchanger");
+               createSymbol(d, OperationClasses.PUMP_CLASS, 50, 50, "Pump");
+               createSymbol(d, OperationClasses.SHUTOFFVALVE_CLASS, 100, 50, "Shutoff Valve");
+               createSymbol(d, OperationClasses.SWITCH_CLASS, 0, 100, "Switch");
+               createSymbol(d, OperationClasses.TURBINE_CLASS, 50, 100, "Turbine");
+               createSymbol(d, OperationClasses.VOLTAGETRANSFORMER_CLASS, 100, 100, "Voltage Transformer");
+
+               createSymbol(d, OperationClasses.BOILER_BUTTON_CLASS, 0, 200, "BoilerBtn");
+               createSymbol(d, OperationClasses.COMPRESSOR_BUTTON_CLASS, 50, 200, "CompressorBtn");
+               createSymbol(d, OperationClasses.CONTROLVALVE_BUTTON_CLASS, 100, 200, "Control ValveBtn");
+               createSymbol(d, OperationClasses.HEATEXCHANGER_BUTTON_CLASS, 0, 250, "HeatExchangerBtn");
+               createSymbol(d, OperationClasses.PUMP_BUTTON_CLASS, 50, 250, "Pump");
+               createSymbol(d, OperationClasses.SHUTOFFVALVE_BUTTON_CLASS, 100, 250, "Shutoff ValveBtn");
+               createSymbol(d, OperationClasses.SWITCH_BUTTON_CLASS, 0, 300, "SwitchBtn");
+               createSymbol(d, OperationClasses.TURBINE_BUTTON_CLASS, 50, 300, "TurbineBtn");
+               createSymbol(d, OperationClasses.VOLTAGETRANSFORMER_BUTTON_CLASS, 100, 300, "Voltage TransformerBtn");
+         */
+        createShape(d, new Ellipse2D.Double(-10, -10, 20, 20), -50, 0, Color.RED, "circle");
+
+        d.setHint(DiagramHints.KEY_MUTATOR, new DummyDiagramMutator(d));
+
+        return d;
+    }
+
+    public static IElement createSymbol(IDiagram d, ElementClass clazz, double x, double y, Object dada)
+    {
+        IElement box = Element.spawnNew( clazz );
+        d.addElement(box);
+        Move m = box.getElementClass().getSingleItem(Move.class);
+        m.moveTo(box, x, y);
+        box.setHint(ElementHints.KEY_TEXT, dada.toString());
+        box.setHint(ElementHints.KEY_OBJECT, dada);
+        return box;
+    }
+
+
+    public static IElement createBox(IDiagram d, double x, double y, double width, double height, Color color, Object dada)
+    {
+        IElement box = Element.spawnNew( BoxClass.BOXCLASS.newClassWith(ElementParentTransform.INSTANCE) );
+        d.addElement(box);
+        Move m = box.getElementClass().getSingleItem(Move.class);
+        Resize s = box.getElementClass().getSingleItem(Resize.class);
+        FillColor ch = box.getElementClass().getSingleItem(FillColor.class);
+        ch.setFillColor(box, color);
+        m.moveTo(box, x, y);
+        s.resize(box, new Rectangle2D.Double(0,0,width, height));
+        box.setHint(ElementHints.KEY_TEXT, dada.toString());
+        box.setHint(ElementHints.KEY_OBJECT, dada);
+        return box;
+    }
+
+    private static IElement createImage(IDiagram d, int x, int y, Image image) {
+        IElement result = Element.spawnNew( ImageClass.INSTANCE );
+        d.addElement(result);
+        ElementUtils.setPos(result, x, y);
+        result.setHint(ElementHints.KEY_IMAGE, image);
+        return result;
+    }
+
+    public static IElement createShape(IDiagram d, Shape shape, double x, double y, Color color, Object dada)
+    {
+        IElement box = Element.spawnNew( ShapeClass.CIRCLE_CLASS );
+        d.addElement(box);
+        Move m = box.getElementClass().getSingleItem(Move.class);
+        FillColor ch = box.getElementClass().getSingleItem(FillColor.class);
+        ch.setFillColor(box, color);
+        m.moveTo(box, x, y);
+        box.setHint(ElementHints.KEY_TEXT, dada.toString());
+        box.setHint(ElementHints.KEY_OBJECT, dada);
+        return box;
+    }
+
+    public static IElement createSlider(IDiagram d, double x, double y, double width, double height, Object dada)
+    {
+        IElement e = Element.spawnNew( SliderClass.SLIDER );
+        d.addElement(e);
+        Move m = e.getElementClass().getSingleItem(Move.class);
+        Resize s = e.getElementClass().getSingleItem(Resize.class);
+        m.moveTo(e, x, y);
+        s.resize(e, new Rectangle2D.Double(0,0,width, height));
+        e.setHint(ElementHints.KEY_OBJECT, dada);
+        return e;
+    }
+
+    public static IElement createValve(IDiagram d, double x, double y, Object dada)
+    {
+        IElement e = Element.spawnNew( ValveClass.INSTANCE );
+        d.addElement(e);
+        Move m = e.getElementClass().getSingleItem(Move.class);
+        m.moveTo(e, x, y);
+        e.setHint(ElementHints.KEY_OBJECT, dada);
+        return e;
+    }
+
+    public static IElement createWheel(IDiagram d, double x, double y, double width, double height, Object dada)
+    {
+        IElement e = Element.spawnNew( WheelClass.WHEEL );
+        d.addElement(e);
+
+        ElementUtils.fitToRectangle(e, new Rectangle2D.Double(x, y, width, height));
+
+        //Move m = e.getElementClass().getSingleItem(Move.class);
+        //Scale s = e.getElementClass().getSingleItem(Scale.class);
+        //m.move(e, new Point2D.Double(x, y));
+        //Point2D s.getScale(e)
+        //s.setScale(e, newScale)
+        e.setHint(ElementHints.KEY_OBJECT, dada);
+        return e;
+    }
+
+    public static IElement createLabel(IDiagram d, double x, double y, Object dada, String label)
+    {
+        IElement e = Element.spawnNew( LabelClass.CLASS );
+        d.addElement(e);
+        Move m = e.getElementClass().getSingleItem(Move.class);
+        m.moveTo(e, x, y);
+
+        ElementUtils.setText(e, label);
+
+        e.setHint(ElementHints.KEY_OBJECT, dada);
+        return e;
+    }
+
+    public static IElement createButton(IDiagram d, double x, double y, double width, double height, Object dada, String label)
+    {
+        IElement e = Element.spawnNew( ButtonClass.BUTTON_CLASS );
+        d.addElement(e);
+        Move m = e.getElementClass().getSingleItem(Move.class);
+        m.moveTo(e, x, y);
+        Resize s = e.getElementClass().getSingleItem(Resize.class);
+        s.resize(e, new Rectangle2D.Double(0,0,width, height));
+        Text t = e.getElementClass().getSingleItem(Text.class);
+        t.setText(e, label);
+        e.setHint(ElementHints.KEY_OBJECT, dada);
+        return e;
+    }
+
+    public static IElement createFlag(IDiagram d, double x, double y, double dir, FlagClass.Type type, Color color, Object dada, String label)
+    {
+        return createFlag(d, x, y, dir, type, color, dada, label, FlagClass.Mode.External);
+    }
+
+    public static IElement createFlag(IDiagram d, double x, double y, double dir, FlagClass.Type type, Color color, Object dada, String label, FlagClass.Mode mode)
+    {
+        IElement f = Element.spawnNew( FlagClass.FLAGCLASS );
+        d.addElement(f);
+        Move m = f.getElementClass().getSingleItem(Move.class);
+        FillColor ch = f.getElementClass().getSingleItem(FillColor.class);
+        ch.setFillColor(f, color);
+        m.moveTo(f, x, y);
+        Text t = f.getElementClass().getSingleItem(Text.class);
+        t.setText(f, label);
+        f.setHint(ElementHints.KEY_OBJECT, dada);
+        f.setHint(FlagClass.KEY_FLAG_TYPE, type);
+        f.setHint(FlagClass.KEY_FLAG_MODE, mode);
+        return f;
+    }
+
+    public static IElement createToggleButton(IDiagram d, double x, double y, double width, double height, Object dada, String label)
+    {
+        IElement e = Element.spawnNew( ToggleButtonClass.BUTTON_CLASS );
+        d.addElement(e);
+        Move m = e.getElementClass().getSingleItem(Move.class);
+        m.moveTo(e, x, y);
+        Resize s = e.getElementClass().getSingleItem(Resize.class);
+        s.resize(e, new Rectangle2D.Double(0,0,width, height));
+        Text t = e.getElementClass().getSingleItem(Text.class);
+        t.setText(e, label);
+        e.setHint(ElementHints.KEY_OBJECT, dada);
+        return e;
+    }
+
+    public static IElement connect(IDiagram d, IElement e1, int t1, IElement e2, int t2)
+    {
+        List<Terminal> boxTerminals = new ArrayList<Terminal>();
+        TerminalTopology boxNodeHandler = e1.getElementClass().getSingleItem(TerminalTopology.class);
+        boxNodeHandler.getTerminals(e1, boxTerminals);
+        Terminal _t1 = boxTerminals.get(t1);
+
+        boxTerminals.clear();
+        boxNodeHandler = e2.getElementClass().getSingleItem(TerminalTopology.class);
+        boxNodeHandler.getTerminals(e2, boxTerminals);
+        Terminal _t2 = boxTerminals.get(t2);
+
+        IElement edge = Element.spawnNew(EdgeClass.STRAIGHT);
+        d.addElement(edge);
+
+        Object e1dada = e1.getHint(ElementHints.KEY_OBJECT);
+        Object e2dada = e2.getHint(ElementHints.KEY_OBJECT);
+        if (e1dada!=null && e2dada!=null)
+            edge.setHint(ElementHints.KEY_OBJECT, e1dada +" to "+e2dada);
+
+        Topology topology = d.getDiagramClass().getSingleItem(Topology.class);
+        topology.connect(edge, EdgeEnd.Begin, e1, _t1);
+        topology.connect(edge, EdgeEnd.End, e2, _t2);
+        return edge;
+    }
+
+    public static void validate(IDiagram d, ICanvasContext ctx)
+    {
+        // Validate
+        ArrayList<Issue> issues = new ArrayList<Issue>();
+        for (Validator v : d.getDiagramClass().getItemsByClass(Validator.class))
+        {
+            v.validate(d, ctx, issues);
+        }
+        List<Suggestion> suggestions = new ArrayList<Suggestion>();
+        for (Issue i : issues)
+        {
+            suggestions.clear();
+            i.addSuggestions(d, ctx, suggestions);
+            if (suggestions.size()==0) continue;
+            suggestions.get(0).fix(d, ctx);
+        }
+
+    }
+
+}