1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.scenegraph.g2d.nodes;
14 import java.awt.BasicStroke;
15 import java.awt.Color;
16 import java.awt.Graphics2D;
17 import java.awt.Stroke;
18 import java.awt.geom.Point2D;
19 import java.awt.geom.Rectangle2D;
21 import org.simantics.scenegraph.g2d.G2DNode;
22 import org.simantics.scenegraph.g2d.events.EventTypes;
23 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;
24 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
25 import org.simantics.scenegraph.utils.GeometryUtils;
26 import org.simantics.scenegraph.utils.NodeUtil;
29 * @author Tuukka Lehtonen
31 public class BoxSelectionNode extends G2DNode {
33 private static final long serialVersionUID = 8508750881358776559L;
35 protected Stroke stroke = new BasicStroke(2);
36 protected Color color = Color.BLACK;
37 protected boolean scaleStroke = false;
38 protected int mouseButton = 0;
40 protected Point2D start = new Point2D.Double(0, 0);
41 protected Point2D end = new Point2D.Double(0, 0);
43 protected SelectionListener listener = null;
45 public static interface SelectionListener {
46 public void onSelect(Rectangle2D rect, int modifiers);
52 addEventHandler(this);
56 public void cleanup() {
57 removeEventHandler(this);
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) {
88 this.mouseButton = mouseButton;
92 public void render(Graphics2D g2d) {
93 Rectangle2D bounds = getBoundsInLocal();
94 if (bounds == null || bounds.isEmpty())
100 if (scaleStroke && stroke instanceof BasicStroke) {
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)
118 listener.onSelect(selection, modifiers);
122 public Rectangle2D getBoundsInLocal() {
123 // Empty bounds indicate no rendering.
124 if (start == null || end == null)
125 return new Rectangle2D.Double();
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()));
135 public int getEventMask() {
136 return EventTypes.MouseButtonReleasedMask | EventTypes.MouseDragBeginMask
137 | EventTypes.MouseMovedMask;
141 protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) {
142 if (e.button == mouseButton) {
143 onSelect(getBoundsInLocal(), e.stateMask);
151 protected boolean mouseMoved(MouseMovedEvent e) {
153 NodeUtil.worldToLocal(this, e.controlPosition, end);