-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.diagram.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
-import java.util.function.Consumer;\r
-\r
-import org.simantics.g2d.canvas.ICanvasContext;\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.SceneGraphNodeKey;\r
-import org.simantics.g2d.element.handler.HandleMouseEvent;\r
-import org.simantics.g2d.element.handler.SceneGraph;\r
-import org.simantics.g2d.utils.Alignment;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\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 TextElementNoBounds implements SceneGraph, HandleMouseEvent {\r
-\r
- private static final long serialVersionUID = -148784588840819612L;\r
-\r
- public static final TextElementNoBounds INSTANCE = new TextElementNoBounds();\r
-\r
- public static final Key SG_NODE = new SceneGraphNodeKey(TextNode.class, "TEXT_SG_NODE");\r
- \r
- protected static final double DEFAULT_PADDING_X = 0.5;\r
- protected static final double DEFAULT_PADDING_Y = 0.5;\r
- protected static final double SCALE = 0.235;\r
-\r
- protected final double originX;\r
- protected final double originY;\r
- protected final Alignment horizontalAlignment;\r
- protected final Alignment verticalAlignment;\r
- protected final double borderWidth;\r
- protected final boolean editable;\r
- protected final double paddingX;\r
- protected final double paddingY;\r
-\r
-\r
- public TextElementNoBounds() {\r
- this(0, 0, Alignment.LEADING, 0);\r
- }\r
-\r
- public TextElementNoBounds(double originX, double originY, Alignment horizontalAlignment) {\r
- this(originX, originY, horizontalAlignment, 0);\r
- }\r
-\r
- public TextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth) {\r
- this(originX, originY, horizontalAlignment, borderWidth, DEFAULT_PADDING_X, DEFAULT_PADDING_Y, true);\r
- }\r
- \r
- public TextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth, double paddingX, double paddingY, boolean editable) {\r
- if (horizontalAlignment == null)\r
- throw new NullPointerException("null horizontal alignment");\r
-\r
- this.originX = originX;\r
- this.originY = originY;\r
- this.horizontalAlignment = horizontalAlignment;\r
- this.verticalAlignment = Alignment.BASELINE;\r
- this.borderWidth = borderWidth;\r
- this.editable = editable;\r
- this.paddingX = paddingX;\r
- this.paddingY = paddingY;\r
- }\r
- \r
-\r
- @Override\r
- public void init(final IElement e, G2DParentNode parent) {\r
- TextNode node = getOrCreateTextNode(e, parent);\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.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
- Alignment vAlign = ElementUtils.getHintOrDefault(e, ElementHints.KEY_VERTICAL_ALIGN, verticalAlignment);\r
- Double borderWidth = ElementUtils.getHintOrDefault(e, MonitorClass.KEY_BORDER_WIDTH, this.borderWidth);\r
-\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.setVerticalAlignment((byte) vAlign.ordinal());\r
- node.setPadding(paddingX, paddingY);\r
- node.setBorderWidth(borderWidth.floatValue());\r
- node.setEditable(editable);\r
- if (at != null)\r
- node.setTransform(at);\r
- \r
- if(Boolean.TRUE.equals(ElementUtils.getHintOrDefault(e, ElementHints.KEY_RESIZABLE, false))) {\r
- Rectangle2D bounds = e.getHint(ElementHints.KEY_BOUNDS);\r
- if(bounds != null) {\r
- node.setTargetBounds(bounds);\r
- node.setWrapText(true);\r
- }\r
- }\r
- }\r
- \r
- protected TextNode getOrCreateTextNode(IElement e, G2DParentNode parent) {\r
- return ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", TextNode.class, new TextNodeCallBack(e));\r
- }\r
- \r
- private class TextNodeCallBack implements Consumer<TextNode> {\r
- \r
- IElement e;\r
- \r
- public TextNodeCallBack(IElement e) {\r
- this.e = e;\r
- }\r
- \r
- @Override\r
- public void accept(TextNode node) {\r
- node.setTextListener(new ITextListener() {\r
- @Override\r
- public void textChanged() {}\r
-\r
- @Override\r
- public void textEditingStarted() {}\r
-\r
- @Override\r
- public void textEditingCancelled() {\r
- TextNode node = (TextNode) e.getHint(SG_NODE);\r
- if (node != null)\r
- endEdit(node);\r
- }\r
-\r
- @Override\r
- public void textEditingEnded() {\r
- TextNode node = (TextNode) e.getHint(SG_NODE);\r
- if (node == null)\r
- return;\r
- //System.out.println("Node text changed: " + node.getText());\r
- ElementUtils.setText(e, node.getText());\r
- IDiagram diagram = ElementUtils.getDiagram(e);\r
- DiagramUtils.synchronizeHintsToBackend(diagram, e);\r
- endEdit(node);\r
- }\r
- });\r
- }\r
- }\r
-\r
- @Override\r
- public void cleanup(IElement e) {\r
- ElementUtils.removePossibleNode(e, SG_NODE);\r
- }\r
-\r
- // FIXME: hazardous with TextElementHandler.INSTANCE\r
- TextEditActivation editActivation = null;\r
-\r
- @Override\r
- public boolean handleMouseEvent(IElement e, ICanvasContext ctx, MouseEvent me) {\r
- if (me instanceof MouseEnterEvent) {\r
- e.setHint(ElementHints.KEY_HOVER, true);\r
- } else if (me instanceof MouseExitEvent) {\r
- e.setHint(ElementHints.KEY_HOVER, false);\r
- }\r
-\r
- return false;\r
- }\r
-\r
- protected void endEdit(TextNode node) {\r
- if (editActivation != null) {\r
- editActivation.release();\r
- editActivation = null;\r
-\r
- node.setEditMode(false);\r
- node.repaint();\r
- }\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- final int prime = 31;\r
- int result = 1;\r
- long temp;\r
- temp = Double.doubleToLongBits(borderWidth);\r
- result = prime * result + (int) (temp ^ (temp >>> 32));\r
- result = prime * result + horizontalAlignment.hashCode();\r
- temp = Double.doubleToLongBits(originX);\r
- result = prime * result + (int) (temp ^ (temp >>> 32));\r
- temp = Double.doubleToLongBits(originY);\r
- result = prime * result + (int) (temp ^ (temp >>> 32));\r
- temp = Double.doubleToLongBits(paddingX);\r
- result = prime * result + (int) (temp ^ (temp >>> 32));\r
- temp = Double.doubleToLongBits(paddingY);\r
- result = prime * result + (int) (temp ^ (temp >>> 32));\r
- return result;\r
- }\r
-\r
- @Override\r
- public boolean equals(Object obj) {\r
- if (this == obj)\r
- return true;\r
- if (obj == null)\r
- return false;\r
- if (getClass() != obj.getClass())\r
- return false;\r
- TextElementNoBounds other = (TextElementNoBounds) obj;\r
- if (Double.doubleToLongBits(borderWidth) != Double.doubleToLongBits(other.borderWidth))\r
- return false;\r
- if (horizontalAlignment != other.horizontalAlignment)\r
- return false;\r
- if (Double.doubleToLongBits(originX) != Double.doubleToLongBits(other.originX))\r
- return false;\r
- if (Double.doubleToLongBits(originY) != Double.doubleToLongBits(other.originY))\r
- return false;\r
- if (Double.doubleToLongBits(paddingX) != Double.doubleToLongBits(other.paddingX))\r
- return false;\r
- if (Double.doubleToLongBits(paddingY) != Double.doubleToLongBits(other.paddingY))\r
- return false;\r
- return true;\r
- }\r
- \r
- \r
-\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.diagram.elements;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.util.function.Consumer;
+
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.diagram.DiagramUtils;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.element.ElementHints;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.SceneGraphNodeKey;
+import org.simantics.g2d.element.handler.HandleMouseEvent;
+import org.simantics.g2d.element.handler.SceneGraph;
+import org.simantics.g2d.utils.Alignment;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.events.MouseEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+
+/**
+ * ElementHandler for text elements
+ * In-line editing supported.
+ *
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ */
+public class TextElementNoBounds implements SceneGraph, HandleMouseEvent {
+
+ private static final long serialVersionUID = -148784588840819612L;
+
+ public static final TextElementNoBounds INSTANCE = new TextElementNoBounds();
+
+ public static final Key SG_NODE = new SceneGraphNodeKey(TextNode.class, "TEXT_SG_NODE");
+
+ protected static final double DEFAULT_PADDING_X = 0.5;
+ protected static final double DEFAULT_PADDING_Y = 0.5;
+ protected static final double DEFAULT_SCALE = 0.235;
+
+ protected final double originX;
+ protected final double originY;
+ protected final Alignment horizontalAlignment;
+ protected final Alignment verticalAlignment;
+ protected final double borderWidth;
+ protected final boolean editable;
+ protected final double paddingX;
+ protected final double paddingY;
+ protected final double scale;
+
+
+ public TextElementNoBounds() {
+ this(0, 0, Alignment.LEADING, 0);
+ }
+
+ public TextElementNoBounds(double originX, double originY, Alignment horizontalAlignment) {
+ this(originX, originY, horizontalAlignment, 0);
+ }
+
+ public TextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth) {
+ this(originX, originY, horizontalAlignment, borderWidth, DEFAULT_PADDING_X, DEFAULT_PADDING_Y, true);
+ }
+
+ public TextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth, double paddingX, double paddingY, boolean editable) {
+ this(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable, DEFAULT_SCALE);
+ }
+
+ public TextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth, double paddingX, double paddingY, boolean editable, double scale) {
+ this(originX, originY, horizontalAlignment, Alignment.BASELINE, borderWidth, paddingX, paddingY, editable, scale);
+ }
+
+ public TextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, Alignment verticalAlignment, double borderWidth, double paddingX, double paddingY, boolean editable, double scale) {
+ if (horizontalAlignment == null)
+ throw new NullPointerException("null horizontal alignment");
+
+ this.originX = originX;
+ this.originY = originY;
+ this.horizontalAlignment = horizontalAlignment;
+ this.verticalAlignment = verticalAlignment;
+ this.borderWidth = borderWidth;
+ this.editable = editable;
+ this.paddingX = paddingX;
+ this.paddingY = paddingY;
+ this.scale = scale;
+ }
+
+ @Override
+ public void init(final IElement e, G2DParentNode parent) {
+ TextNode node = getOrCreateTextNode(e, parent);
+
+ Font font = ElementUtils.getTextFont(e);
+ Color color = ElementUtils.getTextColor(e);
+ Color fillColor = ElementUtils.getFillColor(e);
+ Color borderColor = ElementUtils.getBorderColor(e, Color.BLACK);
+ String text = ElementUtils.getText(e);
+ AffineTransform at = ElementUtils.getTransform(e);
+ Alignment hAlign = ElementUtils.getHintOrDefault(e, ElementHints.KEY_HORIZONTAL_ALIGN, horizontalAlignment);
+ Alignment vAlign = ElementUtils.getHintOrDefault(e, ElementHints.KEY_VERTICAL_ALIGN, verticalAlignment);
+ Double borderWidth = ElementUtils.getHintOrDefault(e, MonitorClass.KEY_BORDER_WIDTH, this.borderWidth);
+
+ node.init(text, font, color, originX, originY, scale);
+ node.setBackgroundColor(fillColor);
+ node.setBorderColor(borderColor);
+ node.setHorizontalAlignment((byte) hAlign.ordinal());
+ node.setVerticalAlignment((byte) vAlign.ordinal());
+ node.setPadding(paddingX, paddingY);
+ node.setBorderWidth(borderWidth.floatValue());
+ node.setEditable(editable);
+ if (at != null)
+ node.setTransform(at);
+
+ if(Boolean.TRUE.equals(ElementUtils.getHintOrDefault(e, ElementHints.KEY_RESIZABLE, false))) {
+ Rectangle2D bounds = e.getHint(ElementHints.KEY_BOUNDS);
+ if(bounds != null) {
+ node.setTargetBounds(bounds);
+ node.setWrapText(true);
+ }
+ }
+ }
+
+ protected TextNode getOrCreateTextNode(IElement e, G2DParentNode parent) {
+ return ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", TextNode.class, new TextNodeCallBack(e));
+ }
+
+ private class TextNodeCallBack implements Consumer<TextNode> {
+
+ IElement e;
+
+ public TextNodeCallBack(IElement e) {
+ this.e = e;
+ }
+
+ @Override
+ public void accept(TextNode node) {
+ node.setTextListener(new ITextListener() {
+ @Override
+ public void textChanged() {}
+
+ @Override
+ public void textEditingStarted() {}
+
+ @Override
+ public void textEditingCancelled() {
+ TextNode node = (TextNode) e.getHint(SG_NODE);
+ if (node != null)
+ endEdit(node);
+ }
+
+ @Override
+ public void textEditingEnded() {
+ TextNode node = (TextNode) e.getHint(SG_NODE);
+ if (node == null)
+ return;
+ //System.out.println("Node text changed: " + node.getText());
+ ElementUtils.setText(e, node.getText());
+ IDiagram diagram = ElementUtils.getDiagram(e);
+ DiagramUtils.synchronizeHintsToBackend(diagram, e);
+ endEdit(node);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void cleanup(IElement e) {
+ ElementUtils.removePossibleNode(e, SG_NODE);
+ }
+
+ // FIXME: hazardous with TextElementHandler.INSTANCE
+ TextEditActivation editActivation = null;
+
+ @Override
+ public boolean handleMouseEvent(IElement e, ICanvasContext ctx, MouseEvent me) {
+ if (me instanceof MouseEnterEvent) {
+ e.setHint(ElementHints.KEY_HOVER, true);
+ } else if (me instanceof MouseExitEvent) {
+ e.setHint(ElementHints.KEY_HOVER, false);
+ }
+
+ return false;
+ }
+
+ protected void endEdit(TextNode node) {
+ if (editActivation != null) {
+ editActivation.release();
+ editActivation = null;
+
+ node.setEditMode(false);
+ node.repaint();
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ long temp;
+ temp = Double.doubleToLongBits(borderWidth);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + horizontalAlignment.hashCode();
+ temp = Double.doubleToLongBits(originX);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(originY);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(paddingX);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(paddingY);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ TextElementNoBounds other = (TextElementNoBounds) obj;
+ if (Double.doubleToLongBits(borderWidth) != Double.doubleToLongBits(other.borderWidth))
+ return false;
+ if (horizontalAlignment != other.horizontalAlignment)
+ return false;
+ if (Double.doubleToLongBits(originX) != Double.doubleToLongBits(other.originX))
+ return false;
+ if (Double.doubleToLongBits(originY) != Double.doubleToLongBits(other.originY))
+ return false;
+ if (Double.doubleToLongBits(paddingX) != Double.doubleToLongBits(other.paddingX))
+ return false;
+ if (Double.doubleToLongBits(paddingY) != Double.doubleToLongBits(other.paddingY))
+ return false;
+ return true;
+ }
+
+
+
}
\ No newline at end of file