From c4f64a4971085eb531dee47904c83cab41f3d86b Mon Sep 17 00:00:00 2001 From: weisj Date: Fri, 23 Oct 2020 19:43:48 +0200 Subject: [PATCH] Add default implementation of UIAwareIcon which don't rely on the IconLoader mechanism for external custom icons. --- .../darklaf/icons/DefaultUIAwareIcon.java | 108 ++++++++++++++++++ .../weisj/darklaf/icons/IconLoader.java | 23 ++++ .../weisj/darklaf/icons/LazyUIAwareIcon.java | 70 ++++++++++++ .../darklaf/icons/SimpleUIAwareIcon.java | 56 +++++++++ .../weisj/darklaf/icons/UIAwareIcon.java | 16 ++- 5 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 property-loader/src/main/java/com/github/weisj/darklaf/icons/DefaultUIAwareIcon.java create mode 100644 property-loader/src/main/java/com/github/weisj/darklaf/icons/LazyUIAwareIcon.java create mode 100644 property-loader/src/main/java/com/github/weisj/darklaf/icons/SimpleUIAwareIcon.java diff --git a/property-loader/src/main/java/com/github/weisj/darklaf/icons/DefaultUIAwareIcon.java b/property-loader/src/main/java/com/github/weisj/darklaf/icons/DefaultUIAwareIcon.java new file mode 100644 index 00000000..e05c91cf --- /dev/null +++ b/property-loader/src/main/java/com/github/weisj/darklaf/icons/DefaultUIAwareIcon.java @@ -0,0 +1,108 @@ +/* + * MIT License + * + * Copyright (c) 2020 Jannis Weis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package com.github.weisj.darklaf.icons; + +import java.awt.*; + +import javax.swing.*; + +/** + * Default base implementation for {@link UIAwareIcon}. The specific loading mechanism needs to be + * implemented in the subclass. + */ +public abstract class DefaultUIAwareIcon implements UIAwareIcon { + + private final UIAwareIcon dual; + + protected Icon light; + protected Icon dark; + + public DefaultUIAwareIcon() { + this.dual = createDual(); + } + + protected abstract UIAwareIcon createDual(); + + protected DefaultUIAwareIcon(final DefaultUIAwareIcon dual) { + this.dark = dual.light; + this.light = dual.dark; + this.dual = dual; + } + + + @Override + public UIAwareIcon getDual() { + return dual; + } + + private boolean isDark() { + return IconLoader.getAwareStyle() == AwareIconStyle.DARK; + } + + private Icon getEffectiveIcon() { + return isDark() ? getDarkIcon() : getLightIcon(); + } + + /** + * Load the light version of the icon. This method should never return a null value. + * + * @return the light icon. + */ + protected abstract Icon loadLightIcon(); + + /** + * Load the dark version of the icon. This method should never return a null value. + * + * @return the dark icon. + */ + protected abstract Icon loadDarkIcon(); + + private Icon getLightIcon() { + if (light == null) { + light = loadLightIcon(); + } + return light; + } + + private Icon getDarkIcon() { + if (dark == null) { + dark = loadDarkIcon(); + } + return dark; + } + + @Override + public void paintIcon(final Component c, final Graphics g, final int x, final int y) { + getEffectiveIcon().paintIcon(c, g, x, y); + } + + + @Override + public int getIconWidth() { + return getEffectiveIcon().getIconWidth(); + } + + @Override + public int getIconHeight() { + return getEffectiveIcon().getIconHeight(); + } +} diff --git a/property-loader/src/main/java/com/github/weisj/darklaf/icons/IconLoader.java b/property-loader/src/main/java/com/github/weisj/darklaf/icons/IconLoader.java index fc4e85a1..6bfc99e5 100644 --- a/property-loader/src/main/java/com/github/weisj/darklaf/icons/IconLoader.java +++ b/property-loader/src/main/java/com/github/weisj/darklaf/icons/IconLoader.java @@ -158,6 +158,29 @@ public final class IconLoader { return getUIAwareIcon(path, getDefaultWidth(path), getDefaultHeight(path)); } + /** + * Creates a new {@link UIAwareIcon} which is loaded lazily through the given supplier. + * + * @param lightIconSupplier the supplier for the light icon. + * @param darkIconSupplier the supplier for the dark icon. + * @return the {@link UIAwareIcon} + */ + public UIAwareIcon createUIAwareIcon(final IconSupplier lightIconSupplier, + final IconSupplier darkIconSupplier) { + return new LazyUIAwareIcon(lightIconSupplier, darkIconSupplier); + } + + /** + * Creates a new {@link UIAwareIcon} from the given icon. + * + * @param light the light version of the icon. + * @param dark the dark version of the icon. + * @return the {@link UIAwareIcon}. + */ + public UIAwareIcon createUIAwareIcon(final Icon light, final Icon dark) { + return new SimpleUIAwareIcon(light, dark); + } + /** * Get an aware icon. If [path] is the search root of the current icon loader then the icon resource * will be resolved to [path]/dark/[icon_path] and [path]/light/[icon_path] diff --git a/property-loader/src/main/java/com/github/weisj/darklaf/icons/LazyUIAwareIcon.java b/property-loader/src/main/java/com/github/weisj/darklaf/icons/LazyUIAwareIcon.java new file mode 100644 index 00000000..8590b49a --- /dev/null +++ b/property-loader/src/main/java/com/github/weisj/darklaf/icons/LazyUIAwareIcon.java @@ -0,0 +1,70 @@ +/* + * MIT License + * + * Copyright (c) 2020 Jannis Weis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package com.github.weisj.darklaf.icons; + +import javax.swing.*; + +public class LazyUIAwareIcon extends DefaultUIAwareIcon { + + private IconSupplier lightSupplier; + private IconSupplier darkSupplier; + + public LazyUIAwareIcon(final IconSupplier lightSupplier, final IconSupplier darkSupplier) { + this.lightSupplier = lightSupplier; + this.darkSupplier = darkSupplier; + } + + protected LazyUIAwareIcon(final LazyUIAwareIcon dual) { + super(dual); + this.lightSupplier = dual.darkSupplier; + this.darkSupplier = dual.lightSupplier; + } + + @Override + protected UIAwareIcon createDual() { + return new LazyUIAwareIcon(this); + } + + protected Icon loadLightIcon() { + Icon icon; + if (lightSupplier != null) { + icon = lightSupplier.getIcon(); + lightSupplier = null; + } else { + // Should never happen. + icon = EmptyIcon.create(0); + } + return icon; + } + + protected Icon loadDarkIcon() { + Icon icon; + if (darkSupplier != null) { + icon = darkSupplier.getIcon(); + darkSupplier = null; + } else { + // Should never happen. + icon = EmptyIcon.create(0); + } + return icon; + } +} diff --git a/property-loader/src/main/java/com/github/weisj/darklaf/icons/SimpleUIAwareIcon.java b/property-loader/src/main/java/com/github/weisj/darklaf/icons/SimpleUIAwareIcon.java new file mode 100644 index 00000000..73f5bc68 --- /dev/null +++ b/property-loader/src/main/java/com/github/weisj/darklaf/icons/SimpleUIAwareIcon.java @@ -0,0 +1,56 @@ +/* + * MIT License + * + * Copyright (c) 2020 Jannis Weis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package com.github.weisj.darklaf.icons; + +import javax.swing.*; + +/** + * Implementation of {@link UIAwareIcon} which delegates to preloaded icons. + */ +public class SimpleUIAwareIcon extends DefaultUIAwareIcon { + + public SimpleUIAwareIcon(final Icon light, final Icon dark) { + this.light = light; + this.dark = dark; + } + + protected SimpleUIAwareIcon(final SimpleUIAwareIcon dual) { + super(dual); + this.light = dual.dark; + this.dark = dual.light; + } + + @Override + protected UIAwareIcon createDual() { + return new SimpleUIAwareIcon(this); + } + + @Override + protected Icon loadLightIcon() { + return null; + } + + @Override + protected Icon loadDarkIcon() { + return null; + } +} diff --git a/property-loader/src/main/java/com/github/weisj/darklaf/icons/UIAwareIcon.java b/property-loader/src/main/java/com/github/weisj/darklaf/icons/UIAwareIcon.java index 2e3d28e2..e94550a4 100644 --- a/property-loader/src/main/java/com/github/weisj/darklaf/icons/UIAwareIcon.java +++ b/property-loader/src/main/java/com/github/weisj/darklaf/icons/UIAwareIcon.java @@ -21,10 +21,20 @@ */ package com.github.weisj.darklaf.icons; -import javax.swing.*; - -/** @author Jannis Weis */ +/** + * Icon which dynamically adapts to whether the UI is currently {@link AwareIconStyle#LIGHT light} + * or {@link AwareIconStyle#DARK dark}. + */ public interface UIAwareIcon extends DynamicIcon { + /** + * Return the dual version of the icon. i.e. if the current icon is light then the dual version will + * be dark and vice versa. + * + * Implementations of this method should respect that the appearance of the icon after invoking this + * method twice should be the same. + * + * @return the dual icon. + */ UIAwareIcon getDual(); }