GP-1981 - Theme Help

This commit is contained in:
dragonmacher 2022-11-14 17:07:46 -05:00 committed by ghidragon
parent edfb5a0877
commit 72e87f8e2d
18 changed files with 587 additions and 438 deletions

View file

@ -28,7 +28,6 @@ import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.Configuration;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.framework.LoggingInitialization; import ghidra.framework.LoggingInitialization;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.Swing; import ghidra.util.Swing;
@ -74,11 +73,7 @@ public class AgentWindow extends JFrame implements WindowListener, LogListener {
@Override @Override
public void messageLogged(String message, boolean isError) { public void messageLogged(String message, boolean isError) {
<<<<<<< Upstream, based on origin/master
=======
String fMessage =
isError ? "<font color=\"" + Messages.ERROR + "\">" + message + "</font>" : message;
>>>>>>> 1e5309a GP-1981 - Theming - Color conversion for Debugger modules
Swing.runIfSwingOrRunLater(() -> { Swing.runIfSwingOrRunLater(() -> {
MutableAttributeSet attributes = new SimpleAttributeSet(); MutableAttributeSet attributes = new SimpleAttributeSet();
if (isError) { if (isError) {

View file

@ -165,7 +165,7 @@
with the analyzer.</FONT></P> with the analyzer.</FONT></P>
</BLOCKQUOTE> </BLOCKQUOTE>
<P style="background-color: #FFF0E0;"> <P style="background-color: #FFF0E0; color: black;">
<IMG SRC="../../shared/warning.png" />Note that multi-user merge does not currently support <IMG SRC="../../shared/warning.png" />Note that multi-user merge does not currently support
merging of Program Options (including Analysis Options). Options stored in shared Program database merging of Program Options (including Analysis Options). Options stored in shared Program database
following a conflicting checkin may not reflect option settings specified prior to checkin. following a conflicting checkin may not reflect option settings specified prior to checkin.
@ -182,9 +182,9 @@
the current program.</LI> the current program.</LI>
</UL> </UL>
<P style="background-color: #FFF0E0;"> <P style="background-color: #FFF0E0; color: black;">
<IMG SRC="../../shared/warning.png" />Access to stored configurations is not currently <IMG SRC="../../shared/warning.png" />Access to stored configurations is not currently
aupported across different versions of Ghidra. supported across different versions of Ghidra.
</P> </P>
</BLOCKQUOTE> </BLOCKQUOTE>
@ -452,7 +452,7 @@
</UL> </UL>
</P> </P>
<P style="background-color: #FFF0E0;"> <P style="background-color: #FFF0E0; color: black;">
<IMG SRC="../../shared/warning.png" />When using an external GNU demangler, <IMG SRC="../../shared/warning.png" />When using an external GNU demangler,
please understand the risks associated with using that version of the please understand the risks associated with using that version of the
software. The <CODE>demangler_gnu_v2_24</CODE> version of the software. The <CODE>demangler_gnu_v2_24</CODE> version of the

View file

@ -448,12 +448,11 @@
<TABLE border="1" width="80%"> <TABLE border="1" width="80%">
<TBODY> <TBODY>
<TR> <TR>
<TD align="center" bgcolor="#00ffff" width="25%">File Status</TD> <TH align="center" width="25%">File Status</TH>
<TD align="center" bgcolor="#00ffff" width="20%">Sample Icon in Project Data <TH align="center" width="20%">Sample Icon</TH>
Tree</TD>
<TD align="center" bgcolor="#00ffff" width="40%">Description</TD> <TH align="center" width="40%">Description</TH>
</TR> </TR>
<TR> <TR>

View file

@ -25,7 +25,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
<P align="center">&nbsp;</P> <P align="center">&nbsp;</P>
<P><A name="a"></A><FONT color="#800080" size="7"><B>A</B></FONT></P> <P><A name="a"></A><FONT size="7"><B>A</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="Action"></A>Action</H2> <H2><A name="Action"></A>Action</H2>
@ -97,7 +97,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<H2><A name="b"></A><FONT color="#800080" size="7"><B>B</B></FONT></H2> <H2><A name="b"></A><FONT size="7"><B>B</B></FONT></H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="BackReference"></A>Back Reference</H2> <H2><A name="BackReference"></A>Back Reference</H2>
@ -197,7 +197,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="c"></A><FONT color="#800080" size="7"><B>C</B></FONT></P> <P><A name="c"></A><FONT size="7"><B>C</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="CallBlockModel"></A>Call Block Model</H2> <H2><A name="CallBlockModel"></A>Call Block Model</H2>
@ -319,7 +319,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="d"></A><FONT color="#800080" size="7"><B>D</B></FONT></P> <P><A name="d"></A><FONT size="7"><B>D</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="DataItem"></A>Data (item)</H2> <H2><A name="DataItem"></A>Data (item)</H2>
@ -436,7 +436,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="e"></A><FONT color="#800080" size="7"><B>E</B></FONT></P> <P><A name="e"></A><FONT size="7"><B>E</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="ELF"></A>ELF</H2> <H2><A name="ELF"></A>ELF</H2>
@ -491,7 +491,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="f"></A><FONT color="#800080" size="7"><B>F</B></FONT></P> <P><A name="f"></A><FONT size="7"><B>F</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="FallThroughAddress"></A>Fall Through Address</H2> <H2><A name="FallThroughAddress"></A>Fall Through Address</H2>
@ -555,7 +555,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="g"></A><FONT color="#800080" size="7"><B>G</B></FONT></P> <P><A name="g"></A><FONT size="7"><B>G</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="Ghidra"></A>Ghidra</H2> <H2><A name="Ghidra"></A>Ghidra</H2>
@ -606,7 +606,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="h"></A><FONT color="#800080" size="7"><B>H</B></FONT></P> <P><A name="h"></A><FONT size="7"><B>H</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="HexInteger"></A>Hex Integer</H2> <H2><A name="HexInteger"></A>Hex Integer</H2>
@ -636,7 +636,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="i"></A><FONT color="#800080" size="7"><B>I</B></FONT></P> <P><A name="i"></A><FONT size="7"><B>I</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="IDA_Pro"></A>IDA Pro</H2> <H2><A name="IDA_Pro"></A>IDA Pro</H2>
@ -688,7 +688,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="k"></A><FONT color="#800080" size="7"><B>K</B></FONT></P> <P><A name="k"></A><FONT size="7"><B>K</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="KeyBinding"></A>Key Binding</H2> <H2><A name="KeyBinding"></A>Key Binding</H2>
@ -698,7 +698,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="l"></A><FONT color="#800080" size="7"><B>L</B></FONT></P> <P><A name="l"></A><FONT size="7"><B>L</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="Label"></A>Label&nbsp;</H2> <H2><A name="Label"></A>Label&nbsp;</H2>
@ -756,7 +756,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="m"></A><FONT color="#800080" size="7"><B>M</B></FONT></P> <P><A name="m"></A><FONT size="7"><B>M</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
@ -848,7 +848,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="n"></A><FONT color="#800080" size="7"><B>N</B></FONT></P> <P><A name="n"></A><FONT size="7"><B>N</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="NameSpace"></A>Name Space</H2> <H2><A name="NameSpace"></A>Name Space</H2>
@ -865,7 +865,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="o"></A><FONT color="#800080" size="7"><B>O</B></FONT></P> <P><A name="o"></A><FONT size="7"><B>O</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="Offcut"></A>Offcut</H2> <H2><A name="Offcut"></A>Offcut</H2>
@ -906,7 +906,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="p"></A><FONT color="#800080" size="7"><B>P</B></FONT></P> <P><A name="p"></A><FONT size="7"><B>P</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="PartitionedCodeModel"></A>Partitioned Code Model</H2> <H2><A name="PartitionedCodeModel"></A>Partitioned Code Model</H2>
@ -1058,7 +1058,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="r"></A><FONT color="#800080" size="7"><B>R</B></FONT></P> <P><A name="r"></A><FONT size="7"><B>R</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="ReadOnlyProject"></A>Read-Only Project</H2> <H2><A name="ReadOnlyProject"></A>Read-Only Project</H2>
@ -1108,7 +1108,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="s"></A><FONT color="#800080" size="7"><B>S</B></FONT></P> <P><A name="s"></A><FONT size="7"><B>S</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="Scalar"></A>Scalar</H2> <H2><A name="Scalar"></A>Scalar</H2>
@ -1239,7 +1239,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="t"></A><FONT color="#800080" size="7"><B>T</B></FONT></P> <P><A name="t"></A><FONT size="7"><B>T</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="TabbedWindow"></A>Tabbed Window</H2> <H2><A name="TabbedWindow"></A>Tabbed Window</H2>
@ -1297,7 +1297,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="u"></A><FONT color="#800080" size="7"><B>U</B></FONT></P> <P><A name="u"></A><FONT size="7"><B>U</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="UnconditionalCall"></A>Unconditional Call</H2> <H2><A name="UnconditionalCall"></A>Unconditional Call</H2>
@ -1352,7 +1352,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="v"></A><FONT color="#800080" size="7"><B>V</B></FONT></P> <P><A name="v"></A><FONT size="7"><B>V</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="VersionControl"></A>Version Control</H2> <H2><A name="VersionControl"></A>Version Control</H2>
@ -1383,7 +1383,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="w"></A><FONT color="#800080" size="7"><B>W</B></FONT></P> <P><A name="w"></A><FONT size="7"><B>W</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="Workspace"></A>Workspace</H2> <H2><A name="Workspace"></A>Workspace</H2>
@ -1394,7 +1394,7 @@ xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><A name="x"></A><FONT color="#800080" size="7"><B>X</B></FONT></P> <P><A name="x"></A><FONT size="7"><B>X</B></FONT></P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H2><A name="XREF"></A>XREF</H2> <H2><A name="XREF"></A>XREF</H2>

View file

@ -294,16 +294,11 @@
<CENTER> <CENTER>
<TABLE border="1" width="80%"> <TABLE border="1" width="80%">
<TBODY> <TBODY>
<TR valign="middle">
<TD colspan="2" bgcolor="#c0c0c0" valign="top" align="left">
<P align="center"><B>Tool Options</B></P>
</TD>
</TR>
<TR> <TR>
<TD bgcolor="#DDDDDD" align="left"><B>Option</B></TD> <TH align="left"><B>Option</B></TH>
<TD bgcolor="#DDDDDD" align="left"><B>Description</B></TD> <TH align="left"><B>Description</B></TH>
</TR> </TR>
<TR valign="middle"> <TR valign="middle">
@ -398,15 +393,11 @@
<CENTER> <CENTER>
<TABLE border="1" width="80%"> <TABLE border="1" width="80%">
<TBODY> <TBODY>
<TR valign="middle">
<TD colspan="2" bgcolor="#c0c0c0" valign="top" align="center"><B>Tool
Options</B></TD>
</TR>
<TR> <TR>
<TD bgcolor="#DDDDDD" valign="top" align="left"><B>Option</B></TD> <TH valign="top" align="left"><B>Option</B></TH>
<TD bgcolor="#DDDDDD" valign="top" align="left"><B>Description</B></TD> <TH valign="top" align="left"><B>Description</B></TH>
</TR> </TR>
<TR> <TR>
@ -445,7 +436,7 @@
of the UI. Doing this effectively creates a Dark Theme, which some users find of the UI. Doing this effectively creates a Dark Theme, which some users find
less visually straining.</P> less visually straining.</P>
<BLOCKQUOTE style="background-color: #FFF0E0;"> <BLOCKQUOTE style="background-color: #FFF0E0; color: black;">
<P><IMG alt="" border="0" src="../../shared/warning.png"> As a prototype <P><IMG alt="" border="0" src="../../shared/warning.png"> As a prototype
feature, this feature has many known issues, including:</P> feature, this feature has many known issues, including:</P>

View file

@ -66,8 +66,6 @@ src/main/resources/images/fgpaths.png||GHIDRA||reviewed||END|
src/main/resources/images/fgrevblock.png||GHIDRA||reviewed||END| src/main/resources/images/fgrevblock.png||GHIDRA||reviewed||END|
src/main/resources/images/field.header.png||GHIDRA||reviewed|Custom icon|END| src/main/resources/images/field.header.png||GHIDRA||reviewed|Custom icon|END|
src/main/resources/images/fullscreen_view.png||FAMFAMFAM Icons - CC 2.5||||END| src/main/resources/images/fullscreen_view.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/function_graph.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/function_graph_curvey.png||GHIDRA||reviewed|author eric|END|
src/main/resources/images/graph_view.png||FAMFAMFAM Icons - CC 2.5||||END| src/main/resources/images/graph_view.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/house.png||FAMFAMFAM Icons - CC 2.5||||END| src/main/resources/images/house.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/id.png||FAMFAMFAM Icons - CC 2.5||||END| src/main/resources/images/id.png||FAMFAMFAM Icons - CC 2.5||||END|

View file

@ -33,51 +33,6 @@
"#Function_Graph_Actions">actions</A> that apply to the entire graph.</P> "#Function_Graph_Actions">actions</A> that apply to the entire graph.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<H2><IMG src="images/get-hot-new-stuff.png" alt="Note" border="0">What's New</H2>
<UL>
<li>
Added the Nested Code Layout. This layout shows the code blocks
in a structure that more closely resembles the flow of C code.
</li>
<LI>
Small tweaks (6.0)
<UL>
<li>
<a href="#Satellite_View_Dock">Detachable Satellite View</a>
</li>
<LI>Function signature now included by default</LI>
<LI>Added a <A href="#Vertex_Action_Regroup">regroup action</A> to allow for regrouping
vertices after ungrouping.</LI>
<LI>Articulated edges will now disappear if the connected vertices are dragged outside of
the original angles.</LI>
<LI>
Moved <A href="#Popup_Vertex_Actions">some actions</A> to the context popup menu,
specifically:
<UL>
<LI>Edit Label</LI>
<LI>Fullscreen Mode</LI>
<LI>Jump to XRef</LI>
</UL>
</LI>
</UL>
</LI>
<LI><A href="#Layout_Compressing">Layout Compressing (5.6)</A></LI>
<LI><A href="#Zoom">Keyboard zooming</A> and <A href="#Pan">panning (5.6)</A></LI>
<LI><A href="#Vertex_Grouping">Vertex Grouping (5.5)</A></LI>
</UL><BR>
<BR>
<H2><A name="Primary_View"></A>Primary View</H2> <H2><A name="Primary_View"></A>Primary View</H2>

View file

@ -60,8 +60,8 @@
<tocdef id="Theming" text="Theming" sortgroup="t" target="help/topics/Theming/ThemingOverview.html"> <tocdef id="Theming" text="Theming" sortgroup="t" target="help/topics/Theming/ThemingOverview.html">
<tocdef id="Overview" sortgroup="1" text="Overview" target="help/topics/Theming/ThemingOverview.html"/> <tocdef id="Overview" sortgroup="1" text="Overview" target="help/topics/Theming/ThemingOverview.html"/>
<tocdef id="Editing Themes" sortgroup="2" text="Editing Themes" target="help/topics/Theming/ThemingUserDocs.html"/> <tocdef id="Editing Themes" sortgroup="2" text="Editing Themes" target="help/topics/Theming/ThemingUserDocs.html"/>
<tocdef id="Developer Documentation" sortgroup="3" text="Developer Documentation" target="help/topics/Theming/ThemingDeveloperDocs.html"/> <tocdef id="Architecture" sortgroup="3" text="Architecture" target="help/topics/Theming/ThemingInternals.html"/>
<tocdef id="Architecture Documentation" sortgroup="4" text="Architecture Documentation" target="help/topics/Theming/ThemingInternals.html"/> <tocdef id="Developer Documentation" sortgroup="4" text="Developer's Guide" target="help/topics/Theming/ThemingDeveloperDocs.html"/>
</tocdef> </tocdef>
</tocdef> </tocdef>
</tocroot> </tocroot>

View file

@ -0,0 +1,58 @@
/* ###
* 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 CLASS="path">...</CODE>
*/
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; }

View file

@ -5,129 +5,139 @@
<META name="generator" content= <META name="generator" content=
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net"> "HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
<LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css"> <LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
<TITLE>Theming Developer Documentation</TITLE> <TITLE>Developer's Guide</TITLE>
<TITLE></TITLE>
</HEAD> </HEAD>
<BODY> <BODY>
<H1>Ghidra Theming Developer Documentation</H1> <H1>Developer's Guide to Theming</H1>
<P>This document provides everything an application developer should know when developing <P>This document provides information an application developer should know when developing
plugins, scripts, etc., that use colors, fonts, or icons. By following these guidelines, plugins, actions, scripts, etc., that use colors, fonts, or icons. By following these guidelines,
developers can easily make use of Ghidra's theming capabilities.</P> developers can easily make use of Ghidra's theming capabilities.</P>
<H2>Theme Resource Types</H2> <H2>Theme Resource Types</H2>
<P>When developing application code for Ghidra such as plugins, actions, etc., developers often <P>When developing application code for Ghidra such as plugins, actions, etc., developers often
want to use a color, font, or icon. The key idea to support theming is to never directly want to use colors, fonts, and icons. The key idea to support theming is to never
reference these resources. Instead, the developer should "create" an id string for the resource <B>directly</B>
and then in a .theme.properties file provide a default value for that id (and if appropriate, reference those resources. Instead, the developer should create an ID string for the resource
also define an alternate default value if the theme is a "dark" theme).&nbsp; The way you and then in a <CODE><I>module</I>.theme.properties</CODE> file, provide a default value for that ID.
define and use these ids is a bit different depending on whether the resource is a color, font, (Also, you may define an alternate "dark" default value that will be used if the
or icon. Colors and Icons are similar in that references are done using either GColor or GIcon, current theme is considered a dark theme). The way you
Unfortunately, because of the way Fonts are implemented, there is no GFont, so using fonts is a define and use these IDs is a bit different depending on whether the resource is a color, font,
bit more involved.</P> or icon. Colors and icons are similar in that developers use these types by creating either
<CODE>GColor</CODE> or <CODE>GIcon</CODE>.
Unfortunately, because of the way fonts are implemented, there is no equivalent
<CODE>GFont</CODE>, so using fonts is a bit more involved.</P>
<BLOCKQUOTE> <BLOCKQUOTE>
<H3>Colors</H3> <H3>Colors</H3>
<P>For colors, developers should use the GColor class. Simply construct a new GColor object <P>For colors, developers should use the <CODE>GColor</CODE> class. Simply construct a new
passing in the color resource id as the argument. GColor is a subclass of Color, so it can be <CODE>GColor</CODE> object passing in the color resource ID as the argument.
used anywhere a Color would be used. The developer then needs to provide a default value for <CODE>GColor</CODE> is a subclass of <CODE>Color</CODE>, so it can be
that id in the module's theme.properties file. So, for example:</P> used anywhere a <CODE>Color</CODE> would be used. The developer then needs to provide a
default value for that ID in the module's <CODE><I>module</I>.theme.properties</CODE> file.
So, for example:</P>
<BLOCKQUOTE> <BLOCKQUOTE>
<BLOCKQUOTE> <BLOCKQUOTE>
<CODE class="code">panel.setBackground(Color.Red);</CODE> <CODE>panel.setBackground(Color.Red);</CODE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P>becomes</P> <P>becomes</P>
<BLOCKQUOTE> <BLOCKQUOTE>
<CODE class="code">panel.setBackground(new GColor("color.bg.abc"));</CODE> <CODE>panel.setBackground(new GColor("color.bg.abc"));</CODE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P>and</P> <P>and</P>
<BLOCKQUOTE> <BLOCKQUOTE>
<CODE class="code">public static final Color MY_COLOR = Color.BLUE;</CODE> <CODE>public static final Color MY_COLOR = Color.BLUE;</CODE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P>becomes</P> <P>becomes</P>
<BLOCKQUOTE> <BLOCKQUOTE>
<CODE class="code">public static final Color MY_COLOR = new <CODE>public static final Color MY_COLOR = new
GColor("color.fg.xzy");</CODE> GColor("color.fg.xzy");</CODE>
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P>The GColor class uses a delegation model where all method calls to GColor get mapped to <P>The <CODE>GColor</CODE> class uses a delegation model where all method calls to
its delegate. If ever the color associated with a GColor's resource id changes, the GColor is <CODE>GColor</CODE> get mapped to
refreshed by calling the refresh() method. This is done automatically whenever the its delegate color. If ever the color associated with a <CODE>GColor</CODE>'s resource ID
Gui.setColor(id) is called or a new theme is loaded.</P> changes, the <CODE>GColor</CODE> is automatically updated by calling the
<CODE>refresh()</CODE> method. This is done whenever the
<H3>Fonts</H3> <CODE>Gui.setColor(id)</CODE> is called or a new theme is loaded.</P>
<P>Unfortunately, fonts able to use the delegation trick that was used for colors. Therefore,
there is no GFont class. Programming fonts requires a bit more work. If the use of a font is
in a renderer or in a paint method, imply get the font each time from the Gui class (Font
font = Gui.getFont(String id)). To set a font on a component, use the "registerFont" method
on the Gui class. Once the component is registered, the application will automatically update
the component's font if the font associated with that id changes. So, for example:</P>
<BLOCKQUOTE>
<BLOCKQUOTE>
<CODE class="code">Font font = new Font("Monospaced", Font.BOLD, 12);</CODE>
</BLOCKQUOTE>
<P>becomes</P>
<BLOCKQUOTE>
<CODE class="code">Font font = Gui.getFont("font.xyz");</CODE>
</BLOCKQUOTE>
<P>or</P>
<BLOCKQUOTE>
<CODE class="code">myLabel.setFont(new Font("Dialog", Font.PLAIN, 14)</CODE>
</BLOCKQUOTE>
<P>becomes</P>
<BLOCKQUOTE>
<CODE class="code">Gui.registerFont(myLabel, "font.xyz");</CODE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H3>Icons</H3> <H3>Icons</H3>
<P>Icons work just like colors, so you can just create a GIcon(String id). So, for <P>Icons work just like colors, so you can just create a <CODE>GIcon(String id)</CODE>.
example,&nbsp;</P> So, for example, </P>
<BLOCKQUOTE> <BLOCKQUOTE>
<BLOCKQUOTE> <BLOCKQUOTE>
<CODE class="code">public static final Icon MY_ICON = <CODE>public static final Icon MY_ICON =
ResourceManager("images/balloon.png");</CODE> ResourceManager("images/balloon.png");</CODE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P>becomes</P> <P>becomes</P>
<BLOCKQUOTE> <BLOCKQUOTE>
<CODE class="code">public static final Icon MY_ICON = new <CODE>public static final Icon MY_ICON = new
GIcon("icon.text.bubble");</CODE> GIcon("icon.text.bubble");</CODE>
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE>
<H2>Resource Id Strings<A name="Resource_Ids"></A></H2> <H3>Fonts</H3>
<P>Unfortunately, fonts are unable to use the delegation model used for colors and icons.
Therefore, there is no <CODE>GFont</CODE> class. Programming fonts requires a bit more work.
If a font used directly, such as in renderer or in a paint method, simply get the
font each time
from the <CODE>Gui</CODE> class, as shown below. To set a font on a component, use
<CODE>Gui.registerFont(Component, String)</CODE>. Once the component is registered, the
application will
automatically update the component if the font associated with that ID changes. So, for
example:</P>
<BLOCKQUOTE> <BLOCKQUOTE>
<P>Resource Ids are strings used to identify the color, font, or icon. These strings are <BLOCKQUOTE>
"made up" by the developer and should be chosen in a way that it is as self describing as <CODE>Font font = new Font("Monospaced", Font.BOLD, 12);</CODE>
</BLOCKQUOTE>
<P>becomes</P>
<BLOCKQUOTE>
<CODE>Font font = Gui.getFont("font.xyz");</CODE>
</BLOCKQUOTE>
<P>or</P>
<BLOCKQUOTE>
<CODE>myLabel.setFont(new Font("Dialog", Font.PLAIN, 14)</CODE>
</BLOCKQUOTE>
<P>becomes</P>
<BLOCKQUOTE>
<CODE>Gui.registerFont(myLabel, "font.xyz");</CODE>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H2><A name="Resource_Ids"></A>Resource ID Strings</H2>
<BLOCKQUOTE>
<P>Resource IDs are strings used to identify a color, font, or icon. These strings are
created by the developer and should be chosen in a way that it is as self-describing as
possible. So, for example, if you wanted the text color in some error message in some widget possible. So, for example, if you wanted the text color in some error message in some widget
"abc", you might create the color id "color.fg.abc.error". To make resource ids as consistent "abc", you might create the color ID "color.fg.abc.error". To help keep resource IDs
as possible, we created a convention for ids as follows:&nbsp;</P> consistent, we created a convention for IDs as follows: </P>
<BLOCKQUOTE> <BLOCKQUOTE>
<BLOCKQUOTE> <BLOCKQUOTE>
@ -145,11 +155,10 @@
<LI><B>category:</B> any value, examples include 'bg'(background), 'fg'(foreground), <LI><B>category:</B> any value, examples include 'bg'(background), 'fg'(foreground),
'cursor'. There may be multiple dot-separated values.</LI> 'cursor'. There may be multiple dot-separated values.</LI>
<LI><B>client:</B> the plugin name or feature name; any value usd to represent a more <LI><B>client:</B> the plugin name or feature name.</LI>
specialized use.</LI>
<LI><B>specialized uses:</B> any key value here that applies to the client, such as <LI><B>specialized uses:</B> any key value here that applies to the client, such as
"vertex' for a graph client.</LI> 'vertex' for a graph client.</LI>
</UL> </UL>
<BLOCKQUOTE> <BLOCKQUOTE>
@ -160,6 +169,8 @@
<LI>color.bg.listing</LI> <LI>color.bg.listing</LI>
<LI>color.bg.functiongraph.vertex.group</LI>
<LI>font.listing</LI> <LI>font.listing</LI>
<LI>font.listing.header</LI> <LI>font.listing.header</LI>
@ -176,11 +187,16 @@
<H2>Theme Property Files</H2> <H2>Theme Property Files</H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<P>The default values for resource ids are defined in "theme property" files that created in <P>The default values for resource IDs are defined in files that reside
each module's data directory. For small modules there can be just one theme properties, but a module's data directory (not all modules define this file). These files all
larger modules should probably use multiple files; one for each sub-feature. The application are named to end in <CODE>theme.properties</CODE> and begin with the module's name. Some
will find all theme property files as long as they exist in a module's data directory and end modules make use of multiple files in order to better manage the volume of IDs. In this
with '.theme.properties'.</P> case, the name of each properties file offers a clue as to its contents. Thus, for small
modules, those without many resource IDs in use, one theme properties file is sufficient to
easily define and manage all required IDs. But, we recommend larger modules use multiple
files, one for each sub-feature. The application will find all theme property files as long as
they exist in a module's data directory and are named with the
<CODE>.theme.properties</CODE> suffix.</P>
<H3>Theme Properties File Naming Convention</H3> <H3>Theme Properties File Naming Convention</H3>
@ -191,7 +207,7 @@
<BLOCKQUOTE> <BLOCKQUOTE>
<PRE> <PRE>
<CODE> <CODE>
[module name][.additional name]].theme.properties <I>module name</I>[.additional name]].theme.properties
</CODE> </CODE>
</PRE> </PRE>
</BLOCKQUOTE> </BLOCKQUOTE>
@ -201,17 +217,17 @@
<UL> <UL>
<LI>base.theme.properties</LI> <LI>base.theme.properties</LI>
<LI>base.funtiongraph.theme.properties</LI> <LI>base.listing.theme.properties</LI>
</UL> </UL>
</BLOCKQUOTE> </BLOCKQUOTE>
<H3>Theme Properties File Format</H3> <H3>Theme Properties File Format</H3>
<P>Theme files uses a very simple format for specifying theme property values. Each line <P>Theme files uses a very simple format for specifying theme property values. Each line
specifies a property id (sometimes referfed to as key) and a value, separated by an "=". A specifies a property ID (sometimes referred to as the key) and a value, separated by an
theme properties file consists of two sections: the standard defaults section and a section "=". A theme properties file consists of two sections: the standard defaults section and a
for specifying defaults for "dark" themes. So a file theme file uses the following section for specifying defaults for "dark" themes.
format:</P> </P>
<BLOCKQUOTE> <BLOCKQUOTE>
<CODE> <CODE>
@ -259,13 +275,15 @@ color.fg.listing.bytes = orange
</PRE> </PRE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P>NOTE: The [Dark Defaults] section is for overriding values defined in the standard
[Defaults] section. If a property id is not given a value in the defaults section, it is an <P>NOTE: The <CODE>[Dark Defaults]</CODE> section is for <U>optionally</U> overriding values
error. If a value is not defined in the [Dark Defaults] section, then the value defined in defined in the standard <CODE>[Defaults]</CODE> section. If a property ID is not given a value
the [Defaults] section will be used in a dark theme.</P> in the defaults section, it is an error. If a value is not defined in the
<CODE>[Dark Defaults]</CODE> section, then the value defined in the <CODE>[Defaults]</CODE>
section will be used in a dark theme.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<H2>Theme Property Values<A name="Theme_Property_Values"></A></H2> <H2><A name="Theme_Property_Values"></A>Theme Property Values</H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<P>The values specified in the theme properties files can be specified in a variety of ways, <P>The values specified in the theme properties files can be specified in a variety of ways,
@ -273,15 +291,15 @@ color.fg.listing.bytes = orange
directly in the theme properties file. A font value can specified as a reference to another directly in the theme properties file. A font value can specified as a reference to another
defined font, but with a different size or style.</P> defined font, but with a different size or style.</P>
<P>Also, any value can also be a reference to some other id of the same type. So, for <P>Also, any value can also be a reference to some other ID of the same type. So, for
example, a reference color entry might be something like "color.bg.listing = color.bg". This example, a reference color entry might be something like "color.bg.listing = color.bg". This
says that the listing's background color should be whatever "color.bg" is defined to be. Note says that the listing's background color should be whatever "color.bg" is defined to be. Note
that all of the application's defined properties start with either "color.", "font.", or that all of the application's defined properties start with either "color.", "font.", or
"icon.". Properties defined by a Java LookAndFeel don't follow this pattern. To reference a "icon.". Properties defined by a Java Look and Feel don't follow this pattern. To reference a
property that does not have a standard prefix, an id can be prefixed with "[color]", property that does not have a standard prefix, an ID can be prefixed with "[color]",
"[font]", or "[icon] as appropriate to allow the theme property parser to recognize the "[font]", or "[icon] as appropriate to allow the theme property parser to recognize the
values as ids to other properties. So to refer to a property named "table.background, it values as IDs to other properties. So to refer to a Java property named "table.background",
would be "color.bg.table = [color]table.background".</P> you would use the following definition: "color.bg.table = [color]table.background".</P>
<H3>Color Values</H3> <H3>Color Values</H3>
@ -301,7 +319,8 @@ color.fg.listing.bytes = orange
<LI>rgba(red, green, blue, alpha)</LI> <LI>rgba(red, green, blue, alpha)</LI>
<LI>[web color name] the name of a web color such as red, olive, or purple</LI> <LI><I>web color name</I> // the case-insensitive name of a web color such as red, olive, or
purple</LI>
</UL> </UL>
</BLOCKQUOTE> </BLOCKQUOTE>
@ -324,14 +343,16 @@ color.fg.listing.bytes = orange
<BLOCKQUOTE> <BLOCKQUOTE>
<PRE> <PRE>
<CODE> <CODE>
[family name]-[style]-[size] family name-style-size
</CODE> </CODE>
</PRE> </PRE>
<UL> <UL>
<LI>family name: the font name such as monospaced, dialog, courier.</LI> <LI>family name: the font name such as <CODE>monospaced</CODE>, <CODE>dialog</CODE>,
<CODE>courier</CODE>.</LI>
<LI>style: One of PLAIN, BOLD, ITALIC, or BOLDITALIC.</LI> <LI>style: One of <CODE>PLAIN</CODE>, <CODE>BOLD</CODE>, <CODE>ITALIC</CODE>, or
<CODE>BOLDITALIC</CODE>.</LI>
<LI>size: the font point size. 12 is very common.</LI> <LI>size: the font point size. 12 is very common.</LI>
</UL> </UL>
@ -341,7 +362,7 @@ color.fg.listing.bytes = orange
<PRE> <PRE>
font.foo = monospaced-PLAIN-12 font.foo = monospaced-PLAIN-12
font.foo = courier-BOLD-14 font.foo = courier-BOLD-14
font.foo = SansSerif-ITALIC=10 font.foo = SansSerif-ITALIC-10
</PRE> </PRE>
<H4>Font Modifiers</H4> <H4>Font Modifiers</H4>
@ -352,18 +373,19 @@ color.fg.listing.bytes = orange
<BLOCKQUOTE> <BLOCKQUOTE>
<PRE> <PRE>
<CODE> <CODE>
font.ref[family name][style][size] <I>font.ref</I>[family name][style][size]
</CODE> </CODE>
</PRE> </PRE>
<UL> <UL>
<LI>font.ref - the theme property id of some other font</LI> <LI><I>font.ref</I>: the theme property ID of some other font</LI>
<LI>family name: use the size and style of the reference font, but use this font <LI>family name: use the size and style of the reference font, but use this font
family</LI> family.</LI>
<LI>style: use the same font as the reference font, but with this style. One of PLAIN, <LI>style: use the same font as the reference font, but with this style. One of
BOLD, ITALIC, or BOLDITALIC</LI> <CODE>PLAIN</CODE>, <CODE>BOLD</CODE>, <CODE>ITALIC</CODE>, or
<CODE>BOLDITALIC</CODE>.</LI>
<LI>size: use the same font as the reference font, but with this size.</LI> <LI>size: use the same font as the reference font, but with this size.</LI>
</UL> </UL>
@ -387,22 +409,22 @@ color.fg.listing.bytes = orange
<BLOCKQUOTE> <BLOCKQUOTE>
<PRE> <PRE>
<CODE> <CODE>
iconName[size(width,height)][disabled]{iconOverlayName[size(width,geight)[disabled][move(x,y)]}{...} <I>iconName</I>[size(width,height)][disabled]{iconOverlayName[size(width,height)[disabled][move(x,y)]}{...}
</CODE> </CODE>
</PRE> </PRE>
<UL> <UL>
<LI>iconName - the name the base icon</LI> <LI><I>iconName</I>: the name the base icon</LI>
<LI>size(width,height) - optional modifier to scale the image to the given size.</LI> <LI>size(width,height): optional modifier to scale the image to the given size.</LI>
<LI>disabled - optional modifier to create a disabled version of the icon.</LI> <LI>disabled: optional modifier to create a disabled version of the icon.</LI>
<LI>{...} - optional modifier to overlay an icon on the base icon. It is recursively <LI>{...}: optional modifier to overlay an icon on the base icon. It is recursively
defined using the same format.</LI> defined using the standard icon format.</LI>
<LI>move(x,y) - optional modifier on overlays to position them relative to the base <LI>move(x,y): optional modifier on overlays to position them relative to the base
icon.</LI> icon.</LI>
</UL> </UL>
</BLOCKQUOTE> </BLOCKQUOTE>
@ -417,22 +439,26 @@ color.fg.listing.bytes = orange
// hammer.icon overlayed in its lower right corner // hammer.icon overlayed in its lower right corner
</PRE> </PRE>
<P>To create an icon suitable for dynamically overlaying other icons, there is special syntax <P>To create stand-alone icon suitable for dynamically overlaying other icons, there is
for specifying an empty base icon, then overlay another icon in some specific area of the special syntax for specifying an empty base icon. Use the empty icon along with another
empty icon. This icon can then be used to overlay dynamically in the code. For example, to overlay icon in some specific area of the empty icon to create a final icon that can be used
create an overlay icon that would add a flag to the bottom, right corner any other iconw:</P> as an overlay for other icons. For example, to
create an overlay icon that would add a flag to the bottom-right corner of any other icon:</P>
<PRE> <PRE>
icon.foo = EMPTY_ICON[size(16,16)]{flag.png[size(6,6)][move(10,10)]} icon.overlay.flag = EMPTY_ICON[size(16,16)]{flag.png[size(6,6)][move(10,10)]}
</PRE> </PRE>
<P class="providedbyplugin">Provided by: <I>Theme Manager</I></P>
<P class="relatedtopic">Related Topics</P> <P class="relatedtopic">Related Topics</P>
<UL> <UL>
<LI><A href="ThemingOverview.html">Theming Overview</A></LI> <LI><A href="ThemingOverview.html">Theming Overview</A></LI>
<LI><A href="ThemingUserDocs.html">Theming User Documentation</A></LI> <LI><A href="ThemingUserDocs.html">Theming User's Guide</A></LI>
<LI><A href="ThemingInternals.html">Theming Architecture Documentation</A></LI> <LI><A href="ThemingInternals.html">Theming Architecture</A></LI>
</UL><BR> </UL><BR>
</BLOCKQUOTE> </BLOCKQUOTE>
</BODY> </BODY>

View file

@ -5,90 +5,106 @@
<META name="generator" content= <META name="generator" content=
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net"> "HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
<TITLE>Theming Internals Documentation</TITLE> <TITLE>Theming Architecture</TITLE>
<LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css"> <LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
</HEAD> </HEAD>
<BODY> <BODY>
<H1>Ghidra Theming Internals Documentation</H1> <H1>Theming Architecture</H1>
<P>This document describes the api for initializing and managing themes. A theme (the GTheme <P>This document describes the API for initializing and managing themes. A theme (the
class) in Ghidra represents a specific LookAndFeel as well the set of values for the color, <CODE>GTheme</CODE>
font, and icon resource ids used in the application.&nbsp; The Gui class provides a set of class) in Ghidra represents a specific Look and Feel as well the set of values for the color,
font, and icon resource IDs used in the application. Resource IDs are defined in theme properties
files. Application writers refer to these IDs when using colors, fonts and icons.
The <CODE>Gui</CODE> class provides a set of
static methods that serves as the primary interface for managing all aspects of theming.</P> static methods that serves as the primary interface for managing all aspects of theming.</P>
<H2>GTheme class</H2> <H2>GTheme Class</H2>
<P>The GTheme class is the implementation of the theme concept. At any giving time, the <P>The <CODE>GTheme</CODE> class is the implementation of the theme concept. At any given time,
application is using resource values as specified by an&nbsp; active theme. The theme specifies the application is using resource values as specified by the active theme. The theme specifies
the LookAndFeel, whether or not the overall theme is "dark" (which determines which default the Java Look and Feel, whether or not the overall theme is "dark" (which determines which default
values to use) and any resource values which have been overridden specifically by that theme. values to use) and any resource values which have been overridden specifically by that theme.
There are two types of of themes; "built-in"&nbsp; themes and file based themes. "Built-in" There are two types of of themes; built-in themes and file-based themes. Built-in
themes are implemented directly as sub-classes of GTheme and simply specify a Java LookAndFeel themes are implemented directly as sub-classes of <CODE>GTheme</CODE> and simply specify a
Java Look and Feel
and whether or not the theme is "dark". There is one "built-in" theme for each supported and whether or not the theme is "dark". There is one "built-in" theme for each supported
LookAndFeel. File based themes read their values from a theme file. Theme files are created by Look and Feel. File-based themes read their values from a theme file. Theme files are created by
editing and saving existing themes.</P> editing and saving existing themes.</P>
<H2>GThemeValueMap / ThemeValue class</H2> <H2>GThemeValueMap / ThemeValue Classes</H2>
<P>These are the base classes for storing values for resource ids.&nbsp; A GThemeValueMap <P>These are the base classes for storing values for resource IDs. A <CODE>GThemeValueMap</CODE>
consists of three hashmaps; one each for colors, fonts, and icons. Each hashmap maps an id to a consists of three maps, one each for colors, fonts, and icons. Each map binds an ID to a
appropriate subclass of ThemeValue, which is the base class for ColorValue, FontValue, and appropriate subclass of <CODE>ThemeValue</CODE>, which is the base class for
IconValue. Resource values are stored in these ThemeValue sub-classes because the value can be <CODE>ColorValue</CODE>, <CODE>FontValue</CODE>, and
<CODE>IconValue</CODE>. Resource values are stored in these <CODE>ThemeValue</CODE> sub-classes
because the value can be
either a concrete value or be a reference to some other resource of the same type. So, for either a concrete value or be a reference to some other resource of the same type. So, for
example, "color.bg.foo" could map directly to an actual color or its value could be reference example, "color.bg.foo" could map directly to an actual color or its value could be reference
to some other indirect color like "color.bg.bar". In any ThemeValue object, either the to some other indirect color like "color.bg.bar". In any <CODE>ThemeValue</CODE> object, either
referenceId or the direct value must be null.&nbsp; To get the ultimate concrete value, there the referenced ID or the direct value must be null. To get the ultimate concrete value, there
is a convenience method called "get" on ThemeValues that takes a GThemeValueMap as an argument. is a convenience method called <CODE>get()</CODE> on <CODE>ThemeValue</CODE>s that takes a
This method will recursively resolve referenceIds which is why it needs a value map as an <CODE>GThemeValueMap</CODE> as an argument.
This method will recursively resolve reference IDs, which is why it needs a value map as an
argument.</P> argument.</P>
<P>GThemeValueMaps have some convenience methods for doing set operations.&nbsp; You can load <P><CODE>GThemeValueMap</CODE>s have some convenience methods for performing set operations.
values from other GThemeValueMaps into this map, which adds to the current map, replacing You can load
values with the same id with values from the other map. Also, there is a method for getting the values from other <CODE>GThemeValueMap</CODE>s into this map, which adds to the current map,
differences from one GThemeValueMap to another.&nbsp;</P> replacing values with the same ID with values from the other map. Also, there is a method for
getting the differences from one GThemeValueMap to another.</P>
<H2>Gui class</H2> <H2>Gui Class</H2>
<P>The Gui class is a set of static methods that provides the primary API for managing themes. <P>The <CODE>Gui</CODE> class is a set of static methods that provides the primary API for
managing themes.
It has methods for switching themes, adding themes, deleting themes, saving themes, restoring It has methods for switching themes, adding themes, deleting themes, saving themes, restoring
themes, getting/setting values for resource ids, adding theme listeners, and others.</P> themes, getting/setting values for resource IDs, adding theme listeners, and others. This
class is meant to be used by application developers, along with <CODE>GColor</CODE> for colors
and <CODE>GIcon</CODE> for icons. Fonts are handled slightly differently by making calls to
<CODE>Gui.registerFont(Component, Id)</CODE>
</P>
<H2>Application Initialization</H2> <H2>Application Initialization</H2>
<P>Applications need to call Gui.initialize() before any uses of color, fonts, or icons occur. <P>Applications need to call <CODE>Gui.initialize()</CODE> before any uses of color, fonts, or
This will load all resource defaults from the theme.properties files, read the last used theme icons occur.
from preferences, and load that theme which includes setting the LookAndFeel.</P> This will load all resource defaults from all <CODE>*.theme.properties</CODE> files, read the
last used theme from preferences, and load that theme which includes setting the Look and Feel.
</P>
<H2>Loading a Theme</H2> <H2>Loading a Theme</H2>
<P>Loading a theme consists of two main operations. Loading the LookAndFeel and building the <P>Loading a theme consists of two main operations: loading the Look and Feel and building the
set of values for the resource ids.</P> set of values for all defined resource IDs.</P>
<H2>Loading the LookAndFeel</H2> <H2>Loading the Look and Feel</H2>
<P>Because each LookAndFeel present different challenges to the theming feature, there is a <P>Because each Look and Feel presents different challenges to the theming feature, there is a
LookAndFeelManager for each LookAndFeel. The LookAndFeelManager is responsible for installing <CODE>LookandFeelManager</CODE> for each Look and Feel. The <CODE>LookandFeelManager</CODE> is
the lookAndFeel (in the case of Nimbus, we had to install a special subclass of the responsible for installing
NimbusLookAndFeel),&nbsp; extracting the Java resources mappings(Java LookAndFeel objects also the Look and Feel (in the case of Nimbus, we had to install a special subclass of the
use a resource id concept), group the java resources into common groups,&nbsp; possibly fix up <CODE>NimbusLookandFeel</CODE>), extracting the Java resources mappings (Java Look and Feel
some issues specific to that LookAndFeel, possibly install global properties, and have specific objects also use a resource ID concept), group the Java resources into common groups, possibly
update (kicking) techniques to get that LookAndFeel to update its componentUIs when values fix up some issues specific to that Look and Feel, possibly install global properties, and have
change.</P> specific update techniques to get that Look and Feel to update its component UIs when
values change.</P>
<H2>Creating the Active Theme Values</H2> <H2>Creating the Active Theme Values</H2>
<P>After the LookAndFeel is loaded and the java values extracted, the final resource mapping is <P>After the Look and Feel is loaded and the Java values extracted, the final resource mapping is
created. This is done by loading various resource values sets (each stored in a GThemeValueMap) created. This is done by loading various resource values sets (each stored in a GThemeValueMap)
in the correct order into a new GThemeValueMap in GUI called "currentValues" .&nbsp; When in the correct order into a new <CODE>GThemeValueMap</CODE> in <CODE>ThemeManager</CODE> called
values are loaded into a GThemeValueMap, they will replace any existing values with the same "currentValues" . When values are loaded into a <CODE>GThemeValueMap</CODE>, they will replace
id.&nbsp; The values are loaded in the following order:</P> any existing values with the same ID. The values are loaded in the following order:</P>
<BLOCKQUOTE> <BLOCKQUOTE>
<UL> <UL>
<LI>java defaults (values from LookAndFeel)</LI> <LI>Java defaults (values from Look and Feel)</LI>
<LI>application defaults (from theme.properties files)</LI> <LI>application defaults (from *.theme.properties files)</LI>
<LI>applications dark defaults (if theme is dark)</LI> <LI>applications dark defaults (if theme is dark)</LI>
@ -98,89 +114,114 @@
<H2>Changing Values Associated With Resource Ids</H2> <H2>Changing Values Associated With Resource Ids</H2>
<P>Whenever the value associated with a resource id changes, the application gets "kicked" in <P>Whenever the value associated with a resource ID changes, the application gets notified in
various ways to update the display with the new value. The technique used to "kick" the various ways to update the display with the new value. The technique used to notify the
application differs depending on the resource type and the LookAndFeel (these differences are application differs depending on the resource type and the Look and Feel (these differences are
captured in the LookAndFeelManager sub-classes for each LookAndFeel).&nbsp; It can also vary captured in the <CODE>LookandFeelManager</CODE> sub-classes for each Look and Feel). It can also
depending on whether the value is an application defined resource or a java defined vary depending on whether the value is an application defined resource or a Java defined
resource.</P> resource.</P>
<H3>Updating Colors</H3> <H3>Updating Colors</H3>
<P>Updating Colors is the easiest of all the resource. First GColor.refreshAll() is called, <P>Updating Colors is the easiest of all the resource types. First
which causes every GColor to refresh its delegate. Next, repaint() is called on all the top <CODE>GColor.refreshAll()</CODE> is called,
level java windows in the application. Also, since color values in the UIDefaults are actually which causes every <CODE>GColor</CODE> to refresh its internal delegate <CODE>Color</CODE>.
This is the purpose of using the <CODE>GColor</CODE> class, to introduce a level of indirection
that allows us to change runtime behavior without having to recompile.
Next, <CODE>repaint()</CODE> is called on all the top-level Java windows in the application.
Also, since color values in the <CODE>UIDefaults</CODE> are actually
replaced with GColor objects, this technique works for both application defined resources and replaced with GColor objects, this technique works for both application defined resources and
java defined resources.</P> Java defined resources.</P>
<H3>Updating Fonts</H3>
<P>Updating Fonts is a bit more involved. First, if the changed font is java defined, the
UIDefaults for that font Id (and any that derive from it) are updated. Next, all the components
that have a registeredFontId are updated, and finally the updateComponentTreeUI method is
called on all windows in the application.</P>
<H3>Updating Icons</H3> <H3>Updating Icons</H3>
<P>Updating Icons is a mixed bag. If the Icon is application defined, GIcon.refreshAll() is <P>Updating icons is a mixed bag. If the icon is application defined,
called which causes every GIcon to refresh its delegate and then call repaint on all the <CODE>GIcon.refreshAll()</CODE> is
windows. If the icon is java defined, then the UIDefaults has to be updated and the called which causes every <CODE>GIcon</CODE> to refresh its internal delegate icon and then
updateComponentTreeUI method on all windows is called.</P> call <CODE>repaint()</CODE> on all the
windows. If the icon is Java defined, then the <CODE>UIDefaults</CODE> has to be updated and the
<CODE>updateComponentTreeUI()</CODE> method on all windows is called.</P>
<H3>Updating Fonts</H3>
<P>Updating Fonts is a bit more involved than updating colors and icons, due to the inability
to use the indirection model when working with fonts. First, if the changed font is Java
defined, the <CODE>UIDefaults</CODE> for that font ID (and any that derive from it) are updated.
Next, all the components that have called <CODE>Gui.registeredFont()</CODE> are updated. (The
registration system for fonts is what allows us to notify components of updates, since fonts
cannot use the indirection model.)
Finally, the <CODE>updateComponentTreeUI()</CODE> method is
called on all windows in the application.</P>
<H2>Creating/Editing/Saving Themes</H2> <H2>Creating/Editing/Saving Themes</H2>
<P>New themes can be created and saved to files in the theme directory in the users ghidra <P>New themes can be created and saved to files in the theme directory in the user's
application directory. When the application is started, this directory is scanned and any application directory (<code>&lt;home&gt;/.ghidra/.ghidra-&lt;version&gt/themes</code>).
.theme files are loaded and available to be selected as the active theme. The Gui class has When the application is started, this directory is scanned and any
methods for setting the value of a color, font, or icon for a given resource id. If any values <CODE>*.theme</CODE> files are loaded and available to be selected as the active theme.
The <CODE>Gui</CODE> class has
methods for setting the value of a color, font, or icon for a given resource ID. If any values
are currently different from the active theme, the theme can be saved. If the active theme is a are currently different from the active theme, the theme can be saved. If the active theme is a
built-in theme, then the only choice is to save the theme with a new theme name. Saving the built-in theme, then the only choice is to save using a new theme name. Saving the
theme will create a new xxx.theme file where xxx is the name of the theme. Otherwise, the theme will create a new "xyz.theme" file where "xyz" is the name of the theme. Otherwise, the
existing theme file can be overwritten or a new theme name can be supplied to save to a new existing theme file can be overwritten or a new theme name can be supplied to save to a new
file.</P> file.</P>
<H2>External Icons</H2> <H2>External Icons</H2>
<P>When settings icons for an icon resource id, the user has the option of using a icon that <P>When setting icons for an icon resource ID, the user has the option of using an icon that
exists on the application classpath or using any supported icon file (.png or .gif) If the user exists in the application (on the classpath) or using any supported icon file (.png or .gif) on
chooses to use an icon file, then that icon will be copied into an images directory in their the filesystem. If the user
application directory (.ghidra). These icons are considered external in that if the theme were chooses to use a non-application icon file, then that icon will be copied into an images
given to another user, you would also need to give them the icon files.</P> directory in their application directory. These icons are considered external in that if the
theme were given to another user, you would also need to give them these icon files, as they
will not exist in other application installations.</P>
<H2>Importing/Exporting Themes</H2> <H2>Importing/Exporting Themes</H2>
<P>Themes can be shared with other users by exporting and importing themes. When exporting a <P>Themes can be shared with other users by exporting and importing themes. When exporting a
theme that doesn't use any external icons (icons not on the classpath), the theme can be theme that doesn't use any external icons (icons not on the classpath), the theme can be
exported to a .theme file of the users choosing. If the theme does contain external icons, the exported to a <CODE>.theme</CODE> file of the user's choosing. If the theme does contain
user has the option to save the theme as a .zip file which would contain both the .theme file external icons, the
user has the option to save the theme as a .zip file, which would contain both the .theme file
and all the external icon files.</P> and all the external icon files.</P>
<H2>LookAndFeel Notes</H2> <H2>Look and Feel Notes</H2>
<P>Getting the theming feature to work on all the various Java LookAndFeels is a <P>Getting the theming feature to work on all the various Java Look and Feels is a
challenge.&nbsp; Java created the concept of UiDefaults, which is a mapping of property names challenge. Java created the concept of <CODE>UIDefaults</CODE>, which is a mapping of property
to values. The implication is that users can change default values by setting values on the names
UIDefaults. Unfortunately, not all LookAndFeels support this concept. Nimbus and GTK+, in to values. The implication is that users can change Look and Feel settings by changing values
particular are problematic. Nimbus sort of honors values in UIDefaults, but only if they are in the <CODE>UIDefaults</CODE>. Unfortunately, not all Look and Feels support this concept.
installed before Nimbus is loaded. So for out theming purposes, we had to extend the Nimbus Nimbus and GTK+, in particular are problematic. Nimbus somewhat honors values in
LookAndFeel in order to override the getDefaults() method (this is the method where <CODE>UIDefaults</CODE>, but only if those values are
LookAndFeels populate the UiDefaults) so that we can install any overridden values from the installed before Nimbus is loaded. So for our theming purposes, we had to extend the Nimbus
selected theme. Also, every time a Java defined property changes, we have to re-install the Look and Feel in order to override the <CODE>getDefaults()</CODE> method (this is the method
Nimbus LookAndFeel because once it is installed, it no longer pays attention to changes to the where Look and Feels populate the <CODE>UIDefaults</CODE>) so that we can install any overridden
UIDefaults.&nbsp; The GTK+ LookAndFeel is even more problematic. It gets many of its properties values from the selected theme. Also, since Nimbus does not respect changes to these values after
they have been created, every time a Java defined property changes, we have to re-install the
Nimbus Look and Feel. The GTK+ Look and Feel is even more problematic. It gets many of its
properties
from native libraries and there doesn't appear to be anyway of changing them. Therefore, themes from native libraries and there doesn't appear to be anyway of changing them. Therefore, themes
based on GTK+ doesn't allow for changing java defined values.&nbsp; To compensate for the based on GTK+ doesn't allow for changing Java defined values. To compensate for the
differences among LookAndFeels, we created a LookAndFeelManager base class with sub-classes for differences among Look and Feels, we created a <CODE>LookandFeelManager</CODE> base class with
each LookAndFeel that addresses these differences.</P> sub-classes for each Look and Feel.</P>
<P class="providedbyplugin">Provided by: <I>Theme Manager</I></P>
<P class="relatedtopic">Related Topics</P> <P class="relatedtopic">Related Topics</P>
<UL> <UL>
<LI><A href="ThemingOverview.html">Theming Overview</A></LI> <LI><A href="ThemingOverview.html">Theming Overview</A></LI>
<LI><A href="ThemingUserDocs.html">Theming User Documentation</A></LI> <LI><A href="ThemingUserDocs.html">Theming User's Guide</A></LI>
<LI><A href="ThemingDeveloperDocs.html">Theming Developer Documentation</A></LI> <LI><A href="ThemingDeveloperDocs.html">Theming Developer's Guide</A></LI>
</UL><BR> </UL><BR>
</BODY> </BODY>
</HTML> </HTML>

View file

@ -5,114 +5,133 @@
<META name="generator" content= <META name="generator" content=
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net"> "HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
<TITLE>Theming Overivew</TITLE> <TITLE>General Overivew</TITLE>
<LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css"> <LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
</HEAD> </HEAD>
<BODY> <BODY>
<H1>Ghidra Theming Overview</H1> <H1>Theming Overview</H1>
<P>This document describes Ghidra's support for using and managing UI themes.
</P>
<H2>Goal</H2> <H2>Goal</H2>
<P>The goal was to add a theming infrastructure/feature to Ghidra that would allow <P>The primary goal of theming in Ghidra is to allow users to customize the appearance of the UI
users/developers to completely configure the colors, fonts, and icons used within Ghidra. There and to share that customization with the community. We added infrastructure to Ghidra that
are two main reasons for creating this feature. The first reason is to create the much allows users/developers to completely configure the colors, fonts, and icons used within
requested "Dark Theme". Many people find Ghidra's current color scheme to be hard on the eyes the application. There are two main motivations for creating this feature. The first is to
and would greatly appreciate a color scheme that is not so bright.&nbsp; The second reason is provide the much requested "Dark Theme". Many users find Ghidra's current color scheme to be
for accessibility purposes. For example, the themeing feature would allow for the creating of a hard on the eyes and have requested a dark color scheme. The
high contrast color scheme, or a color scheme that helps mitigate color blindness or a theme second motivation for creating this feature is for accessibility purposes. For example, the
that uses larger fonts.</P> theming feature allows the user to create a theme that uses high contrast colors and larger
&nbsp; fonts.</P>
<H2>Background</H2> <H2>Background</H2>
<P>Ghidra previously used hundreds of hard coded colors, fonts, and icons.&nbsp; They are <P>Before theming, Ghidra used thousands of hard-coded colors, fonts, and icons. They were
defined throughout the code in a somewhat haphazard fashion. Many features use colors to convey defined throughout the code in a somewhat haphazard fashion. Many features use colors to convey
similar concepts, but no effort was even made to use similar colors for those similar concepts. similar concepts, but no effort was made to use similar colors for similar concepts.
Also, these colors were generally chosen to work with one of the common "light" java look and Further, these colors were generally chosen to work with one of the common default Java Look and
feels. They often look terrible when used in conjunction with other LookAndFeels, especially Feels. (A Java Look and Feel is a grouping of UI settings that define the appearance of the
dark ones.</P> application.) Those original colors often looked terrible when used in conjunction with other
Look and Feels, especially dark ones.</P>
<P>Ghidra does allow some customization of the current colors using "options", but this falls <P>Ghidra did allow some customization of the current colors using the Ghidra Options API, but
short for several reasons. One problem is that not all colors or fonts are changeable via the this was inadequate for several reasons. One issue with this approach is that not all colors and
options. Another problem is that the options are tool based and you have to make the same fonts are changeable via the options. Another issue is that the options are tool-based and you
customization for each tool. A third problem is that options are unrelated to the LookAndFeel have to make the same customization for each tool. A third problem is that options are unrelated
option. In other words you can't have different option choices depending on the current to the Look and Feel; you couldn't have different option choices depending on the current Look
LookAndFeel.</P> and Feel.</P>
<P>Also, all of Ghidra's icons are hard coded and many are not suitable to use in a dark theme. <P>As mentioned, all of Ghidra's icons were hard-coded, with many not suitable for use in a dark
Overall, the hard coding of colors, fonts, and icons and the limitation of options makes theme. Overall, the hard-coding of colors, fonts, and icons and the limitation of options made
creating a good dark theme virtually impossible. So to address these issues, a new theming creating a good dark theme virtually impossible. To address these issues, a new theming
infrastructure was created.</P> infrastructure was created.</P>
<H2>General Concepts and Approach</H2> <H2>General Concepts and Approach</H2>
<P>To achieve a theming capability in Ghidra, we had to implement the following concepts. <P>To achieve a theming capability in Ghidra, we had to make the following changes:</P>
First, provide a level of indirection when using colors, fonts, or icons in code. Second, <OL>
introduce the concept of a theme which maps the indirect colors. font, and icons to actual <LI>Replace hard-coded values with a level of indirection for colors, fonts, and icons
values in the context of a java LookAndFeel. Third, provide access to (and the ability to using property names/IDs
change), the colors, fonts, and icons supplied by the Java LookAndFeel. And finally, provide </LI>
the GUIs needed to allow users to switch between, create, edit, save, import, and export <LI>Create the concept of a theme that allows for the the property values to change
themes.</P> as a group and along with the current Look and Feel in use
</LI>
<LI>Create an API that allows for the introduction of system-level properties that can
be mapped to specific Look and Feel values in order to create reusable groups of properties
</LI>
<LI>Provide methods for changing the property values, along with the ability to create,
edit, save, export and import themes
</LI>
</OL>
<BLOCKQUOTE> <BLOCKQUOTE>
<H3>Indirection</H3> <H3>Indirection</H3>
<P>The basic idea for indirection is to never directly use a hard coded color, font, or icon <P>The goal of using indirection is to remove all uses of hard-coded colors, fonts, and icons
when developing a feature in the application. Instead, these properties will be indirectly when developing a feature in the application. Instead, these objects will be indirectly
referred to by an identifying string such as "color.bg.mywidget", where the string will referred to by an identifying string such as "color.bg.mywidget", where the string will
follow a known convention that helps indicate its use. Default values for these identifying follow a known convention that helps indicate its use. Default values for these identifying
strings will be specified in data files that exist in the module where the code that defined strings will be specified in data files that exist in the module where the code that defined
id is located. Also, the values associated with these ids can be either a concrete value such the ID is located. The values associated with these IDs can be either a concrete value such
as an actual color, font, or icon, or the value can be just an identifying string to as an actual color, font, or icon, or the value can be defined using a different property name,
different property. This allows users to change individual values or entire groups of values allowing for properties to be defined by other properties. This allows users to change
with one change.</P> individual values or entire groups of values with one edit.</P>
<H3>Theme</H3> <H3>Theme</H3>
<P>A theme is simply the object that specifies all the values for colors, fonts, and icons <P>A theme is simply the object that specifies all the values for colors, fonts, and icons
used in the application as well as the LookAndFeel. The idea is that there will be a set of used in the application, as well as the Look and Feel. This allows there to be a set of
themes to choose from and by simply switching the theme, the LookAndFeel and all the colors, themes to choose from and by simply switching the theme, the system will then update the Look
fonts, and icons can be switched out at one time. The set of themes to choose from are a mix and Feel along with the colors, fonts, and icons, all with one action. The set of themes to
of built-in themes and saved custom themes. There is one built-in theme for each supported choose from is a mix of built-in themes and saved custom themes. There is one built-in theme
LookAndFeel, which will use the values from the LookAndFeel as well as all the default values for each supported Look and Feel. The chosen theme will use the UI values defied by the Look
for the defined property ids. Users will be able to create custom themes where they can and Feel, as well as all the values for the defined property IDs. Users are able to
basically change any defined color, font, or icon, including those supplied by the associated create custom themes to change any color, font, or icon defined by the application, along with
LookAndFeel for that theme.</P> UI values supplied by the associated Look and Feel.</P>
<H3>Look and Feel Values</H3> <H3>Look and Feel Values</H3>
<P>The Java LookAndFeel is specified by the active theme. The Java LookAndFeel objects also <P>The Java Look and Feel is specified by the active theme. These Look and Feel objects
define colors, fonts, and icons indirectly using identifying strings such as "Button.font" define colors, fonts, and icons indirectly using identifying strings such as "Button.font"
and "Menu.background". These values determine the default values used by all GUI elements and "Menu.background". The Look and Feel mappings determine the default values used by all
unless overridden by developers in code when they create the components. Uses have the GUI elements
ability to change these values in the same way as values defined by Ghidra code. This will unless overridden by developers when they create the components. With theming, users have the
allow users to generate themes that completely change the look of the GUI with out the ability to change these Java Look and Feel defined values in the same way as theme properties
developers having to explicitly set a color, font and icon on every component as they get defined created by application code. Another concept used by Java Look and Feels is that of
created in code.&nbsp; Another concept used by Java LookAndFeels is that many of the shared UI patterns.
individual components share the same colors and those shared colors are defined using a group Look and Feels typically share many of the same colors and those shared colors are defined
key such as "control", "text", or "menu". The idea is that by changing a group color, all by the Look and Feel using a group name/key such as "control", "text", or "menu". This allows
components that share that group color are changed together. Or an individual components for changes to be made at the group level or for the individual property. The theme
color can be changed by changing its specific key such as "Menu.background".</P> framework captures this Java grouping information when creating a theme that for a given
Look and Feel.
</P>
<H3>User Interaction</H3> <H3>User Interaction</H3>
<P>Users will be able create, edit, delete, import, export, and of course switch the <P>Users will be able create, edit, delete, import, export, and of course switch the
application's active theme. The GUI theme editor allows users to do all of these actions. application's active theme. The GUI theme editor allows users to perform all of these actions.
Using the active theme as a starting point, users will be able to change any color, font, or Using the active theme as a starting point, users will be able to change any color, font, or
icon defined either by the LookAndFeel or the application. One or more of these changes can icon defined either by the Look and Feel or the application. One or more of these changes can
be saved as a new theme and stored in a file in their application directory. Themes can be be saved as a new theme and stored in a file in their application directory. Themes can be
shared with other users by exporting and import themes.</P> shared with other users by exporting and importing themes.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<P class="providedbyplugin">Provided by: <I>Theme Manager</I></P>
<P class="relatedtopic">Related Topics</P> <P class="relatedtopic">Related Topics</P>
<UL> <UL>
<LI><A href="ThemingUserDocs.html">Theming User Documentation</A></LI> <LI><A href="ThemingUserDocs.html">Theming User's Guide</A></LI>
<LI><A href="ThemingDeveloperDocs.html">Theming Developer Documentation</A></LI> <LI><A href="ThemingDeveloperDocs.html">Theming Developer's Guide</A></LI>
<LI><A href="ThemingInternals.html">Theming Architecture Documentation</A></LI> <LI><A href="ThemingInternals.html">Theming Architecture</A></LI>
</UL><BR> </UL><BR>
</BODY> </BODY>
</HTML> </HTML>

View file

@ -10,20 +10,21 @@
</HEAD> </HEAD>
<BODY> <BODY>
<H1 align="center">Theming User Help</H1> <H1 align="center">Editing Themes</H1>
<H2>Description</H2> <H2>Description</H2>
<P>The Theming feature allows users to customize the colors, fonts, and icons used throughout <P>The Theming feature allows users to customize the colors, fonts, and icons used throughout
the application. The active theme determines the Java LookAndFeel, whether the theme should use the application. The active theme determines the Java Look and Feel, whether the theme should use
light or dark defaults, and any custom colors, fonts, and icons that override the default light or dark defaults, and any custom colors, fonts, and icons that override the default
values. Users can can easily switch between any of the built-in themes or any saved themes from values. Users can can easily switch between any of the built-in themes or any saved themes found
their home application directory</P> in their home application directory</P>
<P>Users can also edit and create their own themes using the Theme Editor. Custom themes are <P>Users can also edit and create their own themes using the Theme Editor. Custom themes are
stored in the users &lt;application dir&gt;/themes. These are simple text files that can stored in the user's <code>&lt;home&gt;/.ghidra/.ghidra-&lt;version&gt/themes</code> directory.
These theme files are simple text files that can
easily be modified using any text editor. Also, users can share themes by exporting them to a easily be modified using any text editor. Also, users can share themes by exporting them to a
file that can be given to other users who can them import them into their own system.</P> file that can be given to other users who can them import them into their application.</P>
<H2>Theme Dialog<A name="Edit_Theme"></A></H2> <H2>Theme Dialog<A name="Edit_Theme"></A></H2>
@ -32,26 +33,33 @@
<P align="center"><IMG alt="" src="images/ThemeDialog.png"><BR> <P align="center"><IMG alt="" src="images/ThemeDialog.png"><BR>
&nbsp;</P> &nbsp;</P>
<P>The Theme Dialog consists of a theme comboBox and a tabbed set of tables that display the <P>The Theme Dialog consists of a theme drop-down and a tabbed set of tables that display the
values for every color property, font property, and icon property defined by either the Java values for every color property, font property, and icon property defined by either the Java
LookAndFeel or the Ghidra application. All Ghidra defined properties start with "color.", Look and Feel or the application. All application defined properties start with "color.",
"font.", or "icon." depending on whether the the property is a color, font, or icon "font.", or "icon.", depending on whether the the property is a color, font, or icon
respectively. All other properties are defined by the Java LookAndFeel.</P> respectively. All other properties are defined by the Java Look and Feel. This naming
convention is not enforced, thus it is possible that 3rd-party Extensions may introduce
property names that do not match this description. See
the <A href="ThemingDeveloperDocs.html#Resource_Ids">Developer Documentation</A> for more details on the property ID
format and naming conventions.
</P>
<P>Each table entry shows the property id string and then the current value, the theme value, <P>Each table entry shows the property ID string, the current value, the theme value,
and the default color. Most often, the three values are equal. If the theme value is different and the default value. Most often, the three values are equal. If the theme value is different
from the default value, that means that the active theme has overridden the default value for from the default value, that means that the active theme has overridden the default value for
that property. If the current value is different from the theme value, that means the user has that property. If the current value is different from the theme value, that means the user has
changed that value, but not yet saved the changes back to the theme.</P> changed that value, but not yet saved the changes back to the theme.</P>
<P>Individual values can be changed by double clicking the Id or Current Color column. This <P>Individual values can be changed by double-clicking the value in the ID or Current Value
will bring up an appropriate editor for changing the value. When editing a value, the change column. This will bring up an appropriate editor for changing the value. When editing a value,
the change
takes place immediately in the application so you can see the effect. When you leave the takes place immediately in the application so you can see the effect. When you leave the
specific property editor, you have the choice of keeping the change or canceling and having it specific property editor, you have the choice of keeping the change or canceling and having it
revert back to its previous value.</P> revert back to its previous value.</P>
<P>If any values have been changed, the "Save" button will become enabled, allowing you to save <P>If any values have been changed, the <B>Save</B> button will become enabled, allowing you to save
any changes you have made. (Hitting "Dismiss" will also give the the option to save.) If the any changes you have made. (Pressing the <B>Dismiss</B> button will also give the the option to
save.) When saving, if the
current theme is a built-in theme, you will first have to supply a new theme name. If the current theme is a built-in theme, you will first have to supply a new theme name. If the
current theme is a not a built-in theme, you will have the option to overwrite the existing current theme is a not a built-in theme, you will have the option to overwrite the existing
theme or supplying a new name to save it as a new theme.</P> theme or supplying a new name to save it as a new theme.</P>
@ -65,8 +73,8 @@
&nbsp;</P> &nbsp;</P>
<P>Any change you make in the editor is applied to the application immediately. If you press <P>Any change you make in the editor is applied to the application immediately. If you press
the OK button, the change will stay. If you press the Cancel button, the color will revert the <B>OK</B> button, the change will stay. If you press the <B>Cancel</B> button, the color
back to the original color.</P> will revert back to the original color.</P>
<H3>Font Editor</H3> <H3>Font Editor</H3>
@ -76,8 +84,8 @@
&nbsp;</P> &nbsp;</P>
<P>Any change you make in the editor is applied to the application immediately. If you press <P>Any change you make in the editor is applied to the application immediately. If you press
the OK button, the change will stay. If you press the Cancel button, the font will revert the <B>OK</B> button, the change will stay. If you press the <B>Cancel</B> button, the font
back to the original font.</P> will revert back to the original font.</P>
<H3>Icon Editor</H3> <H3>Icon Editor</H3>
@ -86,12 +94,12 @@
<P align="center"><IMG alt="" src="images/IconEditor.png"><BR> <P align="center"><IMG alt="" src="images/IconEditor.png"><BR>
&nbsp;</P> &nbsp;</P>
<P>The Edit Icon dialog has a drop down text field where you can find any existing icon on <P>The Edit Icon dialog has a drop-down text field where you can find any existing icon on
the classpath. If you want to choose an Icon from the file system, press the "..." button and the classpath. If you want to choose an Icon from the file system, press the <B>...</B> button
a FileChooser will appear, allowing you to pick an icon file from anywhere in the filesystem. and a File Chooser will appear, allowing you to pick an icon file from anywhere on the filesystem.
Any change you make in the editor is applied to the application immediately. If you press the Any change you make in the editor is applied to the application immediately. If you press the
OK button, the change will stay. If you press the Cancel button, the icon will revert back to <B>OK</B> button, the change will stay. If you press the <B>Cancel</B> button, the icon will
the original icon.</P> revert back to the original icon.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<H2>Theme Actions</H2> <H2>Theme Actions</H2>
@ -100,30 +108,32 @@
<H3>Switching Themes</H3> <H3>Switching Themes</H3>
<P>To change the current theme, first bring up the <A href="#Edit_Theme">Theme Dialog</A>. <P>To change the current theme, first bring up the <A href="#Edit_Theme">Theme Dialog</A>.
The Theme Dialog can be invoked from the Ghidra Project Window menu using the The Theme Dialog can be invoked from the main application menu using the
<B>Edit</B><IMG alt="" src="images/arrow.gif" border="0"><B>Theme</B> menu. Then select <B>Edit</B><IMG alt="" src="images/arrow.gif" border="0"><B>Theme</B> menu. From the Theme
a theme from the combo box at the top of the Theme Editor dialog.</P> Dialog you can select a theme from the combo box at the top.</P>
<H3>Modifying Theme Values</H3> <H3>Modifying Theme Values</H3>
<P>All the colors, fonts, and icons that have been externalized can be modified using the <A <P>All the colors, fonts, and icons that have been registered with the theme API can be
href="#Edit_Theme">Theme Dialog</A>. The Theme Dialog can be invoked from the modified using the <A href="#Edit_Theme">Theme Dialog</A>. The Theme Dialog can be invoked
Ghidra Project Window using the from the main application menu using the
<B>Edit</B><IMG alt="" src="images/arrow.gif" border="0"><B>Theme</B> menu. Choose the <B>Edit</B><IMG alt="" src="images/arrow.gif" border="0"><B>Theme</B> menu. Choose the
tab for the appropriate type and double-click on the id column or current value column of the tab for the appropriate type and double-click on the ID column or Current Value column of the
item you want to change. An editor for that type will appear.</P> item you want to change. An editor for that type will appear.</P>
<H3>Reseting Theme Values</H3> <H3>Reseting Theme Values</H3>
<P>To reset an individual value back to its original theme value, invoke the <A href= <P>To reset an individual value back to its original theme value, from the
main application menu invoke the <A href=
"#Edit_Theme">Theme Dialog</A> using the <B>Edit</B> <IMG alt="" src="images/arrow.gif" "#Edit_Theme">Theme Dialog</A> using the <B>Edit</B> <IMG alt="" src="images/arrow.gif"
border="0"><B>Theme</B> menu. Switch to the appropriate tab for either colors, fonts, or border="0"><B>Theme</B> menu. Choose the
icons. Right-click on the row of the value you want to reset and choose the <B>Restore tab for the appropriate type and right-click on the row of the value you want to reset, then
Value</B> menu item.</P> choose the <B>Restore Value</B> menu item.</P>
<H3>Reseting All Theme Values<A name="Reset_Theme_Values"></A></H3> <H3>Reseting All Theme Values<A name="Reset_Theme_Values"></A></H3>
<P>To reset all values back to the original values established by the current theme, invoked <P>To reset all values back to the original values established by the current theme, from the
main application menu invoke
the <B>Edit</B><IMG alt="" src="images/arrow.gif" border="0"><B>Theme Actions</B> <IMG the <B>Edit</B><IMG alt="" src="images/arrow.gif" border="0"><B>Theme Actions</B> <IMG
alt="" src="images/arrow.gif" border="0"><B>Reset Theme Values</B> menu.</P> alt="" src="images/arrow.gif" border="0"><B>Reset Theme Values</B> menu.</P>
@ -132,12 +142,13 @@
<P>After making changes to one or more theme values, the <A href="#Edit_Theme">Theme <P>After making changes to one or more theme values, the <A href="#Edit_Theme">Theme
Dialog's</A> <B>Save</B> button will be enabled. Pressing the <B>Save</B> button will give Dialog's</A> <B>Save</B> button will be enabled. Pressing the <B>Save</B> button will give
the user the option of creating a new theme or overwriting the current them (if the current the user the option of creating a new theme or overwriting the current them (if the current
theme is not a built-in theme). Also, users will have the options of saving a theme if they theme is not a built-in theme). Also, users will have the option of saving a theme if they
dismiss the Theme Dialog while there are changes to one or more theme values.</P> dismiss the Theme Dialog while there are changes to one or more theme values.</P>
<H3>Deleting Themes<A name="Delete_Theme"></A></H3> <H3>Deleting Themes<A name="Delete_Theme"></A></H3>
<P>To delete a custom saved theme, invoked the <B>Edit</B><IMG alt="" src= <P>To delete a custom saved theme, from the main application menu invoke the
<B>Edit</B><IMG alt="" src=
"images/arrow.gif" border="0"><B>Theme Actions</B> <IMG alt="" src= "images/arrow.gif" border="0"><B>Theme Actions</B> <IMG alt="" src=
"images/arrow.gif" border="0"><B>Delete Theme...</B> menu. This will bring up a dialog "images/arrow.gif" border="0"><B>Delete Theme...</B> menu. This will bring up a dialog
with a list of themes that can be deleted. Select the theme to delete and press the <B>Ok</B> with a list of themes that can be deleted. Select the theme to delete and press the <B>Ok</B>
@ -145,16 +156,18 @@
<H3>Exporting Themes&gt;<A name="Export_Theme"></A></H3> <H3>Exporting Themes&gt;<A name="Export_Theme"></A></H3>
<P>To export a theme so that it can be shared with others, invoke the <B>Edit</B> <IMG alt="" <P>To export a theme so that it can be shared with others, from the
main application menu invoke the <B>Edit</B> <IMG alt=""
src="images/arrow.gif" border="0"><B>Theme Actions</B> <IMG alt="" src= src="images/arrow.gif" border="0"><B>Theme Actions</B> <IMG alt="" src=
"images/arrow.gif" border="0"><B>Export Theme...</B> menu. You will first be asked if "images/arrow.gif" border="0"><B>Export Theme...</B> menu. You will first be asked if
you want to export as a regular theme file or as a Zip file. The Zip file option is useful if you want to export as a regular theme file or as a Zip file. The Zip file option is useful if
the current theme has icon values that are not included with standard Ghidra. In that case, the current theme has icon values that are not included with standard application. In that case,
the Zip file will include those non standard icon files.</P> the Zip file will include those non-standard icon files.</P>
<H3>Importing Themes<A name="Import_Theme"></A></H3> <H3>Importing Themes<A name="Import_Theme"></A></H3>
<P>To import a theme, invoke the <B>Edit</B> <IMG alt="" src="images/arrow.gif" border= <P>To import a theme, from the main application menu
invoke the <B>Edit</B> <IMG alt="" src="images/arrow.gif" border=
"0"><B>Theme Actions</B> <IMG alt="" src="images/arrow.gif" border="0"><B>Import "0"><B>Theme Actions</B> <IMG alt="" src="images/arrow.gif" border="0"><B>Import
Theme...</B> menu. A file chooser dialog will appear allowing the user to choose a theme file Theme...</B> menu. A file chooser dialog will appear allowing the user to choose a theme file
to import. The selected file can be either a standard theme file or a Zip file containing the to import. The selected file can be either a standard theme file or a Zip file containing the
@ -162,7 +175,7 @@
<H3>Reloading Default Values</H3> <H3>Reloading Default Values</H3>
<P>XThis action causes Ghidra to reload all theme default values. It is really only useful <P>This action causes Ghidra to reload all theme default values. It is really only useful
for developers who are actively making changes to theme.properties files. To activate this for developers who are actively making changes to theme.properties files. To activate this
action, press the refresh button <IMG alt="" src="images/reload3.png" border="0"> in the top action, press the refresh button <IMG alt="" src="images/reload3.png" border="0"> in the top
right corner of the <A href="#Edit_Theme">Theme Dialog</A>.</P> right corner of the <A href="#Edit_Theme">Theme Dialog</A>.</P>
@ -170,23 +183,24 @@
<H2>Theme Property Names</H2> <H2>Theme Property Names</H2>
<P>Theme Property Names (also referred to as ids or keys) that are defined by Ghidra use a <P>Theme Property Names (also referred to as IDs or keys) that are defined by the application
common format to help make sorting and viewing properties more intuitive as to their use. See use a common format to help make sorting and viewing properties more intuitive as to their use. See
the <A href="ThemingDeveloperDocs.html#Resource_Ids">Developer Documentation</A> for more details on the property id the <A href="ThemingDeveloperDocs.html#Resource_Ids">Developer Documentation</A> for more details on the property ID
format and naming conventions.</P> format and naming conventions.</P>
<H2>Theme Files</H2> <H2>Theme Files</H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<P>Theme Files are used to store saved custom themes. They are simple text files and are <P>Theme Files are used to store saved custom themes. They are simple text files and are
stored in the user's home application directory. The first three properties are always the stored in the user's home application directory under
theme name, the look and feel name, and whether the theme uses standard defaults or dark <code>&lt;home&gt;/.ghidra/.ghidra-&lt;version&gt/themes</code>. The first three properties are always the
defaults. Then there is just a list of overridden property "name = value" lines.So the format theme name, the Look and Feel name, and whether the theme uses standard defaults or dark
defaults. Finally, there is a list of overridden property "name = value" lines. The format
is:</P> is:</P>
<CODE> <CODE>
<PRE> <PRE>
name = [theme name] name = [theme name]
lookAndFeel = [lookAndFeel name] Look and Feel = [Look and Feel name]
useDarkDefaults = [true or false] useDarkDefaults = [true or false]
[theme id 1]= [color, icon, or font value] [theme id 1]= [color, icon, or font value]
@ -201,7 +215,7 @@
<P>Example:</P> <P>Example:</P>
<PRE> <PRE>
name = BigFontTheme name = BigFontTheme
lookAndFeel = Nimbus Look and Feel = Nimbus
useDarkDefaults = false useDarkDefaults = false
color.bg = Black color.bg = Black
@ -216,8 +230,8 @@
<P>Each property line is expected to begin with either "color.", "font.", or "icon." Since <P>Each property line is expected to begin with either "color.", "font.", or "icon." Since
java defined properties don't start with these prefixes, they will have "[color]", "[font]", java defined properties don't start with these prefixes, they will have "[color]", "[font]",
or "[icon]" prepended to their property name. These are just there for the purposes of or "[icon]" prepended to their property name. These brackets are only used to aid in
parsing this file. When the properties are used in Ghidra, those bracketed prefixes are parsing this file. When the properties are used in Ghidra, the bracketed prefixes are
removed.</P> removed.</P>
<P>Also, note that the values of these properties can reference other property names. If the <P>Also, note that the values of these properties can reference other property names. If the
@ -225,16 +239,21 @@
bracketed prefix if the property name doesn't start with "color.", "font.", or "icon."</P> bracketed prefix if the property name doesn't start with "color.", "font.", or "icon."</P>
<H3>Specifying Theme Property Values</H3> <H3>Specifying Theme Property Values</H3>
<P>Specifying property values varies depending on whether it is a color, font, or icon. Fonts <P>Specifying property values varies depending on whether it is a color, font, or icon. Fonts
and icons also support specifying modifiers. For a complete description of how to specify and icons also support specifying modifiers. For a complete description of how to specify
these values, see the <A href="ThemingDeveloperDocs.html#Theme_Property_Values">Developer Documentation</A>. these values, see the <A href="ThemingDeveloperDocs.html#Theme_Property_Values">Developer Documentation</A>.
</BLOCKQUOTE> </BLOCKQUOTE>
<P class="providedbyplugin">Provided by: <I>Theme Manager</I></P>
<P class="relatedtopic">Related Topics</P> <P class="relatedtopic">Related Topics</P>
<UL> <UL>
<LI><A href="ThemingOverview.html">Theming Overview</A></LI> <LI><A href="ThemingOverview.html">Theming Overview</A></LI>
<LI><A href="ThemingDeveloperDocs.html">Theming Developer Documentation</A></LI> <LI><A href="ThemingDeveloperDocs.html">Theming Developer's Guide</A></LI>
<LI><A href="ThemingInternals.html">Theming Architecture Documentation</A></LI> <LI><A href="ThemingInternals.html">Theming Architecture</A></LI>
</UL><BR> </UL><BR>
</BODY> </BODY>
</HTML> </HTML>

View file

@ -127,6 +127,16 @@ public class MultiIconBuilder {
return addIcon(icon, w, h, QUADRANT.LL); return addIcon(icon, w, h, QUADRANT.LL);
} }
// TODO
public MultiIconBuilder addCenteredIcon(Icon icon) {
int x = (multiIcon.getIconWidth() - icon.getIconWidth()) / 2;
int y = (multiIcon.getIconHeight() - icon.getIconHeight()) / 2;
TranslateIcon txIcon = new TranslateIcon(icon, x, y);
multiIcon.addIcon(txIcon);
return this;
}
/** /**
* Add text overlaid on the base icon, aligned to the specified quadrant. * Add text overlaid on the base icon, aligned to the specified quadrant.
* *

View file

@ -16,8 +16,7 @@
package help; package help;
import java.awt.Component; import java.awt.Component;
import java.awt.event.KeyAdapter; import java.awt.event.*;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
@ -30,8 +29,7 @@ import javax.help.event.HelpModelEvent;
import javax.help.plaf.HelpNavigatorUI; import javax.help.plaf.HelpNavigatorUI;
import javax.help.plaf.basic.BasicFavoritesCellRenderer; import javax.help.plaf.basic.BasicFavoritesCellRenderer;
import javax.help.plaf.basic.BasicFavoritesNavigatorUI; import javax.help.plaf.basic.BasicFavoritesNavigatorUI;
import javax.swing.JComponent; import javax.swing.*;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultMutableTreeNode;
import ghidra.util.Msg; import ghidra.util.Msg;
@ -70,6 +68,28 @@ public class CustomFavoritesView extends FavoritesView {
public void setUI(HelpNavigatorUI ui) { public void setUI(HelpNavigatorUI ui) {
super.setUI(new CustomFavoritesNavigatorUI(this)); super.setUI(new CustomFavoritesNavigatorUI(this));
} }
private Action superGetAddAction() {
return super.getAddAction();
}
@Override
public Action getAddAction() {
//
// Switching themes triggers a UI update. Internally, the Java Help API is not
// correctly updating listeners, which results in that API having a reference to an old
// UI. Using our own custom action to retrieve the currently active action prevents
// this issue, since we are always getting the active target for actionPerformed().
//
return new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
Action currentAction = superGetAddAction();
currentAction.actionPerformed(e);
}
};
}
} }
class CustomFavoritesNavigatorUI extends BasicFavoritesNavigatorUI { class CustomFavoritesNavigatorUI extends BasicFavoritesNavigatorUI {

View file

@ -28,7 +28,8 @@ import generic.theme.GIcon;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.bean.GGlassPane; import ghidra.util.bean.GGlassPane;
import resources.Icons; import resources.Icons;
import resources.ResourceManager; import resources.MultiIconBuilder;
import resources.icons.EmptyIcon;
// NOTE: for JH 2.0, this class has been rewritten to not // NOTE: for JH 2.0, this class has been rewritten to not
// access the 'frame' and 'dialog' variable directly // access the 'frame' and 'dialog' variable directly
@ -240,7 +241,11 @@ public class GHelpBroker extends DefaultHelpBroker {
JToolBar toolbar = (JToolBar) component; JToolBar toolbar = (JToolBar) component;
toolbar.addSeparator(); toolbar.addSeparator();
Icon zoomOutIcon = ResourceManager.getScaledIcon(ZOOM_OUT_ICON, 24, 24); ImageIcon icon = new MultiIconBuilder(new EmptyIcon(24, 24))
.addCenteredIcon(ZOOM_OUT_ICON)
.build();
Icon zoomOutIcon = icon;
JButton zoomOutBtn = new JButton(zoomOutIcon); JButton zoomOutBtn = new JButton(zoomOutIcon);
zoomOutBtn.setToolTipText("Zoom out"); zoomOutBtn.setToolTipText("Zoom out");
zoomOutBtn.addActionListener(e -> { zoomOutBtn.addActionListener(e -> {
@ -252,7 +257,10 @@ public class GHelpBroker extends DefaultHelpBroker {
}); });
toolbar.add(zoomOutBtn); toolbar.add(zoomOutBtn);
Icon zoomInIcon = ResourceManager.getScaledIcon(ZOOM_IN_ICON, 24, 24); icon = new MultiIconBuilder(new EmptyIcon(24, 24))
.addCenteredIcon(ZOOM_IN_ICON)
.build();
Icon zoomInIcon = icon;
JButton zoomInBtn = new JButton(zoomInIcon); JButton zoomInBtn = new JButton(zoomInIcon);
zoomInBtn.setToolTipText("Zoom in"); zoomInBtn.setToolTipText("Zoom in");
zoomInBtn.addActionListener(e -> { zoomInBtn.addActionListener(e -> {

View file

@ -53,7 +53,8 @@ import utilities.util.FileUtilities;
*/ */
public class GHelpHTMLEditorKit extends HTMLEditorKit { public class GHelpHTMLEditorKit extends HTMLEditorKit {
private static final String G_HELP_STYLE_SHEET = "help/shared/Frontpage.css"; private static final String G_HELP_STYLE_SHEET = "Frontpage.css";
private static final String DARK_G_HELP_STYLE_SHEET = "DarkStyle.css";
private static final Pattern EXTERNAL_URL_PATTERN = Pattern.compile("https?://.*"); private static final Pattern EXTERNAL_URL_PATTERN = Pattern.compile("https?://.*");
@ -320,12 +321,21 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
} }
private URL getGStyleSheetURL() { private URL getGStyleSheetURL() {
URL GStyleSheetURL = ResourceManager.getResource(G_HELP_STYLE_SHEET);
if (GStyleSheetURL != null) { if (Gui.isDarkTheme()) {
return GStyleSheetURL; return findStyleSheet(DARK_G_HELP_STYLE_SHEET);
} }
return findModuleFile("help/shared/FrontPage.css"); return findStyleSheet(G_HELP_STYLE_SHEET);
}
private URL findStyleSheet(String name) {
URL url = ResourceManager.getResource("help/shared/" + name);
if (url != null) {
return url;
}
return findModuleFile("help/shared/" + name);
} }
private URL findApplicationfile(String relativePath) { private URL findApplicationfile(String relativePath) {

View file

@ -31,7 +31,7 @@ import ghidra.util.HelpLocation;
status = PluginStatus.RELEASED, status = PluginStatus.RELEASED,
packageName = UtilityPluginPackage.NAME, packageName = UtilityPluginPackage.NAME,
category = PluginCategoryNames.SUPPORT, category = PluginCategoryNames.SUPPORT,
shortDescription = "Manages themes for the Ghdira GUI", shortDescription = "Manages themes for the Ghidra GUI",
description = "Adds actions and options to manage Themes within Ghidra. " + description = "Adds actions and options to manage Themes within Ghidra. " +
"This plugin is available only in the Ghidra Project Window." "This plugin is available only in the Ghidra Project Window."
) )