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.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(MainApplication.isDisplayingMapView()
069                    && (MainApplication.getLayerManager().getActiveData() != null || mapHasGpxorMarkerLayer()));
070        }
071
072        private static boolean mapHasGpxorMarkerLayer() {
073            for (Layer layer : MainApplication.getLayerManager().getLayers()) {
074                if (layer instanceof GpxLayer || layer instanceof MarkerLayer) {
075                    return true;
076                }
077            }
078            return false;
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.addMapPaintSylesUpdateListener(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}