mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GP-3000 - Theme Cleanup
This commit is contained in:
parent
f022b9a4d5
commit
1fa08a6002
38 changed files with 324 additions and 177 deletions
|
@ -26,6 +26,7 @@ import java.util.Map;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
|
@ -35,6 +36,7 @@ import javax.swing.text.html.HTML.Tag;
|
|||
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.theme.*;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.preferences.Preferences;
|
||||
import ghidra.util.Msg;
|
||||
|
@ -43,11 +45,11 @@ import utilities.util.FileUtilities;
|
|||
|
||||
/**
|
||||
* A class that allows Ghidra to intercept JavaHelp navigation events in order to resolve them
|
||||
* to Ghidra's help system. Without this class, contribution plugins have no way of
|
||||
* to Ghidra's help system. Without this class, contribution plugins have no way of
|
||||
* referencing help documents within Ghidra's default help location.
|
||||
* <p>
|
||||
* This class is currently installed by the {@link GHelpSet}.
|
||||
*
|
||||
*
|
||||
* @see GHelpSet
|
||||
*/
|
||||
public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
||||
|
@ -73,8 +75,7 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
|||
colorsById.put("h3", new GColor("color.fg.help.selector.h3"));
|
||||
colorsById.put("p.providedbyplugin",
|
||||
new GColor("color.fg.help.selector.p.provided.by.plugin"));
|
||||
colorsById.put("p.relatedtopic",
|
||||
new GColor("color.fg.help.selector.p.related.topic"));
|
||||
colorsById.put("p.relatedtopic", new GColor("color.fg.help.selector.p.related.topic"));
|
||||
colorsById.put("th", new GColor("color.fg.help.selector.th"));
|
||||
colorsById.put("code", new GColor("color.fg.help.selector.code"));
|
||||
colorsById.put("code.path", new GColor("color.fg.help.selector.code.path"));
|
||||
|
@ -176,9 +177,9 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Tests the URL of the given event. If the URL is invalid, a new event may be created if
|
||||
* a new, valid URL can be created. Creates a new event with a patched URL if
|
||||
* a new, valid URL can be created. Creates a new event with a patched URL if
|
||||
* the given event's URL is invalid.
|
||||
*/
|
||||
private HyperlinkEvent validateURL(HyperlinkEvent event) {
|
||||
|
@ -235,10 +236,10 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
|||
}
|
||||
|
||||
//
|
||||
// The item was not found by the ResourceManager (i.e., it is not in a 'resources'
|
||||
// The item was not found by the ResourceManager (i.e., it is not in a 'resources'
|
||||
// directory). See if it may be a relative link to a build's installation root (like
|
||||
// a file in <install dir>/docs).
|
||||
//
|
||||
//
|
||||
newUrl = findApplicationfile(HREF);
|
||||
return newUrl;
|
||||
}
|
||||
|
@ -254,7 +255,7 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
|||
}
|
||||
|
||||
try {
|
||||
// put the anchor back into the URL
|
||||
// put the anchor back into the URL
|
||||
return new URL(anchorlessURL, anchor);
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
|
@ -438,7 +439,7 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
|||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
private class GHelpHTMLFactory extends HTMLFactory {
|
||||
@Override
|
||||
|
@ -465,31 +466,36 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overridden to allow us to find images that are defined as constants in places like
|
||||
* Overridden to allow us to find images that are defined as constants in places like
|
||||
* {@link Icons}
|
||||
*/
|
||||
private class GHelpImageView extends ImageView {
|
||||
|
||||
private static final String HELP_SHARED_ARROW = "help/shared/arrow.gif";
|
||||
private static final Icon SHARED_ARROW_ICON = new HelpRightArrowIcon(Colors.FOREGROUND);
|
||||
private static final IconProvider SHARED_ARROW_ICON_PROVIDER =
|
||||
new IconProvider(SHARED_ARROW_ICON, null);
|
||||
|
||||
/*
|
||||
* Unusual Code Alert!
|
||||
* This class exists to enable our help system to find custom icons defined in source
|
||||
* code. The default behavior herein is to supply a URL to the base class to load. This
|
||||
* works fine.
|
||||
*
|
||||
* works fine.
|
||||
*
|
||||
* There is another use case where we wish to have the base class load an image of our
|
||||
* choosing. Why? Well, we modify, in memory, some icons we use. We do this for things
|
||||
* like overlays and rotations.
|
||||
*
|
||||
*
|
||||
* In order to have our base class use the image that we want (and not the one
|
||||
* it loads via a URL), we have to play a small game. We have to allow the base class
|
||||
* to load the image it wants, which is done asynchronously. If we install our custom
|
||||
* image during that process, the loading will throw away the image and not render
|
||||
* anything.
|
||||
*
|
||||
* To get the base class to use our image, we override getImage(). However, we should
|
||||
* anything.
|
||||
*
|
||||
* To get the base class to use our image, we override getImage(). However, we should
|
||||
* only return our image when the base class is finished loading. (See the base class'
|
||||
* paint() method for why we need to do this.)
|
||||
*
|
||||
*
|
||||
* Note: if we start seeing unusual behavior, like images not rendering, or any size
|
||||
* issues, then we can revert this code.
|
||||
*/
|
||||
|
@ -541,12 +547,22 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
|||
return null;
|
||||
}
|
||||
|
||||
String srcString = src.toString();
|
||||
//
|
||||
// This code is looking for the specific referenced image file and then replacing that
|
||||
// image file with something that can update its content at runtime, based on theme.
|
||||
// Alternatively, we could have updated all help files to point to a GIcon, which
|
||||
// handles updating itself when the theme changes. We chose to replace the icon here
|
||||
// instead of in the source code to prevent changing many files.
|
||||
//
|
||||
String srcString = src.toString().trim();
|
||||
if (srcString.equals(HELP_SHARED_ARROW)) {
|
||||
return installImageFromCustomIcon(SHARED_ARROW_ICON_PROVIDER);
|
||||
}
|
||||
|
||||
// check if the srcString is a defined theme icon id
|
||||
if (Gui.hasIcon(srcString)) {
|
||||
//
|
||||
// Wrap the GIcon inside of an IconProvider, as that class can handle a null URL
|
||||
//
|
||||
// Wrap the GIcon inside of an IconProvider, as that class can handle a null URL
|
||||
// returned from GIcon. (This can happen if the GIcon is based on a modified icon.)
|
||||
//
|
||||
GIcon gIcon = new GIcon(srcString);
|
||||
|
@ -562,6 +578,19 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
|||
return url;
|
||||
}
|
||||
|
||||
private URL installImageFromCustomIcon(IconProvider iconProvider) {
|
||||
|
||||
if (iconProvider == null || iconProvider.isInvalid()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.image = iconProvider.getImage();
|
||||
|
||||
// note: this icon is not used to load the image; the 'image' we set is used instead
|
||||
URL url = iconProvider.getOrCreateUrl();
|
||||
return url;
|
||||
}
|
||||
|
||||
private URL installImageFromJavaCode(String srcString) {
|
||||
|
||||
IconProvider iconProvider = getIconFromJavaCode(srcString);
|
||||
|
@ -590,7 +619,7 @@ public class GHelpHTMLEditorKit extends HTMLEditorKit {
|
|||
// check below
|
||||
}
|
||||
|
||||
// Try the ResourceManager. This will work for images that start with GHelp
|
||||
// Try the ResourceManager. This will work for images that start with GHelp
|
||||
// relative link syntax such as 'help/', 'help/topics/' and 'images/'
|
||||
URL resource = ResourceManager.getResource(srcString);
|
||||
return resource;
|
||||
|
|
154
Ghidra/Framework/Help/src/main/java/help/HelpRightArrowIcon.java
Normal file
154
Ghidra/Framework/Help/src/main/java/help/HelpRightArrowIcon.java
Normal file
|
@ -0,0 +1,154 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package help;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.*;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
/**
|
||||
* A basic arrow that points to the right, with padding on the sides and above.
|
||||
*/
|
||||
public class HelpRightArrowIcon implements Icon {
|
||||
|
||||
private static final int ICON_SIZE = 20;
|
||||
|
||||
private Color color;
|
||||
private Shape shape;
|
||||
|
||||
public HelpRightArrowIcon(Color color) {
|
||||
this.color = color;
|
||||
this.shape = buildShape();
|
||||
}
|
||||
|
||||
private Shape buildShape() {
|
||||
|
||||
GeneralPath barPath = new GeneralPath();
|
||||
|
||||
//
|
||||
// Construct the arrow in 2 parts: the line and the angle bracket. The arrow will not fill
|
||||
// the full area. This allows space before and after the arrow. This space serves as
|
||||
// padding between text inside of html content. The arrow is also closer to the bottom,
|
||||
// to aligned vertically with text.
|
||||
//
|
||||
double height = 10;
|
||||
double width = 12;
|
||||
double thickness = 2;
|
||||
double arrowthickness = 3;
|
||||
|
||||
double top = ICON_SIZE - height;
|
||||
double cy = top + (height / 2);
|
||||
double p1x = (ICON_SIZE - width) / 2;
|
||||
double p1y = cy - (thickness / 2);
|
||||
barPath.moveTo(p1x, p1y);
|
||||
|
||||
double barlength = width - 2;
|
||||
double p2x = p1x + barlength;
|
||||
double p2y = p1y;
|
||||
barPath.lineTo(p2x, p2y);
|
||||
|
||||
double p3x = p2x;
|
||||
double p3y = p2y + thickness;
|
||||
barPath.lineTo(p3x, p3y);
|
||||
|
||||
double p4x = p1x;
|
||||
double p4y = p3y;
|
||||
barPath.lineTo(p4x, p4y);
|
||||
|
||||
// back to start of arrow line
|
||||
barPath.lineTo(p1x, p1y);
|
||||
barPath.closePath();
|
||||
|
||||
GeneralPath arrowPath = new GeneralPath();
|
||||
|
||||
// trailing arrow bar center
|
||||
p1x = p1x + barlength + arrowthickness;
|
||||
p1y = cy;
|
||||
arrowPath.moveTo(p1x, p1y);
|
||||
|
||||
// trailing upper arrow bar point
|
||||
double trianglewidth = 5;
|
||||
p2x = p1x - trianglewidth;
|
||||
p2y = top + 1;
|
||||
arrowPath.lineTo(p2x, p2y);
|
||||
|
||||
// leading upper arrow bar point
|
||||
p3x = p2x - arrowthickness;
|
||||
p3y = p2y;
|
||||
arrowPath.lineTo(p3x, p3y);
|
||||
|
||||
// leading arrow bar center
|
||||
p4x = p1x - arrowthickness;
|
||||
p4y = cy;
|
||||
arrowPath.lineTo(p4x, p4y);
|
||||
|
||||
// leading lower arrow bar point
|
||||
double p5x = p3x;
|
||||
double p5y = ICON_SIZE - 1;
|
||||
arrowPath.lineTo(p5x, p5y);
|
||||
|
||||
// trailing lower arrow bar point
|
||||
double p6x = p2x;
|
||||
double p6y = p5y;
|
||||
arrowPath.lineTo(p6x, p6y);
|
||||
|
||||
// back to start
|
||||
double p7x = p1x;
|
||||
double p7y = p1y;
|
||||
arrowPath.lineTo(p7x, p7y);
|
||||
arrowPath.closePath();
|
||||
|
||||
AffineTransform identity = new AffineTransform();
|
||||
Shape barShape = barPath.createTransformedShape(identity);
|
||||
Area barArea = new Area(barShape);
|
||||
|
||||
Shape arrowShape = arrowPath.createTransformedShape(identity);
|
||||
Area arrowArea = new Area(arrowShape);
|
||||
|
||||
Area fullArea = new Area();
|
||||
fullArea.add(barArea);
|
||||
fullArea.add(arrowArea);
|
||||
|
||||
return fullArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
try {
|
||||
g2d.translate(x, y);
|
||||
g2d.setColor(color);
|
||||
g2d.fill(shape);
|
||||
}
|
||||
finally {
|
||||
g2d.translate(-x, -y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return ICON_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return ICON_SIZE;
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 69 B |
Loading…
Add table
Add a link
Reference in a new issue