diff --git a/demos/theming-demo/src/main/java/org/pushingpixels/radiance/demo/theming/main/ControlStatesExtended.java b/demos/theming-demo/src/main/java/org/pushingpixels/radiance/demo/theming/main/ControlStatesExtended.java
index ef2090d05..2351c78a7 100644
--- a/demos/theming-demo/src/main/java/org/pushingpixels/radiance/demo/theming/main/ControlStatesExtended.java
+++ b/demos/theming-demo/src/main/java/org/pushingpixels/radiance/demo/theming/main/ControlStatesExtended.java
@@ -31,11 +31,8 @@
import com.jgoodies.forms.builder.FormBuilder;
import com.jgoodies.forms.factories.Paddings;
-import org.pushingpixels.radiance.theming.api.ComponentState;
import org.pushingpixels.radiance.theming.api.RadianceThemingCortex;
import org.pushingpixels.radiance.theming.api.RadianceThemingSlices;
-import org.pushingpixels.radiance.theming.api.RadianceThemingSlices.ColorSchemeAssociationKind;
-import org.pushingpixels.radiance.theming.api.RadianceThemingSlices.DecorationAreaType;
import org.pushingpixels.radiance.theming.extras.api.skinpack.OfficeSilver2007Skin;
import javax.swing.*;
@@ -44,10 +41,7 @@ public class ControlStatesExtended extends JFrame {
public ControlStatesExtended() {
super("States");
- setIconImage(RadianceLogo.getLogoImage(this,
- RadianceThemingCortex.ComponentScope.getCurrentSkin(this.getRootPane())
- .getColorScheme(DecorationAreaType.PRIMARY_TITLE_PANE,
- ColorSchemeAssociationKind.FILL, ComponentState.ENABLED)));
+ RadianceLogo.tonalConfigureOn(this);
FormBuilder builder = FormBuilder.create().
columns("right:pref, 4dlu, fill:pref:grow").
diff --git a/theming-extras/build.gradle b/theming-extras/build.gradle
index 2e45db843..679ca9ff5 100644
--- a/theming-extras/build.gradle
+++ b/theming-extras/build.gradle
@@ -34,6 +34,7 @@ dependencies {
implementation project(':common')
implementation project(':animation')
implementation project(':theming')
+ implementation libs.ephemeral.chroma
}
ext.designation = "core"
diff --git a/theming-extras/src/main/java/org/pushingpixels/radiance/theming/extras/api/skinpack/OfficeSilver2007Skin.java b/theming-extras/src/main/java/org/pushingpixels/radiance/theming/extras/api/skinpack/OfficeSilver2007Skin.java
index 347ec98c1..db1e41013 100644
--- a/theming-extras/src/main/java/org/pushingpixels/radiance/theming/extras/api/skinpack/OfficeSilver2007Skin.java
+++ b/theming-extras/src/main/java/org/pushingpixels/radiance/theming/extras/api/skinpack/OfficeSilver2007Skin.java
@@ -29,22 +29,24 @@
*/
package org.pushingpixels.radiance.theming.extras.api.skinpack;
-import org.pushingpixels.radiance.theming.api.ComponentState;
-import org.pushingpixels.radiance.theming.api.RadianceColorSchemeBundle;
-import org.pushingpixels.radiance.theming.api.RadianceSkin;
+import org.pushingpixels.ephemeral.chroma.hct.Hct;
+import org.pushingpixels.radiance.theming.api.*;
import org.pushingpixels.radiance.theming.api.RadianceThemingSlices.ColorSchemeAssociationKind;
import org.pushingpixels.radiance.theming.api.RadianceThemingSlices.DecorationAreaType;
-import org.pushingpixels.radiance.theming.api.colorscheme.ColorSchemeSingleColorQuery;
import org.pushingpixels.radiance.theming.api.colorscheme.ColorTransform;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
import org.pushingpixels.radiance.theming.api.painter.border.CompositeBorderPainter;
-import org.pushingpixels.radiance.theming.api.painter.border.DelegateFractionBasedBorderPainter;
-import org.pushingpixels.radiance.theming.api.painter.border.FractionBasedBorderPainter;
+import org.pushingpixels.radiance.theming.api.painter.border.DelegateFractionBasedTonalBorderPainter;
+import org.pushingpixels.radiance.theming.api.painter.border.FractionBasedTonalBorderPainter;
import org.pushingpixels.radiance.theming.api.painter.border.RadianceBorderPainter;
-import org.pushingpixels.radiance.theming.api.painter.decoration.FractionBasedDecorationPainter;
-import org.pushingpixels.radiance.theming.api.painter.fill.ClassicFillPainter;
-import org.pushingpixels.radiance.theming.api.painter.fill.FractionBasedFillPainter;
-import org.pushingpixels.radiance.theming.api.painter.overlay.BottomLineOverlayPainter;
+import org.pushingpixels.radiance.theming.api.painter.decoration.FractionBasedTonalDecorationPainter;
+import org.pushingpixels.radiance.theming.api.painter.fill.ClassicTonalFillPainter;
+import org.pushingpixels.radiance.theming.api.painter.fill.FractionBasedTonalFillPainter;
+import org.pushingpixels.radiance.theming.api.painter.overlay.BottomLineTonalOverlayPainter;
+import org.pushingpixels.radiance.theming.api.palette.ColorSchemeUtils;
+import org.pushingpixels.radiance.theming.api.palette.RadianceColorScheme2;
+import org.pushingpixels.radiance.theming.api.palette.TonalSkin;
import org.pushingpixels.radiance.theming.api.shaper.ClassicButtonShaper;
/**
@@ -53,7 +55,7 @@
*
* @author Kirill Grouchnikov
*/
-public class OfficeSilver2007Skin extends RadianceSkin {
+public class OfficeSilver2007Skin extends RadianceSkin implements TonalSkin {
/**
* Display name for this
skin.
*/
@@ -216,47 +218,97 @@ public OfficeSilver2007Skin() {
DecorationAreaType.PRIMARY_TITLE_PANE,
DecorationAreaType.SECONDARY_TITLE_PANE);
- this.addOverlayPainter(new BottomLineOverlayPainter(
- ColorSchemeSingleColorQuery.composite(ColorSchemeSingleColorQuery.FOREGROUND,
- ColorTransform.alpha(72))),
- DecorationAreaType.PRIMARY_TITLE_PANE,
- DecorationAreaType.SECONDARY_TITLE_PANE);
+ RadianceColorScheme2 officeSilverColorScheme =
+ ColorSchemeUtils.getLightTonalFidelityColorScheme(Hct.fromInt(0xFFC6CACF),
+ Hct.fromInt(0xFFE6EAEE), Hct.fromInt(0xFFF2F5F5));
+ RadianceColorSchemeBundle2 officeSilverDefaultBundle =
+ new RadianceColorSchemeBundle2(officeSilverColorScheme);
+
+ RadianceColorScheme2 rolloverScheme2 = ColorSchemeUtils.getLightTonalFidelityColorScheme(
+ Hct.fromInt(0xFFFFD111), Hct.fromInt(0xFFE6EAEE), Hct.fromInt(0xFFF2F5F5));
+ RadianceColorScheme2 selectedScheme2 = ColorSchemeUtils.getLightTonalFidelityColorScheme(
+ Hct.fromInt(0xFFFFB340), Hct.fromInt(0xFFE6EAEE), Hct.fromInt(0xFFF2F5F5));
+ RadianceColorScheme2 rolloverSelectedScheme2 = ColorSchemeUtils.getLightTonalFidelityColorScheme(
+ Hct.fromInt(0xFFFFA400), Hct.fromInt(0xFFE6EAEE), Hct.fromInt(0xFFF2F5F5));
+ RadianceColorScheme2 pressedScheme2 = ColorSchemeUtils.getLightTonalFidelityColorScheme(
+ Hct.fromInt(0xFFFF8C18), Hct.fromInt(0xFFE6EAEE), Hct.fromInt(0xFFF2F5F5));
+ RadianceColorScheme2 pressedSelectedScheme2 = ColorSchemeUtils.getLightTonalFidelityColorScheme(
+ Hct.fromInt(0xFFFF991C), Hct.fromInt(0xFFE6EAEE), Hct.fromInt(0xFFF2F5F5));;
+
+ // register state-specific color schemes on rollovers, presses and selections
+ officeSilverDefaultBundle.registerColorScheme(rolloverScheme2,
+ ComponentState.ROLLOVER_UNSELECTED);
+ officeSilverDefaultBundle.registerColorScheme(rolloverSelectedScheme2,
+ ComponentState.ROLLOVER_SELECTED);
+ officeSilverDefaultBundle.registerColorScheme(selectedScheme2,
+ ComponentState.SELECTED);
+ officeSilverDefaultBundle.registerColorScheme(pressedScheme2,
+ ComponentState.PRESSED_UNSELECTED);
+ officeSilverDefaultBundle.registerColorScheme(pressedSelectedScheme2,
+ ComponentState.PRESSED_SELECTED);
+
+ // register state-specific highlight color schemes on rollover and selections
+ officeSilverDefaultBundle.registerColorScheme(rolloverScheme2,
+ RadianceThemingSlices.ContainerColorTokensAssociationKind.HIGHLIGHT,
+ ComponentState.ROLLOVER_UNSELECTED);
+ officeSilverDefaultBundle.registerColorScheme(selectedScheme2,
+ RadianceThemingSlices.ContainerColorTokensAssociationKind.HIGHLIGHT,
+ ComponentState.SELECTED, ComponentState.ARMED, ComponentState.ROLLOVER_ARMED);
+ officeSilverDefaultBundle.registerColorScheme(rolloverSelectedScheme2,
+ RadianceThemingSlices.ContainerColorTokensAssociationKind.HIGHLIGHT,
+ ComponentState.ROLLOVER_SELECTED);
+
+ // marks
+ RadianceColorScheme2 markEnabledScheme2 = ColorSchemeUtils.getLightTonalFidelityColorScheme(
+ Hct.fromInt(0xFFFDD07C), Hct.fromInt(0xFFF1F3F3), Hct.fromInt(0xFFF2F5F5));
+ officeSilverDefaultBundle.registerColorScheme(markEnabledScheme2,
+ RadianceThemingSlices.ContainerColorTokensAssociationKind.MARK, ComponentState.ENABLED);
+
+ this.registerDecorationAreaSchemeBundle(officeSilverDefaultBundle,
+ RadianceThemingSlices.DecorationAreaType.NONE);
+
+ this.addOverlayPainter(new BottomLineTonalOverlayPainter(
+ ContainerColorTokensSingleColorQuery.composite(
+ ContainerColorTokensSingleColorQuery.CONTAINER_OUTLINE, ColorTransform.alpha(72))),
+ DecorationAreaType.PRIMARY_TITLE_PANE,
+ DecorationAreaType.SECONDARY_TITLE_PANE);
this.buttonShaper = new ClassicButtonShaper();
- this.fillPainter = new FractionBasedFillPainter("Office Silver 2007",
+ this.fillPainter = new FractionBasedTonalFillPainter("Office Silver 2007",
new float[] {0.0f, 0.49999f, 0.5f, 1.0f},
- new ColorSchemeSingleColorQuery[] {
- ColorSchemeSingleColorQuery.ULTRALIGHT,
- ColorSchemeSingleColorQuery.LIGHT,
- ColorSchemeSingleColorQuery.ULTRADARK,
- ColorSchemeSingleColorQuery.EXTRALIGHT});
+ new ContainerColorTokensSingleColorQuery[] {
+ ContainerColorTokensSingleColorQuery.CONTAINER_LOW,
+ ContainerColorTokensSingleColorQuery.CONTAINER_LOWEST,
+ ContainerColorTokensSingleColorQuery.CONTAINER,
+ ContainerColorTokensSingleColorQuery.CONTAINER_LOW});
- FractionBasedBorderPainter outerBorderPainter = new FractionBasedBorderPainter(
+ FractionBasedTonalBorderPainter outerBorderPainter = new FractionBasedTonalBorderPainter(
"Office Silver 2007 Outer", new float[] {0.0f, 0.5f, 1.0f},
- new ColorSchemeSingleColorQuery[] {
- ColorSchemeSingleColorQuery.LIGHT,
- ColorSchemeSingleColorQuery.ULTRADARK,
- ColorSchemeSingleColorQuery.MID});
- RadianceBorderPainter innerBorderPainter = new DelegateFractionBasedBorderPainter(
+ new ContainerColorTokensSingleColorQuery[] {
+ ContainerColorTokensSingleColorQuery.CONTAINER_LOW,
+ ContainerColorTokensSingleColorQuery.CONTAINER_HIGHEST,
+ ContainerColorTokensSingleColorQuery.CONTAINER
+ });
+ RadianceBorderPainter innerBorderPainter = new DelegateFractionBasedTonalBorderPainter(
"Office Silver 2007 Inner", outerBorderPainter,
new int[] {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
- scheme -> scheme.tint(0.8f));
+ scheme -> ColorSchemeUtils.tint(scheme, 0.8f));
this.borderPainter = new CompositeBorderPainter("Office Silver 2007",
outerBorderPainter, innerBorderPainter);
- this.decorationPainter = new FractionBasedDecorationPainter(
+ this.decorationPainter = new FractionBasedTonalDecorationPainter(
"Office Silver 2007",
new float[] {0.0f, 0.2499999f, 0.25f, 0.3f, 0.7f, 1.0f},
- new ColorSchemeSingleColorQuery[] {
- ColorSchemeSingleColorQuery.ULTRALIGHT,
- ColorSchemeSingleColorQuery.EXTRALIGHT,
- ColorSchemeSingleColorQuery.DARK,
- ColorSchemeSingleColorQuery.MID,
- ColorSchemeSingleColorQuery.LIGHT,
- ColorSchemeSingleColorQuery.ULTRALIGHT});
-
- this.highlightFillPainter = new ClassicFillPainter();
+ new ContainerColorTokensSingleColorQuery[] {
+ ContainerColorTokensSingleColorQuery.CONTAINER_LOWEST,
+ ContainerColorTokensSingleColorQuery.CONTAINER_LOW,
+ ContainerColorTokensSingleColorQuery.CONTAINER_HIGH,
+ ContainerColorTokensSingleColorQuery.CONTAINER,
+ ContainerColorTokensSingleColorQuery.CONTAINER_LOW,
+ ContainerColorTokensSingleColorQuery.CONTAINER_LOWEST});
+
+ this.highlightFillPainter = new ClassicTonalFillPainter();
}
@Override
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/RadianceColorSchemeBundle2.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/RadianceColorSchemeBundle2.java
index b849f40ae..23ad270d6 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/RadianceColorSchemeBundle2.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/RadianceColorSchemeBundle2.java
@@ -33,7 +33,10 @@
import org.pushingpixels.radiance.theming.api.palette.ExtendedContainerColorTokens;
import org.pushingpixels.radiance.theming.api.palette.RadianceColorScheme2;
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
/**
* Color scheme bundle. Defines the visual appearance of a single decoration area of a skin.
@@ -59,7 +62,7 @@ public class RadianceColorSchemeBundle2 {
* scheme. This map doesn't have to contain entries for all
* {@link ComponentState} instances.
*/
- private Map stateHighlightAlphaMap;
+ //private Map stateHighlightAlphaMap;
/**
* Maps from color scheme association kinds to the map of color schemes.
@@ -99,7 +102,7 @@ public RadianceColorSchemeBundle2(RadianceColorScheme2 mainColorScheme) {
this.mainColorScheme = mainColorScheme;
this.stateAlphaMap = new HashMap<>();
- this.stateHighlightAlphaMap = new HashMap<>();
+ //this.stateHighlightAlphaMap = new HashMap<>();
this.colorSchemeMap = new HashMap<>();
for (RadianceThemingSlices.ContainerColorTokensAssociationKind associationKind :
@@ -153,29 +156,29 @@ public void registerColorScheme(RadianceColorScheme2 stateColorScheme, Component
* @param states Component states. If null
, the specified color
* scheme will be applied for all states left unspecified.
*/
- public void registerHighlightColorScheme(RadianceColorScheme2 stateHighlightScheme, ComponentState... states) {
- if (stateHighlightScheme == null) {
- throw new IllegalArgumentException("Cannot pass null color scheme");
- }
- if ((states == null) || (states.length == 0)) {
- for (ComponentState state : ComponentState.getAllStates()) {
- if (this.colorSchemeMap.get(RadianceThemingSlices.ContainerColorTokensAssociationKind.HIGHLIGHT).containsKey(state)) {
- continue;
- }
- if (state.isDisabled()) {
- continue;
- }
- if (state == ComponentState.ENABLED) {
- continue;
- }
- this.colorSchemeMap.get(RadianceThemingSlices.ContainerColorTokensAssociationKind.HIGHLIGHT).put(state, stateHighlightScheme);
- }
- } else {
- for (ComponentState state : states) {
- this.colorSchemeMap.get(RadianceThemingSlices.ContainerColorTokensAssociationKind.HIGHLIGHT).put(state, stateHighlightScheme);
- }
- }
- }
+// public void registerHighlightColorScheme(RadianceColorScheme2 stateHighlightScheme, ComponentState... states) {
+// if (stateHighlightScheme == null) {
+// throw new IllegalArgumentException("Cannot pass null color scheme");
+// }
+// if ((states == null) || (states.length == 0)) {
+// for (ComponentState state : ComponentState.getAllStates()) {
+// if (this.colorSchemeMap.get(RadianceThemingSlices.ContainerColorTokensAssociationKind.HIGHLIGHT).containsKey(state)) {
+// continue;
+// }
+// if (state.isDisabled()) {
+// continue;
+// }
+// if (state == ComponentState.ENABLED) {
+// continue;
+// }
+// this.colorSchemeMap.get(RadianceThemingSlices.ContainerColorTokensAssociationKind.HIGHLIGHT).put(state, stateHighlightScheme);
+// }
+// } else {
+// for (ComponentState state : states) {
+// this.colorSchemeMap.get(RadianceThemingSlices.ContainerColorTokensAssociationKind.HIGHLIGHT).put(state, stateHighlightScheme);
+// }
+// }
+// }
/**
* Registers a highlight alpha channel value for the specific component states.
@@ -183,17 +186,17 @@ public void registerHighlightColorScheme(RadianceColorScheme2 stateHighlightSche
* @param alpha Highlight alpha channel value.
* @param states Component states.
*/
- public void registerHighlightAlpha(float alpha, ComponentState... states) {
- if ((states == null) || (states.length == 0)) {
- for (ComponentState state : ComponentState.getAllStates()) {
- this.stateHighlightAlphaMap.put(state, alpha);
- }
- } else {
- for (ComponentState state : states) {
- this.stateHighlightAlphaMap.put(state, alpha);
- }
- }
- }
+// public void registerHighlightAlpha(float alpha, ComponentState... states) {
+// if ((states == null) || (states.length == 0)) {
+// for (ComponentState state : ComponentState.getAllStates()) {
+// this.stateHighlightAlphaMap.put(state, alpha);
+// }
+// } else {
+// for (ComponentState state : states) {
+// this.stateHighlightAlphaMap.put(state, alpha);
+// }
+// }
+// }
/**
* Returns the color scheme of the specified component in the specified
@@ -212,7 +215,7 @@ public ContainerColorTokens getContainerTokens(ComponentState componentState,
RadianceColorScheme2 registered = this.colorSchemeMap.get(
RadianceThemingSlices.ContainerColorTokensAssociationKind.DEFAULT).get(componentState);
if (registered != null) {
- return componentState.isActive() ? registered.getContainerTokensForState(componentState)
+ return componentState.isActive() ? registered.getActiveContainerTokens()
: registered.getContainerTokens(inactiveContainerType);
}
@@ -251,9 +254,9 @@ public ContainerColorTokens getSystemContainerTokens(
}
}
- public boolean hasHighlightAlphaFor(ComponentState componentState) {
- return this.stateHighlightAlphaMap.containsKey(componentState);
- }
+// public boolean hasHighlightAlphaFor(ComponentState componentState) {
+// return this.stateHighlightAlphaMap.containsKey(componentState);
+// }
/**
* Returns the alpha channel of the highlight color schemes for the specified component state.
@@ -263,14 +266,14 @@ public boolean hasHighlightAlphaFor(ComponentState componentState) {
* @param componentState Component state.
* @return Highlight color scheme alpha channel.
*/
- public float getHighlightAlpha(ComponentState componentState) {
- Float registered = this.stateHighlightAlphaMap.get(componentState);
- if (registered != null) {
- return registered.floatValue();
- }
-
- return 1.0f;
- }
+// public float getHighlightAlpha(ComponentState componentState) {
+// Float registered = this.stateHighlightAlphaMap.get(componentState);
+// if (registered != null) {
+// return registered.floatValue();
+// }
+//
+// return 1.0f;
+// }
public boolean hasAlphaFor(ComponentState componentState) {
return this.stateAlphaMap.containsKey(componentState);
@@ -379,24 +382,32 @@ public ContainerColorTokens getContainerTokens(
RadianceColorScheme2 registered =
this.colorSchemeMap.get(associationKind).get(componentState);
if (registered != null) {
- return componentState.isActive() ? registered.getContainerTokensForState(componentState)
+ return componentState.isActive() ? registered.getActiveContainerTokens()
: registered.getContainerTokens(inactiveContainerType);
}
- // for now look for the best fit only on active states
- Map bestFitForState = this.bestFillMap.get(associationKind);
- if (!bestFitForState.containsKey(componentState)) {
- Collection registeredStates = this.colorSchemeMap.get(associationKind).keySet();
- bestFitForState.put(componentState, componentState.bestFit(registeredStates));
- }
- ComponentState bestFit = bestFitForState.get(componentState);
- if (bestFit != null) {
- registered = this.colorSchemeMap.get(associationKind).get(bestFit);
- if (registered != null)
- return componentState.isActive() ? registered.getContainerTokensForState(componentState)
- : registered.getContainerTokens(inactiveContainerType);
+ RadianceColorScheme2 enabledForAssociationKind =
+ this.colorSchemeMap.get(associationKind).get(ComponentState.ENABLED);
+ if (enabledForAssociationKind != null) {
+ return componentState.isActive()
+ ? enabledForAssociationKind.getContainerTokensForState(componentState)
+ : enabledForAssociationKind.getContainerTokens(inactiveContainerType);
}
+// // for now look for the best fit only on active states
+// Map bestFitForState = this.bestFillMap.get(associationKind);
+// if (!bestFitForState.containsKey(componentState)) {
+// Collection registeredStates = this.colorSchemeMap.get(associationKind).keySet();
+// bestFitForState.put(componentState, componentState.bestFit(registeredStates));
+// }
+// ComponentState bestFit = bestFitForState.get(componentState);
+// if (bestFit != null) {
+// registered = this.colorSchemeMap.get(associationKind).get(bestFit);
+// if (registered != null)
+// return componentState.isActive() ? registered.getContainerTokensForState(componentState)
+// : registered.getContainerTokens(inactiveContainerType);
+// }
+
if (!allowFallback) {
return null;
}
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/ContainerColorTokensSingleColorQuery.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/colorscheme/ContainerColorTokensSingleColorQuery.java
similarity index 85%
rename from theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/ContainerColorTokensSingleColorQuery.java
rename to theming/src/main/java/org/pushingpixels/radiance/theming/api/colorscheme/ContainerColorTokensSingleColorQuery.java
index 12dddb7d5..fe74751f5 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/ContainerColorTokensSingleColorQuery.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/colorscheme/ContainerColorTokensSingleColorQuery.java
@@ -27,7 +27,9 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-package org.pushingpixels.radiance.theming.api.palette;
+package org.pushingpixels.radiance.theming.api.colorscheme;
+
+import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokens;
import java.awt.*;
@@ -56,4 +58,14 @@ public interface ContainerColorTokensSingleColorQuery {
ContainerColorTokensSingleColorQuery CONTAINER_OUTLINE_VARIANT = (colorTokens) ->
colorTokens.getContainerOutlineVariant();
+ static ContainerColorTokensSingleColorQuery composite(
+ ContainerColorTokensSingleColorQuery base, ColorTransform... transforms) {
+ return colorTokens -> {
+ Color result = base.query(colorTokens);
+ for (ColorTransform transform: transforms) {
+ result = transform.transform(result);
+ }
+ return result;
+ };
+ }
}
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/colorscheme/ContainerColorTokensTransform.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/colorscheme/ContainerColorTokensTransform.java
new file mode 100644
index 000000000..81b1a6d4e
--- /dev/null
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/colorscheme/ContainerColorTokensTransform.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005-2025 Radiance Kirill Grouchnikov. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * o Neither the name of the copyright holder nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.pushingpixels.radiance.theming.api.colorscheme;
+
+import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokens;
+
+/**
+ * Defines a transformation on a color scheme.
+ *
+ * @author Kirill Grouchnikov
+ */
+@FunctionalInterface
+public interface ContainerColorTokensTransform {
+ /**
+ * Transforms the specified color tokens.
+ *
+ * @param containerColorTokens
+ * The original color tokens to transform.
+ * @return The transformed color tokens.
+ */
+ ContainerColorTokens transform(ContainerColorTokens containerColorTokens);
+}
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/FractionBasedTonalPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/FractionBasedTonalPainter.java
index 9c8929ff4..c9220d25e 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/FractionBasedTonalPainter.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/FractionBasedTonalPainter.java
@@ -30,8 +30,8 @@
package org.pushingpixels.radiance.theming.api.painter;
import org.pushingpixels.radiance.theming.api.colorscheme.ColorSchemeSingleColorQuery;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
-import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.api.trait.RadianceTrait;
/**
@@ -132,10 +132,11 @@ public float[] getFractions() {
*
* @return Color queries of this painter.
*/
- public ColorSchemeSingleColorQuery[] getColorQueries() {
- ColorSchemeSingleColorQuery[] result = new ColorSchemeSingleColorQuery[this.colorQueries.length];
+ public ContainerColorTokensSingleColorQuery[] getColorQueries() {
+ ContainerColorTokensSingleColorQuery[] result =
+ new ContainerColorTokensSingleColorQuery[this.colorQueries.length];
System.arraycopy(this.colorQueries, 0, result, 0,
- this.colorQueries.length);
+ this.colorQueries.length);
return result;
}
}
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/ClassicTonalBorderPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/ClassicTonalBorderPainter.java
index bea11bb80..708e3f2df 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/ClassicTonalBorderPainter.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/ClassicTonalBorderPainter.java
@@ -29,7 +29,7 @@
*/
package org.pushingpixels.radiance.theming.api.painter.border;
-import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokensSingleColorQuery;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
/**
* Border painter that draws visuals with classic appearance. This class is
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/CompositeBorderPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/CompositeBorderPainter.java
index fab1a3fbb..e888914ab 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/CompositeBorderPainter.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/CompositeBorderPainter.java
@@ -30,6 +30,7 @@
package org.pushingpixels.radiance.theming.api.painter.border;
import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
+import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokens;
import java.awt.*;
@@ -81,12 +82,21 @@ public boolean isPaintingInnerContour() {
public void paintBorder(Graphics g, Component c, float width, float height,
Shape contour, Shape innerContour, RadianceColorScheme borderScheme) {
if (innerContour != null) {
- this.inner.paintBorder(g, c, width, height, innerContour, null,
- borderScheme);
+ this.inner.paintBorder(g, c, width, height, innerContour, null, borderScheme);
}
if (contour != null) {
- this.outer.paintBorder(g, c, width, height, contour, null,
- borderScheme);
+ this.outer.paintBorder(g, c, width, height, contour, null, borderScheme);
+ }
+ }
+
+ @Override
+ public void paintBorder(Graphics g, Component c, float width, float height, Shape contour,
+ Shape innerContour, ContainerColorTokens colorTokens) {
+ if (innerContour != null) {
+ this.inner.paintBorder(g, c, width, height, innerContour, null, colorTokens);
+ }
+ if (contour != null) {
+ this.outer.paintBorder(g, c, width, height, contour, null, colorTokens);
}
}
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/DelegateFractionBasedTonalBorderPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/DelegateFractionBasedTonalBorderPainter.java
new file mode 100644
index 000000000..51bba4296
--- /dev/null
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/DelegateFractionBasedTonalBorderPainter.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2005-2025 Radiance Kirill Grouchnikov. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * o Neither the name of the copyright holder nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.pushingpixels.radiance.theming.api.painter.border;
+
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensTransform;
+import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
+import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokens;
+import org.pushingpixels.radiance.theming.internal.utils.HashMapKey;
+import org.pushingpixels.radiance.theming.internal.utils.LazyResettableHashMap;
+import org.pushingpixels.radiance.theming.internal.utils.RadianceCoreUtilities;
+import org.pushingpixels.radiance.theming.internal.utils.RadianceInternalArrowButton;
+
+import java.awt.*;
+import java.awt.MultipleGradientPaint.CycleMethod;
+
+/**
+ * Delegate border painter that allows tweaking the visual appearance of
+ * borders.
+ *
+ * @author Kirill Grouchnikov
+ */
+public class DelegateFractionBasedTonalBorderPainter implements RadianceBorderPainter {
+ /**
+ * Display name of this border painter.
+ */
+ protected String displayName;
+
+ /**
+ * The delegate border painter.
+ */
+ protected FractionBasedTonalBorderPainter delegate;
+
+ /**
+ * 8-digit hexadecimal masks applied on the colors painted by
+ * {@link #delegate}. Can be used to apply custom translucency. For example,
+ * value 0x80FFFFFF will result in 50% translucency of the original border
+ * color.
+ */
+ protected int[] masks;
+
+ /**
+ * Transformation to be applied on the color schemes prior to compute the
+ * colors to be used for border painting.
+ */
+ protected ContainerColorTokensTransform transform;
+
+ /**
+ * Creates a new delegate border painter
+ *
+ * @param displayName
+ * Display name of this border painter.
+ * @param delegate
+ * The delegate border painter.
+ * @param masks
+ * Array of 8-digit hexadecimal masks applied on the relevant
+ * colors painted by the delegate
.
+ * @param transform
+ * Transformation to be applied on the color schemes prior to
+ * compute the colors to be used for border painting.
+ */
+ public DelegateFractionBasedTonalBorderPainter(String displayName,
+ FractionBasedTonalBorderPainter delegate, int[] masks,
+ ContainerColorTokensTransform transform) {
+
+ this.displayName = displayName;
+ this.delegate = delegate;
+ this.masks = new int[masks.length];
+ System.arraycopy(masks, 0, this.masks, 0, masks.length);
+ this.transform = transform;
+ }
+
+ /**
+ * Map of transformed color tokens (to speed up the subsequent lookups).
+ */
+ protected final static LazyResettableHashMap transformMap =
+ new LazyResettableHashMap<>("DelegateFractionBasedTonalBorderPainter");
+
+ @Override
+ public boolean isPaintingInnerContour() {
+ return false;
+ }
+
+ @Override
+ public void paintBorder(Graphics g, Component c, float width, float height, Shape contour,
+ Shape innerContour, ContainerColorTokens colorTokens) {
+ Graphics2D graphics = (Graphics2D) g.create();
+
+ // shift color tokens
+ ContainerColorTokens shifted = getShiftColorTokens(colorTokens);
+
+ float[] fractions = delegate.getFractions();
+ ContainerColorTokensSingleColorQuery[] colorQueries = delegate.getColorQueries();
+ Color[] fillColors = new Color[fractions.length];
+ for (int i = 0; i < fractions.length; i++) {
+ ContainerColorTokensSingleColorQuery colorQuery = colorQueries[i];
+ Color color = colorQuery.query(shifted);
+ // apply masks
+ color = new Color(this.masks[i] & color.getRGB(), true);
+ fillColors[i] = color;
+ }
+
+ // issue 433 - the "c" can be null when painting
+ // the border of a tree icon used outside the
+ // JTree context.
+ boolean isSpecialButton = (c != null) && c.getClass()
+ .isAnnotationPresent(RadianceInternalArrowButton.class);
+ int joinKind = isSpecialButton ? BasicStroke.JOIN_MITER : BasicStroke.JOIN_ROUND;
+ int capKind = isSpecialButton ? BasicStroke.CAP_SQUARE : BasicStroke.CAP_BUTT;
+ graphics.setStroke(new BasicStroke(1.0f, capKind, joinKind));
+
+ MultipleGradientPaint gradient = new LinearGradientPaint(0, 0, 0, height, fractions,
+ fillColors, CycleMethod.REPEAT);
+ graphics.setPaint(gradient);
+ graphics.draw(contour);
+ graphics.dispose();
+ }
+
+ @Override
+ public void paintBorder(Graphics g, Component c, float width, float height, Shape contour,
+ Shape innerContour, RadianceColorScheme borderScheme) {
+
+ }
+
+ @Override
+ public String getDisplayName() {
+ return this.displayName;
+ }
+
+ /**
+ * Retrieves a transformed color scheme.
+ *
+ * @param orig
+ * Original color scheme.
+ * @return Transformed color scheme.
+ */
+ private ContainerColorTokens getShiftColorTokens(ContainerColorTokens orig) {
+ HashMapKey key = RadianceCoreUtilities.getHashKey(orig.hashCode(),
+ this.getDisplayName(), this.transform);
+ ContainerColorTokens result = transformMap.get(key);
+ if (result == null) {
+ result = this.transform.transform(orig);
+ transformMap.put(key, result);
+ }
+ return result;
+ }
+
+ @Override
+ public Color getRepresentativeColor(RadianceColorScheme borderScheme) {
+ return Color.BLACK;
+ }
+}
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/FractionBasedTonalBorderPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/FractionBasedTonalBorderPainter.java
index 837d039d7..e791f2fd0 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/FractionBasedTonalBorderPainter.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/border/FractionBasedTonalBorderPainter.java
@@ -29,10 +29,10 @@
*/
package org.pushingpixels.radiance.theming.api.painter.border;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
import org.pushingpixels.radiance.theming.api.painter.FractionBasedTonalPainter;
import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokens;
-import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.internal.utils.RadianceInternalArrowButton;
import java.awt.*;
@@ -66,7 +66,8 @@ public FractionBasedTonalBorderPainter(String displayName, float[] fractions,
}
@Override
- public void paintBorder(Graphics g, Component c, float width, float height, Shape contour, Shape innerContour, ContainerColorTokens colorTokens) {
+ public void paintBorder(Graphics g, Component c, float width, float height, Shape contour,
+ Shape innerContour, ContainerColorTokens colorTokens) {
if (contour == null)
return;
@@ -95,7 +96,8 @@ public void paintBorder(Graphics g, Component c, float width, float height, Shap
}
@Override
- public void paintBorder(Graphics g, Component c, float width, float height, Shape contour, Shape innerContour, RadianceColorScheme borderScheme) {
+ public void paintBorder(Graphics g, Component c, float width, float height, Shape contour,
+ Shape innerContour, RadianceColorScheme borderScheme) {
}
@Override
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/FractionBasedDecorationPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/FractionBasedDecorationPainter.java
index e38b99493..508d5d64c 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/FractionBasedDecorationPainter.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/FractionBasedDecorationPainter.java
@@ -29,8 +29,8 @@
*/
package org.pushingpixels.radiance.theming.api.painter.decoration;
-import org.pushingpixels.radiance.theming.api.RadianceThemingSlices;
import org.pushingpixels.radiance.theming.api.RadianceSkin;
+import org.pushingpixels.radiance.theming.api.RadianceThemingSlices;
import org.pushingpixels.radiance.theming.api.colorscheme.ColorSchemeSingleColorQuery;
import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
import org.pushingpixels.radiance.theming.api.painter.FractionBasedPainter;
@@ -39,6 +39,7 @@
import javax.swing.*;
import java.awt.*;
import java.awt.MultipleGradientPaint.CycleMethod;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -96,16 +97,14 @@ public FractionBasedDecorationPainter(String displayName,
super(displayName, fractions, colorQueries);
this.decoratedAreas = new HashSet<>();
if (decorationAreas != null) {
- for (RadianceThemingSlices.DecorationAreaType decorationArea : decorationAreas) {
- this.decoratedAreas.add(decorationArea);
- }
+ this.decoratedAreas.addAll(Arrays.asList(decorationAreas));
}
}
@Override
public void paintDecorationArea(Graphics2D graphics, Component comp,
- RadianceThemingSlices.DecorationAreaType decorationAreaType, int width, int height,
- RadianceSkin skin) {
+ RadianceThemingSlices.DecorationAreaType decorationAreaType, int width, int height,
+ RadianceSkin skin) {
RadianceColorScheme colorScheme = skin.getBackgroundColorScheme(decorationAreaType);
if (this.decoratedAreas.contains(decorationAreaType)) {
this.paintDecoratedBackground(graphics, comp, decorationAreaType,
@@ -116,8 +115,9 @@ public void paintDecorationArea(Graphics2D graphics, Component comp,
}
@Override
- public void paintDecorationArea(Graphics2D graphics, Component comp, RadianceThemingSlices.DecorationAreaType
- decorationAreaType, Shape contour, RadianceColorScheme colorScheme) {
+ public void paintDecorationArea(Graphics2D graphics, Component comp,
+ RadianceThemingSlices.DecorationAreaType decorationAreaType, Shape contour,
+ RadianceColorScheme colorScheme) {
if (this.decoratedAreas.contains(decorationAreaType)) {
this.paintDecoratedBackground(graphics, comp, decorationAreaType,
contour, colorScheme);
@@ -127,8 +127,8 @@ public void paintDecorationArea(Graphics2D graphics, Component comp, RadianceThe
}
private void paintDecoratedBackground(Graphics2D graphics, Component comp,
- RadianceThemingSlices.DecorationAreaType decorationAreaType, int width, int height,
- RadianceColorScheme scheme) {
+ RadianceThemingSlices.DecorationAreaType decorationAreaType, int width, int height,
+ RadianceColorScheme scheme) {
Graphics2D g2d = (Graphics2D) graphics.create();
Color[] fillColors = new Color[this.fractions.length];
for (int i = 0; i < this.fractions.length; i++) {
@@ -154,8 +154,8 @@ private void paintDecoratedBackground(Graphics2D graphics, Component comp,
}
private void paintDecoratedBackground(Graphics2D graphics, Component comp,
- RadianceThemingSlices.DecorationAreaType decorationAreaType, Shape contour,
- RadianceColorScheme scheme) {
+ RadianceThemingSlices.DecorationAreaType decorationAreaType, Shape contour,
+ RadianceColorScheme scheme) {
Graphics2D g2d = (Graphics2D) graphics.create();
Color[] fillColors = new Color[this.fractions.length];
for (int i = 0; i < this.fractions.length; i++) {
@@ -180,14 +180,12 @@ private void paintDecoratedBackground(Graphics2D graphics, Component comp,
g2d.dispose();
}
- private void paintSolidBackground(Graphics2D graphics,
- int width, int height, RadianceColorScheme scheme) {
+ private void paintSolidBackground(Graphics2D graphics, int width, int height, RadianceColorScheme scheme) {
graphics.setColor(scheme.getMidColor());
graphics.fillRect(0, 0, width, height);
}
- private void paintSolidBackground(Graphics2D graphics,
- Shape contour, RadianceColorScheme scheme) {
+ private void paintSolidBackground(Graphics2D graphics, Shape contour, RadianceColorScheme scheme) {
graphics.setColor(scheme.getMidColor());
graphics.fill(contour);
}
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/FractionBasedTonalDecorationPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/FractionBasedTonalDecorationPainter.java
new file mode 100644
index 000000000..6bec1c4f1
--- /dev/null
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/FractionBasedTonalDecorationPainter.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2005-2025 Radiance Kirill Grouchnikov. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * o Neither the name of the copyright holder nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.pushingpixels.radiance.theming.api.painter.decoration;
+
+import org.pushingpixels.radiance.theming.api.RadianceSkin;
+import org.pushingpixels.radiance.theming.api.RadianceThemingSlices;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
+import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
+import org.pushingpixels.radiance.theming.api.painter.FractionBasedTonalPainter;
+import org.pushingpixels.radiance.theming.api.palette.ExtendedContainerColorTokens;
+import org.pushingpixels.radiance.theming.internal.utils.RadianceCoreUtilities;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.MultipleGradientPaint.CycleMethod;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Decoration painter with fraction-based stops and a color query associated
+ * with each stop. This class allows creating multi-gradient decorations with
+ * exact control over which color is used at every gradient control point.
+ *
+ * @author Kirill Grouchnikov
+ */
+public class FractionBasedTonalDecorationPainter extends FractionBasedTonalPainter
+ implements RadianceDecorationPainter {
+ private Set decoratedAreas;
+
+ /**
+ * Creates a new fraction-based decoration painter.
+ *
+ * @param displayName
+ * The display name of this painter.
+ * @param fractions
+ * The fractions of this painter. Must be strictly increasing,
+ * starting from 0.0 and ending at 1.0.
+ * @param colorQueries
+ * The color queries of this painter. Must have the same size as
+ * the fractions array, and all entries must be non-
+ * null
.
+ */
+ public FractionBasedTonalDecorationPainter(String displayName,
+ float[] fractions, ContainerColorTokensSingleColorQuery[] colorQueries) {
+ this(displayName, fractions, colorQueries,
+ RadianceThemingSlices.DecorationAreaType.PRIMARY_TITLE_PANE,
+ RadianceThemingSlices.DecorationAreaType.SECONDARY_TITLE_PANE);
+ }
+
+ /**
+ * Creates a new fraction-based decoration painter.
+ *
+ * @param displayName
+ * The display name of this painter.
+ * @param fractions
+ * The fractions of this painter. Must be strictly increasing,
+ * starting from 0.0 and ending at 1.0.
+ * @param colorQueries
+ * The color queries of this painter. Must have the same size as
+ * the fractions array, and all entries must be non-
+ * null
.
+ * @param decorationAreas
+ * Decoration areas that should be painted based on the color
+ * queries. All the rest will be filled with a solid color from
+ * the background color scheme of the matching decoration area.
+ */
+ public FractionBasedTonalDecorationPainter(String displayName,
+ float[] fractions, ContainerColorTokensSingleColorQuery[] colorQueries,
+ RadianceThemingSlices.DecorationAreaType... decorationAreas) {
+ super(displayName, fractions, colorQueries);
+ this.decoratedAreas = new HashSet<>();
+ if (decorationAreas != null) {
+ this.decoratedAreas.addAll(Arrays.asList(decorationAreas));
+ }
+ }
+
+ @Override
+ public void paintDecorationArea(Graphics2D graphics, Component comp,
+ RadianceThemingSlices.DecorationAreaType decorationAreaType, int width, int height,
+ RadianceSkin skin) {
+ ExtendedContainerColorTokens colorTokens =
+ skin.getBackgroundExtendedContainerTokens(decorationAreaType);
+ if (this.decoratedAreas.contains(decorationAreaType)) {
+ this.paintDecoratedBackground(graphics, comp, decorationAreaType,
+ width, height, colorTokens);
+ } else {
+ this.paintSolidBackground(graphics, width, height, colorTokens);
+ }
+ }
+
+ @Override
+ public void paintDecorationArea(Graphics2D graphics, Component comp,
+ RadianceThemingSlices.DecorationAreaType decorationAreaType, Shape contour,
+ RadianceColorScheme colorScheme) {
+ }
+
+ @Override
+ public void paintDecorationArea(Graphics2D graphics, Component comp,
+ RadianceThemingSlices.DecorationAreaType decorationAreaType, Shape contour,
+ ExtendedContainerColorTokens colorTokens) {
+
+ if (this.decoratedAreas.contains(decorationAreaType)) {
+ this.paintDecoratedBackground(graphics, comp, decorationAreaType,
+ contour, colorTokens);
+ } else {
+ this.paintSolidBackground(graphics, contour, colorTokens);
+ }
+ }
+
+ private void paintDecoratedBackground(Graphics2D graphics, Component comp,
+ RadianceThemingSlices.DecorationAreaType decorationAreaType, int width, int height,
+ ExtendedContainerColorTokens colorTokens) {
+
+ Graphics2D g2d = (Graphics2D) graphics.create();
+ Color[] fillColors = new Color[this.fractions.length];
+ for (int i = 0; i < this.fractions.length; i++) {
+ ContainerColorTokensSingleColorQuery colorQuery = this.colorQueries[i];
+ fillColors[i] = colorQuery.query(colorTokens.getBaseContainerTokens());
+ }
+
+ Component topMostWithSameDecorationAreaType = RadianceCoreUtilities
+ .getTopMostParentWithDecorationAreaType(comp,
+ decorationAreaType);
+ Point inTopMost = SwingUtilities.convertPoint(comp, new Point(0, 0),
+ topMostWithSameDecorationAreaType);
+ int dy = inTopMost.y;
+
+ MultipleGradientPaint gradient = new LinearGradientPaint(0, 0, 0,
+ topMostWithSameDecorationAreaType.getHeight(), this.fractions,
+ fillColors, CycleMethod.REPEAT);
+ g2d.setPaint(gradient);
+ g2d.translate(0, -dy);
+ g2d.fillRect(0, 0, width, topMostWithSameDecorationAreaType.getHeight());
+
+ g2d.dispose();
+ }
+
+ private void paintDecoratedBackground(Graphics2D graphics, Component comp,
+ RadianceThemingSlices.DecorationAreaType decorationAreaType, Shape contour,
+ ExtendedContainerColorTokens colorTokens) {
+
+ Graphics2D g2d = (Graphics2D) graphics.create();
+ Color[] fillColors = new Color[this.fractions.length];
+ for (int i = 0; i < this.fractions.length; i++) {
+ ContainerColorTokensSingleColorQuery colorQuery = this.colorQueries[i];
+ fillColors[i] = colorQuery.query(colorTokens.getBaseContainerTokens());
+ }
+
+ Component topMostWithSameDecorationAreaType = RadianceCoreUtilities
+ .getTopMostParentWithDecorationAreaType(comp,
+ decorationAreaType);
+ Point inTopMost = SwingUtilities.convertPoint(comp, new Point(0, 0),
+ topMostWithSameDecorationAreaType);
+ int dy = inTopMost.y;
+
+ MultipleGradientPaint gradient = new LinearGradientPaint(0, 0, 0,
+ topMostWithSameDecorationAreaType.getHeight(), this.fractions,
+ fillColors, CycleMethod.REPEAT);
+ g2d.setPaint(gradient);
+ g2d.translate(0, -dy);
+ g2d.fill(contour);
+
+ g2d.dispose();
+ }
+
+ private void paintSolidBackground(Graphics2D graphics, int width, int height,
+ ExtendedContainerColorTokens colorTokens) {
+
+ graphics.setColor(colorTokens.getBaseContainerTokens().getContainerSurface());
+ graphics.fillRect(0, 0, width, height);
+ }
+
+ private void paintSolidBackground(Graphics2D graphics, Shape contour,
+ ExtendedContainerColorTokens colorTokens) {
+
+ graphics.setColor(colorTokens.getBaseContainerTokens().getContainerSurface());
+ graphics.fill(contour);
+ }
+}
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/MatteDecorationPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/MatteDecorationPainter.java
index 8978fcbbd..d476723ec 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/MatteDecorationPainter.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/decoration/MatteDecorationPainter.java
@@ -168,10 +168,8 @@ protected void fill(Graphics2D graphics, ExtendedContainerColorTokens colorToken
// 0 - flex : light -> medium
// flex - : medium fill
- Color startColor = colorTokens.getBaseContainerTokens()
- .getContainerSurfaceLowest();
- Color endColor = colorTokens.getBaseContainerTokens()
- .getContainerSurface();
+ Color startColor = colorTokens.getBaseContainerTokens().getContainerSurfaceLowest();
+ Color endColor = colorTokens.getBaseContainerTokens().getContainerSurface();
int gradientHeight = Math.max(FLEX_POINT, height + offsetY);
Paint paint = (gradientHeight == FLEX_POINT) ?
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/ClassicTonalFillPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/ClassicTonalFillPainter.java
index 8222a73df..573a902cd 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/ClassicTonalFillPainter.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/ClassicTonalFillPainter.java
@@ -29,7 +29,7 @@
*/
package org.pushingpixels.radiance.theming.api.painter.fill;
-import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokensSingleColorQuery;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
/**
* Fill painter that draws visuals with classic appearance. This class is part
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/FractionBasedTonalFillPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/FractionBasedTonalFillPainter.java
index 235e47ceb..4cd7ed356 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/FractionBasedTonalFillPainter.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/FractionBasedTonalFillPainter.java
@@ -29,10 +29,10 @@
*/
package org.pushingpixels.radiance.theming.api.painter.fill;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
import org.pushingpixels.radiance.theming.api.painter.FractionBasedTonalPainter;
import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokens;
-import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokensSingleColorQuery;
import java.awt.*;
import java.awt.MultipleGradientPaint.CycleMethod;
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/GlassTonalFillPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/GlassTonalFillPainter.java
index 58dd4cfad..25e45754b 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/GlassTonalFillPainter.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/fill/GlassTonalFillPainter.java
@@ -29,7 +29,7 @@
*/
package org.pushingpixels.radiance.theming.api.painter.fill;
-import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokensSingleColorQuery;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
/**
* Fill painter that draws visuals with glass appearance. This class is part
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/overlay/BottomLineTonalOverlayPainter.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/overlay/BottomLineTonalOverlayPainter.java
index d90a72b6f..cec2c3810 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/overlay/BottomLineTonalOverlayPainter.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/painter/overlay/BottomLineTonalOverlayPainter.java
@@ -32,7 +32,7 @@
import org.pushingpixels.radiance.common.api.RadianceCommonCortex;
import org.pushingpixels.radiance.theming.api.RadianceSkin;
import org.pushingpixels.radiance.theming.api.RadianceThemingSlices;
-import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokensSingleColorQuery;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.api.palette.ExtendedContainerColorTokens;
import org.pushingpixels.radiance.theming.internal.utils.RadianceColorUtilities;
import org.pushingpixels.radiance.theming.internal.utils.RadianceCoreUtilities;
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/ColorSchemeUtils.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/ColorSchemeUtils.java
index 4e19d9675..df4f3ba39 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/ColorSchemeUtils.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/ColorSchemeUtils.java
@@ -29,6 +29,7 @@
*/
package org.pushingpixels.radiance.theming.api.palette;
+import org.pushingpixels.ephemeral.chroma.blend.Blend;
import org.pushingpixels.ephemeral.chroma.dynamiccolor.DynamicScheme;
import org.pushingpixels.ephemeral.chroma.hct.Hct;
import org.pushingpixels.ephemeral.chroma.palettes.TonalPalette;
@@ -193,6 +194,13 @@ public ContainerColorTokens getPrimaryContainerTokens() {
return primaryContainerTokens;
}
+ @Override
+ public ContainerColorTokens getActiveContainerTokens() {
+ return (activeStatesContainerType == ActiveStatesContainerType.PRIMARY)
+ ? this.getPrimaryContainerTokens()
+ : this.getTonalContainerTokens();
+ }
+
@Override
public ContainerColorTokens getContainerTokensForState(ComponentState componentState) {
if (componentState.isDisabled()) {
@@ -200,11 +208,7 @@ public ContainerColorTokens getContainerTokensForState(ComponentState componentS
return getContainerTokensForState(componentState.getEnabledMatch());
}
- // TODO: TONAL - configurable at the skin definition level
- ContainerColorTokens defaultActive =
- (activeStatesContainerType == ActiveStatesContainerType.PRIMARY)
- ? this.getPrimaryContainerTokens()
- : this.getTonalContainerTokens();
+ ContainerColorTokens defaultActive = getActiveContainerTokens();
if ((componentState == ComponentState.PRESSED_UNSELECTED) ||
(componentState == ComponentState.ARMED)) {
if (!stateTokens.containsKey(componentState)) {
@@ -362,6 +366,13 @@ public ContainerColorTokens getPrimaryContainerTokens() {
return primaryContainerTokens;
}
+ @Override
+ public ContainerColorTokens getActiveContainerTokens() {
+ return (activeStatesContainerType == ActiveStatesContainerType.PRIMARY)
+ ? this.getPrimaryContainerTokens()
+ : this.getTonalContainerTokens();
+ }
+
@Override
public ContainerColorTokens getContainerTokensForState(ComponentState componentState) {
if (componentState.isDisabled()) {
@@ -369,11 +380,7 @@ public ContainerColorTokens getContainerTokensForState(ComponentState componentS
return getContainerTokensForState(componentState.getEnabledMatch());
}
- // TODO: TONAL - configurable at the skin definition level
- ContainerColorTokens defaultActive =
- (activeStatesContainerType == ActiveStatesContainerType.PRIMARY)
- ? this.getPrimaryContainerTokens()
- : this.getTonalContainerTokens();
+ ContainerColorTokens defaultActive = getActiveContainerTokens();
if ((componentState == ComponentState.PRESSED_UNSELECTED) ||
(componentState == ComponentState.ARMED)) {
if (!stateTokens.containsKey(componentState)) {
@@ -820,4 +827,82 @@ public static RadianceColorScheme2 getDarkPrimaryFidelityColorScheme(
return result;
}
+
+ public static ContainerColorTokens tint(ContainerColorTokens original, float tintFactor) {
+ return new ContainerColorTokens() {
+ @Override
+ public boolean isDark() {
+ return original.isDark();
+ }
+
+ @Override
+ public Color getContainerSurfaceLowest() {
+ return new Color(Blend.hctHue(original.getContainerSurfaceLowest().getRGB(),
+ Color.WHITE.getRGB(), tintFactor));
+ }
+
+ @Override
+ public Color getContainerSurfaceLow() {
+ return new Color(Blend.hctHue(original.getContainerSurfaceLow().getRGB(),
+ Color.WHITE.getRGB(), tintFactor));
+ }
+
+ @Override
+ public Color getContainerSurface() {
+ return new Color(Blend.hctHue(original.getContainerSurface().getRGB(),
+ Color.WHITE.getRGB(), tintFactor));
+ }
+
+ @Override
+ public Color getContainerSurfaceHigh() {
+ return new Color(Blend.hctHue(original.getContainerSurfaceHigh().getRGB(),
+ Color.WHITE.getRGB(), tintFactor));
+ }
+
+ @Override
+ public Color getContainerSurfaceHighest() {
+ return new Color(Blend.hctHue(original.getContainerSurfaceHighest().getRGB(),
+ Color.WHITE.getRGB(), tintFactor));
+ }
+
+ @Override
+ public Color getOnContainer() {
+ return new Color(Blend.hctHue(original.getOnContainer().getRGB(),
+ Color.WHITE.getRGB(), tintFactor));
+ }
+
+ @Override
+ public Color getOnContainerVariant() {
+ return new Color(Blend.hctHue(original.getOnContainerVariant().getRGB(),
+ Color.WHITE.getRGB(), tintFactor));
+ }
+
+ @Override
+ public Color getContainerOutline() {
+ return new Color(Blend.hctHue(original.getContainerOutline().getRGB(),
+ Color.WHITE.getRGB(), tintFactor));
+ }
+
+ @Override
+ public Color getContainerOutlineVariant() {
+ return new Color(Blend.hctHue(original.getContainerOutlineVariant().getRGB(),
+ Color.WHITE.getRGB(), tintFactor));
+ }
+
+ @Override
+ public float getContainerSurfaceDisabledAlpha() {
+ return original.getContainerSurfaceDisabledAlpha();
+ }
+
+ @Override
+ public float getOnContainerDisabledAlpha() {
+ return original.getOnContainerDisabledAlpha();
+ }
+
+ @Override
+ public float getContainerOutlineDisabledAlpha() {
+ return original.getContainerOutlineDisabledAlpha();
+ }
+ };
+ }
}
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/RadianceColorScheme2.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/RadianceColorScheme2.java
index d9ea54673..d86499336 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/RadianceColorScheme2.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/palette/RadianceColorScheme2.java
@@ -49,6 +49,8 @@ public interface RadianceColorScheme2 {
ContainerColorTokens getPrimaryContainerTokens();
+ ContainerColorTokens getActiveContainerTokens();
+
ContainerColorTokens getContainerTokensForState(ComponentState componentState);
default ExtendedContainerColorTokens getExtendedContainerTokens(ComponentState componentState) {
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/BusinessAccentedTonalSkin.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/BusinessAccentedTonalSkin.java
index 2a3b587af..fd90a6b13 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/BusinessAccentedTonalSkin.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/BusinessAccentedTonalSkin.java
@@ -31,6 +31,7 @@
import org.pushingpixels.ephemeral.chroma.hct.Hct;
import org.pushingpixels.radiance.theming.api.*;
+import org.pushingpixels.radiance.theming.api.colorscheme.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
import org.pushingpixels.radiance.theming.api.painter.border.ClassicTonalBorderPainter;
import org.pushingpixels.radiance.theming.api.painter.decoration.ArcDecorationPainter;
@@ -40,7 +41,6 @@
import org.pushingpixels.radiance.theming.api.painter.overlay.BottomLineTonalOverlayPainter;
import org.pushingpixels.radiance.theming.api.painter.overlay.TopShadowOverlayPainter;
import org.pushingpixels.radiance.theming.api.palette.ColorSchemeUtils;
-import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.api.palette.RadianceColorScheme2;
import org.pushingpixels.radiance.theming.api.shaper.ClassicButtonShaper;
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/ModerateSkin.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/ModerateSkin.java
index 8e0160e7a..1adc3977d 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/ModerateSkin.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/ModerateSkin.java
@@ -31,10 +31,7 @@
import org.pushingpixels.ephemeral.chroma.hct.Hct;
import org.pushingpixels.radiance.theming.api.*;
-import org.pushingpixels.radiance.theming.api.colorscheme.ColorSchemeSingleColorQuery;
-import org.pushingpixels.radiance.theming.api.colorscheme.MetallicColorScheme;
-import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
-import org.pushingpixels.radiance.theming.api.colorscheme.SteelBlueColorScheme;
+import org.pushingpixels.radiance.theming.api.colorscheme.*;
import org.pushingpixels.radiance.theming.api.painter.border.ClassicBorderPainter;
import org.pushingpixels.radiance.theming.api.painter.border.ClassicTonalBorderPainter;
import org.pushingpixels.radiance.theming.api.painter.decoration.MatteDecorationPainter;
@@ -43,7 +40,6 @@
import org.pushingpixels.radiance.theming.api.painter.overlay.BottomLineTonalOverlayPainter;
import org.pushingpixels.radiance.theming.api.painter.overlay.TopShadowOverlayPainter;
import org.pushingpixels.radiance.theming.api.palette.ColorSchemeUtils;
-import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.api.palette.RadianceColorScheme2;
import org.pushingpixels.radiance.theming.api.palette.TonalSkin;
import org.pushingpixels.radiance.theming.api.shaper.ClassicButtonShaper;
diff --git a/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/SaharaSkin.java b/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/SaharaSkin.java
index 4ae8ae4e1..185f88697 100644
--- a/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/SaharaSkin.java
+++ b/theming/src/main/java/org/pushingpixels/radiance/theming/api/skin/SaharaSkin.java
@@ -31,10 +31,7 @@
import org.pushingpixels.ephemeral.chroma.hct.Hct;
import org.pushingpixels.radiance.theming.api.*;
-import org.pushingpixels.radiance.theming.api.colorscheme.ColorSchemeSingleColorQuery;
-import org.pushingpixels.radiance.theming.api.colorscheme.DesertSandColorScheme;
-import org.pushingpixels.radiance.theming.api.colorscheme.MetallicColorScheme;
-import org.pushingpixels.radiance.theming.api.colorscheme.RadianceColorScheme;
+import org.pushingpixels.radiance.theming.api.colorscheme.*;
import org.pushingpixels.radiance.theming.api.painter.border.ClassicBorderPainter;
import org.pushingpixels.radiance.theming.api.painter.border.ClassicTonalBorderPainter;
import org.pushingpixels.radiance.theming.api.painter.decoration.MatteDecorationPainter;
@@ -45,7 +42,6 @@
import org.pushingpixels.radiance.theming.api.painter.overlay.BottomLineTonalOverlayPainter;
import org.pushingpixels.radiance.theming.api.painter.overlay.TopShadowOverlayPainter;
import org.pushingpixels.radiance.theming.api.palette.ColorSchemeUtils;
-import org.pushingpixels.radiance.theming.api.palette.ContainerColorTokensSingleColorQuery;
import org.pushingpixels.radiance.theming.api.palette.RadianceColorScheme2;
import org.pushingpixels.radiance.theming.api.palette.TonalSkin;
import org.pushingpixels.radiance.theming.api.shaper.ClassicButtonShaper;