001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.mappaint;
003
004import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005import static org.openstreetmap.josm.tools.I18n.tr;
006
007import java.awt.event.ActionEvent;
008import java.util.HashMap;
009import java.util.Map;
010
011import javax.swing.JCheckBoxMenuItem;
012import javax.swing.JMenu;
013
014import org.openstreetmap.josm.actions.JosmAction;
015import org.openstreetmap.josm.gui.MainApplication;
016import org.openstreetmap.josm.gui.dialogs.MapPaintDialog;
017import org.openstreetmap.josm.gui.layer.GpxLayer;
018import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
019import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.MapPaintStylesUpdateListener;
020import org.openstreetmap.josm.gui.util.StayOpenCheckBoxMenuItem;
021import org.openstreetmap.josm.tools.ImageProvider;
022
023/**
024 * The View -> Map Paint Styles menu
025 * @since 5086
026 */
027public class MapPaintMenu extends JMenu implements MapPaintStylesUpdateListener {
028
029    private static class MapPaintAction extends JosmAction {
030
031        private transient StyleSource style;
032        private final JCheckBoxMenuItem button;
033
034        MapPaintAction(StyleSource style) {
035            super(style.getDisplayString(), style.getIconProvider(),
036                    tr("Select the map painting styles"), null, true, "mappaint/" + style.getDisplayString(), true);
037            this.button = new StayOpenCheckBoxMenuItem(this);
038            this.style = style;
039            updateButton();
040            putValue("help", ht("/Dialog/MapPaint"));
041        }
042
043        private void updateButton() {
044            button.getModel().setSelected(style.active);
045        }
046
047        private void toggleStyle() {
048            MapPaintStyles.toggleStyleActive(MapPaintStyles.getStyles().getStyleSources().indexOf(style));
049            updateButton();
050        }
051
052        @Override
053        public void actionPerformed(ActionEvent ae) {
054            toggleStyle();
055        }
056
057        public JCheckBoxMenuItem getButton() {
058            return button;
059        }
060
061        public void setStyle(StyleSource style) {
062            this.style = style;
063        }
064
065        @Override
066        protected boolean listenToSelectionChange() {
067            return false;
068        }
069
070        @Override
071        public void updateEnabledState() {
072            setEnabled(MainApplication.isDisplayingMapView()
073                    && (MainApplication.getLayerManager().getActiveData() != null || mapHasGpxOrMarkerLayer()));
074        }
075
076        private static boolean mapHasGpxOrMarkerLayer() {
077            return MainApplication.getLayerManager().getLayers().stream()
078                    .anyMatch(layer -> layer instanceof GpxLayer || layer instanceof MarkerLayer);
079        }
080    }
081
082    private final transient Map<String, MapPaintAction> actions = new HashMap<>();
083
084    /**
085     * Constructs a new {@code MapPaintMenu}
086     */
087    public MapPaintMenu() {
088        super(tr("Map Paint Styles"));
089        setIcon(ImageProvider.get("dialogs", "mapstyle", ImageProvider.ImageSizes.MENU));
090        MapPaintStyles.addMapPaintStylesUpdateListener(this);
091        putClientProperty("help", ht("/Dialog/MapPaint"));
092    }
093
094    @Override
095    public void mapPaintStylesUpdated() {
096        removeAll();
097        for (StyleSource style : MapPaintStyles.getStyles().getStyleSources()) {
098            final String k = style.getDisplayString();
099            MapPaintAction a = actions.get(k);
100            if (a == null) {
101                a = new MapPaintAction(style);
102                actions.put(k, a);
103                add(a.getButton());
104            } else {
105                a.setStyle(style);
106                add(a.getButton());
107                a.updateButton();
108            }
109        }
110        addSeparator();
111        add(MapPaintDialog.PREFERENCE_ACTION);
112    }
113
114    @Override
115    public void mapPaintStyleEntryUpdated(int idx) {
116        mapPaintStylesUpdated();
117    }
118}