diff --git a/core/src/main/java/com/github/weisj/darklaf/LafManager.java b/core/src/main/java/com/github/weisj/darklaf/LafManager.java index fa1158c7..bc3a97de 100644 --- a/core/src/main/java/com/github/weisj/darklaf/LafManager.java +++ b/core/src/main/java/com/github/weisj/darklaf/LafManager.java @@ -23,8 +23,12 @@ */ package com.github.weisj.darklaf; -import com.github.weisj.darklaf.task.DefaultsInitTask; -import com.github.weisj.darklaf.theme.*; +import com.github.weisj.darklaf.task.DefaultsAdjustmentTask; +import com.github.weisj.darklaf.theme.DarculaTheme; +import com.github.weisj.darklaf.theme.Theme; +import com.github.weisj.darklaf.theme.info.DefaultThemeProvider; +import com.github.weisj.darklaf.theme.info.PreferredThemeStyle; +import com.github.weisj.darklaf.theme.info.ThemeProvider; import javax.swing.*; import java.awt.*; @@ -48,7 +52,7 @@ public final class LafManager { private static Theme theme; private static boolean logEnabled = false; private static boolean decorationsOverwrite = true; - private static final Collection uiDefaultsTasks = new HashSet<>(); + private static final Collection uiDefaultsTasks = new HashSet<>(); static { enableLogging(true); @@ -241,7 +245,7 @@ public final class LafManager { * * @param task the defaults init task. */ - public static void registerDefaultsInitTask(final DefaultsInitTask task) { + public static void registerDefaultsAdjustmentTask(final DefaultsAdjustmentTask task) { uiDefaultsTasks.add(task); } @@ -250,7 +254,7 @@ public final class LafManager { * * @param task the defaults init task. */ - public static void removeDefaultsInitTask(final DefaultsInitTask task) { + public static void removeDefaultsAdjustmentTask(final DefaultsAdjustmentTask task) { uiDefaultsTasks.remove(task); } @@ -259,7 +263,7 @@ public final class LafManager { * * @return collection of init tasks. */ - public static Collection getUserInitTasks() { + public static Collection getUserAdjustmentTasks() { return uiDefaultsTasks; } diff --git a/core/src/main/java/com/github/weisj/darklaf/components/border/DarkBorders.java b/core/src/main/java/com/github/weisj/darklaf/components/border/DarkBorders.java index 6490a5d8..e37471d4 100644 --- a/core/src/main/java/com/github/weisj/darklaf/components/border/DarkBorders.java +++ b/core/src/main/java/com/github/weisj/darklaf/components/border/DarkBorders.java @@ -63,21 +63,16 @@ public final class DarkBorders { return createBorder(top, left, bottom, right, lineWidgetBorderMap, "borderSecondary"); } - public static void update(final Map defaults) { - Color borderColor = getColor(defaults, "border"); + public static void update(final UIDefaults defaults) { + Color borderColor = defaults.getColor("border"); for (WeakReference border : lineBorderMap.values()) { WeakLineBorder b = border.get(); if (b != null) b.setColor(borderColor); } - Color borderSecondaryColor = getColor(defaults, "borderSecondary"); + Color borderSecondaryColor = defaults.getColor("borderSecondary"); for (WeakReference border : lineWidgetBorderMap.values()) { WeakLineBorder b = border.get(); if (b != null) b.setColor(borderSecondaryColor); } } - - private static Color getColor(final Map defaults, final String key) { - Object color = defaults.get(key); - return color instanceof Color ? (Color) color : null; - } } diff --git a/core/src/main/java/com/github/weisj/darklaf/platform/Decorations.java b/core/src/main/java/com/github/weisj/darklaf/platform/Decorations.java index 31dad92b..60457cd5 100644 --- a/core/src/main/java/com/github/weisj/darklaf/platform/Decorations.java +++ b/core/src/main/java/com/github/weisj/darklaf/platform/Decorations.java @@ -34,7 +34,6 @@ import com.github.weisj.darklaf.util.SystemInfo; import javax.swing.*; import java.awt.*; -import java.util.Map; import java.util.Properties; public final class Decorations { @@ -84,7 +83,7 @@ public final class Decorations { decorationsProvider.initialize(); } - public static void loadDecorationProperties(final Properties uiProps, final Map defaults) { + public static void loadDecorationProperties(final Properties uiProps, final UIDefaults defaults) { decorationsProvider.loadDecorationProperties(uiProps, defaults); } } diff --git a/core/src/main/java/com/github/weisj/darklaf/platform/DefaultDecorationsProvider.java b/core/src/main/java/com/github/weisj/darklaf/platform/DefaultDecorationsProvider.java index 3260d19c..f9dc4297 100644 --- a/core/src/main/java/com/github/weisj/darklaf/platform/DefaultDecorationsProvider.java +++ b/core/src/main/java/com/github/weisj/darklaf/platform/DefaultDecorationsProvider.java @@ -28,7 +28,6 @@ import com.github.weisj.darklaf.platform.decorations.DecorationsProvider; import javax.swing.*; import java.awt.*; -import java.util.Map; import java.util.Properties; public class DefaultDecorationsProvider implements DecorationsProvider { @@ -60,6 +59,6 @@ public class DefaultDecorationsProvider implements DecorationsProvider { } @Override - public void loadDecorationProperties(final Properties properties, final Map currentDefaults) { + public void loadDecorationProperties(final Properties properties, final UIDefaults currentDefaults) { } } diff --git a/core/src/main/java/com/github/weisj/darklaf/task/DefaultsAdjustmentTask.java b/core/src/main/java/com/github/weisj/darklaf/task/DefaultsAdjustmentTask.java new file mode 100644 index 00000000..e19e42db --- /dev/null +++ b/core/src/main/java/com/github/weisj/darklaf/task/DefaultsAdjustmentTask.java @@ -0,0 +1,39 @@ +/* + * 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.task; + +import com.github.weisj.darklaf.theme.Theme; + +import java.util.Properties; + +public interface DefaultsAdjustmentTask { + + /** + * Execute the task. + * + * @param currentTheme the current theme. + * @param properties the properties. + */ + void run(final Theme currentTheme, final Properties properties); +} diff --git a/core/src/main/java/com/github/weisj/darklaf/task/DefaultsInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/DefaultsInitTask.java index 302f6d45..8887a840 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/DefaultsInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/DefaultsInitTask.java @@ -25,9 +25,8 @@ package com.github.weisj.darklaf.task; import com.github.weisj.darklaf.theme.Theme; -import java.util.Map; +import javax.swing.*; -@FunctionalInterface public interface DefaultsInitTask { /** @@ -36,7 +35,7 @@ public interface DefaultsInitTask { * @param currentTheme the current theme being initialized. * @param defaults the current defaults to work with. */ - void run(final Theme currentTheme, final Map defaults); + void run(final Theme currentTheme, final UIDefaults defaults); /** * Indicated that this task should only be run if the laf is actually installed. diff --git a/core/src/main/java/com/github/weisj/darklaf/task/FontDefaultsInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/FontDefaultsInitTask.java index a6559266..1d801a63 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/FontDefaultsInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/FontDefaultsInitTask.java @@ -25,11 +25,11 @@ package com.github.weisj.darklaf.task; import com.github.weisj.darklaf.DarkLaf; import com.github.weisj.darklaf.PropertyLoader; -import com.github.weisj.darklaf.theme.FontMapper; -import com.github.weisj.darklaf.theme.FontSizeRule; import com.github.weisj.darklaf.theme.Theme; +import com.github.weisj.darklaf.theme.info.FontSizeRule; import com.github.weisj.darklaf.util.SystemInfo; +import javax.swing.*; import javax.swing.plaf.FontUIResource; import javax.swing.plaf.UIResource; import java.awt.*; @@ -38,19 +38,20 @@ import java.text.AttributedCharacterIterator; import java.util.Collections; import java.util.Map; import java.util.Properties; +import java.util.logging.Logger; public class FontDefaultsInitTask implements DefaultsInitTask { + private static final Logger LOGGER = Logger.getLogger(FontDefaultsInitTask.class.getName()); private static final String FONT_PROPERTY_PATH = "properties/"; private static final String FONT_SIZE_DEFAULTS_NAME = "font_sizes"; - private static final String FONT_DEFAULTS_NAME = "font_sizes"; + private static final String FONT_DEFAULTS_NAME = "font"; private static final String MAC_OS_CATALINA_FONT_NAME = ".AppleSystemUIFont"; private static final String MAC_OS_FONT_NAME = ".SF NS Text"; - private final PropertyFontMapper fontMapper = new PropertyFontMapper(); @Override - public void run(final Theme currentTheme, final Map defaults) { + public void run(final Theme currentTheme, final UIDefaults defaults) { loadFontProperties(defaults); if (SystemInfo.isMac) { patchMacOSFonts(defaults); @@ -58,7 +59,7 @@ public class FontDefaultsInitTask implements DefaultsInitTask { applyFontRule(currentTheme, defaults); } - private void loadFontProperties(final Map defaults) { + private void loadFontProperties(final UIDefaults defaults) { Properties fontSizeProps = PropertyLoader.loadProperties(DarkLaf.class, FONT_SIZE_DEFAULTS_NAME, FONT_PROPERTY_PATH); @@ -69,7 +70,7 @@ public class FontDefaultsInitTask implements DefaultsInitTask { PropertyLoader.putProperties(fontProps, defaults); } - private void patchMacOSFonts(final Map defaults) { + private void patchMacOSFonts(final UIDefaults defaults) { for (Map.Entry entry : defaults.entrySet()) { if (entry.getValue() instanceof Font) { Font font = (Font) entry.getValue(); @@ -89,9 +90,9 @@ public class FontDefaultsInitTask implements DefaultsInitTask { return macFont == null ? font : macFont; } - private void applyFontRule(final Theme currentTheme, final Map defaults) { + private void applyFontRule(final Theme currentTheme, final UIDefaults defaults) { FontSizeRule rule = currentTheme.getFontSizeRule(); - if (rule == null || rule == FontSizeRule.DEFAULT) return; + if (rule == null || rule.getType() == FontSizeRule.AdjustmentType.NO_ADJUSTMENT) return; for (Map.Entry entry : defaults.entrySet()) { if (entry != null && entry.getValue() instanceof Font) { entry.setValue(fontWithRule((Font) entry.getValue(), rule, defaults)); @@ -99,17 +100,20 @@ public class FontDefaultsInitTask implements DefaultsInitTask { } } - private Font fontWithRule(final Font font, final FontSizeRule rule, final Map defaults) { - Font withRule = getFontMapper(rule).map(font, defaults); + private Font fontWithRule(final Font font, final FontSizeRule rule, final UIDefaults defaults) { + if (font == null || defaults == null) return font; + float size = font.getSize2D(); + float newSize = rule.adjustFontSize(size, defaults); + if (newSize == size) return font; + if (newSize <= 0) { + LOGGER.warning("Font " + font + " would be invisible after applying " + rule + ". Font won't be changed!"); + return font; + } + Font withRule = font.deriveFont(newSize); if (font instanceof UIResource && !(withRule instanceof UIResource)) { withRule = new FontUIResource(withRule); } return withRule; } - - private FontMapper getFontMapper(final FontSizeRule rule) { - fontMapper.setPropertyKey(rule == null ? null : rule.getPropertyKey()); - return fontMapper; - } } diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/FontMapper.java b/core/src/main/java/com/github/weisj/darklaf/task/FontMapper.java similarity index 90% rename from theme/src/main/java/com/github/weisj/darklaf/theme/FontMapper.java rename to core/src/main/java/com/github/weisj/darklaf/task/FontMapper.java index e4b7daa7..9d8fab0e 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/FontMapper.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/FontMapper.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.weisj.darklaf.theme; +package com.github.weisj.darklaf.task; +import javax.swing.*; import java.awt.*; -import java.util.Map; public interface FontMapper { - Font map(final Font font, final Map defaults); + Font map(final Font font, final UIDefaults defaults); } diff --git a/core/src/main/java/com/github/weisj/darklaf/task/IdeaDefaultsInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/IdeaDefaultsInitTask.java index 3f258eef..f040d945 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/IdeaDefaultsInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/IdeaDefaultsInitTask.java @@ -26,16 +26,15 @@ package com.github.weisj.darklaf.task; import com.github.weisj.darklaf.theme.Theme; import javax.swing.*; -import java.util.Map; public class IdeaDefaultsInitTask implements DefaultsInitTask { @Override - public void run(final Theme currentTheme, final Map defaults) { + public void run(final Theme currentTheme, final UIDefaults defaults) { initIdeaDefaults(defaults); } @SuppressWarnings({"HardCodedStringLiteral"}) - private void initIdeaDefaults(final Map defaults) { + private void initIdeaDefaults(final UIDefaults defaults) { defaults.put("Table.ancestorInputMap", new UIDefaults.LazyInputMap( new Object[]{ "ctrl C", "copy", diff --git a/core/src/main/java/com/github/weisj/darklaf/task/InputDefaultsInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/InputDefaultsInitTask.java index 74f750ba..d11fed04 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/InputDefaultsInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/InputDefaultsInitTask.java @@ -31,21 +31,20 @@ import javax.swing.plaf.metal.MetalLookAndFeel; import javax.swing.text.DefaultEditorKit; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; -import java.util.Map; public class InputDefaultsInitTask implements DefaultsInitTask { @Override - public void run(final Theme currentTheme, final Map defaults) { + public void run(final Theme currentTheme, final UIDefaults defaults) { initInputMapDefaults(defaults); patchComboBox(new MetalLookAndFeel().getDefaults(), defaults); } - private void initInputMapDefaults(final Map defaults) { + private void initInputMapDefaults(final UIDefaults defaults) { // Make ENTER work in JTrees final InputMap treeInputMap = (InputMap) defaults.get("Tree.focusInputMap"); if (treeInputMap != null) { - // it's really possible. For example, GTK+ doesn't have such map + // it's really possible. For example, GTK+ doesn't have such a map. treeInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "toggle"); } // Cut/Copy/Paste in JTextAreas @@ -99,7 +98,7 @@ public class InputDefaultsInitTask implements DefaultsInitTask { inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, mask), DefaultEditorKit.cutAction); } - private static void patchComboBox(final UIDefaults metalDefaults, final Map defaults) { + private static void patchComboBox(final UIDefaults metalDefaults, final UIDefaults defaults) { defaults.remove("ComboBox.ancestorInputMap"); defaults.remove("ComboBox.actionMap"); defaults.put("ComboBox.ancestorInputMap", metalDefaults.get("ComboBox.ancestorInputMap")); diff --git a/core/src/main/java/com/github/weisj/darklaf/task/PlatformDefaultsInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/PlatformDefaultsInitTask.java index f47f76eb..768d275d 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/PlatformDefaultsInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/PlatformDefaultsInitTask.java @@ -29,11 +29,10 @@ import com.github.weisj.darklaf.ui.popupmenu.DarkPopupMenuUI; import com.github.weisj.darklaf.util.SystemInfo; import javax.swing.*; -import java.util.Map; public class PlatformDefaultsInitTask implements DefaultsInitTask { @Override - public void run(final Theme currentTheme, final Map defaults) { + public void run(final Theme currentTheme, final UIDefaults defaults) { String key = DarkPopupMenuUI.KEY_DEFAULT_LIGHTWEIGHT_POPUPS; if (SystemInfo.isWindows10 && Decorations.isCustomDecorationSupported()) { JPopupMenu.setDefaultLightWeightPopupEnabled(Boolean.TRUE.equals(defaults.get(key + ".windows"))); diff --git a/core/src/main/java/com/github/weisj/darklaf/task/PropertyFontMapper.java b/core/src/main/java/com/github/weisj/darklaf/task/PropertyFontMapper.java index 44604713..15ffd8bd 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/PropertyFontMapper.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/PropertyFontMapper.java @@ -24,11 +24,10 @@ package com.github.weisj.darklaf.task; import com.github.weisj.darklaf.LafManager; -import com.github.weisj.darklaf.theme.FontMapper; import com.github.weisj.darklaf.theme.Theme; +import javax.swing.*; import java.awt.*; -import java.util.Map; import java.util.logging.Logger; public class PropertyFontMapper implements FontMapper { @@ -52,7 +51,7 @@ public class PropertyFontMapper implements FontMapper { } @Override - public Font map(final Font font, final Map defaults) { + public Font map(final Font font, final UIDefaults defaults) { if (propertyKey == null) return font; adjustment = getSize(defaults); // No need to create a new font. @@ -67,7 +66,7 @@ public class PropertyFontMapper implements FontMapper { return font.deriveFont(font.getSize2D() + adjustment); } - private int getSize(final Map defaults) { + private int getSize(final UIDefaults defaults) { // Use cached value if already queried. if (lastTheme == LafManager.getTheme()) return adjustment; lastTheme = LafManager.getTheme(); diff --git a/core/src/main/java/com/github/weisj/darklaf/task/SystemDefaultsInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/SystemDefaultsInitTask.java index 6d5f3528..e798fd55 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/SystemDefaultsInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/SystemDefaultsInitTask.java @@ -27,7 +27,7 @@ import com.github.weisj.darklaf.DarkLaf; import com.github.weisj.darklaf.PropertyLoader; import com.github.weisj.darklaf.theme.Theme; -import java.util.Map; +import javax.swing.*; import java.util.Properties; public class SystemDefaultsInitTask implements DefaultsInitTask { @@ -36,11 +36,11 @@ public class SystemDefaultsInitTask implements DefaultsInitTask { private static final String OVERWRITES_NAME = "overwrites"; @Override - public void run(final Theme currentTheme, final Map defaults) { + public void run(final Theme currentTheme, final UIDefaults defaults) { loadSystemOverwrites(defaults); } - private void loadSystemOverwrites(final Map defaults) { + private void loadSystemOverwrites(final UIDefaults defaults) { Properties overwrites = PropertyLoader.loadProperties(DarkLaf.class, OVERWRITES_NAME, OVERWRITES_PATH); overwrites.values().removeIf(v -> System.getProperty(DarkLaf.SYSTEM_PROPERTY_PREFIX + v.toString()) == null); overwrites.entrySet().forEach( diff --git a/core/src/main/java/com/github/weisj/darklaf/task/ThemeDefaultsInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/ThemeDefaultsInitTask.java index 8b50d383..577ae2d8 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/ThemeDefaultsInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/ThemeDefaultsInitTask.java @@ -32,7 +32,6 @@ import com.github.weisj.darklaf.util.SystemInfo; import javax.swing.*; import javax.swing.text.html.HTMLEditorKit; import java.util.HashMap; -import java.util.Map; import java.util.Properties; public class ThemeDefaultsInitTask implements DefaultsInitTask { @@ -49,12 +48,11 @@ public class ThemeDefaultsInitTask implements DefaultsInitTask { private static final String[] ICON_PROPERTIES = new String[]{ "control", "dialog", "files", "frame", "indicator", "menu", "misc", "navigation" }; - private final DefaultsInitTask userPreferenceInitTask = new UserPreferenceInitTask(); + private final DefaultsAdjustmentTask userPreferenceInitTask = new UserPreferenceAdjustmentTask(); @Override - public void run(final Theme currentTheme, final Map defaults) { - if (!(defaults instanceof UIDefaults)) return; - loadThemeDefaults(currentTheme, (UIDefaults) defaults); + public void run(final Theme currentTheme, final UIDefaults defaults) { + loadThemeDefaults(currentTheme, defaults); } private void loadThemeDefaults(final Theme currentTheme, final UIDefaults defaults) { @@ -87,7 +85,7 @@ public class ThemeDefaultsInitTask implements DefaultsInitTask { installGlobals(uiProps, defaults); } - private void installGlobals(final Properties uiProps, final Map defaults) { + private void installGlobals(final Properties uiProps, final UIDefaults defaults) { final HashMap globalSettings = new HashMap<>(); for (final Object key : uiProps.keySet()) { if (key instanceof String && ((String) key).startsWith(GLOBAL_PREFIX)) { diff --git a/core/src/main/java/com/github/weisj/darklaf/task/UserPreferenceInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/UserPreferenceAdjustmentTask.java similarity index 79% rename from core/src/main/java/com/github/weisj/darklaf/task/UserPreferenceInitTask.java rename to core/src/main/java/com/github/weisj/darklaf/task/UserPreferenceAdjustmentTask.java index 3017a5fa..fff394bf 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/UserPreferenceInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/UserPreferenceAdjustmentTask.java @@ -26,14 +26,14 @@ package com.github.weisj.darklaf.task; import com.github.weisj.darklaf.LafManager; import com.github.weisj.darklaf.theme.Theme; -import java.util.Map; +import java.util.Properties; -public class UserPreferenceInitTask implements DefaultsInitTask { +public class UserPreferenceAdjustmentTask implements DefaultsAdjustmentTask { @Override - public void run(final Theme currentTheme, final Map defaults) { - for (DefaultsInitTask task : LafManager.getUserInitTasks()) { - if (task != null) task.run(currentTheme, defaults); + public void run(final Theme currentTheme, final Properties properties) { + for (DefaultsAdjustmentTask task : LafManager.getUserAdjustmentTasks()) { + if (task != null) task.run(currentTheme, properties); } } } diff --git a/core/src/main/java/com/github/weisj/darklaf/task/UtilityDefaultsInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/UtilityDefaultsInitTask.java index e88f2823..fe9bba6b 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/UtilityDefaultsInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/UtilityDefaultsInitTask.java @@ -29,11 +29,11 @@ import com.github.weisj.darklaf.icons.IconLoader; import com.github.weisj.darklaf.theme.Theme; import com.github.weisj.darklaf.util.DarkUIUtil; -import java.util.Map; +import javax.swing.*; public class UtilityDefaultsInitTask implements DefaultsInitTask { @Override - public void run(final Theme currentTheme, final Map defaults) { + public void run(final Theme currentTheme, final UIDefaults defaults) { setupUtils(currentTheme, defaults); } @@ -41,7 +41,7 @@ public class UtilityDefaultsInitTask implements DefaultsInitTask { * Update the values for all classes using theme defaults and notify them that the theme has * changed. */ - private void setupUtils(final Theme currentTheme, final Map defaults) { + private void setupUtils(final Theme currentTheme, final UIDefaults defaults) { DarkUIUtil.setDropOpacity(getOpacity(defaults, "dropOpacity")); DarkUIUtil.setGlowOpacity(getOpacity(defaults, "glowOpacity")); DarkUIUtil.setShadowOpacity(getOpacity(defaults, "shadowOpacity")); @@ -50,7 +50,7 @@ public class UtilityDefaultsInitTask implements DefaultsInitTask { IconLoader.updateThemeStatus(currentTheme); } - private float getOpacity(final Map defaults, final String key) { + private float getOpacity(final UIDefaults defaults, final String key) { Object obj = defaults.get(key); int val = (obj instanceof Integer) ? (int) obj : 100; return val / 100f; diff --git a/core/src/test/java/theme/MyCustomTheme.java b/core/src/test/java/theme/MyCustomTheme.java index 96892b6c..c3d87cd7 100644 --- a/core/src/test/java/theme/MyCustomTheme.java +++ b/core/src/test/java/theme/MyCustomTheme.java @@ -23,9 +23,9 @@ */ package theme; -import com.github.weisj.darklaf.theme.ColorToneRule; -import com.github.weisj.darklaf.theme.PresetIconRule; import com.github.weisj.darklaf.theme.Theme; +import com.github.weisj.darklaf.theme.info.ColorToneRule; +import com.github.weisj.darklaf.theme.info.PresetIconRule; import com.github.weisj.darklaf.util.SystemInfo; import javax.swing.*; diff --git a/core/src/test/java/ui/ComponentDemo.java b/core/src/test/java/ui/ComponentDemo.java index e4c78660..f0914eba 100644 --- a/core/src/test/java/ui/ComponentDemo.java +++ b/core/src/test/java/ui/ComponentDemo.java @@ -25,6 +25,9 @@ package ui; import com.github.weisj.darklaf.LafManager; import com.github.weisj.darklaf.theme.*; +import com.github.weisj.darklaf.theme.info.ColorToneRule; +import com.github.weisj.darklaf.theme.info.ContrastRule; +import com.github.weisj.darklaf.theme.info.PreferredThemeStyle; import javax.swing.*; import java.awt.*; @@ -34,8 +37,7 @@ public interface ComponentDemo { static Theme getTheme() { return LafManager.themeForPreferredStyle(new PreferredThemeStyle(ContrastRule.STANDARD, - ColorToneRule.LIGHT, - FontSizeRule.DEFAULT)); + ColorToneRule.LIGHT)); } JComponent createComponent(); diff --git a/macos/src/main/java/com/github/weisj/darklaf/platform/macos/MacOSDecorationsProvider.java b/macos/src/main/java/com/github/weisj/darklaf/platform/macos/MacOSDecorationsProvider.java index d59b8402..3f405c40 100644 --- a/macos/src/main/java/com/github/weisj/darklaf/platform/macos/MacOSDecorationsProvider.java +++ b/macos/src/main/java/com/github/weisj/darklaf/platform/macos/MacOSDecorationsProvider.java @@ -24,14 +24,13 @@ package com.github.weisj.darklaf.platform.macos; import com.github.weisj.darklaf.PropertyLoader; +import com.github.weisj.darklaf.icons.IconLoader; import com.github.weisj.darklaf.platform.decorations.CustomTitlePane; import com.github.weisj.darklaf.platform.decorations.DecorationsProvider; -import com.github.weisj.darklaf.icons.IconLoader; import com.github.weisj.darklaf.platform.macos.ui.MacOSTitlePane; import javax.swing.*; import java.awt.*; -import java.util.Map; import java.util.Properties; public class MacOSDecorationsProvider implements DecorationsProvider { @@ -52,7 +51,7 @@ public class MacOSDecorationsProvider implements DecorationsProvider { } @Override - public void loadDecorationProperties(final Properties properties, final Map currentDefaults) { + public void loadDecorationProperties(final Properties properties, final UIDefaults currentDefaults) { IconLoader iconLoader = IconLoader.get(MacOSDecorationsProvider.class); PropertyLoader.putProperties(PropertyLoader.loadProperties(MacOSDecorationsProvider.class, "macos_decorations", ""), diff --git a/platform-base/src/main/java/com/github/weisj/darklaf/platform/decorations/DecorationsProvider.java b/platform-base/src/main/java/com/github/weisj/darklaf/platform/decorations/DecorationsProvider.java index a12cbc37..18f36957 100644 --- a/platform-base/src/main/java/com/github/weisj/darklaf/platform/decorations/DecorationsProvider.java +++ b/platform-base/src/main/java/com/github/weisj/darklaf/platform/decorations/DecorationsProvider.java @@ -25,7 +25,6 @@ package com.github.weisj.darklaf.platform.decorations; import javax.swing.*; import java.awt.*; -import java.util.Map; import java.util.Properties; public interface DecorationsProvider { @@ -59,7 +58,7 @@ public interface DecorationsProvider { * @param properties the properties to load the values into. * @param currentDefaults the current ui defaults. */ - void loadDecorationProperties(Properties properties, Map currentDefaults); + void loadDecorationProperties(final Properties properties, final UIDefaults currentDefaults); /** * Initialize the window of a popup menu. diff --git a/property-loader/src/main/java/com/github/weisj/darklaf/PropertyLoader.java b/property-loader/src/main/java/com/github/weisj/darklaf/PropertyLoader.java index fc7e7780..6bbecadd 100644 --- a/property-loader/src/main/java/com/github/weisj/darklaf/PropertyLoader.java +++ b/property-loader/src/main/java/com/github/weisj/darklaf/PropertyLoader.java @@ -98,27 +98,27 @@ public final class PropertyLoader { } public static void putProperties(final Properties properties, final Properties accumulator, - final Map currentDefaults) { + final UIDefaults currentDefaults) { putProperties(properties, accumulator, currentDefaults, ICON_LOADER); } public static void putProperties(final Properties properties, final Properties accumulator, - final Map currentDefaults, final IconLoader iconLoader) { + final UIDefaults currentDefaults, final IconLoader iconLoader) { putProperties(properties, properties.stringPropertyNames(), accumulator, currentDefaults, iconLoader); } - public static void putProperties(final Properties properties, final Map defaults) { + public static void putProperties(final Properties properties, final UIDefaults defaults) { putProperties(properties, defaults, ICON_LOADER); } - public static void putProperties(final Properties properties, final Map defaults, + public static void putProperties(final Properties properties, final UIDefaults defaults, final IconLoader iconLoader) { putProperties(properties, properties.stringPropertyNames(), defaults, defaults, iconLoader); } public static void putProperties(final Map properties, final Set keys, final Map accumulator, - final Map currentDefaults, final IconLoader iconLoader) { + final UIDefaults currentDefaults, final IconLoader iconLoader) { for (final String key : keys) { final String value = properties.get(key).toString(); Object parsed = parseValue(key, value, accumulator, currentDefaults, iconLoader); @@ -138,7 +138,7 @@ public final class PropertyLoader { private static Object parseValue(final String propertyKey, final String value, final Map accumulator, - final Map currentDefaults, final IconLoader iconLoader) { + final UIDefaults currentDefaults, final IconLoader iconLoader) { if (PropertyValue.NULL.equals(value)) { return null; } @@ -218,8 +218,9 @@ public final class PropertyLoader { } @SuppressWarnings("MagicConstant") - private static Object parseFont(final String key, final String value, final Map accumulator, - final Map currentDefaults) { + private static Object parseFont(final String key, final String value, + final Map accumulator, + final UIDefaults currentDefaults) { String val = value; Font base = null; int size = -1; @@ -243,7 +244,7 @@ public final class PropertyLoader { } if (base == null) base = parseExplicitFont(value); if (base == null && accumulator.get(key) instanceof Font) base = (Font) accumulator.get(key); - if (base == null && currentDefaults.get(key) instanceof Font) base = (Font) currentDefaults.get(key); + if (base == null) base = currentDefaults.getFont(key); if (base == null) base = new Font("Dialog", Font.PLAIN, 12); if (size > 0) base = base.deriveFont((float) size); if (style >= 0) base = base.deriveFont(style); @@ -288,14 +289,14 @@ public final class PropertyLoader { private static Pair parseFrom(final String val, final Map accumulator, - final Map currentDefaults) { + final UIDefaults currentDefaults) { String key = val.substring(FONT_FROM.length() + 1); int index = key.indexOf(ARG_END); String rest = key.substring(index + 1); key = key.substring(0, index); Font font = null; if (accumulator.get(key) instanceof Font) font = (Font) accumulator.get(key); - if (font == null && currentDefaults.get(key) instanceof Font) font = (Font) currentDefaults.get(key); + if (font == null) font = currentDefaults.getFont(key); return new Pair<>(font, rest); } diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/DarculaTheme.java b/theme/src/main/java/com/github/weisj/darklaf/theme/DarculaTheme.java index 17a29e26..16e30e1c 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/DarculaTheme.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/DarculaTheme.java @@ -23,6 +23,9 @@ */ package com.github.weisj.darklaf.theme; +import com.github.weisj.darklaf.theme.info.ColorToneRule; +import com.github.weisj.darklaf.theme.info.PresetIconRule; + /** * @author Jannis Weis */ diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/FontSizeRule.java b/theme/src/main/java/com/github/weisj/darklaf/theme/FontSizeRule.java deleted file mode 100644 index 4184467c..00000000 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/FontSizeRule.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.theme; - -public enum FontSizeRule { - DEFAULT("default"), - TINY("tiny"), - SMALLER("smaller"), - SMALL("small"), - MEDIUM("medium"), - LARGE("large"), - LARGER("larger"), - HUGE("huge"); - - private final String propertyKey; - - FontSizeRule(final String propertyKey) { - this.propertyKey = propertyKey; - } - - public String getPropertyKey() { - return "fontSize." + propertyKey; - } -} diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/HighContrastDarkTheme.java b/theme/src/main/java/com/github/weisj/darklaf/theme/HighContrastDarkTheme.java index 5c9ea6ad..0075b826 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/HighContrastDarkTheme.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/HighContrastDarkTheme.java @@ -23,6 +23,10 @@ */ package com.github.weisj.darklaf.theme; +import com.github.weisj.darklaf.theme.info.ColorToneRule; +import com.github.weisj.darklaf.theme.info.ContrastRule; +import com.github.weisj.darklaf.theme.info.PresetIconRule; + import javax.swing.*; import java.util.Properties; diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/HighContrastLightTheme.java b/theme/src/main/java/com/github/weisj/darklaf/theme/HighContrastLightTheme.java index 033933d4..0ea5836e 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/HighContrastLightTheme.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/HighContrastLightTheme.java @@ -23,6 +23,10 @@ */ package com.github.weisj.darklaf.theme; +import com.github.weisj.darklaf.theme.info.ColorToneRule; +import com.github.weisj.darklaf.theme.info.ContrastRule; +import com.github.weisj.darklaf.theme.info.PresetIconRule; + import javax.swing.*; import java.util.Properties; diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/IntelliJTheme.java b/theme/src/main/java/com/github/weisj/darklaf/theme/IntelliJTheme.java index 002bf4cf..3ff29f96 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/IntelliJTheme.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/IntelliJTheme.java @@ -23,6 +23,9 @@ */ package com.github.weisj.darklaf.theme; +import com.github.weisj.darklaf.theme.info.ColorToneRule; +import com.github.weisj.darklaf.theme.info.PresetIconRule; + import javax.swing.*; import java.util.Properties; diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/SolarizedDarkTheme.java b/theme/src/main/java/com/github/weisj/darklaf/theme/SolarizedDarkTheme.java index 148e4477..9b406d3a 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/SolarizedDarkTheme.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/SolarizedDarkTheme.java @@ -23,6 +23,9 @@ */ package com.github.weisj.darklaf.theme; +import com.github.weisj.darklaf.theme.info.ColorToneRule; +import com.github.weisj.darklaf.theme.info.PresetIconRule; + import javax.swing.*; import java.util.Properties; diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/SolarizedLightTheme.java b/theme/src/main/java/com/github/weisj/darklaf/theme/SolarizedLightTheme.java index 38f9fa79..36e27477 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/SolarizedLightTheme.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/SolarizedLightTheme.java @@ -23,6 +23,9 @@ */ package com.github.weisj.darklaf.theme; +import com.github.weisj.darklaf.theme.info.ColorToneRule; +import com.github.weisj.darklaf.theme.info.PresetIconRule; + import javax.swing.*; import java.util.Properties; diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/Theme.java b/theme/src/main/java/com/github/weisj/darklaf/theme/Theme.java index 36265b20..4c3ca009 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/Theme.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/Theme.java @@ -24,6 +24,10 @@ package com.github.weisj.darklaf.theme; import com.github.weisj.darklaf.PropertyLoader; +import com.github.weisj.darklaf.theme.info.ColorToneRule; +import com.github.weisj.darklaf.theme.info.ContrastRule; +import com.github.weisj.darklaf.theme.info.FontSizeRule; +import com.github.weisj.darklaf.theme.info.PresetIconRule; import javax.swing.*; import javax.swing.text.html.StyleSheet; @@ -309,7 +313,7 @@ public abstract class Theme { * @return the font size rule. */ public FontSizeRule getFontSizeRule() { - if (fontSizeRule == null) fontSizeRule = FontSizeRule.DEFAULT; + if (fontSizeRule == null) fontSizeRule = FontSizeRule.getDefault(); return fontSizeRule; } diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/ColorToneRule.java b/theme/src/main/java/com/github/weisj/darklaf/theme/info/ColorToneRule.java similarity index 96% rename from theme/src/main/java/com/github/weisj/darklaf/theme/ColorToneRule.java rename to theme/src/main/java/com/github/weisj/darklaf/theme/info/ColorToneRule.java index f1f84e55..f90f38ee 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/ColorToneRule.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/info/ColorToneRule.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.weisj.darklaf.theme; +package com.github.weisj.darklaf.theme.info; public enum ColorToneRule { DARK, diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/ContrastRule.java b/theme/src/main/java/com/github/weisj/darklaf/theme/info/ContrastRule.java similarity index 96% rename from theme/src/main/java/com/github/weisj/darklaf/theme/ContrastRule.java rename to theme/src/main/java/com/github/weisj/darklaf/theme/info/ContrastRule.java index 0e022ecb..53dc2fd3 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/ContrastRule.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/info/ContrastRule.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.weisj.darklaf.theme; +package com.github.weisj.darklaf.theme.info; public enum ContrastRule { HIGH_CONTRAST, diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/DefaultThemeProvider.java b/theme/src/main/java/com/github/weisj/darklaf/theme/info/DefaultThemeProvider.java similarity index 98% rename from theme/src/main/java/com/github/weisj/darklaf/theme/DefaultThemeProvider.java rename to theme/src/main/java/com/github/weisj/darklaf/theme/info/DefaultThemeProvider.java index 2b98b0d1..06190ff7 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/DefaultThemeProvider.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/info/DefaultThemeProvider.java @@ -21,7 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.weisj.darklaf.theme; +package com.github.weisj.darklaf.theme.info; + +import com.github.weisj.darklaf.theme.*; public class DefaultThemeProvider implements ThemeProvider { diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/info/FontSizePreset.java b/theme/src/main/java/com/github/weisj/darklaf/theme/info/FontSizePreset.java new file mode 100644 index 00000000..76b3590e --- /dev/null +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/info/FontSizePreset.java @@ -0,0 +1,74 @@ +/* + * 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.theme.info; + +import javax.swing.*; +import java.util.logging.Logger; + +public enum FontSizePreset { + TINY("tiny"), + SMALLER("smaller"), + SMALL("small"), + MEDIUM("medium"), + LARGE("large"), + LARGER("larger"), + HUGE("huge"); + + private static final Logger LOGGER = Logger.getLogger(FontSizePreset.class.getName()); + private final String propertyName; + private final FontSizeRule.AdjustmentType type; + + FontSizePreset(final String propertyName) { + this(propertyName, FontSizeRule.AdjustmentType.ABSOLUTE_ADJUSTMENT); + } + + FontSizePreset(final String propertyName, final FontSizeRule.AdjustmentType type) { + this.propertyName = propertyName; + this.type = type; + } + + public float adjustFontSize(final float size, final UIDefaults defaults) { + int adjustment = getSize(defaults); + return type.adjustSize(size, adjustment, adjustment / 100f); + } + + private String getPropertyName() { + return "fontSize." + propertyName; + } + + public FontSizeRule.AdjustmentType getType() { + return type; + } + + private int getSize(final UIDefaults defaults) { + String key = getPropertyName(); + Object obj = defaults.get(getPropertyName()); + if (!(obj instanceof Integer)) { + LOGGER.warning("Font size property '" + key + "' not specified. Font will not be changed"); + return Integer.MAX_VALUE; + } else { + return (int) obj; + } + } +} diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/info/FontSizeRule.java b/theme/src/main/java/com/github/weisj/darklaf/theme/info/FontSizeRule.java new file mode 100644 index 00000000..fc7c670c --- /dev/null +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/info/FontSizeRule.java @@ -0,0 +1,130 @@ +/* + * 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.theme.info; + +import javax.swing.*; + +public class FontSizeRule { + private static final FontSizeRule DEFAULT = new FontSizeRule(AdjustmentType.NO_ADJUSTMENT, 0, 1f); + + private final AdjustmentType type; + private final FontSizePreset preset; + private final float relativeAdjustment; + private final int absoluteAdjustment; + + protected FontSizeRule(final FontSizePreset preset) { + this.preset = preset; + type = preset.getType(); + relativeAdjustment = 1f; + absoluteAdjustment = 0; + } + + protected FontSizeRule(final AdjustmentType type, + final int absoluteAdjustment, final float relativeAdjustment) { + this.type = type; + this.absoluteAdjustment = absoluteAdjustment; + this.relativeAdjustment = relativeAdjustment; + preset = null; + } + + public static FontSizeRule getDefault() { + return DEFAULT; + } + + public static FontSizeRule fromPreset(final FontSizePreset preset) { + return new FontSizeRule(preset); + } + + public static FontSizeRule absoluteAdjustment(final int adjustment) { + return new FontSizeRule(AdjustmentType.ABSOLUTE_ADJUSTMENT, adjustment, 1f); + } + + public static FontSizeRule relativeAdjustment(final float percent) { + return new FontSizeRule(AdjustmentType.RELATIVE_ADJUSTMENT, 0, percent); + } + + public float adjustFontSize(final float size, final UIDefaults defaults) { + if (preset != null) return preset.adjustFontSize(size, defaults); + return type.adjustSize(size, absoluteAdjustment, relativeAdjustment); + } + + public AdjustmentType getType() { + if (preset == null) { + // Prevent unnecessary mapping of font. + if (type == AdjustmentType.ABSOLUTE_ADJUSTMENT && absoluteAdjustment == 0) { + return AdjustmentType.NO_ADJUSTMENT; + } + if (type == AdjustmentType.RELATIVE_ADJUSTMENT && relativeAdjustment == 1f) { + return AdjustmentType.NO_ADJUSTMENT; + } + } + return type; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder("FontSizeRule{type=").append(type); + if (preset != null) { + builder.append(", preset=").append(preset); + } else { + switch (type) { + case ABSOLUTE_ADJUSTMENT: + builder.append(", absoluteAdjustment=").append(absoluteAdjustment); + break; + case RELATIVE_ADJUSTMENT: + builder.append(", relativeAdjustment=").append(relativeAdjustment); + break; + case NO_ADJUSTMENT: + default: + break; + } + } + builder.append("}"); + return builder.toString(); + } + + public enum AdjustmentType { + NO_ADJUSTMENT { + @Override + public float adjustSize(final float size, final int absolute, final float relative) { + return size; + } + }, + ABSOLUTE_ADJUSTMENT { + @Override + public float adjustSize(final float size, final int absolute, final float relative) { + return size + absolute; + } + }, + RELATIVE_ADJUSTMENT { + @Override + public float adjustSize(final float size, final int absolute, final float relative) { + return size * relative; + } + }; + + abstract public float adjustSize(final float size, final int absolute, final float relative); + } + +} diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/PreferredThemeStyle.java b/theme/src/main/java/com/github/weisj/darklaf/theme/info/PreferredThemeStyle.java similarity index 73% rename from theme/src/main/java/com/github/weisj/darklaf/theme/PreferredThemeStyle.java rename to theme/src/main/java/com/github/weisj/darklaf/theme/info/PreferredThemeStyle.java index c44d284a..daf59d4f 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/PreferredThemeStyle.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/info/PreferredThemeStyle.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.weisj.darklaf.theme; +package com.github.weisj.darklaf.theme.info; public class PreferredThemeStyle { @@ -29,6 +29,15 @@ public class PreferredThemeStyle { private final ColorToneRule colorToneRule; private final FontSizeRule fontSizeRule; + public PreferredThemeStyle(final ContrastRule contrastRule, + final ColorToneRule colorToneRule) { + if (contrastRule == null) throw new IllegalArgumentException("null is not a valid contrast rule"); + if (colorToneRule == null) throw new IllegalArgumentException("null is not a valid style rule"); + this.contrastRule = contrastRule; + this.colorToneRule = colorToneRule; + this.fontSizeRule = FontSizeRule.getDefault(); + } + public PreferredThemeStyle(final ContrastRule contrastRule, final ColorToneRule colorToneRule, final FontSizeRule fontSizeRule) { @@ -52,4 +61,12 @@ public class PreferredThemeStyle { return fontSizeRule; } + @Override + public String toString() { + return "PreferredThemeStyle{" + + "contrastRule=" + contrastRule + + ", colorToneRule=" + colorToneRule + + ", fontSizeRule=" + fontSizeRule + + '}'; + } } diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/PresetIconRule.java b/theme/src/main/java/com/github/weisj/darklaf/theme/info/PresetIconRule.java similarity index 96% rename from theme/src/main/java/com/github/weisj/darklaf/theme/PresetIconRule.java rename to theme/src/main/java/com/github/weisj/darklaf/theme/info/PresetIconRule.java index 8c70e5c9..99ffcb8d 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/PresetIconRule.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/info/PresetIconRule.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.weisj.darklaf.theme; +package com.github.weisj.darklaf.theme.info; public enum PresetIconRule { NONE, diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/info/ThemePreferenceProvider.java b/theme/src/main/java/com/github/weisj/darklaf/theme/info/ThemePreferenceProvider.java new file mode 100644 index 00000000..c2e5621e --- /dev/null +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/info/ThemePreferenceProvider.java @@ -0,0 +1,39 @@ +/* + * 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.theme.info; + +public interface ThemePreferenceProvider { + + /** + * Get the preferred theme style. + * + * @return the preferred theme style. + */ + PreferredThemeStyle getPreference(); + + /** + * Initialize all necessary resources. + */ + void initialize(); +} diff --git a/theme/src/main/java/com/github/weisj/darklaf/theme/ThemeProvider.java b/theme/src/main/java/com/github/weisj/darklaf/theme/info/ThemeProvider.java similarity index 93% rename from theme/src/main/java/com/github/weisj/darklaf/theme/ThemeProvider.java rename to theme/src/main/java/com/github/weisj/darklaf/theme/info/ThemeProvider.java index 22429fff..5789b2a4 100644 --- a/theme/src/main/java/com/github/weisj/darklaf/theme/ThemeProvider.java +++ b/theme/src/main/java/com/github/weisj/darklaf/theme/info/ThemeProvider.java @@ -21,7 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.weisj.darklaf.theme; +package com.github.weisj.darklaf.theme.info; + +import com.github.weisj.darklaf.theme.Theme; public interface ThemeProvider { diff --git a/windows/build.gradle.kts b/windows/build.gradle.kts index c3b9b01a..7a954fbf 100644 --- a/windows/build.gradle.kts +++ b/windows/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { javaImplementation(project(":darklaf-native-utils")) javaImplementation(project(":darklaf-utils")) javaImplementation(project(":darklaf-platform-base")) + javaImplementation(project(":darklaf-theme")) javaImplementation(project(":darklaf-property-loader")) } @@ -27,8 +28,8 @@ library { binaries.whenElementFinalized(CppSharedLibrary::class) { linkTask.get().linkerArgs.addAll( when (toolChain) { - is Gcc, is Clang -> listOf("-ldwmapi", "-lGdi32", "-luser32") - is VisualCpp -> listOf("dwmapi.lib", "user32.lib", "Gdi32.lib") + is Gcc, is Clang -> listOf("-ldwmapi", "-lGdi32", "-luser32", "-ladvapi32") + is VisualCpp -> listOf("dwmapi.lib", "user32.lib", "Gdi32.lib", "Advapi32.lib") else -> emptyList() } ) diff --git a/windows/src/main/cpp/JNIDecorations.cpp b/windows/src/main/cpp/Decorations.cpp similarity index 99% rename from windows/src/main/cpp/JNIDecorations.cpp rename to windows/src/main/cpp/Decorations.cpp index 22ec907b..a603c79e 100644 --- a/windows/src/main/cpp/JNIDecorations.cpp +++ b/windows/src/main/cpp/Decorations.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "JNIDecorations.h" +#include "Decorations.h" #include "com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows.h" #include #include diff --git a/windows/src/main/cpp/JNIDecorations.h b/windows/src/main/cpp/Decorations.h similarity index 100% rename from windows/src/main/cpp/JNIDecorations.h rename to windows/src/main/cpp/Decorations.h diff --git a/windows/src/main/cpp/ThemeInfo.cpp b/windows/src/main/cpp/ThemeInfo.cpp new file mode 100644 index 00000000..4730b637 --- /dev/null +++ b/windows/src/main/cpp/ThemeInfo.cpp @@ -0,0 +1,109 @@ +/* + * 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. + */ +#include "com_github_weisj_darklaf_platform_windows_JNIThemeInfoWindows.h" + +#include +#include +#include +#include + +#define DARK_MODE_PATH "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize" +#define DARK_MODE_KEY "AppsUseLightTheme" +#define FONT_SCALE_PATH "Software\\Microsoft\\Accessibility" +#define FONT_SCALE_KEY "TextScaleFactor" + +DWORD RegGetDword(HKEY hKey, const LPCSTR subKey, const LPCSTR value) +{ + DWORD data{}; + DWORD dataSize = sizeof(data); + DWORD flags = RRF_RT_REG_DWORD; +#ifdef _WIN64 + flags |= RRF_SUBKEY_WOW6464KEY; +#else + flags |= RRF_SUBKEY_WOW6432KEY; +#endif + LONG retCode = ::RegGetValue(hKey, subKey, value, flags, nullptr, &data, &dataSize); + if (retCode != ERROR_SUCCESS) + { + throw retCode; + } + return data; +} + +bool IsDarkMode() +{ + try + { + DWORD data = RegGetDword(HKEY_CURRENT_USER, DARK_MODE_PATH, DARK_MODE_KEY); + return data == 0; + } + catch (LONG e) + { + // Error. Simply return false. + return false; + } +} + +bool IsHighContrastMode() +{ + HIGHCONTRAST info = { 0 }; + info.cbSize = sizeof(HIGHCONTRAST); + BOOL ok = SystemParametersInfoW(SPI_GETHIGHCONTRAST, 0, &info, 0); + if (ok) + { + return info.dwFlags & HCF_HIGHCONTRASTON; + } + return false; +} + +unsigned int GetTextScaleFactor() +{ + try + { + return RegGetDword(HKEY_CURRENT_USER, FONT_SCALE_PATH, FONT_SCALE_KEY); + } + catch (LONG e) + { + return 100; + } +} + +JNIEXPORT jboolean JNICALL +Java_com_github_weisj_darklaf_platform_windows_JNIThemeInfoWindows_isDarkThemeEnabled(JNIEnv *env, jclass obj) +{ + return (jboolean)IsDarkMode(); +} + +JNIEXPORT jboolean JNICALL +Java_com_github_weisj_darklaf_platform_windows_JNIThemeInfoWindows_isHighContrastEnabled(JNIEnv *env, jclass obj) +{ + return (jboolean)IsHighContrastMode(); +} + +JNIEXPORT jlong JNICALL +Java_com_github_weisj_darklaf_platform_windows_JNIThemeInfoWindows_getFontScaleFactor(JNIEnv *env, jclass obj) +{ + return (jlong)GetTextScaleFactor(); +} + diff --git a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsThemeInfoProvider.java b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/JNIThemeInfoWindows.java similarity index 85% rename from windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsThemeInfoProvider.java rename to windows/src/main/java/com/github/weisj/darklaf/platform/windows/JNIThemeInfoWindows.java index 904b8d2f..ebe25152 100644 --- a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsThemeInfoProvider.java +++ b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/JNIThemeInfoWindows.java @@ -23,5 +23,11 @@ */ package com.github.weisj.darklaf.platform.windows; -public class WindowsThemeInfoProvider { +public class JNIThemeInfoWindows { + + public static native boolean isDarkThemeEnabled(); + + public static native boolean isHighContrastEnabled(); + + public static native long getFontScaleFactor(); } diff --git a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsDecorationsProvider.java b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsDecorationsProvider.java index c226b9bf..f66f623a 100644 --- a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsDecorationsProvider.java +++ b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsDecorationsProvider.java @@ -24,17 +24,16 @@ package com.github.weisj.darklaf.platform.windows; import com.github.weisj.darklaf.PropertyLoader; -import com.github.weisj.darklaf.platform.decorations.CustomTitlePane; -import com.github.weisj.darklaf.platform.decorations.DecorationsProvider; import com.github.weisj.darklaf.icons.IconLoader; import com.github.weisj.darklaf.platform.PointerUtil; +import com.github.weisj.darklaf.platform.decorations.CustomTitlePane; +import com.github.weisj.darklaf.platform.decorations.DecorationsProvider; import com.github.weisj.darklaf.platform.windows.ui.WindowsTitlePane; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.util.Map; import java.util.Properties; public class WindowsDecorationsProvider implements DecorationsProvider { @@ -83,7 +82,7 @@ public class WindowsDecorationsProvider implements DecorationsProvider { } @Override - public void loadDecorationProperties(final Properties properties, final Map currentDefaults) { + public void loadDecorationProperties(final Properties properties, final UIDefaults currentDefaults) { IconLoader iconLoader = IconLoader.get(WindowsDecorationsProvider.class); PropertyLoader.putProperties(PropertyLoader.loadProperties(WindowsDecorationsProvider.class, "windows_decorations", ""), diff --git a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsThemePreferenceProvider.java b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsThemePreferenceProvider.java new file mode 100644 index 00000000..a5287303 --- /dev/null +++ b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsThemePreferenceProvider.java @@ -0,0 +1,50 @@ +/* + * 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.platform.windows; + +import com.github.weisj.darklaf.theme.info.*; + +public class WindowsThemePreferenceProvider implements ThemePreferenceProvider { + + private final PreferredThemeStyle fallbackStyle = new PreferredThemeStyle(ContrastRule.STANDARD, + ColorToneRule.LIGHT); + + @Override + public PreferredThemeStyle getPreference() { + if (!WindowsLibrary.isLoaded()) return fallbackStyle; + boolean darkMode = JNIThemeInfoWindows.isDarkThemeEnabled(); + boolean highContrast = JNIThemeInfoWindows.isHighContrastEnabled(); + long fontScaling = JNIThemeInfoWindows.getFontScaleFactor(); + ContrastRule contrastRule = highContrast ? ContrastRule.HIGH_CONTRAST : ContrastRule.STANDARD; + ColorToneRule toneRule = darkMode ? ColorToneRule.DARK : ColorToneRule.LIGHT; + FontSizeRule fontSizeRule = FontSizeRule.relativeAdjustment(fontScaling / 100f); + return new PreferredThemeStyle(contrastRule, toneRule, fontSizeRule); + } + + @Override + public void initialize() { + WindowsLibrary.updateLibrary(); + } + +}