mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-24 12:55:47 +08:00
GP-2995 creating a better mapping of look and feel values to more standard ids and easier ways to override values for a specific LaF
This commit is contained in:
@@ -5,12 +5,12 @@ color.bg.currentline.listing = color.bg.currentline
|
||||
color.bg.selection.listing = color.bg.selection
|
||||
color.bg.highlight.listing = color.bg.highlight
|
||||
|
||||
color.bg.listing.tabs.selected = [color]textHighlight
|
||||
color.bg.listing.tabs.unselected = system.color.bg.application
|
||||
color.bg.listing.tabs.selected = [color]system.color.bg.selected.view
|
||||
color.bg.listing.tabs.unselected = [color]system.color.bg.control
|
||||
color.bg.listing.tabs.highlighted = #ABC8FF
|
||||
color.bg.listing.tabs.list = rgb(255, 255, 230)
|
||||
color.bg.listing.tabs.more.tabs.hover = rgb(255, 226, 213)
|
||||
color.fg.listing.tabs.text.selected = [color]textHighlightText
|
||||
color.fg.listing.tabs.text.selected = [color]system.color.fg.selected.view
|
||||
color.fg.listing.tabs.text.unselected = color.fg
|
||||
color.fg.listing.tabs.list = black
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ color.flowtype.fall.through = red
|
||||
color.flowtype.jump.conditional = #007C00 // dark green
|
||||
color.flowtype.jump.unconditional = blue
|
||||
|
||||
color.bg.table.selection.bundle = [color]textHighlight
|
||||
color.fg.table.selection.bundle = [color]textHighlightText
|
||||
color.bg.table.selection.bundle = [color]system.color.bg.selected.view
|
||||
color.fg.table.selection.bundle = [color]system.color.fg.selected.view
|
||||
color.fg.table.bundle.disabled = darkGray
|
||||
color.fg.table.bundle.busy = gray
|
||||
color.fg.table.bundle.inactive = black
|
||||
@@ -75,7 +75,7 @@ color.bg.plugin.datamgr.icon.highlight = rgb(204, 204, 255)
|
||||
color.fg.plugin.disassembledview.address = color.fg
|
||||
|
||||
color.bg.plugin.editors.compositeeditor.text = color.fg
|
||||
color.bg.plugin.editors.compositeeditor.line = system.color.border
|
||||
color.bg.plugin.editors.compositeeditor.line = [color]system.color.bg.border
|
||||
color.bg.plugin.editors.compositeeditor.line.interior = #D4D4D4
|
||||
color.bg.plugin.editors.compositeeditor.byte.header = #DFDFDF
|
||||
color.bg.plugin.editors.compositeeditor.bit.undefined = #F8F8F8
|
||||
@@ -182,8 +182,6 @@ color.flowtype.fall.through = rgb(164, 66, 66)
|
||||
color.flowtype.jump.conditional = rgb(95, 129, 157)
|
||||
color.flowtype.jump.unconditional = rgb(140, 148, 64)
|
||||
|
||||
color.bg.table.selection.bundle = [color]textHighlight
|
||||
color.fg.table.selection.bundle = [color]textHighlightText
|
||||
color.fg.table.bundle.disabled = lightGray
|
||||
color.fg.table.bundle.busy = gray
|
||||
color.fg.table.bundle.inactive = lightGray
|
||||
@@ -211,7 +209,7 @@ color.bg.plugin.datamgr.edge.default = deepskyblue
|
||||
color.bg.plugin.datamgr.edge.composite = plum
|
||||
color.bg.plugin.datamgr.edge.reference = deepskyblue
|
||||
|
||||
color.bg.plugin.editors.compositeeditor.byte.header = [color]text
|
||||
color.bg.plugin.editors.compositeeditor.byte.header = [color]system.color.bg.view
|
||||
|
||||
color.fg.plugin.equate.enum = deepskyblue
|
||||
|
||||
|
||||
+2
-3
@@ -46,7 +46,7 @@ import ghidra.util.bean.opteditor.OptionsVetoException;
|
||||
public abstract class AbstractReferenceHover extends AbstractConfigurableHover {
|
||||
|
||||
private static final int WINDOW_OFFSET = 50;
|
||||
private static final Color BACKGROUND_COLOR = Colors.BACKGROUND_TOOLTIP;
|
||||
private static final Color BACKGROUND_COLOR = Colors.BG_TOOLTIP;
|
||||
private static final Color FG_COLOR_NOT_IN_MEMORY = new GColor("color.fg.hint");
|
||||
|
||||
private CodeFormatService codeFormatService;
|
||||
@@ -128,8 +128,7 @@ public abstract class AbstractReferenceHover extends AbstractConfigurableHover {
|
||||
String widthOptionName = optionName + Options.DELIMITER + "Dialog Width";
|
||||
String heightOptionName = optionName + Options.DELIMITER + "Dialog Height";
|
||||
|
||||
if (optionName.equals(widthOptionName) ||
|
||||
optionName.equals(heightOptionName)) {
|
||||
if (optionName.equals(widthOptionName) || optionName.equals(heightOptionName)) {
|
||||
int dialogWidth = options.getInt(widthOptionName, 600);
|
||||
if (dialogWidth <= 0) {
|
||||
throw new OptionsVetoException(
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ import ghidra.app.plugin.core.console.CodeCompletion;
|
||||
public class CodeCompletionWindow extends JDialog {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/* from ReferenceHoverPlugin */
|
||||
private static final Color BACKGROUND_COLOR = Colors.BACKGROUND_TOOLTIP;
|
||||
private static final Color BACKGROUND_COLOR = Colors.BG_TOOLTIP;
|
||||
|
||||
protected final InterpreterPanel console;
|
||||
protected final JTextPane outputTextField;
|
||||
|
||||
+8
-5
@@ -36,6 +36,7 @@ import resources.ResourceManager;
|
||||
class DnDTreeCellRenderer extends DefaultTreeCellRenderer {
|
||||
private static final Color BACKGROUND_UNSELECTED = new GColor("color.bg.tree");
|
||||
private static final Color BACKGROUND_SELECTED = new GColor("color.bg.tree.selected");
|
||||
private static final Color FOREGROUND_SELECTED = new GColor("color.fg.tree.selected");
|
||||
|
||||
private static final String DISABLED_DOCS = "DisabledDocument.gif";
|
||||
private static final String DISABLED_FRAGMENT = "DisabledFragment";
|
||||
@@ -68,6 +69,7 @@ class DnDTreeCellRenderer extends DefaultTreeCellRenderer {
|
||||
private Color defaultNonSelectionColor;
|
||||
private Color selectionForDragColor;
|
||||
private Color nonSelectionForDragColor;
|
||||
private Color defaultTextSelectionColor;
|
||||
private int rowForFeedback;
|
||||
|
||||
/**
|
||||
@@ -77,6 +79,7 @@ class DnDTreeCellRenderer extends DefaultTreeCellRenderer {
|
||||
super();
|
||||
defaultNonSelectionColor = BACKGROUND_UNSELECTED;
|
||||
defaultSelectionColor = BACKGROUND_SELECTED;
|
||||
defaultTextSelectionColor = FOREGROUND_SELECTED;
|
||||
rowForFeedback = -1;
|
||||
|
||||
// disable HTML rendering
|
||||
@@ -168,12 +171,14 @@ class DnDTreeCellRenderer extends DefaultTreeCellRenderer {
|
||||
}
|
||||
else {
|
||||
setBackgroundSelectionColor(defaultSelectionColor);
|
||||
setTextSelectionColor(defaultTextSelectionColor);
|
||||
setBackgroundNonSelectionColor(defaultNonSelectionColor);
|
||||
}
|
||||
setToolTipText(null);
|
||||
}
|
||||
else {
|
||||
setBackgroundSelectionColor(defaultSelectionColor);
|
||||
setTextSelectionColor(defaultTextSelectionColor);
|
||||
setBackgroundNonSelectionColor(defaultNonSelectionColor);
|
||||
setToolTipText(dtree.getToolTipText(node));
|
||||
}
|
||||
@@ -315,11 +320,9 @@ class DnDTreeCellRenderer extends DefaultTreeCellRenderer {
|
||||
private void loadImages() {
|
||||
// try to load icon images
|
||||
iconMap = new HashMap<>();
|
||||
String[] iconIds =
|
||||
{ DOCS, FRAGMENT, EMPTY_FRAGMENT, VIEWED_FRAGMENT, VIEWED_EMPTY_FRAGMENT,
|
||||
VIEWED_CLOSED_FOLDER, VIEWED_OPEN_FOLDER, VIEWED_CLOSED_FOLDER_WITH_DESC,
|
||||
CLOSED_FOLDER, OPEN_FOLDER,
|
||||
};
|
||||
String[] iconIds = { DOCS, FRAGMENT, EMPTY_FRAGMENT, VIEWED_FRAGMENT, VIEWED_EMPTY_FRAGMENT,
|
||||
VIEWED_CLOSED_FOLDER, VIEWED_OPEN_FOLDER, VIEWED_CLOSED_FOLDER_WITH_DESC, CLOSED_FOLDER,
|
||||
OPEN_FOLDER, };
|
||||
String[] disabledNames = { DISABLED_DOCS, DISABLED_FRAGMENT, DISABLED_EMPTY_FRAGMENT,
|
||||
DISABLED_VIEWED_EMPTY_FRAGMENT, DISABLED_VIEWED_FRAGMENT, DISABLED_VIEWED_CLOSED_FOLDER,
|
||||
DISABLED_VIEWED_OPEN_FOLDER, DISABLED_VIEWED_CLOSED_FOLDER_WITH_DESC,
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ import ghidra.program.util.ProgramSelection;
|
||||
*/
|
||||
public interface FGVertex extends VisualVertex {
|
||||
|
||||
static final Color TOOLTIP_BACKGROUND_COLOR = Colors.BACKGROUND_TOOLTIP;
|
||||
static final Color TOOLTIP_BACKGROUND_COLOR = Colors.BG_TOOLTIP;
|
||||
|
||||
public FGVertex cloneVertex(FGController newController);
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
color.bg.splashscreen = black
|
||||
color.fg.splashscreen = gray
|
||||
|
||||
color.bg.header.active = [color]textHighlight
|
||||
color.bg.header.active = [color]system.color.bg.selected.view
|
||||
color.bg.header.inactive = #A1A1A1
|
||||
color.fg.header.active = [color]textHighlightText
|
||||
color.fg.header.active = [color]system.color.fg.selected.view
|
||||
color.fg.header.inactive = black
|
||||
color.header.drag.cursor = black
|
||||
|
||||
@@ -170,7 +170,7 @@ color.bg.fieldpanel.selection.and.highlight = #344028 // yellow greenish
|
||||
// docking buttons
|
||||
color.fg.button = darkGray
|
||||
|
||||
color.bg.filechooser.shortcut = system.color.bg.widget
|
||||
color.bg.filechooser.shortcut = [color]system.color.bg.view
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ public class EditWindow extends JWindow {
|
||||
private void create() {
|
||||
textField = new JTextField(" ");
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
Color bgColor = Colors.BACKGROUND_TOOLTIP;
|
||||
Color bgColor = Colors.BG_TOOLTIP;
|
||||
panel.setBackground(bgColor);
|
||||
panel.add(textField, BorderLayout.CENTER);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class SplitPanel extends JPanel {
|
||||
this.rightComp = rightComp;
|
||||
this.isHorizontal = isHorizontal;
|
||||
divider = new Divider();
|
||||
divider.setBackground(new GColor("SplitPane.background"));
|
||||
divider.setBackground(new GColor("laf.color.SplitPane.background"));
|
||||
add(leftComp);
|
||||
add(divider);
|
||||
add(rightComp);
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/* ###
|
||||
* 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 docking.theme.gui;
|
||||
|
||||
import generic.theme.GThemeValueMap;
|
||||
import generic.theme.ThemeManager;
|
||||
|
||||
/**
|
||||
* Shares values for the three theme value tables so they all don't have their own copies
|
||||
*/
|
||||
public class GThemeValuesCache {
|
||||
|
||||
private ThemeManager themeManager;
|
||||
private GThemeValueMap currentValues;
|
||||
private GThemeValueMap themeValues;
|
||||
private GThemeValueMap defaultValues;
|
||||
private GThemeValueMap lightValues;
|
||||
private GThemeValueMap darkValues;
|
||||
|
||||
public GThemeValuesCache(ThemeManager themeManager) {
|
||||
this.themeManager = themeManager;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
currentValues = null;
|
||||
themeValues = null;
|
||||
defaultValues = null;
|
||||
lightValues = null;
|
||||
darkValues = null;
|
||||
}
|
||||
|
||||
public GThemeValueMap getCurrentValues() {
|
||||
if (currentValues == null) {
|
||||
currentValues = themeManager.getCurrentValues();
|
||||
}
|
||||
return currentValues;
|
||||
}
|
||||
|
||||
public GThemeValueMap getThemeValues() {
|
||||
if (themeValues == null) {
|
||||
themeValues = themeManager.getThemeValues();
|
||||
}
|
||||
return themeValues;
|
||||
}
|
||||
|
||||
public GThemeValueMap getDefaultValues() {
|
||||
if (defaultValues == null) {
|
||||
defaultValues = themeManager.getDefaults();
|
||||
}
|
||||
return defaultValues;
|
||||
}
|
||||
|
||||
public GThemeValueMap getLightValues() {
|
||||
if (lightValues == null) {
|
||||
lightValues = themeManager.getApplicationLightDefaults();
|
||||
}
|
||||
return lightValues;
|
||||
}
|
||||
|
||||
public GThemeValueMap getDarkValues() {
|
||||
if (darkValues == null) {
|
||||
darkValues = themeManager.getApplicationDarkDefaults();
|
||||
}
|
||||
return darkValues;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,14 +43,14 @@ public class ThemeColorTable extends JPanel implements ActionContextProvider {
|
||||
private GFilterTable<ColorValue> filterTable;
|
||||
private ThemeManager themeManager;
|
||||
|
||||
public ThemeColorTable(ThemeManager themeManager) {
|
||||
public ThemeColorTable(ThemeManager themeManager, GThemeValuesCache valuesProvider) {
|
||||
super(new BorderLayout());
|
||||
this.themeManager = themeManager;
|
||||
colorTableModel = new ThemeColorTableModel(themeManager);
|
||||
colorTableModel = new ThemeColorTableModel(valuesProvider);
|
||||
|
||||
filterTable = new GFilterTable<>(colorTableModel);
|
||||
table = filterTable.getTable();
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
|
||||
|
||||
table.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
|
||||
+14
-16
@@ -43,11 +43,11 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
||||
private GThemeValueMap defaultValues;
|
||||
private GThemeValueMap lightDefaultValues;
|
||||
private GThemeValueMap darkDefaultValues;
|
||||
private ThemeManager themeManager;
|
||||
private GThemeValuesCache valuesCache;
|
||||
|
||||
public ThemeColorTableModel(ThemeManager themeManager) {
|
||||
public ThemeColorTableModel(GThemeValuesCache valuesProvider) {
|
||||
super(new ServiceProviderStub());
|
||||
this.themeManager = themeManager;
|
||||
this.valuesCache = valuesProvider;
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
||||
* Reloads the just the current values shown in the table. Called whenever a color changes.
|
||||
*/
|
||||
public void reloadCurrent() {
|
||||
currentValues = themeManager.getCurrentValues();
|
||||
currentValues = valuesCache.getCurrentValues();
|
||||
colors = currentValues.getColors();
|
||||
fireTableDataChanged();
|
||||
}
|
||||
@@ -74,12 +74,12 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
||||
}
|
||||
|
||||
private void load() {
|
||||
currentValues = themeManager.getCurrentValues();
|
||||
currentValues = valuesCache.getCurrentValues();
|
||||
colors = currentValues.getColors();
|
||||
themeValues = themeManager.getThemeValues();
|
||||
defaultValues = themeManager.getDefaults();
|
||||
lightDefaultValues = themeManager.getApplicationLightDefaults();
|
||||
darkDefaultValues = themeManager.getApplicationDarkDefaults();
|
||||
themeValues = valuesCache.getThemeValues();
|
||||
defaultValues = valuesCache.getDefaultValues();
|
||||
lightDefaultValues = valuesCache.getLightValues();
|
||||
darkDefaultValues = valuesCache.getDarkValues();
|
||||
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
||||
return null;
|
||||
}
|
||||
|
||||
class IdColumn extends AbstractDynamicTableColumn<ColorValue, String, Object> {
|
||||
private class IdColumn extends AbstractDynamicTableColumn<ColorValue, String, Object> {
|
||||
|
||||
@Override
|
||||
public String getColumnName() {
|
||||
@@ -129,7 +129,8 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
||||
}
|
||||
}
|
||||
|
||||
class ValueColumn extends AbstractDynamicTableColumn<ColorValue, ResolvedColor, Object> {
|
||||
private class ValueColumn
|
||||
extends AbstractDynamicTableColumn<ColorValue, ResolvedColor, Object> {
|
||||
private ThemeColorRenderer renderer;
|
||||
private String name;
|
||||
private Supplier<GThemeValueMap> valueSupplier;
|
||||
@@ -236,7 +237,7 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
||||
|
||||
}
|
||||
|
||||
static class SwatchIcon implements Icon {
|
||||
private static class SwatchIcon implements Icon {
|
||||
private Color color;
|
||||
private Color border;
|
||||
|
||||
@@ -264,8 +265,5 @@ public class ThemeColorTableModel extends GDynamicColumnTableModel<ColorValue, O
|
||||
}
|
||||
}
|
||||
|
||||
record ResolvedColor(String id, String refId, Color color) {
|
||||
//
|
||||
}
|
||||
|
||||
private record ResolvedColor(String id, String refId, Color color) { /**/ }
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ public class ThemeDialog extends DialogComponentProvider {
|
||||
|
||||
private ThemeManager themeManager;
|
||||
|
||||
private GThemeValuesCache valuesCache;
|
||||
|
||||
public ThemeDialog(ThemeManager themeManager) {
|
||||
super("Theme Dialog", false);
|
||||
this.themeManager = themeManager;
|
||||
@@ -227,12 +229,17 @@ public class ThemeDialog extends DialogComponentProvider {
|
||||
|
||||
private Component buildTabedTables() {
|
||||
tabbedPane = new JTabbedPane();
|
||||
colorTable = new ThemeColorTable(themeManager);
|
||||
fontTable = new ThemeFontTable(themeManager);
|
||||
iconTable = new ThemeIconTable(themeManager);
|
||||
|
||||
valuesCache = new GThemeValuesCache(themeManager);
|
||||
|
||||
colorTable = new ThemeColorTable(themeManager, valuesCache);
|
||||
iconTable = new ThemeIconTable(themeManager, valuesCache);
|
||||
fontTable = new ThemeFontTable(themeManager, valuesCache);
|
||||
|
||||
tabbedPane.add("Colors", colorTable);
|
||||
tabbedPane.add("Fonts", fontTable);
|
||||
tabbedPane.add("Icons", iconTable);
|
||||
|
||||
return tabbedPane;
|
||||
}
|
||||
|
||||
@@ -284,6 +291,7 @@ public class ThemeDialog extends DialogComponentProvider {
|
||||
private class DialogThemeListener implements ThemeListener {
|
||||
@Override
|
||||
public void themeChanged(ThemeEvent event) {
|
||||
valuesCache.clear();
|
||||
if (event.haveAllValuesChanged()) {
|
||||
reset();
|
||||
return;
|
||||
|
||||
@@ -43,11 +43,11 @@ public class ThemeFontTable extends JPanel implements ActionContextProvider {
|
||||
private GFilterTable<FontValue> filterTable;
|
||||
private ThemeManager themeManager;
|
||||
|
||||
public ThemeFontTable(ThemeManager themeManager) {
|
||||
public ThemeFontTable(ThemeManager themeManager, GThemeValuesCache valuesProvider) {
|
||||
super(new BorderLayout());
|
||||
this.themeManager = themeManager;
|
||||
|
||||
fontTableModel = new ThemeFontTableModel(themeManager);
|
||||
fontTableModel = new ThemeFontTableModel(valuesProvider);
|
||||
filterTable = new GFilterTable<>(fontTableModel);
|
||||
table = filterTable.getTable();
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
|
||||
@@ -24,7 +24,8 @@ import java.util.function.Supplier;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
import docking.widgets.table.*;
|
||||
import generic.theme.*;
|
||||
import generic.theme.FontValue;
|
||||
import generic.theme.GThemeValueMap;
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.framework.plugintool.ServiceProviderStub;
|
||||
@@ -39,11 +40,11 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||
private GThemeValueMap currentValues;
|
||||
private GThemeValueMap themeValues;
|
||||
private GThemeValueMap defaultValues;
|
||||
private ThemeManager themeManager;
|
||||
private GThemeValuesCache valuesProvider;
|
||||
|
||||
public ThemeFontTableModel(ThemeManager themeManager) {
|
||||
public ThemeFontTableModel(GThemeValuesCache valuesProvider) {
|
||||
super(new ServiceProviderStub());
|
||||
this.themeManager = themeManager;
|
||||
this.valuesProvider = valuesProvider;
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -51,7 +52,7 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||
* Reloads the just the current values shown in the table. Called whenever a font changes.
|
||||
*/
|
||||
public void reloadCurrent() {
|
||||
currentValues = themeManager.getCurrentValues();
|
||||
currentValues = valuesProvider.getCurrentValues();
|
||||
fonts = currentValues.getFonts();
|
||||
fireTableDataChanged();
|
||||
}
|
||||
@@ -66,10 +67,10 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||
}
|
||||
|
||||
private void load() {
|
||||
currentValues = themeManager.getCurrentValues();
|
||||
currentValues = valuesProvider.getCurrentValues();
|
||||
fonts = currentValues.getFonts();
|
||||
themeValues = themeManager.getThemeValues();
|
||||
defaultValues = themeManager.getDefaults();
|
||||
themeValues = valuesProvider.getThemeValues();
|
||||
defaultValues = valuesProvider.getDefaultValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,19 +98,28 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getValueText(FontValue fontValue) {
|
||||
if (fontValue == null) {
|
||||
/**
|
||||
* Returns the original value for the id as defined by the current theme
|
||||
* @param id the resource id to get a font value for
|
||||
* @return the original value for the id as defined by the current theme
|
||||
*/
|
||||
public FontValue getThemeValue(String id) {
|
||||
return themeValues.getFont(id);
|
||||
}
|
||||
|
||||
private String getValueText(ResolvedFont resolvedFont) {
|
||||
if (resolvedFont == null) {
|
||||
return "<No Value>";
|
||||
}
|
||||
if (fontValue.getReferenceId() != null) {
|
||||
return "[" + fontValue.getReferenceId() + "]";
|
||||
if (resolvedFont.refId() != null) {
|
||||
return "[" + resolvedFont.refId() + "]";
|
||||
}
|
||||
|
||||
Font font = fontValue.getRawValue();
|
||||
Font font = resolvedFont.font();
|
||||
return FontValue.fontToString(font);
|
||||
}
|
||||
|
||||
class IdColumn extends AbstractDynamicTableColumn<FontValue, String, Object> {
|
||||
private class IdColumn extends AbstractDynamicTableColumn<FontValue, String, Object> {
|
||||
|
||||
@Override
|
||||
public String getColumnName() {
|
||||
@@ -128,7 +138,8 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||
}
|
||||
}
|
||||
|
||||
class FontValueColumn extends AbstractDynamicTableColumn<FontValue, FontValue, Object> {
|
||||
private class FontValueColumn
|
||||
extends AbstractDynamicTableColumn<FontValue, ResolvedFont, Object> {
|
||||
private ThemeFontRenderer renderer;
|
||||
private String name;
|
||||
private Supplier<GThemeValueMap> valueSupplier;
|
||||
@@ -145,19 +156,23 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontValue getValue(FontValue fontValue, Settings settings, Object data,
|
||||
public ResolvedFont getValue(FontValue themeFont, Settings settings, Object data,
|
||||
ServiceProvider provider) throws IllegalArgumentException {
|
||||
GThemeValueMap valueMap = valueSupplier.get();
|
||||
String id = fontValue.getId();
|
||||
return valueMap.getFont(id);
|
||||
String id = themeFont.getId();
|
||||
FontValue fontValue = valueMap.getFont(id);
|
||||
if (fontValue == null) {
|
||||
return null;
|
||||
}
|
||||
return new ResolvedFont(id, fontValue.getReferenceId(), valueMap.getResolvedFont(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GColumnRenderer<FontValue> getColumnRenderer() {
|
||||
public GColumnRenderer<ResolvedFont> getColumnRenderer() {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public Comparator<FontValue> getComparator() {
|
||||
public Comparator<ResolvedFont> getComparator() {
|
||||
return (v1, v2) -> {
|
||||
if (v1 == null && v2 == null) {
|
||||
return 0;
|
||||
@@ -179,33 +194,31 @@ public class ThemeFontTableModel extends GDynamicColumnTableModel<FontValue, Obj
|
||||
|
||||
}
|
||||
|
||||
private class ThemeFontRenderer extends AbstractGColumnRenderer<FontValue> {
|
||||
private class ThemeFontRenderer extends AbstractGColumnRenderer<ResolvedFont> {
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
||||
JLabel label = (JLabel) super.getTableCellRendererComponent(data);
|
||||
FontValue fontValue = (FontValue) data.getValue();
|
||||
ResolvedFont resolvedFont = (ResolvedFont) data.getValue();
|
||||
|
||||
String text = getValueText(fontValue);
|
||||
String text = getValueText(resolvedFont);
|
||||
label.setText(text);
|
||||
label.setOpaque(true);
|
||||
|
||||
Font font = resolvedFont.font();
|
||||
if (font != null) {
|
||||
setToolTipText(FontValue.fontToString(font));
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFilterString(FontValue fontValue, Settings settings) {
|
||||
return getValueText(fontValue);
|
||||
public String getFilterString(ResolvedFont resolvedFont, Settings settings) {
|
||||
return getValueText(resolvedFont);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the original value for the id as defined by the current theme
|
||||
* @param id the resource id to get a font value for
|
||||
* @return the original value for the id as defined by the current theme
|
||||
*/
|
||||
public FontValue getThemeValue(String id) {
|
||||
return themeValues.getFont(id);
|
||||
}
|
||||
|
||||
private record ResolvedFont(String id, String refId, Font font) {/**/}
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@ public class ThemeIconTable extends JPanel implements ActionContextProvider {
|
||||
private GFilterTable<IconValue> filterTable;
|
||||
private ThemeManager themeManager;
|
||||
|
||||
public ThemeIconTable(ThemeManager themeManager) {
|
||||
public ThemeIconTable(ThemeManager themeManager, GThemeValuesCache valuesProvider) {
|
||||
super(new BorderLayout());
|
||||
this.themeManager = themeManager;
|
||||
iconTableModel = new ThemeIconTableModel(themeManager);
|
||||
iconTableModel = new ThemeIconTableModel(valuesProvider);
|
||||
filterTable = new GFilterTable<>(iconTableModel);
|
||||
table = filterTable.getTable();
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
|
||||
@@ -39,11 +39,11 @@ public class ThemeIconTableModel extends GDynamicColumnTableModel<IconValue, Obj
|
||||
private GThemeValueMap currentValues;
|
||||
private GThemeValueMap themeValues;
|
||||
private GThemeValueMap defaultValues;
|
||||
private ThemeManager themeManager;
|
||||
private GThemeValuesCache valuesProvider;
|
||||
|
||||
public ThemeIconTableModel(ThemeManager themeManager) {
|
||||
public ThemeIconTableModel(GThemeValuesCache valuesProvider) {
|
||||
super(new ServiceProviderStub());
|
||||
this.themeManager = themeManager;
|
||||
this.valuesProvider = valuesProvider;
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class ThemeIconTableModel extends GDynamicColumnTableModel<IconValue, Obj
|
||||
* Reloads the just the current values shown in the table. Called whenever an icon changes.
|
||||
*/
|
||||
public void reloadCurrent() {
|
||||
currentValues = themeManager.getCurrentValues();
|
||||
currentValues = valuesProvider.getCurrentValues();
|
||||
icons = currentValues.getIcons();
|
||||
fireTableDataChanged();
|
||||
}
|
||||
@@ -66,10 +66,10 @@ public class ThemeIconTableModel extends GDynamicColumnTableModel<IconValue, Obj
|
||||
}
|
||||
|
||||
private void load() {
|
||||
currentValues = themeManager.getCurrentValues();
|
||||
currentValues = valuesProvider.getCurrentValues();
|
||||
icons = currentValues.getIcons();
|
||||
themeValues = themeManager.getThemeValues();
|
||||
defaultValues = themeManager.getDefaults();
|
||||
themeValues = valuesProvider.getThemeValues();
|
||||
defaultValues = valuesProvider.getDefaultValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,7 +97,16 @@ public class ThemeIconTableModel extends GDynamicColumnTableModel<IconValue, Obj
|
||||
return null;
|
||||
}
|
||||
|
||||
class IdColumn extends AbstractDynamicTableColumn<IconValue, String, Object> {
|
||||
/**
|
||||
* Returns the original value for the id as defined by the current theme
|
||||
* @param id the resource id to get a font value for
|
||||
* @return the original value for the id as defined by the current theme
|
||||
*/
|
||||
public IconValue getThemeValue(String id) {
|
||||
return themeValues.getIcon(id);
|
||||
}
|
||||
|
||||
private class IdColumn extends AbstractDynamicTableColumn<IconValue, String, Object> {
|
||||
|
||||
@Override
|
||||
public String getColumnName() {
|
||||
@@ -116,7 +125,8 @@ public class ThemeIconTableModel extends GDynamicColumnTableModel<IconValue, Obj
|
||||
}
|
||||
}
|
||||
|
||||
class IconValueColumn extends AbstractDynamicTableColumn<IconValue, ResolvedIcon, Object> {
|
||||
private class IconValueColumn
|
||||
extends AbstractDynamicTableColumn<IconValue, ResolvedIcon, Object> {
|
||||
private ThemeIconRenderer renderer;
|
||||
private String name;
|
||||
private Supplier<GThemeValueMap> valueSupplier;
|
||||
@@ -232,14 +242,6 @@ public class ThemeIconTableModel extends GDynamicColumnTableModel<IconValue, Obj
|
||||
}
|
||||
}
|
||||
|
||||
record ResolvedIcon(String id, String refId, Icon icon) {/**/}
|
||||
private record ResolvedIcon(String id, String refId, Icon icon) {/**/}
|
||||
|
||||
/**
|
||||
* Returns the original value for the id as defined by the current theme
|
||||
* @param id the resource id to get a font value for
|
||||
* @return the original value for the id as defined by the current theme
|
||||
*/
|
||||
public IconValue getThemeValue(String id) {
|
||||
return themeValues.getIcon(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ public class GTreeRenderer extends DefaultTreeCellRenderer implements GComponent
|
||||
private static final int DEFAULT_MIN_ICON_WIDTH = 22;
|
||||
private static final Color BACKGROUND_UNSELECTED = new GColor("color.bg.tree");
|
||||
private static final Color BACKGROUND_SELECTED = new GColor("color.bg.tree.selected");
|
||||
private static final Color FOREGROUND_SELECTED = new GColor("color.fg.tree.selected");
|
||||
|
||||
private Object dropTarget;
|
||||
private boolean paintDropTarget;
|
||||
@@ -46,6 +47,7 @@ public class GTreeRenderer extends DefaultTreeCellRenderer implements GComponent
|
||||
setHTMLRenderingEnabled(false);
|
||||
setBackgroundNonSelectionColor(BACKGROUND_UNSELECTED);
|
||||
setBackgroundSelectionColor(BACKGROUND_SELECTED);
|
||||
setTextSelectionColor(FOREGROUND_SELECTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
##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|
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
[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
|
||||
@@ -1,7 +1,8 @@
|
||||
[Defaults]
|
||||
|
||||
color.bg = white // note: this is the text/widget bg color
|
||||
color.fg = black
|
||||
// we define these as shortcuts for the view foreground, background
|
||||
color.bg = [color]system.color.bg.view
|
||||
color.fg = [color]system.color.fg.view
|
||||
|
||||
// On some LaFs the tables and tree use the bg color we define. Make that consistent for all LaFs.
|
||||
[color]Viewport.background = color.bg
|
||||
@@ -12,12 +13,10 @@ color.cursor.unfocused = pink
|
||||
color.fg.error = red
|
||||
color.bg.error = lightcoral
|
||||
color.fg.disabled = lightGray
|
||||
color.bg.uneditable = system.color.bg.application // TODO see if there exists an LaF setting for this
|
||||
color.bg.uneditable = [color]system.color.bg.control
|
||||
color.bg.filtered = yellow
|
||||
color.fg.hint = gray
|
||||
|
||||
color.bg.tooltip = [color]ToolTip.background
|
||||
|
||||
color.fg.messages.hint = color.fg.hint
|
||||
color.fg.messages.alert = orange
|
||||
color.fg.messages.error = color.fg.error
|
||||
@@ -35,14 +34,12 @@ color.fg.table.unselected = white
|
||||
color.fg.error.table.unselected = color.fg.error
|
||||
color.fg.error.table.selected = lightpink
|
||||
|
||||
color.bg.tree = color.bg
|
||||
color.bg.tree.selected = [color]Tree.selectionBackground
|
||||
color.bg.tree = [color]system.color.bg.view
|
||||
color.bg.tree.selected = [color]system.color.bg.selected.view
|
||||
color.fg.tree.selected = [color]system.color.fg.selected.view
|
||||
|
||||
// Fonts
|
||||
font.standard = [font]Panel.font
|
||||
font.bold = font.standard[bold]
|
||||
font.italic = font.standard[italic]
|
||||
font.bold.italic = font.standard[bold][italic]
|
||||
font.standard = [font]system.font.control
|
||||
font.monospaced = monospaced-PLAIN-12
|
||||
|
||||
// Icons files
|
||||
@@ -109,9 +106,6 @@ icon.arrow.up.left = viewmagfit.png[rotate(275)]
|
||||
|
||||
[Dark Defaults]
|
||||
|
||||
color.fg = lightgray
|
||||
color.bg = #1c1d1e
|
||||
|
||||
color.fg.error = indianRed
|
||||
color.fg.disabled = gray
|
||||
color.bg.filtered = beige
|
||||
@@ -125,15 +119,9 @@ color.fg.table.uneditable.selected = lemonchiffon
|
||||
color.fg.table.uneditable.unselected = lightgray
|
||||
|
||||
color.bg.tree = color.bg
|
||||
color.bg.tree.selected = [color]Tree.selectionBackground
|
||||
color.bg.tree.selected = [color]laf.color.Tree.selectionBackground
|
||||
|
||||
// this looks different than the light mode version; good enough until we make a better icon
|
||||
icon.make.selection = stack.png
|
||||
|
||||
|
||||
[CDE/Motif]
|
||||
|
||||
color.bg = [color]window // gray for motif
|
||||
color.fg = [color]textText
|
||||
|
||||
|
||||
|
||||
+11
-12
@@ -16,28 +16,27 @@
|
||||
package generic.theme;
|
||||
|
||||
/**
|
||||
* Loads all the system theme.property files that contain all the default color, font, and
|
||||
* icon values.
|
||||
* Provides theme default values, such as those loaded from {@code *.theme.property} files.
|
||||
*/
|
||||
public interface ThemeDefaultsProvider {
|
||||
public interface ApplicationThemeDefaults {
|
||||
|
||||
/**
|
||||
* Returns the standard defaults {@link GThemeValueMap}
|
||||
* @return the standard defaults {@link GThemeValueMap}
|
||||
* Returns the light default {@link GThemeValueMap}
|
||||
* @return the light default {@link GThemeValueMap}
|
||||
*/
|
||||
public GThemeValueMap getDefaults();
|
||||
public GThemeValueMap getLightValues();
|
||||
|
||||
/**
|
||||
* Returns the dark defaults {@link GThemeValueMap}
|
||||
* @return the dark defaults {@link GThemeValueMap}
|
||||
* Returns the dark default {@link GThemeValueMap}
|
||||
* @return the dark default {@link GThemeValueMap}
|
||||
*/
|
||||
public GThemeValueMap getDarkDefaults();
|
||||
public GThemeValueMap getDarkValues();
|
||||
|
||||
/**
|
||||
* Returns the defaults specific to a given Look and Feel
|
||||
* Returns the default values specific to a given Look and Feel
|
||||
* @param lafType the Look and Feel type
|
||||
* @return the defaults specific to a given Look and Feel
|
||||
* @return the default values specific to a given Look and Feel
|
||||
*/
|
||||
public GThemeValueMap getLookAndFeelDefaults(LafType lafType);
|
||||
public GThemeValueMap getLookAndFeelValues(LafType lafType);
|
||||
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public class ApplicationThemeManager extends ThemeManager {
|
||||
|
||||
@Override
|
||||
public void reloadApplicationDefaults() {
|
||||
themeDefaultsProvider = getThemeDefaultsProvider();
|
||||
applicationDefaults = getApplicationDefaults();
|
||||
buildCurrentValues();
|
||||
lookAndFeelManager.resetAll(javaDefaults);
|
||||
notifyThemeChanged(new AllValuesChangedThemeEvent(false));
|
||||
@@ -127,6 +127,7 @@ public class ApplicationThemeManager extends ThemeManager {
|
||||
if (theme.hasSupportedLookAndFeel()) {
|
||||
activeTheme = theme;
|
||||
LafType lafType = theme.getLookAndFeelType();
|
||||
cleanUiDefaults(); // clear out any values previous themes may have installed
|
||||
lookAndFeelManager = lafType.getLookAndFeelManager(this);
|
||||
try {
|
||||
lookAndFeelManager.installLookAndFeel();
|
||||
@@ -247,20 +248,6 @@ public class ApplicationThemeManager extends ThemeManager {
|
||||
return gColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets specially defined system UI values. These values are created by the application as a
|
||||
* convenience for mapping generic concepts to values that differ by Look and Feel. This allows
|
||||
* clients to use 'system' properties without knowing the actual Look and Feel terms.
|
||||
*
|
||||
* <p>For example, 'system.color.border' defaults to 'controlShadow', but maps to 'nimbusBorder'
|
||||
* in the Nimbus Look and Feel.
|
||||
*
|
||||
* @param map the map
|
||||
*/
|
||||
public void setSystemDefaults(GThemeValueMap map) {
|
||||
systemValues = map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the map of Java default UI values. These are the UI values defined by the current Java
|
||||
* Look and Feel.
|
||||
@@ -409,4 +396,9 @@ public class ApplicationThemeManager extends ThemeManager {
|
||||
GColor.refreshAll(currentValues);
|
||||
GIcon.refreshAll(currentValues);
|
||||
}
|
||||
|
||||
private void cleanUiDefaults() {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
defaults.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import utilities.util.reflection.ReflectionUtilities;
|
||||
public class ColorValue extends ThemeValue<Color> {
|
||||
private static final String COLOR_ID_PREFIX = "color.";
|
||||
private static final String EXTERNAL_PREFIX = "[color]";
|
||||
private static final String SYSTEM_COLOR_PREFIX = "system.color";
|
||||
|
||||
public static final Color LAST_RESORT_DEFAULT = new Color(128, 128, 128);
|
||||
|
||||
@@ -72,8 +71,7 @@ public class ColorValue extends ThemeValue<Color> {
|
||||
* @return true if the given key string is a valid external key for a color value
|
||||
*/
|
||||
public static boolean isColorKey(String key) {
|
||||
return key.startsWith(COLOR_ID_PREFIX) || key.startsWith(EXTERNAL_PREFIX) ||
|
||||
key.startsWith(SYSTEM_COLOR_PREFIX);
|
||||
return key.startsWith(COLOR_ID_PREFIX) || key.startsWith(EXTERNAL_PREFIX);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,15 +105,14 @@ public class ColorValue extends ThemeValue<Color> {
|
||||
"Application", "ghidra.GhidraRun", "java.lang.Class", "java.lang.Thread");
|
||||
t.setStackTrace(filtered);
|
||||
|
||||
Msg.error(this,
|
||||
"Could not resolve indirect color path for \"" + unresolvedId +
|
||||
"\" for primary id \"" + primaryId + "\", using last resort default",
|
||||
t);
|
||||
Msg.error(this, "Could not resolve indirect color path for \"" + unresolvedId +
|
||||
"\" for primary id \"" + primaryId + "\", using last resort default", t);
|
||||
|
||||
return LAST_RESORT_DEFAULT;
|
||||
}
|
||||
|
||||
private static String toExternalId(String internalId) {
|
||||
if (internalId.startsWith(COLOR_ID_PREFIX) || internalId.startsWith(SYSTEM_COLOR_PREFIX)) {
|
||||
if (internalId.startsWith(COLOR_ID_PREFIX)) {
|
||||
return internalId;
|
||||
}
|
||||
return EXTERNAL_PREFIX + internalId;
|
||||
|
||||
@@ -37,6 +37,8 @@ import ghidra.util.datastruct.WeakStore;
|
||||
* set the default value by adding this line "color.mywidget.bg = white".
|
||||
*/
|
||||
public class GColor extends Color {
|
||||
private static final int MISSING_COLOR_RGB = 0x808080;
|
||||
|
||||
// keeps a weak reference to all uses of GColor, so their cached color value can be refreshed
|
||||
private static WeakStore<GColor> inUseColors = new WeakStore<>();
|
||||
|
||||
@@ -50,11 +52,22 @@ public class GColor extends Color {
|
||||
* @param id the id used to lookup the current value for this color
|
||||
*/
|
||||
public GColor(String id) {
|
||||
super(0x808080);
|
||||
super(MISSING_COLOR_RGB);
|
||||
this.id = id;
|
||||
delegate = Gui.getColor(id);
|
||||
inUseColors.add(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor. Used primarily to convert a GColorUiResource to a GColor without having to
|
||||
* lookup the color which can cause errors during theme transitions.
|
||||
* @param gColor the gColor to copy
|
||||
*/
|
||||
protected GColor(GColor gColor) {
|
||||
super(MISSING_COLOR_RGB);
|
||||
this.id = gColor.id;
|
||||
delegate = gColor.delegate;
|
||||
inUseColors.add(this);
|
||||
}
|
||||
|
||||
private GColor(String id, int alpha) {
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package generic.theme;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.plaf.UIResource;
|
||||
|
||||
@@ -36,8 +34,8 @@ public class GColorUIResource extends GColor implements UIResource {
|
||||
* Returns a non-UIResource GColor for this GColorUiResource's id
|
||||
* @return a non-UIResource GColor for this GColorUiResource's id
|
||||
*/
|
||||
public Color toGColor() {
|
||||
return new GColor(getId());
|
||||
public GColor toGColor() {
|
||||
return new GColor(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package generic.theme;
|
||||
|
||||
import static generic.theme.SystemThemeIds.*;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/** TODO doc how clients should use this in their code, with
|
||||
@@ -24,18 +26,9 @@ import java.awt.Color;
|
||||
* Colors.Java.BORDER
|
||||
*/
|
||||
public class GThemeDefaults {
|
||||
|
||||
public static class Ids {
|
||||
|
||||
public static class Java {
|
||||
public static final String BORDER = "system.color.border";
|
||||
}
|
||||
|
||||
public static class Fonts {
|
||||
public static final String STANDARD = "font.standard";
|
||||
public static final String BOLD = "font.bold";
|
||||
public static final String ITALIC = "font.italic";
|
||||
public static final String BOLD_ITALIC = "font.bold.italic";
|
||||
public static final String MONOSPACED = "font.monospaced";
|
||||
}
|
||||
}
|
||||
@@ -44,11 +37,23 @@ public class GThemeDefaults {
|
||||
* Colors mapped to system values
|
||||
*/
|
||||
public static class Colors {
|
||||
//@formatter:off
|
||||
|
||||
// standard color concepts defined by LookAndFeel
|
||||
public static final GColor BG_CONTROL = new GColor(BG_CONTROL_ID);
|
||||
public static final GColor BG_VIEW = new GColor(BG_VIEW_ID);
|
||||
public static final GColor BG_TOOLTIP = new GColor(BG_TOOLTIP_ID);
|
||||
public static final GColor BG_VIEW_SELECTED = new GColor(BG_VIEW_SELECTED_ID);
|
||||
public static final GColor BG_BORDER = new GColor(BG_BORDER_ID);
|
||||
|
||||
public static final GColor FG_CONTROL = new GColor(FG_CONTROL_ID);
|
||||
public static final GColor FG_VIEW = new GColor(FG_VIEW_ID);
|
||||
public static final GColor FG_TOOLTIP = new GColor(FG_TOOLTIP_ID);
|
||||
public static final GColor FG_VIEW_SELECTED = new GColor(FG_VIEW_SELECTED_ID);
|
||||
public static final GColor FG_DISABLED = new GColor(FG_DISABLED_ID);
|
||||
|
||||
// generic color concepts
|
||||
//@formatter:off
|
||||
public static final GColor BACKGROUND = new GColor("color.bg");
|
||||
public static final GColor BACKGROUND_TOOLTIP = new GColor("color.bg.tooltip");
|
||||
public static final GColor CURSOR = new GColor("color.cursor.focused");
|
||||
public static final GColor DISABLED = new GColor("color.palette.disabled");
|
||||
public static final GColor ERROR = new GColor("color.fg.error"); // TODO replace most uses of this with Messages.ERROR
|
||||
@@ -57,7 +62,7 @@ public class GThemeDefaults {
|
||||
//@formatter:on
|
||||
|
||||
public static class Java {
|
||||
public static final GColor BORDER = new GColor(Ids.Java.BORDER);
|
||||
public static final GColor BORDER = BG_BORDER;
|
||||
}
|
||||
|
||||
public static class Tables {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package generic.theme;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
@@ -340,4 +342,50 @@ public class GThemeValueMap {
|
||||
public Set<String> getIconIds() {
|
||||
return iconMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resolved color, following indirections as need to get the color ultimately
|
||||
* assigned to the given id.
|
||||
* @param id the id for which to get a color
|
||||
* @return the resolved color, following indirections as need to get the color ultimately
|
||||
* assigned to the given id.
|
||||
*/
|
||||
public Color getResolvedColor(String id) {
|
||||
ColorValue colorValue = colorMap.get(id);
|
||||
if (colorValue != null) {
|
||||
return colorValue.get(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resolved font, following indirections as need to get the font ultimately
|
||||
* assigned to the given id.
|
||||
* @param id the id for which to get a font
|
||||
* @return the resolved font, following indirections as need to get the font ultimately
|
||||
* assigned to the given id
|
||||
*/
|
||||
public Font getResolvedFont(String id) {
|
||||
FontValue fontValue = fontMap.get(id);
|
||||
if (fontValue != null) {
|
||||
return fontValue.get(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resolved icon, following indirections as need to get the icon ultimately
|
||||
* assigned to the given id.
|
||||
* @param id the id for which to get an icon
|
||||
* @return the resolved icon, following indirections as need to get the icon ultimately
|
||||
* assigned to the given id
|
||||
*/
|
||||
public Icon getResolvedIcon(String id) {
|
||||
IconValue iconValue = iconMap.get(id);
|
||||
if (iconValue != null) {
|
||||
return iconValue.get(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-5
@@ -26,13 +26,13 @@ import ghidra.util.Msg;
|
||||
* Loads all the system theme.property files that contain all the default color, font, and
|
||||
* icon values.
|
||||
*/
|
||||
public class ApplicationThemeDefaultsProvider implements ThemeDefaultsProvider {
|
||||
public class PropertyFileThemeDefaults implements ApplicationThemeDefaults {
|
||||
|
||||
private GThemeValueMap defaults = new GThemeValueMap();
|
||||
private GThemeValueMap darkDefaults = new GThemeValueMap();
|
||||
private Map<LafType, GThemeValueMap> lafDefaultsMap = new HashMap<>();
|
||||
|
||||
ApplicationThemeDefaultsProvider() {
|
||||
PropertyFileThemeDefaults() {
|
||||
loadThemeDefaultFiles();
|
||||
}
|
||||
|
||||
@@ -69,17 +69,17 @@ public class ApplicationThemeDefaultsProvider implements ThemeDefaultsProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public GThemeValueMap getDefaults() {
|
||||
public GThemeValueMap getLightValues() {
|
||||
return defaults;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GThemeValueMap getDarkDefaults() {
|
||||
public GThemeValueMap getDarkValues() {
|
||||
return darkDefaults;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GThemeValueMap getLookAndFeelDefaults(LafType lafType) {
|
||||
public GThemeValueMap getLookAndFeelValues(LafType lafType) {
|
||||
return lafDefaultsMap.get(lafType);
|
||||
}
|
||||
|
||||
@@ -215,21 +215,21 @@ public class StubThemeManager extends ThemeManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThemeDefaultsProvider getThemeDefaultsProvider() {
|
||||
return new ThemeDefaultsProvider() {
|
||||
protected ApplicationThemeDefaults getApplicationDefaults() {
|
||||
return new ApplicationThemeDefaults() {
|
||||
|
||||
@Override
|
||||
public GThemeValueMap getDefaults() {
|
||||
public GThemeValueMap getLightValues() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GThemeValueMap getDarkDefaults() {
|
||||
public GThemeValueMap getDarkValues() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GThemeValueMap getLookAndFeelDefaults(LafType lafType) {
|
||||
public GThemeValueMap getLookAndFeelValues(LafType lafType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/* ###
|
||||
* 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 generic.theme.laf.UiDefaultsMapper;
|
||||
|
||||
/**
|
||||
* These are the standard system ids defined to represent general LookAndFeel color and font
|
||||
* concepts. Various LaF have different names for these concepts and even defines additional
|
||||
* concepts. These are the ones we use regardless of the LookAndFeel being used. When we
|
||||
* load a specific LookAndFeel, a {@link UiDefaultsMapper}, specific to that LaF is used to map
|
||||
* its system ids to our standard system ids. Also, {@link GThemeDefaults} uses these system
|
||||
* ids to define colors that can be used throughout the application without using these ids
|
||||
* directly.
|
||||
* <P>
|
||||
* The ids are assigned to categories as follows:
|
||||
* <UL>
|
||||
* <LI>CONTROL- these ids are used for colors and fonts for general system components such as
|
||||
* Buttons, Checkboxes, or anything that doesn't fit into one of the other areas</LI>
|
||||
* <LI>VIEW - these ids are used for the colors and fonts used for widgets that display data
|
||||
* such as Trees, Tables, TextFieds, and Lists</LI>
|
||||
* <LI>MENU - these ids are used by menu components such as Menus and MenuItems.</LI>
|
||||
* <LI>TOOLTIP - these ids are used just by the tooltip component
|
||||
* </UL>
|
||||
* <P>
|
||||
* For each of those categories the ids specify a specific property for those components.
|
||||
* <UL>
|
||||
* <LI> BG - the background color
|
||||
* <LI> FG - the foreground color
|
||||
* <LI> BG_SELECTED - the background color when the component is selected
|
||||
* <LI> FG_SELECTED - the foreground color when the component is selected
|
||||
* <LI> FG_DISABLED - the foreground color when the component is disabled
|
||||
* <LI> BG_BORDER - the border color
|
||||
* <LI> FONT - the font
|
||||
*
|
||||
* </UL>
|
||||
*/
|
||||
public class SystemThemeIds {
|
||||
public static final String FONT_CONTROL_ID = "system.font.control";
|
||||
public static final String FONT_VIEW_ID = "system.font.view";
|
||||
public static final String FONT_MENU_ID = "system.font.menu";
|
||||
|
||||
public static final String BG_CONTROL_ID = "system.color.bg.control";
|
||||
public static final String BG_VIEW_ID = "system.color.bg.view";
|
||||
public static final String BG_TOOLTIP_ID = "system.color.bg.tooltip";
|
||||
public static final String BG_VIEW_SELECTED_ID = "system.color.bg.selected.view";
|
||||
public static final String BG_BORDER_ID = "system.color.bg.border";
|
||||
|
||||
public static final String FG_CONTROL_ID = "system.color.fg.control";
|
||||
public static final String FG_VIEW_ID = "system.color.fg.view";
|
||||
public static final String FG_TOOLTIP_ID = "system.color.fg.tooltip";
|
||||
public static final String FG_VIEW_SELECTED_ID = "system.color.fg.selected.view";
|
||||
public static final String FG_DISABLED_ID = "system.color.fg.disabled";
|
||||
|
||||
}
|
||||
@@ -30,7 +30,6 @@ import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||
import ghidra.util.datastruct.WeakSet;
|
||||
import resources.ResourceManager;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
import utility.function.Callback;
|
||||
|
||||
/**
|
||||
* This class manages application themes and their values. The ThemeManager is an abstract
|
||||
@@ -67,10 +66,9 @@ public abstract class ThemeManager {
|
||||
protected GTheme activeTheme = getDefaultTheme();
|
||||
|
||||
protected GThemeValueMap javaDefaults = new GThemeValueMap();
|
||||
protected GThemeValueMap systemValues = new GThemeValueMap();
|
||||
protected GThemeValueMap currentValues = new GThemeValueMap();
|
||||
|
||||
protected ThemeDefaultsProvider themeDefaultsProvider;
|
||||
protected ApplicationThemeDefaults applicationDefaults;
|
||||
|
||||
// these notifications are only when the user is manipulating theme values, so rare and at
|
||||
// user speed, so using copy on read
|
||||
@@ -86,11 +84,11 @@ public abstract class ThemeManager {
|
||||
// default behavior is only install to INSTANCE if first time
|
||||
INSTANCE = this;
|
||||
}
|
||||
themeDefaultsProvider = getThemeDefaultsProvider();
|
||||
applicationDefaults = getApplicationDefaults();
|
||||
}
|
||||
|
||||
protected ThemeDefaultsProvider getThemeDefaultsProvider() {
|
||||
return new ApplicationThemeDefaultsProvider();
|
||||
protected ApplicationThemeDefaults getApplicationDefaults() {
|
||||
return new PropertyFileThemeDefaults();
|
||||
}
|
||||
|
||||
protected void installInGui() {
|
||||
@@ -101,12 +99,11 @@ public abstract class ThemeManager {
|
||||
GThemeValueMap map = new GThemeValueMap();
|
||||
|
||||
map.load(javaDefaults);
|
||||
map.load(systemValues);
|
||||
map.load(themeDefaultsProvider.getDefaults());
|
||||
map.load(applicationDefaults.getLightValues());
|
||||
if (activeTheme.useDarkDefaults()) {
|
||||
map.load(themeDefaultsProvider.getDarkDefaults());
|
||||
map.load(applicationDefaults.getDarkValues());
|
||||
}
|
||||
map.load(themeDefaultsProvider.getLookAndFeelDefaults(getLookAndFeelType()));
|
||||
map.load(applicationDefaults.getLookAndFeelValues(getLookAndFeelType()));
|
||||
map.load(activeTheme);
|
||||
currentValues = map;
|
||||
}
|
||||
@@ -270,12 +267,11 @@ public abstract class ThemeManager {
|
||||
public GThemeValueMap getThemeValues() {
|
||||
GThemeValueMap map = new GThemeValueMap();
|
||||
map.load(javaDefaults);
|
||||
map.load(systemValues);
|
||||
map.load(themeDefaultsProvider.getDefaults());
|
||||
map.load(applicationDefaults.getLightValues());
|
||||
if (activeTheme.useDarkDefaults()) {
|
||||
map.load(themeDefaultsProvider.getDarkDefaults());
|
||||
map.load(applicationDefaults.getDarkValues());
|
||||
}
|
||||
map.load(themeDefaultsProvider.getLookAndFeelDefaults(getLookAndFeelType()));
|
||||
map.load(applicationDefaults.getLookAndFeelValues(getLookAndFeelType()));
|
||||
map.load(activeTheme);
|
||||
return map;
|
||||
}
|
||||
@@ -418,9 +414,9 @@ public abstract class ThemeManager {
|
||||
* theme.properties files
|
||||
*/
|
||||
public GThemeValueMap getApplicationDarkDefaults() {
|
||||
GThemeValueMap map = new GThemeValueMap(themeDefaultsProvider.getDefaults());
|
||||
map.load(themeDefaultsProvider.getDarkDefaults());
|
||||
map.load(themeDefaultsProvider.getLookAndFeelDefaults(getLookAndFeelType()));
|
||||
GThemeValueMap map = new GThemeValueMap(applicationDefaults.getLightValues());
|
||||
map.load(applicationDefaults.getDarkValues());
|
||||
map.load(applicationDefaults.getLookAndFeelValues(getLookAndFeelType()));
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -431,10 +427,25 @@ public abstract class ThemeManager {
|
||||
* theme.properties files
|
||||
*/
|
||||
public GThemeValueMap getApplicationLightDefaults() {
|
||||
GThemeValueMap map = new GThemeValueMap(themeDefaultsProvider.getDefaults());
|
||||
GThemeValueMap map = new GThemeValueMap(applicationDefaults.getLightValues());
|
||||
map.load(applicationDefaults.getLookAndFeelValues(getLookAndFeelType()));
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns application defaults values (does not include java default values)
|
||||
* @return application defaults values (does not include java default values)
|
||||
*/
|
||||
public GThemeValueMap getApplicationOverrides() {
|
||||
GThemeValueMap currentDefaults = new GThemeValueMap();
|
||||
currentDefaults.load(applicationDefaults.getLightValues());
|
||||
if (activeTheme.useDarkDefaults()) {
|
||||
currentDefaults.load(applicationDefaults.getDarkValues());
|
||||
}
|
||||
currentDefaults.load(applicationDefaults.getLookAndFeelValues(getLookAndFeelType()));
|
||||
return currentDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link GThemeValueMap} containing all default values for the current theme. It
|
||||
* is a combination of application defined defaults and java {@link LookAndFeel} defaults.
|
||||
@@ -442,12 +453,11 @@ public abstract class ThemeManager {
|
||||
*/
|
||||
public GThemeValueMap getDefaults() {
|
||||
GThemeValueMap currentDefaults = new GThemeValueMap(javaDefaults);
|
||||
currentDefaults.load(systemValues);
|
||||
currentDefaults.load(themeDefaultsProvider.getDefaults());
|
||||
currentDefaults.load(applicationDefaults.getLightValues());
|
||||
if (activeTheme.useDarkDefaults()) {
|
||||
currentDefaults.load(themeDefaultsProvider.getDarkDefaults());
|
||||
currentDefaults.load(applicationDefaults.getDarkValues());
|
||||
}
|
||||
currentDefaults.load(themeDefaultsProvider.getLookAndFeelDefaults(getLookAndFeelType()));
|
||||
currentDefaults.load(applicationDefaults.getLookAndFeelValues(getLookAndFeelType()));
|
||||
return currentDefaults;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/* ###
|
||||
* 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.util.Map;
|
||||
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
|
||||
|
||||
import generic.theme.ApplicationThemeManager;
|
||||
import generic.theme.GThemeValueMap;
|
||||
import generic.theme.laf.nimbus.SelectedTreePainter;
|
||||
|
||||
/**
|
||||
* Extends the {@link NimbusLookAndFeel} (Nimbus) to intercept {@link #getDefaults()}. Nimbus
|
||||
* does not honor changes to the UIDefaults after it is installed as the active
|
||||
* {@link LookAndFeel}, so we have to make the changes at the time the UIDefaults are installed.
|
||||
* <P>
|
||||
* To get around this issue, we extend Nimbus so that we can install our GColors and
|
||||
* overridden properties as Nimbus is being installed, specifically during the call to the
|
||||
* getDefaults() method. For all other Look And Feels, the GColors and overridden properties are
|
||||
* changed in the UIDefaults after the Look And Feel is installed, so they don't need to extend the
|
||||
* Look and Feel class.
|
||||
* <P>
|
||||
* Also, unlike other LaFs, Nimbus needs to be reinstalled every time we need to make a change to
|
||||
* any of the UIDefaults values, since it does not respond to changes other than when first
|
||||
* installed.
|
||||
*/
|
||||
public class CustomNimbusLookAndFeel extends NimbusLookAndFeel {
|
||||
private ApplicationThemeManager themeManager;
|
||||
private Map<String, String> normalizedIdToLafIdMap;
|
||||
|
||||
CustomNimbusLookAndFeel(ApplicationThemeManager themeManager) {
|
||||
this.themeManager = themeManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIDefaults getDefaults() {
|
||||
UIDefaults defaults = super.getDefaults();
|
||||
|
||||
installCustomPainters(defaults);
|
||||
|
||||
// normally all of this wiring is handled by the LookAndFeelManager (see above)
|
||||
UiDefaultsMapper uiDefaultsMapper = new NimbusUiDefaultsMapper(defaults);
|
||||
installJavaDefaultsIntoThemeManager(uiDefaultsMapper);
|
||||
uiDefaultsMapper.installValuesIntoUIDefaults(getApplicationOverrides());
|
||||
|
||||
normalizedIdToLafIdMap = uiDefaultsMapper.getNormalizedIdToLafIdMap();
|
||||
return defaults;
|
||||
}
|
||||
|
||||
protected void installJavaDefaultsIntoThemeManager(UiDefaultsMapper uiDefaultsMapper) {
|
||||
GThemeValueMap javaDefaults = uiDefaultsMapper.getJavaDefaults();
|
||||
themeManager.setJavaDefaults(javaDefaults);
|
||||
}
|
||||
|
||||
private void installCustomPainters(UIDefaults defaults) {
|
||||
defaults.put("Tree:TreeCell[Enabled+Selected].backgroundPainter",
|
||||
new SelectedTreePainter());
|
||||
defaults.put("Tree:TreeCell[Focused+Selected].backgroundPainter",
|
||||
new SelectedTreePainter());
|
||||
}
|
||||
|
||||
public Map<String, String> getNormalizedIdToLafIdMap() {
|
||||
return normalizedIdToLafIdMap;
|
||||
}
|
||||
|
||||
protected GThemeValueMap getApplicationOverrides() {
|
||||
return themeManager.getApplicationOverrides();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/* ###
|
||||
* 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 static generic.theme.SystemThemeIds.*;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
import ghidra.util.WebColors;
|
||||
|
||||
public class FlatDarkUiDefaultsMapper extends FlatUiDefaultsMapper {
|
||||
|
||||
protected FlatDarkUiDefaultsMapper(UIDefaults defaults) {
|
||||
super(defaults);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assignSystemColorValues() {
|
||||
super.assignSystemColorValues();
|
||||
|
||||
// We don't think the FlatDark LaF's view background (Trees, Tables, Lists) is dark
|
||||
// enough, so we are overriding the view group background and foreground colors
|
||||
assignSystemColorDirect(BG_VIEW_ID, new Color(0x1c1d1e));
|
||||
assignSystemColorDirect(FG_VIEW_ID, WebColors.LIGHT_GRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assignNormalizedColorValues() {
|
||||
super.assignNormalizedColorValues();
|
||||
|
||||
//
|
||||
// These components are initialized to "text", but we want them mapped to use
|
||||
// our view background color so that they look like normal editable widgets
|
||||
//
|
||||
overrideColor("ComboBox.background", BG_VIEW_ID);
|
||||
overrideColor("ComboBox.background", BG_VIEW_ID);
|
||||
overrideColor("EditorPane.background", BG_VIEW_ID);
|
||||
overrideColor("FormattedTextField.background", BG_VIEW_ID);
|
||||
overrideColor("List.background", BG_VIEW_ID);
|
||||
overrideColor("PasswordField.background", BG_VIEW_ID);
|
||||
overrideColor("Table.background", BG_VIEW_ID);
|
||||
overrideColor("Table.focusCellBackground", BG_VIEW_ID);
|
||||
overrideColor("TableHeader.focusCellBackground", BG_VIEW_ID);
|
||||
overrideColor("TextField.background", BG_VIEW_ID);
|
||||
overrideColor("Tree.background", BG_VIEW_ID);
|
||||
overrideColor("Tree.textBackground", BG_VIEW_ID);
|
||||
overrideColor("TextArea.background", BG_VIEW_ID);
|
||||
overrideColor("TextArea.foreground", BG_VIEW_ID);
|
||||
overrideColor("TextPane.background", BG_VIEW_ID);
|
||||
overrideColor("TextPane.foreground", BG_VIEW_ID);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,18 +15,16 @@
|
||||
*/
|
||||
package generic.theme.laf;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import generic.theme.*;
|
||||
import generic.theme.ApplicationThemeManager;
|
||||
import generic.theme.LafType;
|
||||
|
||||
public class FlatLookAndFeelManager extends LookAndFeelManager {
|
||||
|
||||
public FlatLookAndFeelManager(LafType laf, ApplicationThemeManager themeManager) {
|
||||
super(laf, themeManager);
|
||||
|
||||
// establish system color to LookAndFeel colors
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_WIDGET_BACKGROUND_COLOR_ID, "text"));
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_TOOLTIP_BACKGROUND_COLOR_ID, "info"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,7 +37,10 @@ public class FlatLookAndFeelManager extends LookAndFeelManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThemeGrouper getThemeGrouper() {
|
||||
return new FlatThemeGrouper();
|
||||
protected UiDefaultsMapper getUiDefaultsMapper(UIDefaults defaults) {
|
||||
if (getLookAndFeelType() == LafType.FLAT_DARK) {
|
||||
return new FlatDarkUiDefaultsMapper(defaults);
|
||||
}
|
||||
return new FlatUiDefaultsMapper(defaults);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/* ###
|
||||
* 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 generic.theme.GThemeValueMap;
|
||||
|
||||
/**
|
||||
* Adds specialized groupings unique to the Flat LookAndFeels
|
||||
*/
|
||||
public class FlatThemeGrouper extends ThemeGrouper {
|
||||
|
||||
@Override
|
||||
public void group(GThemeValueMap values) {
|
||||
// @formatter:off
|
||||
defineCustomColorGroup("color.flat.menu.hover.bg", "MenuBar.hoverBackground", values);
|
||||
defineCustomColorGroup("color.flat.button.hover.bg", "Button.hoverBackground", values);
|
||||
defineCustomColorGroup("color.flat.button.selected.bg", "Button.selectedBackground",values);
|
||||
defineCustomColorGroup("color.flat.button.toolbar.hover.bg", "Button.toolbar.hoverBackground",values);
|
||||
defineCustomColorGroup("color.flat.button.toolbar.pressed.bg", "Button.toolbar.pressedBackground",values);
|
||||
defineCustomColorGroup("color.flat.checkbox.icon.focus.border", "CheckBox.icon.focusedBorderColor",values);
|
||||
defineCustomColorGroup("color.flat.menu.accelerator.fg", "Menu.acceleratorForeground",values);
|
||||
|
||||
|
||||
defineCustomColorGroup("color.flat.focus.border", "Button.focusedBorderColor", values);
|
||||
defineCustomColorGroup("color.flat.focus", "Component.focusColor", values);
|
||||
defineCustomColorGroup("color.flat.focus.bg", "Button.focusedBackground", values);
|
||||
defineCustomColorGroup("color.flat.checkmark", "CheckBox.icon.checkmarkColor", values);
|
||||
defineCustomColorGroup("color.flat.disabled", "Button.disabledBorderColor", values);
|
||||
defineCustomColorGroup("color.flat.disabled.selected", "Button.disabledSelectedBackground",values);
|
||||
defineCustomColorGroup("color.flat.arrow", "Spinner.buttonArrowColor",values);
|
||||
defineCustomColorGroup("color.flat.arrow.disabled", "Spinner.buttonDisabledArrowColor",values);
|
||||
defineCustomColorGroup("color.flat.arrow.hover", "Spinner.buttonHoverArrowColor",values);
|
||||
defineCustomColorGroup("color.flat.arrow.pressed", "Spinner.buttonPressedArrowColor",values);
|
||||
|
||||
defineCustomColorGroup("color.flat.dropcell.bg", "List.dropCellBackground",values);
|
||||
defineCustomColorGroup("color.flat.dropline", "List.dropLineColor",values);
|
||||
defineCustomColorGroup("color.flat.underline", "MenuItem.underlineSelectionColor",values);
|
||||
defineCustomColorGroup("color.flat.docking.bg", "ToolBar.dockingBackground",values);
|
||||
defineCustomColorGroup("color.flat.progressbar.bg", "ProgressBar.background",values);
|
||||
defineCustomColorGroup("color.flat.progressbar.fg", "ProgressBar.foreground",values);
|
||||
defineCustomColorGroup("color.flat.icon.bg", "Tree.icon.openColor",values);
|
||||
defineCustomColorGroup("color.flat.selection.inactive", "Tree.selectionInactiveBackground",values);
|
||||
|
||||
|
||||
// @formatter:on
|
||||
super.group(values);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/* ###
|
||||
* 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 javax.swing.UIDefaults;
|
||||
|
||||
public class FlatUiDefaultsMapper extends UiDefaultsMapper {
|
||||
|
||||
protected FlatUiDefaultsMapper(UIDefaults defaults) {
|
||||
super(defaults);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerIgnoredLafIds() {
|
||||
super.registerIgnoredLafIds();
|
||||
ignoredLafIds.add("Actions.Blue");
|
||||
ignoredLafIds.add("Actions.Green");
|
||||
ignoredLafIds.add("Actions.Grey");
|
||||
ignoredLafIds.add("Actions.Greyinline");
|
||||
ignoredLafIds.add("Actions.Red");
|
||||
ignoredLafIds.add("Actions.Yellow");
|
||||
|
||||
ignoredLafIds.add("Objects.BlackText");
|
||||
ignoredLafIds.add("Objects.Blue");
|
||||
ignoredLafIds.add("Objects.Green");
|
||||
ignoredLafIds.add("Objects.GreenAndroid");
|
||||
ignoredLafIds.add("Objects.Grey");
|
||||
ignoredLafIds.add("Objects.Pink");
|
||||
ignoredLafIds.add("Objects.Purple");
|
||||
ignoredLafIds.add("Objects.Red");
|
||||
ignoredLafIds.add("Objects.RedStatus");
|
||||
ignoredLafIds.add("Objects.Yellow");
|
||||
ignoredLafIds.add("Objects.YellowDark");
|
||||
|
||||
ignoredLafIds.add("h0.font");
|
||||
ignoredLafIds.add("h00.font");
|
||||
ignoredLafIds.add("h1.font");
|
||||
ignoredLafIds.add("h1.regular.font");
|
||||
ignoredLafIds.add("h2.font");
|
||||
ignoredLafIds.add("h2.regular.font");
|
||||
ignoredLafIds.add("h3.font");
|
||||
ignoredLafIds.add("h3.regular.font");
|
||||
ignoredLafIds.add("h4.font");
|
||||
ignoredLafIds.add("large.font");
|
||||
ignoredLafIds.add("light.font");
|
||||
ignoredLafIds.add("medium.font");
|
||||
ignoredLafIds.add("mini.font");
|
||||
ignoredLafIds.add("monospaced.font");
|
||||
ignoredLafIds.add("small.font");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/* ###
|
||||
* 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.*;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
|
||||
|
||||
import generic.theme.*;
|
||||
import generic.theme.laf.nimbus.SelectedTreePainter;
|
||||
|
||||
/**
|
||||
* Extends the {@link NimbusLookAndFeel} to intercept the {@link #getDefaults()}. Nimbus does
|
||||
* not honor changes to the UIDefaults after it is installed as the active
|
||||
* {@link LookAndFeel}, so we have to make the changes at the time the UIDefaults are installed.
|
||||
*
|
||||
* To get around this issue, we extend the NimbusLookAndFeel
|
||||
* so that we can install our GColors and overridden properties as Nimbus is being installed,
|
||||
* specifically during the call to the getDefaults() method. For all other Look And Feels, the
|
||||
* GColors and overridden properties are changed in the UIDefaults after the Look And Feel is
|
||||
* installed, so they don't need to extends the Look and Feel class.
|
||||
*
|
||||
* Also, note that Nimbus needs to be reinstalled every time we need to make a change to any of the
|
||||
* UIDefaults values, since it does not respond to changes other than when first installed.
|
||||
*/
|
||||
public class GNimbusLookAndFeel extends NimbusLookAndFeel {
|
||||
private ApplicationThemeManager themeManager;
|
||||
|
||||
GNimbusLookAndFeel(ApplicationThemeManager themeManager) {
|
||||
this.themeManager = themeManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIDefaults getDefaults() {
|
||||
UIDefaults defaults = super.getDefaults();
|
||||
|
||||
installCustomPainters(defaults);
|
||||
|
||||
GThemeValueMap javaDefaults = extractJavaDefaults(defaults);
|
||||
|
||||
// replace all colors with GColors
|
||||
for (ColorValue colorValue : javaDefaults.getColors()) {
|
||||
String id = colorValue.getId();
|
||||
defaults.put(id, themeManager.getGColorUiResource(id));
|
||||
}
|
||||
|
||||
// put fonts back into defaults in case they have been changed by the current theme
|
||||
for (FontValue fontValue : javaDefaults.getFonts()) {
|
||||
String id = fontValue.getId();
|
||||
Font font = themeManager.getFont(id);
|
||||
defaults.put(id, new FontUIResource(font));
|
||||
}
|
||||
|
||||
// put icons back into defaults in case they have been changed by the current theme
|
||||
for (IconValue iconValue : javaDefaults.getIcons()) {
|
||||
String id = iconValue.getId();
|
||||
// because some icons are weird, put raw icons into defaults, only use GIcons for
|
||||
// setting Icons explicitly on components
|
||||
Icon icon = themeManager.getIcon(id);
|
||||
defaults.put(id, icon);
|
||||
}
|
||||
|
||||
defaults.put("Label.textForeground", themeManager.getGColorUiResource("Label.foreground"));
|
||||
themeManager.refreshGThemeValues();
|
||||
return defaults;
|
||||
}
|
||||
|
||||
private void installCustomPainters(UIDefaults defaults) {
|
||||
defaults.put("Tree:TreeCell[Enabled+Selected].backgroundPainter",
|
||||
new SelectedTreePainter());
|
||||
defaults.put("Tree:TreeCell[Focused+Selected].backgroundPainter",
|
||||
new SelectedTreePainter());
|
||||
}
|
||||
|
||||
protected GThemeValueMap extractJavaDefaults(UIDefaults defaults) {
|
||||
GThemeValueMap javaDefaults = new GThemeValueMap();
|
||||
|
||||
List<String> colorIds =
|
||||
LookAndFeelManager.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 =
|
||||
LookAndFeelManager.getLookAndFeelIdsForType(defaults, Font.class);
|
||||
for (String id : fontIds) {
|
||||
Font font = defaults.getFont(id);
|
||||
FontValue value = new FontValue(id, LookAndFeelManager.fromUiResource(font));
|
||||
javaDefaults.addFont(value);
|
||||
}
|
||||
List<String> iconIds =
|
||||
LookAndFeelManager.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.
|
||||
themeManager.setJavaDefaults(javaDefaults);
|
||||
return javaDefaults;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package generic.theme.laf;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
import generic.theme.ApplicationThemeManager;
|
||||
import generic.theme.LafType;
|
||||
|
||||
@@ -26,4 +28,9 @@ public class GtkLookAndFeelManager extends LookAndFeelManager {
|
||||
public GtkLookAndFeelManager(ApplicationThemeManager themeManager) {
|
||||
super(LafType.GTK, themeManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UiDefaultsMapper getUiDefaultsMapper(UIDefaults defaults) {
|
||||
return new GtkUiDefaultsMapper(defaults);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* ###
|
||||
* 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 static generic.theme.SystemThemeIds.*;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
public class GtkUiDefaultsMapper extends UiDefaultsMapper {
|
||||
|
||||
protected GtkUiDefaultsMapper(UIDefaults defaults) {
|
||||
super(defaults);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerIgnoredLafIds() {
|
||||
super.registerIgnoredLafIds();
|
||||
ignoredLafIds.add("textInactiveText");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assignColorMatchersToComponentIds() {
|
||||
super.assignColorMatchersToComponentIds();
|
||||
assignSystemColorFromLafId(FG_VIEW_ID, "windowText");
|
||||
assignSystemColorFromLafId(FG_DISABLED_ID, "Label.disabledForeground");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,32 +36,14 @@ import ghidra.util.SystemUtilities;
|
||||
*/
|
||||
public abstract class LookAndFeelManager {
|
||||
|
||||
/**
|
||||
* These are color ids (see {@link GColor} used to represent general concepts that
|
||||
* application developers can use to get the color for that concept as defined by
|
||||
* a specific {@link LookAndFeel}. This class will define some standard default
|
||||
* mappings in the constructor, but it is expected that each specific LookAndFeelManager
|
||||
* will override these mappings with values appropriate for that LookAndFeel.
|
||||
*/
|
||||
protected static final String SYSTEM_APP_BACKGROUND_COLOR_ID = "system.color.bg.application";
|
||||
protected static final String SYSTEM_WIDGET_BACKGROUND_COLOR_ID = "system.color.bg.widget";
|
||||
protected static final String SYSTEM_TOOLTIP_BACKGROUND_COLOR_ID = "system.color.bg.tooltip";
|
||||
protected static final String SYSTEM_BORDER_COLOR_ID = "system.color.border";
|
||||
|
||||
private LafType laf;
|
||||
private Map<String, ComponentFontRegistry> fontRegistryMap = new HashMap<>();
|
||||
protected GThemeValueMap systemToLafMap = new GThemeValueMap();
|
||||
protected ApplicationThemeManager themeManager;
|
||||
protected Map<String, String> normalizedIdToLafIdMap;
|
||||
|
||||
protected LookAndFeelManager(LafType laf, ApplicationThemeManager themeManager) {
|
||||
this.laf = laf;
|
||||
this.themeManager = themeManager;
|
||||
|
||||
// establish system color to LookAndFeel colors
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_APP_BACKGROUND_COLOR_ID, "control"));
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_WIDGET_BACKGROUND_COLOR_ID, "control"));
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_TOOLTIP_BACKGROUND_COLOR_ID, "control"));
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_BORDER_COLOR_ID, "controlShadow"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,10 +67,8 @@ public abstract class LookAndFeelManager {
|
||||
public void installLookAndFeel() throws ClassNotFoundException, InstantiationException,
|
||||
IllegalAccessException, UnsupportedLookAndFeelException {
|
||||
|
||||
cleanUiDefaults();
|
||||
themeManager.setSystemDefaults(systemToLafMap);
|
||||
doInstallLookAndFeel();
|
||||
installJavaDefaults();
|
||||
processJavaDefaults();
|
||||
fixupLookAndFeelIssues();
|
||||
installGlobalProperties();
|
||||
installCustomLookAndFeelActions();
|
||||
@@ -119,10 +99,14 @@ public abstract class LookAndFeelManager {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
for (FontValue fontValue : fonts) {
|
||||
String id = fontValue.getId();
|
||||
String lafId = normalizedIdToLafIdMap.get(id);
|
||||
if (lafId == null) {
|
||||
continue;
|
||||
}
|
||||
Font correctFont = Gui.getFont(id);
|
||||
Font storedFont = defaults.getFont(id);
|
||||
if (correctFont != null && !correctFont.equals(storedFont)) {
|
||||
defaults.put(id, correctFont);
|
||||
defaults.put(lafId, toUiResource(correctFont));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,10 +116,11 @@ public abstract class LookAndFeelManager {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
for (IconValue iconValue : icons) {
|
||||
String id = iconValue.getId();
|
||||
String lafId = normalizedIdToLafIdMap.get(id);
|
||||
Icon correctIcon = Gui.getIcon(id);
|
||||
Icon storedIcon = defaults.getIcon(id);
|
||||
if (correctIcon != null && !correctIcon.equals(storedIcon)) {
|
||||
defaults.put(id, correctIcon);
|
||||
defaults.put(lafId, correctIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,14 +139,16 @@ public abstract class LookAndFeelManager {
|
||||
* @param newIcon the new icon to use for the given set of icon ids
|
||||
*/
|
||||
public void iconsChanged(Set<String> changedIconIds, Icon newIcon) {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
if (!(newIcon instanceof UIResource)) {
|
||||
newIcon = new IconUIResource(newIcon);
|
||||
}
|
||||
for (String changedIconId : changedIconIds) {
|
||||
String lafIconId = normalizedIdToLafIdMap.get(changedIconId);
|
||||
defaults.put(lafIconId, newIcon);
|
||||
}
|
||||
|
||||
if (!changedIconIds.isEmpty()) {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
for (String javaIconId : changedIconIds) {
|
||||
defaults.put(javaIconId, newIcon);
|
||||
}
|
||||
updateComponentUis();
|
||||
}
|
||||
themeManager.refreshGThemeValues();
|
||||
@@ -173,16 +160,22 @@ public abstract class LookAndFeelManager {
|
||||
* @param changedJavaFontIds the set of Java Font ids that are affected by this change
|
||||
*/
|
||||
public void fontsChanged(Set<String> changedJavaFontIds) {
|
||||
if (!changedJavaFontIds.isEmpty()) {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
for (String javaFontId : changedJavaFontIds) {
|
||||
// even though all these derive from the new font, they might be different
|
||||
// because of FontModifiers.
|
||||
Font font = Gui.getFont(javaFontId);
|
||||
defaults.put(javaFontId, new FontUIResource(font));
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
for (String changedFontId : changedJavaFontIds) {
|
||||
// even though all these derive from the new font, they might be different
|
||||
// because of FontModifiers.
|
||||
Font font = Gui.getFont(changedFontId);
|
||||
String lafFontId = normalizedIdToLafIdMap.get(changedFontId);
|
||||
if (lafFontId != null) {
|
||||
// lafFontId is null for group ids
|
||||
defaults.put(lafFontId, new FontUIResource(font));
|
||||
}
|
||||
}
|
||||
|
||||
if (!changedJavaFontIds.isEmpty()) {
|
||||
updateComponentUis();
|
||||
}
|
||||
|
||||
updateAllRegisteredComponentFonts();
|
||||
repaintAll();
|
||||
}
|
||||
@@ -212,26 +205,9 @@ public abstract class LookAndFeelManager {
|
||||
register.addComponent(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a color that is not a {@link UIResource}.
|
||||
* @param color the color to return an non UIResource color for
|
||||
* @return a color that is not a {@link UIResource}.
|
||||
*/
|
||||
public static Color fromUiResource(Color color) {
|
||||
if (color.getClass() == Color.class) {
|
||||
return color;
|
||||
}
|
||||
return new Color(color.getRGB(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a font that is not a {@link UIResource}.
|
||||
* @param font the font to return an non UIResource font for
|
||||
* @return a font that is not a {@link UIResource}.
|
||||
*/
|
||||
public static Font fromUiResource(Font font) {
|
||||
if (font instanceof UIResource) {
|
||||
return new FontNonUiResource(font);
|
||||
private Font toUiResource(Font font) {
|
||||
if (!(font instanceof UIResource)) {
|
||||
return new FontUIResource(font);
|
||||
}
|
||||
return font;
|
||||
}
|
||||
@@ -261,80 +237,21 @@ public abstract class LookAndFeelManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts java default colors, fonts, and icons and stores them in {@link Gui}.
|
||||
* Extracts java default colors, fonts, and icons and stores them in the
|
||||
* {@link ThemeManager} and updates the {@link UIDefaults} by installing GColors for all
|
||||
* color values and installing any overridden fonts or icons.
|
||||
*/
|
||||
private void installJavaDefaults() {
|
||||
GThemeValueMap javaDefaults = extractJavaDefaults();
|
||||
ThemeGrouper grouper = getThemeGrouper();
|
||||
grouper.group(javaDefaults);
|
||||
protected void processJavaDefaults() {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
UiDefaultsMapper uiDefaultsMapper = getUiDefaultsMapper(defaults);
|
||||
|
||||
GThemeValueMap javaDefaults = uiDefaultsMapper.getJavaDefaults();
|
||||
themeManager.setJavaDefaults(javaDefaults);
|
||||
installPropertiesBackIntoUiDefaults(javaDefaults);
|
||||
uiDefaultsMapper.installValuesIntoUIDefaults(themeManager.getApplicationOverrides());
|
||||
normalizedIdToLafIdMap = uiDefaultsMapper.getNormalizedIdToLafIdMap();
|
||||
}
|
||||
|
||||
protected ThemeGrouper getThemeGrouper() {
|
||||
return new ThemeGrouper();
|
||||
}
|
||||
|
||||
protected void installPropertiesBackIntoUiDefaults(GThemeValueMap javaDefaults) {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
|
||||
GTheme theme = themeManager.getActiveTheme();
|
||||
|
||||
// we replace java default colors with GColor equivalents so that we
|
||||
// can change colors without having to reinstall ui on each component
|
||||
// This trick only works for colors. Fonts and icons don't universally
|
||||
// allow being wrapped like colors do.
|
||||
for (ColorValue colorValue : javaDefaults.getColors()) {
|
||||
String id = colorValue.getId();
|
||||
defaults.put(id, themeManager.getGColorUiResource(id));
|
||||
}
|
||||
|
||||
// put fonts back into defaults in case they have been changed by the current theme
|
||||
for (FontValue fontValue : javaDefaults.getFonts()) {
|
||||
String id = fontValue.getId();
|
||||
FontValue themeValue = theme.getFont(id);
|
||||
if (themeValue != null) {
|
||||
Font font = Gui.getFont(id);
|
||||
defaults.put(id, new FontUIResource(font));
|
||||
}
|
||||
}
|
||||
|
||||
// put icons back into defaults in case they have been changed by the current theme
|
||||
for (IconValue iconValue : javaDefaults.getIcons()) {
|
||||
String id = iconValue.getId();
|
||||
IconValue themeValue = theme.getIcon(id);
|
||||
if (themeValue != null) {
|
||||
// because some icons are weird, put raw icons into defaults, only use GIcons for
|
||||
// setting Icons explicitly on components
|
||||
Icon icon = Gui.getIcon(id);
|
||||
defaults.put(id, icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected GThemeValueMap extractJavaDefaults() {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
GThemeValueMap values = new GThemeValueMap();
|
||||
// for now, just doing color properties.
|
||||
List<String> ids = getLookAndFeelIdsForType(defaults, Color.class);
|
||||
for (String id : ids) {
|
||||
// convert UIResource color to regular colors so if used, they don't get wiped
|
||||
// out when we update the UIs
|
||||
values.addColor(new ColorValue(id, fromUiResource(UIManager.getColor(id))));
|
||||
}
|
||||
ids = getLookAndFeelIdsForType(defaults, Font.class);
|
||||
for (String id : ids) {
|
||||
// convert UIResource fonts to regular fonts so if used, they don't get wiped
|
||||
// out when we update UIs
|
||||
values.addFont(new FontValue(id, fromUiResource(UIManager.getFont(id))));
|
||||
}
|
||||
ids = getLookAndFeelIdsForType(defaults, Icon.class);
|
||||
for (String id : ids) {
|
||||
Icon icon = UIManager.getIcon(id);
|
||||
values.addIcon(new IconValue(id, icon));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
protected abstract UiDefaultsMapper getUiDefaultsMapper(UIDefaults defaults);
|
||||
|
||||
protected String findLookAndFeelClassName(String lookAndFeelName) {
|
||||
LookAndFeelInfo[] installedLookAndFeels = UIManager.getInstalledLookAndFeels();
|
||||
@@ -463,26 +380,6 @@ public abstract class LookAndFeelManager {
|
||||
installPopupMenuSettingsOverride();
|
||||
}
|
||||
|
||||
private void cleanUiDefaults() {
|
||||
GThemeValueMap javaDefaults = themeManager.getJavaDefaults();
|
||||
if (javaDefaults == null) {
|
||||
return;
|
||||
}
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
for (ColorValue colorValue : javaDefaults.getColors()) {
|
||||
String id = colorValue.getId();
|
||||
defaults.put(id, null);
|
||||
}
|
||||
for (FontValue fontValue : javaDefaults.getFonts()) {
|
||||
String id = fontValue.getId();
|
||||
defaults.put(id, null);
|
||||
}
|
||||
for (IconValue iconValue : javaDefaults.getIcons()) {
|
||||
String id = iconValue.getId();
|
||||
defaults.put(id, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the given UIDefaults for ids whose value matches the given class
|
||||
* @param defaults the UIDefaults to search
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package generic.theme.laf;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
import generic.theme.ApplicationThemeManager;
|
||||
import generic.theme.LafType;
|
||||
|
||||
@@ -25,7 +27,7 @@ public class MacLookAndFeelManager extends LookAndFeelManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThemeGrouper getThemeGrouper() {
|
||||
return new MacThemeGrouper();
|
||||
protected UiDefaultsMapper getUiDefaultsMapper(UIDefaults defaults) {
|
||||
return new MacUiDefaultsMapper(defaults);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/* ###
|
||||
* 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 generic.theme.GThemeValueMap;
|
||||
|
||||
/**
|
||||
* Adds specialized groupings unique to the Mac LookAndFeel
|
||||
*/
|
||||
public class MacThemeGrouper extends ThemeGrouper {
|
||||
|
||||
@Override
|
||||
public void group(GThemeValueMap values) {
|
||||
// @formatter:off
|
||||
defineCustomColorGroup("color.mac.disabled.fg", "Menu.disabledForeground", values);
|
||||
defineCustomColorGroup("color.mac.button.select", "Button.select", values);
|
||||
defineCustomColorGroup("color.mac.menu.select", "Menu.selectionBackground",values);
|
||||
defineCustomColorGroup("color.mac.seletion.inactive.bg", "List.selectionInactiveBackground",values);//d4d4d4
|
||||
|
||||
defineCustomFontGroup("font.mac.small.font", "IconButton.font", values);
|
||||
// @formatter:on
|
||||
super.group(values);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/* ###
|
||||
* 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 javax.swing.UIDefaults;
|
||||
|
||||
public class MacUiDefaultsMapper extends UiDefaultsMapper {
|
||||
|
||||
protected MacUiDefaultsMapper(UIDefaults defaults) {
|
||||
super(defaults);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package generic.theme.laf;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
import generic.theme.ApplicationThemeManager;
|
||||
import generic.theme.LafType;
|
||||
|
||||
@@ -23,4 +25,9 @@ public class MetalLookAndFeelManager extends LookAndFeelManager {
|
||||
public MetalLookAndFeelManager(ApplicationThemeManager themeManager) {
|
||||
super(LafType.METAL, themeManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UiDefaultsMapper getUiDefaultsMapper(UIDefaults defaults) {
|
||||
return new MetalUiDefaultsMapper(defaults);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* ###
|
||||
* 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 static generic.theme.SystemThemeIds.*;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
public class MetalUiDefaultsMapper extends UiDefaultsMapper {
|
||||
|
||||
protected MetalUiDefaultsMapper(UIDefaults defaults) {
|
||||
super(defaults);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerIgnoredLafIds() {
|
||||
super.registerIgnoredLafIds();
|
||||
ignoredLafIds.add("textInactiveText");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assignSystemColorValues() {
|
||||
super.assignSystemColorValues();
|
||||
assignSystemColorFromLafId(FG_DISABLED_ID, "Label.disabledForeground");
|
||||
assignSystemColorFromLafId(FG_VIEW_ID, "windowText");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package generic.theme.laf;
|
||||
|
||||
import generic.theme.*;
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
import generic.theme.ApplicationThemeManager;
|
||||
import generic.theme.LafType;
|
||||
|
||||
/**
|
||||
* Motif {@link LookAndFeelManager}. Specialized so that it can return the Motif installer
|
||||
@@ -24,11 +27,11 @@ public class MotifLookAndFeelManager extends LookAndFeelManager {
|
||||
|
||||
public MotifLookAndFeelManager(ApplicationThemeManager themeManager) {
|
||||
super(LafType.MOTIF, themeManager);
|
||||
// establish system color to LookAndFeel colors
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_APP_BACKGROUND_COLOR_ID, "control"));
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_WIDGET_BACKGROUND_COLOR_ID, "window"));
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_TOOLTIP_BACKGROUND_COLOR_ID, "info"));
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_BORDER_COLOR_ID, "activeCaptionBorder"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UiDefaultsMapper getUiDefaultsMapper(UIDefaults defaults) {
|
||||
return new MotifUiDefaultsMapper(defaults);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,10 +49,4 @@ public class MotifLookAndFeelManager extends LookAndFeelManager {
|
||||
setKeyBinding("PASTE", "ctrl V", UIPrefixValues);
|
||||
setKeyBinding("CUT", "ctrl X", UIPrefixValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThemeGrouper getThemeGrouper() {
|
||||
return new MotifThemeGrouper();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
-10
@@ -15,21 +15,18 @@
|
||||
*/
|
||||
package generic.theme.laf;
|
||||
|
||||
import generic.theme.GThemeValueMap;
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
/**
|
||||
* Adds specialized groupings unique to the Motif LookAndFeel
|
||||
*/
|
||||
public class MotifThemeGrouper extends ThemeGrouper {
|
||||
public MotifThemeGrouper() {
|
||||
public class MotifUiDefaultsMapper extends UiDefaultsMapper {
|
||||
|
||||
protected MotifUiDefaultsMapper(UIDefaults defaults) {
|
||||
super(defaults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void group(GThemeValueMap values) {
|
||||
defineCustomFontGroup("font.monospaced", "Spinner.font", values);
|
||||
|
||||
super.group(values);
|
||||
protected void registerIgnoredLafIds() {
|
||||
super.registerIgnoredLafIds();
|
||||
ignoredLafIds.add("controlLightShadow");
|
||||
}
|
||||
|
||||
}
|
||||
+28
-16
@@ -32,9 +32,6 @@ public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
||||
|
||||
public NimbusLookAndFeelManager(ApplicationThemeManager themeManager) {
|
||||
super(LafType.NIMBUS, themeManager);
|
||||
|
||||
// establish system color specific to Nimbus
|
||||
systemToLafMap.addColor(new ColorValue(SYSTEM_BORDER_COLOR_ID, "nimbusBorder"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -63,11 +60,30 @@ public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
||||
|
||||
private void reinstallNimubus() {
|
||||
try {
|
||||
UIManager.setLookAndFeel(new GNimbusLookAndFeel(themeManager) {
|
||||
/**
|
||||
* In order to get Nimbus to honor changes to fonts and icons in the UiDefaults,
|
||||
* we have to reinstall nimbus. Reinstalling nimbus is a bit different that the first
|
||||
* install. First, we don't want to re-install the java defaults, the current ones are
|
||||
* fine and we don't want loose any current theme values changes. Second, when we
|
||||
* get font and theme value overrides, we want to use all the current values as they
|
||||
* may include additional overrides than just the original values from theme.property
|
||||
* files.
|
||||
*/
|
||||
UIManager.setLookAndFeel(new CustomNimbusLookAndFeel(themeManager) {
|
||||
@Override
|
||||
protected GThemeValueMap extractJavaDefaults(UIDefaults defaults) {
|
||||
return themeManager.getJavaDefaults();
|
||||
protected void installJavaDefaultsIntoThemeManager(
|
||||
UiDefaultsMapper uiDefaultsMapper) {
|
||||
// as explained above, don't change the java defaults in the theme manager
|
||||
// on a reinstall
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GThemeValueMap getApplicationOverrides() {
|
||||
// on a reinstall, we may also have overrides in the current values and not
|
||||
// just the theme.property files
|
||||
return themeManager.getCurrentValues();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
catch (UnsupportedLookAndFeelException e) {
|
||||
@@ -78,18 +94,15 @@ public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
||||
|
||||
@Override
|
||||
protected void doInstallLookAndFeel() throws UnsupportedLookAndFeelException {
|
||||
UIManager.setLookAndFeel(new GNimbusLookAndFeel(themeManager));
|
||||
CustomNimbusLookAndFeel nimbusLookAndFeel = new CustomNimbusLookAndFeel(themeManager);
|
||||
UIManager.setLookAndFeel(nimbusLookAndFeel);
|
||||
normalizedIdToLafIdMap = nimbusLookAndFeel.getNormalizedIdToLafIdMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GThemeValueMap extractJavaDefaults() {
|
||||
protected void processJavaDefaults() {
|
||||
// The GNimbusLookAndFeel already extracted the java defaults and installed them in the Gui
|
||||
return themeManager.getJavaDefaults();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThemeGrouper getThemeGrouper() {
|
||||
return new NimbusThemeGrouper();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,8 +118,7 @@ public class NimbusLookAndFeelManager extends LookAndFeelManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installPropertiesBackIntoUiDefaults(GThemeValueMap javaDefaults) {
|
||||
// do nothing, this was handled when we overrode the getDefaults() method in the
|
||||
// GNimubusLookAndFeel
|
||||
protected UiDefaultsMapper getUiDefaultsMapper(UIDefaults defaults) {
|
||||
return new NimbusUiDefaultsMapper(defaults);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/* ###
|
||||
* 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 generic.theme.GThemeValueMap;
|
||||
|
||||
/**
|
||||
* Adds specialized groupings unique to the Nimbus LookAndFeel
|
||||
*/
|
||||
public class NimbusThemeGrouper extends ThemeGrouper {
|
||||
public NimbusThemeGrouper() {
|
||||
// Nimbus defines a new type of button
|
||||
buttonGroup.addComponents("ArrowButton");
|
||||
|
||||
// Nimbus defines some other color sources
|
||||
colorSourceProperties.add("nimbusFocus");
|
||||
colorSourceProperties.add("nimbusOrange");
|
||||
colorSourceProperties.add("nimbusBorder");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void group(GThemeValueMap values) {
|
||||
defineCustomColorGroup("color.nimbus.text.alt", "Menu.foreground", values);
|
||||
defineCustomFontGroup("font.titledborder", "TitledBorder.font", values);
|
||||
|
||||
super.group(values);
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user