mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-09-20 17:41:48 +00:00
GP-4676 adding option to globally control blinking cursors
This commit is contained in:
parent
907a834fdc
commit
2f823d23eb
|
@ -392,9 +392,15 @@
|
|||
<TBODY>
|
||||
<TR>
|
||||
<TH valign="top" align="left"><B>Option</B></TH>
|
||||
|
||||
|
||||
<TH valign="top" align="left"><B>Description</B></TH>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD valign="top" width="200" align="left">Allow Blinking Cursors</TD>
|
||||
|
||||
<TD valign="top" align="left">This controls whether text components and other
|
||||
components that have a text cursor will blink when they have focus.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD valign="top" width="200" align="left">Automatically Save Tools</TD>
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
|||
private static final String CURSOR_COLOR_OPTIONS_NAME = "Cursor.Cursor Color - Focused";
|
||||
private static final String UNFOCUSED_CURSOR_COLOR_OPTIONS_NAME =
|
||||
"Cursor.Cursor Color - Unfocused";
|
||||
private static final String BLINK_CURSOR_OPTIONS_NAME = "Cursor.Blink Cursor";
|
||||
private static final String MOUSE_WHEEL_HORIZONTAL_SCROLLING_OPTIONS_NAME =
|
||||
"Mouse.Horizontal Scrolling";
|
||||
|
||||
|
@ -417,10 +416,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
|||
Color color = ((Color) newValue);
|
||||
fieldPanel.setNonFocusCursorColor(color);
|
||||
}
|
||||
else if (optionName.equals(BLINK_CURSOR_OPTIONS_NAME)) {
|
||||
Boolean isBlinkCursor = ((Boolean) newValue);
|
||||
fieldPanel.setBlinkCursor(isBlinkCursor);
|
||||
}
|
||||
else if (optionName.equals(GhidraOptions.HIGHLIGHT_CURSOR_LINE_COLOR)) {
|
||||
cursorHighlightColor = (Color) newValue;
|
||||
if (currentCursorMarkers != null) {
|
||||
|
@ -562,8 +557,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
|||
fieldOptions.registerThemeColorBinding(UNFOCUSED_CURSOR_COLOR_OPTIONS_NAME,
|
||||
UNFOCUSED_CURSOR_COLOR.getId(), helpLocation,
|
||||
"The color of the cursor in the browser when the browser does not have focus.");
|
||||
fieldOptions.registerOption(BLINK_CURSOR_OPTIONS_NAME, true, helpLocation,
|
||||
"When selected, the cursor will blink when the containing window is focused.");
|
||||
fieldOptions.registerThemeColorBinding(GhidraOptions.HIGHLIGHT_CURSOR_LINE_COLOR,
|
||||
CURRENT_LINE_HIGHLIGHT_COLOR.getId(), helpLocation,
|
||||
"The background color of the line where the cursor is located");
|
||||
|
@ -599,9 +592,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
|||
color = fieldOptions.getColor(UNFOCUSED_CURSOR_COLOR_OPTIONS_NAME, UNFOCUSED_CURSOR_COLOR);
|
||||
fieldPanel.setNonFocusCursorColor(color);
|
||||
|
||||
Boolean isBlinkCursor = fieldOptions.getBoolean(BLINK_CURSOR_OPTIONS_NAME, true);
|
||||
fieldPanel.setBlinkCursor(isBlinkCursor);
|
||||
|
||||
boolean horizontalScrollingEnabled =
|
||||
fieldOptions.getBoolean(MOUSE_WHEEL_HORIZONTAL_SCROLLING_OPTIONS_NAME, true);
|
||||
fieldPanel.setHorizontalScrollingEnabled(horizontalScrollingEnabled);
|
||||
|
|
|
@ -42,6 +42,7 @@ import docking.widgets.indexedscrollpane.IndexScrollListener;
|
|||
import docking.widgets.indexedscrollpane.IndexedScrollable;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.ThemeManager;
|
||||
import ghidra.util.*;
|
||||
|
||||
public class FieldPanel extends JPanel
|
||||
|
@ -127,6 +128,7 @@ public class FieldPanel extends JPanel
|
|||
setFocusable(true);
|
||||
|
||||
hoverHandler = new HoverHandler(this);
|
||||
initializeCursorBlinking();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -392,6 +394,17 @@ public class FieldPanel extends JPanel
|
|||
super.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUI() {
|
||||
super.updateUI();
|
||||
initializeCursorBlinking();
|
||||
}
|
||||
|
||||
private void initializeCursorBlinking() {
|
||||
boolean blinkingCursors = ThemeManager.getInstance().isBlinkingCursors();
|
||||
setBlinkCursor(blinkingCursors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
if (viewport == null) {
|
||||
|
@ -423,7 +436,9 @@ public class FieldPanel extends JPanel
|
|||
}
|
||||
|
||||
public void setBlinkCursor(Boolean blinkCursor) {
|
||||
cursorHandler.setBlinkCursor(blinkCursor);
|
||||
if (cursorHandler != null) {
|
||||
cursorHandler.setBlinkCursor(blinkCursor);
|
||||
}
|
||||
}
|
||||
|
||||
public void enableSelection(boolean b) {
|
||||
|
@ -1397,6 +1412,7 @@ public class FieldPanel extends JPanel
|
|||
return accessibleFieldPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(double preciseWheelRotation, boolean horizontal) {
|
||||
|
||||
Layout firstLayout = model.getLayout(BigInteger.ZERO);
|
||||
|
|
|
@ -45,6 +45,7 @@ public class ApplicationThemeManager extends ThemeManager {
|
|||
// stores the original value for ids whose value has changed from the current theme
|
||||
private GThemeValueMap changedValuesMap = new GThemeValueMap();
|
||||
protected LookAndFeelManager lookAndFeelManager;
|
||||
private boolean blinkingCursors = true;
|
||||
|
||||
/**
|
||||
* Initialized the Theme and its values for the application.
|
||||
|
@ -126,26 +127,31 @@ public class ApplicationThemeManager extends ThemeManager {
|
|||
}
|
||||
|
||||
update(() -> {
|
||||
|
||||
activeTheme = theme;
|
||||
activeLafType = theme.getLookAndFeelType();
|
||||
useDarkDefaults = theme.useDarkDefaults();
|
||||
|
||||
cleanUiDefaults(); // clear out any values previous themes may have installed
|
||||
lookAndFeelManager = activeLafType.getLookAndFeelManager(this);
|
||||
try {
|
||||
lookAndFeelManager.installLookAndFeel();
|
||||
if (updateLookAndFeel()) {
|
||||
themePreferences.save(theme);
|
||||
notifyThemeChanged(new AllValuesChangedThemeEvent(true));
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.error(this, "Error setting Look and Feel: " + activeLafType.getName(), e);
|
||||
}
|
||||
});
|
||||
|
||||
currentValues.checkForUnresolvedReferences();
|
||||
}
|
||||
|
||||
private boolean updateLookAndFeel() {
|
||||
try {
|
||||
cleanUiDefaults(); // clear out any values previous themes may have installed
|
||||
lookAndFeelManager.installLookAndFeel();
|
||||
notifyThemeChanged(new AllValuesChangedThemeEvent(true));
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.error(this, "Error setting Look and Feel: " + activeLafType.getName(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLookAndFeel(LafType lafType, boolean useDarkDefaults) {
|
||||
|
||||
|
@ -162,19 +168,31 @@ public class ApplicationThemeManager extends ThemeManager {
|
|||
this.useDarkDefaults = useDarkDefaults;
|
||||
|
||||
update(() -> {
|
||||
|
||||
cleanUiDefaults(); // clear out any values previous themes may have installed
|
||||
lookAndFeelManager = lafType.getLookAndFeelManager(this);
|
||||
try {
|
||||
lookAndFeelManager.installLookAndFeel();
|
||||
notifyThemeChanged(new AllValuesChangedThemeEvent(true));
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.error(this, "Error setting Look and Feel: " + lafType.getName(), e);
|
||||
}
|
||||
updateLookAndFeel();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlinkingCursors(boolean b) {
|
||||
if (blinkingCursors == b) {
|
||||
return;
|
||||
}
|
||||
blinkingCursors = b;
|
||||
|
||||
// Need to reinstall the look and feel so that UIDefaults for cursor blinking are set.
|
||||
// For most look and feels, we could have just updated the UIs, but because Nimbus
|
||||
// doesn't respect UIDefaults changes after loading, it is easier to just reinstall.
|
||||
update(() -> {
|
||||
updateLookAndFeel();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlinkingCursors() {
|
||||
return blinkingCursors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTheme(GTheme newTheme) {
|
||||
loadThemes();
|
||||
|
|
|
@ -19,8 +19,7 @@ import java.awt.*;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
|
||||
import generic.theme.builtin.*;
|
||||
|
@ -667,6 +666,29 @@ public abstract class ThemeManager {
|
|||
int newSize = Math.max(MIN_FONT_SIZE, currentSize += amount);
|
||||
setFont(fontValue.getId(), directFont.deriveFont((float) newSize));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets application's blinking cursor state. This will affect all JTextFields, JTextAreas,
|
||||
* JTextPanes via {@link UIDefaults}. Custom components can also respect this setting by
|
||||
* either adding a {@link ThemeListener} or overriding {@link JComponent#updateUI()}
|
||||
* <P> NOTE: This method is a bit odd here as it doesn't really apply to a theme. But it
|
||||
* requires manipulation of the look and feel which is managed by the theme. If other
|
||||
* application level properties come along and also require changing the UIDefaults,
|
||||
* perhaps a more general solution might be to add a way for clients to register a callback
|
||||
* so that they get a chance to change the UIDefaults map as the look and feel is loaded.
|
||||
* @param b true for blinking text cursors, false for non-blinking text cursors
|
||||
*/
|
||||
public void setBlinkingCursors(boolean b) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the application should allow blinking cursors, false otherwise. Custom
|
||||
* components can use this method to determine if they should have a blinking cursor or not.
|
||||
* @return true if the application should allow blinking cursors, false otherwise.
|
||||
*/
|
||||
public boolean isBlinkingCursors() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public class FlatLookAndFeelManager extends LookAndFeelManager {
|
|||
|
||||
@Override
|
||||
protected void fixupLookAndFeelIssues() {
|
||||
|
||||
super.fixupLookAndFeelIssues();
|
||||
//
|
||||
// The FlatTreeUI class will remove default renderers inside the call to updateRenderer()
|
||||
// if "Tree.showDefaultIcons" is false. We want the tree to display folder icons.
|
||||
|
|
|
@ -37,6 +37,7 @@ import utilities.util.reflection.ReflectionUtilities;
|
|||
*/
|
||||
public abstract class LookAndFeelManager {
|
||||
|
||||
private static final int DEFAULT_CURSOR_BLINK_RATE = 500;
|
||||
private LafType laf;
|
||||
private Map<String, ComponentFontRegistry> fontRegistryMap = new HashMap<>();
|
||||
private Map<Component, String> componentToIdMap = new WeakHashMap<>();
|
||||
|
@ -290,6 +291,7 @@ public abstract class LookAndFeelManager {
|
|||
*/
|
||||
protected void fixupLookAndFeelIssues() {
|
||||
installGlobalFontSizeOverride();
|
||||
installCursorBlinkingProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -355,6 +357,15 @@ public abstract class LookAndFeelManager {
|
|||
setGlobalFontSizeOverride(overrideFontInteger);
|
||||
}
|
||||
|
||||
public void installCursorBlinkingProperties() {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
|
||||
int blinkRate = themeManager.isBlinkingCursors() ? DEFAULT_CURSOR_BLINK_RATE : 0;
|
||||
defaults.put("TextPane.caretBlinkRate", blinkRate);
|
||||
defaults.put("TextField.caretBlinkRate", blinkRate);
|
||||
defaults.put("TextArea.caretBlinkRate", blinkRate);
|
||||
}
|
||||
|
||||
private void installCustomLookAndFeelActions() {
|
||||
// these prefixes are for text components
|
||||
String[] UIPrefixValues =
|
||||
|
|
|
@ -42,6 +42,7 @@ import docking.util.AnimationUtils;
|
|||
import docking.util.image.ToolIconURL;
|
||||
import docking.widgets.OptionDialog;
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.theme.ThemeManager;
|
||||
import generic.util.WindowUtilities;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.util.GenericHelpTopics;
|
||||
|
@ -91,6 +92,7 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
|
|||
public static final String AUTOMATICALLY_SAVE_TOOLS = "Automatically Save Tools";
|
||||
private static final String USE_ALERT_ANIMATION_OPTION_NAME = "Use Notification Animation";
|
||||
private static final String SHOW_TOOLTIPS_OPTION_NAME = "Show Tooltips";
|
||||
private static final String BLINKING_CURSORS_OPTION_NAME = "Allow Blinking Cursors";
|
||||
|
||||
// TODO: Experimental Option !!
|
||||
private static final String ENABLE_COMPRESSED_DATABUFFER_OUTPUT =
|
||||
|
@ -353,6 +355,9 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
|
|||
"When enabled data buffers sent to Ghidra Server are compressed (see server " +
|
||||
"configuration for other direction)");
|
||||
|
||||
options.registerOption(BLINKING_CURSORS_OPTION_NAME, true, help, "This controls whether" +
|
||||
" text cursors blink when focused");
|
||||
|
||||
options.registerOption(RESTORE_PREVIOUS_PROJECT_NAME, true, help,
|
||||
"Restore the previous project when Ghidra starts.");
|
||||
|
||||
|
@ -373,6 +378,9 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
|
|||
|
||||
shouldRestorePreviousProject = options.getBoolean(RESTORE_PREVIOUS_PROJECT_NAME, true);
|
||||
|
||||
boolean blink = options.getBoolean(BLINKING_CURSORS_OPTION_NAME, true);
|
||||
ThemeManager.getInstance().setBlinkingCursors(blink);
|
||||
|
||||
options.addOptionsChangeListener(this);
|
||||
}
|
||||
|
||||
|
@ -397,6 +405,9 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
|
|||
else if (RESTORE_PREVIOUS_PROJECT_NAME.equals(optionName)) {
|
||||
shouldRestorePreviousProject = (Boolean) newValue;
|
||||
}
|
||||
else if (BLINKING_CURSORS_OPTION_NAME.equals(optionName)) {
|
||||
ThemeManager.getInstance().setBlinkingCursors((Boolean) newValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue
Block a user