-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g2d.participant;\r
-\r
-import java.awt.BasicStroke;\r
-import java.awt.Color;\r
-import java.awt.Cursor;\r
-import java.awt.Shape;\r
-import java.awt.geom.Path2D;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.canvas.IMouseCursorContext;\r
-import org.simantics.g2d.canvas.IMouseCursorHandle;\r
-import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;\r
-import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
-import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;\r
-import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;\r
-import org.simantics.g2d.diagram.DiagramHints;\r
-import org.simantics.g2d.diagram.handler.PickContext;\r
-import org.simantics.g2d.diagram.participant.Selection;\r
-import org.simantics.g2d.diagram.participant.pointertool.AbstractMode;\r
-import org.simantics.g2d.participant.MouseUtil.MouseInfo;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
-import org.simantics.scenegraph.g2d.events.Event;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent;\r
-import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
-import org.simantics.scenegraph.g2d.events.command.CommandEvent;\r
-import org.simantics.scenegraph.g2d.events.command.Commands;\r
-import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
-import org.simantics.utils.ObjectUtils;\r
-import org.simantics.utils.page.MarginUtils;\r
-\r
-/**\r
- * ZoomToAreaHandler starts an area zoom mode when a ZOOM_TO_AREA command is\r
- * issued.\r
- *\r
- * @author Tuukka Lehtonen\r
- */\r
-public class ZoomToAreaHandler extends AbstractCanvasParticipant {\r
-\r
- public final static Cursor ZOOM_CURSOR = new Cursor(Cursor.CROSSHAIR_CURSOR);\r
-\r
- @EventHandler(priority = 0)\r
- public boolean handleZoomToArea(CommandEvent event) {\r
- if (Commands.ZOOM_TO_AREA.equals( event.command )) {\r
- if (!getContext().containsItemByClass(ZoomToAreaMode.class)) {\r
- getContext().add( new ZoomToAreaMode() );\r
- setDirty();\r
- }\r
- return true;\r
- }\r
- return false;\r
- }\r
-\r
- class ZoomToAreaMode extends AbstractMode {\r
-\r
- @Dependency TransformUtil util;\r
- @Dependency Selection selection;\r
- @Dependency PickContext pickContext;\r
- @Dependency KeyUtil keyUtil;\r
- @Dependency MouseUtil mouseUtil;\r
- @Dependency CanvasBoundsParticipant canvasBounds;\r
-\r
- public final BasicStroke STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10f, new float[] {4,2}, 0);\r
-\r
- public static final int PAINT_PRIORITY = 30;\r
-\r
- Point2D startingPoint;\r
- Point2D currentPoint;\r
- IMouseCursorHandle cursor;\r
-\r
- public ZoomToAreaMode() {\r
- super(0);\r
- }\r
-\r
- @Override\r
- public void addedToContext(ICanvasContext ctx) {\r
- super.addedToContext(ctx);\r
- IMouseCursorContext mctx = getContext().getMouseCursorContext();\r
- if (mctx != null)\r
- cursor = mctx.setCursor(getMouseId(), ZOOM_CURSOR);\r
- MouseInfo mi = mouseUtil.getMouseInfo(getMouseId());\r
- if (mi != null)\r
- currentPoint = mi.canvasPosition;\r
- }\r
-\r
- @Override\r
- public void removedFromContext(ICanvasContext ctx) {\r
- if (cursor != null) {\r
- cursor.remove();\r
- cursor = null;\r
- }\r
- super.removedFromContext(ctx);\r
- }\r
-\r
- @EventHandler(priority = 10)\r
- public boolean handleEvent(Event e) {\r
- if (e instanceof CommandEvent) {\r
- CommandEvent ce = (CommandEvent) e;\r
- if (ce.command.equals( Commands.CANCEL )){\r
- setDirty();\r
- remove();\r
- return true;\r
- }\r
- } else if (e instanceof MouseMovedEvent) {\r
- MouseMovedEvent event = (MouseMovedEvent) e;\r
- if (event.mouseId != getMouseId()) return false;\r
- Point2D canvasPos = util.controlToCanvas(event.controlPosition, null);\r
- if (!ObjectUtils.objectEquals(currentPoint, canvasPos))\r
- {\r
- currentPoint = canvasPos;\r
- update(getBox());\r
- setDirty();\r
- }\r
- return false;\r
- } else if (e instanceof MouseButtonEvent) {\r
- MouseButtonEvent event = (MouseButtonEvent) e;\r
-\r
- if (event.mouseId != getMouseId()) return false;\r
- if (event.button != MouseEvent.LEFT_BUTTON) return false;\r
-\r
- // Eat all other mouse button events besides press and click.\r
- // Must use mouse clicks here because otherwise selection\r
- // participants etc. might alter selections on the next incoming\r
- // mouse click event, which only confuses the user.\r
- if (e instanceof MouseClickEvent) {\r
- Point2D canvasPos = util.controlToCanvas(event.controlPosition, null);\r
- currentPoint = canvasPos;\r
-\r
- if (startingPoint == null) {\r
- // Start marking the box\r
- startingPoint = currentPoint;\r
- setDirty();\r
- return true;\r
- }\r
-\r
- Rectangle2D area = new Rectangle2D.Double();\r
- area.setFrameFromDiagonal(startingPoint, currentPoint);\r
-\r
- Rectangle2D controlArea = canvasBounds.getControlBounds();\r
- util.fitArea(controlArea, area, PanZoomRotateHandler.getZoomToFitMargins(getHintStack()));\r
-\r
- setDirty();\r
- remove();\r
- return true;\r
- }\r
- return true;\r
- }\r
- return false;\r
- }\r
-\r
- /**\r
- * Get selection box in control coordinates\r
- * @return control coordinates\r
- */\r
- protected Rectangle2D getBox() {\r
- if (startingPoint == null)\r
- return null;\r
- Point2D p1 = startingPoint;\r
- Point2D p2 = currentPoint;\r
- double ax = p1.getX();\r
- double ay = p1.getY();\r
- double bx = p2.getX();\r
- double by = p2.getY();\r
- if (bx < ax) {\r
- double temp = ax;\r
- ax = bx;\r
- bx = temp;\r
- }\r
- if (by < ay) {\r
- double temp = ay;\r
- ay = by;\r
- by = temp;\r
- }\r
- return new Rectangle2D.Double(ax, ay, bx - ax, by - ay);\r
- }\r
-\r
- protected Path2D getCrossHair(Rectangle2D controlBounds) {\r
- Point2D controlPos = util.canvasToControl(currentPoint, null);\r
- Path2D path = new Path2D.Double();\r
- path.moveTo(controlBounds.getMinX(), controlPos.getY());\r
- path.lineTo(controlBounds.getMaxX(), controlPos.getY());\r
- path.moveTo(controlPos.getX(), controlBounds.getMinY());\r
- path.lineTo(controlPos.getX(), controlBounds.getMaxY());\r
- return path;\r
- }\r
-\r
- public synchronized Color getToolColor()\r
- {\r
- Color c = getHint(DiagramHints.KEY_SELECTION_FRAME_COLOR);\r
- if (c!=null) return c;\r
- return Color.BLACK;\r
- }\r
-\r
- protected ShapeNode node = null;\r
-\r
- @SGInit\r
- public void initSG(G2DParentNode parent) {\r
- node = parent.addNode("zoom to area", ShapeNode.class);\r
- node.setZIndex(PAINT_PRIORITY);\r
- node.setStroke(STROKE);\r
- node.setScaleStroke(true);\r
- node.setColor(getToolColor());\r
- node.setFill(false);\r
- }\r
-\r
- void update(Shape shape) {\r
- if (node != null) {\r
- node.setShape(shape);\r
- }\r
- }\r
-\r
- @SGCleanup\r
- public void cleanupSG() {\r
- if (node != null) {\r
- node.remove();\r
- node = null;\r
- }\r
- }\r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * 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.g2d.participant;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Shape;
+import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.canvas.IMouseCursorContext;
+import org.simantics.g2d.canvas.IMouseCursorHandle;
+import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
+import org.simantics.g2d.diagram.DiagramHints;
+import org.simantics.g2d.diagram.handler.PickContext;
+import org.simantics.g2d.diagram.participant.Selection;
+import org.simantics.g2d.diagram.participant.pointertool.AbstractMode;
+import org.simantics.g2d.participant.MouseUtil.MouseInfo;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.events.Event;
+import org.simantics.scenegraph.g2d.events.MouseEvent;
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
+import org.simantics.scenegraph.g2d.events.command.CommandEvent;
+import org.simantics.scenegraph.g2d.events.command.Commands;
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;
+import org.simantics.utils.ObjectUtils;
+import org.simantics.utils.page.MarginUtils;
+
+/**
+ * ZoomToAreaHandler starts an area zoom mode when a ZOOM_TO_AREA command is
+ * issued.
+ *
+ * @author Tuukka Lehtonen
+ */
+public class ZoomToAreaHandler extends AbstractCanvasParticipant {
+
+ public final static Cursor ZOOM_CURSOR = new Cursor(Cursor.CROSSHAIR_CURSOR);
+
+ @EventHandler(priority = 0)
+ public boolean handleZoomToArea(CommandEvent event) {
+ if (Commands.ZOOM_TO_AREA.equals( event.command )) {
+ if (!getContext().containsItemByClass(ZoomToAreaMode.class)) {
+ getContext().add( new ZoomToAreaMode() );
+ setDirty();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ class ZoomToAreaMode extends AbstractMode {
+
+ @Dependency TransformUtil util;
+ @Dependency Selection selection;
+ @Dependency PickContext pickContext;
+ @Dependency KeyUtil keyUtil;
+ @Dependency MouseUtil mouseUtil;
+ @Dependency CanvasBoundsParticipant canvasBounds;
+
+ public final BasicStroke STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10f, new float[] {4,2}, 0);
+
+ public static final int PAINT_PRIORITY = 30;
+
+ Point2D startingPoint;
+ Point2D currentPoint;
+ IMouseCursorHandle cursor;
+
+ public ZoomToAreaMode() {
+ super(0);
+ }
+
+ @Override
+ public void addedToContext(ICanvasContext ctx) {
+ super.addedToContext(ctx);
+ IMouseCursorContext mctx = getContext().getMouseCursorContext();
+ if (mctx != null)
+ cursor = mctx.setCursor(getMouseId(), ZOOM_CURSOR);
+ MouseInfo mi = mouseUtil.getMouseInfo(getMouseId());
+ if (mi != null)
+ currentPoint = mi.canvasPosition;
+ }
+
+ @Override
+ public void removedFromContext(ICanvasContext ctx) {
+ if (cursor != null) {
+ cursor.remove();
+ cursor = null;
+ }
+ super.removedFromContext(ctx);
+ }
+
+ @EventHandler(priority = 10)
+ public boolean handleEvent(Event e) {
+ if (e instanceof CommandEvent) {
+ CommandEvent ce = (CommandEvent) e;
+ if (ce.command.equals( Commands.CANCEL )){
+ setDirty();
+ remove();
+ return true;
+ }
+ } else if (e instanceof MouseMovedEvent) {
+ MouseMovedEvent event = (MouseMovedEvent) e;
+ if (event.mouseId != getMouseId()) return false;
+ Point2D canvasPos = util.controlToCanvas(event.controlPosition, null);
+ if (!ObjectUtils.objectEquals(currentPoint, canvasPos))
+ {
+ currentPoint = canvasPos;
+ update(getBox());
+ setDirty();
+ }
+ return false;
+ } else if (e instanceof MouseButtonEvent) {
+ MouseButtonEvent event = (MouseButtonEvent) e;
+
+ if (event.mouseId != getMouseId()) return false;
+ if (event.button != MouseEvent.LEFT_BUTTON) return false;
+
+ // Eat all other mouse button events besides press and click.
+ // Must use mouse clicks here because otherwise selection
+ // participants etc. might alter selections on the next incoming
+ // mouse click event, which only confuses the user.
+ if (e instanceof MouseClickEvent) {
+ Point2D canvasPos = util.controlToCanvas(event.controlPosition, null);
+ currentPoint = canvasPos;
+
+ if (startingPoint == null) {
+ // Start marking the box
+ startingPoint = currentPoint;
+ setDirty();
+ return true;
+ }
+
+ Rectangle2D area = new Rectangle2D.Double();
+ area.setFrameFromDiagonal(startingPoint, currentPoint);
+
+ Rectangle2D controlArea = canvasBounds.getControlBounds();
+ util.fitArea(controlArea, area, PanZoomRotateHandler.getZoomToFitMargins(getHintStack()));
+
+ setDirty();
+ remove();
+ return true;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Get selection box in control coordinates
+ * @return control coordinates
+ */
+ protected Rectangle2D getBox() {
+ if (startingPoint == null)
+ return null;
+ Point2D p1 = startingPoint;
+ Point2D p2 = currentPoint;
+ double ax = p1.getX();
+ double ay = p1.getY();
+ double bx = p2.getX();
+ double by = p2.getY();
+ if (bx < ax) {
+ double temp = ax;
+ ax = bx;
+ bx = temp;
+ }
+ if (by < ay) {
+ double temp = ay;
+ ay = by;
+ by = temp;
+ }
+ return new Rectangle2D.Double(ax, ay, bx - ax, by - ay);
+ }
+
+ protected Path2D getCrossHair(Rectangle2D controlBounds) {
+ Point2D controlPos = util.canvasToControl(currentPoint, null);
+ Path2D path = new Path2D.Double();
+ path.moveTo(controlBounds.getMinX(), controlPos.getY());
+ path.lineTo(controlBounds.getMaxX(), controlPos.getY());
+ path.moveTo(controlPos.getX(), controlBounds.getMinY());
+ path.lineTo(controlPos.getX(), controlBounds.getMaxY());
+ return path;
+ }
+
+ public synchronized Color getToolColor()
+ {
+ Color c = getHint(DiagramHints.KEY_SELECTION_FRAME_COLOR);
+ if (c!=null) return c;
+ return Color.BLACK;
+ }
+
+ protected ShapeNode node = null;
+
+ @SGInit
+ public void initSG(G2DParentNode parent) {
+ node = parent.addNode("zoom to area", ShapeNode.class);
+ node.setZIndex(PAINT_PRIORITY);
+ node.setStroke(STROKE);
+ node.setScaleStroke(true);
+ node.setColor(getToolColor());
+ node.setFill(false);
+ }
+
+ void update(Shape shape) {
+ if (node != null) {
+ node.setShape(shape);
+ }
+ }
+
+ @SGCleanup
+ public void cleanupSG() {
+ if (node != null) {
+ node.remove();
+ node = null;
+ }
+ }
+ }
+
+}