]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
7ca96929fc6ea7c0eac79f343cd2eece39911a4e
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.jfreechart.chart.element;\r
13 \r
14 import java.awt.Shape;\r
15 import java.awt.geom.AffineTransform;\r
16 import java.awt.geom.Rectangle2D;\r
17 \r
18 import org.jfree.chart.JFreeChart;\r
19 import org.simantics.g2d.canvas.ICanvasContext;\r
20 import org.simantics.g2d.diagram.DiagramUtils;\r
21 import org.simantics.g2d.diagram.IDiagram;\r
22 import org.simantics.g2d.element.ElementHints;\r
23 import org.simantics.g2d.element.ElementUtils;\r
24 import org.simantics.g2d.element.IElement;\r
25 import org.simantics.g2d.element.SceneGraphNodeKey;\r
26 import org.simantics.g2d.element.handler.HandleMouseEvent;\r
27 import org.simantics.g2d.element.handler.InternalSize;\r
28 import org.simantics.g2d.element.handler.PropertySetter;\r
29 import org.simantics.g2d.element.handler.SceneGraph;\r
30 import org.simantics.scenegraph.Node;\r
31 import org.simantics.scenegraph.g2d.G2DParentNode;\r
32 import org.simantics.scenegraph.g2d.IG2DNode;\r
33 import org.simantics.scenegraph.g2d.events.MouseEvent;\r
34 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent;\r
35 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;\r
36 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
37 import org.simantics.utils.datastructures.hints.IHintListener;\r
38 import org.simantics.utils.datastructures.hints.IHintObservable;\r
39 \r
40 /**\r
41  * Chart scenegraph for chart elements in diagrams\r
42  * @author Teemu Lempinen\r
43  *\r
44  */\r
45 public class ChartSceneGraph  implements SceneGraph, HandleMouseEvent, InternalSize {\r
46     private static final long serialVersionUID = 1875762898776996989L;\r
47 \r
48     public static final Key KEY_SG_NODE = new SceneGraphNodeKey(Node.class, "CHART_SG_NODE");\r
49     public static final Key KEY_SG_SELECTION_NODE = new SceneGraphNodeKey(Node.class, "CHART_SG_SELECTION_NODE");\r
50 \r
51     protected IHintListener hoverHintListener;\r
52 \r
53     public ChartSceneGraph() {\r
54     }\r
55 \r
56     /**\r
57      * Expands bounds a little to allow selecting and grabbing a chart element\r
58      * from outside the chart graphics\r
59      */\r
60     @Override\r
61     public Rectangle2D getBounds(IElement e, Rectangle2D s) {\r
62         if (s==null) s = new Rectangle2D.Double();\r
63 \r
64         IG2DNode node = (IG2DNode)e.getHint(KEY_SG_NODE);\r
65         AffineTransform at = (AffineTransform)e.getHint(ElementHints.KEY_TRANSFORM);\r
66         if(at != null && node != null && node.getBoundsInLocal() != null) {\r
67             Shape shape = node.getBoundsInLocal();\r
68             Rectangle2D r = shape.getBounds2D();\r
69             double scaleX = at.getScaleX();\r
70             double scaleY = at.getScaleY();\r
71             ChartNode.expand(r, 1 * scaleX, 1 * scaleY);\r
72             shape = r;\r
73             s.setFrame(shape.getBounds2D());\r
74         } else {\r
75             s.setFrame((Rectangle2D)e.getHint(ElementHints.KEY_BOUNDS));\r
76         }\r
77         return s;\r
78     }\r
79 \r
80     @Override\r
81     public void cleanup(IElement e) {\r
82         if(hoverHintListener != null)\r
83             e.removeHintListener(hoverHintListener);\r
84 \r
85         Node node = e.removeHint(KEY_SG_NODE);\r
86         if (node != null)\r
87             node.remove();\r
88     }\r
89 \r
90     @Override\r
91     public void init(final IElement e, G2DParentNode parent) {\r
92         ChartNode node = e.getHint(KEY_SG_NODE);\r
93         if(node == null) {\r
94             // Create a new chart node\r
95             node = parent.getOrCreateNode("chart_"+e.hashCode(), ChartNode.class);\r
96 \r
97             Rectangle2D bounds = (Rectangle2D)e.getHint(ElementHints.KEY_BOUNDS);\r
98             if(bounds == null) {\r
99                 bounds = new Rectangle2D.Double(-40, -40, 80, 80);\r
100                 e.setHint(ElementHints.KEY_BOUNDS, bounds);\r
101             }\r
102             node.setBounds(bounds);\r
103 \r
104             JFreeChart chart = e.getHint(ChartElementFactory.KEY_CHART);\r
105             if(chart != null)\r
106                 node.setChart(chart);\r
107 \r
108             // Add a resize listener for updating bounds information to graph after resizing\r
109             node.setResizeListener(new ResizeListener() {\r
110 \r
111                 @Override\r
112                 public void elementResized(Rectangle2D newBounds) {\r
113                     e.setHint(ElementHints.KEY_BOUNDS, newBounds);\r
114                     IDiagram diagram = ElementUtils.getDiagram(e);\r
115                     DiagramUtils.synchronizeHintsToBackend(diagram, e);\r
116                 }\r
117             });\r
118 \r
119             e.setHint(KEY_SG_NODE, node);\r
120         }\r
121 \r
122         // Hover listening\r
123         hoverHintListener = new IHintListener() {\r
124             @Override\r
125             public void hintRemoved(IHintObservable sender, Key key, Object oldValue) {\r
126 \r
127             }\r
128 \r
129             @Override\r
130             public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
131                 if(key == ElementHints.KEY_HOVER) {\r
132                     IElement e = (IElement)sender;\r
133                     ChartNode name = (ChartNode) e.getHint(KEY_SG_NODE);\r
134                     if (name != null)\r
135                         name.setHover(Boolean.TRUE.equals(e.getHint(ElementHints.KEY_HOVER)));\r
136                 }\r
137             }\r
138         };\r
139         e.addHintListener(hoverHintListener);\r
140 \r
141         update(e);\r
142     }\r
143 \r
144     public void update(IElement e) {\r
145         PropertySetter setter = e.getElementClass().getSingleItem(PropertySetter.class);\r
146         setter.syncPropertiesToNode(e);\r
147     }\r
148 \r
149     \r
150     @Override\r
151     public boolean handleMouseEvent(IElement e, ICanvasContext ctx, MouseEvent me) {\r
152         if (me instanceof MouseEnterEvent) {\r
153             e.setHint(ElementHints.KEY_HOVER, true);\r
154         } else if (me instanceof MouseExitEvent) {\r
155             e.setHint(ElementHints.KEY_HOVER, false);\r
156         }\r
157         return false;\r
158     }\r
159 }\r