GP-6189 - Byte Viewer - Updated cursor colors

This commit is contained in:
dragonmacher
2025-12-23 19:35:20 -05:00
parent f9cee4d639
commit 8d7bd95d89
13 changed files with 234 additions and 318 deletions
@@ -6,9 +6,12 @@ color.bg.byteviewer.highlight.middle.mouse = color.bg.highlight
color.fg.byteviewer.separator = color.palette.blue color.fg.byteviewer.separator = color.palette.blue
color.fg.byteviewer.changed = red color.fg.byteviewer.changed = red
color.cursor.byteviewer.focused.active = color.cursor.focused
color.cursor.byteviewer.focused.not.active = black color.cursor.byteviewer.focused.edit = color.palette.red
color.cursor.byteviewer.unfocused = color.cursor.unfocused color.cursor.byteviewer.unfocused.edit = color.palette.pink
color.cursor.byteviewer.focused.non.edit = color.palette.black
color.cursor.byteviewer.unfocused.non.edit = color.palette.silver
icon.plugin.byteviewer.provider = binaryData.gif icon.plugin.byteviewer.provider = binaryData.gif
icon.plugin.byteviewer.options = wrench.png icon.plugin.byteviewer.options = wrench.png
@@ -20,5 +23,8 @@ font.byteviewer.status = SansSerif-PLAIN-11
color.bg.byteviewer.highlight = rgb(191, 191, 64) // olive color.bg.byteviewer.highlight = rgb(191, 191, 64) // olive
color.fg.byteviewer.changed = indianRed color.fg.byteviewer.changed = indianRed
color.cursor.byteviewer.focused.not.active = gray
color.cursor.byteviewer.focused.edit = #FF6666
color.cursor.byteviewer.unfocused.edit = #9900FF
color.cursor.byteviewer.focused.non.edit = color.palette.white
color.cursor.byteviewer.unfocused.non.edit = #97BCE2
@@ -25,45 +25,44 @@
<table border="1" width="82%"> <table border="1" width="82%">
<tbody> <tbody>
<tr> <tr>
<td width="31%"> Block Separator Color</td> <td width="40%" valign="top"> Block Separator Color</td>
<td width="69%"> Used to render gaps in memory, i.e., separators between memory blocks</td> <td width="60%"> Used to render gaps in memory, i.e., separators between memory blocks</td>
</tr> </tr>
<tr>
<td width="31%"> Current View Cursor Color</td>
<td width="69%"> Used in the view that has focus</td>
</tr>
<tr>
<td width="31%"> Cursor Color</td>
<td width="69%"> Used in the views that do not have focus</td>
</tr>
<tr>
<td width="31%"> Edit Cursor Color<a name="EditColor"></a></td>
<td width="69%"> Used to indicate changed bytes in memory; this color is
used as the cursor color in those views that support editing</td>
</tr>
<tr>
<td width="31%"> Font</td>
<td width="69%"> Font specified for all views</td>
</tr>
<tr>
<td width="31%"> Highlight Cursor Line</td>
<td width="69%"> Highlights the line containing the cursor</td>
</tr>
<tr>
<td width="31%"> Highlight Cursor Line Color</td>
<td width="69%"> The color of the highlight for the line containing the cursor</td>
</tr>
<tr>
<td width="31%"> Non-Focus Cursor Color</td>
<td width="69%"> The cursor color when the Byte Viewer is not focuses</td>
</tr>
<tr> <tr>
<td width="31%"> Middle-Mouse Color</td> <td width="40%" valign="top"> Edit Text Color<a name="EditColor"></a></td>
<td width="69%"> The color when the user middle-mouses in the Byte Viewer</td> <td width="60%"> Used to indicate changed bytes in memory.</td>
</tr>
<tr>
<td width="40%" valign="top"> Cursor Color Focused</td>
<td width="60%"> Used in the view that has focus</td>
</tr>
<tr>
<td width="40%" valign="top"> Cursor Color Unfocused</td>
<td width="60%"> Used in the views that do not have focus</td>
</tr>
<tr>
<td width="40%" valign="top"> Cursor Color Focused Edit</td>
<td width="60%"> Used in the view that has focus when in edit mode</td>
</tr>
<tr>
<td width="40%" valign="top"> Cursor Color Unfocused Edit</td>
<td width="60%"> Used in the views that do not have focus when in edit mode</td>
</tr>
<tr>
<td width="40%" valign="top"> Font</td>
<td width="60%"> Font specified for all views</td>
</tr>
<tr>
<td width="40%" valign="top"> Highlight Cursor Line</td>
<td width="60%"> Highlights the line containing the cursor</td>
</tr>
<tr>
<td width="40%" valign="top"> Highlight Cursor Line Color</td>
<td width="60%"> The color of the highlight for the line containing the cursor</td>
</tr>
<tr>
<td width="40%" valign="top"> Middle-Mouse Color</td>
<td width="60%"> The color when the user middle-mouses in the Byte Viewer</td>
</tr> </tr>
</tbody> </tbody>
@@ -103,7 +103,7 @@
<font color="#ff0000"> red</font> to denote the change.</p> <font color="#ff0000"> red</font> to denote the change.</p>
</blockquote> </blockquote>
<h3><a name="Add_Byteviewer_HexLong_Panel"></a><a name="HexLongr"></a>Hex Long</h3> <h3><a name="Add_Byteviewer_HexLong_Panel"></a><a name="HexLong"></a>Hex Long</h3>
<blockquote> <blockquote>
<p>This format shows eight-byte numbers represented as an 16-digit hex number.&nbsp;</p> <p>This format shows eight-byte numbers represented as an 16-digit hex number.&nbsp;</p>
<p> This view supports <a href="#EditBytes">editing</a>. When a byte <p> This view supports <a href="#EditBytes">editing</a>. When a byte
@@ -219,11 +219,11 @@
<h2>Cursor Colors</h2> <h2>Cursor Colors</h2>
<blockquote> <blockquote>
<p>The format view that currently has focus shows its cursor in <font <p>The format view that currently has focus shows its cursor in <font
color="#ff00ff">magenta</font>. (Cursor colors can be changed via the <a color="#000000"><B>black</B></font>. (Cursor colors can be changed via the <a
href="ByteViewerOptions.htm#EditColorsAndFont">Options</a> dialog) If href="ByteViewerOptions.htm#EditColorsAndFont">Options</a> dialog) If
the byte editing is enabled and the view that is in focus supports the byte editing is enabled and the view that is in focus supports
editing, editing,
then the cursor is <font color="#ff0000">red</font>.&nbsp;</p> then the cursor is <font color="#ff0000"><B>red</B></font>.&nbsp;</p>
</blockquote> </blockquote>
<br> <br>
@@ -20,8 +20,6 @@ import java.awt.FontMetrics;
import java.awt.event.*; import java.awt.event.*;
import java.math.BigInteger; import java.math.BigInteger;
import javax.swing.SwingUtilities;
import docking.DockingUtils; import docking.DockingUtils;
import docking.widgets.EventTrigger; import docking.widgets.EventTrigger;
import docking.widgets.fieldpanel.FieldPanel; import docking.widgets.fieldpanel.FieldPanel;
@@ -33,6 +31,7 @@ import generic.theme.GColor;
import ghidra.app.plugin.core.format.*; import ghidra.app.plugin.core.format.*;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.Swing;
import help.Help; import help.Help;
import help.HelpService; import help.HelpService;
@@ -52,11 +51,17 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
private ProgramByteBlockSet blockSet; private ProgramByteBlockSet blockSet;
private boolean consumeKeyStrokes; private boolean consumeKeyStrokes;
private boolean editMode; // true if this component is in edit mode; private boolean editMode; // true if this component is in edit mode; cursor is different color.
// cursor is different color.
private Color editColor; //@formatter:off
private Color currentCursorColor; private Color editedTextColor = ByteViewerComponentProvider.EDITED_TEXT_COLOR;
private Color currentCursorLineColor; private Color focusedEditCursorColor = ByteViewerComponentProvider.CURSOR_COLOR_FOCUSED_EDIT;
private Color unfocusedEditCursorColor = ByteViewerComponentProvider.CURSOR_COLOR_UNFOCUSED_EDIT;
private Color focusedNonEditCursorColor = ByteViewerComponentProvider.CURSOR_COLOR_FOCUSED_NON_EDIT;
private Color unfocusedNonEditCursorColor = ByteViewerComponentProvider.CURSOR_COLOR_UNFOCUSED_NON_EDIT;
private Color currentCursorLineColor = ByteViewerComponentProvider.CURRENT_LINE_COLOR;
//@formatter:on
private ByteViewerLayoutModel layoutModel; private ByteViewerLayoutModel layoutModel;
private boolean doingRefresh; private boolean doingRefresh;
private boolean doingEdit; private boolean doingEdit;
@@ -151,9 +156,6 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
} }
} }
/**
* Called from the parent FieldPanel whenever the cursor position changes.
*/
@Override @Override
public void fieldLocationChanged(FieldLocation loc, Field field, EventTrigger trigger) { public void fieldLocationChanged(FieldLocation loc, Field field, EventTrigger trigger) {
fieldLocationChanged(loc, field, false, trigger == EventTrigger.GUI_ACTION); fieldLocationChanged(loc, field, false, trigger == EventTrigger.GUI_ACTION);
@@ -174,10 +176,10 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
//Set this component as the current view in the panel //Set this component as the current view in the panel
panel.setCurrentView(ByteViewerComponent.this); panel.setCurrentView(ByteViewerComponent.this);
} }
// do the color update later because the field panel
// listener is called after this one, and sets the // Update later because the field panel listener is called after this one, and sets the
// colors incorrectly // colors incorrectly
SwingUtilities.invokeLater(updateColorRunner); Swing.runLater(updateColorRunner);
lastFieldLoc = loc; lastFieldLoc = loc;
@@ -308,7 +310,7 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
getToolkit().beep(); getToolkit().beep();
} }
} }
catch (ByteBlockAccessException exc) { catch (ByteBlockAccessException | NumberFormatException exc) {
panel.setStatusMessage("Editing not allowed: " + exc.getMessage()); panel.setStatusMessage("Editing not allowed: " + exc.getMessage());
getToolkit().beep(); getToolkit().beep();
@@ -358,19 +360,6 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
layoutModel.setIndexMap(indexMap); layoutModel.setIndexMap(indexMap);
} }
/**
* Set the color used to denote changes in the byte block.
* @param c the color for unsaved changed byte values
*/
void setEditColor(Color c) {
editColor = c;
for (FieldFactory fieldFactorie : fieldFactories) {
fieldFactorie.setEditColor(c);
}
layoutModel.layoutChanged();
updateColor();
}
void setHighlightButton(int highlightButton) { void setHighlightButton(int highlightButton) {
this.highlightButton = highlightButton; this.highlightButton = highlightButton;
} }
@@ -379,25 +368,6 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
highlightProvider.setHighlightColor(color); highlightProvider.setHighlightColor(color);
} }
/**
* Set the color for the component that has focus.
*
* @param c the color to set
*/
void setCurrentCursorColor(Color c) {
currentCursorColor = c;
updateColor();
}
/**
* Set the background color for the line containing the cursor.
*
* @param c the color to set
*/
void setCurrentCursorLineColor(Color c) {
currentCursorLineColor = c;
}
/** /**
* Set the color for showing gaps in indexes. * Set the color for showing gaps in indexes.
* *
@@ -414,8 +384,8 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
* Get the color of unsaved byte changes * Get the color of unsaved byte changes
* @return the color of unsaved byte changes * @return the color of unsaved byte changes
*/ */
Color getEditColor() { Color getEditedTextColor() {
return editColor; return editedTextColor;
} }
void setIndexMap(IndexMap map) { void setIndexMap(IndexMap map) {
@@ -677,20 +647,26 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
return; return;
} }
this.editMode = editMode; this.editMode = editMode;
updateColor(); updateFocusedColor();
udpateNonFocusedColor();
} }
private void updateColor() { private void updateFocusedColor() {
if (panel.getCurrentComponent() == this) { if (panel.getCurrentComponent() == this) {
if (editMode) { if (editMode) {
setFocusedCursorColor(editColor); setFocusedCursorColor(focusedEditCursorColor);
} }
else { else {
setFocusedCursorColor(currentCursorColor); setFocusedCursorColor(focusedNonEditCursorColor);
} }
} }
} }
private void udpateNonFocusedColor() {
Color c = editMode ? unfocusedEditCursorColor : unfocusedNonEditCursorColor;
setNonFocusCursorColor(c);
}
boolean getEditMode() { boolean getEditMode() {
return editMode; return editMode;
} }
@@ -735,12 +711,12 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
createFields(); createFields();
setCursorOn(true); setCursorOn(true);
editColor = ByteViewerComponentProvider.CHANGED_VALUE_COLOR; editedTextColor = ByteViewerComponentProvider.EDITED_TEXT_COLOR;
currentCursorColor = ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR;
setNonFocusCursorColor(ByteViewerComponentProvider.CURSOR_NOT_FOCUSED_COLOR);
setFocusedCursorColor(currentCursorColor);
updateColorRunner = () -> updateColor(); setNonFocusCursorColor(ByteViewerComponentProvider.CURSOR_COLOR_UNFOCUSED_NON_EDIT);
setFocusedCursorColor(ByteViewerComponentProvider.CURSOR_COLOR_FOCUSED_NON_EDIT);
updateColorRunner = () -> updateFocusedColor();
addMouseListener(new MouseAdapter() { addMouseListener(new MouseAdapter() {
@Override @Override
@@ -779,7 +755,7 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
fieldFactories[i] = fieldFactories[i] =
new FieldFactory(model, bytesPerLine, fieldOffset, fm, highlightProvider); new FieldFactory(model, bytesPerLine, fieldOffset, fm, highlightProvider);
fieldOffset += model.getUnitByteSize(); fieldOffset += model.getUnitByteSize();
fieldFactories[i].setEditColor(editColor); fieldFactories[i].setEditColor(editedTextColor);
fieldFactories[i].setIndexMap(indexMap); fieldFactories[i].setIndexMap(indexMap);
} }
layoutModel.setFactorys(fieldFactories, model, charWidth); layoutModel.setFactorys(fieldFactories, model, charWidth);
@@ -979,4 +955,5 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
} }
} }
} }
@@ -25,7 +25,8 @@ import java.util.List;
import javax.swing.JComponent; import javax.swing.JComponent;
import docking.action.ToggleDockingAction; import docking.action.ToggleDockingAction;
import generic.theme.*; import generic.theme.GColor;
import generic.theme.GIcon;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.GhidraOptions.CURSOR_MOUSE_BUTTON_NAMES; import ghidra.GhidraOptions.CURSOR_MOUSE_BUTTON_NAMES;
import ghidra.app.plugin.core.format.*; import ghidra.app.plugin.core.format.*;
@@ -63,10 +64,12 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
static final String CURSOR = "byteviewer.color.cursor"; static final String CURSOR = "byteviewer.color.cursor";
static final GColor SEPARATOR_COLOR = new GColor("color.fg.byteviewer.separator"); static final GColor SEPARATOR_COLOR = new GColor("color.fg.byteviewer.separator");
static final GColor CHANGED_VALUE_COLOR = new GColor("color.fg.byteviewer.changed");
static final GColor CURSOR_ACTIVE_COLOR = new GColor("color.cursor.byteviewer.focused.active"); static final GColor EDITED_TEXT_COLOR = new GColor("color.fg.byteviewer.changed");
static final GColor CURSOR_NON_ACTIVE_COLOR = new GColor("color.cursor.byteviewer.focused.not.active"); static final GColor CURSOR_COLOR_FOCUSED_EDIT = new GColor("color.cursor.byteviewer.focused.edit");
static final GColor CURSOR_NOT_FOCUSED_COLOR = new GColor("color.cursor.byteviewer.unfocused"); static final GColor CURSOR_COLOR_UNFOCUSED_EDIT = new GColor("color.cursor.byteviewer.unfocused.edit");
static final GColor CURSOR_COLOR_FOCUSED_NON_EDIT = new GColor("color.cursor.byteviewer.focused.non.edit");
static final GColor CURSOR_COLOR_UNFOCUSED_NON_EDIT = new GColor("color.cursor.byteviewer.unfocused.non.edit");
static final GColor CURRENT_LINE_COLOR = GhidraOptions.DEFAULT_CURSOR_LINE_COLOR; static final GColor CURRENT_LINE_COLOR = GhidraOptions.DEFAULT_CURSOR_LINE_COLOR;
//@formatter:on //@formatter:on
@@ -74,10 +77,11 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
static final String INDEX_COLUMN_NAME = "Addresses"; static final String INDEX_COLUMN_NAME = "Addresses";
static final String SEPARATOR_COLOR_OPTION_NAME = "Block Separator Color"; static final String SEPARATOR_COLOR_OPTION_NAME = "Block Separator Color";
static final String CHANGED_VALUE_COLOR_OPTION_NAME = "Changed Values Color"; static final String EDIT_TEXT_COLOR_OPTION_NAME = "Edited Text Color";
static final String CURSOR_ACTIVE_COLOR_OPTION_NAME = "Active Cursor Color"; static final String CURSOR_FOCUSED_COLOR_OPTION_NAME = "Cursor Color Focused";
static final String CURSOR_NON_ACTIVE_COLOR_OPTION_NAME = "Non-Active Cursor Color"; static final String CURSOR_UNFOCUSED_COLOR_OPTION_NAME = "Cursor Color Unfocused";
static final String CURSOR_NOT_FOCUSED_COLOR_OPTION_NAME = "Non-Focused Cursor Color"; static final String CURSOR_FOCUSED_EDIT_COLOR_OPTION_NAME = "Cursor Color Focused Edit";
static final String CURSOR_UNFOCUSED_EDIT_COLOR_OPTION_NAME = "Cursor Color Unfocused Edit";
static final String OPTION_FONT = "Font"; static final String OPTION_FONT = "Font";
@@ -185,9 +189,6 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
CURSOR_MOUSE_BUTTON_NAMES mouseButton = (CURSOR_MOUSE_BUTTON_NAMES) newValue; CURSOR_MOUSE_BUTTON_NAMES mouseButton = (CURSOR_MOUSE_BUTTON_NAMES) newValue;
panel.setHighlightButton(mouseButton.getMouseEventID()); panel.setHighlightButton(mouseButton.getMouseEventID());
} }
else if (optionName.equals(OPTION_HIGHLIGHT_MIDDLE_MOUSE_NAME)) {
panel.setMouseButtonHighlightColor((Color) newValue);
}
} }
} }
@@ -206,19 +207,25 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
opt.registerThemeColorBinding(SEPARATOR_COLOR_OPTION_NAME, SEPARATOR_COLOR.getId(), help, opt.registerThemeColorBinding(SEPARATOR_COLOR_OPTION_NAME, SEPARATOR_COLOR.getId(), help,
"Color used for separator shown between memory blocks."); "Color used for separator shown between memory blocks.");
opt.registerThemeColorBinding(CHANGED_VALUE_COLOR_OPTION_NAME, CHANGED_VALUE_COLOR.getId(), opt.registerThemeColorBinding(EDIT_TEXT_COLOR_OPTION_NAME, EDITED_TEXT_COLOR.getId(),
new HelpLocation("ByteViewerPlugin", "EditColor"), new HelpLocation("ByteViewerPlugin", "EditColor"),
"Color of changed bytes when editing."); "Color of changed bytes when editing.");
opt.registerThemeColorBinding(CURSOR_ACTIVE_COLOR_OPTION_NAME, CURSOR_ACTIVE_COLOR.getId(), opt.registerThemeColorBinding(CURSOR_FOCUSED_COLOR_OPTION_NAME,
help, "Color of cursor in the active view."); CURSOR_COLOR_FOCUSED_NON_EDIT.getId(),
help, "Color of cursor in the focused view.");
opt.registerThemeColorBinding(CURSOR_NON_ACTIVE_COLOR_OPTION_NAME, opt.registerThemeColorBinding(CURSOR_UNFOCUSED_COLOR_OPTION_NAME,
CURSOR_NON_ACTIVE_COLOR.getId(), help, "Color of cursor in the non-active views."); CURSOR_COLOR_UNFOCUSED_NON_EDIT.getId(), help,
"Color of cursor in the unfocused views.");
opt.registerThemeColorBinding(CURSOR_NOT_FOCUSED_COLOR_OPTION_NAME, opt.registerThemeColorBinding(CURSOR_FOCUSED_EDIT_COLOR_OPTION_NAME,
CURSOR_NOT_FOCUSED_COLOR.getId(), help, CURSOR_COLOR_FOCUSED_EDIT.getId(), help,
"Color of cursor when the byteview does not have focus."); "Color of the cursor in the focused view when editing.");
opt.registerThemeColorBinding(CURSOR_UNFOCUSED_EDIT_COLOR_OPTION_NAME,
CURSOR_COLOR_UNFOCUSED_EDIT.getId(), help,
"Color of the cursor in the unfocused view when editing.");
opt.registerThemeColorBinding(CURRENT_LINE_COLOR_OPTION_NAME, opt.registerThemeColorBinding(CURRENT_LINE_COLOR_OPTION_NAME,
GhidraOptions.DEFAULT_CURSOR_LINE_COLOR.getId(), help, GhidraOptions.DEFAULT_CURSOR_LINE_COLOR.getId(), help,
@@ -238,16 +245,6 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
opt.getColor(OPTION_HIGHLIGHT_MIDDLE_MOUSE_NAME, HIGHLIGHT_MIDDLE_MOUSE_COLOR); opt.getColor(OPTION_HIGHLIGHT_MIDDLE_MOUSE_NAME, HIGHLIGHT_MIDDLE_MOUSE_COLOR);
panel.setMouseButtonHighlightColor(middleMouseColor); panel.setMouseButtonHighlightColor(middleMouseColor);
panel.setCurrentCursorColor(CURSOR_ACTIVE_COLOR);
panel.setNonFocusCursorColor(CURSOR_NOT_FOCUSED_COLOR);
panel.setCursorColor(CURSOR_NON_ACTIVE_COLOR);
panel.setCurrentCursorLineColor(CURRENT_LINE_COLOR);
Font font = Gui.getFont(DEFAULT_FONT_ID);
FontMetrics fm = panel.getFontMetrics(font);
panel.restoreConfigState(fm, CHANGED_VALUE_COLOR);
opt.addOptionsChangeListener(this); opt.addOptionsChangeListener(this);
// cursor highlight options // cursor highlight options
@@ -308,8 +305,8 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
return offset; return offset;
} }
Color getCursorColor() { Color getFocusedNonEditCursorColor() {
return CURSOR_NON_ACTIVE_COLOR; return CURSOR_COLOR_FOCUSED_NON_EDIT;
} }
int getGroupSize() { int getGroupSize() {
@@ -530,4 +527,5 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
public void removeDisplayListener(AddressSetDisplayListener listener) { public void removeDisplayListener(AddressSetDisplayListener listener) {
panel.removeDisplayListener(listener); panel.removeDisplayListener(listener);
} }
} }
@@ -63,16 +63,13 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
private IndexMap indexMap; // maps indexes to the correct block and offset private IndexMap indexMap; // maps indexes to the correct block and offset
private int blockOffset; private int blockOffset;
private ByteViewerComponent currentView; private ByteViewerComponent currentView;
private Color editColor;
private Color currentCursorColor;
private Color currentCursorLineColor;
private Color highlightColor; private Color highlightColor;
private int highlightButton; private int highlightButton;
private List<LayoutModelListener> layoutListeners = new ArrayList<>(1); private List<LayoutModelListener> layoutListeners = new ArrayList<>(1);
private boolean addingView; // don't respond to cursor location private boolean addingView; // don't respond to cursor location changes while this flag is true
// changes while this flag is true
private final ByteViewerComponentProvider provider;
private final ByteViewerComponentProvider provider;
private List<AddressSetDisplayListener> displayListeners = new ArrayList<>(); private List<AddressSetDisplayListener> displayListeners = new ArrayList<>();
private ByteViewerIndexedView indexedView; private ByteViewerIndexedView indexedView;
@@ -83,7 +80,6 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
viewList = new ArrayList<>(); viewList = new ArrayList<>();
indexMap = new IndexMap(); indexMap = new IndexMap();
create(); create();
editColor = ByteViewerComponentProvider.CHANGED_VALUE_COLOR;
} }
@Override @Override
@@ -115,20 +111,6 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
super.paintComponent(g); super.paintComponent(g);
} }
void setCurrentCursorColor(Color c) {
currentCursorColor = c;
for (ByteViewerComponent comp : viewList) {
comp.setCurrentCursorColor(c);
}
}
void setCurrentCursorLineColor(Color c) {
currentCursorLineColor = c;
for (ByteViewerComponent comp : viewList) {
comp.setCurrentCursorLineColor(c);
}
}
void setHighlightButton(int highlightButton) { void setHighlightButton(int highlightButton) {
this.highlightButton = highlightButton; this.highlightButton = highlightButton;
for (ByteViewerComponent comp : viewList) { for (ByteViewerComponent comp : viewList) {
@@ -143,12 +125,6 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
} }
} }
void setCursorColor(Color c) {
for (ByteViewerComponent comp : viewList) {
comp.setNonFocusCursorColor(c);
}
}
void setSeparatorColor(Color c) { void setSeparatorColor(Color c) {
indexFactory.setMissingValueColor(c); indexFactory.setMissingValueColor(c);
for (ByteViewerComponent comp : viewList) { for (ByteViewerComponent comp : viewList) {
@@ -156,12 +132,6 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
} }
} }
void setNonFocusCursorColor(Color c) {
for (ByteViewerComponent comp : viewList) {
comp.setNonFocusCursorColor(c);
}
}
/** /**
* Set the byte blocks and create an new IndexMap object that will be passed to the index panel * Set the byte blocks and create an new IndexMap object that will be passed to the index panel
* and to each component that shows a format. * and to each component that shows a format.
@@ -307,15 +277,11 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
if (viewList.size() != 0) { if (viewList.size() != 0) {
addingView = true; addingView = true;
} }
final ViewerPosition vp = getViewerPosition();
// create new ByteViewerComponent ViewerPosition vp = getViewerPosition();
ByteViewerComponent c = newByteViewerComponent(model); ByteViewerComponent c = newByteViewerComponent(model);
c.setEditColor(editColor);
c.setNonFocusCursorColor(ByteViewerComponentProvider.CURSOR_NOT_FOCUSED_COLOR);
c.setCurrentCursorColor(currentCursorColor);
c.setCurrentCursorLineColor(currentCursorLineColor);
c.setEditMode(editMode); c.setEditMode(editMode);
c.setIndexMap(indexMap); c.setIndexMap(indexMap);
c.setMouseButtonHighlightColor(highlightColor); c.setMouseButtonHighlightColor(highlightColor);
@@ -375,9 +341,6 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
} }
void setCurrentView(ByteViewerComponent c) { void setCurrentView(ByteViewerComponent c) {
if (currentView != null && currentView != c) {
currentView.setFocusedCursorColor(provider.getCursorColor());
}
currentView = c; currentView = c;
} }
@@ -565,17 +528,6 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
indexPanel.setViewerPosition(vpos.getIndex(), vpos.getXOffset(), vpos.getYOffset()); indexPanel.setViewerPosition(vpos.getIndex(), vpos.getXOffset(), vpos.getYOffset());
} }
/**
* Restore the configuration of the plugin.
*
* @param metrics font metrics
* @param newEditColor color for showing edits
*/
void restoreConfigState(FontMetrics metrics, Color newEditColor) {
setFontMetrics(metrics);
setEditColor(newEditColor);
}
void restoreConfigState(int newBytesPerLine, int offset) { void restoreConfigState(int newBytesPerLine, int offset) {
if (blockOffset != offset) { if (blockOffset != offset) {
blockOffset = offset; blockOffset = offset;
@@ -603,13 +555,6 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
indexPanel.modelSizeChanged(IndexMapper.IDENTITY_MAPPER); indexPanel.modelSizeChanged(IndexMapper.IDENTITY_MAPPER);
} }
void setEditColor(Color editColor) {
this.editColor = editColor;
for (ByteViewerComponent c : viewList) {
c.setEditColor(editColor);
}
}
protected FontMetrics getFontMetrics() { protected FontMetrics getFontMetrics() {
return fontMetrics; return fontMetrics;
} }
@@ -20,8 +20,8 @@ import java.awt.FontMetrics;
import java.math.BigInteger; import java.math.BigInteger;
import docking.widgets.fieldpanel.field.Field; import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.Highlight;
import docking.widgets.fieldpanel.support.FieldHighlightFactory; import docking.widgets.fieldpanel.support.FieldHighlightFactory;
import docking.widgets.fieldpanel.support.Highlight;
import ghidra.app.plugin.core.format.*; import ghidra.app.plugin.core.format.*;
import ghidra.program.model.address.AddressOutOfBoundsException; import ghidra.program.model.address.AddressOutOfBoundsException;
@@ -46,12 +46,6 @@ class FieldFactory {
private int unitByteSize; private int unitByteSize;
private FieldHighlightFactory highlightFactory; private FieldHighlightFactory highlightFactory;
/**
* Constructor
* @param model data format model that knows how to represent the data
* @param fieldCount number of fields in a row
* @param label label that is used as a renderer in the field viewer
*/
FieldFactory(DataFormatModel model, int bytesPerLine, int fieldOffset, FontMetrics fm, FieldFactory(DataFormatModel model, int bytesPerLine, int fieldOffset, FontMetrics fm,
ByteViewerHighlighter highlightProvider) { ByteViewerHighlighter highlightProvider) {
this.model = model; this.model = model;
@@ -60,20 +54,21 @@ class FieldFactory {
this.highlightFactory = new SimpleHighlightFactory(highlightProvider); this.highlightFactory = new SimpleHighlightFactory(highlightProvider);
charWidth = fm.charWidth('W'); charWidth = fm.charWidth('W');
width = charWidth * model.getDataUnitSymbolSize(); width = charWidth * model.getDataUnitSymbolSize();
editColor = ByteViewerComponentProvider.CHANGED_VALUE_COLOR; editColor = ByteViewerComponentProvider.EDITED_TEXT_COLOR;
separatorColor = ByteViewerComponentProvider.SEPARATOR_COLOR; separatorColor = ByteViewerComponentProvider.SEPARATOR_COLOR;
unitByteSize = model.getUnitByteSize(); unitByteSize = model.getUnitByteSize();
} }
/** /**
* Sets the starting x position for the fields generated by this factory. * Sets the starting x position for the fields generated by this factory.
* @param x the x position
*/ */
public void setStartX(int x) { public void setStartX(int x) {
startX = x; startX = x;
} }
/** /**
* Returns the starting x position for the fields generated by this factory. * {@return the starting x position for the fields generated by this factory.}
*/ */
public int getStartX() { public int getStartX() {
return startX; return startX;
@@ -95,11 +90,6 @@ class FieldFactory {
return indexMap.getBlockInfo(index, fieldOffset) != null; return indexMap.getBlockInfo(index, fieldOffset) != null;
} }
/**
* Gets a Field object for the given index.
* This method is called for the given index and the fieldOffset
* that is defined in the constructor.
*/
public Field getField(BigInteger index) { public Field getField(BigInteger index) {
if (indexMap == null) { if (indexMap == null) {
return null; return null;
@@ -145,9 +135,6 @@ class FieldFactory {
} }
} }
/**
* Returns the width (in pixels) of the fields generated by this factory.
*/
public int getWidth() { public int getWidth() {
return width; return width;
} }
@@ -156,12 +143,10 @@ class FieldFactory {
return fm; return fm;
} }
/////////////////////////////////////////////////////////////////// //=================================================================================================
// *** package-level methods // Package Methods
/////////////////////////////////////////////////////////////////// //=================================================================================================
/**
* Set the index map.
*/
void setIndexMap(IndexMap indexMap) { void setIndexMap(IndexMap indexMap) {
this.indexMap = indexMap; this.indexMap = indexMap;
if (indexMap != null) { if (indexMap != null) {
@@ -191,14 +176,12 @@ class FieldFactory {
/** /**
* Set the color used to denote changes. * Set the color used to denote changes.
* @param c the color
*/ */
void setEditColor(Color c) { void setEditColor(Color c) {
editColor = c; editColor = c;
} }
/**
* Set the color that indicates gaps in memory.
*/
void setSeparatorColor(Color c) { void setSeparatorColor(Color c) {
separatorColor = c; separatorColor = c;
} }
@@ -157,7 +157,8 @@ public abstract class HexValueFormatModel implements UniversalDataFormatModel {
@Override @Override
public HelpLocation getHelpLocation() { public HelpLocation getHelpLocation() {
return new HelpLocation("ByteViewerPlugin", "HexValue"); String anchor = name.replaceAll("\\s", "");
return new HelpLocation("ByteViewerPlugin", anchor);
} }
@Override @Override
@@ -174,7 +174,7 @@ public class ByteViewerConnectedToolBehaviorTest extends AbstractGhidraHeadedInt
ByteViewerComponent c2 = panel2.getCurrentComponent(); ByteViewerComponent c2 = panel2.getCurrentComponent();
ByteField f2 = c2.getField(BigInteger.ZERO, 0); ByteField f2 = c2.getField(BigInteger.ZERO, 0);
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, f2.getForeground()); assertEquals(ByteViewerComponentProvider.EDITED_TEXT_COLOR, f2.getForeground());
} }
@Test @Test
@@ -204,7 +204,7 @@ public class ByteViewerConnectedToolBehaviorTest extends AbstractGhidraHeadedInt
ByteViewerComponent c2 = panel2.getCurrentComponent(); ByteViewerComponent c2 = panel2.getCurrentComponent();
ByteField f2 = c2.getField(BigInteger.ZERO, 0); ByteField f2 = c2.getField(BigInteger.ZERO, 0);
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, f2.getForeground()); assertEquals(ByteViewerComponentProvider.EDITED_TEXT_COLOR, f2.getForeground());
undo(program); undo(program);
@@ -292,7 +292,7 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0); hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0);
}); });
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, assertEquals(ByteViewerComponentProvider.EDITED_TEXT_COLOR,
((ByteField) hexComp.getCurrentField()).getForeground()); ((ByteField) hexComp.getCurrentField()).getForeground());
} }
@@ -351,7 +351,7 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0); hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0);
}); });
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, assertEquals(ByteViewerComponentProvider.EDITED_TEXT_COLOR,
((ByteField) hexComp.getCurrentField()).getForeground()); ((ByteField) hexComp.getCurrentField()).getForeground());
} }
@@ -410,7 +410,7 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0); hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0);
}); });
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, assertEquals(ByteViewerComponentProvider.EDITED_TEXT_COLOR,
((ByteField) hexComp.getCurrentField()).getForeground()); ((ByteField) hexComp.getCurrentField()).getForeground());
} }
@@ -469,7 +469,7 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0); hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0);
}); });
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, assertEquals(ByteViewerComponentProvider.EDITED_TEXT_COLOR,
((ByteField) hexComp.getCurrentField()).getForeground()); ((ByteField) hexComp.getCurrentField()).getForeground());
} }
@@ -519,7 +519,7 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
// does not support editing // does not support editing
Color fg = ((ByteField) c.getCurrentField()).getForeground(); Color fg = ((ByteField) c.getCurrentField()).getForeground();
if (fg != null) { if (fg != null) {
assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR, fg); assertEquals(ByteViewerComponentProvider.CURSOR_COLOR_FOCUSED_NON_EDIT, fg);
} }
} }
@@ -568,7 +568,7 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
// does not support editing // does not support editing
Color fg = ((ByteField) c.getCurrentField()).getForeground(); Color fg = ((ByteField) c.getCurrentField()).getForeground();
if (fg != null) { if (fg != null) {
assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR, fg); assertEquals(ByteViewerComponentProvider.CURSOR_COLOR_FOCUSED_NON_EDIT, fg);
} }
} }
@@ -613,7 +613,7 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
intComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0); intComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0);
}); });
// color should indicate the edit // color should indicate the edit
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, assertEquals(ByteViewerComponentProvider.EDITED_TEXT_COLOR,
((ByteField) intComp.getCurrentField()).getForeground()); ((ByteField) intComp.getCurrentField()).getForeground());
} }
@@ -930,7 +930,7 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
Component[] c = container.getComponents(); Component[] c = container.getComponents();
for (Component element : c) { for (Component element : c) {
if (element instanceof JLabel) { if (element instanceof JLabel) {
if (name.equals(((JLabel) element).getName())) { if (name.equals(element.getName())) {
return ((JLabel) element).getText(); return ((JLabel) element).getText();
} }
} }
@@ -20,7 +20,7 @@ color.fg.glasspane.message = color.palette.lightcornflowerblue
color.bg.selection = color.palette.palegreen color.bg.selection = color.palette.palegreen
color.bg.highlight = color.palette.lemonchiffon color.bg.highlight = color.palette.lemonchiffon
color.bg.currentline = color.palette.aliceblue color.bg.currentline = color.palette.lightcyan
color.bg.find.highlight = #FFF38E // light yellow color.bg.find.highlight = #FFF38E // light yellow
color.bg.find.highlight.active = #FFC55B // light orange color.bg.find.highlight.active = #FFC55B // light orange
@@ -197,6 +197,8 @@ color.bg.find.highlight.active = #BC7474 // rosybrown
color.bg.highlight = #67582A // olivish color.bg.highlight = #67582A // olivish
color.bg.currentline = ##393D64 // gray purple
color.bg.filechooser.shortcut = [color]system.color.bg.view color.bg.filechooser.shortcut = [color]system.color.bg.view
@@ -32,6 +32,7 @@ color.palette.khaki = khaki
color.palette.lavender = lavender color.palette.lavender = lavender
color.palette.lemonchiffon = lemonchiffon color.palette.lemonchiffon = lemonchiffon
color.palette.lightcoral = lightcoral color.palette.lightcoral = lightcoral
color.palette.lightcyan = lightcyan
color.palette.lightgray = rgb(192, 192, 192) color.palette.lightgray = rgb(192, 192, 192)
color.palette.lightgreen = rgb(127, 255, 127) color.palette.lightgreen = rgb(127, 255, 127)
color.palette.lightpink = lightpink color.palette.lightpink = lightpink