mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-29 00:55:32 +08:00
GP-1981 fixed Nimbus (yet again!) to update values. This time went all
the way to re-installing the LookAndFeel
This commit is contained in:
@@ -23,7 +23,6 @@ import java.util.function.Supplier;
|
|||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
|
|
||||||
import docking.theme.*;
|
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import generic.theme.*;
|
import generic.theme.*;
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.Settings;
|
||||||
@@ -194,13 +193,13 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
|||||||
return "<No Value>";
|
return "<No Value>";
|
||||||
}
|
}
|
||||||
if (resolvedColor.refId() != null) {
|
if (resolvedColor.refId() != null) {
|
||||||
return resolvedColor.refId();
|
return "[" + resolvedColor.refId() + "]";
|
||||||
}
|
}
|
||||||
Color color = resolvedColor.color();
|
Color color = resolvedColor.color();
|
||||||
String text = WebColors.toString(color, false);
|
String text = WebColors.toString(color, false);
|
||||||
String name = WebColors.toWebColorName(color);
|
String name = WebColors.toWebColorName(color);
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
text += " [" + name + "]";
|
text += " (" + name + ")";
|
||||||
}
|
}
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class ThemeDialog extends DialogComponentProvider {
|
|||||||
if (result == OptionDialog.YES_OPTION) {
|
if (result == OptionDialog.YES_OPTION) {
|
||||||
return ThemeUtils.saveThemeChanges();
|
return ThemeUtils.saveThemeChanges();
|
||||||
}
|
}
|
||||||
Gui.reloadGhidraDefaults();
|
Gui.restoreThemeValues();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,19 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getValueText(ResolvedFont resolvedFont) {
|
||||||
|
if (resolvedFont == null) {
|
||||||
|
return "<No Value>";
|
||||||
|
}
|
||||||
|
Font font = resolvedFont.font();
|
||||||
|
String fontString = ThemeWriter.fontToString(font);
|
||||||
|
|
||||||
|
if (resolvedFont.refId() != null) {
|
||||||
|
return "[" + resolvedFont.refId() + "]";//+ " [" + fontString + "]";
|
||||||
|
}
|
||||||
|
return fontString;
|
||||||
|
}
|
||||||
|
|
||||||
class IdColumn extends AbstractDynamicTableColumn<FontValue, String, Object> {
|
class IdColumn extends AbstractDynamicTableColumn<FontValue, String, Object> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -138,7 +151,7 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
|||||||
if (v2 == null) {
|
if (v2 == null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return v1.font().toString().compareTo(v2.font().toString());
|
return getValueText(v1).compareTo(getValueText(v2));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,19 +179,6 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
|||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getValueText(ResolvedFont resolvedFont) {
|
|
||||||
if (resolvedFont == null) {
|
|
||||||
return "<No Value>";
|
|
||||||
}
|
|
||||||
Font font = resolvedFont.font();
|
|
||||||
String fontString = ThemeWriter.fontToString(font);
|
|
||||||
|
|
||||||
if (resolvedFont.refId() != null) {
|
|
||||||
return resolvedFont.refId() + " [" + fontString + "]";
|
|
||||||
}
|
|
||||||
return fontString;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFilterString(ResolvedFont fontValue, Settings settings) {
|
public String getFilterString(ResolvedFont fontValue, Settings settings) {
|
||||||
return getValueText(fontValue);
|
return getValueText(fontValue);
|
||||||
|
|||||||
@@ -20,18 +20,28 @@ package generic.theme;
|
|||||||
*/
|
*/
|
||||||
public class ColorChangedThemeEvent extends ThemeEvent {
|
public class ColorChangedThemeEvent extends ThemeEvent {
|
||||||
private final ColorValue color;
|
private final ColorValue color;
|
||||||
|
private final GThemeValueMap values;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
* @param values the set of theme values used to resolve indirect references
|
||||||
* @param color the new {@link ColorValue} for the color id that changed
|
* @param color the new {@link ColorValue} for the color id that changed
|
||||||
*/
|
*/
|
||||||
public ColorChangedThemeEvent(ColorValue color) {
|
public ColorChangedThemeEvent(GThemeValueMap values, ColorValue color) {
|
||||||
|
this.values = values;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isColorChanged(String id) {
|
public boolean isColorChanged(String id) {
|
||||||
return id.equals(color.getId());
|
if (id.equals(color.getId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ColorValue testValue = values.getColor(id);
|
||||||
|
if (testValue == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return testValue.inheritsFrom(color.getId(), values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -41,9 +41,6 @@ public class ColorValue extends ThemeValue<Color> {
|
|||||||
*/
|
*/
|
||||||
public ColorValue(String id, Color value) {
|
public ColorValue(String id, Color value) {
|
||||||
super(id, getRefId(value), getRawColor(value));
|
super(id, getRefId(value), getRawColor(value));
|
||||||
if (value instanceof GColor) {
|
|
||||||
throw new IllegalArgumentException("Can't use GColor as the value!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -20,18 +20,28 @@ package generic.theme;
|
|||||||
*/
|
*/
|
||||||
public class FontChangedThemeEvent extends ThemeEvent {
|
public class FontChangedThemeEvent extends ThemeEvent {
|
||||||
private final FontValue font;
|
private final FontValue font;
|
||||||
|
private final GThemeValueMap values;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
* @param values the set of theme values used to resolve indirect references
|
||||||
* @param font the new {@link FontValue} for the font id that changed
|
* @param font the new {@link FontValue} for the font id that changed
|
||||||
*/
|
*/
|
||||||
public FontChangedThemeEvent(FontValue font) {
|
public FontChangedThemeEvent(GThemeValueMap values, FontValue font) {
|
||||||
|
this.values = values;
|
||||||
this.font = font;
|
this.font = font;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFontChanged(String id) {
|
public boolean isFontChanged(String id) {
|
||||||
return id.equals(font.getId());
|
if (id.equals(font.getId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
FontValue testValue = values.getFont(id);
|
||||||
|
if (testValue == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return testValue.inheritsFrom(font.getId(), values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -39,6 +39,18 @@ import utilities.util.reflection.ReflectionUtilities;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a static set of methods for globally managing application themes and their values.
|
* Provides a static set of methods for globally managing application themes and their values.
|
||||||
|
* <P>
|
||||||
|
* The basic idea is that all the colors, fonts, and icons used in an application should be
|
||||||
|
* accessed indirectly via an "id" string. Then the actual color, font, or icon can be changed
|
||||||
|
* without changing the source code. The default mapping of the id strings to a value is defined
|
||||||
|
* in <name>.theme.properties files which are dynamically discovered by searching the module's
|
||||||
|
* data directory. Also, these files can optionally define a dark default value for an id which
|
||||||
|
* would replace the standard default value in the event that the current theme specifies that it
|
||||||
|
* is a dark theme. Themes are used to specify the application's {@link LookAndFeel}, whether or
|
||||||
|
* not it is dark, and any customized values for colors, fonts, or icons. There are several
|
||||||
|
* "built-in" themes, one for each supported {@link LookAndFeel}, but additional themes can
|
||||||
|
* be defined and stored in the users application home directory as a <name>.theme file.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class Gui {
|
public class Gui {
|
||||||
public static final String THEME_DIR = "themes";
|
public static final String THEME_DIR = "themes";
|
||||||
@@ -90,7 +102,7 @@ public class Gui {
|
|||||||
public static void reloadGhidraDefaults() {
|
public static void reloadGhidraDefaults() {
|
||||||
loadThemeDefaults();
|
loadThemeDefaults();
|
||||||
buildCurrentValues();
|
buildCurrentValues();
|
||||||
lookAndFeelManager.update();
|
lookAndFeelManager.resetAll(javaDefaults);
|
||||||
notifyThemeChanged(new AllValuesChangedThemeEvent(false));
|
notifyThemeChanged(new AllValuesChangedThemeEvent(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +112,7 @@ public class Gui {
|
|||||||
*/
|
*/
|
||||||
public static void restoreThemeValues() {
|
public static void restoreThemeValues() {
|
||||||
buildCurrentValues();
|
buildCurrentValues();
|
||||||
lookAndFeelManager.update();
|
lookAndFeelManager.resetAll(javaDefaults);
|
||||||
notifyThemeChanged(new AllValuesChangedThemeEvent(false));
|
notifyThemeChanged(new AllValuesChangedThemeEvent(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,13 +276,13 @@ public class Gui {
|
|||||||
updateChangedValuesMap(currentValue, newValue);
|
updateChangedValuesMap(currentValue, newValue);
|
||||||
|
|
||||||
currentValues.addFont(newValue);
|
currentValues.addFont(newValue);
|
||||||
// all fonts are direct (there is no GFont), so to we need to update the
|
notifyThemeChanged(new FontChangedThemeEvent(currentValues, newValue));
|
||||||
// UiDefaults for java fonts. Ghidra fonts are expected to be "on the fly" (they
|
|
||||||
// call Gui.getFont(id) for every use.
|
// update all java LookAndFeel fonts affected by this changed
|
||||||
String id = newValue.getId();
|
String id = newValue.getId();
|
||||||
boolean isJavaFont = javaDefaults.containsFont(id);
|
Set<String> affectedJavaFontIds = findAffectedJavaFontIds(id);
|
||||||
lookAndFeelManager.updateFont(id, newValue.get(currentValues), isJavaFont);
|
Font newFont = newValue.get(currentValues);
|
||||||
notifyThemeChanged(new FontChangedThemeEvent(newValue));
|
lookAndFeelManager.updateFonts(id, affectedJavaFontIds, newFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -292,12 +304,11 @@ public class Gui {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateChangedValuesMap(currentValue, newValue);
|
updateChangedValuesMap(currentValue, newValue);
|
||||||
|
|
||||||
currentValues.addColor(newValue);
|
currentValues.addColor(newValue);
|
||||||
String id = newValue.getId();
|
notifyThemeChanged(new ColorChangedThemeEvent(currentValues, newValue));
|
||||||
boolean isJavaColor = javaDefaults.containsColor(id);
|
|
||||||
lookAndFeelManager.updateColor(id, newValue.get(currentValues), isJavaColor);
|
// now update the ui
|
||||||
notifyThemeChanged(new ColorChangedThemeEvent(newValue));
|
lookAndFeelManager.updateColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -321,10 +332,14 @@ public class Gui {
|
|||||||
updateChangedValuesMap(currentValue, newValue);
|
updateChangedValuesMap(currentValue, newValue);
|
||||||
|
|
||||||
currentValues.addIcon(newValue);
|
currentValues.addIcon(newValue);
|
||||||
|
notifyThemeChanged(new IconChangedThemeEvent(currentValues, newValue));
|
||||||
|
|
||||||
|
// now update the ui
|
||||||
|
// update all java LookAndFeel icons affected by this changed
|
||||||
String id = newValue.getId();
|
String id = newValue.getId();
|
||||||
boolean isJavaIcon = javaDefaults.containsIcon(id);
|
Set<String> affectedJavaIconIds = findAffectedJavaIconIds(id);
|
||||||
lookAndFeelManager.updateIcon(id, newValue.get(currentValues), isJavaIcon);
|
Icon newIcon = newValue.get(currentValues);
|
||||||
notifyThemeChanged(new IconChangedThemeEvent(newValue));
|
lookAndFeelManager.updateIcons(id, affectedJavaIconIds, newIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -378,14 +393,8 @@ public class Gui {
|
|||||||
* @return a fixed up version of the given map with relationships restored where possible
|
* @return a fixed up version of the given map with relationships restored where possible
|
||||||
*/
|
*/
|
||||||
public static GThemeValueMap fixupJavaDefaultsInheritence(GThemeValueMap map) {
|
public static GThemeValueMap fixupJavaDefaultsInheritence(GThemeValueMap map) {
|
||||||
List<ColorValue> colors = map.getColors();
|
JavaColorMapping.fixupJavaDefaultsInheritence(map);
|
||||||
JavaColorMapping mapping = new JavaColorMapping();
|
JavaFontMapping.fixupJavaDefaultsInheritence(map);
|
||||||
for (ColorValue value : colors) {
|
|
||||||
ColorValue mapped = mapping.map(map, value);
|
|
||||||
if (mapped != null) {
|
|
||||||
map.addColor(mapped);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,4 +726,30 @@ public class Gui {
|
|||||||
changedValuesMap.addIcon(currentValue);
|
changedValuesMap.addIcon(currentValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Set<String> findAffectedJavaFontIds(String id) {
|
||||||
|
Set<String> affectedIds = new HashSet<>();
|
||||||
|
List<FontValue> fonts = javaDefaults.getFonts();
|
||||||
|
for (FontValue fontValue : fonts) {
|
||||||
|
String fontId = fontValue.getId();
|
||||||
|
FontValue currentFontValue = currentValues.getFont(fontId);
|
||||||
|
if (fontId.equals(id) || currentFontValue.inheritsFrom(id, currentValues)) {
|
||||||
|
affectedIds.add(fontId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return affectedIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<String> findAffectedJavaIconIds(String id) {
|
||||||
|
Set<String> affectedIds = new HashSet<>();
|
||||||
|
List<IconValue> icons = javaDefaults.getIcons();
|
||||||
|
for (IconValue iconValue : icons) {
|
||||||
|
String iconId = iconValue.getId();
|
||||||
|
if (iconId.equals(id) || iconValue.inheritsFrom(id, currentValues)) {
|
||||||
|
affectedIds.add(iconId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return affectedIds;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,19 +19,28 @@ package generic.theme;
|
|||||||
* {@link ThemeEvent} for when an icon changes for exactly one icon id.
|
* {@link ThemeEvent} for when an icon changes for exactly one icon id.
|
||||||
*/
|
*/
|
||||||
public class IconChangedThemeEvent extends ThemeEvent {
|
public class IconChangedThemeEvent extends ThemeEvent {
|
||||||
|
private final GThemeValueMap values;
|
||||||
private final IconValue icon;
|
private final IconValue icon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param icon the new {@link IconValue} for the icon id that changed
|
* @param icon the new {@link IconValue} for the icon id that changed
|
||||||
*/
|
*/
|
||||||
public IconChangedThemeEvent(IconValue icon) {
|
public IconChangedThemeEvent(GThemeValueMap values, IconValue icon) {
|
||||||
|
this.values = values;
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isIconChanged(String id) {
|
public boolean isIconChanged(String id) {
|
||||||
return id.equals(icon.getId());
|
if (id.equals(icon.getId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
IconValue testValue = values.getIcon(id);
|
||||||
|
if (testValue == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return testValue.inheritsFrom(icon.getId(), values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import resources.ResourceManager;
|
|||||||
public class IconValue extends ThemeValue<Icon> {
|
public class IconValue extends ThemeValue<Icon> {
|
||||||
static final String ICON_ID_PREFIX = "icon.";
|
static final String ICON_ID_PREFIX = "icon.";
|
||||||
|
|
||||||
public static final String LAST_RESORT_DEFAULT = "images/bomb.gif";
|
public static final Icon LAST_RESORT_DEFAULT = ResourceManager.getDefaultIcon();
|
||||||
|
|
||||||
private static final String EXTERNAL_PREFIX = "[icon]";
|
private static final String EXTERNAL_PREFIX = "[icon]";
|
||||||
|
|
||||||
@@ -42,10 +42,6 @@ public class IconValue extends ThemeValue<Icon> {
|
|||||||
*/
|
*/
|
||||||
public IconValue(String id, Icon icon) {
|
public IconValue(String id, Icon icon) {
|
||||||
super(id, getRefId(icon), getRawIcon(icon));
|
super(id, getRefId(icon), getRawIcon(icon));
|
||||||
if (icon instanceof GIcon) {
|
|
||||||
throw new IllegalArgumentException("Can't use GIcon as the value!");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -67,7 +63,7 @@ public class IconValue extends ThemeValue<Icon> {
|
|||||||
protected Icon getUnresolvedReferenceValue(String id) {
|
protected Icon getUnresolvedReferenceValue(String id) {
|
||||||
Msg.warn(this,
|
Msg.warn(this,
|
||||||
"Could not resolve indirect icon path for" + id + ", using last resort default");
|
"Could not resolve indirect icon path for" + id + ", using last resort default");
|
||||||
return ResourceManager.getDefaultIcon();
|
return LAST_RESORT_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -71,33 +71,63 @@ public abstract class ThemeValue<T> implements Comparable<ThemeValue<T>> {
|
|||||||
/**
|
/**
|
||||||
* Returns the T value for this instance, following references as needed. Uses the given
|
* Returns the T value for this instance, following references as needed. Uses the given
|
||||||
* preferredValues map to resolve references.
|
* preferredValues map to resolve references.
|
||||||
* @param preferredValues the {@link GThemeValueMap} used to resolve references if this
|
* @param values the {@link GThemeValueMap} used to resolve references if this
|
||||||
* instance doesn't have an actual value.
|
* instance doesn't have an actual value.
|
||||||
* @return the T value for this instance, following references as needed.
|
* @return the T value for this instance, following references as needed.
|
||||||
*/
|
*/
|
||||||
public T get(GThemeValueMap preferredValues) {
|
public T get(GThemeValueMap values) {
|
||||||
return doGetValue(preferredValues);
|
if (value != null) {
|
||||||
}
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
private T doGetValue(GThemeValueMap values) {
|
|
||||||
ThemeValue<T> result = this;
|
|
||||||
Set<String> visitedKeys = new HashSet<>();
|
Set<String> visitedKeys = new HashSet<>();
|
||||||
visitedKeys.add(id); // seed with my id, we don't want to see that key again
|
visitedKeys.add(id);
|
||||||
|
ThemeValue<T> parent = getReferredValue(values, refId);
|
||||||
|
|
||||||
// loop resolving indirect references
|
// loop resolving indirect references
|
||||||
while (result != null) {
|
while (parent != null) {
|
||||||
if (result.value != null) {
|
if (parent.value != null) {
|
||||||
return result.value;
|
return parent.value;
|
||||||
}
|
}
|
||||||
if (visitedKeys.contains(result.refId)) {
|
visitedKeys.add(parent.id);
|
||||||
|
if (visitedKeys.contains(parent.refId)) {
|
||||||
Msg.warn(this, "Theme value reference loop detected for key: " + id);
|
Msg.warn(this, "Theme value reference loop detected for key: " + id);
|
||||||
return getUnresolvedReferenceValue(id);
|
return getUnresolvedReferenceValue(id);
|
||||||
}
|
}
|
||||||
result = getReferredValue(values, result.refId);
|
parent = getReferredValue(values, parent.refId);
|
||||||
}
|
}
|
||||||
return getUnresolvedReferenceValue(id);
|
return getUnresolvedReferenceValue(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean inheritsFrom(String ancestorId, GThemeValueMap values) {
|
||||||
|
if (refId == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (refId.equals(ancestorId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> visitedKeys = new HashSet<>();
|
||||||
|
visitedKeys.add(id);
|
||||||
|
ThemeValue<T> parent = getReferredValue(values, refId);
|
||||||
|
|
||||||
|
// loop resolving indirect references
|
||||||
|
while (parent != null) {
|
||||||
|
if (parent.refId == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (parent.refId.equals(ancestorId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
visitedKeys.add(parent.id);
|
||||||
|
if (visitedKeys.contains(parent.refId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
parent = getReferredValue(values, parent.refId);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the T to be used if the indirect reference couldn't be resolved.
|
* Returns the T to be used if the indirect reference couldn't be resolved.
|
||||||
* @param unresolvedId the id that couldn't be resolved
|
* @param unresolvedId the id that couldn't be resolved
|
||||||
|
|||||||
+202
-195
@@ -15,8 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package generic.theme.builtin;
|
package generic.theme.builtin;
|
||||||
|
|
||||||
|
import static java.util.Map.*;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.util.HashMap;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import generic.theme.ColorValue;
|
import generic.theme.ColorValue;
|
||||||
@@ -26,203 +28,208 @@ import generic.theme.GThemeValueMap;
|
|||||||
* Maps Java UIDefaults color ids to parent color ids
|
* Maps Java UIDefaults color ids to parent color ids
|
||||||
*/
|
*/
|
||||||
public class JavaColorMapping {
|
public class JavaColorMapping {
|
||||||
private Map<String, String> map = new HashMap<>();
|
private static Map<String, String> map = Map.ofEntries(
|
||||||
|
entry("Button.background", "control"),
|
||||||
public JavaColorMapping() {
|
entry("Button.foreground", "controlText"),
|
||||||
// color relationships mined from BasicLookAndFeel
|
entry("Button.shadow", "controlShadow"),
|
||||||
map.put("Button.background", "control");
|
entry("Button.darkShadow", "controlDkShadow"),
|
||||||
map.put("Button.foreground", "controlText");
|
entry("Button.light", "controlHighlight"),
|
||||||
map.put("Button.shadow", "controlShadow");
|
entry("Button.highlight", "controlLtHighlight"),
|
||||||
map.put("Button.darkShadow", "controlDkShadow");
|
entry("ToggleButton.background", "control"),
|
||||||
map.put("Button.light", "controlHighlight");
|
entry("ToggleButton.foreground", "controlText"),
|
||||||
map.put("Button.highlight", "controlLtHighlight");
|
entry("ToggleButton.shadow", "controlShadow"),
|
||||||
map.put("ToggleButton.background", "control");
|
entry("ToggleButton.darkShadow", "controlDkShadow"),
|
||||||
map.put("ToggleButton.foreground", "controlText");
|
entry("ToggleButton.light", "controlHighlight"),
|
||||||
map.put("ToggleButton.shadow", "controlShadow");
|
entry("ToggleButton.highlight", "controlLtHighlight"),
|
||||||
map.put("ToggleButton.darkShadow", "controlDkShadow");
|
entry("RadioButton.background", "control"),
|
||||||
map.put("ToggleButton.light", "controlHighlight");
|
entry("RadioButton.foreground", "controlText"),
|
||||||
map.put("ToggleButton.highlight", "controlLtHighlight");
|
entry("RadioButton.shadow", "controlShadow"),
|
||||||
map.put("RadioButton.background", "control");
|
entry("RadioButton.darkShadow", "controlDkShadow"),
|
||||||
map.put("RadioButton.foreground", "controlText");
|
entry("RadioButton.light", "controlHighlight"),
|
||||||
map.put("RadioButton.shadow", "controlShadow");
|
entry("RadioButton.highlight", "controlLtHighlight"),
|
||||||
map.put("RadioButton.darkShadow", "controlDkShadow");
|
entry("CheckBox.background", "control"),
|
||||||
map.put("RadioButton.light", "controlHighlight");
|
entry("CheckBox.foreground", "controlText"),
|
||||||
map.put("RadioButton.highlight", "controlLtHighlight");
|
entry("ColorChooser.background", "control"),
|
||||||
map.put("CheckBox.background", "control");
|
entry("ColorChooser.foreground", "controlText"),
|
||||||
map.put("CheckBox.foreground", "controlText");
|
entry("ColorChooser.swatchesDefaultRecentColor", "control"),
|
||||||
map.put("ColorChooser.background", "control");
|
entry("ComboBox.background", "window"),
|
||||||
map.put("ColorChooser.foreground", "controlText");
|
entry("ComboBox.foreground", "textText"),
|
||||||
map.put("ColorChooser.swatchesDefaultRecentColor", "control");
|
entry("ComboBox.buttonBackground", "control"),
|
||||||
map.put("ComboBox.background", "window");
|
entry("ComboBox.buttonShadow", "controlShadow"),
|
||||||
map.put("ComboBox.foreground", "textText");
|
entry("ComboBox.buttonDarkShadow", "controlDkShadow"),
|
||||||
map.put("ComboBox.buttonBackground", "control");
|
entry("ComboBox.buttonHighlight", "controlLtHighlight"),
|
||||||
map.put("ComboBox.buttonShadow", "controlShadow");
|
entry("ComboBox.selectionBackground", "textHighlight"),
|
||||||
map.put("ComboBox.buttonDarkShadow", "controlDkShadow");
|
entry("ComboBox.selectionForeground", "textHighlightText"),
|
||||||
map.put("ComboBox.buttonHighlight", "controlLtHighlight");
|
entry("ComboBox.disabledBackground", "control"),
|
||||||
map.put("ComboBox.selectionBackground", "textHighlight");
|
entry("ComboBox.disabledForeground", "textHInactiveText"),
|
||||||
map.put("ComboBox.selectionForeground", "textHighlightText");
|
entry("InternalFrame.borderColor", "control"),
|
||||||
map.put("ComboBox.disabledBackground", "control");
|
entry("InternalFrame.borderShadow", "controlShadow"),
|
||||||
map.put("ComboBox.disabledForeground", "textHInactiveText");
|
entry("InternalFrame.borderDarkShadow", "controlDkShadow"),
|
||||||
map.put("InternalFrame.borderColor", "control");
|
entry("InternalFrame.borderHighlight", "controlLtHighlight"),
|
||||||
map.put("InternalFrame.borderShadow", "controlShadow");
|
entry("InternalFrame.borderLight", "controlHighlight"),
|
||||||
map.put("InternalFrame.borderDarkShadow", "controlDkShadow");
|
entry("InternalFrame.activeTitleBackground", "activeCaption"),
|
||||||
map.put("InternalFrame.borderHighlight", "controlLtHighlight");
|
entry("InternalFrame.activeTitleForeground", "activeCaptionText"),
|
||||||
map.put("InternalFrame.borderLight", "controlHighlight");
|
entry("InternalFrame.inactiveTitleBackground", "inactiveCaption"),
|
||||||
map.put("InternalFrame.activeTitleBackground", "activeCaption");
|
entry("InternalFrame.inactiveTitleForeground", "inactiveCaptionText"),
|
||||||
map.put("InternalFrame.activeTitleForeground", "activeCaptionText");
|
entry("Label.background", "control"),
|
||||||
map.put("InternalFrame.inactiveTitleBackground", "inactiveCaption");
|
entry("Label.foreground", "controlText"),
|
||||||
map.put("InternalFrame.inactiveTitleForeground", "inactiveCaptionText");
|
entry("Label.disabledShadow", "controlShadow"),
|
||||||
map.put("Label.background", "control");
|
entry("List.background", "window"),
|
||||||
map.put("Label.foreground", "controlText");
|
entry("List.foreground", "textText"),
|
||||||
map.put("Label.disabledShadow", "controlShadow");
|
entry("List.selectionBackground", "textHighlight"),
|
||||||
map.put("List.background", "window");
|
entry("List.selectionForeground", "textHighlightText"),
|
||||||
map.put("List.foreground", "textText");
|
entry("List.dropLineColor", "controlShadow"),
|
||||||
map.put("List.selectionBackground", "textHighlight");
|
entry("MenuBar.background", "menu"),
|
||||||
map.put("List.selectionForeground", "textHighlightText");
|
entry("MenuBar.foreground", "menuText"),
|
||||||
map.put("List.dropLineColor", "controlShadow");
|
entry("MenuBar.shadow", "controlShadow"),
|
||||||
map.put("MenuBar.background", "menu");
|
entry("MenuBar.highlight", "controlLtHighlight"),
|
||||||
map.put("MenuBar.foreground", "menuText");
|
entry("MenuItem.background", "menu"),
|
||||||
map.put("MenuBar.shadow", "controlShadow");
|
entry("MenuItem.foreground", "menuText"),
|
||||||
map.put("MenuBar.highlight", "controlLtHighlight");
|
entry("MenuItem.selectionForeground", "textHighlightText"),
|
||||||
map.put("MenuItem.background", "menu");
|
entry("MenuItem.selectionBackground", "textHighlight"),
|
||||||
map.put("MenuItem.foreground", "menuText");
|
entry("MenuItem.acceleratorForeground", "menuText"),
|
||||||
map.put("MenuItem.selectionForeground", "textHighlightText");
|
entry("MenuItem.acceleratorSelectionForeground", "textHighlightText"),
|
||||||
map.put("MenuItem.selectionBackground", "textHighlight");
|
entry("RadioButtonMenuItem.background", "menu"),
|
||||||
map.put("MenuItem.acceleratorForeground", "menuText");
|
entry("RadioButtonMenuItem.foreground", "menuText"),
|
||||||
map.put("MenuItem.acceleratorSelectionForeground", "textHighlightText");
|
entry("RadioButtonMenuItem.selectionForeground", "textHighlightText"),
|
||||||
map.put("RadioButtonMenuItem.background", "menu");
|
entry("RadioButtonMenuItem.selectionBackground", "textHighlight"),
|
||||||
map.put("RadioButtonMenuItem.foreground", "menuText");
|
entry("RadioButtonMenuItem.acceleratorForeground", "menuText"),
|
||||||
map.put("RadioButtonMenuItem.selectionForeground", "textHighlightText");
|
entry("RadioButtonMenuItem.acceleratorSelectionForeground", "textHighlightText"),
|
||||||
map.put("RadioButtonMenuItem.selectionBackground", "textHighlight");
|
entry("CheckBoxMenuItem.background", "menu"),
|
||||||
map.put("RadioButtonMenuItem.acceleratorForeground", "menuText");
|
entry("CheckBoxMenuItem.foreground", "menuText"),
|
||||||
map.put("RadioButtonMenuItem.acceleratorSelectionForeground", "textHighlightText");
|
entry("CheckBoxMenuItem.selectionForeground", "textHighlightText"),
|
||||||
map.put("CheckBoxMenuItem.background", "menu");
|
entry("CheckBoxMenuItem.selectionBackground", "textHighlight"),
|
||||||
map.put("CheckBoxMenuItem.foreground", "menuText");
|
entry("CheckBoxMenuItem.acceleratorForeground", "menuText"),
|
||||||
map.put("CheckBoxMenuItem.selectionForeground", "textHighlightText");
|
entry("CheckBoxMenuItem.acceleratorSelectionForeground", "textHighlightText"),
|
||||||
map.put("CheckBoxMenuItem.selectionBackground", "textHighlight");
|
entry("Menu.background", "menu"),
|
||||||
map.put("CheckBoxMenuItem.acceleratorForeground", "menuText");
|
entry("Menu.foreground", "menuText"),
|
||||||
map.put("CheckBoxMenuItem.acceleratorSelectionForeground", "textHighlightText");
|
entry("Menu.selectionForeground", "textHighlightText"),
|
||||||
map.put("Menu.background", "menu");
|
entry("Menu.selectionBackground", "textHighlight"),
|
||||||
map.put("Menu.foreground", "menuText");
|
entry("Menu.acceleratorForeground", "menuText"),
|
||||||
map.put("Menu.selectionForeground", "textHighlightText");
|
entry("Menu.acceleratorSelectionForeground", "textHighlightText"),
|
||||||
map.put("Menu.selectionBackground", "textHighlight");
|
entry("PopupMenu.background", "menu"),
|
||||||
map.put("Menu.acceleratorForeground", "menuText");
|
entry("PopupMenu.foreground", "menuText"),
|
||||||
map.put("Menu.acceleratorSelectionForeground", "textHighlightText");
|
entry("OptionPane.background", "control"),
|
||||||
map.put("PopupMenu.background", "menu");
|
entry("OptionPane.foreground", "controlText"),
|
||||||
map.put("PopupMenu.foreground", "menuText");
|
entry("OptionPane.messageForeground", "controlText"),
|
||||||
map.put("OptionPane.background", "control");
|
entry("Panel.background", "control"),
|
||||||
map.put("OptionPane.foreground", "controlText");
|
entry("Panel.foreground", "textText"),
|
||||||
map.put("OptionPane.messageForeground", "controlText");
|
entry("ProgressBar.foreground", "textHighlight"),
|
||||||
map.put("Panel.background", "control");
|
entry("ProgressBar.background", "control"),
|
||||||
map.put("Panel.foreground", "textText");
|
entry("ProgressBar.selectionForeground", "control"),
|
||||||
map.put("ProgressBar.foreground", "textHighlight");
|
entry("ProgressBar.selectionBackground", "textHighlight"),
|
||||||
map.put("ProgressBar.background", "control");
|
entry("Separator.background", "controlLtHighlight"),
|
||||||
map.put("ProgressBar.selectionForeground", "control");
|
entry("Separator.foreground", "controlShadow"),
|
||||||
map.put("ProgressBar.selectionBackground", "textHighlight");
|
entry("ScrollBar.foreground", "control"),
|
||||||
map.put("Separator.background", "controlLtHighlight");
|
entry("ScrollBar.track", "scrollbar"),
|
||||||
map.put("Separator.foreground", "controlShadow");
|
entry("ScrollBar.trackHighlight", "controlDkShadow"),
|
||||||
map.put("ScrollBar.foreground", "control");
|
entry("ScrollBar.thumb", "control"),
|
||||||
map.put("ScrollBar.track", "scrollbar");
|
entry("ScrollBar.thumbHighlight", "controlLtHighlight"),
|
||||||
map.put("ScrollBar.trackHighlight", "controlDkShadow");
|
entry("ScrollBar.thumbDarkShadow", "controlDkShadow"),
|
||||||
map.put("ScrollBar.thumb", "control");
|
entry("ScrollBar.thumbShadow", "controlShadow"),
|
||||||
map.put("ScrollBar.thumbHighlight", "controlLtHighlight");
|
entry("ScrollPane.background", "control"),
|
||||||
map.put("ScrollBar.thumbDarkShadow", "controlDkShadow");
|
entry("ScrollPane.foreground", "controlText"),
|
||||||
map.put("ScrollBar.thumbShadow", "controlShadow");
|
entry("Viewport.background", "control"),
|
||||||
map.put("ScrollPane.background", "control");
|
entry("Viewport.foreground", "textText"),
|
||||||
map.put("ScrollPane.foreground", "controlText");
|
entry("Slider.foreground", "control"),
|
||||||
map.put("Viewport.background", "control");
|
entry("Slider.background", "control"),
|
||||||
map.put("Viewport.foreground", "textText");
|
entry("Slider.highlight", "controlLtHighlight"),
|
||||||
map.put("Slider.foreground", "control");
|
entry("Slider.shadow", "controlShadow"),
|
||||||
map.put("Slider.background", "control");
|
entry("Slider.focus", "controlDkShadow"),
|
||||||
map.put("Slider.highlight", "controlLtHighlight");
|
entry("Spinner.background", "control"),
|
||||||
map.put("Slider.shadow", "controlShadow");
|
entry("Spinner.foreground", "control"),
|
||||||
map.put("Slider.focus", "controlDkShadow");
|
entry("SplitPane.background", "control"),
|
||||||
map.put("Spinner.background", "control");
|
entry("SplitPane.highlight", "controlLtHighlight"),
|
||||||
map.put("Spinner.foreground", "control");
|
entry("SplitPane.shadow", "controlShadow"),
|
||||||
map.put("SplitPane.background", "control");
|
entry("SplitPane.darkShadow", "controlDkShadow"),
|
||||||
map.put("SplitPane.highlight", "controlLtHighlight");
|
entry("TabbedPane.background", "control"),
|
||||||
map.put("SplitPane.shadow", "controlShadow");
|
entry("TabbedPane.foreground", "controlText"),
|
||||||
map.put("SplitPane.darkShadow", "controlDkShadow");
|
entry("TabbedPane.highlight", "controlLtHighlight"),
|
||||||
map.put("TabbedPane.background", "control");
|
entry("TabbedPane.light", "controlHighlight"),
|
||||||
map.put("TabbedPane.foreground", "controlText");
|
entry("TabbedPane.shadow", "controlShadow"),
|
||||||
map.put("TabbedPane.highlight", "controlLtHighlight");
|
entry("TabbedPane.darkShadow", "controlDkShadow"),
|
||||||
map.put("TabbedPane.light", "controlHighlight");
|
entry("TabbedPane.focus", "controlText"),
|
||||||
map.put("TabbedPane.shadow", "controlShadow");
|
entry("Table.foreground", "controlText"),
|
||||||
map.put("TabbedPane.darkShadow", "controlDkShadow");
|
entry("Table.background", "window"),
|
||||||
map.put("TabbedPane.focus", "controlText");
|
entry("Table.selectionForeground", "textHighlightText"),
|
||||||
map.put("Table.foreground", "controlText");
|
entry("Table.selectionBackground", "textHighlight"),
|
||||||
map.put("Table.background", "window");
|
entry("Table.dropLineColor", "controlShadow"),
|
||||||
map.put("Table.selectionForeground", "textHighlightText");
|
entry("Table.focusCellBackground", "window"),
|
||||||
map.put("Table.selectionBackground", "textHighlight");
|
entry("Table.focusCellForeground", "controlText"),
|
||||||
map.put("Table.dropLineColor", "controlShadow");
|
entry("TableHeader.foreground", "controlText"),
|
||||||
map.put("Table.focusCellBackground", "window");
|
entry("TableHeader.background", "control"),
|
||||||
map.put("Table.focusCellForeground", "controlText");
|
entry("TableHeader.focusCellBackground", "text"),
|
||||||
map.put("TableHeader.foreground", "controlText");
|
entry("TextField.background", "window"),
|
||||||
map.put("TableHeader.background", "control");
|
entry("TextField.foreground", "textText"),
|
||||||
map.put("TableHeader.focusCellBackground", "text");
|
entry("TextField.shadow", "controlShadow"),
|
||||||
map.put("TextField.background", "window");
|
entry("TextField.darkShadow", "controlDkShadow"),
|
||||||
map.put("TextField.foreground", "textText");
|
entry("TextField.light", "controlHighlight"),
|
||||||
map.put("TextField.shadow", "controlShadow");
|
entry("TextField.highlight", "controlLtHighlight"),
|
||||||
map.put("TextField.darkShadow", "controlDkShadow");
|
entry("TextField.inactiveForeground", "textHInactiveText"),
|
||||||
map.put("TextField.light", "controlHighlight");
|
entry("TextField.inactiveBackground", "control"),
|
||||||
map.put("TextField.highlight", "controlLtHighlight");
|
entry("TextField.selectionBackground", "textHighlight"),
|
||||||
map.put("TextField.inactiveForeground", "textHInactiveText");
|
entry("TextField.selectionForeground", "textHighlightText"),
|
||||||
map.put("TextField.inactiveBackground", "control");
|
entry("TextField.caretForeground", "textText"),
|
||||||
map.put("TextField.selectionBackground", "textHighlight");
|
entry("FormattedTextField.background", "window"),
|
||||||
map.put("TextField.selectionForeground", "textHighlightText");
|
entry("FormattedTextField.foreground", "textText"),
|
||||||
map.put("TextField.caretForeground", "textText");
|
entry("FormattedTextField.inactiveForeground", "textHInactiveText"),
|
||||||
map.put("FormattedTextField.background", "window");
|
entry("FormattedTextField.inactiveBackground", "control"),
|
||||||
map.put("FormattedTextField.foreground", "textText");
|
entry("FormattedTextField.selectionBackground", "textHighlight"),
|
||||||
map.put("FormattedTextField.inactiveForeground", "textHInactiveText");
|
entry("FormattedTextField.selectionForeground", "textHighlightText"),
|
||||||
map.put("FormattedTextField.inactiveBackground", "control");
|
entry("FormattedTextField.caretForeground", "textText"),
|
||||||
map.put("FormattedTextField.selectionBackground", "textHighlight");
|
entry("PasswordField.background", "window"),
|
||||||
map.put("FormattedTextField.selectionForeground", "textHighlightText");
|
entry("PasswordField.foreground", "textText"),
|
||||||
map.put("FormattedTextField.caretForeground", "textText");
|
entry("PasswordField.inactiveForeground", "textHInactiveText"),
|
||||||
map.put("PasswordField.background", "window");
|
entry("PasswordField.inactiveBackground", "control"),
|
||||||
map.put("PasswordField.foreground", "textText");
|
entry("PasswordField.selectionBackground", "textHighlight"),
|
||||||
map.put("PasswordField.inactiveForeground", "textHInactiveText");
|
entry("PasswordField.selectionForeground", "textHighlightText"),
|
||||||
map.put("PasswordField.inactiveBackground", "control");
|
entry("PasswordField.caretForeground", "textText"),
|
||||||
map.put("PasswordField.selectionBackground", "textHighlight");
|
entry("TextArea.background", "window"),
|
||||||
map.put("PasswordField.selectionForeground", "textHighlightText");
|
entry("TextArea.foreground", "textText"),
|
||||||
map.put("PasswordField.caretForeground", "textText");
|
entry("TextArea.inactiveForeground", "textHInactiveText"),
|
||||||
map.put("TextArea.background", "window");
|
entry("TextArea.selectionBackground", "textHighlight"),
|
||||||
map.put("TextArea.foreground", "textText");
|
entry("TextArea.selectionForeground", "textHighlightText"),
|
||||||
map.put("TextArea.inactiveForeground", "textHInactiveText");
|
entry("TextArea.caretForeground", "textText"),
|
||||||
map.put("TextArea.selectionBackground", "textHighlight");
|
entry("TextPane.foreground", "textText"),
|
||||||
map.put("TextArea.selectionForeground", "textHighlightText");
|
entry("TextPane.selectionBackground", "textHighlight"),
|
||||||
map.put("TextArea.caretForeground", "textText");
|
entry("TextPane.selectionForeground", "textHighlightText"),
|
||||||
map.put("TextPane.foreground", "textText");
|
entry("TextPane.caretForeground", "textText"),
|
||||||
map.put("TextPane.selectionBackground", "textHighlight");
|
entry("TextPane.inactiveForeground", "textHInactiveText"),
|
||||||
map.put("TextPane.selectionForeground", "textHighlightText");
|
entry("EditorPane.foreground", "textText"),
|
||||||
map.put("TextPane.caretForeground", "textText");
|
entry("EditorPane.selectionBackground", "textHighlight"),
|
||||||
map.put("TextPane.inactiveForeground", "textHInactiveText");
|
entry("EditorPane.selectionForeground", "textHighlightText"),
|
||||||
map.put("EditorPane.foreground", "textText");
|
entry("EditorPane.caretForeground", "textText"),
|
||||||
map.put("EditorPane.selectionBackground", "textHighlight");
|
entry("EditorPane.inactiveForeground", "textHInactiveText"),
|
||||||
map.put("EditorPane.selectionForeground", "textHighlightText");
|
entry("TitledBorder.titleColor", "controlText"),
|
||||||
map.put("EditorPane.caretForeground", "textText");
|
entry("ToolBar.background", "control"),
|
||||||
map.put("EditorPane.inactiveForeground", "textHInactiveText");
|
entry("ToolBar.foreground", "controlText"),
|
||||||
map.put("TitledBorder.titleColor", "controlText");
|
entry("ToolBar.shadow", "controlShadow"),
|
||||||
map.put("ToolBar.background", "control");
|
entry("ToolBar.darkShadow", "controlDkShadow"),
|
||||||
map.put("ToolBar.foreground", "controlText");
|
entry("ToolBar.light", "controlHighlight"),
|
||||||
map.put("ToolBar.shadow", "controlShadow");
|
entry("ToolBar.highlight", "controlLtHighlight"),
|
||||||
map.put("ToolBar.darkShadow", "controlDkShadow");
|
entry("ToolBar.dockingBackground", "control"),
|
||||||
map.put("ToolBar.light", "controlHighlight");
|
entry("ToolBar.floatingBackground", "control"),
|
||||||
map.put("ToolBar.highlight", "controlLtHighlight");
|
entry("ToolTip.background", "info"),
|
||||||
map.put("ToolBar.dockingBackground", "control");
|
entry("ToolTip.foreground", "infoText"),
|
||||||
map.put("ToolBar.floatingBackground", "control");
|
entry("Tree.background", "window"),
|
||||||
map.put("ToolTip.background", "info");
|
entry("Tree.foreground", "textText"),
|
||||||
map.put("ToolTip.foreground", "infoText");
|
entry("Tree.textForeground", "textText"),
|
||||||
map.put("Tree.background", "window");
|
entry("Tree.textBackground", "text"),
|
||||||
map.put("Tree.foreground", "textText");
|
entry("Tree.selectionForeground", "textHighlightText"),
|
||||||
map.put("Tree.textForeground", "textText");
|
entry("Tree.selectionBackground", "textHighlight"),
|
||||||
map.put("Tree.textBackground", "text");
|
entry("Tree.dropLineColor", "controlShadow"));
|
||||||
map.put("Tree.selectionForeground", "textHighlightText");
|
|
||||||
map.put("Tree.selectionBackground", "textHighlight");
|
|
||||||
map.put("Tree.dropLineColor", "controlShadow");
|
|
||||||
|
|
||||||
|
public static void fixupJavaDefaultsInheritence(GThemeValueMap values) {
|
||||||
|
List<ColorValue> colors = values.getColors();
|
||||||
|
for (ColorValue value : colors) {
|
||||||
|
ColorValue mapped = map(values, value);
|
||||||
|
if (mapped != null) {
|
||||||
|
values.addColor(mapped);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ColorValue map(GThemeValueMap values, ColorValue value) {
|
private static ColorValue map(GThemeValueMap values, ColorValue value) {
|
||||||
String id = value.getId();
|
String id = value.getId();
|
||||||
String refId = map.get(id);
|
String refId = map.get(id);
|
||||||
if (refId == null) {
|
if (refId == null) {
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package generic.theme.builtin;
|
||||||
|
|
||||||
|
import static java.util.Map.*;
|
||||||
|
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import generic.theme.FontValue;
|
||||||
|
import generic.theme.GThemeValueMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps Java UIDefaults color ids to parent color ids
|
||||||
|
*/
|
||||||
|
public class JavaFontMapping {
|
||||||
|
private final static String BUTTON_GROUP = "ButtonComponents.font";
|
||||||
|
private final static String TEXT_GROUP = "TextComponents.font";
|
||||||
|
private final static String MENU_GROUP = "MenuComponents.font";
|
||||||
|
private final static String MENU_ACCELERATOR_GROUP = "MenuComponents.acceleratorFont";
|
||||||
|
private final static String DIALOG_GROUP = "Dialogs.font";
|
||||||
|
private final static String WIDGET_GROUP = "Components.font";
|
||||||
|
|
||||||
|
private static Map<String, String> map = Map.ofEntries(
|
||||||
|
entry("ArrowButton.font", BUTTON_GROUP), // nimbus
|
||||||
|
entry("Button.font", BUTTON_GROUP),
|
||||||
|
entry("CheckBox.font", BUTTON_GROUP),
|
||||||
|
entry("RadioButton.font", BUTTON_GROUP),
|
||||||
|
entry("ToggleButton.font", BUTTON_GROUP),
|
||||||
|
|
||||||
|
entry("CheckBoxMenuItem.font", MENU_GROUP),
|
||||||
|
entry("Menu.font", MENU_GROUP),
|
||||||
|
entry("MenuBar.font", MENU_GROUP),
|
||||||
|
entry("MenuItem.font", MENU_GROUP),
|
||||||
|
entry("PopupMenu.font", MENU_GROUP),
|
||||||
|
entry("RadioButtonMenuItem.font", MENU_GROUP),
|
||||||
|
|
||||||
|
entry("CheckBoxMenuItem.acceleratorFont", MENU_ACCELERATOR_GROUP), // metal, motif
|
||||||
|
entry("Menu.acceleratorFont", MENU_ACCELERATOR_GROUP), // metal, motif
|
||||||
|
entry("MenuItem.acceleratorFont", MENU_ACCELERATOR_GROUP), // metal, motfi
|
||||||
|
entry("RadioButtonMenuItem.acceleratorFont", MENU_ACCELERATOR_GROUP), // metal
|
||||||
|
|
||||||
|
entry("EditorPane.font", TEXT_GROUP),
|
||||||
|
entry("FormattedTextField.font", TEXT_GROUP),
|
||||||
|
entry("PasswordField.font", TEXT_GROUP),
|
||||||
|
entry("TextArea.font", TEXT_GROUP),
|
||||||
|
entry("TextField.font", TEXT_GROUP),
|
||||||
|
entry("TextPane.font", TEXT_GROUP),
|
||||||
|
|
||||||
|
entry("ColorChooser.font", DIALOG_GROUP),
|
||||||
|
entry("FileChooser.font", DIALOG_GROUP), // nimbus
|
||||||
|
|
||||||
|
entry("ComboBox.font", WIDGET_GROUP),
|
||||||
|
entry("InternalFrame.titleFont", WIDGET_GROUP), // metal, motif, flat
|
||||||
|
entry("Label.font", WIDGET_GROUP),
|
||||||
|
entry("List.font", WIDGET_GROUP),
|
||||||
|
entry("OptionPane.font", DIALOG_GROUP),
|
||||||
|
entry("Panel.font", WIDGET_GROUP),
|
||||||
|
entry("ProgressBar.font", WIDGET_GROUP),
|
||||||
|
entry("RootPane.font", WIDGET_GROUP),
|
||||||
|
entry("Scrollbar.font", WIDGET_GROUP),
|
||||||
|
entry("ScrollBarThumb.font", WIDGET_GROUP), // nimbus
|
||||||
|
entry("ScrollBarTrack.font", WIDGET_GROUP), // nimbus
|
||||||
|
entry("ScrollPane.font", WIDGET_GROUP),
|
||||||
|
entry("Separator.font", WIDGET_GROUP), // nimbus
|
||||||
|
entry("Slider.font", WIDGET_GROUP),
|
||||||
|
entry("SliderThumb.font", WIDGET_GROUP), // nimbus
|
||||||
|
entry("SliderTrack.font", WIDGET_GROUP), // nimbus
|
||||||
|
entry("Spinner.font", WIDGET_GROUP),
|
||||||
|
entry("SplitPane.font", WIDGET_GROUP), // nimbus
|
||||||
|
entry("TabbedPane.font", WIDGET_GROUP),
|
||||||
|
entry("TitledBorder.font", WIDGET_GROUP),
|
||||||
|
entry("ToolBar.font", WIDGET_GROUP),
|
||||||
|
entry("ToolTip.font", TEXT_GROUP),
|
||||||
|
entry("Viewport.font", WIDGET_GROUP),
|
||||||
|
|
||||||
|
entry("Tree.font", WIDGET_GROUP),
|
||||||
|
entry("Table.font", WIDGET_GROUP),
|
||||||
|
entry("TableHeader.font", "Table.font"));
|
||||||
|
|
||||||
|
public static void fixupJavaDefaultsInheritence(GThemeValueMap values) {
|
||||||
|
createGroupDefaults(values);
|
||||||
|
List<FontValue> fonts = values.getFonts();
|
||||||
|
for (FontValue value : fonts) {
|
||||||
|
FontValue mapped = map(values, value);
|
||||||
|
if (mapped != null) {
|
||||||
|
values.addFont(mapped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FontValue map(GThemeValueMap values, FontValue value) {
|
||||||
|
String id = value.getId();
|
||||||
|
String refId = map.get(id);
|
||||||
|
if (refId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
FontValue refValue = values.getFont(refId);
|
||||||
|
if (refValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Font originalFont = value.get(values);
|
||||||
|
Font refFont = refValue.get(values);
|
||||||
|
if (originalFont == null || refFont == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (originalFont.equals(refFont)) {
|
||||||
|
return new FontValue(id, refId);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createGroupDefaults(GThemeValueMap valuesMap) {
|
||||||
|
addFontValue(valuesMap, BUTTON_GROUP, "Button.font");
|
||||||
|
addFontValue(valuesMap, TEXT_GROUP, "TextField.font");
|
||||||
|
addFontValue(valuesMap, MENU_GROUP, "Menu.font");
|
||||||
|
addFontValue(valuesMap, MENU_ACCELERATOR_GROUP, "Menu.acceleratorFont");
|
||||||
|
addFontValue(valuesMap, DIALOG_GROUP, "ColorChooser.font");
|
||||||
|
addFontValue(valuesMap, WIDGET_GROUP, "Label.font");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addFontValue(GThemeValueMap valuesMap, String groupId, String exemplarId) {
|
||||||
|
FontValue font = valuesMap.getFont(exemplarId);
|
||||||
|
if (font != null) {
|
||||||
|
valuesMap.addFont(new FontValue(groupId, font.get(valuesMap)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package generic.theme.laf;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.UIDefaults;
|
||||||
|
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
|
||||||
|
|
||||||
|
import generic.theme.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extends the NimbusLookAndFeel to intercept the {@link #getDefaults()}. To get Nimbus
|
||||||
|
* to use our indirect values, we have to get in early.
|
||||||
|
*/
|
||||||
|
public class GNimbusLookAndFeel extends NimbusLookAndFeel {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UIDefaults getDefaults() {
|
||||||
|
UIDefaults defaults = super.getDefaults();
|
||||||
|
GThemeValueMap javaDefaults = extractJavaDefaults(defaults);
|
||||||
|
|
||||||
|
// replace all colors with GColors
|
||||||
|
for (ColorValue colorValue : javaDefaults.getColors()) {
|
||||||
|
String id = colorValue.getId();
|
||||||
|
defaults.put(id, Gui.getGColorUiResource(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// only replace fonts that have been changed by the theme
|
||||||
|
for (FontValue fontValue : javaDefaults.getFonts()) {
|
||||||
|
String id = fontValue.getId();
|
||||||
|
Font font = Gui.getFont(id);
|
||||||
|
defaults.put(id, font);
|
||||||
|
}
|
||||||
|
|
||||||
|
// only replace icons that have been changed by the theme
|
||||||
|
for (IconValue iconValue : javaDefaults.getIcons()) {
|
||||||
|
String id = iconValue.getId();
|
||||||
|
Icon icon = Gui.getRawIcon(id, true);
|
||||||
|
defaults.put(id, icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults.put("Label.textForeground", Gui.getGColorUiResource("Label.foreground"));
|
||||||
|
GColor.refreshAll();
|
||||||
|
GIcon.refreshAll();
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected GThemeValueMap extractJavaDefaults(UIDefaults defaults) {
|
||||||
|
GThemeValueMap javaDefaults = new GThemeValueMap();
|
||||||
|
|
||||||
|
List<String> colorIds =
|
||||||
|
LookAndFeelInstaller.getLookAndFeelIdsForType(defaults, Color.class);
|
||||||
|
for (String id : colorIds) {
|
||||||
|
Color color = defaults.getColor(id);
|
||||||
|
ColorValue value = new ColorValue(id, color);
|
||||||
|
javaDefaults.addColor(value);
|
||||||
|
}
|
||||||
|
List<String> fontIds =
|
||||||
|
LookAndFeelInstaller.getLookAndFeelIdsForType(defaults, Font.class);
|
||||||
|
for (String id : fontIds) {
|
||||||
|
Font font = defaults.getFont(id);
|
||||||
|
FontValue value = new FontValue(id, font);
|
||||||
|
javaDefaults.addFont(value);
|
||||||
|
}
|
||||||
|
List<String> iconIds =
|
||||||
|
LookAndFeelInstaller.getLookAndFeelIdsForType(defaults, Icon.class);
|
||||||
|
for (String id : iconIds) {
|
||||||
|
Icon icon = defaults.getIcon(id);
|
||||||
|
javaDefaults.addIcon(new IconValue(id, icon));
|
||||||
|
}
|
||||||
|
// need to set javaDefalts now to trigger building currentValues so the when
|
||||||
|
// we create GColors below, they can be resolved.
|
||||||
|
Gui.setJavaDefaults(javaDefaults);
|
||||||
|
|
||||||
|
return javaDefaults;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package generic.theme.laf;
|
package generic.theme.laf;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Font;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
@@ -46,43 +49,69 @@ public abstract class LookAndFeelManager {
|
|||||||
updateComponentUis();
|
updateComponentUis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
public void resetAll(GThemeValueMap javaDefaults) {
|
||||||
GColor.refreshAll();
|
GColor.refreshAll();
|
||||||
GIcon.refreshAll();
|
GIcon.refreshAll();
|
||||||
|
resetIcons(javaDefaults);
|
||||||
|
resetFonts(javaDefaults);
|
||||||
updateComponentUis();
|
updateComponentUis();
|
||||||
// repaintAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateColor(String id, Color color, boolean isJavaColor) {
|
private void resetFonts(GThemeValueMap javaDefaults) {
|
||||||
|
List<FontValue> fonts = javaDefaults.getFonts();
|
||||||
|
UIDefaults defaults = UIManager.getDefaults();
|
||||||
|
for (FontValue fontValue : fonts) {
|
||||||
|
String id = fontValue.getId();
|
||||||
|
Font correctFont = Gui.getFont(id);
|
||||||
|
Font storedFont = defaults.getFont(id);
|
||||||
|
if (correctFont != null && !correctFont.equals(storedFont)) {
|
||||||
|
defaults.put(id, correctFont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetIcons(GThemeValueMap javaDefaults) {
|
||||||
|
List<IconValue> icons = javaDefaults.getIcons();
|
||||||
|
UIDefaults defaults = UIManager.getDefaults();
|
||||||
|
for (IconValue iconValue : icons) {
|
||||||
|
String id = iconValue.getId();
|
||||||
|
Icon correctIcon = Gui.getRawIcon(id, false);
|
||||||
|
Icon storedIcon = defaults.getIcon(id);
|
||||||
|
if (correctIcon != null && !correctIcon.equals(storedIcon)) {
|
||||||
|
defaults.put(id, correctIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateColors() {
|
||||||
GColor.refreshAll();
|
GColor.refreshAll();
|
||||||
repaintAll();
|
repaintAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateIcon(String id, Icon icon, boolean isJavaIcon) {
|
public void updateIcons(String id, Set<String> affectedJavaIds, Icon newIcon) {
|
||||||
// Icons are a mixed bag. Java Icons are direct and Ghidra Icons are indirect (to support static use)
|
if (!affectedJavaIds.isEmpty()) {
|
||||||
// Mainly because Nimbus is buggy and can't handle non-nimbus Icons, so we can't wrap them
|
UIDefaults defaults = UIManager.getDefaults();
|
||||||
// So need to update UiDefaults for java icons. For Ghidra Icons, it is sufficient to refrech
|
for (String javaIconId : affectedJavaIds) {
|
||||||
// GIcons and repaint
|
defaults.put(javaIconId, newIcon);
|
||||||
if (isJavaIcon) {
|
}
|
||||||
UIManager.getDefaults().put(id, icon);
|
|
||||||
updateComponentUis();
|
updateComponentUis();
|
||||||
}
|
}
|
||||||
GIcon.refreshAll();
|
GIcon.refreshAll();
|
||||||
repaintAll();
|
repaintAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateFont(String id, Font font, boolean isJavaFont) {
|
public void updateFonts(String id, Set<String> affectedJavaIds, Font newFont) {
|
||||||
if (isJavaFont) {
|
if (!affectedJavaIds.isEmpty()) {
|
||||||
UIManager.getDefaults().put(id, font);
|
UIDefaults defaults = UIManager.getDefaults();
|
||||||
|
for (String javaFontId : affectedJavaIds) {
|
||||||
|
defaults.put(javaFontId, newFont);
|
||||||
|
}
|
||||||
updateComponentUis();
|
updateComponentUis();
|
||||||
}
|
}
|
||||||
else {
|
repaintAll();
|
||||||
repaintAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateComponentUis() {
|
protected void updateComponentUis() {
|
||||||
for (Window window : Window.getWindows()) {
|
for (Window window : Window.getWindows()) {
|
||||||
SwingUtilities.updateComponentTreeUI(window);
|
SwingUtilities.updateComponentTreeUI(window);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-77
@@ -15,11 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package generic.theme.laf;
|
package generic.theme.laf;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Dimension;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
|
|
||||||
|
|
||||||
import generic.theme.*;
|
import generic.theme.*;
|
||||||
|
|
||||||
@@ -37,7 +35,7 @@ public class NimbusLookAndFeelInstaller extends LookAndFeelInstaller {
|
|||||||
@Override
|
@Override
|
||||||
protected void installJavaDefaults() {
|
protected void installJavaDefaults() {
|
||||||
// even though java defaults have been installed, we need to fix them up now
|
// even though java defaults have been installed, we need to fix them up now
|
||||||
// that nimbus has finished initializing
|
// that Nimbus has finished initializing
|
||||||
GColor.refreshAll();
|
GColor.refreshAll();
|
||||||
Gui.setJavaDefaults(Gui.getJavaDefaults());
|
Gui.setJavaDefaults(Gui.getJavaDefaults());
|
||||||
}
|
}
|
||||||
@@ -53,77 +51,4 @@ public class NimbusLookAndFeelInstaller extends LookAndFeelInstaller {
|
|||||||
|
|
||||||
// (see NimbusDefaults for key values that can be changed here)
|
// (see NimbusDefaults for key values that can be changed here)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Extends the NimbusLookAndFeel to intercept the {@link #getDefaults()}. To get Nimbus
|
|
||||||
* to use our indirect values, we have to get in early.
|
|
||||||
*/
|
|
||||||
static class GNimbusLookAndFeel extends NimbusLookAndFeel {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UIDefaults getDefaults() {
|
|
||||||
UIDefaults defaults = super.getDefaults();
|
|
||||||
GThemeValueMap javaDefaults = extractJavaDefaults(defaults);
|
|
||||||
|
|
||||||
// need to set javaDefalts now to trigger building currentValues so the when
|
|
||||||
// we create GColors below, they can be resolved.
|
|
||||||
Gui.setJavaDefaults(javaDefaults);
|
|
||||||
|
|
||||||
// replace all colors with GColors
|
|
||||||
for (ColorValue colorValue : javaDefaults.getColors()) {
|
|
||||||
String id = colorValue.getId();
|
|
||||||
defaults.put(id, Gui.getGColorUiResource(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
GTheme theme = Gui.getActiveTheme();
|
|
||||||
|
|
||||||
// only replace fonts that have been changed by the theme
|
|
||||||
for (FontValue fontValue : theme.getFonts()) {
|
|
||||||
String id = fontValue.getId();
|
|
||||||
Font font = Gui.getFont(id);
|
|
||||||
defaults.put(id, font);
|
|
||||||
}
|
|
||||||
|
|
||||||
// only replace icons that have been changed by the theme
|
|
||||||
for (IconValue iconValue : theme.getIcons()) {
|
|
||||||
String id = iconValue.getId();
|
|
||||||
Icon icon = Gui.getRawIcon(id, true);
|
|
||||||
defaults.put(id, icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
defaults.put("Label.textForeground", Gui.getGColorUiResource("Label.foreground"));
|
|
||||||
GColor.refreshAll();
|
|
||||||
GIcon.refreshAll();
|
|
||||||
return defaults;
|
|
||||||
}
|
|
||||||
|
|
||||||
private GThemeValueMap extractJavaDefaults(UIDefaults defaults) {
|
|
||||||
GThemeValueMap javaDefaults = new GThemeValueMap();
|
|
||||||
|
|
||||||
List<String> colorIds =
|
|
||||||
LookAndFeelInstaller.getLookAndFeelIdsForType(defaults, Color.class);
|
|
||||||
for (String id : colorIds) {
|
|
||||||
Color color = defaults.getColor(id);
|
|
||||||
ColorValue value = new ColorValue(id, color);
|
|
||||||
javaDefaults.addColor(value);
|
|
||||||
}
|
|
||||||
List<String> fontIds =
|
|
||||||
LookAndFeelInstaller.getLookAndFeelIdsForType(defaults, Font.class);
|
|
||||||
for (String id : fontIds) {
|
|
||||||
Font font = defaults.getFont(id);
|
|
||||||
FontValue value = new FontValue(id, font);
|
|
||||||
javaDefaults.addFont(value);
|
|
||||||
}
|
|
||||||
List<String> iconIds =
|
|
||||||
LookAndFeelInstaller.getLookAndFeelIdsForType(defaults, Icon.class);
|
|
||||||
for (String id : iconIds) {
|
|
||||||
Icon icon = defaults.getIcon(id);
|
|
||||||
javaDefaults.addIcon(new IconValue(id, icon));
|
|
||||||
}
|
|
||||||
|
|
||||||
return javaDefaults;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-54
@@ -15,14 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package generic.theme.laf;
|
package generic.theme.laf;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Font;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import generic.theme.LafType;
|
import generic.theme.*;
|
||||||
|
import ghidra.util.exception.AssertException;
|
||||||
|
|
||||||
public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
||||||
private UIDefaults overrides = new UIDefaults();
|
|
||||||
|
|
||||||
public NimbusLookAndFeelManager() {
|
public NimbusLookAndFeelManager() {
|
||||||
super(LafType.NIMBUS);
|
super(LafType.NIMBUS);
|
||||||
@@ -34,69 +35,39 @@ public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateColor(String id, Color color, boolean isJavaColor) {
|
public void resetAll(GThemeValueMap javaDefaults) {
|
||||||
super.updateColor(id, color, isJavaColor);
|
GColor.refreshAll();
|
||||||
|
GIcon.refreshAll();
|
||||||
|
reinstallNimubus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void updateFonts(String id, Set<String> affectedJavaIds, Font newFont) {
|
||||||
public void updateFont(String id, Font font, boolean isJavaFont) {
|
if (!affectedJavaIds.isEmpty()) {
|
||||||
if (isJavaFont) {
|
reinstallNimubus();
|
||||||
overrides.put(id, font);
|
|
||||||
updateNimbusOverrides();
|
|
||||||
}
|
}
|
||||||
repaintAll();
|
repaintAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void updateIcons(String id, Set<String> affectedJavaIds, Icon newIcon) {
|
||||||
public void updateIcon(String id, Icon icon, boolean isJavaIcon) {
|
if (!affectedJavaIds.isEmpty()) {
|
||||||
if (isJavaIcon) {
|
reinstallNimubus();
|
||||||
overrides.put(id, icon);
|
|
||||||
updateNimbusOverrides();
|
|
||||||
}
|
}
|
||||||
|
GIcon.refreshAll();
|
||||||
repaintAll();
|
repaintAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateNimbusOverrides() {
|
private void reinstallNimubus() {
|
||||||
UIDefaults defaults = getNimbusOverrides();
|
try {
|
||||||
for (Window window : Window.getWindows()) {
|
UIManager.setLookAndFeel(new GNimbusLookAndFeel() {
|
||||||
updateNimbusUI(window, defaults);
|
protected GThemeValueMap extractJavaDefaults(UIDefaults defaults) {
|
||||||
|
return Gui.getJavaDefaults();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
catch (UnsupportedLookAndFeelException e) {
|
||||||
|
throw new AssertException("This can't happen, we are just re-installing the same L&F");
|
||||||
private void updateNimbusUI(Component c, UIDefaults defaults) {
|
|
||||||
updateNimbusUIComp(c, defaults);
|
|
||||||
c.invalidate();
|
|
||||||
c.validate();
|
|
||||||
c.repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
private UIDefaults getNimbusOverrides() {
|
|
||||||
UIDefaults defaults = new UIDefaults();
|
|
||||||
defaults.putAll(overrides);
|
|
||||||
return defaults;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateNimbusUIComp(Component c, UIDefaults defaults) {
|
|
||||||
if (c instanceof JComponent) {
|
|
||||||
JComponent jc = (JComponent) c;
|
|
||||||
jc.putClientProperty("Nimbus.Overrides", defaults);
|
|
||||||
JPopupMenu jpm = jc.getComponentPopupMenu();
|
|
||||||
if (jpm != null) {
|
|
||||||
updateNimbusUI(jpm, defaults);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component[] children = null;
|
|
||||||
if (c instanceof JMenu) {
|
|
||||||
children = ((JMenu) c).getMenuComponents();
|
|
||||||
}
|
|
||||||
else if (c instanceof Container) {
|
|
||||||
children = ((Container) c).getComponents();
|
|
||||||
}
|
|
||||||
if (children != null) {
|
|
||||||
for (Component child : children) {
|
|
||||||
updateNimbusUIComp(child, defaults);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
updateComponentUis();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package generic.theme;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ColorValueTest {
|
||||||
|
|
||||||
|
private GThemeValueMap values;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
values = new GThemeValueMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectValue() {
|
||||||
|
ColorValue value = new ColorValue("color.test", Color.RED);
|
||||||
|
values.addColor(value);
|
||||||
|
|
||||||
|
assertEquals("color.test", value.getId());
|
||||||
|
assertEquals(Color.RED, value.getRawValue());
|
||||||
|
assertNull(value.getReferenceId());
|
||||||
|
assertEquals(Color.RED, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIndirectValue() {
|
||||||
|
values.addColor(new ColorValue("color.parent", Color.RED));
|
||||||
|
ColorValue value = new ColorValue("color.test", "color.parent");
|
||||||
|
values.addColor(value);
|
||||||
|
|
||||||
|
assertEquals("color.test", value.getId());
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
assertEquals("color.parent", value.getReferenceId());
|
||||||
|
assertEquals(Color.RED, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void TestIndirectMultiHopValue() {
|
||||||
|
values.addColor(new ColorValue("color.grandparent", Color.RED));
|
||||||
|
values.addColor(new ColorValue("color.parent", "color.grandparent"));
|
||||||
|
ColorValue value = new ColorValue("color.test", "color.parent");
|
||||||
|
values.addColor(value);
|
||||||
|
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
assertEquals("color.parent", value.getReferenceId());
|
||||||
|
assertEquals(Color.RED, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void TestUnresolvedIndirectValue() {
|
||||||
|
ColorValue value = new ColorValue("color.test", "color.parent");
|
||||||
|
values.addColor(value);
|
||||||
|
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
assertEquals("color.parent", value.getReferenceId());
|
||||||
|
assertEquals(ColorValue.LAST_RESORT_DEFAULT, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReferenceLoop() {
|
||||||
|
values.addColor(new ColorValue("color.grandparent", "color.test"));
|
||||||
|
values.addColor(new ColorValue("color.parent", "color.grandparent"));
|
||||||
|
ColorValue value = new ColorValue("color.test", "color.parent");
|
||||||
|
assertEquals(ColorValue.LAST_RESORT_DEFAULT, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToExernalId() {
|
||||||
|
ColorValue value = new ColorValue("color.test", Color.BLUE);
|
||||||
|
assertEquals("color.test", value.toExternalId("color.test"));
|
||||||
|
assertEquals("[color]foo.bar", value.toExternalId("foo.bar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromExternalId() {
|
||||||
|
ColorValue value = new ColorValue("color.test", Color.BLUE);
|
||||||
|
assertEquals("color.test", value.fromExternalId("color.test"));
|
||||||
|
assertEquals("foo.bar", value.fromExternalId("[color]foo.bar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsColorKey() {
|
||||||
|
assertTrue(ColorValue.isColorKey("color.a.b.c"));
|
||||||
|
assertTrue(ColorValue.isColorKey("[color]a.b.c"));
|
||||||
|
assertFalse(ColorValue.isColorKey("a.b.c"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInheritsFrom() {
|
||||||
|
ColorValue grandParent = new ColorValue("color.grandparent", Color.RED);
|
||||||
|
values.addColor(grandParent);
|
||||||
|
ColorValue parent = new ColorValue("color.parent", "color.grandparent");
|
||||||
|
values.addColor(parent);
|
||||||
|
ColorValue value = new ColorValue("color.test", "color.parent");
|
||||||
|
values.addColor(value);
|
||||||
|
|
||||||
|
assertTrue(value.inheritsFrom("color.parent", values));
|
||||||
|
assertTrue(value.inheritsFrom("color.grandparent", values));
|
||||||
|
assertTrue(parent.inheritsFrom("color.grandparent", values));
|
||||||
|
|
||||||
|
assertFalse(value.inheritsFrom("color.test", values));
|
||||||
|
assertFalse(parent.inheritsFrom("color.test", values));
|
||||||
|
assertFalse(grandParent.inheritsFrom("color.test", values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreatingValueFromGColor() {
|
||||||
|
ColorValue parent = new ColorValue("color.parent", Color.RED);
|
||||||
|
values.addColor(parent);
|
||||||
|
Color gColor = new GColor("color.parent");
|
||||||
|
ColorValue value = new ColorValue("color.value", gColor);
|
||||||
|
assertEquals("color.parent", value.getReferenceId());
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package generic.theme;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.awt.Font;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import generic.theme.FontValue;
|
||||||
|
import generic.theme.GThemeValueMap;
|
||||||
|
|
||||||
|
public class FontValueTest {
|
||||||
|
private static Font FONT = new Font("Dialog", 12, Font.PLAIN);
|
||||||
|
private GThemeValueMap values;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
values = new GThemeValueMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectValue() {
|
||||||
|
FontValue value = new FontValue("font.test", FONT);
|
||||||
|
values.addFont(value);
|
||||||
|
|
||||||
|
assertEquals("font.test", value.getId());
|
||||||
|
assertEquals(FONT, value.getRawValue());
|
||||||
|
assertNull(value.getReferenceId());
|
||||||
|
assertEquals(FONT, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIndirectValue() {
|
||||||
|
values.addFont(new FontValue("font.parent", FONT));
|
||||||
|
FontValue value = new FontValue("font.test", "font.parent");
|
||||||
|
values.addFont(value);
|
||||||
|
|
||||||
|
assertEquals("font.test", value.getId());
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
assertEquals("font.parent", value.getReferenceId());
|
||||||
|
assertEquals(FONT, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void TestIndirectMultiHopValue() {
|
||||||
|
values.addFont(new FontValue("font.grandparent", FONT));
|
||||||
|
values.addFont(new FontValue("font.parent", "font.grandparent"));
|
||||||
|
FontValue value = new FontValue("font.test", "font.parent");
|
||||||
|
values.addFont(value);
|
||||||
|
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
assertEquals("font.parent", value.getReferenceId());
|
||||||
|
assertEquals(FONT, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void TestUnresolvedIndirectValue() {
|
||||||
|
FontValue value = new FontValue("font.test", "font.parent");
|
||||||
|
values.addFont(value);
|
||||||
|
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
assertEquals("font.parent", value.getReferenceId());
|
||||||
|
assertEquals(FontValue.LAST_RESORT_DEFAULT, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReferenceLoop() {
|
||||||
|
values.addFont(new FontValue("font.grandparent", "font.test"));
|
||||||
|
values.addFont(new FontValue("font.parent", "font.grandparent"));
|
||||||
|
FontValue value = new FontValue("font.test", "font.parent");
|
||||||
|
assertEquals(FontValue.LAST_RESORT_DEFAULT, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToExernalId() {
|
||||||
|
FontValue value = new FontValue("font.test", FONT);
|
||||||
|
assertEquals("font.test", value.toExternalId("font.test"));
|
||||||
|
assertEquals("[font]foo.bar", value.toExternalId("foo.bar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromExternalId() {
|
||||||
|
FontValue value = new FontValue("font.test", FONT);
|
||||||
|
assertEquals("font.test", value.fromExternalId("font.test"));
|
||||||
|
assertEquals("foo.bar", value.fromExternalId("[font]foo.bar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsFontKey() {
|
||||||
|
assertTrue(FontValue.isFontKey("font.a.b.c"));
|
||||||
|
assertTrue(FontValue.isFontKey("[font]a.b.c"));
|
||||||
|
assertFalse(FontValue.isFontKey("a.b.c"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInheritsFrom() {
|
||||||
|
FontValue grandParent = new FontValue("font.grandparent", FONT);
|
||||||
|
values.addFont(grandParent);
|
||||||
|
FontValue parent = new FontValue("font.parent", "font.grandparent");
|
||||||
|
values.addFont(parent);
|
||||||
|
FontValue value = new FontValue("font.test", "font.parent");
|
||||||
|
values.addFont(value);
|
||||||
|
|
||||||
|
assertTrue(value.inheritsFrom("font.parent", values));
|
||||||
|
assertTrue(value.inheritsFrom("font.grandparent", values));
|
||||||
|
assertTrue(parent.inheritsFrom("font.grandparent", values));
|
||||||
|
|
||||||
|
assertFalse(value.inheritsFrom("font.test", values));
|
||||||
|
assertFalse(parent.inheritsFrom("font.test", values));
|
||||||
|
assertFalse(grandParent.inheritsFrom("font.test", values));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-10
@@ -13,20 +13,12 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package docking.theme;
|
package generic.theme;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.commons.collections4.map.HashedMap;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
import docking.test.AbstractDockingTest;
|
public class GuiTest {
|
||||||
import generic.theme.*;
|
|
||||||
|
|
||||||
public class GuiTest extends AbstractDockingTest {
|
|
||||||
|
|
||||||
private Map<String, List<String>> aliasMap = new HashedMap<>();
|
|
||||||
private GThemeValueMap darkValues = new GThemeValueMap();
|
private GThemeValueMap darkValues = new GThemeValueMap();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package generic.theme;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import javax.swing.Icon;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import resources.ResourceManager;
|
||||||
|
|
||||||
|
public class IconValueTest {
|
||||||
|
private static Icon ICON1 = ResourceManager.getDefaultIcon();
|
||||||
|
private GThemeValueMap values;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
values = new GThemeValueMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectValue() {
|
||||||
|
IconValue value = new IconValue("icon.test", ICON1);
|
||||||
|
values.addIcon(value);
|
||||||
|
|
||||||
|
assertEquals("icon.test", value.getId());
|
||||||
|
assertEquals(ICON1, value.getRawValue());
|
||||||
|
assertNull(value.getReferenceId());
|
||||||
|
assertEquals(ICON1, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIndirectValue() {
|
||||||
|
values.addIcon(new IconValue("icon.parent", ICON1));
|
||||||
|
IconValue value = new IconValue("icon.test", "icon.parent");
|
||||||
|
values.addIcon(value);
|
||||||
|
|
||||||
|
assertEquals("icon.test", value.getId());
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
assertEquals("icon.parent", value.getReferenceId());
|
||||||
|
assertEquals(ICON1, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void TestIndirectMultiHopValue() {
|
||||||
|
values.addIcon(new IconValue("icon.grandparent", ICON1));
|
||||||
|
values.addIcon(new IconValue("icon.parent", "icon.grandparent"));
|
||||||
|
IconValue value = new IconValue("icon.test", "icon.parent");
|
||||||
|
values.addIcon(value);
|
||||||
|
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
assertEquals("icon.parent", value.getReferenceId());
|
||||||
|
assertEquals(ICON1, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void TestUnresolvedIndirectValue() {
|
||||||
|
IconValue value = new IconValue("icon.test", "icon.parent");
|
||||||
|
values.addIcon(value);
|
||||||
|
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
assertEquals("icon.parent", value.getReferenceId());
|
||||||
|
assertEquals(IconValue.LAST_RESORT_DEFAULT, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReferenceLoop() {
|
||||||
|
values.addIcon(new IconValue("icon.grandparent", "icon.test"));
|
||||||
|
values.addIcon(new IconValue("icon.parent", "icon.grandparent"));
|
||||||
|
IconValue value = new IconValue("icon.test", "icon.parent");
|
||||||
|
assertEquals(IconValue.LAST_RESORT_DEFAULT, value.get(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToExernalId() {
|
||||||
|
IconValue value = new IconValue("icon.test", ICON1);
|
||||||
|
assertEquals("icon.test", value.toExternalId("icon.test"));
|
||||||
|
assertEquals("[icon]foo.bar", value.toExternalId("foo.bar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromExternalId() {
|
||||||
|
IconValue value = new IconValue("icon.test", ICON1);
|
||||||
|
assertEquals("icon.test", value.fromExternalId("icon.test"));
|
||||||
|
assertEquals("foo.bar", value.fromExternalId("[icon]foo.bar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsIconKey() {
|
||||||
|
assertTrue(IconValue.isIconKey("icon.a.b.c"));
|
||||||
|
assertTrue(IconValue.isIconKey("[icon]a.b.c"));
|
||||||
|
assertFalse(IconValue.isIconKey("a.b.c"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInheritsFrom() {
|
||||||
|
IconValue grandParent = new IconValue("icon.grandparent", ICON1);
|
||||||
|
values.addIcon(grandParent);
|
||||||
|
IconValue parent = new IconValue("icon.parent", "icon.grandparent");
|
||||||
|
values.addIcon(parent);
|
||||||
|
IconValue value = new IconValue("icon.test", "icon.parent");
|
||||||
|
values.addIcon(value);
|
||||||
|
|
||||||
|
assertTrue(value.inheritsFrom("icon.parent", values));
|
||||||
|
assertTrue(value.inheritsFrom("icon.grandparent", values));
|
||||||
|
assertTrue(parent.inheritsFrom("icon.grandparent", values));
|
||||||
|
|
||||||
|
assertFalse(value.inheritsFrom("icon.test", values));
|
||||||
|
assertFalse(parent.inheritsFrom("icon.test", values));
|
||||||
|
assertFalse(grandParent.inheritsFrom("icon.test", values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreatingValueFromGIcon() {
|
||||||
|
IconValue parent = new IconValue("icon.parent", ICON1);
|
||||||
|
values.addIcon(parent);
|
||||||
|
Icon gIcon = new GIcon("icon.parent");
|
||||||
|
IconValue value = new IconValue("icon.value", gIcon);
|
||||||
|
assertEquals("icon.parent", value.getReferenceId());
|
||||||
|
assertNull(value.getRawValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package generic.theme;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
|
||||||
|
import javax.swing.Icon;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import resources.ResourceManager;
|
||||||
|
|
||||||
|
public class ThemeEventTest {
|
||||||
|
private static Font FONT1 = new Font("Dialog", 12, Font.PLAIN);
|
||||||
|
private static Font FONT2 = new Font("Dialog", 14, Font.PLAIN);
|
||||||
|
private static Icon ICON1 = ResourceManager.loadImage("images/flag.png");
|
||||||
|
private static Icon ICON2 = ResourceManager.loadImage("images/exec.png");
|
||||||
|
|
||||||
|
private GThemeValueMap values;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
values = new GThemeValueMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsColorChangedDirect() {
|
||||||
|
ColorValue value = new ColorValue("color.value", Color.RED);
|
||||||
|
values.addColor(value);
|
||||||
|
ColorValue newValue = new ColorValue("color.value", Color.BLUE);
|
||||||
|
values.addColor(value);
|
||||||
|
|
||||||
|
ColorChangedThemeEvent event = new ColorChangedThemeEvent(values, newValue);
|
||||||
|
assertTrue(event.isColorChanged("color.value"));
|
||||||
|
assertFalse(event.isColorChanged("color.othervalue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsColorChangedIndirect() {
|
||||||
|
ColorValue parent = new ColorValue("color.parent", Color.RED);
|
||||||
|
values.addColor(parent);
|
||||||
|
ColorValue value = new ColorValue("color.value", "color.parent");
|
||||||
|
values.addColor(value);
|
||||||
|
|
||||||
|
ColorValue newValue = new ColorValue("color.parent", Color.BLUE);
|
||||||
|
values.addColor(value);
|
||||||
|
|
||||||
|
ColorChangedThemeEvent event = new ColorChangedThemeEvent(values, newValue);
|
||||||
|
assertTrue(event.isColorChanged("color.parent"));
|
||||||
|
assertTrue(event.isColorChanged("color.value"));
|
||||||
|
assertFalse(event.isColorChanged("color.othervalue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsFontChangedDirect() {
|
||||||
|
FontValue value = new FontValue("font.value", FONT1);
|
||||||
|
values.addFont(value);
|
||||||
|
FontValue newValue = new FontValue("font.value", FONT2);
|
||||||
|
values.addFont(value);
|
||||||
|
|
||||||
|
FontChangedThemeEvent event = new FontChangedThemeEvent(values, newValue);
|
||||||
|
assertTrue(event.isFontChanged("font.value"));
|
||||||
|
assertFalse(event.isFontChanged("font.othervalue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsFontChangedIndirect() {
|
||||||
|
FontValue parent = new FontValue("font.parent", FONT1);
|
||||||
|
values.addFont(parent);
|
||||||
|
FontValue value = new FontValue("font.value", "font.parent");
|
||||||
|
values.addFont(value);
|
||||||
|
|
||||||
|
FontValue newValue = new FontValue("font.parent", FONT2);
|
||||||
|
values.addFont(value);
|
||||||
|
|
||||||
|
FontChangedThemeEvent event = new FontChangedThemeEvent(values, newValue);
|
||||||
|
assertTrue(event.isFontChanged("font.parent"));
|
||||||
|
assertTrue(event.isFontChanged("font.value"));
|
||||||
|
assertFalse(event.isFontChanged("font.othervalue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsIconChangedDirect() {
|
||||||
|
IconValue value = new IconValue("ICON.value", ICON1);
|
||||||
|
values.addIcon(value);
|
||||||
|
IconValue newValue = new IconValue("icon.value", ICON2);
|
||||||
|
values.addIcon(value);
|
||||||
|
|
||||||
|
IconChangedThemeEvent event = new IconChangedThemeEvent(values, newValue);
|
||||||
|
assertTrue(event.isIconChanged("icon.value"));
|
||||||
|
assertFalse(event.isIconChanged("icon.othervalue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsIconChangedIndirect() {
|
||||||
|
IconValue parent = new IconValue("icon.parent", ICON1);
|
||||||
|
values.addIcon(parent);
|
||||||
|
IconValue value = new IconValue("icon.value", "icon.parent");
|
||||||
|
values.addIcon(value);
|
||||||
|
|
||||||
|
IconValue newValue = new IconValue("icon.parent", ICON2);
|
||||||
|
values.addIcon(value);
|
||||||
|
|
||||||
|
IconChangedThemeEvent event = new IconChangedThemeEvent(values, newValue);
|
||||||
|
assertTrue(event.isIconChanged("icon.parent"));
|
||||||
|
assertTrue(event.isIconChanged("icon.value"));
|
||||||
|
assertFalse(event.isIconChanged("icon.othervalue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user