GP-757 - Function Graph - added options to set background color for

graph view and for the vertices

Closes #1324
This commit is contained in:
dragonmacher 2021-03-08 18:15:27 -05:00
parent c905c203f0
commit 9e785c25ec
18 changed files with 150 additions and 30 deletions

View file

@ -578,6 +578,10 @@ public class FGProvider extends VisualGraphComponentProvider<FGVertex, FGEdge, F
} }
} }
public void optionsChanged() {
controller.optionsChanged();
}
@Override @Override
public void domainObjectChanged(DomainObjectChangedEvent ev) { public void domainObjectChanged(DomainObjectChangedEvent ev) {
if (!isVisible()) { if (!isVisible()) {

View file

@ -172,6 +172,8 @@ public class FunctionGraphPlugin extends ProgramPlugin implements OptionsChangeL
functionGraphOptions.loadOptions(options); functionGraphOptions.loadOptions(options);
connectedProvider.optionsChanged();
if (functionGraphOptions.optionChangeRequiresRelayout(optionName)) { if (functionGraphOptions.optionChangeRequiresRelayout(optionName)) {
connectedProvider.refreshAndKeepPerspective(); connectedProvider.refreshAndKeepPerspective();
} }

View file

@ -36,6 +36,7 @@ import ghidra.graph.viewer.*;
import ghidra.graph.viewer.layout.LayoutListener.ChangeType; import ghidra.graph.viewer.layout.LayoutListener.ChangeType;
import ghidra.graph.viewer.layout.LayoutProvider; import ghidra.graph.viewer.layout.LayoutProvider;
import ghidra.graph.viewer.layout.VisualGraphLayout; import ghidra.graph.viewer.layout.VisualGraphLayout;
import ghidra.graph.viewer.options.VisualGraphOptions;
import ghidra.graph.viewer.renderer.VisualGraphEdgeLabelRenderer; import ghidra.graph.viewer.renderer.VisualGraphEdgeLabelRenderer;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
@ -65,6 +66,8 @@ public class FGComponent extends GraphComponent<FGVertex, FGEdge, FunctionGraph>
// the base class builds. // the base class builds.
// super(data.getFunctionGraph()); // super(data.getFunctionGraph());
setGraphOptions(functionGraphView.getController().getFunctionGraphOptions());
setGraph(data.getFunctionGraph()); setGraph(data.getFunctionGraph());
this.functionGraphView = functionGraphView; this.functionGraphView = functionGraphView;
@ -217,7 +220,12 @@ public class FGComponent extends GraphComponent<FGVertex, FGEdge, FunctionGraph>
edgeLabelRenderer.setRotateEdgeLabels(false); edgeLabelRenderer.setRotateEdgeLabels(false);
renderContext.setEdgeLabelRenderer(edgeLabelRenderer); renderContext.setEdgeLabelRenderer(edgeLabelRenderer);
// Give user notice when seeing the graph for a non-function. viewer.setGraphOptions(options);
Color bgColor = options.getGraphBackgroundColor();
if (bgColor.equals(VisualGraphOptions.DEFAULT_GRAPH_BACKGROUND_COLOR)) {
// Give user notice when seeing the graph for a non-function. Don't do this if the
// user has manually set the background color (this would require another option).
Function function = functionGraphData.getFunction(); Function function = functionGraphData.getFunction();
if (function instanceof UndefinedFunction) { if (function instanceof UndefinedFunction) {
viewer.setBackground(UNDEFINED_FUNCTION_COLOR); viewer.setBackground(UNDEFINED_FUNCTION_COLOR);
@ -225,6 +233,7 @@ public class FGComponent extends GraphComponent<FGVertex, FGEdge, FunctionGraph>
else { else {
viewer.setBackground(Color.WHITE); viewer.setBackground(Color.WHITE);
} }
}
return viewer; return viewer;
} }
@ -248,6 +257,8 @@ public class FGComponent extends GraphComponent<FGVertex, FGEdge, FunctionGraph>
renderContext.setVertexFillPaintTransformer(new FGVertexPickableBackgroundPaintTransformer( renderContext.setVertexFillPaintTransformer(new FGVertexPickableBackgroundPaintTransformer(
pickedVertexState, Color.YELLOW, START_COLOR, END_COLOR)); pickedVertexState, Color.YELLOW, START_COLOR, END_COLOR));
viewer.setGraphOptions(options);
return viewer; return viewer;
} }
@ -274,7 +285,7 @@ public class FGComponent extends GraphComponent<FGVertex, FGEdge, FunctionGraph>
//================================================================================================== //==================================================================================================
public FunctionGraphOptions getFucntionGraphOptions() { public FunctionGraphOptions getFucntionGraphOptions() {
return functionGraphView.getController().getFunctionGraphOptions(); return (FunctionGraphOptions) options;
} }
public void ensureCursorVisible(FGVertex vertex) { public void ensureCursorVisible(FGVertex vertex) {

View file

@ -33,7 +33,6 @@ public class FGPrimaryViewer extends GraphViewer<FGVertex, FGEdge> {
super(layout, size); super(layout, size);
setVertexTooltipProvider(new FGVertexTooltipProvider()); setVertexTooltipProvider(new FGVertexTooltipProvider());
setGraphOptions(graphComponent.getFucntionGraphOptions());
} }
@Override @Override

View file

@ -140,9 +140,6 @@ public abstract class AbstractGraphComponentPanel extends JPanel {
} }
Component header = getHeader(); Component header = getHeader();
if (clickedComponent == null) {
return false;
}
return SwingUtilities.isDescendingFrom(clickedComponent, header); return SwingUtilities.isDescendingFrom(clickedComponent, header);
} }

View file

@ -98,7 +98,7 @@ public interface FGVertex extends VisualVertex {
* grouped, but that it has been part of a group and can be put back into its group form * grouped, but that it has been part of a group and can be put back into its group form
* again. * again.
* *
* @param groupMember True if this vertex is a associate with a group * @param groupInfo True if this vertex is a associate with a group
*/ */
public void updateGroupAssociationStatus(GroupHistoryInfo groupInfo); public void updateGroupAssociationStatus(GroupHistoryInfo groupInfo);
@ -190,8 +190,8 @@ public interface FGVertex extends VisualVertex {
public void refreshDisplay(); public void refreshDisplay();
/** /**
* Refresh the vertex's display information if the given address is the entry point * Refresh the vertex's display information if the given address is the vertex entry point
* of the vertex. * @param address the addresses
*/ */
public void refreshDisplayForAddress(Address address); public void refreshDisplayForAddress(Address address);

View file

@ -15,6 +15,7 @@
*/ */
package ghidra.app.plugin.core.functiongraph.graph.vertex; package ghidra.app.plugin.core.functiongraph.graph.vertex;
import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
@ -23,6 +24,7 @@ import java.util.List;
import docking.widgets.fieldpanel.*; import docking.widgets.fieldpanel.*;
import ghidra.app.plugin.core.functiongraph.FGColorProvider; import ghidra.app.plugin.core.functiongraph.FGColorProvider;
import ghidra.app.plugin.core.functiongraph.mvc.FGController; import ghidra.app.plugin.core.functiongraph.mvc.FGController;
import ghidra.app.plugin.core.functiongraph.mvc.FunctionGraphOptions;
import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.format.FormatManager;
import ghidra.app.util.viewer.listingpanel.*; import ghidra.app.util.viewer.listingpanel.*;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
@ -66,6 +68,10 @@ public class FGVertexListingPanel extends ListingPanel {
ListingModel model = getListingModel(); ListingModel model = getListingModel();
model.addListener(listener); model.addListener(listener);
FunctionGraphOptions options = controller.getFunctionGraphOptions();
Color color = options.getDefaultVertexBackgroundColor();
setTextBackgroundColor(color);
FGColorProvider colorProvider = controller.getColorProvider(); FGColorProvider colorProvider = controller.getColorProvider();
if (!colorProvider.isUsingCustomColors()) { if (!colorProvider.isUsingCustomColors()) {
enablePropertyBasedColorModel(true); // turn on user colors in the graph enablePropertyBasedColorModel(true); // turn on user colors in the graph

View file

@ -382,6 +382,7 @@ public class GroupedFunctionGraphComponentPanel extends AbstractGraphComponentPa
} }
private void doSetBackgroundColor(Color color) { private void doSetBackgroundColor(Color color) {
setBackground(color);
contentPanel.setBackground(color); contentPanel.setBackground(color);
userTextArea.setBackground(color); userTextArea.setBackground(color);
controller.removeColor(vertex); controller.removeColor(vertex);
@ -561,12 +562,26 @@ public class GroupedFunctionGraphComponentPanel extends AbstractGraphComponentPa
@Override @Override
void refreshDisplay() { void refreshDisplay() {
updateDefaultBackgroundColor();
Set<FGVertex> vertices = groupVertex.getVertices(); Set<FGVertex> vertices = groupVertex.getVertices();
for (FGVertex v : vertices) { for (FGVertex v : vertices) {
v.refreshDisplay(); v.refreshDisplay();
} }
} }
private void updateDefaultBackgroundColor() {
FunctionGraphOptions options = controller.getFunctionGraphOptions();
Color newBgColor = options.getDefaultGroupBackgroundColor();
if (!defaultBackgroundColor.equals(newBgColor)) {
defaultBackgroundColor = newBgColor;
if (userDefinedColor == null) {
doSetBackgroundColor(defaultBackgroundColor);
}
}
}
@Override @Override
void refreshDisplayForAddress(Address address) { void refreshDisplayForAddress(Address address) {
Set<FGVertex> vertices = groupVertex.getVertices(); Set<FGVertex> vertices = groupVertex.getVertices();

View file

@ -251,6 +251,19 @@ public class ListingGraphComponentPanel extends AbstractGraphComponentPanel {
title = createTitle(); title = createTitle();
genericHeader.setTitle(title); genericHeader.setTitle(title);
previewListingPanel = null; previewListingPanel = null;
updateDefaultBackgroundColor();
}
private void updateDefaultBackgroundColor() {
FunctionGraphOptions options = controller.getFunctionGraphOptions();
Color newBgColor = options.getDefaultVertexBackgroundColor();
if (!defaultBackgroundColor.equals(newBgColor)) {
defaultBackgroundColor = newBgColor;
if (userDefinedColor == null) {
listingPanel.setTextBackgroundColor(defaultBackgroundColor);
}
}
} }
@Override @Override
@ -522,7 +535,8 @@ public class ListingGraphComponentPanel extends AbstractGraphComponentPanel {
tooltipTitleLabel.setText("From: " + getTitle()); tooltipTitleLabel.setText("From: " + getTitle());
} }
previewListingPanel.getFieldPanel().setBackgroundColorModel( previewListingPanel.getFieldPanel()
.setBackgroundColorModel(
new HighlightingColorModel(address, getColorForEdge(edge))); new HighlightingColorModel(address, getColorForEdge(edge)));
} }

View file

@ -332,7 +332,8 @@ public class FGController implements ProgramLocationListener, ProgramSelectionLi
} }
private boolean shouldSaveVertexChanges() { private boolean shouldSaveVertexChanges() {
return functionGraphOptions.getNavigationHistoryChoice() == NavigationHistoryChoices.VERTEX_CHANGES; return functionGraphOptions
.getNavigationHistoryChoice() == NavigationHistoryChoices.VERTEX_CHANGES;
} }
@Override @Override
@ -634,6 +635,10 @@ public class FGController implements ProgramLocationListener, ProgramSelectionLi
viewSettings.setLocation(location); viewSettings.setLocation(location);
} }
public void optionsChanged() {
view.optionsChanged();
}
public void refreshDisplayWithoutRebuilding() { public void refreshDisplayWithoutRebuilding() {
view.refreshDisplayWithoutRebuilding(); view.refreshDisplayWithoutRebuilding();
} }

View file

@ -73,7 +73,6 @@ public class FGView extends VisualGraphView<FGVertex, FGEdge, FunctionGraph> {
protected void installGraphViewer() { protected void installGraphViewer() {
FGComponent newFgComponent = createGraphComponent(); FGComponent newFgComponent = createGraphComponent();
newFgComponent.setGraphOptions(controller.getFunctionGraphOptions());
setGraphComponent(newFgComponent); setGraphComponent(newFgComponent);
// we must assign the variable here, as the call to setGraphComponent() will call // we must assign the variable here, as the call to setGraphComponent() will call

View file

@ -70,6 +70,10 @@ public class FunctionGraphOptions extends VisualGraphOptions {
"<li><b>Never</b> - do not automatically relayout the graph</li></ul><br><br>" + "<li><b>Never</b> - do not automatically relayout the graph</li></ul><br><br>" +
"<b><i>See help for more</i></b>"; "<b><i>See help for more</i></b>";
private static final String DEFAULT_VERTEX_BACKGROUND_COLOR_KEY = "Default Vertex Color";
private static final String DEFAULT_VERTEX_BACKGROUND_COLOR_DESCRPTION =
"The default background color applied to each vertex";
private static final String DEFAULT_GROUP_BACKGROUND_COLOR_KEY = "Default Group Color"; private static final String DEFAULT_GROUP_BACKGROUND_COLOR_KEY = "Default Group Color";
private static final String DEFAULT_GROUP_BACKGROUND_COLOR_DESCRPTION = private static final String DEFAULT_GROUP_BACKGROUND_COLOR_DESCRPTION =
"The default background color applied to newly created group vertices"; "The default background color applied to newly created group vertices";
@ -80,11 +84,14 @@ public class FunctionGraphOptions extends VisualGraphOptions {
"Signals that any user color changes to a group vertex will apply that same color to " + "Signals that any user color changes to a group vertex will apply that same color to " +
"all grouped vertices as well."; "all grouped vertices as well.";
public static final Color DEFAULT_VERTEX_BACKGROUND_COLOR = Color.WHITE;
public static final Color DEFAULT_GROUP_BACKGROUND_COLOR = new Color(226, 255, 155); public static final Color DEFAULT_GROUP_BACKGROUND_COLOR = new Color(226, 255, 155);
private static final Color HOVER_HIGHLIGHT_FALL_THROUGH_COLOR = new Color(255, 127, 127); private static final Color HOVER_HIGHLIGHT_FALL_THROUGH_COLOR = new Color(255, 127, 127);
private static final Color HOVER_HIGHLIGHT_UNCONDITIONAL_COLOR = new Color(127, 127, 255); private static final Color HOVER_HIGHLIGHT_UNCONDITIONAL_COLOR = new Color(127, 127, 255);
private static final Color HOVER_HIGHLIGHT_CONDITIONAL_COLOR = Color.GREEN; private static final Color HOVER_HIGHLIGHT_CONDITIONAL_COLOR = Color.GREEN;
private Color defaultVertexBackgroundColor = DEFAULT_VERTEX_BACKGROUND_COLOR;
private boolean updateGroupColorsAutomatically = true; private boolean updateGroupColorsAutomatically = true;
private Color defaultGroupBackgroundColor = DEFAULT_GROUP_BACKGROUND_COLOR; private Color defaultGroupBackgroundColor = DEFAULT_GROUP_BACKGROUND_COLOR;
@ -104,6 +111,10 @@ public class FunctionGraphOptions extends VisualGraphOptions {
private Map<String, FGLayoutOptions> layoutOptionsByName = new HashMap<>(); private Map<String, FGLayoutOptions> layoutOptionsByName = new HashMap<>();
public Color getDefaultVertexBackgroundColor() {
return defaultVertexBackgroundColor;
}
public Color getDefaultGroupBackgroundColor() { public Color getDefaultGroupBackgroundColor() {
return defaultGroupBackgroundColor; return defaultGroupBackgroundColor;
} }
@ -174,6 +185,12 @@ public class FunctionGraphOptions extends VisualGraphOptions {
options.registerOption(SCROLL_WHEEL_PANS_KEY, getScrollWheelPans(), help, options.registerOption(SCROLL_WHEEL_PANS_KEY, getScrollWheelPans(), help,
SCROLL_WHEEL_PANS_DESCRIPTION); SCROLL_WHEEL_PANS_DESCRIPTION);
options.registerOption(GRAPH_BACKGROUND_COLOR_KEY, DEFAULT_GRAPH_BACKGROUND_COLOR,
help, GRAPH_BACKGROUND_COLOR_DESCRPTION);
options.registerOption(DEFAULT_VERTEX_BACKGROUND_COLOR_KEY, DEFAULT_VERTEX_BACKGROUND_COLOR,
help, DEFAULT_VERTEX_BACKGROUND_COLOR_DESCRPTION);
options.registerOption(DEFAULT_GROUP_BACKGROUND_COLOR_KEY, DEFAULT_GROUP_BACKGROUND_COLOR, options.registerOption(DEFAULT_GROUP_BACKGROUND_COLOR_KEY, DEFAULT_GROUP_BACKGROUND_COLOR,
help, DEFAULT_GROUP_BACKGROUND_COLOR_DESCRPTION); help, DEFAULT_GROUP_BACKGROUND_COLOR_DESCRPTION);
@ -242,6 +259,12 @@ public class FunctionGraphOptions extends VisualGraphOptions {
scrollWheelPans = options.getBoolean(SCROLL_WHEEL_PANS_KEY, scrollWheelPans); scrollWheelPans = options.getBoolean(SCROLL_WHEEL_PANS_KEY, scrollWheelPans);
graphBackgroundColor =
options.getColor(GRAPH_BACKGROUND_COLOR_KEY, DEFAULT_GRAPH_BACKGROUND_COLOR);
defaultVertexBackgroundColor =
options.getColor(DEFAULT_VERTEX_BACKGROUND_COLOR_KEY, DEFAULT_VERTEX_BACKGROUND_COLOR);
defaultGroupBackgroundColor = defaultGroupBackgroundColor =
options.getColor(DEFAULT_GROUP_BACKGROUND_COLOR_KEY, DEFAULT_GROUP_BACKGROUND_COLOR); options.getColor(DEFAULT_GROUP_BACKGROUND_COLOR_KEY, DEFAULT_GROUP_BACKGROUND_COLOR);
@ -308,5 +331,4 @@ public class FunctionGraphOptions extends VisualGraphOptions {
public void setLayoutOptions(String layoutName, FGLayoutOptions options) { public void setLayoutOptions(String layoutName, FGLayoutOptions options) {
layoutOptionsByName.put(layoutName, options); layoutOptionsByName.put(layoutName, options);
} }
} }

View file

@ -124,7 +124,7 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
// a cache to prevent unnecessary layout calculations // a cache to prevent unnecessary layout calculations
private Dimension lastSize; private Dimension lastSize;
private VisualGraphOptions options = new VisualGraphOptions(); protected VisualGraphOptions options = new VisualGraphOptions();
public GraphComponent(G graph) { public GraphComponent(G graph) {
@ -208,9 +208,7 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
renderContext.setVertexFillPaintTransformer( renderContext.setVertexFillPaintTransformer(
new PickableVertexPaintTransformer<>(pickedVertexState, Color.WHITE, Color.YELLOW)); new PickableVertexPaintTransformer<>(pickedVertexState, Color.WHITE, Color.YELLOW));
viewer.setBackground(Color.WHITE); viewer.setGraphOptions(options);
viewer.setGraphOptions(new VisualGraphOptions());
return viewer; return viewer;
} }
@ -297,6 +295,8 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
SatelliteGraphViewer<V, E> viewer = createSatelliteGraphViewer(masterViewer, viewerSize); SatelliteGraphViewer<V, E> viewer = createSatelliteGraphViewer(masterViewer, viewerSize);
viewer.setGraphOptions(options);
viewer.setMinimumSize(viewerSize); viewer.setMinimumSize(viewerSize);
viewer.setMaximumSize(viewerSize); viewer.setMaximumSize(viewerSize);
@ -525,6 +525,15 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
public void setGraphOptions(VisualGraphOptions options) { public void setGraphOptions(VisualGraphOptions options) {
this.options = options; this.options = options;
// the viewers may be null if called during initialization
if (primaryViewer != null) {
primaryViewer.setGraphOptions(options);
}
if (satelliteViewer != null) {
satelliteViewer.setGraphOptions(options);
}
} }
public boolean isUninitialized() { public boolean isUninitialized() {
@ -562,6 +571,11 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
return mainPanel; return mainPanel;
} }
public void optionsChanged() {
primaryViewer.optionsChanged();
satelliteViewer.optionsChanged();
}
public void repaint() { public void repaint() {
mainPanel.repaint(); mainPanel.repaint();
} }

View file

@ -88,7 +88,7 @@ public class GraphViewer<V extends VisualVertex, E extends VisualEdge<V>>
gPickedState = new GPickedState<>((MultiPickedState<V>) pickedState); gPickedState = new GPickedState<>((MultiPickedState<V>) pickedState);
setPickedVertexState(gPickedState); setPickedVertexState(gPickedState);
popupRegulator = new PopupRegulator<V, E>(new GraphViewerPopupSource()); popupRegulator = new PopupRegulator<>(new GraphViewerPopupSource());
} }
private void buildUpdater() { private void buildUpdater() {
@ -158,6 +158,11 @@ public class GraphViewer<V extends VisualVertex, E extends VisualEdge<V>>
public void setGraphOptions(VisualGraphOptions options) { public void setGraphOptions(VisualGraphOptions options) {
this.options = options; this.options = options;
optionsChanged();
}
public void optionsChanged() {
setBackground(options.getGraphBackgroundColor());
} }
public VisualGraphOptions getOptions() { public VisualGraphOptions getOptions() {

View file

@ -21,6 +21,7 @@ import edu.uci.ics.jung.visualization.control.SatelliteVisualizationViewer;
import edu.uci.ics.jung.visualization.renderers.Renderer; import edu.uci.ics.jung.visualization.renderers.Renderer;
import ghidra.graph.viewer.event.mouse.VisualGraphPluggableGraphMouse; import ghidra.graph.viewer.event.mouse.VisualGraphPluggableGraphMouse;
import ghidra.graph.viewer.event.mouse.VisualGraphSatelliteGraphMouse; import ghidra.graph.viewer.event.mouse.VisualGraphSatelliteGraphMouse;
import ghidra.graph.viewer.options.VisualGraphOptions;
import ghidra.graph.viewer.renderer.VisualGraphRenderer; import ghidra.graph.viewer.renderer.VisualGraphRenderer;
import ghidra.graph.viewer.renderer.VisualVertexSatelliteRenderer; import ghidra.graph.viewer.renderer.VisualVertexSatelliteRenderer;
@ -36,6 +37,7 @@ public class SatelliteGraphViewer<V extends VisualVertex, E extends VisualEdge<V
protected GraphViewer<V, E> graphViewer; protected GraphViewer<V, E> graphViewer;
private boolean docked; private boolean docked;
private VisualGraphOptions options;
public SatelliteGraphViewer(GraphViewer<V, E> master, Dimension preferredSize) { public SatelliteGraphViewer(GraphViewer<V, E> master, Dimension preferredSize) {
super(master, preferredSize); super(master, preferredSize);
@ -73,6 +75,15 @@ public class SatelliteGraphViewer<V extends VisualVertex, E extends VisualEdge<V
return new VisualVertexSatelliteRenderer<>(); return new VisualVertexSatelliteRenderer<>();
} }
public void setGraphOptions(VisualGraphOptions options) {
this.options = options;
optionsChanged();
}
public void optionsChanged() {
setBackground(options.getGraphBackgroundColor());
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public VisualGraphPluggableGraphMouse<V, E> getGraphMouse() { public VisualGraphPluggableGraphMouse<V, E> getGraphMouse() {
@ -87,5 +98,4 @@ public class SatelliteGraphViewer<V extends VisualVertex, E extends VisualEdge<V
} }
super.setGraphMouse(graphMouse); super.setGraphMouse(graphMouse);
} }
} }

View file

@ -31,7 +31,6 @@ import ghidra.graph.VisualGraph;
import ghidra.graph.viewer.event.mouse.VertexTooltipProvider; import ghidra.graph.viewer.event.mouse.VertexTooltipProvider;
import ghidra.graph.viewer.event.mouse.VisualGraphMousePlugin; import ghidra.graph.viewer.event.mouse.VisualGraphMousePlugin;
import ghidra.graph.viewer.layout.LayoutProvider; import ghidra.graph.viewer.layout.LayoutProvider;
import ghidra.graph.viewer.options.VisualGraphOptions;
import ghidra.graph.viewer.vertex.VertexClickListener; import ghidra.graph.viewer.vertex.VertexClickListener;
import ghidra.graph.viewer.vertex.VertexFocusListener; import ghidra.graph.viewer.vertex.VertexFocusListener;
@ -159,6 +158,13 @@ public class VisualGraphView<V extends VisualVertex,
undockedSatelliteContentPanel.validate(); undockedSatelliteContentPanel.validate();
} }
/**
* Called when the options used by this graph view have changed
*/
public void optionsChanged() {
graphComponent.optionsChanged();
}
/** /**
* Sets the given layout provider, <b>but does not actually perform a layout</b>. * Sets the given layout provider, <b>but does not actually perform a layout</b>.
* @param newLayoutProvider the new provider * @param newLayoutProvider the new provider
@ -201,7 +207,6 @@ public class VisualGraphView<V extends VisualVertex,
protected void installGraphViewer() { protected void installGraphViewer() {
GraphComponent<V, E, G> newGraphComponent = new GraphComponent<>(graph); GraphComponent<V, E, G> newGraphComponent = new GraphComponent<>(graph);
newGraphComponent.setGraphOptions(new VisualGraphOptions());
setGraphComponent(newGraphComponent); setGraphComponent(newGraphComponent);
} }
@ -522,7 +527,7 @@ public class VisualGraphView<V extends VisualVertex,
public MouseEvent translateMouseEventFromVertexToViewSpace(V v, MouseEvent e) { public MouseEvent translateMouseEventFromVertexToViewSpace(V v, MouseEvent e) {
Point viewerPoint = translatePointFromVertexToViewSpace(v, e.getPoint()); Point viewerPoint = translatePointFromVertexToViewSpace(v, e.getPoint());
VisualizationViewer<V, E> newSource = getPrimaryGraphViewer(); VisualizationViewer<V, E> newSource = getPrimaryGraphViewer();
return new MouseEvent(newSource, e.getID(), e.getWhen(), e.getModifiers(), return new MouseEvent(newSource, e.getID(), e.getWhen(), e.getModifiersEx(),
(int) viewerPoint.getX(), (int) viewerPoint.getY(), e.getClickCount(), (int) viewerPoint.getX(), (int) viewerPoint.getY(), e.getClickCount(),
e.isPopupTrigger(), e.getButton()); e.isPopupTrigger(), e.getButton());
} }

View file

@ -15,10 +15,16 @@
*/ */
package ghidra.graph.viewer.options; package ghidra.graph.viewer.options;
import java.awt.Color;
import docking.DockingUtils; import docking.DockingUtils;
public class VisualGraphOptions { public class VisualGraphOptions {
public static final String GRAPH_BACKGROUND_COLOR_KEY = "Graph Background Color";
public static final String GRAPH_BACKGROUND_COLOR_DESCRPTION =
"The graph display background color";
public static final String SHOW_ANIMATION_OPTIONS_KEY = "Use Animation"; public static final String SHOW_ANIMATION_OPTIONS_KEY = "Use Animation";
public static final String SHOW_ANIMATION_DESCRIPTION = "Signals to the Function Graph to " + public static final String SHOW_ANIMATION_DESCRIPTION = "Signals to the Function Graph to " +
"use animated transitions for certain operations, like navigation."; "use animated transitions for certain operations, like navigation.";
@ -48,6 +54,9 @@ public class VisualGraphOptions {
"new graphs and already rendered graphs are zoomed and positioned. See the help for " + "new graphs and already rendered graphs are zoomed and positioned. See the help for " +
"more details."; "more details.";
public static final Color DEFAULT_GRAPH_BACKGROUND_COLOR = Color.WHITE;
protected Color graphBackgroundColor = DEFAULT_GRAPH_BACKGROUND_COLOR;
protected boolean useAnimation = true; protected boolean useAnimation = true;
protected boolean scrollWheelPans = false; protected boolean scrollWheelPans = false;
@ -59,6 +68,10 @@ public class VisualGraphOptions {
protected ViewRestoreOption viewRestoreOption = ViewRestoreOption.START_FULLY_ZOOMED_OUT; protected ViewRestoreOption viewRestoreOption = ViewRestoreOption.START_FULLY_ZOOMED_OUT;
public Color getGraphBackgroundColor() {
return graphBackgroundColor;
}
public boolean getScrollWheelPans() { public boolean getScrollWheelPans() {
return scrollWheelPans; return scrollWheelPans;
} }

View file

@ -151,7 +151,6 @@ public class TestGraphAlgorithmSteppingViewerPanel<V, E extends GEdge<V>> extend
tvg.setLayout(layout); tvg.setLayout(layout);
viewer = new GraphViewer<>(layout, new Dimension(400, 400)); viewer = new GraphViewer<>(layout, new Dimension(400, 400));
viewer.setBackground(Color.WHITE);
viewer.setGraphOptions(new VisualGraphOptions()); viewer.setGraphOptions(new VisualGraphOptions());
Renderer<AlgorithmTestSteppingVertex<V>, AlgorithmTestSteppingEdge<V>> renderer = Renderer<AlgorithmTestSteppingVertex<V>, AlgorithmTestSteppingEdge<V>> renderer =