GP-1981 - Theming - PDB and Code Compare Modules

This commit is contained in:
dragonmacher 2022-09-02 16:22:34 -04:00 committed by ghidragon
parent 2f453099ba
commit a99841e6d4
21 changed files with 93 additions and 67 deletions

View File

@ -21,7 +21,7 @@ import java.util.Set;
import docking.action.DockingAction;
import docking.action.MenuData;
import docking.tool.ToolConstants;
import generic.theme.GThemeDefaults.Colors.Dialogs;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.CorePluginPackage;
import ghidra.app.context.NavigatableActionContext;
import ghidra.app.context.NavigatableContextAction;
@ -135,12 +135,12 @@ public class InstructionSearchPlugin extends ProgramPlugin {
if (selection.getNumAddresses() == 0) {
dialog.displayMessage(
"Select instructions from the listing (and hit reload) to populate the table.",
Dialogs.FG_MESSAGE_NORMAL);
Messages.FG_MESSAGE_NORMAL);
return false;
}
if (!isSelectionSizeValid(selection)) {
dialog.displayMessage("Invalid selection. Cannot select more than " +
MAX_SELECTION_SIZE + " instructions and/or data items.", Dialogs.FG_MESSAGE_ERROR);
MAX_SELECTION_SIZE + " instructions and/or data items.", Messages.FG_MESSAGE_ERROR);
return false;
}
@ -150,7 +150,7 @@ public class InstructionSearchPlugin extends ProgramPlugin {
}
}
catch (InvalidInputException e) {
dialog.displayMessage(e.getMessage(), Dialogs.FG_MESSAGE_ERROR);
dialog.displayMessage(e.getMessage(), Messages.FG_MESSAGE_ERROR);
return false;
}

View File

@ -26,7 +26,7 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane;
import docking.DialogComponentProvider;
import generic.theme.GThemeDefaults.Colors.Dialogs;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.plugin.core.instructionsearch.model.*;
import ghidra.app.plugin.core.instructionsearch.ui.SelectionModeWidget.InputMode;
import ghidra.app.plugin.core.instructionsearch.util.InstructionSearchUtils;
@ -293,7 +293,7 @@ public class InsertBytesWidget extends DialogComponentProvider implements KeyLis
// exit.
if (allBytes.size() < instruction.getLength()) {
msgPanel.setMessageText("Input invalid: unknown disassembly error.",
Dialogs.FG_MESSAGE_ERROR);
Messages.FG_MESSAGE_ERROR);
return;
}
allBytes.subList(0, instruction.getLength()).clear();
@ -304,7 +304,7 @@ public class InsertBytesWidget extends DialogComponentProvider implements KeyLis
// If there's an exception, just stop and let the user figure out what went
// wrong - no need to continue.
msgPanel.setMessageText("Input invalid: unknown disassembly error.",
Dialogs.FG_MESSAGE_ERROR);
Messages.FG_MESSAGE_ERROR);
Msg.debug(this, "Error disassembling instruction", e);
return;

View File

@ -24,7 +24,7 @@ import javax.swing.*;
import docking.ComponentProvider;
import docking.DialogComponentProvider;
import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Dialogs;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.app.plugin.core.instructionsearch.InstructionSearchPlugin;
import ghidra.app.plugin.core.instructionsearch.model.InstructionMetadata;
@ -141,7 +141,7 @@ public class InstructionSearchDialog extends DialogComponentProvider implements
if (selection == null && getMessagePanel() != null) {
getMessagePanel().setMessageText(
"Select instructions from the listing (and hit reload) to populate the table.",
Dialogs.FG_MESSAGE_NORMAL);
Messages.FG_MESSAGE_NORMAL);
}
if (selection != null && plugin.isSelectionValid(selection, this)) {

View File

@ -22,7 +22,7 @@ import javax.swing.*;
import docking.DockingWindowManager;
import docking.widgets.EmptyBorderButton;
import generic.theme.GThemeDefaults.Colors.Dialogs;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.plugin.core.instructionsearch.InstructionSearchPlugin;
import ghidra.app.plugin.core.instructionsearch.model.*;
import ghidra.app.services.GoToService;
@ -521,7 +521,7 @@ public class InstructionTable extends AbstractInstructionTable {
dialog.getMessagePanel()
.setMessageText(
"Instruction was loaded manually, no address in the listing to navigate to.",
Dialogs.FG_MESSAGE_NORMAL);
Messages.FG_MESSAGE_NORMAL);
}
}
}

View File

@ -17,7 +17,7 @@ package ghidra.app.plugin.core.instructionsearch.ui;
import java.util.*;
import generic.theme.GThemeDefaults.Colors.Dialogs;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.plugin.core.instructionsearch.InstructionSearchPlugin;
import ghidra.app.plugin.core.instructionsearch.model.InstructionMetadata;
import ghidra.app.plugin.core.instructionsearch.ui.SearchDirectionWidget.Direction;
@ -137,7 +137,7 @@ class SearchInstructionsTask extends Task {
// If we've gone through all the ranges and there are still no results, show an
// error message.
searchDialog.getMessagePanel()
.setMessageText("No results found", Dialogs.FG_MESSAGE_NORMAL);
.setMessageText("No results found", Messages.FG_MESSAGE_NORMAL);
return;
}

View File

@ -42,7 +42,7 @@ public class EntropyOverviewColorService implements OverviewColorService {
private byte[] chunkBuffer;
private double[] logtable;
private int[] histogram = new int[256];
private Palette palette;
private OverviewPalette palette;
private EntropyOverviewOptionsManager entropyOptionsManager;
private OverviewColorComponent overviewComponent;
private OverviewColorLegendDialog legendDialog;

View File

@ -85,7 +85,7 @@ public class EntropyOverviewOptionsManager implements OptionsChangeListener {
private EntropyKnot knot4type;
private Color knot5color;
private EntropyKnot knot5type;
private Palette palette = new Palette(256, UNINITIALIZED_COLOR);
private OverviewPalette palette = new OverviewPalette(256, UNINITIALIZED_COLOR);
private EntropyOverviewColorService service;
public EntropyOverviewOptionsManager(PluginTool tool, EntropyOverviewColorService service) {
@ -193,7 +193,7 @@ public class EntropyOverviewOptionsManager implements OptionsChangeListener {
* Returns the palette computed after reading the options.
* @return the color palette for the {@link EntropyOverviewColorService}
*/
public Palette getPalette() {
public OverviewPalette getPalette() {
return palette;
}

View File

@ -25,13 +25,13 @@ import generic.theme.GThemeDefaults.Colors.Java;
public class KnotLabelPanel extends JPanel {
private static final Font FONT = new Font("Times New Roman", Font.BOLD, 16);
private int topBottomMargin = 10;
private Palette palette;
private OverviewPalette palette;
public KnotLabelPanel(int topBottomMargin) {
this.topBottomMargin = topBottomMargin;
}
public void setPalette(Palette palette) {
public void setPalette(OverviewPalette palette) {
this.palette = palette;
}

View File

@ -39,7 +39,7 @@ public class KnotPanel extends JPanel implements ComponentListener {
private static final Color FG_COLOR_TEXT =
new GColor("color.bg.plugin.overview.entropy.palette.text");
private Palette palette = null;
private OverviewPalette palette = null;
private FontMetrics metrics;
private ChangeListener paletteListener = e -> buildLabels();
@ -117,7 +117,7 @@ public class KnotPanel extends JPanel implements ComponentListener {
return getFontMetrics(newFont);
}
public void setPalette(Palette pal) {
public void setPalette(OverviewPalette pal) {
palette = pal;
palette.addPaletteListener(paletteListener);
buildLabels();

View File

@ -48,7 +48,7 @@ public class LegendPanel extends JPanel {
return new Dimension(210, 300);
}
public void setPalette(Palette pal) {
public void setPalette(OverviewPalette pal) {
palettePanel.setPalette(pal);
knotPanel.setPalette(pal);
}

View File

@ -28,7 +28,7 @@ import ghidra.util.datastruct.WeakSet;
/**
* Manages the colors used by the entropy overview bar.
*/
public class Palette {
public class OverviewPalette {
private Color uninitializedColor;
private Color[] colors;
private ArrayList<KnotRecord> knots;
@ -36,7 +36,7 @@ public class Palette {
private WeakSet<ChangeListener> listeners =
WeakDataStructureFactory.createSingleThreadAccessWeakSet();
public Palette(int sz, Color uninit) {
public OverviewPalette(int sz, Color uninit) {
uninitializedColor = uninit;
colors = new Color[sz];
knots = new ArrayList<>();

View File

@ -23,7 +23,7 @@ import generic.theme.GThemeDefaults.Colors.Java;
public class PalettePanel extends JPanel {
private Palette palette;
private OverviewPalette palette;
private final int topBottomMargin;
PalettePanel(int topBottomMargin) {
@ -35,7 +35,7 @@ public class PalettePanel extends JPanel {
return new Dimension(20, 10);
}
public void setPalette(Palette palette) {
public void setPalette(OverviewPalette palette) {
this.palette = palette;
}

View File

@ -41,6 +41,8 @@ import docking.widgets.label.GIconLabel;
import docking.widgets.label.GLabel;
import docking.widgets.textfield.HexOrDecimalInput;
import docking.widgets.textfield.HintTextField;
import generic.theme.GThemeDefaults.Colors;
import generic.theme.TempColorUtils;
import ghidra.app.util.bin.format.pdb.PdbParser;
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbIdentifiers;
import ghidra.app.util.pdb.pdbapplicator.PdbApplicatorControl;
@ -172,7 +174,7 @@ public class LoadPdbDialog extends DialogComponentProvider {
protected void dialogShown() {
cancelButton.requestFocusInWindow();
if ( getCurrentSymbolFileInfo() != null ) {
if (getCurrentSymbolFileInfo() != null) {
searchForPdbs(false);
}
}
@ -377,7 +379,7 @@ public class LoadPdbDialog extends DialogComponentProvider {
programNameTextField.setEditable(false);
programNameTextField.setText(program.getName());
pdbPathTextField = new BetterNonEditableTextField(20, "Missing", Color.red);
pdbPathTextField = new BetterNonEditableTextField(20, "Missing", Colors.ERROR);
pdbPathTextField.setEditable(false);
pdbPathTextField.setText(programSymbolFileInfo.getPath());
pdbPathTextField.getDocument().addDocumentListener(docListener);
@ -399,7 +401,7 @@ public class LoadPdbDialog extends DialogComponentProvider {
new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC,
SymbolFilePanel.SEARCH_OPTIONS_HELP_ANCHOR));
pdbUniqueIdTextField = new BetterNonEditableTextField(36, "Missing", Color.red);
pdbUniqueIdTextField = new BetterNonEditableTextField(36, "Missing", Colors.ERROR);
pdbUniqueIdTextField.setEditable(false);
pdbUniqueIdTextField.setText(programSymbolFileInfo.getUniqifierString());
pdbUniqueIdTextField.setToolTipText(
@ -889,10 +891,9 @@ public class LoadPdbDialog extends DialogComponentProvider {
Container parent = getParent();
if (parent != null && !isEditable()) {
Color bg = parent.getBackground();
// mint a new Color object to avoid it being
// ignored because the parent handed us a DerivedColor
// instance
return new Color(bg.getRGB());
// mint a new Color object to avoid it being ignored because the parent handed us a
// DerivedColor instance
return TempColorUtils.fromRgb(bg.getRGB());
}
return super.getBackground();
}
@ -931,10 +932,9 @@ public class LoadPdbDialog extends DialogComponentProvider {
Container parent = getParent();
if (parent != null && !isEditable()) {
Color bg = parent.getBackground();
// mint a new Color object to avoid it being
// ignored because the parent handed us a DerivedColor
// instance
return new Color(bg.getRGB());
// mint a new Color object to avoid it being ignored because the parent handed us a
// DerivedColor instance
return TempColorUtils.fromRgb(bg.getRGB());
}
return super.getBackground();
}

View File

@ -27,6 +27,7 @@ import docking.DockingWindowManager;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GHtmlLabel;
import docking.widgets.label.GLabel;
import generic.theme.GThemeDefaults.Colors;
import ghidra.util.HelpLocation;
import ghidra.util.table.GhidraTable;
import pdb.PdbPlugin;
@ -40,6 +41,7 @@ class SymbolFilePanel extends JPanel {
interface SearchCallback {
void searchForPdbs(boolean allowRemote);
}
static final String SEARCH_OPTIONS_HELP_ANCHOR = "PDB_Search_Search_Options";
private SymbolFileTableModel tableModel;
private GhidraTable table;
@ -117,7 +119,8 @@ class SymbolFilePanel extends JPanel {
private JPanel buildWelcomePanel() {
welcomePanel = new JPanel();
welcomePanel.add(new GHtmlLabel(
"<html><br><center><font color=red>Configuration must be set first!"));
"<html><br><center><font color=\"" + Colors.ERROR.toHexString() +
"\">Configuration must be set first!"));
welcomePanel.setPreferredSize(tablePanel.getPreferredSize());
return welcomePanel;

View File

@ -36,6 +36,7 @@ import docking.widgets.label.GHtmlLabel;
import docking.widgets.label.GLabel;
import docking.widgets.table.GTable;
import docking.widgets.textfield.HintTextField;
import generic.theme.GThemeDefaults.Colors;
import ghidra.framework.preferences.Preferences;
import ghidra.util.*;
import ghidra.util.layout.PairLayout;
@ -108,7 +109,8 @@ class SymbolServerPanel extends JPanel {
JScrollPane tableScrollPane = buildTable();
defaultConfigNotice = new JPanel();
defaultConfigNotice.add(new GHtmlLabel(
"<html><center><font color=red><br>" + "Missing / invalid configuration.<br><br>" +
"<html><center><font color=\"" + Colors.ERROR.toHexString() +
"\"><br>" + "Missing / invalid configuration.<br><br>" +
"Using default search location:<br>" + "Program's Import Location<br>",
SwingConstants.CENTER));
defaultConfigNotice.setPreferredSize(tableScrollPane.getPreferredSize());
@ -395,8 +397,8 @@ class SymbolServerPanel extends JPanel {
String[] envParts = envString.split("[*;]");
List<String> results = new ArrayList<>();
Set<String> locationStringDeduplicationSet = new HashSet<>();
for (int i = 0; i < envParts.length; i++) {
String locationString = envParts[i].trim();
for (String envPart : envParts) {
String locationString = envPart.trim();
if (!locationString.isBlank() && !locationString.equalsIgnoreCase("srv") &&
!locationStringDeduplicationSet.contains(locationString)) {
results.add(locationString);

View File

@ -65,7 +65,7 @@ public class GThemeDefaults {
//@formatter:on
}
public static class Dialogs {
public static class Messages {
//@formatter:off
public static final GColor FG_MESSAGE_NORMAL = new GColor("color.fg.dialog.status.normal");
public static final GColor FG_MESSAGE_ERROR = new GColor("color.fg.dialog.status.error");
@ -79,24 +79,38 @@ public class GThemeDefaults {
public static class Palette {
/** Transparent color */
public static final Color NO_COLOR = palette("nocolor");
public static final Color NO_COLOR = getColor("nocolor");
public static final GColor BLACK = palette("black");
public static final GColor BLUE = palette("blue");
public static final GColor CYAN = palette("cyan");
public static final GColor GOLD = palette("gold");
public static final GColor GRAY = palette("gray");
public static final GColor GREEN = palette("green");
public static final GColor LIGHT_GRAY = palette("lightgray");
public static final GColor LIME = palette("lime");
public static final GColor MAGENTA = palette("magenta");
public static final GColor ORANGE = palette("orange");
public static final GColor PINK = palette("pink");
public static final GColor RED = palette("red");
public static final GColor WHITE = palette("white");
public static final GColor YELLOW = palette("yellow");
public static final GColor BLACK = getColor("black");
public static final GColor BLUE = getColor("blue");
public static final GColor CYAN = getColor("cyan");
public static final GColor GOLD = getColor("gold");
public static final GColor GRAY = getColor("gray");
public static final GColor GREEN = getColor("green");
public static final GColor LAVENDER = getColor("lavander");
public static final GColor LIGHT_GRAY = getColor("lightgray");
public static final GColor LIME = getColor("lime");
public static final GColor MAGENTA = getColor("magenta");
public static final GColor ORANGE = getColor("orange");
public static final GColor PINK = getColor("pink");
public static final GColor RED = getColor("red");
public static final GColor WHITE = getColor("white");
public static final GColor YELLOW = getColor("yellow");
private static GColor palette(String name) {
/**
* Returns a new {@link GColor} for the given palette name.
* <p>
* For a list of supported palette IDs, see {@code docking.palette.theme.properties}.
* <p>
* It is preferred to use the static colors defined in {@link Palette} when possible, as
* it prevents excess object creation. This method should be used when the desired
* palette color is not in that list. Further, this method should only be called once
* per use, such as when initializing a constant value.
*
* @param name the palette entry name
* @return the GColor
*/
public static GColor getColor(String name) {
return new GColor("color.palette." + name);
}
}

View File

@ -35,6 +35,14 @@ public class TempColorUtils {
return new Color(r, g, b);
}
public static Color fromRgba(int r, int g, int b, int a) {
return new Color(r, g, b, a);
}
public static Color fromRgba(float r, float g, float b, float a) {
return new Color(r, g, b, a);
}
public static Color withAlpha(Color c, int a) {
return new Color(c.getRed(), c.getGreen(), c.getBlue(), a);
}

View File

@ -9,11 +9,10 @@ color.bg.visualgraph.message = rgb(138, 185, 241) // jordy blue
color.bg.visualgraph.drop.shadow.dark = black
color.bg.visualgraph.drop.shadow.light = gray
color.bg.visualgraph.satellite.vertex = color.palette.material.secondary.variant
color.bg.visualgraph.satellite.vertex = #018786
color.fg.visualgraph.message = color.palette.black
// TODO maybe make this darker for light mode; it is bright against a bright background
color.bg.visualgraph.dockingvertex = color.palette.material.secondary
color.bg.visualgraph.dockingvertex = #03DAC6
color.fg.visualgraph.dockingvertex = black
color.visualgraph.dockingvertex.cursor = red
@ -45,9 +44,9 @@ color.fg.visualgraph.message = color.palette.lightgray
color.bg.visualgraph.drop.shadow.dark = black
color.bg.visualgraph.drop.shadow.light = gray
color.bg.visualgraph.satellite.vertex = color.palette.material.secondary.variant
color.bg.visualgraph.satellite.vertex = #018786
color.bg.visualgraph.dockingvertex = color.palette.material.secondary.variant
color.bg.visualgraph.dockingvertex = #018786
color.fg.visualgraph.dockingvertex = black // unchanged
color.visualgraph.dockingvertex.cursor = pink // arbitrary

View File

@ -35,7 +35,7 @@ import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.label.GDLabel;
import docking.widgets.list.GListCellRenderer;
import generic.theme.GThemeDefaults.Colors.Dialogs;
import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.GThemeDefaults.Colors.Tables;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.preferences.Preferences;
@ -61,7 +61,7 @@ class EditPluginPathDialog extends DialogComponentProvider {
private final static int SIDE_MARGIN = 5;
private final static Color INVALID_PATH_COLOR = Tables.FG_ERROR_UNSELECTED;
private final static Color INVALID_SELECTED_PATH_COLOR = Tables.FG_ERROR_SELECTED;
private final static Color STATUS_MESSAGE_COLOR = Dialogs.FG_MESSAGE_NORMAL;
private final static Color STATUS_MESSAGE_COLOR = Messages.FG_MESSAGE_NORMAL;
final static String EMPTY_STATUS = " ";
private ExtensionFileFilter JAR_FILTER =

View File

@ -27,7 +27,7 @@ import org.apache.logging.log4j.core.config.Configuration;
import docking.StatusBarSpacer;
import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDLabel;
import generic.theme.GThemeDefaults.Colors.Dialogs;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.layout.HorizontalLayout;
@ -96,7 +96,7 @@ public class LogPanel extends JPanel implements LogListener {
public void messageLogged(String message, boolean isError) {
messageUpdater.run(() -> {
label.setForeground(isError ? Dialogs.FG_MESSAGE_ERROR : defaultColor);
label.setForeground(isError ? Messages.FG_MESSAGE_ERROR : defaultColor);
String text = message.replace("\n", " ");
label.setText(text);
label.setToolTipText(text);

View File

@ -74,7 +74,7 @@ public class OverviewPluginScreenShots extends GhidraScreenShotGenerator {
public void testEntropyLegend() {
EntropyOverviewOptionsManager options =
new EntropyOverviewOptionsManager(tool, entropyService);
Palette palette = options.getPalette();
OverviewPalette palette = options.getPalette();
LegendPanel legendPanel = new LegendPanel();
legendPanel.setPalette(palette);
OverviewColorLegendDialog legendDialog =