GP-1981 externalized icons for XTRA modules. Added loadIcon method in

ResourceManager. Created api for integrating Options with Theming. Fixed
issue with system property mappings. Created dynamic icons for the close
and drop-down menu item icons.
This commit is contained in:
ghidragon 2022-09-26 18:46:30 -04:00
parent 0971c0088c
commit d466dbf06b
32 changed files with 637 additions and 260 deletions

View file

@ -24,14 +24,13 @@ import docking.ActionContext;
import docking.WindowPosition;
import docking.action.*;
import docking.widgets.EmptyBorderButton;
import generic.theme.GIcon;
import ghidra.framework.plugintool.ComponentProviderAdapter;
import ghidra.framework.plugintool.PluginTool;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import resources.ResourceManager;
public class HelloWorldComponentProvider extends ComponentProviderAdapter {
private final static String PREV_IMAGE = "images/information.png";
private final static HelpLocation HELP = new HelpLocation("SampleHelpTopic",
"SampleHelpTopic_Anchor_Name");
private MyButton activeButtonObj;
@ -41,7 +40,7 @@ public class HelloWorldComponentProvider extends ComponentProviderAdapter {
public HelloWorldComponentProvider(PluginTool tool, String name) {
super(tool, name, name);
buildMainPanel();
setIcon(ResourceManager.loadImage("images/erase16.png"));
setIcon(new GIcon("icon.sample.provider"));
setHelpLocation(HELP);
setDefaultWindowPosition(WindowPosition.WINDOW);
setTitle("Hello World Component");
@ -64,13 +63,13 @@ public class HelloWorldComponentProvider extends ComponentProviderAdapter {
// put in Menu called "Hello", with Menu item of "World". Since this will be a local action
// the menu item will appear on the local toolbar drop down.
ImageIcon prevImage = ResourceManager.loadImage(PREV_IMAGE);
action.setMenuBarData(new MenuData(new String[] { "Misc", "Hello World" }, prevImage));
Icon icon = new GIcon("icon.sample.action.hello.world");
action.setMenuBarData(new MenuData(new String[] { "Misc", "Hello World" }, icon));
action.setKeyBindingData(new KeyBindingData(KeyStroke.getKeyStroke(KeyEvent.VK_W,
InputEvent.CTRL_MASK)));
// puts the action on the local toolbar.
action.setToolBarData(new ToolBarData(prevImage));
action.setToolBarData(new ToolBarData(icon));
action.setDescription("Hello World");
// set the help URL for the action

View file

@ -15,6 +15,14 @@
*/
package ghidra.examples;
import java.awt.Event;
import java.awt.event.KeyEvent;
import javax.swing.*;
import docking.ActionContext;
import docking.action.*;
import generic.theme.GIcon;
import ghidra.app.ExamplesPluginPackage;
import ghidra.app.events.ProgramLocationPluginEvent;
import ghidra.app.plugin.PluginCategoryNames;
@ -28,15 +36,6 @@ import ghidra.program.model.listing.Program;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import java.awt.Event;
import java.awt.event.KeyEvent;
import javax.swing.*;
import resources.ResourceManager;
import docking.ActionContext;
import docking.action.*;
/**
* Class description goes here
*
@ -54,120 +53,120 @@ import docking.action.*;
)
//@formatter:on
public class KitchenSinkPlugin extends ProgramPlugin {
private final static String NEXT_IMAGE = "images/right.png";
private final static String PREV_IMAGE = "images/left.png";
private DockingAction helloProgramAction;
private Program program;
private DockingAction helloProgramAction;
private Program program;
/**
* Constructor
*/
public KitchenSinkPlugin(PluginTool tool) {
/**
* Constructor
*/
public KitchenSinkPlugin(PluginTool tool) {
super(tool);
super(tool);
// set up list of services.
setupServices();
// set up list of services.
setupServices();
// set up list of actions.
setupActions();
}
private void setupServices() {
registerServiceProvided(HelloWorldService.class,
new HelloWorldService() {
public void sayHello() {
announce("Hello");
}
});
}
private void setupActions() {
DockingAction action = new DockingAction("Hello World", getName() ) {
@Override
public void actionPerformed( ActionContext context ) {
Msg.info(this, "Hello World:: action");
announce("Hello World");
}
};
action.setEnabled( true );
String helloGroup = "Hello";
ImageIcon prevImage = ResourceManager.loadImage(PREV_IMAGE);
action.setMenuBarData( new MenuData( new String[] {"Misc", "Hello World"}, prevImage, helloGroup ) );
action.setPopupMenuData( new MenuData( new String[] {"Hello World"}, prevImage, helloGroup ) );
action.setKeyBindingData( new KeyBindingData( KeyStroke.getKeyStroke('H', Event.CTRL_MASK ) ) );
action.setToolBarData( new ToolBarData( prevImage, helloGroup ) );
action.setDescription("Hello World");
action.setHelpLocation(new HelpLocation("SampleHelpTopic", "KS_Hello_World"));
tool.addAction(action);
action = new DockingAction("Hello Program", getName() ) {
@Override
public void actionPerformed( ActionContext context ) {
Msg.info(this, "Hello Program:: action");
sayHelloProgram();
}
};
action.setEnabled(false);
ImageIcon nextImage = ResourceManager.loadImage(NEXT_IMAGE);
action.setMenuBarData( new MenuData( new String[]{"Misc", "Hello Program"}, nextImage, helloGroup ) );
action.setKeyBindingData( new KeyBindingData( KeyStroke.getKeyStroke(KeyEvent.VK_P, Event.CTRL_MASK ) ) );
action.setToolBarData( new ToolBarData( nextImage, helloGroup ) );
action.setDescription("Hello Program");
action.setHelpLocation(new HelpLocation("SampleHelpTopic", "KS_Hello_Program"));
tool.addAction(action);
// remember this action so I can enable/disable it later
helloProgramAction = action;
}
@Override
protected void programActivated(Program activatedProgram) {
helloProgramAction.setEnabled(true);
this.program = activatedProgram;
// set up list of actions.
setupActions();
}
private void setupServices() {
registerServiceProvided(HelloWorldService.class,
new HelloWorldService() {
public void sayHello() {
announce("Hello");
}
});
}
private void setupActions() {
DockingAction action = new DockingAction("Hello World", getName()) {
@Override
public void actionPerformed(ActionContext context) {
Msg.info(this, "Hello World:: action");
announce("Hello World");
}
};
action.setEnabled(true);
String helloGroup = "Hello";
Icon prevImage = new GIcon("icon.sample.kitchen.sink.action.hello.world");
action.setMenuBarData(
new MenuData(new String[] { "Misc", "Hello World" }, prevImage, helloGroup));
action.setPopupMenuData(
new MenuData(new String[] { "Hello World" }, prevImage, helloGroup));
action.setKeyBindingData(new KeyBindingData(KeyStroke.getKeyStroke('H', Event.CTRL_MASK)));
action.setToolBarData(new ToolBarData(prevImage, helloGroup));
action.setDescription("Hello World");
action.setHelpLocation(new HelpLocation("SampleHelpTopic", "KS_Hello_World"));
tool.addAction(action);
action = new DockingAction("Hello Program", getName()) {
@Override
public void actionPerformed(ActionContext context) {
Msg.info(this, "Hello Program:: action");
sayHelloProgram();
}
};
action.setEnabled(false);
Icon nextImage = new GIcon("icon.sample.kitchen.sink.action.hello.program");
action.setMenuBarData(
new MenuData(new String[] { "Misc", "Hello Program" }, nextImage, helloGroup));
action.setKeyBindingData(
new KeyBindingData(KeyStroke.getKeyStroke(KeyEvent.VK_P, Event.CTRL_MASK)));
action.setToolBarData(new ToolBarData(nextImage, helloGroup));
action.setDescription("Hello Program");
action.setHelpLocation(new HelpLocation("SampleHelpTopic", "KS_Hello_Program"));
tool.addAction(action);
// remember this action so I can enable/disable it later
helloProgramAction = action;
}
@Override
protected void programDeactivated(Program deactivatedProgram) {
protected void programActivated(Program activatedProgram) {
helloProgramAction.setEnabled(true);
this.program = activatedProgram;
}
@Override
protected void programDeactivated(Program deactivatedProgram) {
if (this.program == deactivatedProgram) {
helloProgramAction.setEnabled(false);
this.program = null;
}
}
protected void sayHelloProgram() {
if (program == null) {
return;
}
protected void sayHelloProgram() {
announce("Hello " + program.getName());
}
if (program == null) {
return;
}
protected void announce(String message) {
JOptionPane.showMessageDialog(null,message,"Hello World",
JOptionPane.INFORMATION_MESSAGE);
}
/**
announce("Hello " + program.getName());
}
protected void announce(String message) {
JOptionPane.showMessageDialog(null, message, "Hello World",
JOptionPane.INFORMATION_MESSAGE);
}
/**
* If your plugin maintains configuration state, you must save that state information
* to the SaveState object in this method. For example, the Code Browser can be configured
* to show fields in different colors. This is the method where that type
* information is saved.
* to the SaveState object in this method. For example, the Code Browser can be configured
* to show fields in different colors. This is the method where that type
* information is saved.
*/
@Override
public void writeConfigState(SaveState saveState) {
}
@Override
public void writeConfigState(SaveState saveState) {
}
/**
* If your plugin maintains configuration state, this is where you read it
* back in.
* back in.
*/
@Override
public void readConfigState(SaveState saveState) {
}
@Override
public void readConfigState(SaveState saveState) {
}
}

View file

@ -23,15 +23,15 @@ import docking.ActionContext;
import docking.WindowPosition;
import docking.action.DockingAction;
import docking.action.ToolBarData;
import generic.theme.GIcon;
import ghidra.framework.plugintool.ComponentProviderAdapter;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.listing.*;
import ghidra.program.util.ProgramLocation;
import resources.ResourceManager;
public class ShowInfoComponentProvider extends ComponentProviderAdapter {
private final static ImageIcon CLEAR_ICON = ResourceManager.loadImage("images/erase16.png");
private final static ImageIcon INFO_ICON = ResourceManager.loadImage("images/information.png");
private final static Icon CLEAR_ICON = new GIcon("icon.sample.hello.world.action.clear");
private final static Icon PROVIDER_ICON = new GIcon("icon.sample.provider.hello.world");
private JPanel panel;
private JTextArea textArea;
@ -42,7 +42,7 @@ public class ShowInfoComponentProvider extends ComponentProviderAdapter {
public ShowInfoComponentProvider(PluginTool tool, String name) {
super(tool, name, name);
create();
setIcon(INFO_ICON);
setIcon(PROVIDER_ICON);
setDefaultWindowPosition(WindowPosition.BOTTOM);
setTitle("Show Info");
setVisible(true);

View file

@ -15,17 +15,17 @@
*/
package ghidra.examples.graph;
import javax.swing.ImageIcon;
import javax.swing.Icon;
import docking.ActionContext;
import docking.action.DockingAction;
import docking.action.ToolBarData;
import generic.theme.GIcon;
import ghidra.app.ExamplesPluginPackage;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.util.HelpLocation;
import resources.ResourceManager;
/**
* Sample plugin to demonstrate a plugin with a dockable GUI graph component
@ -64,8 +64,7 @@ public class SampleGraphPlugin extends Plugin {
showProvider();
}
};
ImageIcon icon = ResourceManager.loadImage("images/applications-development.png");
Icon icon = new GIcon("icon.sample.action.show.graph");
showProviderAction.setToolBarData(new ToolBarData(icon, "View"));
showProviderAction.setHelpLocation(DEFAULT_HELP);
tool.addAction(showProviderAction);
@ -75,7 +74,6 @@ public class SampleGraphPlugin extends Plugin {
provider.setVisible(true);
}
@Override
protected void dispose() {
provider.dispose();

View file

@ -21,12 +21,12 @@ import java.util.Collection;
import javax.swing.Icon;
import edu.uci.ics.jung.algorithms.layout.Layout;
import generic.theme.GIcon;
import ghidra.examples.graph.*;
import ghidra.graph.viewer.layout.AbstractLayoutProvider;
import ghidra.graph.viewer.layout.VisualGraphLayout;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
import resources.ResourceManager;
/**
* The layout provider for the {@link SampleGraphPlugin}.
@ -34,7 +34,7 @@ import resources.ResourceManager;
public abstract class SampleGraphLayoutProvider
extends AbstractLayoutProvider<SampleVertex, SampleEdge, SampleGraph> {
private static final Icon DEFAULT_ICON = ResourceManager.loadImage("images/color_swatch.png");
private static final Icon DEFAULT_ICON = new GIcon("icon.sample.provider.graph");
@Override
public abstract VisualGraphLayout<SampleVertex, SampleEdge> getLayout(SampleGraph g,

View file

@ -17,12 +17,12 @@ package ghidra.examples.graph.layout;
import javax.swing.Icon;
import generic.theme.GIcon;
import ghidra.examples.graph.*;
import ghidra.graph.viewer.layout.AbstractLayoutProvider;
import ghidra.graph.viewer.layout.VisualGraphLayout;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
import resources.ResourceManager;
/**
* A layout provider for the {@link SampleGraphPlugin}
@ -31,7 +31,7 @@ public class SampleGraphPluginDependencyLayoutProvider
extends AbstractLayoutProvider<SampleVertex, SampleEdge, SampleGraph> {
private static final String NAME = "Plugin Dependency Layout";
private static final Icon DEFAULT_ICON = ResourceManager.loadImage("images/color_swatch.png");
private static final Icon DEFAULT_ICON = new GIcon("icon.sample.graph.dependency.layout");
@Override
public VisualGraphLayout<SampleVertex, SampleEdge> getLayout(SampleGraph g, TaskMonitor monitor)