]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/participant/ZoomToAreaHandler.java
Let the request processor handle the exceptions
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / participant / ZoomToAreaHandler.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.g2d.participant;
13
14 import java.awt.BasicStroke;
15 import java.awt.Color;
16 import java.awt.Cursor;
17 import java.awt.Shape;
18 import java.awt.geom.Path2D;
19 import java.awt.geom.Point2D;
20 import java.awt.geom.Rectangle2D;
21
22 import org.simantics.g2d.canvas.ICanvasContext;
23 import org.simantics.g2d.canvas.IMouseCursorContext;
24 import org.simantics.g2d.canvas.IMouseCursorHandle;
25 import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
26 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
27 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
28 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
29 import org.simantics.g2d.diagram.DiagramHints;
30 import org.simantics.g2d.diagram.handler.PickContext;
31 import org.simantics.g2d.diagram.participant.Selection;
32 import org.simantics.g2d.diagram.participant.pointertool.AbstractMode;
33 import org.simantics.g2d.participant.MouseUtil.MouseInfo;
34 import org.simantics.scenegraph.g2d.G2DParentNode;
35 import org.simantics.scenegraph.g2d.events.Event;
36 import org.simantics.scenegraph.g2d.events.MouseEvent;
37 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
38 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonEvent;
39 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;
40 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
41 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
42 import org.simantics.scenegraph.g2d.events.command.Commands;
43 import org.simantics.scenegraph.g2d.nodes.ShapeNode;
44 import org.simantics.utils.ObjectUtils;
45 import org.simantics.utils.page.MarginUtils;
46
47 /**
48  * ZoomToAreaHandler starts an area zoom mode when a ZOOM_TO_AREA command is
49  * issued.
50  *
51  * @author Tuukka Lehtonen
52  */
53 public class ZoomToAreaHandler extends AbstractCanvasParticipant {
54
55     public final static Cursor ZOOM_CURSOR = new Cursor(Cursor.CROSSHAIR_CURSOR);
56
57     @EventHandler(priority = 0)
58     public boolean handleZoomToArea(CommandEvent event) {
59         if (Commands.ZOOM_TO_AREA.equals( event.command )) {
60             if (!getContext().containsItemByClass(ZoomToAreaMode.class)) {
61                 getContext().add( new ZoomToAreaMode() );
62                 setDirty();
63             }
64             return true;
65         }
66         return false;
67     }
68
69     class ZoomToAreaMode extends AbstractMode {
70
71         @Dependency TransformUtil util;
72         @Dependency Selection selection;
73         @Dependency PickContext pickContext;
74         @Dependency KeyUtil keyUtil;
75         @Dependency MouseUtil mouseUtil;
76         @Dependency CanvasBoundsParticipant canvasBounds;
77
78         public final BasicStroke STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10f, new float[] {4,2}, 0);
79
80         public static final int PAINT_PRIORITY = 30;
81
82         Point2D startingPoint;
83         Point2D currentPoint;
84         IMouseCursorHandle cursor;
85
86         public ZoomToAreaMode() {
87             super(0);
88         }
89
90         @Override
91         public void addedToContext(ICanvasContext ctx) {
92             super.addedToContext(ctx);
93             IMouseCursorContext mctx = getContext().getMouseCursorContext();
94             if (mctx != null)
95                 cursor = mctx.setCursor(getMouseId(), ZOOM_CURSOR);
96             MouseInfo mi = mouseUtil.getMouseInfo(getMouseId());
97             if (mi != null)
98                 currentPoint = mi.canvasPosition;
99         }
100
101         @Override
102         public void removedFromContext(ICanvasContext ctx) {
103             if (cursor != null) {
104                 cursor.remove();
105                 cursor = null;
106             }
107             super.removedFromContext(ctx);
108         }
109
110         @EventHandler(priority = 10)
111         public boolean handleEvent(Event e) {
112             if (e instanceof CommandEvent) {
113                 CommandEvent ce = (CommandEvent) e;
114                 if (ce.command.equals( Commands.CANCEL )){
115                     setDirty();
116                     remove();
117                     return true;
118                 }
119             } else if (e instanceof MouseMovedEvent) {
120                 MouseMovedEvent event = (MouseMovedEvent) e;
121                 if (event.mouseId != getMouseId()) return false;
122                 Point2D canvasPos = util.controlToCanvas(event.controlPosition, null);
123                 if (!ObjectUtils.objectEquals(currentPoint, canvasPos))
124                 {
125                     currentPoint = canvasPos;
126                     update(getBox());
127                     setDirty();
128                 }
129                 return false;
130             } else if (e instanceof MouseButtonEvent) {
131                 MouseButtonEvent event = (MouseButtonEvent) e;
132
133                 if (event.mouseId != getMouseId()) return false;
134                 if (event.button != MouseEvent.LEFT_BUTTON) return false;
135
136                 // Eat all other mouse button events besides press and click.
137                 // Must use mouse clicks here because otherwise selection
138                 // participants etc. might alter selections on the next incoming
139                 // mouse click event, which only confuses the user.
140                 if (e instanceof MouseClickEvent) {
141                     Point2D canvasPos = util.controlToCanvas(event.controlPosition, null);
142                     currentPoint = canvasPos;
143
144                     if (startingPoint == null) {
145                         // Start marking the box
146                         startingPoint = currentPoint;
147                         setDirty();
148                         return true;
149                     }
150
151                     Rectangle2D area = new Rectangle2D.Double();
152                     area.setFrameFromDiagonal(startingPoint, currentPoint);
153
154                     Rectangle2D controlArea = canvasBounds.getControlBounds();
155                     util.fitArea(controlArea, area, PanZoomRotateHandler.getZoomToFitMargins(getHintStack()));
156
157                     setDirty();
158                     remove();
159                     return true;
160                 }
161                 return true;
162             }
163             return false;
164         }
165
166         /**
167          * Get selection box in control coordinates
168          * @return control coordinates
169          */
170         protected Rectangle2D getBox() {
171             if (startingPoint == null)
172                 return null;
173             Point2D p1 = startingPoint;
174             Point2D p2 = currentPoint;
175             double ax = p1.getX();
176             double ay = p1.getY();
177             double bx = p2.getX();
178             double by = p2.getY();
179             if (bx < ax) {
180                 double temp = ax;
181                 ax = bx;
182                 bx = temp;
183             }
184             if (by < ay) {
185                 double temp = ay;
186                 ay = by;
187                 by = temp;
188             }
189             return new Rectangle2D.Double(ax, ay, bx - ax, by - ay);
190         }
191
192         protected Path2D getCrossHair(Rectangle2D controlBounds) {
193             Point2D controlPos = util.canvasToControl(currentPoint, null);
194             Path2D path = new Path2D.Double();
195             path.moveTo(controlBounds.getMinX(), controlPos.getY());
196             path.lineTo(controlBounds.getMaxX(), controlPos.getY());
197             path.moveTo(controlPos.getX(), controlBounds.getMinY());
198             path.lineTo(controlPos.getX(), controlBounds.getMaxY());
199             return path;
200         }
201
202         public synchronized Color getToolColor()
203         {
204             Color c = getHint(DiagramHints.KEY_SELECTION_FRAME_COLOR);
205             if (c!=null) return c;
206             return Color.BLACK;
207         }
208
209         protected ShapeNode node = null;
210
211         @SGInit
212         public void initSG(G2DParentNode parent) {
213             node = parent.addNode("zoom to area", ShapeNode.class);
214             node.setZIndex(PAINT_PRIORITY);
215             node.setStroke(STROKE);
216             node.setScaleStroke(true);
217             node.setColor(getToolColor());
218             node.setFill(false);
219         }
220
221         void update(Shape shape) {
222             if (node != null) {
223                 node.setShape(shape);
224             }
225         }
226
227         @SGCleanup
228         public void cleanupSG() {
229             if (node != null) {
230                 node.remove();
231                 node = null;
232             }
233         }
234     }
235
236 }