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}