001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.tools.internal;
018:
019: import java.awt.Color;
020: import java.awt.Point;
021: import java.awt.Rectangle;
022:
023: import net.refractions.udig.project.command.NavCommand;
024: import net.refractions.udig.project.command.factory.NavigationCommandFactory;
025: import net.refractions.udig.project.render.IViewportModel;
026: import net.refractions.udig.project.ui.commands.DrawCommandFactory;
027: import net.refractions.udig.project.ui.internal.commands.draw.DrawShapeCommand;
028: import net.refractions.udig.project.ui.render.displayAdapter.MapMouseEvent;
029: import net.refractions.udig.project.ui.tool.AbstractModalTool;
030: import net.refractions.udig.project.ui.tool.ModalTool;
031: import net.refractions.udig.ui.graphics.ViewportGraphics;
032:
033: /**
034: * This class Provides zoom box and click functionality.
035: *
036: * @author Jesse Eichar
037: * @version $Revision: 1.9 $
038: */
039: public class Zoom extends AbstractModalTool implements ModalTool {
040: /** <code>ZOOMFACTOR</code> field */
041: public static final double ZOOMFACTOR = 2;
042: private boolean zooming;
043: private Point start;
044: NavigationCommandFactory factory = NavigationCommandFactory
045: .getInstance();
046: DrawCommandFactory dfactory = DrawCommandFactory.getInstance();
047: DrawShapeCommand shapeCommand = dfactory.createDrawShapeCommand(
048: new Rectangle(0, 0, 0, 0), Color.ORANGE,
049: ViewportGraphics.LINE_DASH, 1);
050:
051: /**
052: * Creates an new instance of Zoom
053: */
054: public Zoom() {
055: super (MOUSE | MOTION);
056: shapeCommand.setFill(new Color(Color.ORANGE.getRed(),
057: Color.ORANGE.getGreen(), Color.ORANGE.getBlue(), 50));
058: }
059:
060: public void mouseDragged(MapMouseEvent e) {
061: if (start == null) {
062: mousePressed(e);
063: return;
064: }
065: shapeCommand.setShape(new Rectangle(Math.min(start.x, e.x),
066: Math.min(start.y, e.y), Math.abs(e.x - start.x), Math
067: .abs(start.y - e.y)));
068: context.getViewportPane().repaint();
069: }
070:
071: Rectangle calculateOriginRectImproved(MapMouseEvent e) {
072: if (start == null)
073: mousePressed(e);
074: int x1 = start.x;
075: int x2 = e.x;
076: int y1 = start.y;
077: int y2 = e.y;
078: int width1, height1;
079: int width2, height2;
080: int width, height;
081: height1 = Math.abs(y2 - y1);
082: width1 = (int) (height1 * context.getViewportModel()
083: .getAspectRatio());
084: width2 = Math.abs(x2 - x1);
085: height2 = (int) (width2 / context.getViewportModel()
086: .getAspectRatio());
087: // choose heights and widths based on which axis is the longest
088: if (height1 > height2) {
089: width = width1;
090: height = height1;
091: } else {
092: width = width2;
093: height = height2;
094: }
095:
096: //center user selected area in center of new box.
097: int x = x1, y = y1;
098: if (x1 > x2) {
099: x = x1 - width + (width - Math.abs(x2 - x1)) / 2;
100: } else {
101: x = x - (width - Math.abs(x2 - x1)) / 2;
102: }
103: if (y1 > y2) {
104: y = y1 - height + (height - Math.abs(y2 - y1)) / 2;
105: } else {
106: y = y - (height - Math.abs(y2 - y1)) / 2;
107: }
108:
109: return new Rectangle(x, y, width, height);
110: }
111:
112: /**
113: * @see net.refractions.udig.project.tool.AbstractTool#mousePressed(net.refractions.udig.project.render.displayAdapter.MapMouseEvent)
114: */
115: public void mousePressed(MapMouseEvent e) {
116: if (!e.isAltDown()
117: && !e.isShiftDown()
118: && (e.button == MapMouseEvent.BUTTON1
119: || e.button == MapMouseEvent.BUTTON3 || (e.button == MapMouseEvent.BUTTON1 && e
120: .isControlDown()))) {
121: zooming = true;
122: start = e.getPoint();
123: shapeCommand.setValid(true);
124: shapeCommand
125: .setShape(new Rectangle(start.x, start.y, 0, 0));
126: getContext().sendASyncCommand(shapeCommand);
127:
128: }
129: }
130:
131: /**
132: * @see net.refractions.udig.project.tool.AbstractTool#mouseReleased(net.refractions.udig.project.render.displayAdapter.MapMouseEvent)
133: */
134: public void mouseReleased(MapMouseEvent e) {
135: if (zooming) {
136: IViewportModel m = getContext().getViewportModel();
137: if ((Math.abs(start.x - e.x) < 5)
138: && (Math.abs(start.y - e.y) < 5)) {
139: switch (e.button) {
140: case MapMouseEvent.BUTTON1: {
141: NavCommand[] commands = new NavCommand[] {
142: factory.createSetViewportCenterCommand(m
143: .pixelToWorld(start.x, start.y)),
144: factory.createZoomCommand(ZOOMFACTOR) };
145: getContext().sendASyncCommand(
146: factory.createCompositeCommand(commands));
147: break;
148: }
149: case MapMouseEvent.BUTTON3: {
150: NavCommand[] commands = new NavCommand[] {
151: factory.createSetViewportCenterCommand(m
152: .pixelToWorld(start.x, start.y)),
153: factory.createZoomCommand(1 / ZOOMFACTOR) };
154: getContext().sendASyncCommand(
155: factory.createCompositeCommand(commands));
156: break;
157: }
158: } //switch
159: shapeCommand.setValid(false);
160: return;
161: }
162: Rectangle r = calculateOriginRectImproved(e);
163: switch (e.button) {
164: case MapMouseEvent.BUTTON1: {
165: if (e.isControlDown()) {
166: zoomout(m, r);
167: } else {
168: zoomin(m, r);
169: }
170: break;
171: }
172: case MapMouseEvent.BUTTON3: {
173: zoomout(m, r);
174: break;
175: }
176: default:
177: break;
178: }
179: zooming = false;
180: shapeCommand.setValid(false);
181: }
182: }
183:
184: /**
185: *
186: * @param m
187: * @param r
188: */
189: private void zoomin(IViewportModel m, Rectangle r) {
190: NavCommand[] commands = new NavCommand[] {
191: factory.createSetViewportCenterCommand(m.pixelToWorld(
192: r.x + r.width / 2, r.y + r.height / 2)),
193: factory.createZoomCommand(getContext().getMapDisplay()
194: .getDisplaySize().getWidth()
195: / r.width) };
196: getContext().sendASyncCommand(
197: factory.createCompositeCommand(commands));
198: }
199:
200: /**
201: *
202: * @param m
203: * @param r
204: */
205: private void zoomout(IViewportModel m, Rectangle r) {
206: NavCommand[] commands = new NavCommand[] {
207: factory.createSetViewportCenterCommand(m.pixelToWorld(
208: r.x + r.width / 2, r.y + r.height / 2)),
209: factory.createZoomCommand(r.width
210: / getContext().getMapDisplay().getDisplaySize()
211: .getWidth()) };
212: getContext().sendASyncCommand(
213: factory.createCompositeCommand(commands));
214: }
215:
216: /**
217: * @see net.refractions.udig.project.tool.Tool#dispose()
218: */
219: public void dispose() {
220: super.dispose();
221: }
222: }
|