mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-4154 - Theming - Fixed font issues; updated font usage with attributes
This commit is contained in:
parent
c5bad0a88f
commit
b586d65a3b
91 changed files with 1309 additions and 1191 deletions
|
@ -133,10 +133,18 @@ icon.task.progress.hourglass.11 = hourglass24_11.png
|
|||
|
||||
// Fonts
|
||||
|
||||
font.splash.header.default = Serif-BOLD-35
|
||||
font.splash.status = Serif-BOLD-12
|
||||
font.table.header.number = arial-BOLD-12
|
||||
font.input.hint = monospaced-PLAIN-10
|
||||
font.splash.header.default = serif-bold-35
|
||||
font.splash.status = serif-bold-12
|
||||
|
||||
// default table renderer uses the JLabel font, which is mapped to system.font.control
|
||||
font.table.base = [font]system.font.control
|
||||
font.table.header.number = arial-bold-12
|
||||
|
||||
font.input.hint = monospaced-plain-10
|
||||
|
||||
font.task.monitor.label.message = sansserif-plain-10
|
||||
|
||||
font.wizard.border.title = sansserif-plain-10
|
||||
|
||||
|
||||
|
||||
|
@ -144,7 +152,6 @@ font.input.hint = monospaced-PLAIN-10
|
|||
[Dark Defaults]
|
||||
|
||||
|
||||
|
||||
color.fg.filterfield = color.palette.darkslategray
|
||||
|
||||
color.bg.highlight = #703401 // orangish
|
||||
|
|
|
@ -59,9 +59,9 @@
|
|||
<tocdef id="Root" sortgroup="a" text="Welcome to Help">
|
||||
<tocdef id="Theming" text="Theming" sortgroup="t" target="help/topics/Theming/ThemingOverview.html">
|
||||
<tocdef id="Overview" sortgroup="1" text="Overview" target="help/topics/Theming/ThemingOverview.html"/>
|
||||
<tocdef id="Editing Themes" sortgroup="2" text="Editing Themes" target="help/topics/Theming/ThemingUserDocs.html"/>
|
||||
<tocdef id="Architecture" sortgroup="3" text="Architecture" target="help/topics/Theming/ThemingInternals.html"/>
|
||||
<tocdef id="Developer Documentation" sortgroup="4" text="Developer's Guide" target="help/topics/Theming/ThemingDeveloperDocs.html"/>
|
||||
<tocdef id="Editing Themes" sortgroup="2" text="User's Guide" target="help/topics/Theming/ThemingUserDocs.html"/>
|
||||
<tocdef id="Developer Documentation" sortgroup="3" text="Developer's Guide" target="help/topics/Theming/ThemingDeveloperDocs.html"/>
|
||||
<tocdef id="Architecture" sortgroup="4" text="Architecture" target="help/topics/Theming/ThemingInternals.html"/>
|
||||
</tocdef>
|
||||
</tocdef>
|
||||
</tocroot>
|
||||
|
|
|
@ -13,6 +13,14 @@
|
|||
plugins, actions, scripts, etc., that use colors, fonts, or icons. By following these guidelines,
|
||||
developers can easily make use of Ghidra's theming capabilities.</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<BLOCKQUOTE>
|
||||
<P><IMG border="0" src="help/shared/tip.png" alt="Tip">Most classes referenced in this document
|
||||
live in the <CODE>generic.theme</CODE> package.
|
||||
</P>
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H2>Theme Resource Types</H2>
|
||||
|
||||
<P>When developing application code for Ghidra such as plugins, actions, etc., developers often
|
||||
|
@ -122,8 +130,58 @@
|
|||
|
||||
<BLOCKQUOTE>
|
||||
<CODE>Gui.registerFont(myLabel, "font.xyz");</CODE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
|
||||
|
||||
<H3>Font Usage in Tables, Lists and Custom Painting</H3>
|
||||
<P>
|
||||
Ghidra makes great use of tables and to a lesser extent, lists. Both tables and lists
|
||||
use renderers to paint cell values.
|
||||
</P>
|
||||
<UL>
|
||||
<LI>
|
||||
Java - By default, Java will use the font of the table/list as the font used during rendering.
|
||||
</LI>
|
||||
<LI>
|
||||
Ghidra Tables - Ghidra does <U>not</U> use the table's font for rendering by default. Instead,
|
||||
the renderer is initialized with the fonts used by <CODE>JLabel</CODE>, with additional
|
||||
fonts for bold and monospaced text.
|
||||
</LI>
|
||||
<LI>
|
||||
Ghidra Lists - Ghidra does not currently use custom rendering for lists. Thus, list cell
|
||||
rendering will make use of the list's font, which is Java's default behavior.
|
||||
</LI>
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
We point out this difference between Java and Ghidra here so that developers understand
|
||||
that changing fonts used for tables differs from Java. Specifically, calling
|
||||
<BLOCKQUOTE>
|
||||
<BLOCKQUOTE>
|
||||
<PRE>
|
||||
<CODE>
|
||||
table.setFont(newFont);
|
||||
</CODE>
|
||||
</PRE>
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
<P>
|
||||
will not affect the font used when rendering the table. To programmatically change the
|
||||
fonts used for tables, you can set the font directly on each cell renderer. As with a
|
||||
any custom fonts used, be sure to define theme properties file and register then with the
|
||||
Gui class as outlined above.
|
||||
</P>
|
||||
<P>
|
||||
The fonts used for any painting operations, including table and list cell rendering, as well
|
||||
as any code that overrides <CODE>paint</CODE> will work correctly within the theming
|
||||
environment as long as the fonts are derived from the default Look and Feel values or are
|
||||
obtained from the <CODE>Gui</CODE> class. In other words, as long as the
|
||||
fonts used in custom painting are not hard-coded, any changes to the fonts via the theming
|
||||
API will appear on the next call to paint the UI.
|
||||
</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
|
|
|
@ -26,7 +26,9 @@ import docking.action.DockingActionIf;
|
|||
import docking.action.KeyBindingData;
|
||||
import docking.tool.ToolConstants;
|
||||
import docking.widgets.label.GIconLabel;
|
||||
import generic.theme.GAttributes;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.HelpLocation;
|
||||
import resources.Icons;
|
||||
|
||||
|
@ -43,7 +45,8 @@ public class KeyEntryDialog extends DialogComponentProvider {
|
|||
private KeyEntryTextField keyEntryField;
|
||||
private JTextPane collisionPane;
|
||||
private StyledDocument doc;
|
||||
private SimpleAttributeSet textAttrSet;
|
||||
|
||||
private SimpleAttributeSet textAttrs;
|
||||
private Color bgColor;
|
||||
|
||||
public KeyEntryDialog(Tool tool, DockingActionIf action) {
|
||||
|
@ -172,10 +175,8 @@ public class KeyEntryDialog extends DialogComponentProvider {
|
|||
}
|
||||
|
||||
private void setUpAttributes() {
|
||||
textAttrSet = new SimpleAttributeSet();
|
||||
textAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
|
||||
textAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
|
||||
textAttrSet.addAttribute(StyleConstants.Foreground, Messages.NORMAL);
|
||||
Font font = Gui.getFont("font.standard");
|
||||
textAttrs = new GAttributes(font, Messages.NORMAL);
|
||||
}
|
||||
|
||||
private void updateCollisionPane(KeyStroke ks) {
|
||||
|
@ -194,7 +195,7 @@ public class KeyEntryDialog extends DialogComponentProvider {
|
|||
String ksName = KeyBindingUtils.parseKeyStroke(ks);
|
||||
String text = keyBindings.getActionsForKeyStrokeText(ksName);
|
||||
try {
|
||||
doc.insertString(0, text, textAttrSet);
|
||||
doc.insertString(0, text, textAttrs);
|
||||
collisionPane.setCaretPosition(0);
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.swing.*;
|
|||
|
||||
import docking.widgets.combobox.GComboBox;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
/**
|
||||
|
@ -133,7 +134,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
|||
JPanel panel = new JPanel(new GridLayout(2, 1));
|
||||
|
||||
GDLabel styleLabel = new GDLabel("Styles");
|
||||
styleLabel.setFont(getFont().deriveFont(1));
|
||||
Gui.registerFont(styleLabel, Font.BOLD);
|
||||
styleLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
panel.add(styleLabel);
|
||||
|
||||
|
@ -150,7 +151,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
|||
JPanel panel = new JPanel(new GridLayout(2, 1));
|
||||
|
||||
GDLabel sizeLabel = new GDLabel("Sizes");
|
||||
sizeLabel.setFont(getFont().deriveFont(1));
|
||||
Gui.registerFont(sizeLabel, Font.BOLD);
|
||||
sizeLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
panel.add(sizeLabel);
|
||||
|
||||
|
@ -168,7 +169,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
|||
JPanel panel = new JPanel(new GridLayout(2, 1));
|
||||
|
||||
GDLabel fontLabel = new GDLabel("Fonts");
|
||||
fontLabel.setFont(getFont().deriveFont(1));
|
||||
Gui.registerFont(fontLabel, Font.BOLD);
|
||||
fontLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
panel.add(fontLabel);
|
||||
|
||||
|
|
|
@ -25,22 +25,32 @@ import javax.swing.plaf.basic.BasicHTML;
|
|||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
import docking.widgets.label.GDHtmlLabel;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GColorUIResource;
|
||||
import generic.theme.*;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.GThemeDefaults.Colors.Tables;
|
||||
import ghidra.util.Msg;
|
||||
import util.CollectionUtils;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
|
||||
/**
|
||||
* A common base class for list and table renderer objects, unifying the Ghidra look and feel.
|
||||
* <p>
|
||||
* It allows (but default-disables) HTML content, automatically paints alternating row
|
||||
* background colors, and highlights the drop target in a drag-n-drop operation.
|
||||
*
|
||||
* It allows (but default-disables) HTML content, automatically paints alternating row background
|
||||
* colors, and highlights the drop target in a drag-n-drop operation.
|
||||
* <p>
|
||||
* The preferred method to change the font used by this renderer is {@link #setBaseFontId(String)}.
|
||||
* If you would like this renderer to use a monospaced font, then, as an alternative to creating a
|
||||
* font ID, you can instead override {@link #getDefaultFont()} to return this
|
||||
* class's {@link #fixedWidthFont}. Also, the fixed width font of this class is based on the
|
||||
* default font set when calling {@link #setBaseFontId(String)}, so it stays up-to-date with theme
|
||||
* changes.
|
||||
*/
|
||||
public abstract class AbstractGCellRenderer extends GDHtmlLabel {
|
||||
private static final Color BACKGROUND_COLOR = new GColor("color.bg.table.row");
|
||||
private static final Color ALT_BACKGROUND_COLOR = new GColor("color.bg.table.row.alt");
|
||||
|
||||
private static final String BASE_FONT_ID = "font.table.base";
|
||||
|
||||
/** Allows the user to disable alternating row colors on JLists and JTables */
|
||||
private static final String DISABLE_ALTERNATING_ROW_COLORS_PROPERTY =
|
||||
"disable.alternating.row.colors";
|
||||
|
@ -61,6 +71,9 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
|
|||
private boolean instanceAlternateRowColors = true;
|
||||
|
||||
public AbstractGCellRenderer() {
|
||||
|
||||
setBaseFontId(BASE_FONT_ID);
|
||||
|
||||
noFocusBorder = BorderFactory.createEmptyBorder(0, 5, 0, 5);
|
||||
Border innerBorder = BorderFactory.createEmptyBorder(0, 4, 0, 4);
|
||||
Border outerBorder = BorderFactory.createLineBorder(Palette.YELLOW, 1);
|
||||
|
@ -114,34 +127,48 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
|
|||
return getBackgroundColorForRow(row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this renderer's theme font id. This will be used to load the base font and to create
|
||||
* the derived fonts, such as bold and fixed width.
|
||||
* @param fontId the font id
|
||||
* @see Gui#registerFont(Component, String)
|
||||
*/
|
||||
public void setBaseFontId(String fontId) {
|
||||
Font f = Gui.getFont(fontId);
|
||||
defaultFont = f;
|
||||
fixedWidthFont = new Font("monospaced", f.getStyle(), f.getSize());
|
||||
boldFont = f.deriveFont(Font.BOLD);
|
||||
|
||||
Gui.registerFont(this, fontId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFont(Font f) {
|
||||
super.setFont(f);
|
||||
defaultFont = f;
|
||||
fixedWidthFont = new Font("monospaced", defaultFont.getStyle(), defaultFont.getSize());
|
||||
boldFont = f.deriveFont(Font.BOLD);
|
||||
}
|
||||
|
||||
protected void superSetFont(Font font) {
|
||||
super.setFont(font);
|
||||
}
|
||||
//
|
||||
// Due to the nature of how setFont() is typically used (external client setup vs internal
|
||||
// rendering), we created setBaseFontId() to allow external clients to set the base font in
|
||||
// a way that is consistent with theming. Ignore any request to use one of our existing
|
||||
// fonts, as some clients may do that from the getTableCellRendererComponent() method.
|
||||
//
|
||||
if (defaultFont != null &&
|
||||
!CollectionUtils.isOneOf(f, defaultFont, fixedWidthFont, boldFont)) {
|
||||
|
||||
// sets the font of this renderer to be bold until the next time that
|
||||
// getTableCellRenderer() is called, as it resets the font to the default font on each pass
|
||||
protected void setBold() {
|
||||
super.setFont(boldFont);
|
||||
String caller =
|
||||
ReflectionUtilities.getClassNameOlderThan(getClass().getName(), "generic.theme");
|
||||
Msg.debug(this, "Calling setFont() on the renderer is discouraged. " +
|
||||
"To change the font, call setBaseFontId(). Called from " + caller);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the row where DnD would perform drop operation.
|
||||
* @param dropRow the drop row
|
||||
* Sets the font of this renderer to be bold until the next time that getTableCellRenderer() is
|
||||
* called, as it resets the font to the default font on each pass.
|
||||
* @see #getDefaultFont()
|
||||
*/
|
||||
public void setDropRow(int dropRow) {
|
||||
this.dropRow = dropRow;
|
||||
}
|
||||
|
||||
protected Border getNoFocusBorder() {
|
||||
return noFocusBorder;
|
||||
protected void setBold() {
|
||||
super.setFont(boldFont);
|
||||
}
|
||||
|
||||
protected Font getDefaultFont() {
|
||||
|
@ -156,6 +183,18 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
|
|||
return boldFont;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the row where DnD would perform drop operation.
|
||||
* @param dropRow the drop row
|
||||
*/
|
||||
public void setDropRow(int dropRow) {
|
||||
this.dropRow = dropRow;
|
||||
}
|
||||
|
||||
protected Border getNoFocusBorder() {
|
||||
return noFocusBorder;
|
||||
}
|
||||
|
||||
protected Color getDefaultBackgroundColor() {
|
||||
return BACKGROUND_COLOR;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,8 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
|||
new DropDownWindowVisibilityListener<>();
|
||||
|
||||
private GDHtmlLabel previewLabel;
|
||||
protected GList<T> list = new GList<>();
|
||||
protected DropDownList list = new DropDownList();
|
||||
|
||||
private WeakSet<DropDownSelectionChoiceListener<T>> choiceListeners =
|
||||
WeakDataStructureFactory.createSingleThreadAccessWeakSet();
|
||||
private Collection<CellEditorListener> cellEditorListeners = new HashSet<>();
|
||||
|
@ -82,7 +83,6 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
|||
private WindowComponentListener parentWindowListener = new WindowComponentListener();
|
||||
private T selectedValue;
|
||||
|
||||
private int cellHeight;
|
||||
private int matchingWindowHeight = MIN_HEIGHT;
|
||||
private Point lastLocation;
|
||||
protected final DropDownTextFieldDataModel<T> dataModel;
|
||||
|
@ -278,15 +278,6 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
|||
|
||||
private void initDataList() {
|
||||
|
||||
Font font = list.getFont();
|
||||
FontMetrics fontMetrics = list.getFontMetrics(font);
|
||||
int padding = 2; // top and bottom border height
|
||||
int lineHeight = fontMetrics.getHeight() + padding;
|
||||
int iconAndPaddingHeight = 16 + padding;
|
||||
cellHeight = Math.max(lineHeight, iconAndPaddingHeight);
|
||||
|
||||
list.setFixedCellHeight(cellHeight);
|
||||
list.setFixedCellWidth(MIN_WIDTH - 20); // add some fudge for scrollbars
|
||||
list.setCellRenderer(dataModel.getListRenderer());
|
||||
|
||||
list.addKeyListener(keyListener);
|
||||
|
@ -654,7 +645,7 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
|||
* signalling to use the clicked item. When pressing Enter, they may have been typing and
|
||||
* ignoring the list, so we have to do some validation.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // for the cast to T
|
||||
@SuppressWarnings("unchecked") // the item better be our type
|
||||
private void setTextFromListOnEnterPress() {
|
||||
Object selectedItem = list.getSelectedValue();
|
||||
if (selectedItem == null) {
|
||||
|
@ -747,6 +738,30 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
|||
// Inner Classes
|
||||
//=================================================================================================
|
||||
|
||||
protected class DropDownList extends GList<T> {
|
||||
@Override
|
||||
public void setFont(Font f) {
|
||||
super.setFont(f);
|
||||
updateCellDimensions(f);
|
||||
}
|
||||
|
||||
private void updateCellDimensions(Font font) {
|
||||
|
||||
if (font == null || list == null) {
|
||||
return; // UI is initializing
|
||||
}
|
||||
|
||||
FontMetrics fontMetrics = list.getFontMetrics(font);
|
||||
int padding = 2; // top and bottom border height
|
||||
int lineHeight = fontMetrics.getHeight() + padding;
|
||||
int iconAndPaddingHeight = 16 + padding;
|
||||
int cellHeight = Math.max(lineHeight, iconAndPaddingHeight);
|
||||
|
||||
list.setFixedCellHeight(cellHeight);
|
||||
list.setFixedCellWidth(MIN_WIDTH - 20); // add some fudge for scrollbars
|
||||
}
|
||||
}
|
||||
|
||||
private class HideWindowFocusListener extends FocusAdapter {
|
||||
@Override
|
||||
public void focusLost(FocusEvent event) {
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
*/
|
||||
package docking.widgets.dialogs;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
|
@ -26,6 +27,7 @@ import docking.DockingUtils;
|
|||
import docking.widgets.label.GDLabel;
|
||||
import docking.widgets.label.GLabel;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.framework.Platform;
|
||||
|
||||
|
@ -34,6 +36,8 @@ public class MultiLineInputDialog extends DialogComponentProvider {
|
|||
private static final KeyStroke SUBMIT_KEYSTROKE =
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, DockingUtils.CONTROL_KEY_MODIFIER_MASK);
|
||||
|
||||
private static final String FONT_ID = "font.input.hint";
|
||||
|
||||
private boolean isCanceled;
|
||||
private JTextArea inputTextArea;
|
||||
|
||||
|
@ -84,10 +88,7 @@ public class MultiLineInputDialog extends DialogComponentProvider {
|
|||
}
|
||||
JLabel hintLabel = new GLabel("(" + metaKeyText + "-Enter to accept)");
|
||||
hintLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
Font font = hintLabel.getFont();
|
||||
Font smallerFont = font.deriveFont(12F);
|
||||
Font smallItalicFont = smallerFont.deriveFont(Font.ITALIC);
|
||||
hintLabel.setFont(smallItalicFont);
|
||||
Gui.registerFont(hintLabel, FONT_ID);
|
||||
hintLabel.setForeground(Messages.HINT);
|
||||
|
||||
dataPanel.add(messageLabel, BorderLayout.NORTH);
|
||||
|
|
|
@ -49,39 +49,54 @@ class DirectoryList extends GList<File> implements GhidraFileChooserDirectoryMod
|
|||
|
||||
/**
|
||||
* Create a new DirectoryList instance.
|
||||
*
|
||||
*
|
||||
* @param chooser the {@link GhidraFileChooser} this instance is nested in
|
||||
* @param model the {@link DirectoryListModel}
|
||||
* @param font the parent component's font, used to calculate row height in the list once
|
||||
*/
|
||||
DirectoryList(GhidraFileChooser chooser, DirectoryListModel model, Font font) {
|
||||
DirectoryList(GhidraFileChooser chooser, DirectoryListModel model) {
|
||||
super(model);
|
||||
this.chooser = chooser;
|
||||
this.model = model;
|
||||
build(font);
|
||||
build();
|
||||
}
|
||||
|
||||
private void build(Font font) {
|
||||
@Override
|
||||
public void setFont(Font font) {
|
||||
super.setFont(font);
|
||||
updateCellDimensions(font);
|
||||
}
|
||||
|
||||
private void updateCellDimensions(Font font) {
|
||||
|
||||
if (font == null) {
|
||||
return; // UI is being updated
|
||||
}
|
||||
|
||||
FileListCellRenderer cellRenderer = (FileListCellRenderer) getCellRenderer();
|
||||
if (cellRenderer == null) {
|
||||
return; // initializing
|
||||
}
|
||||
|
||||
// Enable the list to calculate the width of the cells on its own, but manually specify the
|
||||
// height to ensure some padding between rows.
|
||||
//
|
||||
// Use 1/3 of the line height of the font to ensure visually consistent padding between
|
||||
// rows. (Historically, 5px was used as the padding between the default 12pt (15px line
|
||||
// height) rows, so 15px line height/5px padding equals .333 ratio.)
|
||||
FontMetrics metrics = cellRenderer.getFontMetrics(font);
|
||||
setFixedCellHeight(Math.max(metrics.getHeight(), DEFAULT_ICON_SIZE) +
|
||||
Math.max(metrics.getHeight() / 3, MIN_HEIGHT_PADDING));
|
||||
setFixedCellWidth(-1);
|
||||
}
|
||||
|
||||
private void build() {
|
||||
|
||||
setLayoutOrientation(JList.VERTICAL_WRAP);
|
||||
|
||||
FileListCellRenderer cellRenderer = new FileListCellRenderer(chooser);
|
||||
setCellRenderer(cellRenderer);
|
||||
|
||||
// Enable the list to calculate the width of the cells on its own, but manually
|
||||
// specify the height to ensure some padding between rows.
|
||||
// We need the parent component's Font instead of using our
|
||||
// own #getFont() because we are not a child of the parent yet and
|
||||
// the font may be set to something other than the default.
|
||||
// Use 1/3 of the line height of the font to ensure visually consistent
|
||||
// padding between rows. (historically, 5px was used as the padding
|
||||
// between the default 12pt (15px lineht) rows, so 15px lineht/5px padding
|
||||
// equals .333 ratio.)
|
||||
FontMetrics metrics = cellRenderer.getFontMetrics(font);
|
||||
setFixedCellHeight(
|
||||
Math.max(metrics.getHeight(), DEFAULT_ICON_SIZE) +
|
||||
Math.max(metrics.getHeight() / 3, MIN_HEIGHT_PADDING));
|
||||
setFixedCellWidth(-1);
|
||||
updateCellDimensions(getFont());
|
||||
|
||||
addMouseListener(new GMouseListenerAdapter() {
|
||||
@Override
|
||||
|
|
|
@ -558,7 +558,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
|
|||
|
||||
private JScrollPane buildDirectoryList() {
|
||||
directoryListModel = new DirectoryListModel();
|
||||
directoryList = new DirectoryList(this, directoryListModel, rootPanel.getFont());
|
||||
directoryList = new DirectoryList(this, directoryListModel);
|
||||
directoryList.setName("LIST");
|
||||
directoryList.setBackground(BACKGROUND_COLOR);
|
||||
|
||||
|
|
|
@ -51,18 +51,17 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||
private static final Color BG_DRAG = new GColor("color.bg.table.row.drag");
|
||||
|
||||
/*
|
||||
* The map uses thread local variables to ensure that rendering and background model
|
||||
* The map uses thread local variables to ensure that rendering and background model
|
||||
* manipulation are thread safe.
|
||||
*/
|
||||
private static Map<Integer, ThreadLocal<DecimalFormat>> decimalFormatCache =
|
||||
new HashMap<>();
|
||||
private static Map<Integer, ThreadLocal<DecimalFormat>> decimalFormatCache = new HashMap<>();
|
||||
static {
|
||||
|
||||
int n = FloatingPointPrecisionSettingsDefinition.MAX_PRECISION;
|
||||
for (int i = 0; i <= n; i++) {
|
||||
int precision = i;
|
||||
ThreadLocal<DecimalFormat> localFormatter = ThreadLocal.withInitial(
|
||||
() -> new DecimalFormat(createDecimalFormat(precision)));
|
||||
ThreadLocal<DecimalFormat> localFormatter =
|
||||
ThreadLocal.withInitial(() -> new DecimalFormat(createDecimalFormat(precision)));
|
||||
decimalFormatCache.put(precision, localFormatter);
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +83,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||
|
||||
/**
|
||||
* Constructs a new GTableCellRenderer using the specified font.
|
||||
*
|
||||
*
|
||||
* @param f the font to use when rendering text in the table cells
|
||||
*/
|
||||
public GTableCellRenderer(Font f) {
|
||||
|
@ -94,7 +93,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||
|
||||
/**
|
||||
* Return the cell renderer text
|
||||
*
|
||||
*
|
||||
* @param value Cell object value
|
||||
* @return A string interpretation of value; generated by calling value.toString()
|
||||
*/
|
||||
|
@ -149,7 +148,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||
* Provide basic cell rendering -- setting foreground and background colors, font, text,
|
||||
* alignment, drop color, and border. Additional data that may be of use to the renderer is
|
||||
* passed through the {@link docking.widgets.table.GTableCellRenderingData} object.
|
||||
*
|
||||
*
|
||||
* @param data Context data used in the rendering of a data cell.
|
||||
* @return The component used for drawing the table cell.
|
||||
*/
|
||||
|
@ -158,7 +157,6 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||
Object value = data.getValue();
|
||||
JTable table = data.getTable();
|
||||
int row = data.getRowViewIndex();
|
||||
int column = data.getColumnViewIndex();
|
||||
boolean isSelected = data.isSelected();
|
||||
boolean hasFocus = data.hasFocus();
|
||||
Settings settings = data.getColumnSettings();
|
||||
|
@ -173,7 +171,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||
}
|
||||
|
||||
TableModel model = table.getModel();
|
||||
configureFont(table, model, column);
|
||||
setFont(getDefaultFont());
|
||||
|
||||
if (isSelected) {
|
||||
setForeground(table.getSelectionForeground());
|
||||
|
@ -199,8 +197,14 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||
setForeground(table.getForeground());
|
||||
}
|
||||
|
||||
protected void configureFont(JTable table, TableModel model, int column) {
|
||||
setFont(defaultFont);
|
||||
/**
|
||||
* Override to change the font that will be used each time the renderer is initialized inside
|
||||
* of {@link #getTableCellRendererComponent(GTableCellRenderingData)}
|
||||
* @return the font
|
||||
*/
|
||||
@Override
|
||||
protected Font getDefaultFont() {
|
||||
return defaultFont;
|
||||
}
|
||||
|
||||
protected int getRadix(Settings settings) {
|
||||
|
@ -217,7 +221,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
|
|||
|
||||
/**
|
||||
* Format a Number per the Settings parameters.
|
||||
*
|
||||
*
|
||||
* @param value the number to format
|
||||
* @param settings settings controlling the display of the Number parameter
|
||||
* @return a formatted representation of the Number value
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package docking.widgets.textarea;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
|
||||
/**
|
||||
* Simple text area that shows a text hint when the field is empty.
|
||||
*
|
||||
* Hint text will be shown in light grey, italicized, and in angle brackets. Normal text will
|
||||
* be plain black.
|
||||
*/
|
||||
public class HintTextArea extends JTextArea {
|
||||
|
||||
private String hint;
|
||||
|
||||
/**
|
||||
* Constructs the class with the hint text to be shown.
|
||||
*
|
||||
* @param hint the hint
|
||||
*/
|
||||
public HintTextArea(String hint) {
|
||||
this.hint = hint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Need to override the setText method so we can set font attributes.
|
||||
*
|
||||
* @param text the text
|
||||
*/
|
||||
@Override
|
||||
public void setText(String text) {
|
||||
super.setText(text);
|
||||
setAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
if (getText().isEmpty()) {
|
||||
if (g instanceof Graphics2D) {
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
g2.setColor(Messages.HINT);
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
if (hint != null) {
|
||||
g2.drawString(hint, 5, 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text attributes to be used when NOT viewing the hint.
|
||||
*/
|
||||
protected void setAttributes() {
|
||||
this.setFont(getFont().deriveFont(Font.PLAIN));
|
||||
setForeground(Colors.FOREGROUND);
|
||||
}
|
||||
}
|
|
@ -67,7 +67,7 @@ public class HintTextField extends JTextField {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*
|
||||
* @param hint the hint text
|
||||
* @param required true, if the field should be marked as required
|
||||
* @param verifier input verifier, or null if none needed
|
||||
|
@ -78,7 +78,6 @@ public class HintTextField extends JTextField {
|
|||
this.verifier = verifier;
|
||||
|
||||
addListeners();
|
||||
setFont(getFont().deriveFont(Font.PLAIN));
|
||||
validateField();
|
||||
}
|
||||
|
||||
|
@ -143,7 +142,7 @@ public class HintTextField extends JTextField {
|
|||
/**
|
||||
* Sets whether the field is required or not. If so, it will be rendered
|
||||
* differently to indicate that to the user.
|
||||
*
|
||||
*
|
||||
* @param required true if required, false otherwise
|
||||
*/
|
||||
public void setRequired(boolean required) {
|
||||
|
@ -161,7 +160,7 @@ public class HintTextField extends JTextField {
|
|||
|
||||
/**
|
||||
* Returns true if the field contains valid input.
|
||||
*
|
||||
*
|
||||
* @return true if valid, false otherwise
|
||||
*/
|
||||
public boolean isFieldValid() {
|
||||
|
@ -179,7 +178,7 @@ public class HintTextField extends JTextField {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks the validity of the field and sets the appropriate
|
||||
* Checks the validity of the field and sets the appropriate
|
||||
* field attributes.
|
||||
*/
|
||||
private void validateField() {
|
||||
|
|
|
@ -28,6 +28,7 @@ import docking.ReusableDialogComponentProvider;
|
|||
import docking.widgets.EmptyBorderButton;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.*;
|
||||
import help.Help;
|
||||
import help.HelpService;
|
||||
|
@ -47,6 +48,8 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
|
|||
|
||||
private final static String INIT_TITLE = "<< untitled >>";
|
||||
|
||||
private static final String FONT_ID = "font.wizard.border.title";
|
||||
|
||||
private PanelManager panelMgr;
|
||||
private WizardPanel currWizPanel;
|
||||
private JButton backButton;
|
||||
|
@ -91,7 +94,7 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @see docking.wizard.WizardPanelListener#validityChanged()
|
||||
*/
|
||||
@Override
|
||||
|
@ -108,7 +111,7 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
|
|||
return getStatusText();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @see docking.wizard.WizardPanelListener#setStatusMessage(String)
|
||||
*/
|
||||
@Override
|
||||
|
@ -220,8 +223,7 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
|
|||
titleLabel = (wizardIcon == null ? new GDLabel(INIT_TITLE)
|
||||
: new GDLabel(INIT_TITLE, wizardIcon, SwingConstants.TRAILING));
|
||||
|
||||
EmptyBorderButton helpButton =
|
||||
new EmptyBorderButton(Icons.INFO_ICON);
|
||||
EmptyBorderButton helpButton = new EmptyBorderButton(Icons.INFO_ICON);
|
||||
helpButton.setToolTipText("Help (F1)");
|
||||
helpButton.addActionListener(
|
||||
e -> DockingWindowManager.getHelpService().showHelp(rootPanel, false, rootPanel));
|
||||
|
@ -438,7 +440,7 @@ if (!visitedMap.containsKey(currWizPanel)) {
|
|||
return; // nothing to do
|
||||
}
|
||||
|
||||
// this will have no effect if we are not showing, but the above call will handle that
|
||||
// this will have no effect if we are not showing, but the above call will handle that
|
||||
// case
|
||||
defaultFocusComponent.requestFocusInWindow();
|
||||
}
|
||||
|
@ -465,14 +467,12 @@ if (!visitedMap.containsKey(currWizPanel)) {
|
|||
if (scrollPane.getVerticalScrollBar().isShowing()) {
|
||||
TitledBorder titledBorder =
|
||||
new TitledBorder(BorderFactory.createEmptyBorder(), "(scroll for more options)");
|
||||
|
||||
Font font = titledBorder.getTitleFont();
|
||||
if (font == null) {
|
||||
// workaround for bug on Java 7
|
||||
font = titleLabel.getFont();
|
||||
}
|
||||
|
||||
titledBorder.setTitleFont(font.deriveFont(10f));
|
||||
Gui.addThemeListener(e -> {
|
||||
if (e.isFontChanged(FONT_ID)) {
|
||||
titledBorder.setTitleFont(Gui.getFont(FONT_ID));
|
||||
}
|
||||
});
|
||||
titledBorder.setTitleFont(Gui.getFont(FONT_ID));
|
||||
titledBorder.setTitleColor(Messages.NORMAL);
|
||||
titledBorder.setTitlePosition(TitledBorder.BOTTOM);
|
||||
titledBorder.setTitleJustification(TitledBorder.TRAILING);
|
||||
|
|
|
@ -15,20 +15,14 @@
|
|||
*/
|
||||
package ghidra.docking.util;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Taskbar;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
|
||||
import docking.framework.ApplicationInformationDisplayFactory;
|
||||
import generic.theme.LafType;
|
||||
import generic.theme.ThemeManager;
|
||||
import ghidra.framework.preferences.Preferences;
|
||||
import ghidra.util.SystemUtilities;
|
||||
|
||||
/**
|
||||
* A utility class to manage LookAndFeel (LaF) settings.
|
||||
|
@ -40,38 +34,12 @@ public class LookAndFeelUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads settings from {@link Preferences}.
|
||||
* This method does nothing. This is not handled by the theming system in the look and feel
|
||||
* manager.
|
||||
*/
|
||||
@Deprecated(since = "11.1", forRemoval = true)
|
||||
public static void installGlobalOverrides() {
|
||||
|
||||
//
|
||||
// Users can change this via the SystemUtilities.FONT_SIZE_OVERRIDE_PROPERTY_NAME
|
||||
// system property.
|
||||
//
|
||||
Integer fontOverride = SystemUtilities.getFontSizeOverrideValue();
|
||||
if (fontOverride != null) {
|
||||
setGlobalFontSizeOverride(fontOverride);
|
||||
}
|
||||
}
|
||||
|
||||
/** Allows you to globally set the font size (don't use this method!) */
|
||||
private static void setGlobalFontSizeOverride(int fontSize) {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
|
||||
Set<Entry<Object, Object>> set = defaults.entrySet();
|
||||
Iterator<Entry<Object, Object>> iterator = set.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Entry<Object, Object> entry = iterator.next();
|
||||
Object key = entry.getKey();
|
||||
|
||||
if (key.toString().toLowerCase().indexOf("font") != -1) {
|
||||
Font currentFont = defaults.getFont(key);
|
||||
if (currentFont != null) {
|
||||
Font newFont = currentFont.deriveFont((float) fontSize);
|
||||
UIManager.put(key, newFont);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void performPlatformSpecificFixups() {
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import docking.widgets.EmptyBorderButton;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.label.GDHtmlLabel;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||
import ghidra.util.datastruct.WeakSet;
|
||||
|
@ -43,6 +44,8 @@ import resources.Icons;
|
|||
*/
|
||||
public class TaskMonitorComponent extends JPanel implements TaskMonitor {
|
||||
|
||||
private static final String MESSAGE_FONT_ID = "font.task.monitor.label.message";
|
||||
|
||||
private WeakSet<CancelledListener> listeners =
|
||||
WeakDataStructureFactory.createCopyOnReadWeakSet();
|
||||
|
||||
|
@ -458,7 +461,7 @@ public class TaskMonitorComponent extends JPanel implements TaskMonitor {
|
|||
// don't care
|
||||
}
|
||||
};
|
||||
messageLabel.setFont(messageLabel.getFont().deriveFont((float) 10.0));
|
||||
Gui.registerFont(messageLabel, MESSAGE_FONT_ID);
|
||||
Dimension d = messageLabel.getPreferredSize();
|
||||
d.width = 180;
|
||||
messageLabel.setPreferredSize(d);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue