Ignore:
Timestamp:
2017-06-11T14:39:43+02:00 (7 years ago)
Author:
michael2402
Message:

Unify handling of visibility checkbox and opacity slider

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/dialogs/layer/LayerVisibilityAction.java

    r11913 r12392  
    1616import javax.swing.ImageIcon;
    1717import javax.swing.JCheckBox;
     18import javax.swing.JComponent;
    1819import javax.swing.JLabel;
    1920import javax.swing.JMenuItem;
     
    5152    private final JPopupMenu popup;
    5253    private SideButton sideButton;
    53     private final JCheckBox visibilityCheckbox;
     54    /**
     55     * The real content, just to add a border
     56     */
     57    private final JPanel content = new JPanel();
    5458    final OpacitySlider opacitySlider = new OpacitySlider();
    55     private final ArrayList<FilterSlider<?>> sliders = new ArrayList<>();
     59    private final ArrayList<LayerVisibilityMenuEntry> sliders = new ArrayList<>();
    5660
    5761    /**
     
    6569        popup.addMouseWheelListener(MouseWheelEvent::consume);
    6670
    67         // just to add a border
    68         JPanel content = new JPanel();
    6971        popup.add(content);
    7072        content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
     
    7476        putValue(SHORT_DESCRIPTION, tr("Change visibility of the selected layer."));
    7577
    76         visibilityCheckbox = new JCheckBox(tr("Show layer"));
    77         visibilityCheckbox.addChangeListener(e -> setVisibleFlag(visibilityCheckbox.isSelected()));
    78         content.add(visibilityCheckbox, GBC.eop());
    79 
    80         addSlider(content, opacitySlider);
    81         addSlider(content, new ColorfulnessSlider());
    82         addSlider(content, new GammaFilterSlider());
    83         addSlider(content, new SharpnessSlider());
    84     }
    85 
    86     private void addSlider(JPanel content, FilterSlider<?> slider) {
    87         // wrap to a common content pane to allow for mouse wheel listener on label.
    88         JPanel container = new JPanel(new GridBagLayout());
    89         container.add(new JLabel(slider.getIcon()), GBC.std().span(1, 2).insets(0, 0, 5, 0));
    90         container.add(new JLabel(slider.getLabel()), GBC.eol());
    91         container.add(slider, GBC.eol());
    92         content.add(container, GBC.eop());
    93 
    94         container.addMouseWheelListener(slider::mouseWheelMoved);
     78        addContentEntry(new VisibilityCheckbox());
     79
     80        addContentEntry(opacitySlider);
     81        addContentEntry(new ColorfulnessSlider());
     82        addContentEntry(new GammaFilterSlider());
     83        addContentEntry(new SharpnessSlider());
     84    }
     85
     86    private void addContentEntry(LayerVisibilityMenuEntry slider) {
     87        content.add(slider.getPanel(), GBC.eop());
    9588        sliders.add(slider);
    9689    }
     
    118111        List<Layer> layers = model.getSelectedLayers();
    119112
    120         visibilityCheckbox.setEnabled(!layers.isEmpty());
    121113        boolean allVisible = true;
    122114        boolean allHidden = true;
     
    125117            allHidden &= !l.isVisible();
    126118        }
    127         // TODO: Indicate tristate.
    128         visibilityCheckbox.setSelected(allVisible && !allHidden);
    129 
    130         for (FilterSlider<?> slider : sliders) {
    131             slider.updateSlider(layers, allHidden);
     119
     120        for (LayerVisibilityMenuEntry slider : sliders) {
     121            slider.updateLayers(layers, allVisible, allHidden);
    132122        }
    133123    }
     
    154144    public void setCorrespondingSideButton(SideButton sideButton) {
    155145        this.sideButton = sideButton;
     146    }
     147
     148    /**
     149     * An entry in the visibility settings dropdown.
     150     * @author Michael Zangl
     151     */
     152    private interface LayerVisibilityMenuEntry {
     153
     154        /**
     155         * Update the displayed value depending on the current layers
     156         * @param layers The layers
     157         * @param allVisible <code>true</code> if all layers are visible
     158         * @param allHidden <code>true</code> if all layers are hidden
     159         */
     160        void updateLayers(List<Layer> layers, boolean allVisible, boolean allHidden);
     161
     162        /**
     163         * Get the panel that should be added to the menu
     164         * @return The panel
     165         */
     166        JComponent getPanel();
     167    }
     168
     169    private class VisibilityCheckbox extends JCheckBox implements LayerVisibilityMenuEntry {
     170
     171        VisibilityCheckbox() {
     172            super(tr("Show layer"));
     173            addChangeListener(e -> setVisibleFlag(isSelected()));
     174        }
     175
     176        @Override
     177        public void updateLayers(List<Layer> layers, boolean allVisible, boolean allHidden) {
     178            setEnabled(!layers.isEmpty());
     179            // TODO: Indicate tristate.
     180            setSelected(allVisible && !allHidden);
     181        }
     182
     183        @Override
     184        public JComponent getPanel() {
     185            return this;
     186        }
    156187    }
    157188
     
    162193     * @param <T> The layer type.
    163194     */
    164     private abstract class FilterSlider<T extends Layer> extends JSlider {
     195    private abstract class AbstractFilterSlider<T extends Layer> extends JPanel implements LayerVisibilityMenuEntry {
    165196        private final double minValue;
    166197        private final double maxValue;
    167198        private final Class<T> layerClassFilter;
     199
     200        protected final JSlider slider = new JSlider(JSlider.HORIZONTAL);
    168201
    169202        /**
     
    173206         * @param layerClassFilter The type of layer influenced by this filter.
    174207         */
    175         FilterSlider(double minValue, double maxValue, Class<T> layerClassFilter) {
    176             super(JSlider.HORIZONTAL);
     208        AbstractFilterSlider(double minValue, double maxValue, Class<T> layerClassFilter) {
     209            super(new GridBagLayout());
    177210            this.minValue = minValue;
    178211            this.maxValue = maxValue;
    179212            this.layerClassFilter = layerClassFilter;
    180             setMaximum(SLIDER_STEPS);
     213
     214            add(new JLabel(getIcon()), GBC.std().span(1, 2).insets(0, 0, 5, 0));
     215            add(new JLabel(getLabel()), GBC.eol());
     216            add(slider, GBC.eol());
     217            addMouseWheelListener(this::mouseWheelMoved);
     218
     219            slider.setMaximum(SLIDER_STEPS);
    181220            int tick = convertFromRealValue(1);
    182             setMinorTickSpacing(tick);
    183             setMajorTickSpacing(tick);
    184             setPaintTicks(true);
    185 
    186             addChangeListener(e -> onStateChanged());
     221            slider.setMinorTickSpacing(tick);
     222            slider.setMajorTickSpacing(tick);
     223            slider.setPaintTicks(true);
     224
     225            slider.addChangeListener(e -> onStateChanged());
    187226        }
    188227
    189228        /**
    190229         * Called whenever the state of the slider was changed.
    191          * @see #getValueIsAdjusting()
     230         * @see JSlider#getValueIsAdjusting()
    192231         * @see #getRealValue()
    193232         */
     
    206245            }
    207246            double rotation = -1 * e.getPreciseWheelRotation();
    208             double destinationValue = getValue() + rotation * SLIDER_WHEEL_INCREMENT;
     247            double destinationValue = slider.getValue() + rotation * SLIDER_WHEEL_INCREMENT;
    209248            if (rotation < 0) {
    210249                destinationValue = Math.floor(destinationValue);
     
    212251                destinationValue = Math.ceil(destinationValue);
    213252            }
    214             setValue(Utils.clamp((int) destinationValue, getMinimum(), getMaximum()));
     253            slider.setValue(Utils.clamp((int) destinationValue, slider.getMinimum(), slider.getMaximum()));
    215254        }
    216255
     
    218257
    219258        protected double getRealValue() {
    220             return convertToRealValue(getValue());
     259            return convertToRealValue(slider.getValue());
    221260        }
    222261
     
    227266
    228267        protected void setRealValue(double value) {
    229             setValue(convertFromRealValue(value));
     268            slider.setValue(convertFromRealValue(value));
    230269        }
    231270
    232271        protected int convertFromRealValue(double value) {
    233272            int i = (int) ((value - minValue) / (maxValue - minValue) * SLIDER_STEPS + .5);
    234             return Utils.clamp(i, getMinimum(), getMaximum());
     273            return Utils.clamp(i, slider.getMinimum(), slider.getMaximum());
    235274        }
    236275
     
    239278        public abstract String getLabel();
    240279
    241         public void updateSlider(List<Layer> layers, boolean allHidden) {
     280        @Override
     281        public void updateLayers(List<Layer> layers, boolean allVisible, boolean allHidden) {
    242282            Collection<? extends Layer> usedLayers = filterLayers(layers);
    243             if (usedLayers.isEmpty() || allHidden) {
    244                 setEnabled(false);
     283            if (!usedLayers.stream().anyMatch(Layer::isVisible)) {
     284                slider.setEnabled(false);
    245285            } else {
    246                 setEnabled(true);
     286                slider.setEnabled(true);
    247287                updateSliderWhileEnabled(usedLayers, allHidden);
    248288            }
     
    254294
    255295        protected abstract void updateSliderWhileEnabled(Collection<? extends Layer> usedLayers, boolean allHidden);
     296
     297        @Override
     298        public JComponent getPanel() {
     299            return this;
     300        }
    256301    }
    257302
     
    262307     * @see Layer#setOpacity(double)
    263308     */
    264     class OpacitySlider extends FilterSlider<Layer> {
     309    class OpacitySlider extends AbstractFilterSlider<Layer> {
    265310        /**
    266311         * Creaate a new {@link OpacitySlider}.
     
    268313        OpacitySlider() {
    269314            super(0, 1, Layer.class);
    270             setToolTipText(tr("Adjust opacity of the layer."));
     315            slider.setToolTipText(tr("Adjust opacity of the layer."));
    271316        }
    272317
    273318        @Override
    274319        protected void onStateChanged() {
    275             if (getRealValue() <= 0.001 && !getValueIsAdjusting()) {
     320            if (getRealValue() <= 0.001 && !slider.getValueIsAdjusting()) {
    276321                setVisibleFlag(false);
    277322            } else {
     
    333378     * @see ImageryFilterSettings#setGamma(double)
    334379     */
    335     private class GammaFilterSlider extends FilterSlider<ImageryLayer> {
     380    private class GammaFilterSlider extends AbstractFilterSlider<ImageryLayer> {
    336381
    337382        /**
     
    340385        GammaFilterSlider() {
    341386            super(-1, 1, ImageryLayer.class);
    342             setToolTipText(tr("Adjust gamma value of the layer."));
     387            slider.setToolTipText(tr("Adjust gamma value of the layer."));
    343388        }
    344389
     
    392437     * @see ImageryFilterSettings#setSharpenLevel(double)
    393438     */
    394     private class SharpnessSlider extends FilterSlider<ImageryLayer> {
     439    private class SharpnessSlider extends AbstractFilterSlider<ImageryLayer> {
    395440
    396441        /**
     
    399444        SharpnessSlider() {
    400445            super(0, MAX_SHARPNESS_FACTOR, ImageryLayer.class);
    401             setToolTipText(tr("Adjust sharpness/blur value of the layer."));
     446            slider.setToolTipText(tr("Adjust sharpness/blur value of the layer."));
    402447        }
    403448
     
    429474     * @see ImageryFilterSettings#setColorfulness(double)
    430475     */
    431     private class ColorfulnessSlider extends FilterSlider<ImageryLayer> {
     476    private class ColorfulnessSlider extends AbstractFilterSlider<ImageryLayer> {
    432477
    433478        /**
     
    436481        ColorfulnessSlider() {
    437482            super(0, MAX_COLORFUL_FACTOR, ImageryLayer.class);
    438             setToolTipText(tr("Adjust colorfulness of the layer."));
     483            slider.setToolTipText(tr("Adjust colorfulness of the layer."));
    439484        }
    440485
Note: See TracChangeset for help on using the changeset viewer.