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;
013import javax.swing.JScrollPane;
014
015import org.openstreetmap.josm.Main;
016import org.openstreetmap.josm.actions.ExpertToggleAction;
017import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
018import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
019import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
020import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting;
021import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
022import org.openstreetmap.josm.gui.util.GuiHelper;
023import org.openstreetmap.josm.tools.GBC;
024
025/**
026 * Map drawing preferences.
027 */
028public class DrawingPreference implements SubPreferenceSetting {
029
030    /**
031     * Factory used to create a new {@code DrawingPreference}.
032     */
033    public static class Factory implements PreferenceSettingFactory {
034        @Override
035        public PreferenceSetting createPreferenceSetting() {
036            return new DrawingPreference();
037        }
038    }
039
040    private GPXSettingsPanel gpxPanel;
041    private final JCheckBox directionHint = new JCheckBox(tr("Draw Direction Arrows"));
042    private final JCheckBox headArrow = new JCheckBox(tr("Only on the head of a way."));
043    private final JCheckBox onewayArrow = new JCheckBox(tr("Draw oneway arrows."));
044    private final JCheckBox segmentOrderNumber = new JCheckBox(tr("Draw segment order numbers"));
045    private final JCheckBox segmentOrderNumberOnSelectedWay = new JCheckBox(tr("Draw segment order numbers on selected way"));
046    private final JCheckBox sourceBounds = new JCheckBox(tr("Draw boundaries of downloaded data"));
047    private final JCheckBox virtualNodes = new JCheckBox(tr("Draw virtual nodes in select mode"));
048    private final JCheckBox inactive = new JCheckBox(tr("Draw inactive layers in other color"));
049    private final JCheckBox discardableKeys = new JCheckBox(tr("Display discardable keys"));
050
051    // Options that affect performance
052    private final JCheckBox useHighlighting = new JCheckBox(tr("Highlight target ways and nodes"));
053    private final JCheckBox drawHelperLine = new JCheckBox(tr("Draw rubber-band helper line"));
054    private final JCheckBox useAntialiasing = new JCheckBox(tr("Smooth map graphics (antialiasing)"));
055    private final JCheckBox useWireframeAntialiasing = new JCheckBox(tr("Smooth map graphics in wireframe mode (antialiasing)"));
056    private final JCheckBox outlineOnly = new JCheckBox(tr("Draw only outlines of areas"));
057
058    @Override
059    public void addGui(PreferenceTabbedPane gui) {
060        gpxPanel = new GPXSettingsPanel();
061        gui.addValidationListener(gpxPanel);
062        JPanel panel = gpxPanel;
063
064        JScrollPane scrollpane = new JScrollPane(panel);
065        scrollpane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
066        GuiHelper.setDefaultIncrement(scrollpane);
067        gui.getDisplayPreference().addSubTab(this, tr("GPS Points"), scrollpane);
068        panel = new JPanel(new GridBagLayout());
069        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
070
071        // directionHint
072        directionHint.addActionListener(e -> {
073            if (directionHint.isSelected()) {
074                headArrow.setSelected(Main.pref.getBoolean("draw.segment.head_only", false));
075            } else {
076                headArrow.setSelected(false);
077            }
078            headArrow.setEnabled(directionHint.isSelected());
079        });
080        directionHint.setToolTipText(tr("Draw direction hints for way segments."));
081        directionHint.setSelected(Main.pref.getBoolean("draw.segment.direction", false));
082
083        // only on the head of a way
084        headArrow.setToolTipText(tr("Only on the head of a way."));
085        headArrow.setSelected(Main.pref.getBoolean("draw.segment.head_only", false));
086        headArrow.setEnabled(directionHint.isSelected());
087
088        // draw oneway arrows
089        onewayArrow.setToolTipText(tr("Draw arrows in the direction of oneways and other directed features."));
090        onewayArrow.setSelected(Main.pref.getBoolean("draw.oneway", true));
091
092        // segment order number
093        segmentOrderNumber.setToolTipText(tr("Draw the order numbers of all segments within their way."));
094        segmentOrderNumber.setSelected(Main.pref.getBoolean("draw.segment.order_number", false));
095        segmentOrderNumberOnSelectedWay.setToolTipText(tr("Draw the order numbers of all segments within their way."));
096        segmentOrderNumberOnSelectedWay.setSelected(Main.pref.getBoolean("draw.segment.order_number.on_selected", false));
097
098        // downloaded area
099        sourceBounds.setToolTipText(tr("Draw the boundaries of data loaded from the server."));
100        sourceBounds.setSelected(Main.pref.getBoolean("draw.data.downloaded_area", true));
101
102        // virtual nodes
103        virtualNodes.setToolTipText(tr("Draw virtual nodes in select mode for easy way modification."));
104        virtualNodes.setSelected(Main.pref.getInteger("mappaint.node.virtual-size", 8) != 0);
105
106        // background layers in inactive color
107        inactive.setToolTipText(tr("Draw the inactive data layers in a different color."));
108        inactive.setSelected(Main.pref.getBoolean("draw.data.inactive_color", true));
109
110        // antialiasing
111        useAntialiasing.setToolTipText(tr("Apply antialiasing to the map view resulting in a smoother appearance."));
112        useAntialiasing.setSelected(Main.pref.getBoolean("mappaint.use-antialiasing", true));
113
114        // wireframe mode antialiasing
115        useWireframeAntialiasing.setToolTipText(tr("Apply antialiasing to the map view in wireframe mode resulting in a smoother appearance."));
116        useWireframeAntialiasing.setSelected(Main.pref.getBoolean("mappaint.wireframe.use-antialiasing", false));
117
118        // highlighting
119        useHighlighting.setToolTipText(tr("Hightlight target nodes and ways while drawing or selecting"));
120        useHighlighting.setSelected(Main.pref.getBoolean("draw.target-highlight", true));
121
122        drawHelperLine.setToolTipText(tr("Draw rubber-band helper line"));
123        drawHelperLine.setSelected(Main.pref.getBoolean("draw.helper-line", true));
124
125        // outlineOnly
126        outlineOnly.setToolTipText(tr("This option suppresses the filling of areas, overriding anything specified in the selected style."));
127        outlineOnly.setSelected(Main.pref.getBoolean("draw.data.area_outline_only", false));
128
129        // discardable keys
130        discardableKeys.setToolTipText(tr("Display keys which have been deemed uninteresting to the point that they can be silently removed."));
131        discardableKeys.setSelected(Main.pref.getBoolean("display.discardable-keys", false));
132
133        JLabel performanceLabel = new JLabel(tr("Options that affect drawing performance"));
134
135        panel.add(new JLabel(tr("Segment drawing options")),
136                GBC.eop().insets(5, 10, 0, 0));
137        panel.add(directionHint, GBC.eop().insets(20, 0, 0, 0));
138        panel.add(headArrow, GBC.eop().insets(40, 0, 0, 0));
139        panel.add(onewayArrow, GBC.eop().insets(20, 0, 0, 0));
140        panel.add(segmentOrderNumber, GBC.eop().insets(20, 0, 0, 0));
141        panel.add(segmentOrderNumberOnSelectedWay, GBC.eop().insets(20, 0, 0, 0));
142
143        panel.add(new JLabel(tr("Select and draw mode options")),
144                GBC.eop().insets(5, 10, 0, 0));
145        panel.add(virtualNodes, GBC.eop().insets(20, 0, 0, 0));
146        panel.add(drawHelperLine, GBC.eop().insets(20, 0, 0, 0));
147
148        panel.add(performanceLabel, GBC.eop().insets(5, 10, 0, 0));
149        panel.add(useAntialiasing, GBC.eop().insets(20, 0, 0, 0));
150        panel.add(useWireframeAntialiasing, GBC.eop().insets(20, 0, 0, 0));
151        panel.add(useHighlighting, GBC.eop().insets(20, 0, 0, 0));
152        panel.add(outlineOnly, GBC.eol().insets(20, 0, 0, 0));
153
154        panel.add(new JLabel(tr("Other options")),
155                GBC.eop().insets(5, 10, 0, 0));
156        panel.add(sourceBounds, GBC.eop().insets(20, 0, 0, 0));
157        panel.add(inactive, GBC.eop().insets(20, 0, 0, 0));
158        panel.add(discardableKeys, GBC.eop().insets(20, 0, 0, 0));
159
160        ExpertToggleAction.addVisibilitySwitcher(performanceLabel);
161        ExpertToggleAction.addVisibilitySwitcher(useAntialiasing);
162        ExpertToggleAction.addVisibilitySwitcher(useWireframeAntialiasing);
163        ExpertToggleAction.addVisibilitySwitcher(useHighlighting);
164        ExpertToggleAction.addVisibilitySwitcher(outlineOnly);
165        ExpertToggleAction.addVisibilitySwitcher(discardableKeys);
166
167        panel.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.BOTH));
168        scrollpane = new JScrollPane(panel);
169        scrollpane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
170        GuiHelper.setDefaultIncrement(scrollpane);
171        gui.getDisplayPreference().addSubTab(this, tr("OSM Data"), scrollpane);
172    }
173
174    @Override
175    public boolean ok() {
176        boolean restart = gpxPanel.savePreferences();
177        Main.pref.put("draw.data.area_outline_only", outlineOnly.isSelected());
178        Main.pref.put("draw.segment.direction", directionHint.isSelected());
179        Main.pref.put("draw.segment.head_only", headArrow.isSelected());
180        Main.pref.put("draw.oneway", onewayArrow.isSelected());
181        Main.pref.put("draw.segment.order_number", segmentOrderNumber.isSelected());
182        Main.pref.put("draw.segment.order_number.on_selected", segmentOrderNumberOnSelectedWay.isSelected());
183        Main.pref.put("draw.data.downloaded_area", sourceBounds.isSelected());
184        Main.pref.put("draw.data.inactive_color", inactive.isSelected());
185        Main.pref.put("mappaint.use-antialiasing", useAntialiasing.isSelected());
186        Main.pref.put("mappaint.wireframe.use-antialiasing", useWireframeAntialiasing.isSelected());
187        Main.pref.put("draw.target-highlight", useHighlighting.isSelected());
188        Main.pref.put("draw.helper-line", drawHelperLine.isSelected());
189        Main.pref.put("display.discardable-keys", discardableKeys.isSelected());
190        int vn = Main.pref.getInteger("mappaint.node.virtual-size", 8);
191        if (virtualNodes.isSelected()) {
192            if (vn < 1) {
193                vn = 8;
194            }
195        } else {
196            vn = 0;
197        }
198        Main.pref.putInteger("mappaint.node.virtual-size", vn);
199        return restart;
200    }
201
202    @Override
203    public boolean isExpert() {
204        return false;
205    }
206
207    @Override
208    public TabPreferenceSetting getTabPreferenceSetting(final PreferenceTabbedPane gui) {
209        return gui.getDisplayPreference();
210    }
211}