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

Last change on this file since 6340 was 6340, checked in by Don-vip, 5 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.