mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-28 23:55:45 +08:00
GP-5084 Adding ability to choose which corner the function graph satellite appears in.
This commit is contained in:
+9
@@ -137,6 +137,15 @@
|
|||||||
hand corner of the graph and is only visible if the Satellite View is hidden or
|
hand corner of the graph and is only visible if the Satellite View is hidden or
|
||||||
undocked.</P>
|
undocked.</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
<H3><A name="Satellite_Location"></A>Docked Satellite Location</H3>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>When the Satellite View is attached, or <B>docked</B>, to the Primary View, you
|
||||||
|
can choose which corner to show the satellite view. To change the
|
||||||
|
corner, right-click in the graph, select <B>Docked Satellite Position</B> and then
|
||||||
|
select the appropriate sub-menu for the desired corner.<P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<H2><A name="Vertices"></A>Vertices (Blocks)</H2>
|
<H2><A name="Vertices"></A>Vertices (Blocks)</H2>
|
||||||
|
|||||||
+8
@@ -266,6 +266,14 @@
|
|||||||
hand corner of the graph and is only visible if the Satellite View is hidden or
|
hand corner of the graph and is only visible if the Satellite View is hidden or
|
||||||
undocked.</P>
|
undocked.</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<H3><A name="Satellite_Location"></A>Docked Satellite Location</H3>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>When the Satellite View is attached, or <B>docked</B>, to the Primary View, you
|
||||||
|
can choose which corner to show the satellite view. To change the
|
||||||
|
corner, right-click in the graph, select <B>Docked Satellite Position</B> and then
|
||||||
|
select the appropriate sub-menu for the desired corner.<P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<H2><A name="Options"></A>Options</H2>
|
<H2><A name="Options"></A>Options</H2>
|
||||||
|
|||||||
+88
-3
@@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.graph.featurette;
|
package ghidra.graph.featurette;
|
||||||
|
|
||||||
|
import static ghidra.graph.viewer.GraphComponent.SatellitePosition.*;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
|
||||||
@@ -29,6 +31,7 @@ import ghidra.framework.options.SaveState;
|
|||||||
import ghidra.graph.VisualGraph;
|
import ghidra.graph.VisualGraph;
|
||||||
import ghidra.graph.VisualGraphComponentProvider;
|
import ghidra.graph.VisualGraphComponentProvider;
|
||||||
import ghidra.graph.viewer.*;
|
import ghidra.graph.viewer.*;
|
||||||
|
import ghidra.graph.viewer.GraphComponent.SatellitePosition;
|
||||||
import ghidra.graph.viewer.actions.*;
|
import ghidra.graph.viewer.actions.*;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
|
||||||
@@ -56,9 +59,14 @@ public class VgSatelliteFeaturette<V extends VisualVertex,
|
|||||||
|
|
||||||
private static final String DISPLAY_SATELLITE = "DISPLAY_SATELLITE";
|
private static final String DISPLAY_SATELLITE = "DISPLAY_SATELLITE";
|
||||||
private static final String DOCK_SATELLITE = "DOCK_SATELLITE";
|
private static final String DOCK_SATELLITE = "DOCK_SATELLITE";
|
||||||
|
private static final String DOCK_SATELLITE_POSITION = "DOCK_SATELLITE_POSITION";
|
||||||
|
|
||||||
private ToggleDockingAction toggleSatelliteAction;
|
private ToggleDockingAction toggleSatelliteAction;
|
||||||
private ToggleDockingAction dockSatelliteAction;
|
private ToggleDockingAction dockSatelliteAction;
|
||||||
|
private ToggleDockingAction upperLeftAction;
|
||||||
|
private ToggleDockingAction upperRightAction;
|
||||||
|
private ToggleDockingAction lowerLeftAction;
|
||||||
|
private ToggleDockingAction lowerRightAction;
|
||||||
|
|
||||||
private Tool tool;
|
private Tool tool;
|
||||||
private VisualGraphView<?, ?, ?> view;
|
private VisualGraphView<?, ?, ?> view;
|
||||||
@@ -75,6 +83,7 @@ public class VgSatelliteFeaturette<V extends VisualVertex,
|
|||||||
public void writeConfigState(SaveState saveState) {
|
public void writeConfigState(SaveState saveState) {
|
||||||
saveState.putBoolean(DOCK_SATELLITE, dockSatelliteAction.isSelected());
|
saveState.putBoolean(DOCK_SATELLITE, dockSatelliteAction.isSelected());
|
||||||
saveState.putBoolean(DISPLAY_SATELLITE, toggleSatelliteAction.isSelected());
|
saveState.putBoolean(DISPLAY_SATELLITE, toggleSatelliteAction.isSelected());
|
||||||
|
saveState.putString(DOCK_SATELLITE_POSITION, view.getSatellitePosition().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -90,6 +99,25 @@ public class VgSatelliteFeaturette<V extends VisualVertex,
|
|||||||
boolean showSatellite = saveState.getBoolean(DISPLAY_SATELLITE, true);
|
boolean showSatellite = saveState.getBoolean(DISPLAY_SATELLITE, true);
|
||||||
toggleSatelliteAction.setSelected(showSatellite);
|
toggleSatelliteAction.setSelected(showSatellite);
|
||||||
view.setSatelliteVisible(showSatellite);
|
view.setSatelliteVisible(showSatellite);
|
||||||
|
|
||||||
|
String positionString = saveState.getString(DOCK_SATELLITE_POSITION, LOWER_RIGHT.name());
|
||||||
|
SatellitePosition position = SatellitePosition.valueOf(positionString);
|
||||||
|
view.setSatellitePosition(position);
|
||||||
|
deselectAllSatellitePositions();
|
||||||
|
switch (position) {
|
||||||
|
case LOWER_LEFT:
|
||||||
|
lowerLeftAction.setSelected(true);
|
||||||
|
break;
|
||||||
|
case LOWER_RIGHT:
|
||||||
|
lowerRightAction.setSelected(true);
|
||||||
|
break;
|
||||||
|
case UPPER_LEFT:
|
||||||
|
upperLeftAction.setSelected(true);
|
||||||
|
break;
|
||||||
|
case UPPER_RIGHT:
|
||||||
|
upperRightAction.setSelected(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -185,9 +213,20 @@ public class VgSatelliteFeaturette<V extends VisualVertex,
|
|||||||
dockSatelliteAction.setHelpLocation(
|
dockSatelliteAction.setHelpLocation(
|
||||||
new HelpLocation("FunctionCallGraphPlugin", "Satellite_View"));
|
new HelpLocation("FunctionCallGraphPlugin", "Satellite_View"));
|
||||||
|
|
||||||
// Note: this is not a local action, since it should appear in satellite and the main view
|
upperLeftAction = new SatellitePositionAction("Upper Left", UPPER_LEFT, provider);
|
||||||
|
upperRightAction = new SatellitePositionAction("Upper Right", UPPER_RIGHT, provider);
|
||||||
|
lowerLeftAction = new SatellitePositionAction("Lower Left", LOWER_LEFT, provider);
|
||||||
|
lowerRightAction = new SatellitePositionAction("Lower Right", LOWER_RIGHT, provider);
|
||||||
|
lowerRightAction.setSelected(true);
|
||||||
|
|
||||||
|
// Note: these are not local actions, since they should appear in satellite and the main view
|
||||||
tool.addAction(toggleSatelliteAction);
|
tool.addAction(toggleSatelliteAction);
|
||||||
tool.addAction(dockSatelliteAction);
|
tool.addAction(dockSatelliteAction);
|
||||||
|
tool.addAction(upperLeftAction);
|
||||||
|
tool.addAction(upperRightAction);
|
||||||
|
tool.addAction(lowerLeftAction);
|
||||||
|
tool.addAction(lowerRightAction);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -197,6 +236,13 @@ public class VgSatelliteFeaturette<V extends VisualVertex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deselectAllSatellitePositions() {
|
||||||
|
upperLeftAction.setSelected(false);
|
||||||
|
upperRightAction.setSelected(false);
|
||||||
|
lowerLeftAction.setSelected(false);
|
||||||
|
lowerRightAction.setSelected(false);
|
||||||
|
}
|
||||||
|
|
||||||
// only remove the provider if the user had docked the satellite
|
// only remove the provider if the user had docked the satellite
|
||||||
private void closeSatelliteProvider(boolean remove) {
|
private void closeSatelliteProvider(boolean remove) {
|
||||||
if (satelliteProvider == null) {
|
if (satelliteProvider == null) {
|
||||||
@@ -299,4 +345,43 @@ public class VgSatelliteFeaturette<V extends VisualVertex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class SatellitePositionAction extends ToggleDockingAction {
|
||||||
|
|
||||||
|
private SatellitePosition position;
|
||||||
|
private ComponentProvider provider;
|
||||||
|
|
||||||
|
public SatellitePositionAction(String name, SatellitePosition posiiton,
|
||||||
|
ComponentProvider provider) {
|
||||||
|
super(name, owner);
|
||||||
|
this.position = posiiton;
|
||||||
|
this.provider = provider;
|
||||||
|
setPopupMenuData(new MenuData(new String[] { "Docked Satellite Position", name }));
|
||||||
|
setHelpLocation(new HelpLocation("FunctionCallGraphPlugin", "Satellite_Location"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionContext context) {
|
||||||
|
deselectAllSatellitePositions();
|
||||||
|
setSelected(true);
|
||||||
|
view.setSatellitePosition(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAddToPopup(ActionContext context) {
|
||||||
|
ComponentProvider componentProvider = context.getComponentProvider();
|
||||||
|
if (componentProvider != provider && componentProvider != satelliteProvider) {
|
||||||
|
// appear in satellite and the main provider
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context instanceof VisualGraphActionContext vgContext) {
|
||||||
|
return vgContext.shouldShowSatelliteActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ import util.CollectionUtils;
|
|||||||
* @see GraphViewer
|
* @see GraphViewer
|
||||||
*/
|
*/
|
||||||
public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G extends VisualGraph<V, E>> {
|
public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G extends VisualGraph<V, E>> {
|
||||||
|
public enum SatellitePosition {
|
||||||
|
UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, LOWER_RIGHT
|
||||||
|
}
|
||||||
|
|
||||||
private static final double PARENT_TO_SATELLITE_RATIO = 4;// 2.5 smaller view seems better
|
private static final double PARENT_TO_SATELLITE_RATIO = 4;// 2.5 smaller view seems better
|
||||||
private static final int MINIMUM_SATELLITE_WIDTH = 150;
|
private static final int MINIMUM_SATELLITE_WIDTH = 150;
|
||||||
@@ -130,6 +133,7 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
|
|||||||
private Dimension lastSize;
|
private Dimension lastSize;
|
||||||
|
|
||||||
protected VisualGraphOptions vgOptions = new VisualGraphOptions();
|
protected VisualGraphOptions vgOptions = new VisualGraphOptions();
|
||||||
|
private SatellitePosition dockedSatellitePosition = SatellitePosition.UPPER_RIGHT;
|
||||||
|
|
||||||
public GraphComponent(G graph) {
|
public GraphComponent(G graph) {
|
||||||
|
|
||||||
@@ -782,6 +786,15 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
|
|||||||
updateSatellite(docked, true);
|
updateSatellite(docked, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SatellitePosition getSatellitePosition() {
|
||||||
|
return dockedSatellitePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSatellitePosition(SatellitePosition position) {
|
||||||
|
dockedSatellitePosition = position;
|
||||||
|
updateSatellite(satelliteViewer.isDocked(), isSatelliteShowing());
|
||||||
|
}
|
||||||
|
|
||||||
public void setSatelliteVisible(boolean visible) {
|
public void setSatelliteVisible(boolean visible) {
|
||||||
|
|
||||||
if (isSatelliteShowing() == visible) {
|
if (isSatelliteShowing() == visible) {
|
||||||
@@ -823,9 +836,8 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
|
|||||||
staleGraphViewPanel.setBounds(x, y, stalePanelSize.width, stalePanelSize.height);
|
staleGraphViewPanel.setBounds(x, y, stalePanelSize.width, stalePanelSize.height);
|
||||||
|
|
||||||
Dimension buttonSize = showUndockedSatelliteButton.getPreferredSize();
|
Dimension buttonSize = showUndockedSatelliteButton.getPreferredSize();
|
||||||
x = parentSize.width - buttonSize.width;
|
Point p = getSatellitePosition(parentSize, buttonSize);
|
||||||
y = parentSize.height - buttonSize.height;
|
showUndockedSatelliteButton.setBounds(p.x, p.y, buttonSize.width, buttonSize.height);
|
||||||
showUndockedSatelliteButton.setBounds(x, y, buttonSize.width, buttonSize.height);
|
|
||||||
|
|
||||||
lastSize = new Dimension(parentSize.width, parentSize.height);
|
lastSize = new Dimension(parentSize.width, parentSize.height);
|
||||||
}
|
}
|
||||||
@@ -843,15 +855,30 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
|
|||||||
int newWidth = getNewBoundsSize(parentSize, satelliteSize);
|
int newWidth = getNewBoundsSize(parentSize, satelliteSize);
|
||||||
satelliteSize.width = newWidth;
|
satelliteSize.width = newWidth;
|
||||||
satelliteSize.height = newWidth;
|
satelliteSize.height = newWidth;
|
||||||
int x = parentSize.width - satelliteSize.width;
|
Point p = getSatellitePosition(parentSize, satelliteSize);
|
||||||
int y = parentSize.height - satelliteSize.height;
|
satelliteViewer.setBounds(p.x, p.y, satelliteSize.width, satelliteSize.height);
|
||||||
satelliteViewer.setBounds(x, y, satelliteSize.width, satelliteSize.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VisualGraphViewUpdater<V, E> viewUpdater = getViewUpdater();
|
VisualGraphViewUpdater<V, E> viewUpdater = getViewUpdater();
|
||||||
viewUpdater.fitGraphToViewerNow(satelliteViewer);
|
viewUpdater.fitGraphToViewerNow(satelliteViewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Point getSatellitePosition(Dimension parentSize, Dimension satelliteSize) {
|
||||||
|
int x = parentSize.width - satelliteSize.width;
|
||||||
|
int y = parentSize.height - satelliteSize.height;
|
||||||
|
switch (dockedSatellitePosition) {
|
||||||
|
case LOWER_LEFT:
|
||||||
|
return new Point(0, y);
|
||||||
|
case UPPER_LEFT:
|
||||||
|
return new Point(0, 0);
|
||||||
|
case UPPER_RIGHT:
|
||||||
|
return new Point(x, 0);
|
||||||
|
case LOWER_RIGHT:
|
||||||
|
default:
|
||||||
|
return new Point(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int getNewBoundsSize(Dimension parentBounds, Dimension satelliteBounds) {
|
private int getNewBoundsSize(Dimension parentBounds, Dimension satelliteBounds) {
|
||||||
double newSatelliteHeight = parentBounds.height / PARENT_TO_SATELLITE_RATIO;
|
double newSatelliteHeight = parentBounds.height / PARENT_TO_SATELLITE_RATIO;
|
||||||
double newSatelliteWidth = parentBounds.width / PARENT_TO_SATELLITE_RATIO;
|
double newSatelliteWidth = parentBounds.width / PARENT_TO_SATELLITE_RATIO;
|
||||||
@@ -1259,4 +1286,5 @@ public class GraphComponent<V extends VisualVertex, E extends VisualEdge<V>, G e
|
|||||||
// stub
|
// stub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -29,6 +29,7 @@ import edu.uci.ics.jung.visualization.VisualizationViewer;
|
|||||||
import edu.uci.ics.jung.visualization.control.ScalingControl;
|
import edu.uci.ics.jung.visualization.control.ScalingControl;
|
||||||
import generic.theme.Gui;
|
import generic.theme.Gui;
|
||||||
import ghidra.graph.VisualGraph;
|
import ghidra.graph.VisualGraph;
|
||||||
|
import ghidra.graph.viewer.GraphComponent.SatellitePosition;
|
||||||
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;
|
||||||
@@ -124,6 +125,7 @@ public class VisualGraphView<V extends VisualVertex,
|
|||||||
|
|
||||||
protected LayoutProvider<V, E, G> layoutProvider;
|
protected LayoutProvider<V, E, G> layoutProvider;
|
||||||
private final ScalingControl scaler = new VisualGraphScalingControl();
|
private final ScalingControl scaler = new VisualGraphScalingControl();
|
||||||
|
private SatellitePosition satellitePosition = SatellitePosition.LOWER_RIGHT;
|
||||||
|
|
||||||
public VisualGraphView() {
|
public VisualGraphView() {
|
||||||
build();
|
build();
|
||||||
@@ -263,6 +265,7 @@ public class VisualGraphView<V extends VisualVertex,
|
|||||||
undockedSatelliteContentPanel.add(graphComponent.getSatelliteContentComponent());
|
undockedSatelliteContentPanel.add(graphComponent.getSatelliteContentComponent());
|
||||||
undockedSatelliteContentPanel.validate();
|
undockedSatelliteContentPanel.validate();
|
||||||
}
|
}
|
||||||
|
graphComponent.setSatellitePosition(satellitePosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -421,6 +424,17 @@ public class VisualGraphView<V extends VisualVertex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSatellitePosition(SatellitePosition position) {
|
||||||
|
satellitePosition = position;
|
||||||
|
if (graphComponent != null) {
|
||||||
|
graphComponent.setSatellitePosition(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SatellitePosition getSatellitePosition() {
|
||||||
|
return satellitePosition;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the satellite intended to be docked. If this component is built, then
|
* Returns whether the satellite intended to be docked. If this component is built, then
|
||||||
* a result of true means that the satellite is docked. If the component is not yet
|
* a result of true means that the satellite is docked. If the component is not yet
|
||||||
|
|||||||
Reference in New Issue
Block a user