001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.preferences.display; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.GridBagLayout; 007 008import javax.swing.BorderFactory; 009import javax.swing.Box; 010import javax.swing.JCheckBox; 011import javax.swing.JLabel; 012import javax.swing.JPanel; 013 014import org.openstreetmap.josm.actions.ExpertToggleAction; 015import org.openstreetmap.josm.data.preferences.BooleanProperty; 016import org.openstreetmap.josm.gui.autofilter.AutoFilterManager; 017import org.openstreetmap.josm.gui.autofilter.AutoFilterRule; 018import org.openstreetmap.josm.gui.help.HelpUtil; 019import org.openstreetmap.josm.gui.layer.OsmDataLayer; 020import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting; 021import org.openstreetmap.josm.gui.preferences.PreferenceSetting; 022import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory; 023import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane; 024import org.openstreetmap.josm.gui.widgets.JosmComboBox; 025import org.openstreetmap.josm.spi.preferences.Config; 026import org.openstreetmap.josm.tools.GBC; 027 028/** 029 * "OSM Data" drawing preferences. 030 */ 031public class DrawingPreference extends DefaultTabPreferenceSetting { 032 033 /** 034 * Factory used to create a new {@code DrawingPreference}. 035 */ 036 public static class Factory implements PreferenceSettingFactory { 037 @Override 038 public PreferenceSetting createPreferenceSetting() { 039 return new DrawingPreference(); 040 } 041 } 042 043 /** 044 * Property controlling whether to draw boundaries of downloaded data 045 * @since 14648 046 */ 047 public static final BooleanProperty SOURCE_BOUNDS_PROP = new BooleanProperty("draw.data.downloaded_area", true); 048 049 private final JCheckBox directionHint = new JCheckBox(tr("Draw Direction Arrows")); 050 private final JCheckBox headArrow = new JCheckBox(tr("Only on the head of a way.")); 051 private final JCheckBox onewayArrow = new JCheckBox(tr("Draw oneway arrows.")); 052 private final JCheckBox segmentOrderNumber = new JCheckBox(tr("Draw segment order numbers")); 053 private final JCheckBox segmentOrderNumberOnSelectedWay = new JCheckBox(tr("Draw segment order numbers on selected way")); 054 private final JCheckBox sourceBounds = new JCheckBox(tr("Draw boundaries of downloaded data")); 055 private final JCheckBox virtualNodes = new JCheckBox(tr("Draw virtual nodes in select mode")); 056 private final JCheckBox inactive = new JCheckBox(tr("Draw inactive layers in other color")); 057 private final JCheckBox discardableKeys = new JCheckBox(tr("Display discardable keys")); 058 private final JCheckBox autoFilters = new JCheckBox(tr("Use auto filters")); 059 private final JLabel lblRule = new JLabel(tr("Rule")); 060 private final JosmComboBox<AutoFilterRule> autoFilterRules = new JosmComboBox<>( 061 AutoFilterManager.getInstance().getAutoFilterRules().toArray(new AutoFilterRule[] {})); 062 063 // Options that affect performance 064 private final JCheckBox useHighlighting = new JCheckBox(tr("Highlight target ways and nodes")); 065 private final JCheckBox drawHelperLine = new JCheckBox(tr("Draw rubber-band helper line")); 066 private final JCheckBox useAntialiasing = new JCheckBox(tr("Smooth map graphics (antialiasing)")); 067 private final JCheckBox useWireframeAntialiasing = new JCheckBox(tr("Smooth map graphics in wireframe mode (antialiasing)")); 068 private final JCheckBox outlineOnly = new JCheckBox(tr("Draw only outlines of areas")); 069 private final JCheckBox hideLabelsWhileDragging = new JCheckBox(tr("Hide labels while dragging the map")); 070 071 DrawingPreference() { 072 super("layer/osmdata_small", tr("OSM Data"), tr("Settings that control the drawing of OSM data.")); 073 } 074 075 @Override 076 public void addGui(PreferenceTabbedPane gui) { 077 JPanel panel = new JPanel(new GridBagLayout()); 078 panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 079 080 // directionHint 081 directionHint.addActionListener(e -> { 082 if (directionHint.isSelected()) { 083 headArrow.setSelected(Config.getPref().getBoolean("draw.segment.head_only", false)); 084 } else { 085 headArrow.setSelected(false); 086 } 087 headArrow.setEnabled(directionHint.isSelected()); 088 }); 089 directionHint.setToolTipText(tr("Draw direction hints for way segments.")); 090 directionHint.setSelected(Config.getPref().getBoolean("draw.segment.direction", false)); 091 092 // only on the head of a way 093 headArrow.setToolTipText(tr("Only on the head of a way.")); 094 headArrow.setSelected(Config.getPref().getBoolean("draw.segment.head_only", false)); 095 headArrow.setEnabled(directionHint.isSelected()); 096 097 // draw oneway arrows 098 onewayArrow.setToolTipText(tr("Draw arrows in the direction of oneways and other directed features.")); 099 onewayArrow.setSelected(Config.getPref().getBoolean("draw.oneway", true)); 100 101 // segment order number 102 segmentOrderNumber.setToolTipText(tr("Draw the order numbers of all segments within their way.")); 103 segmentOrderNumber.setSelected(Config.getPref().getBoolean("draw.segment.order_number", false)); 104 segmentOrderNumberOnSelectedWay.setToolTipText(tr("Draw the order numbers of all segments within their way.")); 105 segmentOrderNumberOnSelectedWay.setSelected(Config.getPref().getBoolean("draw.segment.order_number.on_selected", false)); 106 107 // downloaded area 108 sourceBounds.setToolTipText(tr("Draw the boundaries of data loaded from the server.")); 109 sourceBounds.setSelected(SOURCE_BOUNDS_PROP.get()); 110 111 // virtual nodes 112 virtualNodes.setToolTipText(tr("Draw virtual nodes in select mode for easy way modification.")); 113 virtualNodes.setSelected(Config.getPref().getInt("mappaint.node.virtual-size", 8) != 0); 114 115 // background layers in inactive color 116 inactive.setToolTipText(tr("Draw the inactive data layers in a different color.")); 117 inactive.setSelected(Config.getPref().getBoolean("draw.data.inactive_color", true)); 118 119 // antialiasing 120 useAntialiasing.setToolTipText(tr("Apply antialiasing to the map view resulting in a smoother appearance.")); 121 useAntialiasing.setSelected(Config.getPref().getBoolean("mappaint.use-antialiasing", true)); 122 123 // wireframe mode antialiasing 124 useWireframeAntialiasing.setToolTipText(tr("Apply antialiasing to the map view in wireframe mode resulting in a smoother appearance.")); 125 useWireframeAntialiasing.setSelected(Config.getPref().getBoolean("mappaint.wireframe.use-antialiasing", false)); 126 127 // highlighting 128 useHighlighting.setToolTipText(tr("Hightlight target nodes and ways while drawing or selecting")); 129 useHighlighting.setSelected(Config.getPref().getBoolean("draw.target-highlight", true)); 130 131 drawHelperLine.setToolTipText(tr("Draw rubber-band helper line")); 132 drawHelperLine.setSelected(Config.getPref().getBoolean("draw.helper-line", true)); 133 134 // outlineOnly 135 outlineOnly.setToolTipText(tr("This option suppresses the filling of areas, overriding anything specified in the selected style.")); 136 outlineOnly.setSelected(Config.getPref().getBoolean("draw.data.area_outline_only", false)); 137 138 // hideLabelsWhileDragging 139 hideLabelsWhileDragging.setToolTipText(tr("This option hides the textual labels of OSM objects while dragging the map.")); 140 hideLabelsWhileDragging.setSelected(OsmDataLayer.PROPERTY_HIDE_LABELS_WHILE_DRAGGING.get()); 141 142 // discardable keys 143 discardableKeys.setToolTipText(tr("Display keys which have been deemed uninteresting to the point that they can be silently removed.")); 144 discardableKeys.setSelected(Config.getPref().getBoolean("display.discardable-keys", false)); 145 146 // auto filters 147 autoFilters.setToolTipText(tr("Display buttons to automatically filter numeric values of a predefined tag")); 148 autoFilters.setSelected(AutoFilterManager.PROP_AUTO_FILTER_ENABLED.get()); 149 autoFilters.addActionListener(e -> { 150 lblRule.setEnabled(autoFilters.isSelected()); 151 autoFilterRules.setEnabled(autoFilters.isSelected()); 152 }); 153 autoFilterRules.setToolTipText("Rule defining which tag will provide automatic filters, below a certain zoom level"); 154 autoFilterRules.setSelectedItem(AutoFilterManager.getInstance().getAutoFilterRule(AutoFilterManager.PROP_AUTO_FILTER_RULE.get())); 155 156 JLabel performanceLabel = new JLabel(tr("Options that affect drawing performance")); 157 158 panel.add(new JLabel(tr("Segment drawing options")), 159 GBC.eop().insets(5, 10, 0, 0)); 160 panel.add(directionHint, GBC.eop().insets(20, 0, 0, 0)); 161 panel.add(headArrow, GBC.eop().insets(40, 0, 0, 0)); 162 panel.add(onewayArrow, GBC.eop().insets(20, 0, 0, 0)); 163 panel.add(segmentOrderNumber, GBC.eop().insets(20, 0, 0, 0)); 164 panel.add(segmentOrderNumberOnSelectedWay, GBC.eop().insets(20, 0, 0, 0)); 165 166 panel.add(new JLabel(tr("Select and draw mode options")), 167 GBC.eop().insets(5, 10, 0, 0)); 168 panel.add(virtualNodes, GBC.eop().insets(20, 0, 0, 0)); 169 panel.add(drawHelperLine, GBC.eop().insets(20, 0, 0, 0)); 170 171 panel.add(performanceLabel, GBC.eop().insets(5, 10, 0, 0)); 172 panel.add(useAntialiasing, GBC.eop().insets(20, 0, 0, 0)); 173 panel.add(useWireframeAntialiasing, GBC.eop().insets(20, 0, 0, 0)); 174 panel.add(useHighlighting, GBC.eop().insets(20, 0, 0, 0)); 175 panel.add(outlineOnly, GBC.eol().insets(20, 0, 0, 0)); 176 panel.add(hideLabelsWhileDragging, GBC.eol().insets(20, 0, 0, 0)); 177 178 panel.add(new JLabel(tr("Other options")), 179 GBC.eop().insets(5, 10, 0, 0)); 180 panel.add(sourceBounds, GBC.eop().insets(20, 0, 0, 0)); 181 panel.add(inactive, GBC.eop().insets(20, 0, 0, 0)); 182 panel.add(discardableKeys, GBC.eop().insets(20, 0, 0, 0)); 183 panel.add(autoFilters, GBC.eop().insets(20, 0, 0, 0)); 184 panel.add(lblRule, GBC.std().insets(40, 0, 0, 0)); 185 panel.add(autoFilterRules, GBC.eop().fill(GBC.HORIZONTAL).insets(5, 0, 0, 0)); 186 187 ExpertToggleAction.addVisibilitySwitcher(performanceLabel); 188 ExpertToggleAction.addVisibilitySwitcher(useAntialiasing); 189 ExpertToggleAction.addVisibilitySwitcher(useWireframeAntialiasing); 190 ExpertToggleAction.addVisibilitySwitcher(useHighlighting); 191 ExpertToggleAction.addVisibilitySwitcher(outlineOnly); 192 ExpertToggleAction.addVisibilitySwitcher(hideLabelsWhileDragging); 193 ExpertToggleAction.addVisibilitySwitcher(discardableKeys); 194 195 panel.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.BOTH)); 196 createPreferenceTabWithScrollPane(gui, panel); 197 } 198 199 @Override 200 public boolean ok() { 201 OsmDataLayer.PROPERTY_HIDE_LABELS_WHILE_DRAGGING.put(hideLabelsWhileDragging.isSelected()); 202 Config.getPref().putBoolean("draw.data.area_outline_only", outlineOnly.isSelected()); 203 Config.getPref().putBoolean("draw.segment.direction", directionHint.isSelected()); 204 Config.getPref().putBoolean("draw.segment.head_only", headArrow.isSelected()); 205 Config.getPref().putBoolean("draw.oneway", onewayArrow.isSelected()); 206 Config.getPref().putBoolean("draw.segment.order_number", segmentOrderNumber.isSelected()); 207 Config.getPref().putBoolean("draw.segment.order_number.on_selected", segmentOrderNumberOnSelectedWay.isSelected()); 208 SOURCE_BOUNDS_PROP.put(sourceBounds.isSelected()); 209 Config.getPref().putBoolean("draw.data.inactive_color", inactive.isSelected()); 210 Config.getPref().putBoolean("mappaint.use-antialiasing", useAntialiasing.isSelected()); 211 Config.getPref().putBoolean("mappaint.wireframe.use-antialiasing", useWireframeAntialiasing.isSelected()); 212 Config.getPref().putBoolean("draw.target-highlight", useHighlighting.isSelected()); 213 Config.getPref().putBoolean("draw.helper-line", drawHelperLine.isSelected()); 214 Config.getPref().putBoolean("display.discardable-keys", discardableKeys.isSelected()); 215 AutoFilterManager.PROP_AUTO_FILTER_ENABLED.put(autoFilters.isSelected()); 216 AutoFilterManager.PROP_AUTO_FILTER_RULE.put(((AutoFilterRule) autoFilterRules.getSelectedItem()).getKey()); 217 int vn = Config.getPref().getInt("mappaint.node.virtual-size", 8); 218 if (virtualNodes.isSelected()) { 219 if (vn < 1) { 220 vn = 8; 221 } 222 } else { 223 vn = 0; 224 } 225 Config.getPref().putInt("mappaint.node.virtual-size", vn); 226 return false; 227 } 228 229 @Override 230 public boolean isExpert() { 231 return false; 232 } 233 234 @Override 235 public String getHelpContext() { 236 return HelpUtil.ht("/Preferences/DrawingPreference"); 237 } 238}