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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.scenegraph.g2d.nodes;
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
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
29 * @author Tuukka Lehtonen
\r
31 public class BoxSelectionNode extends G2DNode {
33 private static final long serialVersionUID = 8508750881358776559L;
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
40 protected Point2D start = new Point2D.Double(0, 0);
\r
41 protected Point2D end = new Point2D.Double(0, 0);
\r
43 protected SelectionListener listener = null;
\r
45 public static interface SelectionListener {
46 public void onSelect(Rectangle2D rect, int modifiers);
50 public void init() {
\r
52 addEventHandler(this);
\r
56 public void cleanup() {
\r
57 removeEventHandler(this);
\r
62 public void setStroke(Stroke stroke) {
67 public void setColor(Color color) {
71 @SyncField("scaleStroke")
72 public void setScaleStroke(boolean scaleStroke) {
73 this.scaleStroke = scaleStroke;
77 public void setStart(Point2D start) {
82 public void setEnd(Point2D end) {
86 @SyncField("mouseButton")
87 public void setMouseButton(int mouseButton) {
\r
88 this.mouseButton = mouseButton;
\r
92 public void render(Graphics2D g2d) {
93 Rectangle2D bounds = getBoundsInLocal();
\r
94 if (bounds == null || bounds.isEmpty())
\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())));
104 g2d.setStroke(stroke);
111 public void setSelectionListener(SelectionListener listener) {
112 this.listener = listener;
116 private void onSelect(Rectangle2D selection, int modifiers) {
117 if (listener != null)
\r
118 listener.onSelect(selection, modifiers);
\r
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
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
135 public int getEventMask() {
\r
136 return EventTypes.MouseButtonReleasedMask | EventTypes.MouseDragBeginMask
\r
137 | EventTypes.MouseMovedMask;
\r
141 protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) {
\r
142 if (e.button == mouseButton) {
\r
143 onSelect(getBoundsInLocal(), e.stateMask);
\r
151 protected boolean mouseMoved(MouseMovedEvent e) {
\r
153 NodeUtil.worldToLocal(this, e.controlPosition, end);
\r