]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Editable multi-line text elements
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 25 Nov 2013 13:17:28 +0000 (13:17 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 25 Nov 2013 13:17:28 +0000 (13:17 +0000)
refs #2929

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28372 ac1ea38d-2e2b-0410-8846-a27921b304fc

20 files changed:
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/AuxiliaryFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextElementHandler.java [deleted file]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextElementNoBounds.java [deleted file]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextNode.java [deleted file]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/InputFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleNode.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextElement.java [deleted file]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextElementFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextNode.java [deleted file]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/StockFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementNoBounds.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowConnectionFactory.java

index c25ac8ec198915d4fe076cc48b7efa69aa401104..40e523b1860d804bbdf79660c74c29e5dc7bc1cb 100644 (file)
@@ -16,8 +16,8 @@ import java.awt.geom.Ellipse2D;
 import java.util.Collection;\r
 \r
 import org.simantics.db.Resource;\r
+import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\r
 import org.simantics.g2d.element.ElementClass;\r
-import org.simantics.g2d.element.IElement;\r
 import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
 import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
 import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
@@ -32,7 +32,6 @@ import org.simantics.g2d.element.handler.impl.TextImpl;
 import org.simantics.g2d.image.Image;\r
 import org.simantics.g2d.image.impl.ShapeImage;\r
 import org.simantics.g2d.utils.Alignment;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
 \r
 /**\r
  * @author Tuukka Lehtonen\r
@@ -53,27 +52,12 @@ public class AuxiliaryFactory extends SysdynElementFactory {
                 new StaticObjectAdapter(elementType),\r
                 new StaticSymbolImpl(AUX_STATIC_IMAGE),\r
                 StaticSymbolImageInitializer.INSTANCE,\r
-                new AuxiliarySceneGraph(0, 0, Alignment.LEADING, 0, 1.5, 1.5, true),\r
+                new SysdynTextElementHandler(0, 0, Alignment.LEADING, 0, 1.5, 1.5, true),\r
                 BoundsOutline.INSTANCE,\r
+                ResizeRectangularSceneGraph.INSTANCE,\r
+                RESIZE_PROPERTY_SETTER,   \r
                 new WholeElementTerminals(terminals)\r
         ).setId(AuxiliaryFactory.class.getSimpleName());\r
     }\r
-    \r
-    public static class AuxiliarySceneGraph extends HoverTextElementHandler {\r
-\r
-               private static final long serialVersionUID = -7077873654863790864L;\r
-               \r
-               public AuxiliarySceneGraph(double i, double j, Alignment leading, double k, double d,\r
-                               double e, boolean b) {\r
-                       super(i, j, leading, k, d, e, b);\r
-               }\r
-\r
-               @Override\r
-               public void init(IElement e, G2DParentNode parent) {\r
-                       super.init(e, parent);\r
-                       unflipText(e);\r
-               }\r
-\r
-    }\r
        \r
 }\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextElementHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextElementHandler.java
deleted file mode 100644 (file)
index 5621765..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
- * 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.sysdyn.ui.elements;\r
-\r
-import java.awt.Font;\r
-import java.awt.font.FontRenderContext;\r
-import java.awt.font.TextLayout;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Rectangle2D;\r
-\r
-import org.simantics.g2d.element.ElementHints;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.InternalSize;\r
-import org.simantics.g2d.utils.Alignment;\r
-\r
-public class HoverTextElementHandler extends HoverTextElementNoBounds implements InternalSize {\r
-\r
-    private static final long serialVersionUID = 8800738238681432901L;\r
-\r
-    public static final HoverTextElementHandler INSTANCE         = new HoverTextElementHandler();\r
-\r
-    public HoverTextElementHandler() {\r
-        super();\r
-    }\r
-\r
-    public HoverTextElementHandler(double originX, double originY, Alignment horizontalAlignment) {\r
-        super(originX, originY, horizontalAlignment);\r
-    }\r
-\r
-    public HoverTextElementHandler(double originX, double originY, Alignment horizontalAlignment, double borderWidth) {\r
-        super(originX, originY, horizontalAlignment, borderWidth);\r
-    }\r
-\r
-    public HoverTextElementHandler(double originX, double originY, Alignment horizontalAlignment, double borderWidth,\r
-            double paddingX, double paddingY, boolean editable) {\r
-        super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable);\r
-    }\r
-\r
-    @Override\r
-    public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
-        HoverTextNode node = (HoverTextNode) e.getHint(SG_NODE);\r
-        if (size == null)\r
-            size = new Rectangle2D.Double();\r
-        if (node != null)\r
-            size.setRect(node.getBoundsInLocal());\r
-        else {\r
-            String text = e.getHint(ElementHints.KEY_TEXT);\r
-            Font font = e.getHint(ElementHints.KEY_FONT);\r
-            if(text == null || font == null)\r
-                size.setFrame(0, 0, 0, 0);\r
-            else {\r
-                FontRenderContext FRC = new FontRenderContext(new AffineTransform(), true, true);\r
-                TextLayout tl = new TextLayout(text, font, FRC);\r
-                Rectangle2D bounds = tl.getLogicalHighlightShape(0, text.length()).getBounds2D();   \r
-                size.setFrame(\r
-                        bounds.getX() * SCALE - paddingX,\r
-                        bounds.getY() * SCALE -paddingY, \r
-                        bounds.getWidth()* SCALE + paddingX + paddingX, \r
-                        bounds.getHeight()* SCALE + paddingY + paddingY);\r
-            }\r
-        }\r
-        return size;\r
-    }\r
-}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextElementNoBounds.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextElementNoBounds.java
deleted file mode 100644 (file)
index d007651..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/*******************************************************************************\r
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
- * 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.sysdyn.ui.elements;\r
-\r
-import java.awt.Color;\r
-import java.awt.Font;\r
-import java.awt.geom.AffineTransform;\r
-\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.ui.IWorkbenchPage;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.ReadRequest;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.diagram.elements.DiagramNodeUtil;\r
-import org.simantics.diagram.elements.ITextListener;\r
-import org.simantics.diagram.elements.TextElementNoBounds;\r
-import org.simantics.diagram.elements.TextNode;\r
-import org.simantics.diagram.participant.SGFocusParticipant;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.chassis.SWTChassis;\r
-import org.simantics.g2d.diagram.DiagramUtils;\r
-import org.simantics.g2d.diagram.IDiagram;\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.LifeCycle;\r
-import org.simantics.g2d.utils.Alignment;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.ModelingResources;\r
-import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
-import org.simantics.modeling.ui.diagramEditor.DiagramViewer;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
-import org.simantics.sysdyn.SysdynResource;\r
-import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
-import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
-import org.simantics.ui.SimanticsUI;\r
-import org.simantics.utils.datastructures.Callback;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-import org.simantics.utils.datastructures.hints.IHintListener;\r
-import org.simantics.utils.datastructures.hints.IHintObservable;\r
-\r
-/**\r
- * ElementHandler for text elements\r
- * In-line editing supported.\r
- * \r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- */\r
-public class HoverTextElementNoBounds extends TextElementNoBounds implements LifeCycle {\r
-\r
-       private static final long serialVersionUID = -148784588840819612L;\r
-\r
-       public static final HoverTextElementNoBounds INSTANCE         = new HoverTextElementNoBounds();\r
-\r
-       static class HoverHintListener implements IHintListener {\r
-               @Override\r
-               public void hintRemoved(IHintObservable sender, Key key, Object oldValue) {\r
-               }\r
-               @Override\r
-               public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
-                       if (key == ElementHints.KEY_HOVER) {\r
-                               IElement e = (IElement)sender;\r
-                               TextNode name = (TextNode) e.getHint(SG_NODE);\r
-                               if (name != null)\r
-                                       name.setHover(Boolean.TRUE.equals(e.getHint(ElementHints.KEY_HOVER)));\r
-                       }\r
-               }\r
-       }\r
-\r
-       protected static IHintListener hoverHintListener = new HoverHintListener();\r
-\r
-       public HoverTextElementNoBounds() {\r
-               super(0, 0, Alignment.LEADING, 0);\r
-       }\r
-\r
-       public HoverTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment) {\r
-               super(originX, originY, horizontalAlignment, 0);\r
-       }\r
-\r
-       public HoverTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth) {\r
-               super(originX, originY, horizontalAlignment, borderWidth);\r
-       }\r
-\r
-       public HoverTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth, double paddingX, double paddingY, boolean editable) {\r
-               super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable);\r
-       }\r
-\r
-       protected HoverTextNode getTextNode(IElement e, G2DParentNode parent) {\r
-               return ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", HoverTextNode.class, getCallback(e, parent, HoverTextNode.class));\r
-       }\r
-               \r
-       protected <T extends HoverTextNode> Callback<T> getCallback(final IElement e, G2DParentNode parent, Class<T> nodeClass) {\r
-               return new Callback<T>() {\r
-                       @Override\r
-                       public void run(T node) {\r
-                               node.setTextListener(new ITextListener() {\r
-\r
-                                       String textBeforeEdit;\r
-                                       Resource component;\r
-\r
-                                       @Override\r
-                                       public void textChanged() {\r
-                                               TextNode node = (TextNode) e.getHint(SG_NODE);\r
-                                               if(!new VariableNameValidator().isValid(component, node.getText(), false)) {\r
-                                                       node.setColor(Color.RED);\r
-                                               } else {\r
-                                                       node.setColor(ElementUtils.getTextColor(e, Color.BLACK));\r
-                                               }\r
-\r
-\r
-                                       }\r
-\r
-                                       @Override\r
-                                       public void textEditingStarted() {\r
-                                               TextNode node = (TextNode) e.getHint(SG_NODE);\r
-                                               textBeforeEdit = node.getText();\r
-\r
-                                               if(component != null) return;\r
-                                               \r
-                                               Object o = e.getHint(ElementHints.KEY_OBJECT);\r
-                                               if(o != null && o instanceof Resource) {\r
-                                                       final Resource element = (Resource)o;\r
-                                                       SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
-\r
-                                                               @Override\r
-                                                               public void run(ReadGraph graph) throws DatabaseException {\r
-                                                                       component = graph.getPossibleObject(element, ModelingResources.getInstance(graph).ElementToComponent);\r
-                                                               }\r
-                                                       });\r
-                                               }\r
-                                       }\r
-\r
-                                       @Override\r
-                                       public void textEditingCancelled() {\r
-                                               TextNode node = (TextNode) e.getHint(SG_NODE);\r
-                                               if (node != null) {\r
-                                                       if(new VariableNameValidator().isValid(component, node.getText(), false))\r
-                                                               node.setColor(ElementUtils.getTextColor(e, Color.BLACK));\r
-                                                       endEdit(node);\r
-                                               }\r
-                                       }\r
-\r
-                                       @Override\r
-                                       public void textEditingEnded() {\r
-                                               TextNode node = (TextNode) e.getHint(SG_NODE);\r
-                                               if (node == null)\r
-                                                       return;\r
-                                               String text = node.getText();\r
-                                               if(!new VariableNameValidator().isValid(component, text, false)) {\r
-                                                       text = textBeforeEdit;\r
-                                                       node.setText(text);\r
-                                                       if(new VariableNameValidator().isValid(component, text, false))\r
-                                                               node.setColor(ElementUtils.getTextColor(e, Color.BLACK));\r
-                                               } else {\r
-                                                       Object o = e.getHint(ElementHints.KEY_OBJECT);\r
-                                                       final String textAfterEdit = text;\r
-                                                       if(o != null && o instanceof Resource) {\r
-                                                               SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
-                                                                   @Override\r
-                                                                   public void perform(WriteGraph graph) throws DatabaseException {\r
-                                                                       Resource configuration = graph.getPossibleObject(component, Layer0.getInstance(graph).PartOf);\r
-                                                                       new VariableNameValidator().renameInAllEquations(graph, configuration, textBeforeEdit, textAfterEdit);\r
-                                                                   }\r
-                                                               });\r
-                                                       }\r
-                                               }\r
-                                               ElementUtils.setText(e, text);\r
-                                               IDiagram diagram = ElementUtils.getDiagram(e);\r
-                                               DiagramUtils.synchronizeHintsToBackend(diagram, e);\r
-                                               endEdit(node);\r
-                                       }\r
-                               });\r
-                       }\r
-               };\r
-       }\r
-       \r
-       public static double SCALE = 0.235;\r
-\r
-       protected void initNode(IElement e, HoverTextNode node) {\r
-               //Font font = new Font("Tahoma", 0, 12);\r
-               Font font = ElementUtils.getTextFont(e);\r
-               Color color = ElementUtils.getTextColor(e);\r
-               Color fillColor = ElementUtils.getFillColor(e);\r
-               Color borderColor = ElementUtils.getBorderColor(e, Color.BLACK);\r
-               String text = ElementUtils.getText(e);\r
-               AffineTransform at = ElementUtils.getTransform(e);\r
-        Alignment hAlign = ElementUtils.getHintOrDefault(e, ElementHints.KEY_HORIZONTAL_ALIGN, horizontalAlignment);\r
-               node.init(text, font, color, originX, originY, SCALE);\r
-               node.setBackgroundColor(fillColor);\r
-               node.setBorderColor(borderColor);\r
-        node.setHorizontalAlignment((byte) hAlign.ordinal());\r
-               node.setPadding(paddingX, paddingY);\r
-               node.setBorderWidth((float) borderWidth);\r
-               node.setEditable(editable);\r
-               if(at != null)\r
-                       node.setTransform(at);\r
-       }\r
-       \r
-       public static void unflipText(IElement e) {\r
-               Object o = e.getHint(SG_NODE);\r
-               if (o instanceof TextNode) {\r
-                       TextNode text = (TextNode)o;\r
-                   AffineTransform at = text.getTransform();\r
-                   double x = at.getTranslateX();\r
-                   double y = at.getTranslateY();\r
-                   at.setToRotation(0);\r
-                   at.setToTranslation(x, y);\r
-                   at.setTransform(at);\r
-               }\r
-       }\r
-       \r
-       protected void activateEdit(final HoverTextNode node, final IElement e) {\r
-               final ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(node);\r
-        // FIXME: needed only because eventdelegator registrations are done before adding node to scene graph.\r
-        if (ctx == null)\r
-            return;\r
-        if (!node.isEditMode()) {\r
-               \r
-               // Get the active editor\r
-               IWorkbenchPage page = SysdynWorkbenchUtils.getActivePageOfEditor();\r
-               final DiagramEditor editor = (DiagramEditor)page.getActiveEditor();\r
-            final ICanvasContext editorCtx = (ICanvasContext) editor.getViewer().getAdapter(ICanvasContext.class);\r
-\r
-            editor.getViewer().getComposite().getDisplay().asyncExec(new Runnable() {\r
-                    \r
-                @Override\r
-                public void run() {\r
-                       Control c = editor.getViewer().getComposite().getDisplay().getFocusControl();\r
-                       if (c == null || "BasicSymbols".equals(c.getParent().getToolTipText())) {\r
-                       // If the variable has been drag and dropped, set focus to diagram and then activate edit.\r
-                               \r
-                               editorCtx.add(new SGFocusParticipant((SWTChassis)editor.getViewer().getComposite(), DiagramViewer.DIAGRAMMING_CONTEXT) {\r
-                \r
-                               @Override\r
-                               public void focusGained(java.awt.event.FocusEvent event) {\r
-                                               \r
-                                       // When focus has been gained, acticate edit and destroy the listener.\r
-                                       editor.getViewer().getComposite().getDisplay().asyncExec(new Runnable() {\r
-                                           \r
-                                           @Override\r
-                                           public void run() {\r
-                                                       if (Boolean.TRUE.equals(node.setEditMode(true))) {\r
-                                                               node.activateEdit(0, e, ctx, true);\r
-                                                               node.repaint();\r
-                                                       }\r
-                                           }\r
-                                       });\r
-                                       ctx.remove(this);\r
-                               }\r
-                               \r
-                               @Override\r
-                               public void focusLost(java.awt.event.FocusEvent e) {\r
-                               }\r
-                       });\r
-                       \r
-                               editor.setFocus();\r
-                       } else {\r
-                               // If the variable has been created with shortcut key, just activate the edit.\r
-                        if (Boolean.TRUE.equals(node.setEditMode(true))) {\r
-                               node.activateEdit(0, e, ctx, true);\r
-                                       node.repaint();\r
-                               }\r
-                       }\r
-                }\r
-            });        \r
-        }\r
-       }\r
-       \r
-       @Override\r
-       public void init(final IElement e, G2DParentNode parent) {\r
-               final HoverTextNode node = getTextNode(e, parent);\r
-               initNode(e, node);\r
-\r
-               Object o = e.getHint(ElementHints.KEY_OBJECT);\r
-               if (o instanceof Resource) {\r
-                       final Resource element = (Resource)o;\r
-                       try {\r
-                               SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
-       \r
-                                       @Override\r
-                                       public void perform(WriteGraph graph) throws DatabaseException {\r
-                                               SysdynResource SR = SysdynResource.getInstance(graph);\r
-                                               ModelingResources MR = ModelingResources.getInstance(graph);\r
-                                               Resource component = graph.getPossibleObject(element, MR.ElementToComponent);\r
-                                               if (component == null)\r
-                                                       return;\r
-                                               \r
-                                               // See if the resource of the element has just been created. \r
-                                               Resource r = graph.getPossibleObject(component, SR.IndependentVariable_isUninitialized);\r
-                                               if (r == null){\r
-                                                       return;\r
-                                               }\r
-                                               \r
-                                               // If the resource is just been created, activate editing its name.\r
-                                               if (!graph.isInstanceOf(r, SR.Loop)) {\r
-                                                       activateEdit(node, e);\r
-                                               }\r
-                                   graph.deny(component, SR.IndependentVariable_isUninitialized, r);\r
-                                       }\r
-                               });\r
-                       } catch (DatabaseException e1) {\r
-                               e1.printStackTrace();\r
-                       }\r
-               }\r
-       }\r
-\r
-       @Override\r
-       public void cleanup(IElement e) {\r
-           ElementUtils.removePossibleNode(e, SG_NODE);\r
-       }\r
-\r
-       @Override\r
-       public void onElementCreated(IElement e) {\r
-       }\r
-\r
-       @Override\r
-       public void onElementDestroyed(IElement e) {\r
-       }\r
-\r
-       @Override\r
-       public void onElementActivated(IDiagram d, IElement e) {\r
-               e.addKeyHintListener(ElementHints.KEY_HOVER, hoverHintListener);\r
-       }\r
-\r
-       @Override\r
-       public void onElementDeactivated(IDiagram d, IElement e) {\r
-           e.removeKeyHintListener(ElementHints.KEY_HOVER, hoverHintListener);\r
-       }\r
-\r
-}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextNode.java
deleted file mode 100644 (file)
index 24f3ab1..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*******************************************************************************\r
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
- * 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.sysdyn.ui.elements;\r
-\r
-import java.awt.BasicStroke;\r
-import java.awt.Color;\r
-import java.awt.Graphics2D;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-\r
-import org.simantics.diagram.elements.DiagramNodeUtil;\r
-import org.simantics.diagram.elements.TextEditActivation;\r
-import org.simantics.diagram.elements.TextNode;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.scenegraph.ISelectionPainterNode;\r
-import org.simantics.scenegraph.g2d.events.EventTypes;\r
-import org.simantics.scenegraph.g2d.events.FocusEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;\r
-import org.simantics.scenegraph.utils.NodeUtil;\r
-import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
-\r
-public class HoverTextNode extends TextNode implements ISelectionPainterNode {\r
-\r
-    private static final long serialVersionUID = 3539499125943249895L;\r
-
-    protected static transient ThreadLocal<Rectangle2D> tempBounds = new ThreadLocal<Rectangle2D>() {\r
-        @Override\r
-        protected Rectangle2D initialValue() {\r
-            return new Rectangle2D.Double();\r
-        }\r
-    };\r
-\r
-    @Override\r
-    public void render(Graphics2D g) {\r
-        if (text == null || font == null || color == null)\r
-            return;\r
-\r
-        AffineTransform ot = g.getTransform();\r
-        g.transform(transform);\r
-\r
-        boolean selected = NodeUtil.isSelected(this, 1);\r
-        if (!selected && hover){\r
-            BasicStroke oldStroke = (BasicStroke)g.getStroke();\r
-            Color oldColor = g.getColor();\r
-            g.setColor(Color.LIGHT_GRAY);\r
-            g.setStroke(new BasicStroke((float)(2.0f)));\r
-            g.scale(scale, scale);\r
-            g.translate(x, y);\r
-            g.draw(expandBoundsUnscaled(getTightAlignedBoundsInLocal(tempBounds.get(), g.getFontRenderContext())));\r
-            g.translate(-x, -y);\r
-            g.scale(scaleRecip, scaleRecip);\r
-            g.setColor(oldColor);\r
-            g.setStroke(oldStroke);\r
-            \r
-        }\r
-\r
-        super.render(g, false);\r
-        g.setTransform(ot);\r
-    }\r
-    \r
-    @Override\r
-    public void remove() {\r
-        super.remove();\r
-        removeEventHandler(this);\r
-    }\r
-    \r
-    @Override\r
-    public int getEventMask(){\r
-               return EventTypes.FocusLostMask | super.getEventMask();\r
-       }\r
-    \r
-    @Override\r
-    protected boolean handleFocusEvent(FocusEvent e) {\r
-        int eventType = EventTypes.toType(e);\r
-        if (eventType == EventTypes.FocusLost){\r
-            //If focus of the element (and the diagram) is lost, save the name of the node\r
-            fireTextEditingEnded();\r
-        }\r
-        return false;\r
-    }\r
-    \r
-    @Override\r
-    protected boolean mouseClicked(MouseClickEvent event) {\r
-        if (event.button != MouseClickEvent.LEFT_BUTTON)\r
-            return false;\r
-        \r
-        if (hitTest(event, 0)) {\r
-               hoverClick++;\r
-               if (hoverClick < 2)\r
-                       return false;\r
-            ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(this);\r
-            // FIXME: needed only because eventdelegator registrations are done before adding node to scene graph.\r
-            if (ctx == null)\r
-                return false;\r
-            IElement e = DiagramNodeUtil.getElement(ctx, this);\r
-            if (!isEditMode()) {\r
-               if (Boolean.TRUE.equals(setEditMode(true))) {\r
-                       editActivation = activateEdit(0, e, ctx);\r
-                       repaint();\r
-               }\r
-            } \r
-        } else {\r
-               hoverClick = 0;\r
-            if (isEditMode()) {\r
-                fireTextEditingEnded();\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-    \r
-    @Override\r
-    protected boolean mouseDoubleClicked(MouseDoubleClickedEvent event) {\r
-       if (event.button != MouseClickEvent.LEFT_BUTTON)\r
-            return false;\r
-        \r
-        if (hitTest(event, 0)) {\r
-            ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(this);\r
-            // FIXME: needed only because eventdelegator registrations are done before adding node to scene graph.\r
-            if (ctx == null)\r
-                return false;\r
-            \r
-            if (text != null) {\r
-               // Select the whole text.\r
-               setCaret(0, false);\r
-               setCaret(text.length(), true);\r
-                   repaint();\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    @Override\r
-    protected boolean mouseButtonPressed(MouseButtonPressedEvent event) {\r
-        if (!isShiftDown(event)) {\r
-               return super.mouseButtonPressed(event);\r
-        }\r
-        \r
-        // Select text if shift is down.\r
-        if (!isEditMode())\r
-            return false;\r
-        \r
-        Point2D local = controlToLocal( event.controlPosition );\r
-        // FIXME: once the event coordinate systems are cleared up, remove this workaround\r
-        local = parentToLocal(local);\r
-        if (hover && this.containsLocal(local)) {\r
-            setCaret(local, true);\r
-        }\r
-        return false;\r
-    }\r
-    \r
-    @Override\r
-    protected boolean mouseDragged(MouseDragBegin e) {\r
-       // Disable dragging if LockSketch is ON\r
-               if (SysdynElementHints.LOCK_TOOL.equals(SysdynWorkbenchUtils.getSysdynToolMode())){\r
-                       super.mouseDragged(e);\r
-                       return true;}\r
-               else\r
-                       return super.mouseDragged(e);\r
-    }\r
-\r
-    public TextEditActivation activateEdit(int mouseId, IElement e, ICanvasContext ctx, boolean save) {\r
-       if (save)\r
-               return editActivation = super.activateEdit(mouseId, e, ctx);\r
-       return super.activateEdit(mouseId, e, ctx);\r
-    }\r
-}\r
index 859dd10952687a03ecb8d6e55e79c21bc8be2841..7f0aca6abab2a2835d78923c3c243f0068979a8d 100644 (file)
@@ -26,6 +26,7 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.exception.MissingVariableException;\r
 import org.simantics.db.layer0.variable.Variable;\r
 import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\r
 import org.simantics.diagram.elements.TextNode;\r
 import org.simantics.diagram.stubs.DiagramResource;\r
 import org.simantics.diagram.ui.DiagramModelHints;\r
@@ -38,7 +39,6 @@ import org.simantics.g2d.element.SceneGraphNodeKey;
 import org.simantics.g2d.element.handler.InternalSize;\r
 import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
 import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
-import org.simantics.g2d.element.handler.impl.HoverImpl;\r
 import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
 import org.simantics.g2d.element.handler.impl.OutlinePick;\r
 import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
@@ -92,7 +92,8 @@ public class InputFactory extends SysdynElementFactory {
                 Input.INSTANCE,\r
                 new InputSceneGraph(0, 0, Alignment.LEADING, 0, 1.5, 1.5, true),\r
                 BoundsOutline.INSTANCE,\r
-                HoverImpl.INSTANCE,\r
+                ResizeRectangularSceneGraph.INSTANCE,\r
+                RESIZE_PROPERTY_SETTER,                    \r
                 new WholeElementTerminals(terminals)\r
         ).setId(InputFactory.class.getSimpleName());\r
     }\r
@@ -165,11 +166,10 @@ public class InputFactory extends SysdynElementFactory {
         Font font = ElementUtils.getTextFont(e);\r
         font = font.deriveFont(font.getStyle());\r
         ElementUtils.setTextFont(e, font);\r
-        ElementUtils.setHover(e, false);\r
     }\r
 \r
 \r
-    public static class InputSceneGraph extends HoverTextElementNoBounds implements InternalSize {\r
+    public static class InputSceneGraph extends SysdynTextElementNoBounds implements InternalSize {\r
 \r
         private static final long   serialVersionUID = -3713275157729126409L;\r
         public static final Key     INPUT_SG_NODE          = new SceneGraphNodeKey(TextNode.class, "INPUT_SG_NODE");\r
index 8ea6915ff5e167604fb1d639b94b60359fb7189c..e8f11057555cca39e780dd9bb298de7e239173ab 100644 (file)
@@ -235,7 +235,7 @@ public class LoopFactory extends SysdynElementFactory {
         * @author Tuomas Miettinen\r
         *\r
         */\r
-       public static class LoopSceneGraph extends HoverTextElementNoBounds  implements HandleMouseEvent {\r
+       public static class LoopSceneGraph extends SysdynTextElementNoBounds  implements HandleMouseEvent {\r
 \r
                private static final long serialVersionUID = -5093461687773246286L;\r
 \r
@@ -286,7 +286,7 @@ public class LoopFactory extends SysdynElementFactory {
                }\r
 \r
                @Override\r
-               protected <T extends HoverTextNode> Callback<T> getCallback(final IElement e, G2DParentNode parent, Class<T> nodeClass) {\r
+               protected <T extends SysdynTextNode> Callback<T> getCallback(final IElement e, G2DParentNode parent, Class<T> nodeClass) {\r
                        return new Callback<T>() {\r
                                @Override\r
                                public void run(T node) {\r
index a7f9b15f2e7532ebc1d2b50b4c0d142c8d4bcb63..be30fe1ff326166cd3ba5d1d1cf4ca66541ab8b4 100644 (file)
@@ -18,6 +18,8 @@ import java.awt.geom.Rectangle2D;
 import java.util.Collection;\r
 \r
 import org.simantics.db.Resource;\r
+import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\r
+import org.simantics.diagram.elements.TextNode;\r
 import org.simantics.g2d.element.ElementClass;\r
 import org.simantics.g2d.element.ElementUtils;\r
 import org.simantics.g2d.element.IElement;\r
@@ -59,12 +61,14 @@ public class ModuleFactory extends SysdynElementFactory {
                 new ModuleSceneGraph(0, 0, Alignment.LEADING, 1f , 2, 3, true),\r
                 BoundsOutline.INSTANCE,\r
                 new BorderColorImpl(Color.BLACK),\r
+                ResizeRectangularSceneGraph.INSTANCE,\r
+                RESIZE_PROPERTY_SETTER,                   \r
                 new WholeElementTerminals(terminals)\r
         ).setId(ModuleFactory.class.getSimpleName());\r
     }\r
     \r
     \r
-    public static class ModuleSceneGraph extends HoverTextElementHandler implements InternalSize {\r
+    public static class ModuleSceneGraph extends SysdynTextElementHandler implements InternalSize {\r
 \r
                private static final long       serialVersionUID = 2367230056477661273L;\r
         \r
@@ -73,14 +77,11 @@ public class ModuleFactory extends SysdynElementFactory {
                super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable);\r
         }\r
                \r
-               @Override\r
-               public void init(IElement e, G2DParentNode parent) {\r
-                       super.init(e, parent);\r
-                       unflipText(e);\r
-               }\r
                \r
-               protected HoverTextNode getTextNode(IElement e, G2DParentNode parent) {\r
-                       return ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", ModuleNode.class, getCallback(e, parent, ModuleNode.class));\r
+               \r
+               @Override\r
+               protected TextNode getOrCreateTextNode(IElement e, G2DParentNode parent) {\r
+            return ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", ModuleNode.class, getCallback(e, parent, ModuleNode.class));\r
                }\r
 \r
     }\r
index fa8439192a512cd1615b1d41ba12b41edfc12f8f..73afad886a070d18eb3f7f640241cff4d79b09ff 100644 (file)
@@ -16,14 +16,13 @@ import java.awt.BasicStroke;
 import java.awt.Color;\r
 import java.awt.Composite;\r
 import java.awt.Graphics2D;\r
-import java.awt.geom.AffineTransform;\r
 import java.awt.geom.Path2D;\r
 import java.awt.geom.Rectangle2D;\r
 \r
 import org.simantics.scenegraph.utils.GeometryUtils;\r
 import org.simantics.scenegraph.utils.NodeUtil;\r
 \r
-public class ModuleNode extends HoverTextNode {\r
+public class ModuleNode extends SysdynTextNode {\r
 \r
        private static final long serialVersionUID = 8535695797227320496L;\r
     private static double              CORNER_LENGTH    = 2.0; \r
@@ -34,15 +33,10 @@ public class ModuleNode extends HoverTextNode {
     public void render(Graphics2D g) {\r
        super.render(g);\r
        \r
-        AffineTransform ot = g.getTransform();\r
         BasicStroke oldStroke = (BasicStroke)g.getStroke();\r
         Color oldColor = g.getColor();\r
 \r
-        g.transform(transform);\r
-        // Apply separate legacy scale\r
-\r
-        \r
-        Rectangle2D bounds = expandBounds( getTightAlignedBoundsInLocal( tempBounds.get() ) );\r
+        Rectangle2D bounds = getBounds();\r
 \r
         \r
         Path2D path = new Path2D.Double();\r
@@ -66,7 +60,6 @@ public class ModuleNode extends HoverTextNode {
         path.lineTo(bounds.getMaxX() + CORNER_PADDING, bounds.getMaxY() + CORNER_PADDING);\r
         path.lineTo(bounds.getMaxX() + CORNER_PADDING, bounds.getMaxY() - CORNER_LENGTH);\r
         \r
-        g.translate(x, y);\r
         g.setStroke(new BasicStroke((float) (/*scale**/scale*borderWidth)));       \r
         g.setColor(borderColor);\r
         g.draw(path);   \r
@@ -87,16 +80,12 @@ public class ModuleNode extends HoverTextNode {
             }\r
             g.setStroke(new BasicStroke(bw));\r
             g.draw(path);\r
-            //g.draw(GeometryUtils.expandRectangle(r, 1.0));\r
 \r
             g.setComposite(oc);\r
         }\r
 \r
         g.setColor(oldColor);\r
         g.setStroke(oldStroke);\r
-        g.translate(-x, -y);\r
-        \r
-        g.setTransform(ot);\r
 \r
     }\r
 \r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextElement.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextElement.java
deleted file mode 100644 (file)
index f71c420..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************\r
- * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
- * 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.sysdyn.ui.elements;\r
-\r
-import java.awt.Color;\r
-import java.awt.Font;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Rectangle2D;\r
-\r
-import org.simantics.diagram.elements.TextElementNoBounds;\r
-import org.simantics.diagram.elements.TextNode;\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.utils.Alignment;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-import org.simantics.utils.datastructures.hints.IHintListener;\r
-import org.simantics.utils.datastructures.hints.IHintObservable;\r
-\r
-/**\r
- * Multi-line text element\r
- * \r
- * @author Teemu Lempinen\r
- *\r
- */\r
-public class MultilineTextElement extends TextElementNoBounds {\r
-\r
-    public MultilineTextElement(double originX, double originY, Alignment horizontalAlignment, double borderWidth, double paddingX, double paddingY, boolean editable) {\r
-        super(originX, originX, horizontalAlignment, borderWidth, paddingX, paddingY, editable);\r
-    }\r
-\r
-    private static final long serialVersionUID = -8558567466321214111L;\r
-\r
-    @Override\r
-    public void init(final IElement e, G2DParentNode parent) {\r
-        MultilineTextNode node = e.getHint(SG_NODE);\r
-        if(node == null) {\r
-            node = parent.addNode(MultilineTextNode.class);\r
-            e.setHint(SG_NODE, node);\r
-        }\r
-\r
-        Font font = ElementUtils.getTextFont(e);\r
-        Color color = ElementUtils.getTextColor(e);\r
-        Color fillColor = ElementUtils.getFillColor(e);\r
-        Color borderColor = ElementUtils.getBorderColor(e, Color.GRAY);\r
-        String text = ElementUtils.getText(e);\r
-        AffineTransform at = ElementUtils.getTransform(e);\r
-        Alignment hAlign = ElementUtils.getHintOrDefault(e, ElementHints.KEY_HORIZONTAL_ALIGN, horizontalAlignment);\r
-        node.init(text, font, color, originX, originY, 0.235);\r
-        node.setBackgroundColor(fillColor);\r
-        node.setBorderColor(borderColor);\r
-        node.setHorizontalAlignment((byte) hAlign.ordinal());\r
-        node.setPadding(paddingX, paddingY);\r
-        node.setBorderWidth((float) 1);\r
-        node.setEditable(false); // Multiline text fields are not editable\r
-        \r
-        Rectangle2D bounds = ElementUtils.getElementBounds(e);\r
-        node.setBounds(new Rectangle2D.Double(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight())); // Multiline text fields have fixed bounds\r
-        if(at != null)\r
-            node.setTransform(at);\r
-    }\r
-\r
-}\r
index b63810ec39142263a8a0023a4174dcf592e3ac4b..d6b56d0a54b6309e2d6e724e154c1ae94a01d3fc 100644 (file)
  *******************************************************************************/\r
 package org.simantics.sysdyn.ui.elements;\r
 \r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Rectangle2D;\r
-\r
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
-import org.simantics.db.common.utils.NameUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.diagram.G2DUtils;\r
 import org.simantics.diagram.adapter.TextElementClassFactory;\r
-import org.simantics.diagram.elements.ElementPropertySetter;\r
-import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.diagram.stubs.G2DResource;\r
-import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
 import org.simantics.g2d.canvas.ICanvasContext;\r
 import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.element.ElementClass;\r
 import org.simantics.g2d.element.ElementHints;\r
-import org.simantics.g2d.element.ElementHints.Properties;\r
-import org.simantics.g2d.element.ElementUtils;\r
 import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.Text;\r
-import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
-import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
-import org.simantics.g2d.element.handler.impl.OutlinePick;\r
-import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
-import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
-import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;\r
-import org.simantics.g2d.element.handler.impl.TextColorImpl;\r
-import org.simantics.g2d.element.handler.impl.TextFontImpl;\r
-import org.simantics.g2d.image.DefaultImages;\r
-import org.simantics.g2d.image.Image;\r
-import org.simantics.g2d.svg.SVGImage;\r
-import org.simantics.g2d.utils.Alignment;\r
 \r
 /**\r
  * Multi-line text element used in comment in sysdyn diagrams\r
@@ -53,74 +27,10 @@ import org.simantics.g2d.utils.Alignment;
  */\r
 public class MultilineTextElementFactory extends TextElementClassFactory {\r
 \r
-    private static final Size SIZE = new Size(new Rectangle2D.Double(0, 0, 17, 7));\r
-    private static final MultilineTextElement ELEMENT = new MultilineTextElement(0, 0, Alignment.LEADING, 1, 1.8, 1.8, false);\r
-    private static final ElementPropertySetter RESIZE_PROPERTY_SETTER =\r
-            new ElementPropertySetter(ResizeRectangularSceneGraph.KEY_SG_NODE);\r
-    \r
-    @Override\r
-    public ElementClass create(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType) throws DatabaseException {\r
-        String id = "MultilineTextElement: " + NameUtils.getSafeName(graph, elementType);\r
-        G2DResource g2d = G2DResource.getInstance(graph);\r
-        String svgDoc = graph.getPossibleRelatedValue(elementType, g2d.HasSVGDocument);\r
-        Image image = null;\r
-        if (svgDoc != null)\r
-            image = new SVGImage(id+".svg", svgDoc);\r
-        else\r
-            image = DefaultImages.ERROR_DECORATOR.get();\r
-        return ElementClass.compile(\r
-                Text.INSTANCE,\r
-                TextColorImpl.BLACK,\r
-                TextFontImpl.DEFAULT,\r
-                new StaticObjectAdapter(elementType),\r
-                DefaultTransform.INSTANCE,\r
-                SimpleElementLayers.INSTANCE,\r
-                new StaticSymbolImpl(image),\r
-\r
-                ELEMENT, // Changes to TextElementClassFactory start from here\r
-                SIZE,\r
-                ResizeRectangularSceneGraph.INSTANCE,\r
-                RESIZE_PROPERTY_SETTER,\r
-                BoundsOutline.INSTANCE,\r
-                OutlinePick.INSTANCE// To here\r
-                ).setId(id);\r
-    }\r
-    \r
-    \r
     @Override\r
-    public void load(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource element, IElement e) throws DatabaseException {\r
+    public void load(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource element, IElement e)\r
+            throws DatabaseException {\r
         super.load(graph, canvas, diagram, element, e);\r
-        \r
-        ElementPropertySetter ps = e.getElementClass().getSingleItem(\r
-                ElementPropertySetter.class);\r
-        ps.loadProperties(e, element, graph);\r
-        \r
-        // Set some hints.. (In future these should be removed)\r
-        Properties properties = e.getHint(ElementHints.KEY_ELEMENT_PROPERTIES);\r
-        if (properties.containsKey("Bounds")) {\r
-            e.setHint(ElementHints.KEY_BOUNDS,\r
-                    (Rectangle2D) properties.get("Bounds"));\r
-        }\r
-        \r
-        // Hack for disabling all rotations in chart elements\r
-        AffineTransform at = DiagramGraphUtil.getAffineTransform(graph, element);\r
-        double x = at.getTranslateX();\r
-        double y = at.getTranslateY();\r
-        at.setToRotation(0);\r
-        at.setToTranslation(x, y);\r
-        ElementUtils.setTransform(e, at); // Set hint transform without rotations\r
-        ps.overrideProperty(e, "Transform", at); // Set property Transform without rotations\r
-        \r
-        DiagramResource DIA = DiagramResource.getInstance(graph);\r
-        G2DResource G2D = G2DResource.getInstance(graph);\r
-        if (graph.isInstanceOf(element, DIA.ColorProvider)) {\r
-            Resource colorResource = graph.getPossibleObject(element,\r
-                    G2D.HasColor);\r
-            if (colorResource != null)\r
-                ElementUtils.setTextColor(e,\r
-                        G2DUtils.getColor(graph, colorResource));\r
-        }\r
+        e.setHint(ElementHints.KEY_RESIZABLE, true);\r
     }\r
-\r
-\r
 }\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextNode.java
deleted file mode 100644 (file)
index 4b27ba0..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-/*******************************************************************************\r
- * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
- * 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.sysdyn.ui.elements;\r
-\r
-import java.awt.AlphaComposite;\r
-import java.awt.BasicStroke;\r
-import java.awt.Color;\r
-import java.awt.Composite;\r
-import java.awt.Font;\r
-import java.awt.FontMetrics;\r
-import java.awt.Graphics2D;\r
-import java.awt.font.LineBreakMeasurer;\r
-import java.awt.font.TextAttribute;\r
-import java.awt.font.TextLayout;\r
-import java.awt.geom.Rectangle2D;\r
-import java.text.AttributedCharacterIterator;\r
-import java.text.AttributedString;\r
-import java.util.ArrayList;\r
-import java.util.Hashtable;\r
-\r
-import org.simantics.diagram.elements.TextNode;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;\r
-import org.simantics.scenegraph.utils.GeometryUtils;\r
-import org.simantics.scenegraph.utils.NodeUtil;\r
-import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
-\r
-/**\r
- * Multi-line text node for diagrams. Editing is not \r
- * implemented yet. \r
- *  \r
- * @author Teemu Lempinen\r
- *\r
- */\r
-public class MultilineTextNode extends TextNode {\r
-\r
-    protected PositionedText[] precomputedLayout;\r
-    protected Rectangle2D bounds;\r
-\r
-    /**\r
-     * Auxiliary class for drawing positioned text\r
-     * @author Teemu Lempinen\r
-     *\r
-     */\r
-    class PositionedText {\r
-        float drawPosX;\r
-        float drawPosY;\r
-        TextLayout layout;      \r
-\r
-        public PositionedText(float drawPosX, float drawPosY, TextLayout layout) {\r
-            this.drawPosX = drawPosX;\r
-            this.drawPosY = drawPosY;\r
-            this.layout = layout;\r
-        }\r
-\r
-        public void render(Graphics2D g) {\r
-            layout.draw(g, drawPosX, drawPosY);\r
-        }\r
-    }\r
-\r
-    private static final long serialVersionUID = -1900821098537908613L;\r
-\r
-    @SyncField({ "bounds" })\r
-    public void setBounds(Rectangle2D bounds) {\r
-        this.bounds = bounds;\r
-    }\r
-\r
-    @Override\r
-    public void init(String text, Font font, Color color, double x, double y, double scale) {\r
-        super.init(text, font, color, x, y, scale);\r
-        resetPrecompudedLayout();\r
-    }\r
-\r
-    @Override\r
-    public void setText(String text) {\r
-        super.setText(text);\r
-        resetPrecompudedLayout();\r
-    }\r
-\r
-    @Override\r
-    public void setFont(Font font) {\r
-        super.setFont(font);\r
-        resetPrecompudedLayout();\r
-    }\r
-    \r
-    @Override\r
-    public void setHover(boolean hover) {\r
-        super.setHover(hover);\r
-        resetPrecompudedLayout();\r
-    }\r
-    \r
-    /**\r
-     * Reset layout cache\r
-     */\r
-    private void resetPrecompudedLayout() {\r
-        precomputedLayout = null;\r
-    }\r
-\r
-    /**\r
-     * Compute layout for multi-row text\r
-     * @param g Graphics2D\r
-     * @param color Font color\r
-     */\r
-    private void precomputeLayout(Graphics2D g, Color color) {\r
-        ArrayList<PositionedText> precomputedLayout = \r
-                new ArrayList<PositionedText>();\r
-\r
-        Hashtable<TextAttribute, Object> map = new Hashtable<TextAttribute, Object>();\r
-\r
-        map.put(TextAttribute.FONT, font);\r
-        map.put(TextAttribute.FOREGROUND, color);\r
-\r
-        AttributedString attributedText = new AttributedString(text.isEmpty() ? "__ERROR__" : text, map);\r
-\r
-        AttributedCharacterIterator paragraph = attributedText.getIterator();\r
-        int paragraphStart = paragraph.getBeginIndex();\r
-        int paragraphEnd = paragraph.getEndIndex();\r
-        LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(paragraph, FRC);\r
-\r
-        if(bounds == null) {\r
-            System.err.println("bounds==null in MultilineTextNode");\r
-            return;\r
-        }\r
-\r
-        float textAreaWidth = (float) scaleRecip * ((float) bounds.getWidth() - 2 * (float) paddingX);\r
-        float breakWidth = textAreaWidth;\r
-\r
-        // Force text to be vertical, by setting break width to 1, if the text area is narrower than "GGGG"\r
-        FontMetrics fm = g.getFontMetrics(font);\r
-        Rectangle2D stringBounds = fm.getStringBounds(text, g);\r
-        Rectangle2D lowerLimitBounds = fm.getStringBounds("GGGG", g);\r
-        if(breakWidth < stringBounds.getWidth() && breakWidth < lowerLimitBounds.getWidth())\r
-            breakWidth = 1;\r
-\r
-        // Maximum height\r
-        float breakHeight = (float) scaleRecip * ((float) bounds.getHeight() - 2 * (float) paddingY);\r
-\r
-        if(breakWidth <= 0 || breakHeight <= 0) {\r
-            return;\r
-        }\r
-\r
-        float drawPosY = 0;\r
-        // Set position to the index of the first character in the paragraph.\r
-        lineMeasurer.setPosition(paragraphStart);\r
-\r
-        // Get lines until the entire paragraph has been displayed.\r
-        int next, limit, charat, position = 0;\r
-        while ((position = lineMeasurer.getPosition()) < paragraphEnd) {\r
-\r
-            // Find possible line break and set it as a limit to the next layout\r
-            next = lineMeasurer.nextOffset(breakWidth);\r
-            limit = next;\r
-            charat = text.indexOf(System.getProperty("line.separator"),position+1);\r
-            if(charat < next && charat != -1){\r
-               limit = charat;\r
-            }\r
-\r
-            // Retrieve next layout. A cleverer program would also cache\r
-            // these layouts until the component is re-sized.\r
-            TextLayout layout = lineMeasurer.nextLayout(breakWidth, limit, false);\r
-\r
-            // Compute pen x position. If the paragraph is right-to-left we\r
-            // will align the TextLayouts to the right edge of the panel.\r
-            // Note: this won't occur for the English text in this sample.\r
-            // Note: drawPosX is always where the LEFT of the text is placed.\r
-            float drawPosX = layout.isLeftToRight() ? 0 : breakWidth\r
-                    - layout.getAdvance();\r
-\r
-            // If text has been forced to vertical, align it to center\r
-            if(breakWidth < textAreaWidth) {\r
-                float centerCorrection = layout.isLeftToRight() ? \r
-                        (float) (layout.getAdvance() / 2) : \r
-                            -1 * (float) (layout.getAdvance() / 2);\r
-                        drawPosX = textAreaWidth / 2 - centerCorrection;\r
-            }\r
-\r
-            // Stop drawing if the text won't fit\r
-            if (breakHeight < drawPosY + layout.getDescent()\r
-                    + layout.getLeading()) {\r
-                break;\r
-            }\r
-\r
-            drawPosY += layout.getAscent();\r
-\r
-            // Add TextLayout at (drawPosX, drawPosY).\r
-            precomputedLayout.add(new PositionedText(drawPosX, drawPosY, layout));\r
-\r
-            // Move y-coordinate in preparation for next layout.\r
-            drawPosY += layout.getDescent() + layout.getLeading();\r
-        }\r
-\r
-        this.precomputedLayout = \r
-                precomputedLayout.toArray(new PositionedText[precomputedLayout.size()]);\r
-    }\r
-\r
-    public void render(Graphics2D g, boolean applyTransform) {\r
-        if (text == null || font == null || color == null)\r
-            return;\r
-\r
-        double horizontalAlignOffset = getHorizontalAlignOffset(bounds);\r
-        double verticalAlignOffset = getVerticalAlignOffset();\r
-        \r
-        Color color = this.color;\r
-\r
-        boolean isSelected = NodeUtil.isSelected(this, 1);\r
-\r
-        if (!isSelected && hover) {\r
-            color = add(color, 120, 120, 120);\r
-        }\r
-        \r
-        if (applyTransform)\r
-            g.transform(transform);\r
-\r
-        g.scale(scale, scale);\r
-        g.translate(horizontalAlignOffset, verticalAlignOffset);\r
-\r
-        Rectangle2D r = new Rectangle2D.Double(bounds.getX()  , bounds.getY(), bounds.getWidth() * scaleRecip, bounds.getHeight() * scaleRecip);\r
-        // Draw border if necessary\r
-        if (borderWidth > 0.f) {\r
-            g.setColor(borderColor);\r
-            g.setStroke(new BasicStroke((float) (scale*borderWidth)));\r
-//            g.draw(r); Borders are disabled for now\r
-        }\r
-\r
-        // Fill background if necessary\r
-        if (backgroundColor != null) {\r
-            g.setColor(backgroundColor);\r
-            g.fill(r);\r
-        }\r
-        \r
-        if (isSelected && showsSelection()) {\r
-            Composite oc = g.getComposite();\r
-            g.setComposite(AlphaComposite.SrcAtop.derive(0.5f));\r
-\r
-            g.setColor(Color.RED);\r
-            float bw = borderWidth;\r
-            double s = GeometryUtils.getScale(g.getTransform());\r
-            if (bw <= 0f) {\r
-                bw = (float) (1f / s);\r
-            } else {\r
-                bw *= 5f * scale;\r
-            }\r
-            g.setStroke(new BasicStroke(bw));\r
-            g.draw(r);\r
-\r
-            g.setComposite(oc);\r
-        }\r
-        \r
-        g.setFont(font);\r
-\r
-        // Draw text \r
-        g.translate(x + paddingX * (float) scaleRecip, y + paddingY * (float) scaleRecip);\r
-        if(precomputedLayout == null) {\r
-            precomputeLayout(g, color);        \r
-            if(precomputedLayout == null)\r
-                return;\r
-        }\r
-\r
-        for(PositionedText text : precomputedLayout)\r
-            text.render(g);\r
-\r
-        \r
-        g.setStroke(new BasicStroke(1));\r
-\r
-        g.translate(-horizontalAlignOffset, -verticalAlignOffset);\r
-        g.scale(scaleRecip, scaleRecip);\r
-        \r
-        renderSelectedHover(g, isSelected, hover);\r
-\r
-    }\r
-    \r
-    @Override\r
-    protected boolean mouseDragged(MouseDragBegin e) {\r
-       // Disable dragging if LockSketch is ON\r
-               if (SysdynElementHints.LOCK_TOOL.equals(SysdynWorkbenchUtils.getSysdynToolMode()))\r
-                       return false;\r
-               else\r
-                       return super.mouseDragged(e);\r
-    }\r
-    \r
-}\r
index 6e310e1974f968fe5ad8b483a13bd84d62959f79..726cae6f4db3946851e02b3f48650671f9bbe1cb 100644 (file)
@@ -21,6 +21,8 @@ import java.util.Collection;
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\r
+import org.simantics.diagram.elements.TextElementHandler;\r
 import org.simantics.diagram.synchronization.SynchronizationHints;\r
 import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
 import org.simantics.g2d.canvas.ICanvasContext;\r
@@ -49,7 +51,7 @@ import org.simantics.sysdyn.SysdynResource;
 \r
 public class ShadowFactory extends SysdynElementFactory {\r
 \r
-    private static HoverTextElementHandler shadowHandler = new HoverTextElementHandler(0, 0, Alignment.LEADING, 0.0, 2.0, 2.0, false); \r
+    private static TextElementHandler shadowHandler = new TextElementHandler(0, 0, Alignment.LEADING, 0.0, 2.0, 2.0, false); \r
     private static final TextColorImpl GRAY = new TextColorImpl(java.awt.Color.GRAY);\r
     private static final BasicStroke    STROKE          = new BasicStroke(1f);\r
     public static final Image          GHOST_IMAGE     = new ShapeImage(getGhostShape(), null, STROKE, true);\r
@@ -90,6 +92,8 @@ public class ShadowFactory extends SysdynElementFactory {
                 StaticSymbolImageInitializer.INSTANCE,\r
                 shadowHandler,\r
                 BoundsOutline.INSTANCE,\r
+                ResizeRectangularSceneGraph.INSTANCE,\r
+                RESIZE_PROPERTY_SETTER,    \r
                 new WholeElementTerminals(terminals)\r
         ).setId(ShadowFactory.class.getSimpleName());\r
     }\r
index 13a6ee48be5bc63d71345ce3fccac47946daf778..a821104cbe06ee5e24685f15a8bd20592e179555 100644 (file)
@@ -19,6 +19,7 @@ import java.util.Collection;
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\r
 import org.simantics.g2d.canvas.ICanvasContext;\r
 import org.simantics.g2d.diagram.IDiagram;\r
 import org.simantics.g2d.element.ElementClass;\r
@@ -39,7 +40,6 @@ import org.simantics.g2d.element.handler.impl.TextImpl;
 import org.simantics.g2d.image.Image;\r
 import org.simantics.g2d.image.impl.ShapeImage;\r
 import org.simantics.g2d.utils.Alignment;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
 \r
 public class StockFactory extends SysdynElementFactory {\r
 \r
@@ -58,9 +58,11 @@ public class StockFactory extends SysdynElementFactory {
                 new StaticObjectAdapter(elementType),\r
                 new StaticSymbolImpl(STOCK_IMAGE),\r
                 StaticSymbolImageInitializer.INSTANCE,\r
-                new StockSceneGraph(0, 0, Alignment.LEADING, 1f, 1.0, 1.0, true),\r
+                new SysdynTextElementHandler(0, 0, Alignment.LEADING, 1f, 1.0, 1.0, true),\r
                 BoundsOutline.INSTANCE,\r
                 new BorderColorImpl(Color.BLACK),\r
+                ResizeRectangularSceneGraph.INSTANCE,\r
+                RESIZE_PROPERTY_SETTER,    \r
                 new WholeElementTerminals(terminals)\r
         ).setId(StockFactory.class.getSimpleName());\r
     }\r
@@ -70,23 +72,5 @@ public class StockFactory extends SysdynElementFactory {
         super.load(graph, canvas, diagram, element, e);\r
         e.setHint(ElementHints.KEY_BORDER_COLOR, e.getHint(ElementHints.KEY_TEXT_COLOR));\r
     }\r
-           \r
-    public static class StockSceneGraph extends HoverTextElementHandler {\r
-\r
-               private static final long serialVersionUID = 6635538659448488606L;\r
-\r
-               public StockSceneGraph(double i, double j, Alignment leading, double k, double d,\r
-                               double e, boolean b) {\r
-                       super(i, j, leading, k, d, e, b);\r
-               }\r
-\r
-               @Override\r
-               public void init(IElement e, G2DParentNode parent) {\r
-                       super.init(e, parent);\r
-                       unflipText(e);\r
-               }\r
-\r
-    }\r
-       \r
     \r
 }\r
index 6f7c9043712676656c3eb1c09f7272d66e7b4963..174ae5748fab4c4b33f19e501283bb0fe0fdc2ec 100644 (file)
@@ -14,6 +14,7 @@ package org.simantics.sysdyn.ui.elements;
 import java.awt.Color;\r
 import java.awt.Font;\r
 import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
 import java.util.ArrayList;\r
 import java.util.Collection;\r
 import java.util.Collections;\r
@@ -32,6 +33,8 @@ import org.simantics.db.exception.ServiceException;
 import org.simantics.diagram.G2DUtils;\r
 import org.simantics.diagram.adapter.SyncElementFactory;\r
 import org.simantics.diagram.content.ResourceTerminal;\r
+import org.simantics.diagram.elements.ElementPropertySetter;\r
+import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\r
 import org.simantics.diagram.stubs.DiagramResource;\r
 import org.simantics.diagram.stubs.G2DResource;\r
 import org.simantics.diagram.synchronization.CompositeHintSynchronizer;\r
@@ -66,6 +69,9 @@ public abstract class SysdynElementFactory extends SyncElementFactory {
             ComponentNameSynchronizer.INSTANCE,\r
             TransformSynchronizer.INSTANCE);\r
 \r
+    public static final ElementPropertySetter RESIZE_PROPERTY_SETTER =\r
+            new ElementPropertySetter(ResizeRectangularSceneGraph.KEY_SG_NODE);\r
+    \r
     protected String getText(ReadGraph graph, Resource element) throws DatabaseException {\r
        Layer0 l0 = Layer0.getInstance(graph);\r
         ModelingResources mr = ModelingResources.getInstance(graph);\r
@@ -81,6 +87,7 @@ public abstract class SysdynElementFactory extends SyncElementFactory {
     \r
     @Override\r
     public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException {\r
+        e.setHint(ElementHints.KEY_RESIZABLE, true);\r
        ElementUtils.setText(e, getText(graph, element));\r
        // Just testing loop finding.\r
        //ModelingResources mr = ModelingResources.getInstance(graph);\r
@@ -153,6 +160,11 @@ public abstract class SysdynElementFactory extends SyncElementFactory {
             font = font.deriveFont(Font.BOLD);\r
             ElementUtils.setTextFont(e, font);\r
         }\r
+        \r
+        double bounds[] = DiagramGraphUtil.getPossibleRelatedDoubleArray(graph, element, G2DResource.getInstance(graph).HasBounds);\r
+        if (bounds != null) {\r
+            e.setHint(ElementHints.KEY_BOUNDS, new Rectangle2D.Double(bounds[0], bounds[1], bounds[2], bounds[3]));\r
+        }\r
 \r
     }\r
 \r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementHandler.java
new file mode 100644 (file)
index 0000000..408ff09
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * 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 - initial API and implementation\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.diagram.elements.TextElementHandler;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.utils.Alignment;\r
+\r
+/**\r
+ * Version of {@link SysdynTextElementNoBounds} that supports InternalSize\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynTextElementHandler extends SysdynTextElementNoBounds implements InternalSize {\r
+    private static final long serialVersionUID = -1307413505370441178L;\r
+\r
+    public static SysdynTextElementHandler INSTANCE = new SysdynTextElementHandler();\r
+    \r
+    public SysdynTextElementHandler() {\r
+        super();\r
+    }\r
+\r
+    public SysdynTextElementHandler(double originX, double originY, Alignment horizontalAlignment) {\r
+        super(originX, originY, horizontalAlignment);\r
+    }\r
+\r
+    public SysdynTextElementHandler(double originX, double originY, Alignment horizontalAlignment, double borderWidth) {\r
+        super(originX, originY, horizontalAlignment, borderWidth);\r
+    }\r
+\r
+    public SysdynTextElementHandler(double originX, double originY, Alignment horizontalAlignment, double borderWidth,\r
+            double paddingX, double paddingY, boolean editable) {\r
+        super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable);\r
+    }\r
+    \r
+    @Override\r
+    public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
+        Rectangle2D bounds = TextElementHandler.calculateBounds(e, size, horizontalAlignment, SCALE, paddingX, paddingX);\r
+        return bounds;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementNoBounds.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementNoBounds.java
new file mode 100644 (file)
index 0000000..76defa5
--- /dev/null
@@ -0,0 +1,306 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * 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 - initial API and implementation\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.Color;\r
+import java.awt.geom.AffineTransform;\r
+\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.ui.IWorkbenchPage;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.elements.DiagramNodeUtil;\r
+import org.simantics.diagram.elements.ITextListener;\r
+import org.simantics.diagram.elements.TextElementNoBounds;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.diagram.participant.SGFocusParticipant;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.chassis.SWTChassis;\r
+import org.simantics.g2d.diagram.DiagramUtils;\r
+import org.simantics.g2d.diagram.IDiagram;\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.utils.Alignment;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramViewer;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
+import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+\r
+/**\r
+ * TextElement for variables in Siamntics System Dynamics\r
+ * \r
+ * The main differences for the basic TextElementNoBounds are:\r
+ * 1. Text is never mirrored\r
+ * 2. Edit mode is activated when the variable is created\r
+ *  \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynTextElementNoBounds extends TextElementNoBounds {\r
+\r
+    private static final long serialVersionUID = -148784588840819612L;\r
+    \r
+    public static final Key ELEMENT_INITIALIZED = new KeyOf(Boolean.class, "SYSDYN_TEXT_ELEMENT_INITIALIZED");\r
+\r
+    // Constructors \r
+    public SysdynTextElementNoBounds() {\r
+        super(0, 0, Alignment.LEADING, 0);\r
+    }\r
+\r
+    public SysdynTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment) {\r
+        super(originX, originY, horizontalAlignment, 0);\r
+    }\r
+\r
+    public SysdynTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth) {\r
+        super(originX, originY, horizontalAlignment, borderWidth);\r
+    }\r
+\r
+    public SysdynTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth, double paddingX, double paddingY, boolean editable) {\r
+        super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable);\r
+    }\r
+\r
+    // End constructors\r
+\r
+    protected <T extends SysdynTextNode> Callback<T> getCallback(final IElement e, G2DParentNode parent, Class<T> nodeClass) {\r
+        return new Callback<T>() {\r
+            @Override\r
+            public void run(T node) {\r
+                node.setTextListener(new ITextListener() {\r
+\r
+                    String textBeforeEdit;\r
+                    Resource component;\r
+\r
+                    @Override\r
+                    public void textChanged() {\r
+                        TextNode node = (TextNode) e.getHint(SG_NODE);\r
+                        if(!new VariableNameValidator().isValid(component, node.getText(), false)) {\r
+                            node.setColor(Color.RED);\r
+                        } else {\r
+                            node.setColor(ElementUtils.getTextColor(e, Color.BLACK));\r
+                        }\r
+\r
+\r
+                    }\r
+\r
+                    @Override\r
+                    public void textEditingStarted() {\r
+                        TextNode node = (TextNode) e.getHint(SG_NODE);\r
+                        textBeforeEdit = node.getText();\r
+\r
+                        if(component != null) return;\r
+                        \r
+                        Object o = e.getHint(ElementHints.KEY_OBJECT);\r
+                        if(o != null && o instanceof Resource) {\r
+                            final Resource element = (Resource)o;\r
+                            SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+\r
+                                @Override\r
+                                public void run(ReadGraph graph) throws DatabaseException {\r
+                                    component = graph.getPossibleObject(element, ModelingResources.getInstance(graph).ElementToComponent);\r
+                                }\r
+                            });\r
+                        }\r
+                    }\r
+\r
+                    @Override\r
+                    public void textEditingCancelled() {\r
+                        TextNode node = (TextNode) e.getHint(SG_NODE);\r
+                        if (node != null) {\r
+                            if(new VariableNameValidator().isValid(component, node.getText(), false))\r
+                                node.setColor(ElementUtils.getTextColor(e, Color.BLACK));\r
+                            endEdit(node);\r
+                        }\r
+                    }\r
+\r
+                    @Override\r
+                    public void textEditingEnded() {\r
+                        TextNode node = (TextNode) e.getHint(SG_NODE);\r
+                        if (node == null)\r
+                            return;\r
+                        String text = node.getText();\r
+                        if(!new VariableNameValidator().isValid(component, text, false)) {\r
+                            text = textBeforeEdit;\r
+                            node.setText(text);\r
+                            if(new VariableNameValidator().isValid(component, text, false))\r
+                                node.setColor(ElementUtils.getTextColor(e, Color.BLACK));\r
+                        } else {\r
+                            Object o = e.getHint(ElementHints.KEY_OBJECT);\r
+                            final String textAfterEdit = text;\r
+                            if(o != null && o instanceof Resource) {\r
+                                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                                    @Override\r
+                                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                                        Resource configuration = graph.getPossibleObject(component, Layer0.getInstance(graph).PartOf);\r
+                                        new VariableNameValidator().renameInAllEquations(graph, configuration, textBeforeEdit, textAfterEdit);\r
+                                    }\r
+                                });\r
+                            }\r
+                        }\r
+                        ElementUtils.setText(e, text);\r
+                        IDiagram diagram = ElementUtils.getDiagram(e);\r
+                        DiagramUtils.synchronizeHintsToBackend(diagram, e);\r
+                        endEdit(node);\r
+                    }\r
+                });\r
+            }\r
+        };\r
+    }\r
+    \r
+    /**\r
+     * Reverts any rotations that are assigned to the text element\r
+     * @param e\r
+     */\r
+    public static void unflipText(IElement e) {\r
+        Object o = e.getHint(SG_NODE);\r
+        if (o instanceof TextNode) {\r
+            TextNode text = (TextNode)o;\r
+            AffineTransform at = text.getTransform();\r
+            double x = at.getTranslateX();\r
+            double y = at.getTranslateY();\r
+            at.setToRotation(0);\r
+            at.setToTranslation(x, y);\r
+            at.setTransform(at);\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Activates edit mode for a newly created variable. \r
+     * \r
+     * Sets focus for diagram if the variable was created by dragging from model browser.\r
+     * \r
+     * @param e\r
+     */\r
+    protected void activateEdit(final IElement e) {\r
+        final SysdynTextNode node = e.getHint(SG_NODE);\r
+        if(node == null)\r
+            return;\r
+        \r
+        final ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(node);\r
+        // FIXME: needed only because eventdelegator registrations are done before adding node to scene graph.\r
+        if (ctx == null)\r
+            return;\r
+        if (!node.isEditMode()) {\r
+            \r
+            // Get the active editor\r
+            IWorkbenchPage page = SysdynWorkbenchUtils.getActivePageOfEditor();\r
+            final DiagramEditor editor = (DiagramEditor)page.getActiveEditor();\r
+            final ICanvasContext editorCtx = (ICanvasContext) editor.getViewer().getAdapter(ICanvasContext.class);\r
+\r
+            editor.getViewer().getComposite().getDisplay().asyncExec(new Runnable() {\r
+                    \r
+                @Override\r
+                public void run() {\r
+                    Control c = editor.getViewer().getComposite().getDisplay().getFocusControl();\r
+                    if (c == null || "BasicSymbols".equals(c.getParent().getToolTipText())) {\r
+                        // If the variable has been drag and dropped, set focus to diagram and then activate edit.\r
+                        \r
+                        editorCtx.add(new SGFocusParticipant((SWTChassis)editor.getViewer().getComposite(), DiagramViewer.DIAGRAMMING_CONTEXT) {\r
+                \r
+                            @Override\r
+                            public void focusGained(java.awt.event.FocusEvent event) {\r
+                                \r
+                                // When focus has been gained, acticate edit and destroy the listener.\r
+                                editor.getViewer().getComposite().getDisplay().asyncExec(new Runnable() {\r
+                                    \r
+                                    @Override\r
+                                    public void run() {\r
+                                        if (Boolean.TRUE.equals(node.setEditMode(true))) {\r
+                                            node.activateEdit(0, e, ctx, true);\r
+                                            node.repaint();\r
+                                        }\r
+                                    }\r
+                                });\r
+                                ctx.remove(this);\r
+                            }\r
+                            \r
+                            @Override\r
+                            public void focusLost(java.awt.event.FocusEvent e) {\r
+                            }\r
+                        });\r
+                    \r
+                        editor.setFocus();\r
+                    } else {\r
+                        // If the variable has been created with shortcut key, just activate the edit.\r
+                        if (Boolean.TRUE.equals(node.setEditMode(true))) {\r
+                            node.activateEdit(0, e, ctx, true);\r
+                            node.repaint();\r
+                        }\r
+                    }\r
+                }\r
+            }); \r
+        }\r
+    }\r
+    \r
+    @Override\r
+    protected TextNode getOrCreateTextNode(IElement e, G2DParentNode parent) {\r
+        return ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", SysdynTextNode.class, getCallback(e, parent, SysdynTextNode.class));\r
+    }\r
+    \r
+    @Override\r
+    public void init(final IElement e, G2DParentNode parent) {\r
+        super.init(e, parent);\r
+\r
+        \r
+        // Add handling for activating text edit for new variables\r
+     // Store initialization status to hints to prevent unnecessary graph queries\r
+        Boolean isInitialized = e.getHint(ELEMENT_INITIALIZED);  \r
+        Object o = e.getHint(ElementHints.KEY_OBJECT);\r
+        if (o instanceof Resource && !Boolean.TRUE.equals(isInitialized)) {\r
+            final Resource element = (Resource)o;\r
+            try {\r
+                SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+    \r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        SysdynResource SR = SysdynResource.getInstance(graph);\r
+                        ModelingResources MR = ModelingResources.getInstance(graph);\r
+                        Resource component = graph.getPossibleObject(element, MR.ElementToComponent);\r
+                        if (component == null)\r
+                            return;\r
+                        \r
+                        // See if the resource of the element has just been created. \r
+                        Resource r = graph.getPossibleObject(component, SR.IndependentVariable_isUninitialized);\r
+                        if (r == null){\r
+                            return;\r
+                        }\r
+                        \r
+                        // If the resource is just been created, activate editing its name.\r
+                        if (!graph.isInstanceOf(r, SR.Loop)) {\r
+                            activateEdit(e);\r
+                        }\r
+                        graph.deny(component, SR.IndependentVariable_isUninitialized, r);\r
+                    }\r
+                });\r
+            } catch (DatabaseException e1) {\r
+                e1.printStackTrace();\r
+            }\r
+            e.setHint(ELEMENT_INITIALIZED, Boolean.TRUE);\r
+        }\r
+        \r
+        unflipText(e);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextNode.java
new file mode 100644 (file)
index 0000000..0330191
--- /dev/null
@@ -0,0 +1,79 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * 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 - initial API and implementation\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+\r
+import org.simantics.diagram.elements.TextEditActivation;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.scenegraph.g2d.events.EventTypes;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;\r
+import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
+\r
+/**\r
+ * Text node for Sysdyn elements.\r
+ * \r
+ *  Additions to the basic node:\r
+ *  1. Draw borders when hovering\r
+ *  2. Support Sysdyn's diagram locking\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynTextNode extends TextNode {\r
+\r
+    private static final long serialVersionUID = 5235077104121753251L;\r
+\r
+    \r
+    @Override\r
+    public int getEventMask(){\r
+        return EventTypes.FocusLostMask | super.getEventMask();\r
+    }\r
+    \r
+    @Override\r
+    protected boolean mouseDragged(MouseDragBegin e) {\r
+        // Disable dragging if LockSketch is ON\r
+        if (SysdynElementHints.LOCK_TOOL.equals(SysdynWorkbenchUtils.getSysdynToolMode())){\r
+            super.mouseDragged(e);\r
+            return true;}\r
+        else\r
+            return super.mouseDragged(e);\r
+    }\r
+    \r
+    \r
+    @Override\r
+    protected void renderSelectedHover(Graphics2D g, boolean isSelected, boolean isHovering) {\r
+        \r
+        if (!isSelected && isHovering) {\r
+            BasicStroke oldStroke = (BasicStroke)g.getStroke();\r
+            Color oldColor = g.getColor();\r
+            g.setColor(Color.LIGHT_GRAY);\r
+            g.setStroke(new BasicStroke((float)(2.0*scale)));\r
+            g.draw(getBoundsInLocal());\r
+            g.setColor(oldColor);\r
+            g.setStroke(oldStroke);\r
+            \r
+        }\r
+        \r
+    }\r
+    \r
+    public TextEditActivation activateEdit(int mouseId, IElement e, ICanvasContext ctx, boolean save) {\r
+        if (save)\r
+            return editActivation = super.activateEdit(mouseId, e, ctx);\r
+        return super.activateEdit(mouseId, e, ctx);\r
+    }\r
+    \r
+}\r
index 94d16aead56f6124896a5cd374f8ff5b159a3c9e..200ce9e57952858312b610f2c72797a1f1436adb 100644 (file)
@@ -13,18 +13,19 @@ package org.simantics.sysdyn.ui.elements;
 \r
 import java.awt.BasicStroke;\r
 import java.awt.Color;\r
-import java.awt.Font;\r
-import java.awt.font.FontRenderContext;\r
-import java.awt.font.TextLayout;\r
+import java.awt.Shape;\r
 import java.awt.geom.AffineTransform;\r
+import java.awt.geom.NoninvertibleTransformException;\r
 import java.awt.geom.Path2D;\r
-import java.awt.geom.Path2D.Double;\r
 import java.awt.geom.Rectangle2D;\r
 import java.util.Collection;\r
 \r
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.elements.ResizeNode.TranslateEdge;\r
+import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\r
+import org.simantics.diagram.elements.TextElementNoBounds;\r
 import org.simantics.diagram.elements.TextNode;\r
 import org.simantics.g2d.canvas.ICanvasContext;\r
 import org.simantics.g2d.diagram.IDiagram;\r
@@ -33,8 +34,8 @@ import org.simantics.g2d.element.ElementHints;
 import org.simantics.g2d.element.ElementUtils;\r
 import org.simantics.g2d.element.IElement;\r
 import org.simantics.g2d.element.SceneGraphNodeKey;\r
-import org.simantics.g2d.element.handler.HandleMouseEvent;\r
 import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.element.handler.SceneGraph;\r
 import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
 import org.simantics.g2d.element.handler.impl.HoverImpl;\r
 import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
@@ -83,10 +84,14 @@ public class ValveFactory extends SysdynElementFactory {
                 new StaticSymbolImpl(VALVE_STATIC_IMAGE),\r
                 StaticSymbolImageInitializer.INSTANCE,\r
                 HoverImpl.INSTANCE,\r
-                ValveSceneGraph.INSTANCE,\r
-                ValveOutline.INSTANCE,\r
                 Orientation.INSTANCE,\r
                 ValveTextLocation.INSTANCE,\r
+                ValveSceneGraph.INSTANCE,\r
+                ValveText.INSTANCE,\r
+                new ResizeRectangularSceneGraph(TextElementNoBounds.SG_NODE),\r
+                RESIZE_PROPERTY_SETTER,          \r
+                ValveBounds.INSTANCE,\r
+                ValveOutline.INSTANCE,\r
                 new WholeElementTerminals(terminals)\r
         ).setId(ValveFactory.class.getSimpleName());\r
     }\r
@@ -120,6 +125,25 @@ public class ValveFactory extends SysdynElementFactory {
         }\r
         SysdynElementUtils.setValveTextLocation(e, locationText);    \r
         \r
+        \r
+        ResizeRectangularSceneGraph resize = e.getElementClass().getSingleItem(ResizeRectangularSceneGraph.class);\r
+        if(resize != null) {\r
+            \r
+            if(location == null || sr.Bottom.equals(location)) {\r
+                resize.setYTranslateEdge(TranslateEdge.NORTH);\r
+                resize.setXTranslateEdge(TranslateEdge.NONE);\r
+            } else if(sr.Top.equals(location)) {\r
+                resize.setYTranslateEdge(TranslateEdge.SOUTH);\r
+                resize.setXTranslateEdge(TranslateEdge.NONE);\r
+            } else if(sr.Left.equals(location)) {\r
+                resize.setYTranslateEdge(TranslateEdge.NONE);\r
+                resize.setXTranslateEdge(TranslateEdge.EAST);\r
+            } else {\r
+                resize.setYTranslateEdge(TranslateEdge.NONE);\r
+                resize.setXTranslateEdge(TranslateEdge.WEST);\r
+            }\r
+        }\r
+        \r
     }\r
     \r
     /**\r
@@ -142,26 +166,110 @@ public class ValveFactory extends SysdynElementFactory {
         path.closePath();\r
         return path;\r
     }\r
+    \r
+    public static class ValveText extends SysdynTextElementNoBounds {\r
+        private static final long serialVersionUID = -5354779831383095960L;\r
+     \r
+        public static ValveText INSTANCE = new ValveText();\r
+        \r
+        public ValveText() {\r
+            super(0, 0, Alignment.CENTER, 0, 1, 1, true);\r
+        }\r
+        \r
+        @Override\r
+        public void init(IElement e, G2DParentNode parent) {\r
+            super.init(e, parent);\r
+            \r
+            TextNode text = e.getHint(TextElementNoBounds.SG_NODE);\r
+            HoverShapeNode valve = e.getHint(ValveSceneGraph.VALVE_SG_NODE);\r
+            if(valve != null && text != null) {\r
+                Rectangle2D textBounds = text.getBoundsInLocal();\r
+                Rectangle2D valveBounds = valve.getBoundsInLocal();\r
+                AffineTransform at = (AffineTransform) text.getTransform().clone();\r
+                at.translate(\r
+                        getTextXTranslate(e, textBounds, valveBounds), \r
+                        getTextYTranslate(e, textBounds, valveBounds));\r
+                text.setTransform(at);\r
+            }\r
+            \r
+        }\r
+        \r
+        private static double getTextXTranslate(IElement e, Rectangle2D textBounds, Rectangle2D valveBounds) {\r
+            String location = e.getHint(SysdynElementHints.KEY_LOCATION);\r
+            if(location.equals("Bottom")) {\r
+                return -textBounds.getCenterX();\r
+            } else if(location.equals("Top")) {\r
+                return -textBounds.getCenterX();\r
+            } else if(location.equals("Left")) {\r
+                return -textBounds.getMaxX() - valveBounds.getWidth() / 2;\r
+            } else {\r
+                return valveBounds.getMaxX() - textBounds.getMinX();\r
+            }\r
+        }\r
+        \r
+        private static double getTextYTranslate(IElement e, Rectangle2D textBounds, Rectangle2D valveBounds) {\r
+            String location = e.getHint(SysdynElementHints.KEY_LOCATION);\r
+            if(location.equals("Bottom")) {\r
+                return valveBounds.getMaxY() - textBounds.getMinY();\r
+            } else if(location.equals("Top")) {\r
+                return valveBounds.getMinY() - textBounds.getMaxY();\r
+            } else if(location.equals("Left")) {\r
+                return -textBounds.getCenterY();\r
+            } else {\r
+                return -textBounds.getCenterY();\r
+            }\r
+        }\r
+    }\r
+    \r
+    public static class ValveBounds implements InternalSize {\r
+        private static final long serialVersionUID = -666692270776359301L;\r
 \r
-    public static class ValveSceneGraph extends HoverTextElementNoBounds  implements InternalSize, HandleMouseEvent {\r
+        public static final ValveBounds INSTANCE         = new ValveBounds();\r
 \r
-        private static final long           serialVersionUID = 5544256245734478634L;\r
+        @Override\r
+        public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
+            TextNode textNode = e.getHint(TextElementNoBounds.SG_NODE);\r
+            ValveSceneGraph valveSG = e.getElementClass().getSingleItem(ValveSceneGraph.class);\r
+\r
+            if(textNode != null && valveSG != null) {\r
+                try {\r
+                    AffineTransform elementTransform = ElementUtils.getTransform(e);\r
+                    AffineTransform nodeTransform = textNode.getTransform();\r
+\r
+                    AffineTransform elementTransformInverse = elementTransform.createInverse();\r
+                    elementTransformInverse.concatenate(nodeTransform);\r
+\r
+                    Rectangle2D text = textNode.getBoundsInLocal();\r
+                    Shape textShape = elementTransformInverse.createTransformedShape(text);\r
+\r
+                    Rectangle2D valve = valveSG.getValveBounds(e, new Rectangle2D.Double());\r
+\r
+                    size.setRect(textShape.getBounds2D());\r
+                    size.add(valve);\r
+                    return size;\r
+                } catch (NoninvertibleTransformException e1) {\r
+                    e1.printStackTrace();\r
+                }\r
+            }\r
+            // FallBack\r
+            Path2D path = createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED)));\r
+            return path.getBounds2D();\r
+        }\r
+\r
+    }\r
+    \r
+    public static class ValveSceneGraph implements SceneGraph {\r
+        private static final long serialVersionUID = 7987939328158347639L;\r
 \r
         public static final ValveSceneGraph INSTANCE         = new ValveSceneGraph();\r
 \r
-        private static final Key            NODE             = new SceneGraphNodeKey(ShapeNode.class, "VALVE_NODE");\r
+        private static final Key            VALVE_SG_NODE             = new SceneGraphNodeKey(ShapeNode.class, "VALVE_SHAPE_NODE");\r
         \r
         private IHintListener hoverHintListener;\r
 \r
-        public ValveSceneGraph() {\r
-//            super(0, VALVE_SIZE + 3.0, Alignment.CENTER); // Move with affine transformation in init()\r
-            super(0, 0, Alignment.CENTER, 0, 1, 1, true);\r
-        }\r
         @Override\r
         public void init(IElement e, G2DParentNode parent) {\r
-            super.init(e, parent);\r
-            AffineTransform at = ElementUtils.getTransform(e);\r
-            final HoverShapeNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "valve", HoverShapeNode.class);\r
+            final HoverShapeNode node = ElementUtils.getOrCreateNode(e, parent, VALVE_SG_NODE, "valveShape", HoverShapeNode.class);\r
 \r
             // Calculate borders from text node bounds.\r
             node.setStroke(STROKE);\r
@@ -175,31 +283,11 @@ public class ValveFactory extends SysdynElementFactory {
             node.setShape(createShape(VALVE_SIZE, Boolean.TRUE.equals(rotated)));\r
             Boolean hover = e.getHint(ElementHints.KEY_HOVER); \r
             node.setHover(hover != null ? hover : false);\r
-\r
-            if(at != null) {\r
+            \r
+            AffineTransform at = ElementUtils.getTransform(e);\r
+            if(at != null)\r
                 node.setTransform(at);\r
             \r
-                TextNode name = (TextNode) e.getHint(SG_NODE);\r
-                if(name != null) {\r
-                    \r
-                    AffineTransform at2 = (AffineTransform) at.clone();\r
-                    Alignment alignment = null;\r
-                    \r
-                    String location = e.getHint(SysdynElementHints.KEY_LOCATION);\r
-                    if(location != null) {\r
-                        at2.translate(getXCoordShift(e), getYCoordShift(e));\r
-                        if(location.equals("Left")) {\r
-                            alignment = Alignment.TRAILING;\r
-                        } else if(location.equals("Right")) {\r
-                            alignment = Alignment.LEADING;\r
-                        }\r
-                    }\r
-                    \r
-                    name.setTransform(at2);\r
-                    if(alignment != null)\r
-                        name.setHorizontalAlignment((byte) alignment.ordinal());\r
-                }\r
-            }\r
 \r
             hoverHintListener = new IHintListener() {\r
                 \r
@@ -211,7 +299,7 @@ public class ValveFactory extends SysdynElementFactory {
                 @Override\r
                 public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
                     IElement e = (IElement)sender;\r
-                    HoverShapeNode shape = (HoverShapeNode) e.getHint(NODE);\r
+                    HoverShapeNode shape = (HoverShapeNode) e.getHint(VALVE_SG_NODE);\r
                     if(shape == null) {\r
                         return;\r
                     }\r
@@ -219,194 +307,32 @@ public class ValveFactory extends SysdynElementFactory {
                     shape.setHover(hover);\r
                 }\r
             };\r
-            e.addHintListener(hoverHintListener);\r
-            \r
-                       unflipText(e);\r
+            e.addHintListener(hoverHintListener);            \r
         }\r
 \r
         @Override\r
         public void cleanup(IElement e) {\r
             e.removeHintListener(hoverHintListener);\r
-            ElementUtils.removePossibleNode(e, NODE);\r
-        }\r
-\r
-        @Override\r
-        public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
-            if (size == null)\r
-                size = new Rectangle2D.Double();\r
-            size.setFrame(createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED))).getBounds2D());\r
-            double paddingX = 2.0;\r
-            double paddingY = 2.0;\r
-            size.setRect(size.getX() - paddingX, size.getY() -paddingY, size.getWidth() + paddingX + paddingX, size.getHeight() + paddingY + paddingY);\r
-            return size;\r
-        }\r
-\r
-        private static double getXCoordShift(IElement e) {\r
-               String location = e.getHint(SysdynElementHints.KEY_LOCATION);\r
-            if(location.equals("Bottom")) {\r
-                return 0;\r
-            } else if(location.equals("Top")) {\r
-               return 0;\r
-            } else if(location.equals("Left")) {\r
-               return -VALVE_SIZE - 1;\r
-            } else {\r
-               return VALVE_SIZE + 1;\r
-            }\r
+            ElementUtils.removePossibleNode(e, VALVE_SG_NODE);            \r
         }\r
         \r
-        private static double getYCoordShift(IElement e) {\r
-               String location = e.getHint(SysdynElementHints.KEY_LOCATION);\r
-            if(location.equals("Bottom")) {\r
-                return VALVE_SIZE + 3;\r
-            } else if(location.equals("Top")) {\r
-               return -VALVE_SIZE - 1;\r
-            } else if(location.equals("Left")) {\r
-               return 0;\r
-            } else {\r
-               return 0;\r
-            }\r
-        }\r
         \r
-        private Rectangle2D getBoundsText(IElement e, Rectangle2D size) {\r
-               HoverTextNode node = (HoverTextNode) e.getHint(SG_NODE);\r
+        public Rectangle2D getValveBounds(IElement e, Rectangle2D size) {\r
             if (size == null)\r
                 size = new Rectangle2D.Double();\r
-            if (node != null) {\r
-                Rectangle2D local = node.getBoundsInLocal();\r
-                local.setRect(local.getX() + getXCoordShift(e), \r
-                                         local.getY() + getYCoordShift(e), \r
-                                         local.getWidth(), \r
-                                         local.getHeight());\r
-                size.setRect(local);\r
-            }\r
-            else {\r
-                String text = e.getHint(ElementHints.KEY_TEXT);\r
-                Font font = e.getHint(ElementHints.KEY_FONT);\r
-                if(text == null || font == null)\r
-                    size.setFrame(0, 0, 0, 0);\r
-                else {\r
-                    FontRenderContext FRC = new FontRenderContext(new AffineTransform(), true, true);\r
-                    TextLayout tl = new TextLayout(text, font, FRC);\r
-                    Rectangle2D bounds = tl.getLogicalHighlightShape(0, text.length()).getBounds2D();   \r
-                    size.setFrame(\r
-                            bounds.getX() * SCALE - paddingX,\r
-                            (bounds.getY() + VALVE_SIZE) * SCALE - paddingY, \r
-                            bounds.getWidth()* SCALE + paddingX + paddingX, \r
-                            bounds.getHeight()* SCALE + paddingY + paddingY);\r
-                }\r
-            }\r
-            return size;\r
-        }\r
-        \r
-        public Path2D.Double getBoundsPath(IElement e, Path2D.Double size) {\r
-            if (size == null)\r
-                size = new Path2D.Double();\r
-\r
-            // Get the rectangles for the Valve symbol and the text field.\r
-            Rectangle2D valve = getBounds(e, new Rectangle2D.Double());\r
-            Rectangle2D text = getBoundsText(e, new Rectangle2D.Double());\r
             \r
-            // Combine the two.\r
-            String location = e.getHint(SysdynElementHints.KEY_LOCATION);\r
-            if(location.equals("Bottom")) {\r
-                return getBoundsPathBottom(size, valve, text);\r
-            } else if(location.equals("Top")) {\r
-               return getBoundsPathTop(size, valve, text);\r
-            } else if(location.equals("Left")) {\r
-               return getBoundsPathLeft(size, valve, text);\r
+            HoverShapeNode node = e.getHint(VALVE_SG_NODE);\r
+            if(node != null) {\r
+                size.setFrame(node.getBoundsInLocal());\r
             } else {\r
-               return getBoundsPathRight(size, valve, text);\r
+                size.setFrame(createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED))).getBounds2D());\r
             }\r
+            \r
+            // Add some padding to the valve\r
+            double padding = 1;\r
+            size.setFrame(size.getX() - padding, size.getY() - padding, size.getWidth() + padding * 2, size.getHeight() + padding * 2);\r
+            return size;\r
         }\r
         \r
-               private Double getBoundsPathBottom(Path2D.Double size, Rectangle2D valve,\r
-                               Rectangle2D text) {\r
-            double xV = valve.getX();\r
-            double xVM = valve.getMaxX();\r
-            double yV = valve.getY();\r
-            //double yVM = valve.getMaxY();\r
-            double xT = text.getX();\r
-            double xTM = text.getMaxX();\r
-            double yT = text.getY();\r
-            double yTM = text.getMaxY();\r
-               size.moveTo(xV, yV);\r
-            size.lineTo(xVM, yV);\r
-            size.lineTo(xVM, yT);\r
-            size.lineTo(xTM, yT);\r
-            size.lineTo(xTM, yTM);\r
-            size.lineTo(xT, yTM);\r
-            size.lineTo(xT, yT);\r
-            size.lineTo(xV, yT);\r
-            size.closePath();\r
-                       return size;\r
-               }\r
-        \r
-               private Double getBoundsPathTop(Path2D.Double size, Rectangle2D valve,\r
-                               Rectangle2D text) {\r
-            double xV = valve.getX();\r
-            double xVM = valve.getMaxX();\r
-            //double yV = valve.getY();\r
-            double yVM = valve.getMaxY();\r
-            double xT = text.getX();\r
-            double xTM = text.getMaxX();\r
-            double yT = text.getY();\r
-            double yTM = text.getMaxY();\r
-               size.moveTo(xT, yT);\r
-               size.lineTo(xTM, yT);\r
-               size.lineTo(xTM, yTM);\r
-               size.lineTo(xVM, yTM);\r
-               size.lineTo(xVM, yVM);\r
-               size.lineTo(xV, yVM);\r
-               size.lineTo(xV, yTM);\r
-               size.lineTo(xT, yTM);\r
-            size.closePath();\r
-                       return size;\r
-               }\r
-        \r
-               private Double getBoundsPathLeft(Path2D.Double size, Rectangle2D valve,\r
-                               Rectangle2D text) {\r
-            double xV = valve.getX();\r
-            double xVM = valve.getMaxX();\r
-            double yV = valve.getY();\r
-            double yVM = valve.getMaxY();\r
-            double xT = text.getX();\r
-            double xTM = text.getMaxX();\r
-            double yT = text.getY();\r
-            double yTM = text.getMaxY();\r
-            size.moveTo(xT, yT);\r
-               size.lineTo(xTM, yT);\r
-               size.lineTo(xTM, yV);\r
-               size.lineTo(xVM, yV);\r
-               size.lineTo(xVM, yVM);\r
-               size.lineTo(xV, yVM);\r
-               size.lineTo(xV, yTM);\r
-               size.lineTo(xT, yTM);\r
-            size.closePath();\r
-                       return size;\r
-               }\r
-        \r
-               private Double getBoundsPathRight(Path2D.Double size, Rectangle2D valve,\r
-                               Rectangle2D text) {\r
-            double xV = valve.getX();\r
-            double xVM = valve.getMaxX();\r
-            double yV = valve.getY();\r
-            double yVM = valve.getMaxY();\r
-            double xT = text.getX();\r
-            double xTM = text.getMaxX();\r
-            double yT = text.getY();\r
-            double yTM = text.getMaxY();\r
-            size.moveTo(xV, yV);\r
-               size.lineTo(xT, yV);\r
-               size.lineTo(xT, yT);\r
-               size.lineTo(xTM, yT);\r
-               size.lineTo(xTM, yTM);\r
-               size.lineTo(xVM, yTM);\r
-               size.lineTo(xVM, yVM);\r
-               size.lineTo(xV, yVM);\r
-            size.closePath();\r
-                       return size;\r
-               }\r
-\r
     }\r
-\r
 }\r
index 37b6969bb56227262a6db26eacb917255dfb89f8..afac8e42552fc363445a496674e7ac9c6c09d15c 100644 (file)
@@ -1,9 +1,14 @@
 package org.simantics.sysdyn.ui.elements;\r
 \r
 import java.awt.Shape;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.NoninvertibleTransformException;\r
 import java.awt.geom.Path2D;\r
 import java.awt.geom.Rectangle2D;\r
 \r
+import org.simantics.diagram.elements.TextElementNoBounds;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.g2d.element.ElementUtils;\r
 import org.simantics.g2d.element.IElement;\r
 import org.simantics.g2d.element.handler.InternalSize;\r
 import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
@@ -15,16 +20,38 @@ public class ValveOutline extends BoundsOutline {
 \r
     private static final long         serialVersionUID = 5544256245734478634L;\r
 \r
-       public ValveOutline() {\r
-               super();\r
-       }\r
+    public ValveOutline() {\r
+        super();\r
+    }\r
+\r
+    @Override\r
+    public Shape getElementShape(IElement e) {\r
+        TextNode textNode = e.getHint(TextElementNoBounds.SG_NODE);\r
+        ValveSceneGraph valveSG = e.getElementClass().getSingleItem(ValveSceneGraph.class);\r
+\r
+        if(textNode != null && valveSG != null) {\r
+            try {\r
+                AffineTransform elementTransform = ElementUtils.getTransform(e);\r
+                AffineTransform nodeTransform = textNode.getTransform();\r
+\r
+                AffineTransform elementTransformInverse = elementTransform.createInverse();\r
+                elementTransformInverse.concatenate(nodeTransform);\r
+\r
+                Rectangle2D text = textNode.getBoundsInLocal();\r
+                Shape textShape = elementTransformInverse.createTransformedShape(text);\r
+\r
+                Rectangle2D valve = valveSG.getValveBounds(e, new Rectangle2D.Double());\r
+\r
+                Path2D path = new Path2D.Double(textShape);\r
+                path.append(valve, false);\r
+\r
+                return path;\r
+            } catch (NoninvertibleTransformException e1) {\r
+                e1.printStackTrace();\r
+            }\r
+        }\r
 \r
-       @Override\r
-       public Shape getElementShape(IElement e) {\r
         InternalSize b = e.getElementClass().getSingleItem(InternalSize.class);\r
-        if (b instanceof ValveSceneGraph)\r
-               return ((ValveSceneGraph)b).getBoundsPath(e, new Path2D.Double());\r
-        else\r
-               return b.getBounds(e, new Rectangle2D.Double());\r
-       }\r
+        return b.getBounds(e, new Rectangle2D.Double());\r
+    }\r
 }\r
index 17489d803d24fb79d732a87aa2fe077b4080d301..567b48c46214aa5df9adcba5897207b7b43ca93b 100644 (file)
@@ -242,19 +242,22 @@ public class RouteFlowConnectionFactory extends SyncElementFactory {
             // Get element bounds to decide allowed terminal direction(s)\r
             IElement te = graph.syncRequest(DiagramRequests.getElement(canvas, diagram, terminalElement, null));\r
 \r
-            ElementUtils.getElementBounds(te, bounds);\r
-\r
-            {\r
-                Shape shp = org.simantics.g2d.utils.GeometryUtils.transformShape(bounds, terminalElementTr);\r
-                bounds.setFrame(shp.getBounds2D());\r
-            }\r
-\r
-            // Valve behaves differently. The flow must start inside the valve bounds\r
             if(te.getElementClass().containsClass(ValveSceneGraph.class)) {\r
+                // Valve behaves differently. The flow must start inside the valve bounds\r
+                ValveSceneGraph vs = te.getElementClass().getSingleItem(ValveSceneGraph.class);\r
+                Rectangle2D size = new Rectangle2D.Double();\r
+                vs.getValveBounds(te, size);\r
+                Shape shp = org.simantics.g2d.utils.GeometryUtils.transformShape(size, terminalElementTr);\r
+                size = (Rectangle2D) shp;\r
                 float lw = FlowConnectionStyle.LINE_WIDTH;\r
-                bounds.setFrame(new Rectangle2D.Double(bounds.getCenterX() - (lw/2), bounds.getCenterY() - (lw/2), lw, lw));\r
+                bounds.setFrame(new Rectangle2D.Double(size.getCenterX() - (lw/2), size.getCenterY() - (lw/2), lw, lw));\r
+            } else {\r
+                // Basic bounds\r
+                bounds = ElementUtils.getElementShape(te).getBounds2D();\r
+                Shape shp = org.simantics.g2d.utils.GeometryUtils.transformShape(bounds, terminalElementTr);\r
+                bounds.setFrame(shp.getBounds2D());\r
             }\r
-\r
+            \r
             x = bounds.getCenterX();\r
             y = bounds.getCenterY();\r
 \r
@@ -268,7 +271,6 @@ public class RouteFlowConnectionFactory extends SyncElementFactory {
             maxx = bounds.getMaxX();\r
             maxy = bounds.getMaxY();\r
 \r
-\r
             Integer allowedDirections = graph.getPossibleRelatedValue(terminal, DIA.Terminal_AllowedDirections, Bindings.INTEGER);\r
 \r
             // Valve behaves differently. Allowed directions depend on the orientation of the valve\r