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
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
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
+++ /dev/null
-/*******************************************************************************\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
+++ /dev/null
-/*******************************************************************************\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
+++ /dev/null
-/*******************************************************************************\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
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
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
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
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
* @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
}\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
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
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
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
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
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
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
}\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
+++ /dev/null
-/*******************************************************************************\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
*******************************************************************************/\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
*/\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
+++ /dev/null
-/*******************************************************************************\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
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
\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
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
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
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
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
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
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
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
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
\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
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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
\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
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
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
}\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
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
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
@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
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
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
\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
// 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
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