001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.download;
003
004import java.awt.Component;
005
006import org.openstreetmap.josm.data.preferences.AbstractProperty;
007
008/**
009 * Defines the sizing policy used for download tabs.
010 * @author Michael Zangl
011 * @since 12705
012 */
013public interface DownloadSourceSizingPolicy {
014    /**
015     * Gets the height of the download source panel.
016     * @return The height the component should have.
017     */
018    int getComponentHeight();
019
020    /**
021     * Check whether the user should be allowed to adjust the height of this download source panel
022     * @return <code>true</code> if the height should be adjustable
023     */
024    boolean isHeightAdjustable();
025
026    /**
027     * Stores the height
028     * @param height the height in pixel
029     */
030    default void storeHeight(int height) {
031        throw new UnsupportedOperationException(
032                "Setting the height is not supported for " + this.getClass().getCanonicalName());
033    }
034
035    /**
036     * The download source has a fixed size provided by the component
037     * @author Michael Zangl
038     */
039    class FixedDownloadSourceSizePolicy implements DownloadSourceSizingPolicy {
040        private final Component base;
041
042        /**
043         * Create a new fixed download source policy
044         * @param base The component of which the size should be taken.
045         */
046        public FixedDownloadSourceSizePolicy(Component base) {
047            this.base = base;
048        }
049
050        @Override
051        public int getComponentHeight() {
052            return (int) base.getPreferredSize().getHeight();
053        }
054
055        @Override
056        public boolean isHeightAdjustable() {
057            return false;
058        }
059    }
060
061    /**
062     * The height of this component is given by a preference entry.
063     * <p>
064     * Mind that using a preferred component size is not possible in this case, since the preference entry needs to have a onstant default value.
065     */
066    class AdjustableDownloadSizePolicy implements DownloadSourceSizingPolicy {
067
068        private final AbstractProperty<Integer> preference;
069
070        /**
071         * Create a new {@link AdjustableDownloadSizePolicy}
072         * @param preference The preference key to use
073         */
074        public AdjustableDownloadSizePolicy(AbstractProperty<Integer> preference) {
075            this.preference = preference;
076        }
077
078        @Override
079        public int getComponentHeight() {
080            return Math.max(1, preference.get());
081        }
082
083        @Override
084        public boolean isHeightAdjustable() {
085            return true;
086        }
087
088        @Override
089        public void storeHeight(int height) {
090            preference.put(height);
091        }
092
093    }
094}