--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.g2d.participant;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+\r
+import org.simantics.g2d.canvas.Hints;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;\r
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;\r
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
+import org.simantics.scenegraph.g2d.events.command.CommandEvent;\r
+import org.simantics.scenegraph.g2d.events.command.Commands;\r
+import org.simantics.scenegraph.g2d.nodes.GridNode;\r
+import org.simantics.scenegraph.g2d.snap.ISnapAdvisor;\r
+import org.simantics.utils.datastructures.hints.HintListenerAdapter;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+\r
+\r
+/**\r
+ * GridPainter draws grid lines through the scene graph.\r
+ *\r
+ * This interactor has no dependencies to other participants.\r
+ *\r
+ * @author Toni Kalajainen\r
+ * \r
+ * @see GridNode\r
+ */\r
+public class GridPainter extends AbstractCanvasParticipant {\r
+\r
+ /**\r
+ * Grid enabled status. Default value is True\r
+ */\r
+ public static final Key KEY_GRID_ENABLED = new KeyOf(Boolean.class, "GRID_ENABLED");\r
+\r
+ /**\r
+ * Specifies the absolute diagram grid size, which is also the snapping grid\r
+ * size. This painter will use {@link GridNode} to draw the grid in a\r
+ * resolution that is no less than this value. The value is expected to be\r
+ * defined in millimeters which is the standard diagram unit.\r
+ */\r
+ public static final Key KEY_GRID_SIZE = new KeyOf(Double.class, "GRID_SIZE");\r
+\r
+ private static final double DEFAULT_GRID_SIZE = 1.0;\r
+\r
+ public static final BasicStroke GRID_LINE_STROKE =\r
+ new BasicStroke(0.1f,\r
+ BasicStroke.CAP_SQUARE,\r
+ BasicStroke.CAP_SQUARE,\r
+ 10.0f, null, 0.0f);\r
+\r
+ IHintListener gridListener = new HintListenerAdapter() {\r
+ public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
+ ICanvasContext cc = getContext();\r
+ if (cc != null) {\r
+ updateNode();\r
+ cc.getContentContext().setDirty();\r
+ }\r
+ }\r
+ };\r
+\r
+ @Override\r
+ public void addedToContext(ICanvasContext ctx) {\r
+ super.addedToContext(ctx);\r
+ getHintStack().addKeyHintListener(getThread(), KEY_GRID_ENABLED, gridListener);\r
+ getHintStack().addKeyHintListener(getThread(), KEY_GRID_SIZE, gridListener);\r
+ getHintStack().addKeyHintListener(getThread(), Hints.KEY_GRID_COLOR, gridListener);\r
+ getHintStack().addKeyHintListener(getThread(), Hints.KEY_DISABLE_PAINTING, gridListener);\r
+ getHintStack().addKeyHintListener(getThread(), DiagramHints.SNAP_ADVISOR, gridListener);\r
+ }\r
+\r
+ @Override\r
+ public void removedFromContext(ICanvasContext ctx) {\r
+ getHintStack().removeKeyHintListener(getThread(), KEY_GRID_ENABLED, gridListener);\r
+ getHintStack().removeKeyHintListener(getThread(), KEY_GRID_SIZE, gridListener);\r
+ getHintStack().removeKeyHintListener(getThread(), Hints.KEY_GRID_COLOR, gridListener);\r
+ getHintStack().removeKeyHintListener(getThread(), Hints.KEY_DISABLE_PAINTING, gridListener);\r
+ getHintStack().removeKeyHintListener(getThread(), DiagramHints.SNAP_ADVISOR, gridListener);\r
+ super.removedFromContext(ctx);\r
+ }\r
+\r
+ @EventHandler(priority = 0)\r
+ public boolean handleKeyEvent(CommandEvent e) {\r
+ if (e.command.equals( Commands.GRID_ENABLE )) {\r
+ setEnabled(true);\r
+ updateNode();\r
+ setDirty();\r
+ return true;\r
+ } else if (e.command.equals( Commands.GRID_DISABLE )) {\r
+ setEnabled(false);\r
+ updateNode();\r
+ setDirty();\r
+ return true;\r
+ } else if (e.command.equals( Commands.GRID_TOGGLE )) {\r
+ setEnabled(!isGridEnabled());\r
+ updateNode();\r
+ setDirty();\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ protected GridNode node = null;\r
+\r
+ @SGInit\r
+ public void initSG(G2DParentNode parent) {\r
+ node = parent.addNode(GridNode.GRID_NODE_ID, GridNode.class);\r
+ node.setLookupId(GridNode.GRID_NODE_ID);\r
+ node.setZIndex(Integer.MIN_VALUE + 1000);\r
+ updateNode();\r
+ }\r
+\r
+ @SGCleanup\r
+ public void cleanupSG() {\r
+ node.remove();\r
+ }\r
+\r
+ protected void updateNode() {\r
+ node.setEnabled(isPaintingEnabled());\r
+ node.setGridColor(getGridColor());\r
+ node.setGridSize(getGridSize());\r
+ node.setSnapAdvisor( (ISnapAdvisor) getHint(DiagramHints.SNAP_ADVISOR) );\r
+ }\r
+\r
+ boolean isPaintingEnabled()\r
+ {\r
+ boolean enabled = isGridEnabled();\r
+ Boolean globalDisable = getHint(Hints.KEY_DISABLE_PAINTING);\r
+ return enabled && !Boolean.TRUE.equals(globalDisable);\r
+ }\r
+\r
+ public boolean isGridEnabled()\r
+ {\r
+ Boolean enabled = getHint(KEY_GRID_ENABLED);\r
+ return !Boolean.FALSE.equals(enabled);\r
+ }\r
+\r
+ public void setEnabled(boolean enabled)\r
+ {\r
+ setHint(KEY_GRID_ENABLED, enabled);\r
+ }\r
+\r
+ public Color getGridColor()\r
+ {\r
+ return getHint(Hints.KEY_GRID_COLOR);\r
+ }\r
+\r
+ /**\r
+ * Convenience method\r
+ * @param r\r
+ * @param g\r
+ * @param b\r
+ */\r
+ public void setGridColor(int r, int g, int b)\r
+ {\r
+ setGridColor(new Color(r, g, b));\r
+ }\r
+\r
+ /**\r
+ * Convenience method\r
+ * @param c\r
+ */\r
+ public void setGridColor(Color c)\r
+ {\r
+ setHint(Hints.KEY_GRID_COLOR, c);\r
+ }\r
+\r
+ public double getGridSize()\r
+ {\r
+ Double d = getHint(KEY_GRID_SIZE);\r
+ return d == null ? DEFAULT_GRID_SIZE : d.doubleValue();\r
+ }\r
+\r
+ public void setGridSize(double gridSize)\r
+ {\r
+ setHint(KEY_GRID_SIZE, gridSize);\r
+ }\r
+\r
+}\r