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