source: josm/trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java@ 6546

Last change on this file since 6546 was 6340, checked in by Don-vip, 10 years ago

refactor of some GUI/widgets classes (impacts some plugins):

  • gui.BookmarkList moves to gui.download as it is only meant to be used by gui.download.BookmarkSelection
  • tools.UrlLabel moves to gui.widgets
  • gui.JMultilineLabel, gui.MultiplitLayout, gui.MultiSplitPane move to gui.widgets
  • Property svn:eol-style set to native
File size: 10.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.AWTEvent;
7import java.awt.Cursor;
8import java.awt.GridBagLayout;
9import java.awt.Insets;
10import java.awt.Toolkit;
11import java.awt.event.AWTEventListener;
12import java.awt.event.ActionEvent;
13import java.awt.event.FocusEvent;
14import java.awt.event.FocusListener;
15import java.awt.event.KeyEvent;
16import java.awt.event.MouseEvent;
17import java.awt.event.MouseListener;
18import java.awt.event.MouseMotionListener;
19
20import javax.swing.JLabel;
21import javax.swing.JPanel;
22
23import org.openstreetmap.josm.Main;
24import org.openstreetmap.josm.actions.mapmode.MapMode;
25import org.openstreetmap.josm.data.coor.EastNorth;
26import org.openstreetmap.josm.data.imagery.OffsetBookmark;
27import org.openstreetmap.josm.gui.ExtendedDialog;
28import org.openstreetmap.josm.gui.layer.ImageryLayer;
29import org.openstreetmap.josm.tools.GBC;
30import org.openstreetmap.josm.tools.ImageProvider;
31import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
32import org.openstreetmap.josm.gui.widgets.JosmTextField;
33
34public class ImageryAdjustAction extends MapMode implements MouseListener, MouseMotionListener, AWTEventListener{
35 static ImageryOffsetDialog offsetDialog;
36 static Cursor cursor = ImageProvider.getCursor("normal", "move");
37
38 double oldDx, oldDy;
39 boolean mouseDown;
40 EastNorth prevEastNorth;
41 private ImageryLayer layer;
42 private MapMode oldMapMode;
43
44 public ImageryAdjustAction(ImageryLayer layer) {
45 super(tr("New offset"), "adjustimg",
46 tr("Adjust the position of this imagery layer"), Main.map,
47 cursor);
48 putValue("toolbar", false);
49 this.layer = layer;
50 }
51
52 @Override public void enterMode() {
53 super.enterMode();
54 if (layer == null)
55 return;
56 if (!layer.isVisible()) {
57 layer.setVisible(true);
58 }
59 oldDx = layer.getDx();
60 oldDy = layer.getDy();
61 addListeners();
62 offsetDialog = new ImageryOffsetDialog();
63 offsetDialog.setVisible(true);
64 }
65
66 protected void addListeners() {
67 Main.map.mapView.addMouseListener(this);
68 Main.map.mapView.addMouseMotionListener(this);
69 try {
70 Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
71 } catch (SecurityException ex) {
72 }
73 }
74
75 @Override public void exitMode() {
76 super.exitMode();
77 if (offsetDialog != null) {
78 layer.setOffset(oldDx, oldDy);
79 offsetDialog.setVisible(false);
80 offsetDialog = null;
81 }
82 removeListeners();
83 }
84
85 protected void removeListeners() {
86 try {
87 Toolkit.getDefaultToolkit().removeAWTEventListener(this);
88 } catch (SecurityException ex) {
89 }
90 if (Main.isDisplayingMapView()) {
91 Main.map.mapView.removeMouseMotionListener(this);
92 Main.map.mapView.removeMouseListener(this);
93 }
94 }
95
96 @Override
97 public void eventDispatched(AWTEvent event) {
98 if (!(event instanceof KeyEvent)) return;
99 if (event.getID() != KeyEvent.KEY_PRESSED) return;
100 if (layer == null) return;
101 if (offsetDialog != null && offsetDialog.areFieldsInFocus()) return;
102 KeyEvent kev = (KeyEvent)event;
103 double dx = 0, dy = 0;
104 switch (kev.getKeyCode()) {
105 case KeyEvent.VK_UP : dy = +1; break;
106 case KeyEvent.VK_DOWN : dy = -1; break;
107 case KeyEvent.VK_LEFT : dx = -1; break;
108 case KeyEvent.VK_RIGHT : dx = +1; break;
109 }
110 if (dx != 0 || dy != 0) {
111 double ppd = layer.getPPD();
112 layer.displace(dx / ppd, dy / ppd);
113 if (offsetDialog != null) {
114 offsetDialog.updateOffset();
115 }
116 kev.consume();
117 Main.map.repaint();
118 }
119 }
120
121 @Override public void mousePressed(MouseEvent e) {
122 if (e.getButton() != MouseEvent.BUTTON1)
123 return;
124
125 if (layer.isVisible()) {
126 requestFocusInMapView();
127 prevEastNorth=Main.map.mapView.getEastNorth(e.getX(),e.getY());
128 Main.map.mapView.setNewCursor(Cursor.MOVE_CURSOR, this);
129 }
130 }
131
132 @Override public void mouseDragged(MouseEvent e) {
133 if (layer == null || prevEastNorth == null) return;
134 EastNorth eastNorth =
135 Main.map.mapView.getEastNorth(e.getX(),e.getY());
136 double dx = layer.getDx()+eastNorth.east()-prevEastNorth.east();
137 double dy = layer.getDy()+eastNorth.north()-prevEastNorth.north();
138 layer.setOffset(dx, dy);
139 if (offsetDialog != null) {
140 offsetDialog.updateOffset();
141 }
142 Main.map.repaint();
143 prevEastNorth = eastNorth;
144 }
145
146 @Override public void mouseReleased(MouseEvent e) {
147 Main.map.mapView.repaint();
148 Main.map.mapView.resetCursor(this);
149 prevEastNorth = null;
150 }
151
152 @Override
153 public void actionPerformed(ActionEvent e) {
154 if (offsetDialog != null || layer == null || Main.map == null)
155 return;
156 oldMapMode = Main.map.mapMode;
157 super.actionPerformed(e);
158 }
159
160 class ImageryOffsetDialog extends ExtendedDialog implements FocusListener {
161 public final JosmTextField tOffset = new JosmTextField();
162 JosmTextField tBookmarkName = new JosmTextField();
163 private boolean ignoreListener;
164 public ImageryOffsetDialog() {
165 super(Main.parent,
166 tr("Adjust imagery offset"),
167 new String[] { tr("OK"),tr("Cancel") },
168 false);
169 setButtonIcons(new String[] { "ok", "cancel" });
170 contentInsets = new Insets(10, 15, 5, 15);
171 JPanel pnl = new JPanel(new GridBagLayout());
172 pnl.add(new JMultilineLabel(tr("Use arrow keys or drag the imagery layer with mouse to adjust the imagery offset.\n" +
173 "You can also enter east and north offset in the {0} coordinates.\n" +
174 "If you want to save the offset as bookmark, enter the bookmark name below",Main.getProjection().toString())), GBC.eop());
175 pnl.add(new JLabel(tr("Offset: ")),GBC.std());
176 pnl.add(tOffset,GBC.eol().fill(GBC.HORIZONTAL).insets(0,0,0,5));
177 pnl.add(new JLabel(tr("Bookmark name: ")),GBC.std());
178 pnl.add(tBookmarkName,GBC.eol().fill(GBC.HORIZONTAL));
179 tOffset.setColumns(16);
180 updateOffsetIntl();
181 tOffset.addFocusListener(this);
182 setContent(pnl);
183 setupDialog();
184 }
185
186 public boolean areFieldsInFocus() {
187 return tOffset.hasFocus();
188 }
189
190 @Override
191 public void focusGained(FocusEvent e) {
192 }
193
194 @Override
195 public void focusLost(FocusEvent e) {
196 if (ignoreListener) return;
197 String ostr = tOffset.getText();
198 int semicolon = ostr.indexOf(';');
199 if( semicolon >= 0 && semicolon + 1 < ostr.length() ) {
200 try {
201 // here we assume that Double.parseDouble() needs '.' as a decimal separator
202 String easting = ostr.substring(0, semicolon).trim().replace(',', '.');
203 String northing = ostr.substring(semicolon + 1).trim().replace(',', '.');
204 double dx = Double.parseDouble(easting);
205 double dy = Double.parseDouble(northing);
206 layer.setOffset(dx, dy);
207 } catch (NumberFormatException nfe) {
208 // we repaint offset numbers in any case
209 }
210 }
211 updateOffsetIntl();
212 if (Main.isDisplayingMapView()) {
213 Main.map.repaint();
214 }
215 }
216
217 public void updateOffset() {
218 ignoreListener = true;
219 updateOffsetIntl();
220 ignoreListener = false;
221 }
222
223 public void updateOffsetIntl() {
224 // Support projections with very small numbers (e.g. 4326)
225 int precision = Main.getProjection().getDefaultZoomInPPD() >= 1.0 ? 2 : 7;
226 // US locale to force decimal separator to be '.'
227 tOffset.setText(new java.util.Formatter(java.util.Locale.US).format(
228 "%1." + precision + "f; %1." + precision + "f",
229 layer.getDx(), layer.getDy()).toString());
230 }
231
232 private boolean confirmOverwriteBookmark() {
233 ExtendedDialog dialog = new ExtendedDialog(
234 Main.parent,
235 tr("Overwrite"),
236 new String[] {tr("Overwrite"), tr("Cancel")}
237 ) {{
238 contentInsets = new Insets(10, 15, 10, 15);
239 }};
240 dialog.setContent(tr("Offset bookmark already exists. Overwrite?"));
241 dialog.setButtonIcons(new String[] {"ok.png", "cancel.png"});
242 dialog.setupDialog();
243 dialog.setVisible(true);
244 return dialog.getValue() == 1;
245 }
246
247 @Override
248 protected void buttonAction(int buttonIndex, ActionEvent evt) {
249 if (buttonIndex == 0 && tBookmarkName.getText() != null && !tBookmarkName.getText().isEmpty() &&
250 OffsetBookmark.getBookmarkByName(layer, tBookmarkName.getText()) != null) {
251 if (!confirmOverwriteBookmark()) return;
252 }
253 super.buttonAction(buttonIndex, evt);
254 }
255
256 @Override
257 public void setVisible(boolean visible) {
258 super.setVisible(visible);
259 if (visible) return;
260 offsetDialog = null;
261 if (getValue() != 1) {
262 layer.setOffset(oldDx, oldDy);
263 } else if (tBookmarkName.getText() != null && !tBookmarkName.getText().isEmpty()) {
264 OffsetBookmark.bookmarkOffset(tBookmarkName.getText(), layer);
265 }
266 Main.main.menu.imageryMenu.refreshOffsetMenu();
267 if (Main.map == null) return;
268 if (oldMapMode != null) {
269 Main.map.selectMapMode(oldMapMode);
270 oldMapMode = null;
271 } else {
272 Main.map.selectSelectTool(false);
273 }
274 }
275 }
276
277 @Override
278 public void destroy() {
279 super.destroy();
280 removeListeners();
281 this.layer = null;
282 this.oldMapMode = null;
283 }
284}
Note: See TracBrowser for help on using the repository browser.