GP-2961 - Theme Fixes - Many changes to deal with odd rendering behavior in Nimbus and the Flat LaFs.

This commit is contained in:
dragonmacher
2022-12-29 14:51:25 -05:00
parent f443b2a907
commit fc301bb386
24 changed files with 274 additions and 167 deletions

View File

@@ -8,6 +8,7 @@
##MODULE IP: Tango Icons - Public Domain
.classpath||GHIDRA||||END|
Module.manifest||GHIDRA||||END|
data/gui.laf.overrides.theme.properties||GHIDRA||||END|
data/gui.palette.theme.properties||GHIDRA||||END|
data/gui.theme.properties||GHIDRA||||END|
src/main/java/ghidra/framework/options/package.html||GHIDRA||||END|

View File

@@ -0,0 +1,55 @@
[Defaults]
// TODO these are only here because they are used in the dark section; remove from here if done in
// source code instead; otherwise, update error reporting to not require an entry in the default
// section for values defined in specific LaF sections
color.flat.text.original.bg = white // default 'text' value in Flat Light
color.flat.selection.inactive.bg = #d3d3d3 // default value in Flat Light
[Dark Defaults]
[Flat Dark]
// the default inactive selection color is too close to the bg color to be easily visible
color.flat.selection.inactive.bg = #0F4C6A
//
// We would like widgets to use a bg color. By default widgets and some other items are all mapped
// to 'text'. The easiest way to change all widgets is to change the value of 'text'. Then, for
// any values that should still use the old value, we need to remap those. (The foreground colors
// for these are mapped to 'textText'. For now, that value seems good enough that we do not need
// to change it.)
//
color.flat.text.original.bg = #46494b // default 'text' value
[color]text = color.bg
[color]desktop = color.flat.text.original.bg
[color]TableHeader = color.flat.text.original.bg
[color]Checkbox.icon.background = color.flat.text.original.bg
[color]Checkbox.icon.selectedBackground = color.flat.text.original.bg
[color]CheckBox.icon[filled].checkmarkColor = color.flat.text.original.bg
[color]ComboBox.buttonBackground = color.flat.text.original.bg
[color]Spinner.background = color.flat.text.original.bg
[color]TextArea.background = color.bg
[color]TextArea.foreground = color.fg
[color]TextPane.background = color.bg
[color]TextPane.foreground = color.fg
[Nimbus]
// Nimbus uses the ToolTipPainter class to paint tooltips. That class does not read the property
// we use for tooltips, which is 'ToolTip.background', even though that is defined by the LaF.
// Setting the 'info' value here to changes the key the painter users to paint tooltips. The info
// value seems to only be used for tooltips, which means this change affects no other components.
[color]info = [color]ToolTip.background

View File

@@ -128,11 +128,6 @@ color.bg.tree = color.bg
color.bg.tree.selected = [color]Tree.selectionBackground
[Flat Dark]
// the default inactive selection color is too close to the bg color to be easily visible
color.flat.selection.inactive = #0F4C6A
[CDE/Motif]
@@ -140,10 +135,3 @@ color.bg = [color]window // gray for motif
color.fg = [color]textText
[Nimbus]
// Nimbus uses the ToolTipPainter class to paint tooltips. That class does not read the property
// we use for tooltips, which is 'ToolTip.background', even though that is defined by the LaF.
// Setting the 'info' value here to changes the key the painter users to paint tooltips. The info
// value seems to only be used for tooltips, which means this change affects no other components.
[color]info = [color]ToolTip.background

View File

@@ -61,6 +61,11 @@ public class ColorValue extends ThemeValue<Color> {
return outputId + " = " + getSerializedValue();
}
@Override
public boolean isExternal() {
return !id.startsWith(COLOR_ID_PREFIX);
}
/**
* Returns true if the given key string is a valid external key for a color value
* @param key the key string to test
@@ -93,7 +98,7 @@ public class ColorValue extends ThemeValue<Color> {
}
@Override
protected Color getUnresolvedReferenceValue(String id, String unresolvedId) {
protected Color getUnresolvedReferenceValue(String primaryId, String unresolvedId) {
Throwable t = ReflectionUtilities.createThrowableWithStackOlderThan();
StackTraceElement[] trace = t.getStackTrace();
@@ -104,7 +109,7 @@ public class ColorValue extends ThemeValue<Color> {
Msg.error(this,
"Could not resolve indirect color path for \"" + unresolvedId +
"\" for primary id \"" + id + "\", using last resort default",
"\" for primary id \"" + primaryId + "\", using last resort default",
t);
return LAST_RESORT_DEFAULT;
}

View File

@@ -57,6 +57,17 @@ public class FontValue extends ThemeValue<Font> {
this.modifier = modifier;
}
@Override
public String getSerializationString() {
String outputId = toExternalId(id);
return outputId + " = " + getValueOutput();
}
@Override
public boolean isExternal() {
return !id.startsWith(FONT_ID_PREFIX);
}
@Override
public Font get(GThemeValueMap values) {
Font font = super.get(values);
@@ -66,12 +77,6 @@ public class FontValue extends ThemeValue<Font> {
return font;
}
@Override
public String getSerializationString() {
String outputId = toExternalId(id);
return outputId + " = " + getValueOutput();
}
private String getValueOutput() {
if (referenceId != null) {
String refId = toExternalId(referenceId);
@@ -107,7 +112,7 @@ public class FontValue extends ThemeValue<Font> {
* @param key the key to associate the parsed value with
* @param value the font value to parse
* @return a FontValue with the given key and the parsed value
* @throws ParseException
* @throws ParseException if there is an exception parsing
*/
public static FontValue parse(String key, String value) throws ParseException {
String id = fromExternalId(key);
@@ -148,10 +153,10 @@ public class FontValue extends ThemeValue<Font> {
}
@Override
protected Font getUnresolvedReferenceValue(String id, String unresolvedId) {
protected Font getUnresolvedReferenceValue(String primaryId, String unresolvedId) {
Msg.warn(this,
"Could not resolve indirect font path for \"" + unresolvedId +
"\" for primary id \"" + id + "\", using last resort default");
"\" for primary id \"" + primaryId + "\", using last resort default");
return LAST_RESORT_DEFAULT;
}

View File

@@ -74,6 +74,17 @@ public class IconValue extends ThemeValue<Icon> {
this.modifier = modifier;
}
@Override
public String getSerializationString() {
String outputId = toExternalId(id);
return outputId + " = " + getValueOutput();
}
@Override
public boolean isExternal() {
return !id.startsWith(ICON_ID_PREFIX);
}
@Override
public Icon get(GThemeValueMap values) {
Icon icon = super.get(values);
@@ -83,12 +94,6 @@ public class IconValue extends ThemeValue<Icon> {
return icon;
}
@Override
public String getSerializationString() {
String outputId = toExternalId(id);
return outputId + " = " + getValueOutput();
}
/**
* Returns true if the given key string is a valid external key for an icon value
* @param key the key string to test
@@ -197,10 +202,10 @@ public class IconValue extends ThemeValue<Icon> {
}
@Override
protected Icon getUnresolvedReferenceValue(String id, String unresolvedId) {
protected Icon getUnresolvedReferenceValue(String primaryId, String unresolvedId) {
Msg.warn(this,
"Could not resolve indirect icon path for \"" + unresolvedId +
"\" for primary id \"" + id + "\", using last resort default");
"\" for primary id \"" + primaryId + "\", using last resort default");
return LAST_RESORT_DEFAULT;
}

View File

@@ -79,6 +79,7 @@ public class ThemePropertyFileReader extends AbstractThemeReader {
return customSectionsMap;
}
@Override
protected void processNoSection(Section section) throws IOException {
if (!section.isEmpty()) {
error(section.getLineNumber(),
@@ -125,17 +126,26 @@ public class ThemePropertyFileReader extends AbstractThemeReader {
private void validate(String name, GThemeValueMap valuesMap) {
for (String id : valuesMap.getColorIds()) {
if (!defaults.containsColor(id)) {
reportMissingDefaultsError("Color", name, id);
ColorValue value = valuesMap.getColor(id);
if (!value.isExternal()) {
reportMissingDefaultsError("Color", name, id);
}
}
}
for (String id : valuesMap.getFontIds()) {
if (!defaults.containsFont(id)) {
reportMissingDefaultsError("Font", name, id);
FontValue value = valuesMap.getFont(id);
if (!value.isExternal()) {
reportMissingDefaultsError("Font", name, id);
}
}
}
for (String id : valuesMap.getIconIds()) {
if (!defaults.containsIcon(id)) {
reportMissingDefaultsError("Icon", name, id);
IconValue value = valuesMap.getIcon(id);
if (!value.isExternal()) {
reportMissingDefaultsError("Icon", name, id);
}
}
}
}

View File

@@ -41,6 +41,13 @@ public abstract class ThemeValue<T> implements Comparable<ThemeValue<T>> {
this.value = value;
}
/**
* True if this value is one that is one that is defined outside of the application, such as a
* Java Look and Feel key.
* @return true if external
*/
public abstract boolean isExternal();
/**
* Returns the identifier for this ThemeValue.
* @return the identifier for this ThemeValue.
@@ -189,11 +196,11 @@ public abstract class ThemeValue<T> implements Comparable<ThemeValue<T>> {
/**
* Returns the T to be used if the indirect reference couldn't be resolved.
* @param id the id we are trying to get a value foe
* @param primaryId the id we are trying to get a value for
* @param unresolvedId the reference id that couldn't be resolved
* @return the default value to be used if the indirect reference couldn't be resolved.
*/
protected abstract T getUnresolvedReferenceValue(String id, String unresolvedId);
protected abstract T getUnresolvedReferenceValue(String primaryId, String unresolvedId);
/**
* Returns the ThemeValue referred to by this ThemeValue. Needs to be overridden by