]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - gis/plugins/org.argeo.gis.ui.rcp.swing/src/main/java/org/argeo/gis/ui/rcp/swing/VersatileZoomTool.java
2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org
.argeo
.gis
.ui
.rcp
.swing
;
19 import java
.awt
.Color
;
20 import java
.awt
.Cursor
;
21 import java
.awt
.Graphics2D
;
22 import java
.awt
.Point
;
23 import java
.awt
.Rectangle
;
24 import java
.awt
.event
.MouseEvent
;
25 import java
.awt
.event
.MouseWheelEvent
;
26 import java
.awt
.event
.MouseWheelListener
;
27 import java
.awt
.geom
.Point2D
;
29 import javax
.swing
.SwingUtilities
;
30 import javax
.swing
.event
.MouseInputAdapter
;
32 import org
.geotools
.geometry
.DirectPosition2D
;
33 import org
.geotools
.geometry
.Envelope2D
;
34 import org
.geotools
.geometry
.jts
.ReferencedEnvelope
;
35 import org
.geotools
.swing
.JMapPane
;
36 import org
.geotools
.swing
.event
.MapMouseEvent
;
37 import org
.geotools
.swing
.tool
.AbstractZoomTool
;
39 public class VersatileZoomTool
extends AbstractZoomTool
{
40 // private Log log = LogFactory.getLog(VersatileZoomTool.class);
42 // private static final ResourceBundle stringRes = ResourceBundle
43 // .getBundle("org/geotools/swing/Text");
46 private Cursor zoomInCursor
;
47 private Cursor panCursor
;
48 private Cursor defaultCursor
;
51 private Point2D startDragPos
;
52 private Point panePos
;
53 private boolean computingZoomBox
;
54 private boolean panning
;
56 private Point2D fieldPosition
;
61 public VersatileZoomTool() {
62 // Toolkit tk = Toolkit.getDefaultToolkit();
63 // zoomInCursor = tk.createCustomCursor(new ImageIcon(getClass()
64 // .getResource("/org/geotools/swing/icons/mActionZoomIn.png"))
65 // .getImage(), new Point(14, 9), stringRes
66 // .getString("tool_name_zoom_in"));
67 zoomInCursor
= new Cursor(Cursor
.SE_RESIZE_CURSOR
);
68 // panCursor = tk.createCustomCursor(new
69 // ImageIcon(getClass().getResource(
70 // "/org/geotools/swing/icons/mActionPan.png")).getImage(),
71 // new Point(15, 15), stringRes.getString("tool_name_pan"));
72 panCursor
= new Cursor(Cursor
.HAND_CURSOR
);
73 defaultCursor
= new Cursor(Cursor
.CROSSHAIR_CURSOR
);
75 startDragPos
= new DirectPosition2D();
76 computingZoomBox
= false;
82 * Zoom in by the currently set increment, with the map centred at the
83 * location (in world coords) of the mouse click
86 * map mapPane mouse event
89 public void onMouseClicked(MapMouseEvent e
) {
90 if (SwingUtilities
.isLeftMouseButton(e
))
91 centerMapToEvent(e
, getZoom());
92 else if (SwingUtilities
.isRightMouseButton(e
))
93 centerMapToEvent(e
, 1 / getZoom());
94 else if (SwingUtilities
.isMiddleMouseButton(e
)) {
95 if (fieldPosition
!= null) {
96 Envelope2D env
= new Envelope2D();
97 final double increment
= 0.1d
;
98 env
.setFrameFromDiagonal(fieldPosition
.getX() - increment
,
99 fieldPosition
.getY() - increment
, fieldPosition
.getX()
100 + increment
, fieldPosition
.getY() + increment
);
101 getMapPane().setDisplayArea(env
);
106 protected void centerMapToEvent(MapMouseEvent e
, Double zoomArg
) {
107 Rectangle paneArea
= getMapPane().getVisibleRect();
108 DirectPosition2D mapPos
= e
.getMapPosition();
110 double scale
= getMapPane().getWorldToScreenTransform().getScaleX();
111 double newScale
= scale
* zoomArg
;
113 DirectPosition2D corner
= new DirectPosition2D(mapPos
.getX() - 0.5d
114 * paneArea
.getWidth() / newScale
, mapPos
.getY() + 0.5d
115 * paneArea
.getHeight() / newScale
);
117 Envelope2D newMapArea
= new Envelope2D();
118 newMapArea
.setFrameFromCenter(mapPos
, corner
);
119 getMapPane().setDisplayArea(newMapArea
);
123 * Records the map position of the mouse event in case this button press is
124 * the beginning of a mouse drag
130 public void onMousePressed(MapMouseEvent ev
) {
131 if (SwingUtilities
.isLeftMouseButton(ev
)) {
132 startDragPos
= new DirectPosition2D();
133 startDragPos
.setLocation(ev
.getMapPosition());
134 } else if (SwingUtilities
.isMiddleMouseButton(ev
)
135 || SwingUtilities
.isRightMouseButton(ev
)) {
136 panePos
= ev
.getPoint();
142 * Records that the mouse is being dragged
148 public void onMouseDragged(MapMouseEvent ev
) {
149 if (SwingUtilities
.isLeftMouseButton(ev
)) {
150 computingZoomBox
= true;
151 } else if (panning
) {
152 Point pos
= ev
.getPoint();
153 if (!pos
.equals(panePos
)) {
154 getMapPane().moveImage(pos
.x
- panePos
.x
, pos
.y
- panePos
.y
);
158 getMapPane().setCursor(getCursor());
162 * If the mouse was dragged, determines the bounds of the box that the user
163 * defined and passes this to the mapPane's
164 * {@link org.geotools.swing.JMapPane#setDisplayArea(org.opengis.geometry.Envelope) }
171 public void onMouseReleased(MapMouseEvent ev
) {
172 if (computingZoomBox
&& !ev
.getPoint().equals(startDragPos
)) {
173 Envelope2D env
= new Envelope2D();
174 env
.setFrameFromDiagonal(startDragPos
, ev
.getMapPosition());
175 computingZoomBox
= false;
176 getMapPane().setDisplayArea(env
);
177 } else if (panning
) {
179 getMapPane().repaint();
181 getMapPane().setCursor(getCursor());
185 * Get the mouse cursor for this tool
188 public Cursor
getCursor() {
189 if (computingZoomBox
)
194 return defaultCursor
;
198 * We use a custom drag box
201 public boolean drawDragBox() {
206 public void setMapPane(JMapPane pane
) {
207 super.setMapPane(pane
);
208 VariableDragBox dragBox
= new VariableDragBox();
209 getMapPane().addMouseListener(dragBox
);
210 getMapPane().addMouseMotionListener(dragBox
);
211 getMapPane().addMouseWheelListener(new MouseWheelListener() {
212 private double clickToZoom
= 0.1; // 1 wheel click is 10% zoom
214 public void mouseWheelMoved(MouseWheelEvent ev
) {
215 int clicks
= ev
.getWheelRotation();
216 // -ve means wheel moved up, +ve means down
217 int sign
= (clicks
< 0 ?
-1 : 1);
219 ReferencedEnvelope env
= getMapPane().getDisplayArea();
222 double width
= env
.getWidth();
223 double delta
= width
* clickToZoom
* sign
;
226 getMapPane().setDisplayArea(env
);
227 getMapPane().repaint();
232 public void setFieldPosition(Point2D fieldPosition
) {
233 this.fieldPosition
= fieldPosition
;
237 * Custom drag box (hacked from JMapPane) so that we can change the behavior
238 * depending on whether we pan or zoom.
240 private class VariableDragBox
extends MouseInputAdapter
{
242 private Point startPos
;
243 private Rectangle rect
;
244 private boolean dragged
;
247 rect
= new Rectangle();
252 public void mousePressed(MouseEvent e
) {
253 startPos
= new Point(e
.getPoint());
257 public void mouseDragged(MouseEvent e
) {
258 if (computingZoomBox
) {
259 Graphics2D g2D
= (Graphics2D
) getMapPane().getGraphics();
260 g2D
.setColor(Color
.WHITE
);
261 g2D
.setXORMode(Color
.RED
);
263 g2D
.drawRect(rect
.x
, rect
.y
, rect
.width
, rect
.height
);
266 rect
.setFrameFromDiagonal(startPos
, e
.getPoint());
267 g2D
.drawRect(rect
.x
, rect
.y
, rect
.width
, rect
.height
);
274 public void mouseReleased(MouseEvent e
) {
276 Graphics2D g2D
= (Graphics2D
) getMapPane().getGraphics();
277 g2D
.setColor(Color
.WHITE
);
278 g2D
.setXORMode(Color
.RED
);
279 g2D
.drawRect(rect
.x
, rect
.y
, rect
.width
, rect
.height
);