From fc301bb38652c6db28b87b508a5e635d3a8a409b Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Thu, 29 Dec 2022 14:51:25 -0500 Subject: [PATCH] GP-2961 - Theme Fixes - Many changes to deal with odd rendering behavior in Nimbus and the Flat LaFs. --- .../Features/Base/data/base.theme.properties | 8 ++- .../topics/BundleManager/BundleManager.htm | 70 ++++++++++++++----- .../topics/CodeBrowserPlugin/CodeBrowser.htm | 6 +- .../GhidraScriptMgrPlugin.htm | 3 +- .../ScriptDevelopment.htm | 18 +++-- .../core/interpreter/InterpreterPanel.java | 9 ++- .../plugin/core/totd/TipOfTheDayDialog.java | 9 ++- .../Python/data/python.theme.properties | 2 + .../help/help/topics/Python/interpreter.html | 8 ++- .../python/PythonCodeCompletionFactory.java | 24 +------ .../src/main/help/help/shared/DarkStyle.css | 58 --------------- .../action/ComponentThemeInspectorAction.java | 17 +++-- .../DefaultTableCellRendererWrapper.java | 1 + Ghidra/Framework/Gui/certification.manifest | 1 + .../data/gui.laf.overrides.theme.properties | 55 +++++++++++++++ .../Framework/Gui/data/gui.theme.properties | 12 ---- .../main/java/generic/theme/ColorValue.java | 9 ++- .../main/java/generic/theme/FontValue.java | 23 +++--- .../main/java/generic/theme/IconValue.java | 21 +++--- .../theme/ThemePropertyFileReader.java | 16 ++++- .../main/java/generic/theme/ThemeValue.java | 11 ++- .../Framework/Help/data/help.theme.properties | 2 +- .../main/resources/help/shared/DarkStyle.css | 55 ++++++++++++--- .../resources/help/shared/DefaultStyle.css | 3 +- 24 files changed, 274 insertions(+), 167 deletions(-) delete mode 100644 Ghidra/Framework/Docking/src/main/help/help/shared/DarkStyle.css create mode 100644 Ghidra/Framework/Gui/data/gui.laf.overrides.theme.properties diff --git a/Ghidra/Features/Base/data/base.theme.properties b/Ghidra/Features/Base/data/base.theme.properties index 74c9b0b196..0dd6c67c68 100644 --- a/Ghidra/Features/Base/data/base.theme.properties +++ b/Ghidra/Features/Base/data/base.theme.properties @@ -28,8 +28,10 @@ color.fg.error.consoletextpane = color.fg.error color.fg.infopanel.version = color.fg -color.fg.interpreterpanel = color.fg -color.fg.interpreterpanel.error = color.fg.error +color.bg.interpreterconsole = color.bg +color.fg.interpreterconsole = color.fg +color.fg.interpreterconsole.error = color.fg.error + color.bg.listing.highlighter.default = yellow color.bg.listing.highlighter.scoped.read = rgb(204,204, 0) color.bg.listing.highlighter.scoped.write = green @@ -207,3 +209,5 @@ color.bg.plugin.datamgr.edge.reference = deepskyblue color.fg.plugin.equate.enum = deepskyblue color.bg.plugin.programdiff.highlight = darkRed + + diff --git a/Ghidra/Features/Base/src/main/help/help/topics/BundleManager/BundleManager.htm b/Ghidra/Features/Base/src/main/help/help/topics/BundleManager/BundleManager.htm index 6abe32a992..2d29ba0156 100644 --- a/Ghidra/Features/Base/src/main/help/help/topics/BundleManager/BundleManager.htm +++ b/Ghidra/Features/Base/src/main/help/help/topics/BundleManager/BundleManager.htm @@ -4,11 +4,13 @@ Ghidra Bundles - - + + +

Ghidra Bundles

-

Dynamic modules

+

Dynamic modules

+

Scripting brings a powerful form of dynamic extensibilty to Ghidra, where Java source code is (re)compiled, loaded, and run without exiting Ghidra. When a script grows large or requires external dependencies, it @@ -17,7 +19,7 @@

To support modularity while preserving the dynamic nature of scripts, Ghidra uses OSGi. Without delving too much into terminology, the key things to know are

-
    +
    1. The unit of modularity in OSGi is the bundle. Bundles are mostly independent components with declared imports and exports.
    2. @@ -47,25 +49,34 @@
    - +

Source bundles

+

When a directory is added to the Bundle Manager, it is treated as a source bundle. When enabled, its Java contents are compiled to +

         <user home>/.ghidra/.ghidra-<version>/osgi/compiled-bundles/<hash>/
     
+

where <hash> is a hash of the source bundle path. These compiled artifacts are then loaded - by the OSGi framework.

-

exploded bundles

+ by the OSGi framework. +

+ + +

Exploded Bundles

+

Each such subdirectory of compiled-bundles/ is an exploded jar -- by compressing it, we get a standard OSGi Jar bundle:

             jar cMf mybundle.jar -C $HOME/.ghidra/.ghidra_<version>/osgi/compiled-bundles/<hash>  .
     
+
-

generated files

+

Generated Files

+

If there is no manifest in the source directory, Ghidra generates one using bndlib so that:

@@ -77,13 +88,17 @@

If no bundle activator is present, a stub is created and referenced in the generated manifest.

+
+
-

Dependency

+

Dependency

+

Two types of code dependency are available when developing with OSGi, intra-bundle and inter-bundle.

-

intra-bundle (compile time) dependency

+

Intra-bundle (compile time) Dependency

+

Classes within a bundle, e.g. source files in a source bundle, can rely one another with Java's usual package import.

This kind of dependency is resolved at compile time -- if a class isn't imported or present, compilation will fail.

@@ -115,8 +130,10 @@ } } +
-

inter-bundle (run time) dependency

+

Inter-bundle (run time) Dependency

+

To make use of code from other bundles, a bundle must declare its dependencies. When a bundle is activated, the framework attempts to resolve its declared dependencies against active bundles. The @@ -128,6 +145,7 @@ resolution.

@importpackage in a script

+

Ghidra's @importpacakge meta-data tag provides a convenient way to declare inter-bundle dependencies directly in a script. Set the value to a comma separated list of packages to import from other bundles.

@@ -161,8 +179,10 @@ } } +

Import-Package in the manifest

+

The underlying OSGi mechanism for declaring inter-bundle dependency is via the manifest.

You can find detailed descriptions of manifest attributes used by OSGi, like Import-Package, here @@ -186,7 +206,10 @@ Bundle-Name: ab12cd89 Bundle-Activator: GeneratedActivator + +

The manifest generated for your_ghidra_scripts is as follows: +

     <user home>/.ghidra/.ghidra-<version>/osgi/compiled-bundles/ef34ab56/META-INF/MANIFEST.MF:
         Manifest-Version: 1.0
@@ -204,9 +227,12 @@
 
     

For full control, users can include a manifest with their bundle's source, e.g. my_ghidra_scripts/META-INF/MANIFEST.MF.

- +
+
+

Enabling and disabling bundles

+

For a bundle's contents to be available (e.g. for loading classes), its OSGi state must be "ACTIVE". Ghidra generally takes care of this, but @@ -224,7 +250,7 @@

The color of each bundle path reflects state as follows:

- +

Adding and removing bundles from the manager

+

Adding a directory to the bundle manager will also enable it, so scripts within become available in the script manager.

Removing a bundle disables it, so its scripts will be removed from the script manager and its dependents will become inactive.

- +

Cleaning bundles

+

When Ghidra builds a source bundle, the results are written to the directory
    <user home>/.ghidra/.ghidra-<version>/osgi/compiled-bundles/<hash>.
@@ -265,13 +293,23 @@

If a source bundle's imports aren't available during build, some source files can produce errors. In order to force Ghidra to recompile, one must either modify the files with errors or clean the bundle then re-enable.

+

Refresh bundles

+

Refresh will deactivate, clean, then reactivate every enabled bundle.

+
+

Related Topics:

+
- +

 

+
+
+
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm b/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm index 792f7ecf05..187bac9f21 100644 --- a/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm +++ b/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm @@ -734,6 +734,10 @@
  • Program Tree
  • Selection & Highlighting
  • -
    + +

     

    +
    +
    +
    diff --git a/Ghidra/Features/Base/src/main/help/help/topics/GhidraScriptMgrPlugin/GhidraScriptMgrPlugin.htm b/Ghidra/Features/Base/src/main/help/help/topics/GhidraScriptMgrPlugin/GhidraScriptMgrPlugin.htm index f45d72aef7..884ee56e12 100644 --- a/Ghidra/Features/Base/src/main/help/help/topics/GhidraScriptMgrPlugin/GhidraScriptMgrPlugin.htm +++ b/Ghidra/Features/Base/src/main/help/help/topics/GhidraScriptMgrPlugin/GhidraScriptMgrPlugin.htm @@ -324,8 +324,7 @@ diff --git a/Ghidra/Features/Base/src/main/help/help/topics/GhidraScriptMgrPlugin/ScriptDevelopment.htm b/Ghidra/Features/Base/src/main/help/help/topics/GhidraScriptMgrPlugin/ScriptDevelopment.htm index dd2c4a5750..d949399ba7 100644 --- a/Ghidra/Features/Base/src/main/help/help/topics/GhidraScriptMgrPlugin/ScriptDevelopment.htm +++ b/Ghidra/Features/Base/src/main/help/help/topics/GhidraScriptMgrPlugin/ScriptDevelopment.htm @@ -2,16 +2,12 @@ - - Script Development - - +

    Ghidra Script Development

    Ghidra provides built-in support for creating scripts using the Java language and @@ -192,5 +188,17 @@

    Returns a new instance of the GhidraScript

    + + +

    Related Topics:

    + + + +

     

    +
    +
    +
    diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/interpreter/InterpreterPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/interpreter/InterpreterPanel.java index 6a9b7be33f..dd7dbe312d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/interpreter/InterpreterPanel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/interpreter/InterpreterPanel.java @@ -50,8 +50,9 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener { "This is the font that will be used in the Console. " + "Double-click the font example to change it."; - private static final Color NORMAL_COLOR = new GColor("color.fg.interpreterpanel"); - private static final Color ERROR_COLOR = new GColor("color.fg.interpreterpanel.error"); + private static final Color NORMAL_COLOR = new GColor("color.fg.interpreterconsole"); + private static final Color ERROR_COLOR = new GColor("color.fg.interpreterconsole.error"); + private static final Color BG_COLOR = new GColor("color.bg.interpreterconsole"); public enum TextType { STDOUT, STDERR, STDIN; @@ -127,6 +128,10 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener { inputTextPane = new JTextPane(); inputTextPane.setName("Interpreter Input Field"); + outputTextPane.setBackground(BG_COLOR); + promptTextPane.setBackground(BG_COLOR); + inputTextPane.setBackground(BG_COLOR); + history = new HistoryManagerImpl(); outputScrollPane.setFocusable(false); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/totd/TipOfTheDayDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/totd/TipOfTheDayDialog.java index fc5a3a0721..5fbf6ce20d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/totd/TipOfTheDayDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/totd/TipOfTheDayDialog.java @@ -35,6 +35,7 @@ class TipOfTheDayDialog extends DialogComponentProvider { private static final String FONT_ID = "font.plugin.tips"; private static final String FONT_LABEL_ID = "font.plugin.tips.label"; private static final int _24_HOURS = 86400000; + private TipOfTheDayPlugin plugin; private JCheckBox showTipsCheckbox; private JButton nextTipButton; @@ -61,15 +62,16 @@ class TipOfTheDayDialog extends DialogComponentProvider { tipArea.setWrapStyleWord(true); tipArea.setLineWrap(true); tipArea.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + tipArea.setBackground(Colors.BACKGROUND); JScrollPane tipScroll = new JScrollPane(tipArea); tipScroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); tipScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); - tipScroll.setBorder(null); + tipScroll.setBorder(BorderFactory.createEmptyBorder()); tipScroll.setPreferredSize(tipArea.getPreferredSize()); showTipsCheckbox = new GCheckBox("Show Tips on Startup?"); - showTipsCheckbox.setSelected(true); // TODO (FixMe) Moved this before its listener to prevent project save for now. + showTipsCheckbox.setSelected(true); // before adding the listener to prevent project save showTipsCheckbox.addItemListener(e -> showTipsChanged()); nextTipButton = new JButton("Next Tip"); @@ -88,9 +90,10 @@ class TipOfTheDayDialog extends DialogComponentProvider { BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10), BorderFactory.createLineBorder(Java.BORDER)); panel.setBorder(panelBorder); - panel.setBackground(Colors.BACKGROUND); JLabel label = new GLabel("Did you know...", tipIcon, SwingConstants.LEFT); + label.setBackground(Colors.BACKGROUND); + label.setOpaque(true); Gui.registerFont(label, FONT_LABEL_ID); panel.add(label, BorderLayout.NORTH); diff --git a/Ghidra/Features/Python/data/python.theme.properties b/Ghidra/Features/Python/data/python.theme.properties index 52757dc295..be4b0ad446 100644 --- a/Ghidra/Features/Python/data/python.theme.properties +++ b/Ghidra/Features/Python/data/python.theme.properties @@ -15,5 +15,7 @@ color.fg.plugin.python.syntax.special = darkgreen icon.plugin.python = python.png + + [Dark Defaults] diff --git a/Ghidra/Features/Python/src/main/help/help/topics/Python/interpreter.html b/Ghidra/Features/Python/src/main/help/help/topics/Python/interpreter.html index ed62387a43..4aeb57dc80 100644 --- a/Ghidra/Features/Python/src/main/help/help/topics/Python/interpreter.html +++ b/Ghidra/Features/Python/src/main/help/help/topics/Python/interpreter.html @@ -2,9 +2,6 @@ - - Python Interpreter @@ -165,5 +162,10 @@

    Provided by: PythonPlugin

    +

     

    +
    +
    +
    + diff --git a/Ghidra/Features/Python/src/main/java/ghidra/python/PythonCodeCompletionFactory.java b/Ghidra/Features/Python/src/main/java/ghidra/python/PythonCodeCompletionFactory.java index 6943b2cbd2..d0a9132072 100644 --- a/Ghidra/Features/Python/src/main/java/ghidra/python/PythonCodeCompletionFactory.java +++ b/Ghidra/Features/Python/src/main/java/ghidra/python/PythonCodeCompletionFactory.java @@ -194,7 +194,7 @@ public class PythonCodeCompletionFactory { PyObject pyObj) { return newCodeCompletion(description, insertion, pyObj, ""); } - + /** * Creates a new CodeCompletion from the given Python objects. * @@ -235,7 +235,7 @@ public class PythonCodeCompletionFactory { } } } - + int charsToRemove = userInput.length(); return new CodeCompletion(description, insertion, comp, charsToRemove); } @@ -249,18 +249,6 @@ public class PythonCodeCompletionFactory { includeTypes = options.getBoolean(INCLUDE_TYPES_LABEL, INCLUDE_TYPES_DEFAULT); options.registerOption(INCLUDE_TYPES_LABEL, INCLUDE_TYPES_DEFAULT, null, INCLUDE_TYPES_DESCRIPTION); - - Iterator iter = classes.iterator(); - while (iter.hasNext()) { - Class currentClass = (Class) iter.next(); - options.registerOption( - COMPLETION_LABEL + Options.DELIMITER + getSimpleName(currentClass), - classToColorMap.get(currentClass), null, - "Color to use for " + classDescription.get(currentClass) + "."); - classToColorMap.put(currentClass, - options.getColor(COMPLETION_LABEL + Options.DELIMITER + getSimpleName(currentClass), - classToColorMap.get(currentClass))); - } } /** @@ -279,13 +267,7 @@ public class PythonCodeCompletionFactory { */ public static void changeOptions(Options options, String name, Object oldValue, Object newValue) { - String classSimpleName = name.substring((COMPLETION_LABEL + Options.DELIMITER).length()); - Class klass = simpleNameToClass.get(classSimpleName); - - if (classToColorMap.containsKey(klass)) { - classToColorMap.put(klass, (Color) newValue); - } - else if (name.equals(INCLUDE_TYPES_LABEL)) { + if (name.equals(INCLUDE_TYPES_LABEL)) { includeTypes = ((Boolean) newValue).booleanValue(); } else { diff --git a/Ghidra/Framework/Docking/src/main/help/help/shared/DarkStyle.css b/Ghidra/Framework/Docking/src/main/help/help/shared/DarkStyle.css deleted file mode 100644 index 6ff0fe6fb8..0000000000 --- a/Ghidra/Framework/Docking/src/main/help/help/shared/DarkStyle.css +++ /dev/null @@ -1,58 +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. - */ -/* - Java Help Note: JavaHelp does not accept sizes (like in 'margin-top') in anything but - px (pixel) or with no type marking. -*/ - -body { margin-bottom: 50px; margin-left: 10px; margin-right: 10px; margin-top: 10px; } /* some padding to improve readability */ -li { font-family:times new roman; font-size:14pt; } -h1 { color:#80a0c0; font-family:times new roman; font-size:36pt; font-style:italic; font-weight:bold; text-align:center; } -h2 { margin: 10px; margin-top: 20px; color:#DDA0DD; font-family:times new roman; font-size:18pt; font-weight:bold; } -h3 { margin-left: 10px; margin-top: 20px; color:#6495ED; font-family:times new roman; font-size:14pt; font-weight:bold; } -h4 { margin-left: 10px; margin-top: 20px; font-family:times new roman; font-size:14pt; font-style:italic; } - -/* - P tag code. Most of the help files nest P tags inside of blockquote tags (the was the - way it had been done in the beginning). The net effect is that the text is indented. In - modern HTML we would use CSS to do this. We need to support the Ghidra P tags, nested in - blockquote tags, as well as naked P tags. The following two lines accomplish this. Note - that the 'blockquote p' definition will inherit from the first 'p' definition. -*/ -p { margin-left: 40px; font-family:times new roman; font-size:14pt; } -blockquote p { margin-left: 10px; } - -p.providedbyplugin { color:#7f7f7f; margin-left: 10px; font-size:14pt; margin-top:100px } -p.ProvidedByPlugin { color:#7f7f7f; margin-left: 10px; font-size:14pt; margin-top:100px } -p.relatedtopic { color:#9370DB; margin-left: 10px; font-size:14pt; } -p.RelatedTopic { color:#9370DB; margin-left: 10px; font-size:14pt; } - -/* - We wish for a tables to have space between it and the preceding element, so that text - is not too close to the top of the table. Also, nest the table a bit so that it is clear - the table relates to the preceding text. -*/ -table { margin-left: 20px; margin-top: 10px; width: 80%;} -td { font-family:times new roman; font-size:14pt; vertical-align: top; } -th { font-family:times new roman; font-size:14pt; font-weight:bold; background-color: #EDF3FE; color: gray;} - -/* - Code-like formatting for things such as file system paths and proper names of classes, - methods, etc. To apply this to a file path, use this syntax: - ... -*/ -code { color: #F5F5F5; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; } -code.path { color: #4682B4; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/ComponentThemeInspectorAction.java b/Ghidra/Framework/Docking/src/main/java/docking/action/ComponentThemeInspectorAction.java index a23b59e0b9..798feb4a35 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/action/ComponentThemeInspectorAction.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/action/ComponentThemeInspectorAction.java @@ -16,8 +16,7 @@ package docking.action; import java.awt.*; -import java.util.ArrayList; -import java.util.Collections; +import java.util.*; import java.util.List; import javax.swing.*; @@ -29,6 +28,7 @@ import org.apache.commons.lang3.StringUtils; import docking.ActionContext; import docking.DockingWindowManager; +import generic.theme.GColor; import generic.util.action.ReservedKeyBindings; import ghidra.util.Msg; @@ -154,6 +154,15 @@ public class ComponentThemeInspectorAction extends DockingAction { spacer = "\t"; } + String bgText = Objects.toString(bg); + if (bg instanceof GColor gColor) { + bgText = gColor.toDebugString(); + } + String fgText = Objects.toString(fg); + if (fg instanceof GColor gColor) { + fgText = gColor.toDebugString(); + } + String tabs = '\n' + StringUtils.repeat(' ', (indent * 3)); buffy.append(tabs) .append(indentMarker) @@ -161,11 +170,11 @@ public class ComponentThemeInspectorAction extends DockingAction { .append(tabs) .append(spacer) .append("bg: ") - .append(bg) + .append(bgText) .append(tabs) .append(spacer) .append("fg: ") - .append(fg) + .append(fgText) .append('\n'); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/DefaultTableCellRendererWrapper.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/DefaultTableCellRendererWrapper.java index a298d08051..c5b58730d0 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/DefaultTableCellRendererWrapper.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/DefaultTableCellRendererWrapper.java @@ -58,6 +58,7 @@ public class DefaultTableCellRendererWrapper extends GTableCellRenderer { JComponent thisRenderer = (JComponent) super.getTableCellRendererComponent(data); + rendererComponent.setForeground(thisRenderer.getForeground()); rendererComponent.setBackground(thisRenderer.getBackground()); if (rendererComponent instanceof JComponent) { diff --git a/Ghidra/Framework/Gui/certification.manifest b/Ghidra/Framework/Gui/certification.manifest index 6a1d818383..8b771b90f8 100644 --- a/Ghidra/Framework/Gui/certification.manifest +++ b/Ghidra/Framework/Gui/certification.manifest @@ -8,6 +8,7 @@ ##MODULE IP: Tango Icons - Public Domain .classpath||GHIDRA||||END| Module.manifest||GHIDRA||||END| +data/gui.laf.overrides.theme.properties||GHIDRA||||END| data/gui.palette.theme.properties||GHIDRA||||END| data/gui.theme.properties||GHIDRA||||END| src/main/java/ghidra/framework/options/package.html||GHIDRA||||END| diff --git a/Ghidra/Framework/Gui/data/gui.laf.overrides.theme.properties b/Ghidra/Framework/Gui/data/gui.laf.overrides.theme.properties new file mode 100644 index 0000000000..918e1bbd12 --- /dev/null +++ b/Ghidra/Framework/Gui/data/gui.laf.overrides.theme.properties @@ -0,0 +1,55 @@ +[Defaults] + +// TODO these are only here because they are used in the dark section; remove from here if done in +// source code instead; otherwise, update error reporting to not require an entry in the default +// section for values defined in specific LaF sections +color.flat.text.original.bg = white // default 'text' value in Flat Light +color.flat.selection.inactive.bg = #d3d3d3 // default value in Flat Light + + +[Dark Defaults] + + + + +[Flat Dark] + +// the default inactive selection color is too close to the bg color to be easily visible +color.flat.selection.inactive.bg = #0F4C6A + +// +// We would like widgets to use a bg color. By default widgets and some other items are all mapped +// to 'text'. The easiest way to change all widgets is to change the value of 'text'. Then, for +// any values that should still use the old value, we need to remap those. (The foreground colors +// for these are mapped to 'textText'. For now, that value seems good enough that we do not need +// to change it.) +// +color.flat.text.original.bg = #46494b // default 'text' value +[color]text = color.bg +[color]desktop = color.flat.text.original.bg +[color]TableHeader = color.flat.text.original.bg +[color]Checkbox.icon.background = color.flat.text.original.bg +[color]Checkbox.icon.selectedBackground = color.flat.text.original.bg +[color]CheckBox.icon[filled].checkmarkColor = color.flat.text.original.bg +[color]ComboBox.buttonBackground = color.flat.text.original.bg +[color]Spinner.background = color.flat.text.original.bg + + + +[color]TextArea.background = color.bg +[color]TextArea.foreground = color.fg + +[color]TextPane.background = color.bg +[color]TextPane.foreground = color.fg + + + + + +[Nimbus] + +// Nimbus uses the ToolTipPainter class to paint tooltips. That class does not read the property +// we use for tooltips, which is 'ToolTip.background', even though that is defined by the LaF. +// Setting the 'info' value here to changes the key the painter users to paint tooltips. The info +// value seems to only be used for tooltips, which means this change affects no other components. +[color]info = [color]ToolTip.background diff --git a/Ghidra/Framework/Gui/data/gui.theme.properties b/Ghidra/Framework/Gui/data/gui.theme.properties index 8a0a75c63a..deeb30c889 100644 --- a/Ghidra/Framework/Gui/data/gui.theme.properties +++ b/Ghidra/Framework/Gui/data/gui.theme.properties @@ -128,11 +128,6 @@ color.bg.tree = color.bg color.bg.tree.selected = [color]Tree.selectionBackground -[Flat Dark] - -// the default inactive selection color is too close to the bg color to be easily visible -color.flat.selection.inactive = #0F4C6A - [CDE/Motif] @@ -140,10 +135,3 @@ color.bg = [color]window // gray for motif color.fg = [color]textText -[Nimbus] - -// Nimbus uses the ToolTipPainter class to paint tooltips. That class does not read the property -// we use for tooltips, which is 'ToolTip.background', even though that is defined by the LaF. -// Setting the 'info' value here to changes the key the painter users to paint tooltips. The info -// value seems to only be used for tooltips, which means this change affects no other components. -[color]info = [color]ToolTip.background diff --git a/Ghidra/Framework/Gui/src/main/java/generic/theme/ColorValue.java b/Ghidra/Framework/Gui/src/main/java/generic/theme/ColorValue.java index 9c2fdf0318..746e95b14f 100644 --- a/Ghidra/Framework/Gui/src/main/java/generic/theme/ColorValue.java +++ b/Ghidra/Framework/Gui/src/main/java/generic/theme/ColorValue.java @@ -61,6 +61,11 @@ public class ColorValue extends ThemeValue { return outputId + " = " + getSerializedValue(); } + @Override + public boolean isExternal() { + return !id.startsWith(COLOR_ID_PREFIX); + } + /** * Returns true if the given key string is a valid external key for a color value * @param key the key string to test @@ -93,7 +98,7 @@ public class ColorValue extends ThemeValue { } @Override - protected Color getUnresolvedReferenceValue(String id, String unresolvedId) { + protected Color getUnresolvedReferenceValue(String primaryId, String unresolvedId) { Throwable t = ReflectionUtilities.createThrowableWithStackOlderThan(); StackTraceElement[] trace = t.getStackTrace(); @@ -104,7 +109,7 @@ public class ColorValue extends ThemeValue { Msg.error(this, "Could not resolve indirect color path for \"" + unresolvedId + - "\" for primary id \"" + id + "\", using last resort default", + "\" for primary id \"" + primaryId + "\", using last resort default", t); return LAST_RESORT_DEFAULT; } diff --git a/Ghidra/Framework/Gui/src/main/java/generic/theme/FontValue.java b/Ghidra/Framework/Gui/src/main/java/generic/theme/FontValue.java index 50e95a91b5..af304469d8 100644 --- a/Ghidra/Framework/Gui/src/main/java/generic/theme/FontValue.java +++ b/Ghidra/Framework/Gui/src/main/java/generic/theme/FontValue.java @@ -57,6 +57,17 @@ public class FontValue extends ThemeValue { this.modifier = modifier; } + @Override + public String getSerializationString() { + String outputId = toExternalId(id); + return outputId + " = " + getValueOutput(); + } + + @Override + public boolean isExternal() { + return !id.startsWith(FONT_ID_PREFIX); + } + @Override public Font get(GThemeValueMap values) { Font font = super.get(values); @@ -66,12 +77,6 @@ public class FontValue extends ThemeValue { return font; } - @Override - public String getSerializationString() { - String outputId = toExternalId(id); - return outputId + " = " + getValueOutput(); - } - private String getValueOutput() { if (referenceId != null) { String refId = toExternalId(referenceId); @@ -107,7 +112,7 @@ public class FontValue extends ThemeValue { * @param key the key to associate the parsed value with * @param value the font value to parse * @return a FontValue with the given key and the parsed value - * @throws ParseException + * @throws ParseException if there is an exception parsing */ public static FontValue parse(String key, String value) throws ParseException { String id = fromExternalId(key); @@ -148,10 +153,10 @@ public class FontValue extends ThemeValue { } @Override - protected Font getUnresolvedReferenceValue(String id, String unresolvedId) { + protected Font getUnresolvedReferenceValue(String primaryId, String unresolvedId) { Msg.warn(this, "Could not resolve indirect font path for \"" + unresolvedId + - "\" for primary id \"" + id + "\", using last resort default"); + "\" for primary id \"" + primaryId + "\", using last resort default"); return LAST_RESORT_DEFAULT; } diff --git a/Ghidra/Framework/Gui/src/main/java/generic/theme/IconValue.java b/Ghidra/Framework/Gui/src/main/java/generic/theme/IconValue.java index ae5479e5e8..b2767a0b4b 100644 --- a/Ghidra/Framework/Gui/src/main/java/generic/theme/IconValue.java +++ b/Ghidra/Framework/Gui/src/main/java/generic/theme/IconValue.java @@ -74,6 +74,17 @@ public class IconValue extends ThemeValue { this.modifier = modifier; } + @Override + public String getSerializationString() { + String outputId = toExternalId(id); + return outputId + " = " + getValueOutput(); + } + + @Override + public boolean isExternal() { + return !id.startsWith(ICON_ID_PREFIX); + } + @Override public Icon get(GThemeValueMap values) { Icon icon = super.get(values); @@ -83,12 +94,6 @@ public class IconValue extends ThemeValue { return icon; } - @Override - public String getSerializationString() { - String outputId = toExternalId(id); - return outputId + " = " + getValueOutput(); - } - /** * Returns true if the given key string is a valid external key for an icon value * @param key the key string to test @@ -197,10 +202,10 @@ public class IconValue extends ThemeValue { } @Override - protected Icon getUnresolvedReferenceValue(String id, String unresolvedId) { + protected Icon getUnresolvedReferenceValue(String primaryId, String unresolvedId) { Msg.warn(this, "Could not resolve indirect icon path for \"" + unresolvedId + - "\" for primary id \"" + id + "\", using last resort default"); + "\" for primary id \"" + primaryId + "\", using last resort default"); return LAST_RESORT_DEFAULT; } diff --git a/Ghidra/Framework/Gui/src/main/java/generic/theme/ThemePropertyFileReader.java b/Ghidra/Framework/Gui/src/main/java/generic/theme/ThemePropertyFileReader.java index 4b1bc12c53..0c20168aa2 100644 --- a/Ghidra/Framework/Gui/src/main/java/generic/theme/ThemePropertyFileReader.java +++ b/Ghidra/Framework/Gui/src/main/java/generic/theme/ThemePropertyFileReader.java @@ -79,6 +79,7 @@ public class ThemePropertyFileReader extends AbstractThemeReader { return customSectionsMap; } + @Override protected void processNoSection(Section section) throws IOException { if (!section.isEmpty()) { error(section.getLineNumber(), @@ -125,17 +126,26 @@ public class ThemePropertyFileReader extends AbstractThemeReader { private void validate(String name, GThemeValueMap valuesMap) { for (String id : valuesMap.getColorIds()) { if (!defaults.containsColor(id)) { - reportMissingDefaultsError("Color", name, id); + ColorValue value = valuesMap.getColor(id); + if (!value.isExternal()) { + reportMissingDefaultsError("Color", name, id); + } } } for (String id : valuesMap.getFontIds()) { if (!defaults.containsFont(id)) { - reportMissingDefaultsError("Font", name, id); + FontValue value = valuesMap.getFont(id); + if (!value.isExternal()) { + reportMissingDefaultsError("Font", name, id); + } } } for (String id : valuesMap.getIconIds()) { if (!defaults.containsIcon(id)) { - reportMissingDefaultsError("Icon", name, id); + IconValue value = valuesMap.getIcon(id); + if (!value.isExternal()) { + reportMissingDefaultsError("Icon", name, id); + } } } } diff --git a/Ghidra/Framework/Gui/src/main/java/generic/theme/ThemeValue.java b/Ghidra/Framework/Gui/src/main/java/generic/theme/ThemeValue.java index 674e6d33f5..61333c8282 100644 --- a/Ghidra/Framework/Gui/src/main/java/generic/theme/ThemeValue.java +++ b/Ghidra/Framework/Gui/src/main/java/generic/theme/ThemeValue.java @@ -41,6 +41,13 @@ public abstract class ThemeValue implements Comparable> { this.value = value; } + /** + * True if this value is one that is one that is defined outside of the application, such as a + * Java Look and Feel key. + * @return true if external + */ + public abstract boolean isExternal(); + /** * Returns the identifier for this ThemeValue. * @return the identifier for this ThemeValue. @@ -189,11 +196,11 @@ public abstract class ThemeValue implements Comparable> { /** * Returns the T to be used if the indirect reference couldn't be resolved. - * @param id the id we are trying to get a value foe + * @param primaryId the id we are trying to get a value for * @param unresolvedId the reference id that couldn't be resolved * @return the default value to be used if the indirect reference couldn't be resolved. */ - protected abstract T getUnresolvedReferenceValue(String id, String unresolvedId); + protected abstract T getUnresolvedReferenceValue(String primaryId, String unresolvedId); /** * Returns the ThemeValue referred to by this ThemeValue. Needs to be overridden by diff --git a/Ghidra/Framework/Help/data/help.theme.properties b/Ghidra/Framework/Help/data/help.theme.properties index c08c5946d8..7a79859e8f 100644 --- a/Ghidra/Framework/Help/data/help.theme.properties +++ b/Ghidra/Framework/Help/data/help.theme.properties @@ -21,7 +21,7 @@ color.fg.help.selector.h1 = #66AAF4 color.fg.help.selector.h2 = #9999F9 color.fg.help.selector.h3 = #FF99CC color.fg.help.selector.p.provided.by.plugin = #CCCCCC -color.fg.help.selector.p.related.topic = #800080 +color.fg.help.selector.p.related.topic = #9370DB color.fg.help.selector.th = #EDF3FE color.fg.help.selector.code = gray color.fg.help.selector.code.path = #5BA5E3 \ No newline at end of file diff --git a/Ghidra/Framework/Help/src/main/resources/help/shared/DarkStyle.css b/Ghidra/Framework/Help/src/main/resources/help/shared/DarkStyle.css index 6ff0fe6fb8..95ab0eac89 100644 --- a/Ghidra/Framework/Help/src/main/resources/help/shared/DarkStyle.css +++ b/Ghidra/Framework/Help/src/main/resources/help/shared/DarkStyle.css @@ -14,17 +14,50 @@ * limitations under the License. */ /* + WARNING! Java Help Note: JavaHelp does not accept sizes (like in 'margin-top') in anything but px (pixel) or with no type marking. + + The blockquote tag is used heavily to control indentation throughout the help docs. Place the + blockquote tag around other elements to create a standard indentation. The default values of + blockquote are: + + blockquote { + display: block; + margin-top: 1em; + margin-bottom: 1em; + margin-left: 40px; + margin-right: 40px; + } + */ -body { margin-bottom: 50px; margin-left: 10px; margin-right: 10px; margin-top: 10px; } /* some padding to improve readability */ -li { font-family:times new roman; font-size:14pt; } -h1 { color:#80a0c0; font-family:times new roman; font-size:36pt; font-style:italic; font-weight:bold; text-align:center; } -h2 { margin: 10px; margin-top: 20px; color:#DDA0DD; font-family:times new roman; font-size:18pt; font-weight:bold; } -h3 { margin-left: 10px; margin-top: 20px; color:#6495ED; font-family:times new roman; font-size:14pt; font-weight:bold; } + + +/* + Add some indentation for lists to show their relation to the preceding text. The value is + chosen based on the left margin of the body and the blockquote. +*/ +ul { margin-left: 50px; } +ol { margin-left: 50px; } +li { font-family:times new roman; font-size:14pt; margin-left: 5px; } + + +h1 { color:#66AAF4; font-family:times new roman; font-size:36pt; font-style:italic; font-weight:bold; text-align:center; } +h2 { margin: 10px; margin-top: 20px; color:#9999F9; font-family:times new roman; font-size:18pt; font-weight:bold; } +h3 { margin-left: 10px; margin-top: 20px; color:#FF99CC; font-family:times new roman; font-size:14pt; font-weight:bold; } h4 { margin-left: 10px; margin-top: 20px; font-family:times new roman; font-size:14pt; font-style:italic; } + +/* + A class to be used for showing screenshot style images. These images will have padding above + and below the image and will be centered. To apply this to a file path, use this syntax: +
    +*/ +div.image { margin-top: 20px; margin-bottom: 40px; text-align: center; } + + + /* P tag code. Most of the help files nest P tags inside of blockquote tags (the was the way it had been done in the beginning). The net effect is that the text is indented. In @@ -34,11 +67,10 @@ h4 { margin-left: 10px; margin-top: 20px; font-family:times new roman; font-size */ p { margin-left: 40px; font-family:times new roman; font-size:14pt; } blockquote p { margin-left: 10px; } - -p.providedbyplugin { color:#7f7f7f; margin-left: 10px; font-size:14pt; margin-top:100px } -p.ProvidedByPlugin { color:#7f7f7f; margin-left: 10px; font-size:14pt; margin-top:100px } +p.providedbyplugin { color:#CCCCCC; margin-left: 10px; font-size:14pt; margin-top:100px } p.relatedtopic { color:#9370DB; margin-left: 10px; font-size:14pt; } -p.RelatedTopic { color:#9370DB; margin-left: 10px; font-size:14pt; } +p.image { margin-top: 100; margin-bottom: 100; } + /* We wish for a tables to have space between it and the preceding element, so that text @@ -49,10 +81,11 @@ table { margin-left: 20px; margin-top: 10px; width: 80%;} td { font-family:times new roman; font-size:14pt; vertical-align: top; } th { font-family:times new roman; font-size:14pt; font-weight:bold; background-color: #EDF3FE; color: gray;} + /* Code-like formatting for things such as file system paths and proper names of classes, methods, etc. To apply this to a file path, use this syntax: ... */ -code { color: #F5F5F5; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; } -code.path { color: #4682B4; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; } +code { color: gray; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; } +code.path { color: #5BA5E3; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; } diff --git a/Ghidra/Framework/Help/src/main/resources/help/shared/DefaultStyle.css b/Ghidra/Framework/Help/src/main/resources/help/shared/DefaultStyle.css index b45630ae27..281d871a1c 100644 --- a/Ghidra/Framework/Help/src/main/resources/help/shared/DefaultStyle.css +++ b/Ghidra/Framework/Help/src/main/resources/help/shared/DefaultStyle.css @@ -31,8 +31,7 @@ } */ - -body { margin-bottom: 50px; margin-left: 10px; margin-right: 10px; margin-top: 10px; } /* some padding to improve readability */ + /* Add some indentation for lists to show their relation to the preceding text. The value is