X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=inline;f=bundles%2Forg.simantics.scenegraph%2Fsrc%2Forg%2Fsimantics%2Fscenegraph%2Fg2d%2Fnodes%2FBoxSelectionNode.java;fp=bundles%2Forg.simantics.scenegraph%2Fsrc%2Forg%2Fsimantics%2Fscenegraph%2Fg2d%2Fnodes%2FBoxSelectionNode.java;h=3bd19430541a91f7661df4e67c71da035e0e1739;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/BoxSelectionNode.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/BoxSelectionNode.java new file mode 100644 index 000000000..3bd194305 --- /dev/null +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/BoxSelectionNode.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.scenegraph.g2d.nodes; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Stroke; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.g2d.events.EventTypes; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent; +import org.simantics.scenegraph.utils.GeometryUtils; +import org.simantics.scenegraph.utils.NodeUtil; + +/** + * @author Tuukka Lehtonen + */ +public class BoxSelectionNode extends G2DNode { + + private static final long serialVersionUID = 8508750881358776559L; + + protected Stroke stroke = new BasicStroke(2); + protected Color color = Color.BLACK; + protected boolean scaleStroke = false; + protected int mouseButton = 0; + + protected Point2D start = new Point2D.Double(0, 0); + protected Point2D end = new Point2D.Double(0, 0); + + protected SelectionListener listener = null; + + public static interface SelectionListener { + public void onSelect(Rectangle2D rect, int modifiers); + } + + @Override + public void init() { + super.init(); + addEventHandler(this); + } + + @Override + public void cleanup() { + removeEventHandler(this); + super.cleanup(); + } + + @SyncField("stroke") + public void setStroke(Stroke stroke) { + this.stroke = stroke; + } + + @SyncField("color") + public void setColor(Color color) { + this.color = color; + } + + @SyncField("scaleStroke") + public void setScaleStroke(boolean scaleStroke) { + this.scaleStroke = scaleStroke; + } + + @SyncField("start") + public void setStart(Point2D start) { + this.start = start; + } + + @SyncField("end") + public void setEnd(Point2D end) { + this.end = end; + } + + @SyncField("mouseButton") + public void setMouseButton(int mouseButton) { + this.mouseButton = mouseButton; + } + + @Override + public void render(Graphics2D g2d) { + Rectangle2D bounds = getBoundsInLocal(); + if (bounds == null || bounds.isEmpty()) + return; + + if (color != null) + g2d.setColor(color); + if (stroke != null) { + if (scaleStroke && stroke instanceof BasicStroke) { + BasicStroke bs = GeometryUtils.scaleStroke(stroke, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform()))); + g2d.setStroke(bs); + } else { + g2d.setStroke(stroke); + } + } + + g2d.draw(bounds); + } + + public void setSelectionListener(SelectionListener listener) { + this.listener = listener; + } + + @ServerSide + private void onSelect(Rectangle2D selection, int modifiers) { + if (listener != null) + listener.onSelect(selection, modifiers); + } + + @Override + public Rectangle2D getBoundsInLocal() { + // Empty bounds indicate no rendering. + if (start == null || end == null) + return new Rectangle2D.Double(); + + Rectangle2D rect = new Rectangle2D.Double(Math.min(start.getX(), end.getX()), + Math.min(start.getY(), end.getY()), + Math.max(start.getX(), end.getX())-Math.min(start.getX(), end.getX()), + Math.max(start.getY(), end.getY())-Math.min(start.getY(), end.getY())); + return rect; + } + + @Override + public int getEventMask() { + return EventTypes.MouseButtonReleasedMask | EventTypes.MouseDragBeginMask + | EventTypes.MouseMovedMask; + } + + @Override + protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) { + if (e.button == mouseButton) { + onSelect(getBoundsInLocal(), e.stateMask); + start = null; + end = null; + } + return false; + } + + @Override + protected boolean mouseMoved(MouseMovedEvent e) { + if (end != null) { + NodeUtil.worldToLocal(this, e.controlPosition, end); + repaint(); + } + return false; + } + +}