]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/BoxSelectionNode.java
Sync git svn branch with SVN repository r33269.
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / BoxSelectionNode.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in 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.scenegraph.g2d.nodes;
13 \r
14 import java.awt.BasicStroke;\r
15 import java.awt.Color;\r
16 import java.awt.Graphics2D;\r
17 import java.awt.Stroke;\r
18 import java.awt.geom.Point2D;\r
19 import java.awt.geom.Rectangle2D;\r
20 \r
21 import org.simantics.scenegraph.g2d.G2DNode;\r
22 import org.simantics.scenegraph.g2d.events.EventTypes;\r
23 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;\r
24 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
25 import org.simantics.scenegraph.utils.GeometryUtils;\r
26 import org.simantics.scenegraph.utils.NodeUtil;\r
27
28 /**\r
29  * @author Tuukka Lehtonen\r
30  */\r
31 public class BoxSelectionNode extends G2DNode {
32
33     private static final long serialVersionUID = 8508750881358776559L;
34
35     protected Stroke            stroke           = new BasicStroke(2);\r
36     protected Color             color            = Color.BLACK;\r
37     protected boolean           scaleStroke      = false;\r
38     protected int               mouseButton      = 0;\r
39
40     protected Point2D           start            = new Point2D.Double(0, 0);\r
41     protected Point2D           end              = new Point2D.Double(0, 0);\r
42 \r
43     protected SelectionListener listener         = null;\r
44 \r
45     public static interface SelectionListener {
46         public void onSelect(Rectangle2D rect, int modifiers);
47     }
48 \r
49     @Override\r
50     public void init() {\r
51         super.init();\r
52         addEventHandler(this);\r
53     }\r
54 \r
55     @Override\r
56     public void cleanup() {\r
57         removeEventHandler(this);\r
58         super.cleanup();\r
59     }\r
60
61     @SyncField("stroke")
62     public void setStroke(Stroke stroke) {
63         this.stroke = stroke;
64     }
65
66     @SyncField("color")
67     public void setColor(Color color) {
68         this.color = color;
69     }
70
71     @SyncField("scaleStroke")
72     public void setScaleStroke(boolean scaleStroke) {
73         this.scaleStroke = scaleStroke;
74     }
75
76     @SyncField("start")
77     public void setStart(Point2D start) {
78         this.start = start;
79     }
80
81     @SyncField("end")
82     public void setEnd(Point2D end) {
83         this.end = end;
84     }
85 \r
86     @SyncField("mouseButton")
87     public void setMouseButton(int mouseButton) {\r
88         this.mouseButton = mouseButton;\r
89     }\r
90 \r
91     @Override
92     public void render(Graphics2D g2d) {
93         Rectangle2D bounds = getBoundsInLocal();\r
94         if (bounds == null || bounds.isEmpty())\r
95             return;\r
96 \r
97         if (color != null)\r
98             g2d.setColor(color);\r
99         if (stroke != null) {\r
100             if (scaleStroke && stroke instanceof BasicStroke) {\r
101                 BasicStroke bs = GeometryUtils.scaleStroke(stroke, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
102                 g2d.setStroke(bs);
103             } else {
104                 g2d.setStroke(stroke);
105             }
106         }
107 \r
108         g2d.draw(bounds);
109     }
110
111     public void setSelectionListener(SelectionListener listener) {
112         this.listener = listener;
113     }
114
115     @ServerSide
116     private void onSelect(Rectangle2D selection, int modifiers) {
117         if (listener != null)\r
118             listener.onSelect(selection, modifiers);\r
119     }
120
121     @Override
122     public Rectangle2D getBoundsInLocal() {\r
123         // Empty bounds indicate no rendering.\r
124         if (start == null || end == null)\r
125             return new Rectangle2D.Double();\r
126
127         Rectangle2D rect = new Rectangle2D.Double(Math.min(start.getX(), end.getX()),
128                 Math.min(start.getY(), end.getY()),
129                 Math.max(start.getX(), end.getX())-Math.min(start.getX(), end.getX()),
130                 Math.max(start.getY(), end.getY())-Math.min(start.getY(), end.getY()));\r
131         return rect;
132     }\r
133 \r
134     @Override\r
135     public int getEventMask() {\r
136         return EventTypes.MouseButtonReleasedMask | EventTypes.MouseDragBeginMask\r
137                 | EventTypes.MouseMovedMask;\r
138     }\r
139 \r
140     @Override\r
141     protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) {\r
142         if (e.button == mouseButton) {\r
143             onSelect(getBoundsInLocal(), e.stateMask);\r
144             start = null;\r
145             end = null;\r
146         }\r
147         return false;\r
148     }\r
149 \r
150     @Override\r
151     protected boolean mouseMoved(MouseMovedEvent e) {\r
152         if (end != null) {\r
153             NodeUtil.worldToLocal(this, e.controlPosition, end);\r
154             repaint();\r
155         }\r
156         return false;\r
157     }\r
158 \r
159 }