source: subversion/applications/editors/josm/plugins/photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/PhotoAdjustMapMode.java

Last change on this file was 33757, checked in by holgermappt, 18 months ago

Code modified to fix linter issues.

File size: 8.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.plugins.photoadjust;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Cursor;
7import java.awt.event.KeyEvent;
8import java.awt.event.MouseAdapter;
9import java.awt.event.MouseEvent;
10import java.awt.event.MouseMotionAdapter;
11import java.util.ArrayList;
12import java.util.Iterator;
13import java.util.List;
14
15import org.openstreetmap.josm.actions.mapmode.MapMode;
16import org.openstreetmap.josm.gui.IconToggleButton;
17import org.openstreetmap.josm.gui.MainApplication;
18import org.openstreetmap.josm.gui.MapFrame;
19import org.openstreetmap.josm.gui.layer.Layer;
20import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
21import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
22import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
23import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
24import org.openstreetmap.josm.gui.layer.MainLayerManager;
25import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
26import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
27import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
28import org.openstreetmap.josm.tools.Shortcut;
29
30/**
31 * Map mode version of the plug-in.  The associated button is shown
32 * only if there is at least one GeoImageLayer.  Otherwise the button
33 * is hidden to make room for other buttons.  This map mode is
34 * inactive if the active layer is a GeoImageLayer as the main plug-in
35 * handles it.
36 */
37public class PhotoAdjustMapMode extends MapMode implements LayerChangeListener, ActiveLayerChangeListener {
38
39    /** True if this map mode waits for mouse events. */
40    private boolean modeActive = false;
41    /** True if the map mode button is selected and active. */
42    private boolean modeSelected = false;
43    private MouseAdapter mouseAdapter;
44    private MouseMotionAdapter mouseMotionAdapter;
45    private IconToggleButton mmButton;
46    private final PhotoAdjustWorker worker;
47    /** True if one existing GeoImageLayer is to be ignored. */
48    private boolean ignoreOneGILayer = false;
49
50    /**
51     * Initialize photo adjust map mode.
52     *
53     * @param worker Worker that does the actual work.
54     */
55    public PhotoAdjustMapMode(PhotoAdjustWorker worker) {
56        super(tr("Adjust photos"), "photoadjust.png",
57              tr("Move and position photos"),
58              // It is almost impossible to find an unused shortcut.
59              Shortcut.registerShortcut("mapmode:photoadjust",
60                                        tr("Mode: {0}", tr("Adjust photos")),
61                                        KeyEvent.CHAR_UNDEFINED, Shortcut.NONE),
62              Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
63        GeoImageLayer.registerSupportedMapMode(this);
64        initAdapters();
65        this.worker = worker;
66        MainApplication.getLayerManager().addLayerChangeListener(this);
67        MainApplication.getLayerManager().addActiveLayerChangeListener(this);
68    }
69
70    /**
71     * The main plugin does nothing but to call this method, which
72     * connects this map mode with a button that is registered as map
73     * mode.
74     *
75     * @param mapFrame Map frame the map mode button is added to.
76     */
77    public void installMapMode(MapFrame mapFrame) {
78        mmButton = new IconToggleButton(this);
79        mmButton.setAutoHideDisabledButton(true);
80        mapFrame.addMapMode(mmButton);
81    }
82
83    @Override
84    public String getModeHelpText() {
85        if (hasLayersToAdjust()) {
86            return tr("Click+drag photo, shift+click to position photo, control+click to set direction.");
87        } else {
88            return tr("Please load some photos.");
89        }
90    }
91
92    @Override
93    public boolean layerIsSupported(Layer layer) {
94        return hasLayersToAdjust();
95    }
96
97    @Override
98    protected void updateEnabledState() {
99        setEnabled(hasLayersToAdjust());
100    }
101
102    /**
103     * Update the button state.  We do this more frequently than the
104     * JOSM core would do it.
105     */
106    public void updateButtonState() {
107        if (mmButton != null) {
108            final boolean enabled = hasLayersToAdjust();
109            setEnabled(enabled);
110            if (enabled) {
111                mmButton.showButton();
112            } else {
113                mmButton.hideButton();
114            }
115        }
116    }
117
118    /**
119     * Activate the map mode, i.e. wait for mouse events.
120     */
121    private void activateMode() {
122        if (modeSelected && !modeActive) {
123            MainApplication.getMap().mapView.addMouseListener(mouseAdapter);
124            MainApplication.getMap().mapView.addMouseMotionListener(mouseMotionAdapter);
125            modeActive = true;
126            updateStatusLine();
127        }
128    }
129
130    /**
131     * Deactivate map mode.
132     */
133    private void deactivateMode() {
134        if (modeActive) {
135            MainApplication.getMap().mapView.removeMouseListener(mouseAdapter);
136            MainApplication.getMap().mapView.removeMouseMotionListener(mouseMotionAdapter);
137            modeActive = false;
138        }
139    }
140
141    @Override
142    public void enterMode() {
143        super.enterMode();
144        modeSelected = true;
145        // Activate the mode only if the current layer is not a GeoImageLayer.
146        // GeoImageLayer's are handled by the plug-in directly.
147        if (!(MainApplication.getLayerManager().getActiveLayer() instanceof GeoImageLayer)) {
148            activateMode();
149        }
150    }
151
152    @Override
153    public void exitMode() {
154        super.exitMode();
155        deactivateMode();
156        modeSelected = false;
157    }
158
159    @Override
160    public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
161        // The main part of the plugin takes care of all operations if a GeoImageLayer is active.
162        if (MainApplication.getLayerManager().getActiveLayer() instanceof GeoImageLayer) {
163            deactivateMode();
164        } else {
165            activateMode();
166        }
167    }
168
169    @Override
170    public void layerAdded(LayerAddEvent e) {
171        if (modeActive) updateStatusLine();
172        updateButtonState();
173    }
174
175    @Override
176    public void layerRemoving(LayerRemoveEvent lre) {
177        if (lre.getRemovedLayer() instanceof GeoImageLayer) {
178            // A GeoImageLayer is about to be removed.  We ignore this layer
179            // in the following update methods to get the correct number of
180            // future GeoImageLayers.
181            ignoreOneGILayer = true;
182        }
183        if (modeActive) updateStatusLine();
184        updateButtonState();
185        ignoreOneGILayer = false;
186    }
187
188    @Override
189    public void layerOrderChanged(LayerOrderChangeEvent e) {
190        // Nothing to do at layer order change.
191    }
192
193    /**
194     * Create mouse adapters similar to the main plug-in.
195     */
196    private void initAdapters() {
197        // The MapMode implements a MouseAdapter and a
198        // MouseMotionAdapter, but we cannot use them because they get
199        // activated with the first layer that is created.  This is
200        // not what we want, we want to activate them if this map mode
201        // gets activated.
202        mouseAdapter = new MouseAdapter() {
203            @Override
204            public void mousePressed(MouseEvent evt) {
205                worker.doMousePressed(evt, getVisibleGeoImageLayers());
206            }
207
208            @Override
209            public void mouseReleased(MouseEvent evt) {
210                worker.doMouseReleased(evt);
211            }
212        };
213
214        mouseMotionAdapter = new MouseMotionAdapter() {
215            @Override
216            public void mouseDragged(MouseEvent evt) {
217                worker.doMouseDragged(evt);
218            }
219        };
220    }
221
222    /**
223     * Replies true if there is at least one geo image layer.
224     *
225     * @return {@code true} if there is at least one geo image layer
226     */
227    private boolean hasLayersToAdjust() {
228        final MainLayerManager layerManager = MainApplication.getLayerManager();
229        if (layerManager == null) return false;
230        int giLayerNum = layerManager.getLayersOfType(GeoImageLayer.class).size();
231        if (ignoreOneGILayer) {
232            giLayerNum--;
233        }
234        return giLayerNum > 0;
235    }
236
237    /**
238     * Prepare list of visible GeoImageLayer's whose photos can be adjusted.
239     *
240     * @return list of visible GeoImageLayer's
241     */
242    private static List<GeoImageLayer> getVisibleGeoImageLayers() {
243        List<GeoImageLayer> all = new ArrayList<>(MainApplication.getLayerManager().getLayersOfType(GeoImageLayer.class));
244        Iterator<GeoImageLayer> it = all.iterator();
245        while (it.hasNext()) {
246            if (!it.next().isVisible()) it.remove();
247        }
248        return all;
249    }
250
251 
252    @Override 
253    public void destroy() { 
254        super.destroy(); 
255        MainApplication.getLayerManager().removeActiveLayerChangeListener(this);
256        MainApplication.getLayerManager().removeLayerChangeListener(this);
257    } 
258
259}
Note: See TracBrowser for help on using the repository browser.