GP-3089 - Theme Fixes

This commit is contained in:
dragonmacher 2023-02-17 11:19:02 -05:00
parent 1e8d324166
commit 7adfd1e8fb
12 changed files with 84 additions and 116 deletions

View file

@ -140,12 +140,6 @@ color.bg.plugin.overview.entropy.uninitialized = blue
color.bg.plugin.overview.entropy.palette.base.low = black color.bg.plugin.overview.entropy.palette.base.low = black
color.bg.plugin.overview.entropy.palette.base.high = white color.bg.plugin.overview.entropy.palette.base.high = white
color.bg.plugin.programdiff.highlight = moccasin
color.bg.plugin.programdiff.details.address = #009999
color.bg.plugin.programdiff.details.comment = #009900
color.bg.plugin.programdiff.details.danger = #FF0000
color.bg.plugin.programdiff.details.emphasize = #009900
color.bg.plugin.references.table.active.operand = rgb(205, 205, 205) color.bg.plugin.references.table.active.operand = rgb(205, 205, 205)
@ -213,8 +207,6 @@ color.bg.plugin.editors.compositeeditor.byte.header = [color]system.color.bg.vie
color.fg.plugin.equate.enum = deepskyblue color.fg.plugin.equate.enum = deepskyblue
color.bg.plugin.programdiff.highlight = darkRed
color.bg.plugin.references.table.active.operand = #5A5E60 color.bg.plugin.references.table.active.operand = #5A5E60

View file

@ -28,6 +28,7 @@ import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.map.LazyMap; import org.apache.commons.collections4.map.LazyMap;
import docking.widgets.PopupWindow; import docking.widgets.PopupWindow;
import generic.theme.*;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.viewer.listingpanel.*; import ghidra.app.util.viewer.listingpanel.*;
@ -85,6 +86,7 @@ public class MarkerManager implements MarkerService {
private List<ChangeListener> listeners = new ArrayList<>(); private List<ChangeListener> listeners = new ArrayList<>();
private MarkerClickedListener markerClickedListener = null; private MarkerClickedListener markerClickedListener = null;
private ThemeListener themeListener = e -> themeChanged(e);
public MarkerManager(Plugin plugin) { public MarkerManager(Plugin plugin) {
this(plugin.getName(), plugin.getTool()); this(plugin.getName(), plugin.getTool());
@ -103,6 +105,13 @@ public class MarkerManager implements MarkerService {
primaryMarginProvider = createMarginProvider(); primaryMarginProvider = createMarginProvider();
primaryOverviewProvider = createOverviewProvider(); primaryOverviewProvider = createOverviewProvider();
Gui.addThemeListener(themeListener);
}
private void themeChanged(ThemeEvent e) {
if (e instanceof ColorChangedThemeEvent) {
markerSetCache.clearColors();
}
} }
private void programClosed(Program program) { private void programClosed(Program program) {
@ -230,6 +239,7 @@ public class MarkerManager implements MarkerService {
} }
public void dispose() { public void dispose() {
Gui.removeThemeListener(themeListener);
updater.dispose(); updater.dispose();
markerSetCache.clear(); markerSetCache.clear();
overviewProviders.forEach(provider -> provider.dispose()); overviewProviders.forEach(provider -> provider.dispose());
@ -475,6 +485,12 @@ public class MarkerManager implements MarkerService {
return entry; return entry;
} }
void clearColors() {
for (MarkerSetCacheEntry entry : map.values()) {
entry.clearColors();
}
}
public void clear() { public void clear() {
map.clear(); map.clear();
} }
@ -509,6 +525,10 @@ public class MarkerManager implements MarkerService {
program.addCloseListener(closeListener); program.addCloseListener(closeListener);
} }
void clearColors() {
colorCache.clear();
}
private void programClosed() { private void programClosed() {
program.removeCloseListener(closeListener); program.removeCloseListener(closeListener);
cache.programClosed(program); cache.programClosed(program);

View file

@ -223,6 +223,7 @@ public class MultiTabPanel extends JPanel {
iconLabel.setToolTipText("Close"); iconLabel.setToolTipText("Close");
iconLabel.setName("Close"); // junit access iconLabel.setName("Close"); // junit access
iconLabel.setOpaque(true);
MouseListener iconSwitcherMouseListener = new MouseAdapter() { MouseListener iconSwitcherMouseListener = new MouseAdapter() {
@Override @Override
@ -925,6 +926,8 @@ public class MultiTabPanel extends JPanel {
this.nameLabel = nameLabel; this.nameLabel = nameLabel;
this.labelPanel = labelPanel; this.labelPanel = labelPanel;
this.iconLabel = iconLabel; this.iconLabel = iconLabel;
setBackground(backgroundColor);
} }
void refresh() { void refresh() {

View file

@ -69,7 +69,6 @@
</TBODY> </TBODY>
</TABLE><BR> </TABLE><BR>
<BR> <BR>
<P>Once a graph is stale, you can press the refresh button at any time to have the graph <P>Once a graph is stale, you can press the refresh button at any time to have the graph
re-create itself <B>without performing a relayout</B>. The green box in the image above re-create itself <B>without performing a relayout</B>. The green box in the image above

View file

@ -1,69 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.functiongraph;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import javax.swing.Icon;
import javax.swing.JComponent;
import docking.*;
import generic.theme.GIcon;
import ghidra.app.plugin.core.functiongraph.mvc.FGController;
import ghidra.framework.plugintool.ComponentProviderAdapter;
import ghidra.util.HelpLocation;
public class FGSatelliteUndockedProvider extends ComponentProviderAdapter {
static final String NAME = "Function Graph Satellite";
private static final Icon ICON = new GIcon("icon.functiongraph.action.provider.satellite");
private FGController controller;
private JComponent satelliteComponent;
public FGSatelliteUndockedProvider(FunctionGraphPlugin plugin, FGController controller,
JComponent satelliteComponent) {
super(plugin.getTool(), NAME, plugin.getName());
this.controller = controller;
this.satelliteComponent = satelliteComponent;
satelliteComponent.setMinimumSize(new Dimension(400, 400));
setHelpLocation(new HelpLocation("FunctionGraphPlugin", "Satellite_View_Dock"));
setIcon(ICON);
setDefaultWindowPosition(WindowPosition.WINDOW);
setWindowMenuGroup(FunctionGraphPlugin.FUNCTION_GRAPH_NAME);
addToTool();
}
@Override
public ActionContext getActionContext(MouseEvent event) {
ComponentProvider primaryProvider = controller.getProvider();
return primaryProvider.getActionContext(event);
}
@Override
public JComponent getComponent() {
return satelliteComponent;
}
@Override
public void componentShown() {
controller.satelliteProviderShown();
}
}

View file

@ -79,6 +79,8 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
protected static final Transferable DUMMY_TRANSFERABLE = new DummyTransferable(); protected static final Transferable DUMMY_TRANSFERABLE = new DummyTransferable();
protected static final String SATELLITE_NAME = "Function Graph Satellite";
protected PluginTool tool; protected PluginTool tool;
protected FunctionGraphPlugin graphPlugin; protected FunctionGraphPlugin graphPlugin;
protected ProgramDB program; protected ProgramDB program;
@ -170,12 +172,12 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
// 01002239 // 01002239
/* /*
A A
|->B |->B
C C
*/ */
// A // A
@ -210,7 +212,7 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
private void build_ghidra(ToyProgramBuilder builder) throws MemoryAccessException { private void build_ghidra(ToyProgramBuilder builder) throws MemoryAccessException {
/* /*
Originally from notepad 'ghidra' Originally from notepad 'ghidra'
A A
|-> B |-> B
|-> C |-> C
@ -222,7 +224,7 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
|-> G |-> G
| |
H H
*/ */
// A - // A -
@ -309,7 +311,7 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
private void build_sscanf(ToyProgramBuilder builder) throws MemoryAccessException { private void build_sscanf(ToyProgramBuilder builder) throws MemoryAccessException {
/* /*
Originally from notepad 'sscanf' Originally from notepad 'sscanf'
A A
|-> B |-> B
| |
@ -320,7 +322,7 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
F F
| |
G G
*/ */
// A - 9 code units // A - 9 code units
@ -1448,14 +1450,14 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
// //
/* /*
0) Initial Graph 0) Initial Graph
1 -> 2 -> 3 -> 4 1 -> 2 -> 3 -> 4
| |
* *
5 5
*/ */
create12345Graph(); create12345Graph();
@ -1479,12 +1481,12 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
/* /*
1) Create two separate group vertices (A and B), such that A has an edge to B. 1) Create two separate group vertices (A and B), such that A has an edge to B.
A (v:{1,2} e:{1->2, 2->3}) -> B (v:{3,4} e:{2->3,3->4,3->5}) A (v:{1,2} e:{1->2, 2->3}) -> B (v:{3,4} e:{2->3,3->4,3->5})
| |
* *
5 5
*/ */
GroupedFunctionGraphVertex groupA = group("A", v1, v2); GroupedFunctionGraphVertex groupA = group("A", v1, v2);
@ -1497,12 +1499,12 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
/* /*
2) Create a third group vertex (Z) that contains a non-grouped vertex *and* one 2) Create a third group vertex (Z) that contains a non-grouped vertex *and* one
of the other groups (B). of the other groups (B).
A (v:{1,2} e:{1->2, 2->3}) -> Z ( A (v:{1,2} e:{1->2, 2->3}) -> Z (
v:{B (v:{3,4} e:{2->3,3->4,3->5}), 5} v:{B (v:{3,4} e:{2->3,3->4,3->5}), 5}
e:{2->3, 3->5} e:{2->3, 3->5}
) )
*/ */
GroupedFunctionGraphVertex groupZ = group("Z", groupB, v5); GroupedFunctionGraphVertex groupZ = group("Z", groupB, v5);
@ -1512,12 +1514,12 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
/* /*
3) Now, ungroup the 1 remaining originally grouped vertex (A). 3) Now, ungroup the 1 remaining originally grouped vertex (A).
1 -> 2 -> Z ( 1 -> 2 -> Z (
v:{B (v:{3,4} e:{2->3,3->4,3->5}), 5} v:{B (v:{3,4} e:{2->3,3->4,3->5}), 5}
e:{2->3, 3->5} e:{2->3, 3->5}
) )
*/ */
ungroup(groupA); ungroup(groupA);
@ -1527,14 +1529,14 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
verifyEdgeCount(2); verifyEdgeCount(2);
/* /*
4) Now, ungroup Z and go back to having one remaining group vertex (B) 4) Now, ungroup Z and go back to having one remaining group vertex (B)
1 -> 2 -> -> B (v:{3,4} e:{2->3,3->4,3->5}) 1 -> 2 -> -> B (v:{3,4} e:{2->3,3->4,3->5})
| |
* *
5 5
*/ */
ungroup(groupZ); ungroup(groupZ);
@ -1546,12 +1548,12 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
/* /*
5) Finally, ungroup the last group and make sure the graph is restored 5) Finally, ungroup the last group and make sure the graph is restored
1 -> 2 -> 3 -> 4 1 -> 2 -> 3 -> 4
| |
* *
5 5
*/ */
ungroup(groupB); ungroup(groupB);
@ -2120,12 +2122,12 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
} }
protected void assertNoUndockedProvider() { protected void assertNoUndockedProvider() {
ComponentProvider provider = tool.getComponentProvider(FGSatelliteUndockedProvider.NAME); ComponentProvider provider = tool.getComponentProvider(SATELLITE_NAME);
assertNull("Undocked satellite provider is installed when it should not be", provider); assertNull("Undocked satellite provider is installed when it should not be", provider);
} }
protected void assertUndockedProviderNotShowing() { protected void assertUndockedProviderNotShowing() {
ComponentProvider provider = tool.getComponentProvider(FGSatelliteUndockedProvider.NAME); ComponentProvider provider = tool.getComponentProvider(SATELLITE_NAME);
if (provider == null) { if (provider == null) {
return; // no provider; not showing return; // no provider; not showing
} }
@ -2133,7 +2135,7 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
} }
protected void assertUndockedProviderShowing() { protected void assertUndockedProviderShowing() {
ComponentProvider provider = tool.getComponentProvider(FGSatelliteUndockedProvider.NAME); ComponentProvider provider = tool.getComponentProvider(SATELLITE_NAME);
assertUndockedProviderShowing(provider); assertUndockedProviderShowing(provider);
} }
@ -2173,7 +2175,7 @@ public abstract class AbstractFunctionGraphTest extends AbstractGhidraHeadedInte
} }
protected void closeUndockedProvider() { protected void closeUndockedProvider() {
ComponentProvider provider = tool.getComponentProvider(FGSatelliteUndockedProvider.NAME); ComponentProvider provider = tool.getComponentProvider(SATELLITE_NAME);
assertNotNull("Undocked provider is not installed when it should be", provider); assertNotNull("Undocked provider is not installed when it should be", provider);
tool.showComponentProvider(provider, false); tool.showComponentProvider(provider, false);
waitForSwing(); waitForSwing();

View file

@ -1,6 +1,14 @@
[Defaults] [Defaults]
color.bg.plugin.programdiff.highlight = moccasin
color.bg.plugin.programdiff.details.address = #009999
color.bg.plugin.programdiff.details.comment = #009900
color.bg.plugin.programdiff.details.danger = #FF0000
color.bg.plugin.programdiff.details.emphasize = #009900
icon.plugin.programdiff.apply = pencil16.png icon.plugin.programdiff.apply = pencil16.png
icon.plugin.programdiff.apply.next = pencil_arrow16.png icon.plugin.programdiff.apply.next = pencil_arrow16.png
icon.plugin.programdiff.ignore = eraser_arrow16.png icon.plugin.programdiff.ignore = eraser_arrow16.png
@ -10,5 +18,8 @@ icon.plugin.programdiff.open.close.program = table_relationship.png
icon.plugin.programdiff.settings = settings16.gif icon.plugin.programdiff.settings = settings16.gif
icon.plugin.programdiff.cursor.location = cursor_arrow.gif icon.plugin.programdiff.cursor.location = cursor_arrow.gif
[Dark Defaults] [Dark Defaults]
color.bg.plugin.programdiff.highlight = #4D4D2A

View file

@ -48,6 +48,7 @@ public abstract class AbstractHtmlLabel extends JLabel
private static final String HTML_TAG = "<html>"; private static final String HTML_TAG = "<html>";
private boolean isUpdating = false; private boolean isUpdating = false;
private boolean isHtml = false;
protected AbstractHtmlLabel() { protected AbstractHtmlLabel() {
addPropertyChangeListener(this); addPropertyChangeListener(this);
@ -64,6 +65,10 @@ public abstract class AbstractHtmlLabel extends JLabel
// do not pass <html> up to the parent so that it does not install its own html rendering // do not pass <html> up to the parent so that it does not install its own html rendering
if (text != null && text.toLowerCase().startsWith(HTML_TAG)) { if (text != null && text.toLowerCase().startsWith(HTML_TAG)) {
text = text.substring(HTML_TAG.length()); text = text.substring(HTML_TAG.length());
isHtml = true;
}
else {
isHtml = false;
} }
super.setText(text); super.setText(text);
@ -80,7 +85,7 @@ public abstract class AbstractHtmlLabel extends JLabel
private void updateHtmlView() { private void updateHtmlView() {
String text = getText(); String text = getText();
if (text == null || !isHTMLRenderingEnabled()) { if (text == null || !isHtml || !isHTMLRenderingEnabled()) {
putClientProperty(BasicHTML.propertyKey, null); putClientProperty(BasicHTML.propertyKey, null);
return; return;
} }
@ -211,10 +216,9 @@ public abstract class AbstractHtmlLabel extends JLabel
String size = Integer.toString(font.getSize()); String size = Integer.toString(font.getSize());
String weight = font.isBold() ? "700" : "400"; String weight = font.isBold() ? "700" : "400";
String style = font.isItalic() ? "italic" : "normal"; String style = font.isItalic() ? "italic" : "normal";
String color = WebColors.toString(bg); String color = WebColors.toString(bg, false);
String css = String.format(s, family, size, weight, style, color); String css = String.format(s, family, size, weight, style, color);
StyleSheet styleSheet = getStyleSheet(); ss.addRule(css);
styleSheet.addRule(css);
} }
@Override @Override

View file

@ -29,7 +29,7 @@ import ghidra.graph.viewer.VisualVertex;
import ghidra.graph.viewer.vertex.AbstractVisualVertexRenderer; import ghidra.graph.viewer.vertex.AbstractVisualVertexRenderer;
/** /**
* A renderer for vertices for the satellite view. This is really just a basic renderer * A renderer for vertices for the satellite view. This is really just a basic renderer
* that adds emphasis capability, as seen in the primary function graph renderer. * that adds emphasis capability, as seen in the primary function graph renderer.
* @param <V> the vertex type * @param <V> the vertex type
* @param <E> the edge type * @param <E> the edge type
@ -59,9 +59,9 @@ public class VisualVertexSatelliteRenderer<V extends VisualVertex, E extends Vis
} }
// POSTERITY NOTE: we used to let the satellite paint the emphasis of nodes, as a way to call // POSTERITY NOTE: we used to let the satellite paint the emphasis of nodes, as a way to call
// attention to the selected node. Now that we use caching, this has the odd // attention to the selected node. Now that we use caching, this has the odd
// side-effect of painting a large vertex in the cached image. Also, we have // side-effect of painting a large vertex in the cached image. Also, we have
// changed how the satellite paints selected vertices, so the effect being // changed how the satellite paints selected vertices, so the effect being
// performed below is no longer necessary. // performed below is no longer necessary.
// GraphicsDecorator emphasisGraphics = getEmphasisGraphics(defaultGraphics, v, rc, layout); // GraphicsDecorator emphasisGraphics = getEmphasisGraphics(defaultGraphics, v, rc, layout);
// rc.setGraphicsContext(emphasisGraphics); // rc.setGraphicsContext(emphasisGraphics);
@ -87,8 +87,12 @@ public class VisualVertexSatelliteRenderer<V extends VisualVertex, E extends Vis
return; return;
} }
// this makes the plain vertices easier to see
paintDropShadow(rc, g, shape);
g.setPaint(fillPaint); g.setPaint(fillPaint);
g.fill(shape); g.fill(shape);
g.setPaint(oldPaint); g.setPaint(oldPaint);
} }
@ -99,7 +103,7 @@ public class VisualVertexSatelliteRenderer<V extends VisualVertex, E extends Vis
// DEBUG original behavior; this can show the true shape of the vertex // DEBUG original behavior; this can show the true shape of the vertex
// return super.prepareFinalVertexShape(rc, v, layout, coords); // return super.prepareFinalVertexShape(rc, v, layout, coords);
// use the compact shape in the satellite view // use the compact shape in the satellite view
return getCompactShape(rc, layout, v); return getCompactShape(rc, layout, v);
} }
@ -117,7 +121,7 @@ public class VisualVertexSatelliteRenderer<V extends VisualVertex, E extends Vis
// int offset = (int) adjustValueForCurrentScale(rc, 10D, .25); // int offset = (int) adjustValueForCurrentScale(rc, 10D, .25);
int offset = 10; int offset = 10;
// scale the offset with the scale of the view, but not as fast, so that as we scale down, // scale the offset with the scale of the view, but not as fast, so that as we scale down,
// the size of the paint area starts to get larger than the vertex // the size of the paint area starts to get larger than the vertex
offset = (int) adjustValueForCurrentScale(rc, offset, .9); offset = (int) adjustValueForCurrentScale(rc, offset, .9);
g.fillOval(bounds.x - offset, bounds.y - offset, bounds.width + (offset * 2), g.fillOval(bounds.x - offset, bounds.y - offset, bounds.width + (offset * 2),

View file

@ -49,6 +49,7 @@ color.palette.pink = pink
color.palette.purple = purple color.palette.purple = purple
color.palette.red = red color.palette.red = red
color.palette.silver = silver color.palette.silver = silver
color.palette.slateblue = slateblue
color.palette.steelblue = steelblue color.palette.steelblue = steelblue
color.palette.tan = tan color.palette.tan = tan
color.palette.teal = teal color.palette.teal = teal

View file

@ -228,8 +228,8 @@ public class ApplicationThemeManager extends ThemeManager {
} }
updateChangedValuesMap(currentValue, newValue); updateChangedValuesMap(currentValue, newValue);
currentValues.addColor(newValue); currentValues.addColor(newValue);
lookAndFeelManager.colorsChanged();
notifyThemeChanged(new ColorChangedThemeEvent(currentValues, newValue)); notifyThemeChanged(new ColorChangedThemeEvent(currentValues, newValue));
lookAndFeelManager.colorsChanged();
} }
@Override @Override

View file

@ -213,7 +213,8 @@ public abstract class LookAndFeelManager {
} }
/** /**
* Subclass provide this method to install the specific loo * Subclass provide this method to install the specific look and feel.
*
* @throws ClassNotFoundException if the <code>LookAndFeel</code> * @throws ClassNotFoundException if the <code>LookAndFeel</code>
* class could not be found * class could not be found
* @throws InstantiationException if a new instance of the class * @throws InstantiationException if a new instance of the class
@ -237,7 +238,7 @@ public abstract class LookAndFeelManager {
} }
/** /**
* Extracts java default colors, fonts, and icons and stores them in the * Extracts java default colors, fonts, and icons and stores them in the
* {@link ThemeManager} and updates the {@link UIDefaults} by installing GColors for all * {@link ThemeManager} and updates the {@link UIDefaults} by installing GColors for all
* color values and installing any overridden fonts or icons. * color values and installing any overridden fonts or icons.
*/ */