mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-1981 added quick font adjust action, cleaned up tempColorUtils
and converted File extension icons file to use theming
This commit is contained in:
parent
45395d7575
commit
c86b884daf
51 changed files with 513 additions and 477 deletions
|
@ -1,60 +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 ghidra.util;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
|
||||
public class UIManagerWrapper {
|
||||
|
||||
private static Map<String, Color> colorMap = new HashMap<>();
|
||||
private static Map<String, Border> borderMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
colorMap.put("Table[Enabled+Selected].textForeground", new Color(255, 255, 255));
|
||||
colorMap.put("Table[Enabled+Selected].textBackground", new Color(57, 105, 138));
|
||||
colorMap.put("Table.textForeground", new Color(35, 35, 36));
|
||||
colorMap.put("Table.alternateRowColor", new Color(237, 243, 254));
|
||||
colorMap.put("Table:\"Table.cellRenderer\".background", new Color(255, 255, 255));
|
||||
|
||||
borderMap.put("Table.focusCellHighlightBorder",
|
||||
BorderFactory.createEmptyBorder(2, 5, 2, 5));
|
||||
borderMap.put("Table.cellNoFocusBorder", BorderFactory.createEmptyBorder(2, 5, 2, 5));
|
||||
}
|
||||
|
||||
public static Color getColor(String text) {
|
||||
UIDefaults uiDefaults = UIManager.getDefaults();
|
||||
Color color = uiDefaults.getColor(text);
|
||||
if (color == null) {
|
||||
color = colorMap.get(text);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
public static Border getBorder(String text) {
|
||||
UIDefaults uiDefaults = UIManager.getDefaults();
|
||||
Border border = uiDefaults.getBorder(text);
|
||||
if (border == null) {
|
||||
border = borderMap.get(text);
|
||||
}
|
||||
return border;
|
||||
}
|
||||
|
||||
}
|
|
@ -41,7 +41,7 @@ import com.google.common.collect.Iterators;
|
|||
import db.DBHandle;
|
||||
import db.DBRecord;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.LockHold;
|
||||
import ghidra.util.database.*;
|
||||
import ghidra.util.database.annot.*;
|
||||
|
@ -566,13 +566,13 @@ public class RStarTreeMapTest {
|
|||
|
||||
public void selectColor(Graphics g, NodeType type) {
|
||||
if (type.isLeaf()) {
|
||||
g.setColor(TempColorUtils.fromRgba(179, 0, 0, 128));
|
||||
g.setColor(ColorUtils.getColor(179, 0, 0, 128));
|
||||
}
|
||||
else if (type.isLeafParent()) {
|
||||
g.setColor(TempColorUtils.fromRgba(0, 179, 0, 128));
|
||||
g.setColor(ColorUtils.getColor(0, 179, 0, 128));
|
||||
}
|
||||
else {
|
||||
g.setColor(TempColorUtils.fromRgba(0, 0, 179, 128));
|
||||
g.setColor(ColorUtils.getColor(0, 0, 179, 128));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -610,7 +610,7 @@ public class RStarTreeMapTest {
|
|||
@Override
|
||||
protected VisitResult visitData(DBIntRectNodeRecord parent,
|
||||
DBIntRectStringDataRecord d, boolean included) {
|
||||
g.setColor(TempColorUtils.fromRgba(0, 0, 0, 128));
|
||||
g.setColor(ColorUtils.getColor(0, 0, 0, 128));
|
||||
drawRect(g, d.getShape(), true);
|
||||
return VisitResult.NEXT;
|
||||
}
|
||||
|
@ -876,7 +876,6 @@ public class RStarTreeMapTest {
|
|||
List<Pair<IntRect, String>> entries = generateRandom(rect(0, 100, 0, 100), 10, 10, 1000);
|
||||
Consumer<List<Pair<IntRect, String>>> inserter = list -> {
|
||||
try (UndoableTransaction tid = UndoableTransaction.start(obj, "AddRandom")) {
|
||||
int i = 0;
|
||||
for (Entry<IntRect, String> ent : list) {
|
||||
obj.map.put(ent.getKey(), ent.getValue());
|
||||
// Note, underlying tree is not synchronized, but map is
|
||||
|
|
|
@ -81,6 +81,7 @@ data/symbols/win64/mfc80u.exports||GHIDRA||||END|
|
|||
data/symbols/win64/mfc90.exports||GHIDRA||||END|
|
||||
data/symbols/win64/mfc90u.exports||GHIDRA||||END|
|
||||
data/symbols/win64/msvcrt.hints||GHIDRA||||END|
|
||||
data/typeinfo/file.extensions.icons.theme.properties||GHIDRA||||END|
|
||||
data/typeinfo/generic/generic_clib.gdt||GHIDRA||||END|
|
||||
data/typeinfo/generic/generic_clib_64.gdt||GHIDRA||||END|
|
||||
data/typeinfo/mac_10.9/mac_osx.gdt||GHIDRA||||END|
|
||||
|
|
|
@ -48,7 +48,6 @@ icon.plugin.bookmark.type.error = icon.base.delete
|
|||
icon.plugin.bookmark.type.analysis = applications-system.png
|
||||
icon.plugin.bookmark.type.default = unknown.gif
|
||||
|
||||
icon.plugin.calltree.provider =
|
||||
icon.plugin.calltree.function = FunctionScope.gif
|
||||
icon.plugin.calltree.recursive = arrow_rotate_clockwise.png
|
||||
icon.plugin.calltree.refresh = icon.refresh
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
[Defaults]
|
||||
|
||||
// Only single level file exts supported right now
|
||||
icon.fsbrowser.file.extension.default = images/famfamfam_silk_icons_v013/page_white.png
|
||||
icon.fsbrowser.file.extension.apk = images/famfamfam_silk_icons_v013/package.png
|
||||
icon.fsbrowser.file.extension.c = images/text-x-csrc.png
|
||||
icon.fsbrowser.file.extension.cpp = images/oxygen/16x16/text-x-c++src.png
|
||||
icon.fsbrowser.file.extension.class = images/famfamfam_silk_icons_v013/cup.png
|
||||
icon.fsbrowser.file.extension.cs = images/oxygen/16x16/text-x-csharp.png
|
||||
icon.fsbrowser.file.extension.css = images/famfamfam_silk_icons_v013/css.png
|
||||
icon.fsbrowser.file.extension.data = images/famfamfam_silk_icons_v013/database.png
|
||||
icon.fsbrowser.file.extension.dfu = images/famfamfam_silk_icons_v013/bullet_blue.png
|
||||
icon.fsbrowser.file.extension.dmg = images/famfamfam_silk_icons_v013/bullet_green.png
|
||||
icon.fsbrowser.file.extension.f = images/F.gif
|
||||
icon.fsbrowser.file.extension.h = images/oxygen/16x16/text-x-chdr.png
|
||||
icon.fsbrowser.file.extension.html = images/famfamfam_silk_icons_v013/html.png
|
||||
icon.fsbrowser.file.extension.img = images/famfamfam_silk_icons_v013/images.png
|
||||
icon.fsbrowser.file.extension.img3 = images/famfamfam_silk_icons_v013/bullet_orange.png
|
||||
icon.fsbrowser.file.extension.index = images/oxygen/16x16/bookmarks.png
|
||||
icon.fsbrowser.file.extension.ipsw = images/oxygen/16x16/multimedia-player-apple-ipod.png
|
||||
icon.fsbrowser.file.extension.iso = images/nuvola/16x16/cdimage.png
|
||||
icon.fsbrowser.file.extension.jar = images/oxygen/16x16/application-x-java-archive.png
|
||||
icon.fsbrowser.file.extension.java = images/famfamfam_silk_icons_v013/page_white_cup.png
|
||||
icon.fsbrowser.file.extension.kext = images/famfamfam_silk_icons_v013/bullet_pink.png
|
||||
icon.fsbrowser.file.extension.lib = images/famfamfam_silk_icons_v013/server.png
|
||||
icon.fsbrowser.file.extension.obj = images/oxygen/16x16/application-x-subrip.png
|
||||
icon.fsbrowser.file.extension.p = images/oxygen/16x16/text-x-pascal.png
|
||||
icon.fsbrowser.file.extension.pdf = images/oxygen/16x16/application-pdf.png
|
||||
icon.fsbrowser.file.extension.plist = images/oxygen/16x16/insert-table.png
|
||||
icon.fsbrowser.file.extension.png = images/famfamfam_silk_icons_v013/bullet_red.png
|
||||
icon.fsbrowser.file.extension.rss = images/famfamfam_silk_icons_v013/rss.png
|
||||
icon.fsbrowser.file.extension.strings = images/oxygen/16x16/insert-text.png
|
||||
icon.fsbrowser.file.extension.txt = images/oxygen/16x16/text-x-bibtex.png
|
||||
icon.fsbrowser.file.extension.usb = images/nuvola/16x16/usb.png
|
||||
icon.fsbrowser.file.extension.xhtml = images/famfamfam_silk_icons_v013/xhtml.png
|
||||
icon.fsbrowser.file.extension.xml = images/oxygen/16x16/text-xml.png
|
||||
icon.fsbrowser.file.extension.zip = images/oxygen/16x16/application-x-bzip.png
|
||||
|
||||
icon.fsbrowser.file.substring.release. = images/famfamfam_silk_icons_v013/bullet_purple.png
|
||||
|
||||
icon.fsbrowser.file.overlay.imported = images/checkmark_green.gif
|
||||
icon.fsbrowser.file.overlay.filesystem = EMPTY_ICON{images/nuvola/16x16/ledgreen.png[size(8,8)][move(8,8)]} // lower right quadrant
|
||||
icon.fsbrowser.file.overlay.missing.password = EMPTY_ICON{images/lock.png[size(8,8)][move(8,0)]} // upper right quadrant
|
|
@ -48,6 +48,7 @@ import ghidra.app.util.viewer.field.FieldFactory;
|
|||
import ghidra.app.util.viewer.format.*;
|
||||
import ghidra.app.util.viewer.listingpanel.*;
|
||||
import ghidra.app.util.viewer.multilisting.MultiListingLayoutModel;
|
||||
import ghidra.app.util.viewer.options.ListingDisplayOptionsEditor;
|
||||
import ghidra.app.util.viewer.util.FieldNavigator;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.NavigatableComponentProviderAdapter;
|
||||
|
@ -128,7 +129,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
|||
// note: the owner has not changed, just the name; remove sometime after version 10
|
||||
String owner = plugin.getName();
|
||||
ComponentProvider.registerProviderNameOwnerChange(OLD_NAME, owner, NAME, owner);
|
||||
|
||||
registerAdjustableFontId(ListingDisplayOptionsEditor.DEFAULT_FONT_ID);
|
||||
setConnected(isConnected);
|
||||
setIcon(new GIcon("icon.plugin.codebrowser.provider"));
|
||||
if (!isConnected) {
|
||||
|
|
|
@ -18,9 +18,9 @@ package ghidra.app.plugin.core.codebrowser;
|
|||
import java.awt.Color;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.app.util.viewer.listingpanel.ListingBackgroundColorModel;
|
||||
import ghidra.app.util.viewer.listingpanel.ListingPanel;
|
||||
import ghidra.util.ColorUtils;
|
||||
|
||||
/**
|
||||
* Class for blending two {@link ListingBackgroundColorModel}s. If neither model has a color
|
||||
|
@ -53,7 +53,7 @@ public class LayeredColorModel implements ListingBackgroundColorModel {
|
|||
}
|
||||
|
||||
private Color blend(Color primary, Color secondary) {
|
||||
return TempColorUtils.blend1(primary, secondary);
|
||||
return ColorUtils.blend(primary, secondary, 0.67);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,7 +25,6 @@ import docking.ActionContext;
|
|||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.context.ListingActionContext;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
|
@ -43,6 +42,7 @@ import ghidra.program.model.address.*;
|
|||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ChangeManager;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.task.SwingUpdateManager;
|
||||
|
||||
|
@ -109,8 +109,8 @@ public class ColorizingPlugin extends ProgramPlugin implements DomainObjectListe
|
|||
List<Element> colorElements = xmlElement.getChildren("COLOR");
|
||||
for (Element element : colorElements) {
|
||||
String rgbString = element.getAttributeValue("RGB");
|
||||
int rgb = Integer.parseInt(rgbString);
|
||||
savedColorHistory.add(TempColorUtils.fromRgba(rgb));
|
||||
int rgba = Integer.parseInt(rgbString);
|
||||
savedColorHistory.add(ColorUtils.getColor(rgba));
|
||||
}
|
||||
|
||||
service.setColorHistory(savedColorHistory);
|
||||
|
|
|
@ -22,12 +22,12 @@ import java.util.List;
|
|||
import docking.options.editor.GhidraColorChooser;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.app.util.viewer.listingpanel.PropertyBasedBackgroundColorModel;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.database.IntRangeMap;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
class ColorizingServiceProvider implements ColorizingService {
|
||||
|
@ -136,9 +136,9 @@ class ColorizingServiceProvider implements ColorizingService {
|
|||
public Color getBackgroundColor(Address address) {
|
||||
IntRangeMap map = getColorRangeMap(false);
|
||||
if (map != null) {
|
||||
Integer value = map.getValue(address);
|
||||
if (value != null) {
|
||||
return TempColorUtils.fromRgba(value);
|
||||
Integer rgba = map.getValue(address);
|
||||
if (rgba != null) {
|
||||
return ColorUtils.getColor(rgba);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -20,8 +20,8 @@ import java.awt.Color;
|
|||
import javax.swing.text.*;
|
||||
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.app.plugin.core.interpreter.AnsiParser.AnsiParserHandler;
|
||||
import ghidra.util.ColorUtils;
|
||||
|
||||
/**
|
||||
* An object for parsing and rendering ANSI-styled strings into a Swing {@link Document}.
|
||||
|
@ -103,12 +103,12 @@ public class AnsiRenderer {
|
|||
int b = v % 6;
|
||||
int g = (v / 6) % 6;
|
||||
int r = (v / 36) % 6;
|
||||
return TempColorUtils.fromRgb(CUBE_STEPS[r], CUBE_STEPS[g], CUBE_STEPS[b]);
|
||||
return ColorUtils.getColor(CUBE_STEPS[r], CUBE_STEPS[g], CUBE_STEPS[b]);
|
||||
}
|
||||
else if (v < 256) {
|
||||
v -= 232;
|
||||
int gray = v * 10 + 8;
|
||||
return TempColorUtils.fromRgb(gray, gray, gray);
|
||||
return ColorUtils.getColor(gray, gray, gray);
|
||||
}
|
||||
else {
|
||||
/* invalid */
|
||||
|
@ -158,7 +158,7 @@ public class AnsiRenderer {
|
|||
int r = Integer.parseInt(bits[pos + 2]);
|
||||
int g = Integer.parseInt(bits[pos + 3]);
|
||||
int b = Integer.parseInt(bits[pos + 4]);
|
||||
attributes.addAttribute(attributeName, TempColorUtils.fromRgb(r, g, b));
|
||||
attributes.addAttribute(attributeName, ColorUtils.getColor(r, g, b));
|
||||
return 5;
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -27,7 +27,6 @@ import javax.swing.ImageIcon;
|
|||
import docking.widgets.fieldpanel.support.FieldRange;
|
||||
import docking.widgets.fieldpanel.support.FieldSelection;
|
||||
import generic.json.Json;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.app.services.MarkerDescriptor;
|
||||
import ghidra.app.services.MarkerSet;
|
||||
import ghidra.app.util.viewer.listingpanel.VerticalPixelAddressMap;
|
||||
|
@ -36,6 +35,7 @@ import ghidra.program.model.address.*;
|
|||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.MarkerLocation;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.datastruct.SortedRangeList;
|
||||
|
||||
|
@ -260,7 +260,10 @@ abstract class MarkerSetImpl implements MarkerSet {
|
|||
}
|
||||
|
||||
protected static Color getFillColor(Color c) {
|
||||
return TempColorUtils.blend2(c, COLOR_VALUE);
|
||||
int red = (c.getRed() + 3 * COLOR_VALUE) / 4;
|
||||
int green = (c.getGreen() + 3 * COLOR_VALUE) / 4;
|
||||
int blue = (c.getBlue() + 3 * COLOR_VALUE) / 4;
|
||||
return ColorUtils.getColor(red, green, blue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/* ###
|
||||
* 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 ghidra.app.plugin.core.misc;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.ComponentProvider;
|
||||
import docking.action.builder.ActionBuilder;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
/**
|
||||
* Manages the markers to display areas where changes have occurred
|
||||
*/
|
||||
@PluginInfo( //@formatter:off
|
||||
status = PluginStatus.RELEASED,
|
||||
packageName = CorePluginPackage.NAME,
|
||||
category = PluginCategoryNames.MISC,
|
||||
shortDescription = "Provides generic actions for increasing/decreasing fonts.",
|
||||
description = "This plugin provides actions for increasing fonts used by component providers. "+
|
||||
"ComponentProviders can either override the \"changeFontSize()\" method or register a" +
|
||||
"theme font id that can be automatically adjusted."
|
||||
) //@formatter:on
|
||||
|
||||
public class FontAdjustPlugin extends Plugin {
|
||||
public FontAdjustPlugin(PluginTool tool) {
|
||||
|
||||
super(tool);
|
||||
|
||||
new ActionBuilder("Increment Font", "tool")
|
||||
.keyBinding("ctrl EQUALS")
|
||||
.onAction(this::incrementFont)
|
||||
.buildAndInstall(tool);
|
||||
|
||||
new ActionBuilder("Decrement Font", "tool")
|
||||
.keyBinding("ctrl MINUS")
|
||||
.onAction(this::decrementFont)
|
||||
.buildAndInstall(tool);
|
||||
|
||||
}
|
||||
|
||||
private void incrementFont(ActionContext context) {
|
||||
Msg.debug(this, "incrementFont");
|
||||
ComponentProvider provider = context.getComponentProvider();
|
||||
if (provider != null) {
|
||||
provider.adjustFontSize(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void decrementFont(ActionContext context) {
|
||||
Msg.debug(this, "decrementFont");
|
||||
ComponentProvider provider = context.getComponentProvider();
|
||||
if (provider != null) {
|
||||
provider.adjustFontSize(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,7 @@ import java.util.ArrayList;
|
|||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||
import ghidra.util.datastruct.WeakSet;
|
||||
|
||||
|
@ -76,7 +76,7 @@ public class OverviewPalette {
|
|||
int green = (int) (lo.getGreen() * (1.0 - t) + hi.getGreen() * t);
|
||||
int blue = (int) (lo.getBlue() * (1.0 - t) + hi.getGreen() * t);
|
||||
t += step;
|
||||
colors[i] = TempColorUtils.fromRgb(red, green, blue);
|
||||
colors[i] = ColorUtils.getColor(red, green, blue);
|
||||
}
|
||||
knots.clear();
|
||||
firePaletteChanged();
|
||||
|
@ -112,7 +112,7 @@ public class OverviewPalette {
|
|||
int green = (int) Math.floor(tmp);
|
||||
tmp = (knot.getBlue() - oldcolor.getBlue()) * t + oldcolor.getBlue();
|
||||
int blue = (int) Math.floor(tmp);
|
||||
colors[start] = TempColorUtils.fromRgb(red, green, blue);
|
||||
colors[start] = ColorUtils.getColor(red, green, blue);
|
||||
cur += radianstep;
|
||||
start += 1;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,8 @@ import generic.theme.Gui;
|
|||
|
||||
public class FixedBitSizeValueField extends JPanel {
|
||||
|
||||
private static final Icon DROP_DOWN_MENU_ICON = new GIcon("icon.base.app.fixed.bit.size.field");
|
||||
private static final Icon DROP_DOWN_MENU_ICON =
|
||||
new GIcon("icon.base.util.fixed.bit.size.field");
|
||||
|
||||
protected JTextField valueField;
|
||||
protected JButton menuButton;
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.util.Map;
|
|||
|
||||
import docking.widgets.fieldpanel.support.BackgroundColorModel;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||
import ghidra.framework.model.DomainObjectChangedEvent;
|
||||
import ghidra.framework.model.DomainObjectListener;
|
||||
|
@ -30,6 +29,7 @@ import ghidra.program.database.IntRangeMap;
|
|||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ChangeManager;
|
||||
import ghidra.util.ColorUtils;
|
||||
|
||||
/**
|
||||
* Default {@link BackgroundColorModel} for the ListingPanel where the color returned
|
||||
|
@ -95,7 +95,7 @@ public class PropertyBasedBackgroundColorModel
|
|||
}
|
||||
Color c = colorCache.get(value);
|
||||
if (c == null) {
|
||||
c = TempColorUtils.fromRgba(value);
|
||||
c = ColorUtils.getColor(value);
|
||||
colorCache.put(value, c);
|
||||
}
|
||||
return c;
|
||||
|
|
|
@ -24,12 +24,12 @@ import javax.swing.KeyStroke;
|
|||
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.framework.options.*;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.util.*;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.XmlProgramUtilities;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
@ -255,7 +255,7 @@ class PropertiesXmlMgr {
|
|||
}
|
||||
else if ("color".equals(type)) {
|
||||
Color color =
|
||||
TempColorUtils.fromRgb(XmlUtilities.parseInt(element.getAttribute("VALUE")));
|
||||
ColorUtils.getColor(XmlUtilities.parseInt(element.getAttribute("VALUE")));
|
||||
list.setColor(name, color);
|
||||
}
|
||||
else if ("file".equals(type)) {
|
||||
|
|
|
@ -15,23 +15,13 @@
|
|||
*/
|
||||
package ghidra.plugins.fsbrowser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import org.jdom.*;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.theme.*;
|
||||
import ghidra.formats.gfilesystem.FSUtilities;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.xml.XmlUtilities;
|
||||
import resources.*;
|
||||
import util.CollectionUtils;
|
||||
import resources.MultiIcon;
|
||||
|
||||
/**
|
||||
* Provides {@link Icon}s that represent the type and status of a file, based on
|
||||
|
@ -58,76 +48,33 @@ public class FileIconService {
|
|||
return Singleton.INSTANCE;
|
||||
}
|
||||
|
||||
public static final String OVERLAY_IMPORTED = "imported";
|
||||
public static final String OVERLAY_FILESYSTEM = "filesystem";
|
||||
public static final String OVERLAY_MISSING_PASSWORD = "password_missing";
|
||||
public static final Icon IMPORTED_OVERLAY_ICON =
|
||||
new GIcon("icon.fsbrowser.file.overlay.imported");
|
||||
public static final Icon FILESYSTEM_OVERLAY_ICON =
|
||||
new GIcon("icon.fsbrowser.file.overlay.filesystem");
|
||||
public static final Icon MISSING_PASSWORD_OVERLAY_ICON =
|
||||
new GIcon("icon.fsbrowser.file.overlay.missing.password");
|
||||
public static final Icon DEFAULT_ICON = new GIcon("icon.fsbrowser.file.extension.default");
|
||||
|
||||
private static final String FILEEXT_MAPPING_FILE = "file_extension_icons.xml";
|
||||
private static final String EXTENSION_ICON_PREFIX = "icon.fsbrowser.file.extension";
|
||||
private static final String SUBSTRING_ICON_PREFIX = "icon.fsbrowser.file.substring";
|
||||
|
||||
private Map<String, String> fileExtToIconName = new HashMap<>();
|
||||
private Map<String, String> fileSubstrToIconName = new HashMap<>();
|
||||
private Map<String, String> overlayNameToIconName = new HashMap<>();
|
||||
private Map<String, QUADRANT> overlayNameToQuad = new HashMap<>();
|
||||
private String defaultIconPath = "images/famfamfam_silk_icons_v013/page_white.png";
|
||||
private int maxExtLevel = 1;
|
||||
|
||||
private Map<String, Icon> iconKeyToIcon = new HashMap<>();
|
||||
|
||||
private ResourceFile xmlFile;
|
||||
private Map<String, Icon> substringToIconMap = new HashMap<>();
|
||||
|
||||
private FileIconService() {
|
||||
this.xmlFile = Application.findDataFileInAnyModule(FILEEXT_MAPPING_FILE);
|
||||
if (xmlFile == null) {
|
||||
Msg.error(this, "Cannot find " + FILEEXT_MAPPING_FILE +
|
||||
". File system browser will not have icons.");
|
||||
}
|
||||
createSubstringMap();
|
||||
}
|
||||
|
||||
private String makeKey(String key, String[] overlays) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(key).append("__");
|
||||
for (String o : overlays) {
|
||||
if (o == null || o.isEmpty()) {
|
||||
continue;
|
||||
private void createSubstringMap() {
|
||||
GThemeValueMap values = Gui.getAllValues();
|
||||
List<IconValue> icons = values.getIcons();
|
||||
for (IconValue iconValue : icons) {
|
||||
String id = iconValue.getId();
|
||||
if (id.startsWith(SUBSTRING_ICON_PREFIX)) {
|
||||
String substring = id.substring(SUBSTRING_ICON_PREFIX.length());
|
||||
substringToIconMap.put(substring, new GIcon(id));
|
||||
}
|
||||
sb.append(o).append("__");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private Icon getCachedIcon(String key, String path, String... overlays) {
|
||||
key = makeKey(key, overlays);
|
||||
Icon cachedIcon = iconKeyToIcon.get(key);
|
||||
if (cachedIcon == null) {
|
||||
cachedIcon = ResourceManager.loadImage(path);
|
||||
if (overlays.length > 0) {
|
||||
int expectedOW = cachedIcon.getIconWidth() / 2;
|
||||
int expectedOH = cachedIcon.getIconHeight() / 2;
|
||||
|
||||
EnumSet<QUADRANT> usedQuads = EnumSet.noneOf(QUADRANT.class);
|
||||
MultiIconBuilder iconBuilder = new MultiIconBuilder(cachedIcon);
|
||||
for (String overlay : overlays) {
|
||||
if (overlay == null || overlay.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String overlayPath = overlayNameToIconName.get(overlay);
|
||||
QUADRANT quad = overlayNameToQuad.get(overlay);
|
||||
if (overlayPath == null || quad == null) {
|
||||
continue;
|
||||
}
|
||||
if (usedQuads.contains(quad)) {
|
||||
Msg.warn(this, "File icon already contains an overlay at " + quad);
|
||||
}
|
||||
usedQuads.add(quad);
|
||||
|
||||
ImageIcon overlayIcon = ResourceManager.loadImage(overlayPath);
|
||||
iconBuilder.addIcon(overlayIcon, expectedOW, expectedOH, quad);
|
||||
}
|
||||
cachedIcon = iconBuilder.build();
|
||||
}
|
||||
iconKeyToIcon.put(key, cachedIcon);
|
||||
}
|
||||
return cachedIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,106 +82,43 @@ public class FileIconService {
|
|||
* name.
|
||||
*
|
||||
* @param fileName name of file that an icon is being requested for.
|
||||
* @param overlays optional list of overlay names, names of icons that
|
||||
* should be overlaid on top of the base icon, that represent a
|
||||
* @param overlays optional list of overlay icons that
|
||||
* should be overlaid on top of the base icon. These icons represent a
|
||||
* status or feature independent of the file's base icon.
|
||||
* @return {@link Icon} instance that best represents the named file, never
|
||||
* null.
|
||||
*/
|
||||
public synchronized Icon getImage(String fileName, String... overlays) {
|
||||
loadIfNeeded();
|
||||
|
||||
public Icon getIcon(String fileName, List<Icon> overlays) {
|
||||
fileName = fileName.toLowerCase();
|
||||
for (int extLevel = 1; extLevel <= maxExtLevel; extLevel++) {
|
||||
String ext = FSUtilities.getExtension(fileName, extLevel);
|
||||
if (ext == null) {
|
||||
break;
|
||||
}
|
||||
String path = fileExtToIconName.get(ext);
|
||||
if (path != null) {
|
||||
return getCachedIcon(ext, path, overlays);
|
||||
String ext = FSUtilities.getExtension(fileName, 1);
|
||||
if (ext != null) {
|
||||
String iconId = EXTENSION_ICON_PREFIX + ext;
|
||||
if (Gui.hasIcon(iconId)) {
|
||||
Icon base = new GIcon(iconId);
|
||||
return buildIcon(base, overlays);
|
||||
}
|
||||
}
|
||||
|
||||
for (String substr : fileSubstrToIconName.keySet()) {
|
||||
if (fileName.indexOf(substr) != -1) {
|
||||
return getCachedIcon("####" + substr, fileSubstrToIconName.get(substr), overlays);
|
||||
for (String substring : substringToIconMap.keySet()) {
|
||||
if (fileName.indexOf(substring) != -1) {
|
||||
return buildIcon(substringToIconMap.get(substring), overlays);
|
||||
}
|
||||
}
|
||||
|
||||
// return default icon for generic file
|
||||
return getCachedIcon("", defaultIconPath, overlays);
|
||||
return buildIcon(DEFAULT_ICON, overlays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads XML file if it has not been loaded yet.
|
||||
*/
|
||||
protected void loadIfNeeded() {
|
||||
if (fileExtToIconName.isEmpty()) {
|
||||
load();
|
||||
private Icon buildIcon(Icon base, List<Icon> overlays) {
|
||||
if (overlays == null || overlays.isEmpty()) {
|
||||
return base;
|
||||
}
|
||||
MultiIcon multiIcon = new MultiIcon(base);
|
||||
for (Icon overlay : overlays) {
|
||||
if (overlay != null) {
|
||||
multiIcon.addIcon(overlay);
|
||||
}
|
||||
}
|
||||
|
||||
private void load() {
|
||||
fileExtToIconName.clear();
|
||||
fileSubstrToIconName.clear();
|
||||
overlayNameToIconName.clear();
|
||||
overlayNameToQuad.clear();
|
||||
iconKeyToIcon.clear();
|
||||
defaultIconPath = null;
|
||||
maxExtLevel = 1;
|
||||
|
||||
try (InputStream xmlInputStream = xmlFile.getInputStream()) {
|
||||
SAXBuilder sax = XmlUtilities.createSecureSAXBuilder(false, false);
|
||||
Document doc = sax.build(xmlInputStream);
|
||||
Element root = doc.getRootElement();
|
||||
for (Element child : CollectionUtils.asList(root.getChildren("file_extension"),
|
||||
Element.class)) {
|
||||
String extension = child.getAttributeValue("extension");
|
||||
String iconPath = child.getAttributeValue("icon");
|
||||
if (extension.endsWith(".")) {
|
||||
addSubstrMapping(extension, iconPath);
|
||||
return multiIcon;
|
||||
}
|
||||
else if (!extension.isEmpty()) {
|
||||
addExtMapping(extension, iconPath);
|
||||
}
|
||||
else {
|
||||
defaultIconPath = iconPath;
|
||||
}
|
||||
}
|
||||
for (Element child : CollectionUtils.asList(root.getChildren("file_overlay"),
|
||||
Element.class)) {
|
||||
String name = child.getAttributeValue("name");
|
||||
String iconPath = child.getAttributeValue("icon");
|
||||
QUADRANT quadrant =
|
||||
QUADRANT.valueOf(child.getAttributeValue("quadrant"), QUADRANT.LR);
|
||||
|
||||
overlayNameToIconName.put(name, iconPath);
|
||||
overlayNameToQuad.put(name, quadrant);
|
||||
}
|
||||
}
|
||||
catch (JDOMException | IOException e) {
|
||||
Msg.error(this, "Error reading file icon data: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void addSubstrMapping(String substr, String iconPath) {
|
||||
fileSubstrToIconName.put(substr, iconPath);
|
||||
}
|
||||
|
||||
private void addExtMapping(String ext, String iconPath) {
|
||||
fileExtToIconName.put(ext, iconPath);
|
||||
maxExtLevel = Math.max(maxExtLevel, countExtLevel(ext));
|
||||
}
|
||||
|
||||
private int countExtLevel(String ext) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < ext.length(); i++) {
|
||||
if (ext.charAt(i) == '.') {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -129,29 +129,28 @@ class FileSystemBrowserComponentProvider extends ComponentProviderAdapter
|
|||
String containerFilename =
|
||||
fsFSRL.hasContainer() ? fsFSRL.getContainer().getName() : "unknown";
|
||||
Icon image = FileIconService.getInstance()
|
||||
.getImage(containerFilename,
|
||||
FileIconService.OVERLAY_FILESYSTEM);
|
||||
.getIcon(containerFilename,
|
||||
List.of(FileIconService.FILESYSTEM_OVERLAY_ICON));
|
||||
setIcon(image);
|
||||
}
|
||||
|
||||
private void renderFile(FSBFileNode node, boolean selected) {
|
||||
FSRL fsrl = node.getFSRL();
|
||||
String filename = fsrl.getName();
|
||||
List<Icon> overlays = new ArrayList<>(3);
|
||||
|
||||
String importOverlay = ProgramMappingService.isFileImportedIntoProject(fsrl)
|
||||
? FileIconService.OVERLAY_IMPORTED
|
||||
: null;
|
||||
String mountedOverlay = fsService.isFilesystemMountedAt(fsrl)
|
||||
? FileIconService.OVERLAY_FILESYSTEM
|
||||
: null;
|
||||
if (ProgramMappingService.isFileImportedIntoProject(fsrl)) {
|
||||
overlays.add(FileIconService.IMPORTED_OVERLAY_ICON);
|
||||
}
|
||||
if (fsService.isFilesystemMountedAt(fsrl)) {
|
||||
overlays.add(FileIconService.FILESYSTEM_OVERLAY_ICON);
|
||||
}
|
||||
if (node.hasMissingPassword()) {
|
||||
overlays.add(FileIconService.MISSING_PASSWORD_OVERLAY_ICON);
|
||||
}
|
||||
|
||||
String missingPasswordOverlay = node.hasMissingPassword()
|
||||
? FileIconService.OVERLAY_MISSING_PASSWORD
|
||||
: null;
|
||||
|
||||
Icon ico = FileIconService.getInstance()
|
||||
.getImage(filename, importOverlay, mountedOverlay, missingPasswordOverlay);
|
||||
setIcon(ico);
|
||||
Icon icon = FileIconService.getInstance().getIcon(filename, overlays);
|
||||
setIcon(icon);
|
||||
|
||||
if (ProgramMappingService.isFileOpen(fsrl)) {
|
||||
// TODO: change this to a OVERLAY_OPEN option when fetching icon
|
||||
|
|
|
@ -50,7 +50,6 @@ import generic.test.AbstractGenericTest;
|
|||
import generic.theme.GThemeDefaults.Colors;
|
||||
import generic.theme.GThemeDefaults.Colors.Java;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.TempColorUtils;
|
||||
import generic.util.image.ImageUtils;
|
||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||
import ghidra.app.plugin.core.analysis.AnalysisOptionsDialog;
|
||||
|
@ -80,6 +79,7 @@ import ghidra.program.model.listing.Program;
|
|||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.test.TestEnv;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import resources.ResourceManager;
|
||||
|
||||
|
@ -794,14 +794,14 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
|
|||
for (Component component : comps) {
|
||||
int pad = 6;
|
||||
Point p = component.getLocationOnScreen();
|
||||
g.setColor(TempColorUtils.fromRgb(250, 250, 250)); // just slightly not white
|
||||
g.setColor(ColorUtils.getOpaqueColor(0xfafafa)); // just slightly not white
|
||||
g.fillRoundRect(p.x - rect.x - pad, p.y - rect.y - pad, component.getWidth() + pad * 2,
|
||||
component.getHeight() + pad * 2, pad * 2, pad * 2);
|
||||
}
|
||||
for (Component component : comps) {
|
||||
int pad = 3;
|
||||
Point p = component.getLocationOnScreen();
|
||||
g.setColor(TempColorUtils.fromRgb(240, 240, 240)); // faint gray
|
||||
g.setColor(ColorUtils.getOpaqueColor(0xf0f0f0)); // faint gray
|
||||
g.fillRoundRect(p.x - rect.x - pad, p.y - rect.y - pad, component.getWidth() + pad * 2,
|
||||
component.getHeight() + pad * 2, pad * 2, pad * 2);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import docking.action.DockingActionIf;
|
|||
import docking.options.editor.DefaultOptionComponent;
|
||||
import docking.widgets.table.GTable;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
||||
import ghidra.app.services.*;
|
||||
|
@ -44,6 +43,7 @@ import ghidra.program.model.address.AddressSetView;
|
|||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.test.TestEnv;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.classfinder.ClassSearcher;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
@ -351,7 +351,7 @@ public class AnalysisOptions2Test extends AbstractGhidraHeadedIntegrationTest {
|
|||
int r = Integer.parseInt(parts[0]);
|
||||
int g = Integer.parseInt(parts[1]);
|
||||
int b = Integer.parseInt(parts[2]);
|
||||
return TempColorUtils.fromRgb(r, g, b);
|
||||
return ColorUtils.getColor(r, g, b);
|
||||
}
|
||||
|
||||
private void selectAnalyzer(String name) {
|
||||
|
|
|
@ -34,7 +34,6 @@ import docking.widgets.fieldpanel.FieldPanel;
|
|||
import docking.widgets.fieldpanel.support.FieldLocation;
|
||||
import docking.widgets.fieldpanel.support.FieldSelection;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.GhidraOptions;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.app.plugin.core.marker.MarkerManagerPlugin;
|
||||
|
@ -50,6 +49,7 @@ import ghidra.program.util.ProgramLocation;
|
|||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.test.TestEnv;
|
||||
import ghidra.util.ColorUtils;
|
||||
|
||||
public class ColorizingPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
|
@ -180,7 +180,7 @@ public class ColorizingPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
Address address2 = address1.add(8);
|
||||
Address address3 = address2.add(16);
|
||||
|
||||
Color color = TempColorUtils.fromRgba(100, 100, 100, 100);
|
||||
Color color = ColorUtils.getColor(100, 100, 100, 100);
|
||||
setColor(color, address1, address2, address3);
|
||||
assertColorForAddress(color, address1, address2, address3);
|
||||
|
||||
|
@ -200,7 +200,7 @@ public class ColorizingPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
|
||||
// change the location so that the current line marker does not affect our color check below
|
||||
address = address.add(400);
|
||||
Color color = TempColorUtils.fromRgb(100, 100, 100);
|
||||
Color color = ColorUtils.getColor(100, 100, 100);
|
||||
setBackgroundFromAPI(address, color);
|
||||
|
||||
assertMarkerColorAtAddress(address, color);
|
||||
|
@ -220,7 +220,7 @@ public class ColorizingPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
Address address2 = address1.add(8);
|
||||
Address address3 = address2.add(8);
|
||||
|
||||
Color color = TempColorUtils.fromRgba(100, 100, 100, 100);
|
||||
Color color = ColorUtils.getColor(100, 100, 100, 100);
|
||||
setColor(color, address1, address2, address3);
|
||||
|
||||
// start before the first address to test that the next range action is enabled and the
|
||||
|
|
|
@ -45,7 +45,6 @@ import docking.widgets.tree.GTree;
|
|||
import docking.widgets.tree.GTreeNode;
|
||||
import generic.test.TestUtils;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.GhidraOptions;
|
||||
import ghidra.app.plugin.core.console.ConsolePlugin;
|
||||
import ghidra.app.util.viewer.options.OptionsGui;
|
||||
|
@ -57,6 +56,7 @@ import ghidra.framework.plugintool.dialog.KeyBindingsPanel;
|
|||
import ghidra.framework.preferences.Preferences;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.test.TestEnv;
|
||||
import ghidra.util.ColorUtils;
|
||||
|
||||
/**
|
||||
* Tests for the options dialog.
|
||||
|
@ -126,7 +126,7 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
selectAddressEntryInScreenElementOptionsList(optionsGui);
|
||||
|
||||
Color newColor =
|
||||
TempColorUtils.fromRgb(255, addressFieldColor.getGreen(), addressFieldColor.getBlue());
|
||||
ColorUtils.getColor(255, addressFieldColor.getGreen(), addressFieldColor.getBlue());
|
||||
setAddressColorValueInOptionsGUI(optionsGui, newColor);
|
||||
|
||||
// close the options
|
||||
|
|
|
@ -15,23 +15,57 @@
|
|||
*/
|
||||
package ghidra.plugins.fsbrowser;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import docking.test.AbstractDockingTest;
|
||||
import generic.theme.GIcon;
|
||||
import resources.MultiIcon;
|
||||
|
||||
public class FileIconServiceTest extends AbstractGenericTest
|
||||
{
|
||||
public class FileIconServiceTest extends AbstractDockingTest {
|
||||
|
||||
@Test
|
||||
public void testGetIcon() {
|
||||
FileIconService fis = FileIconService.getInstance();
|
||||
Assert.assertNotNull(fis.getImage("blah.txt"));
|
||||
Icon icon = fis.getIcon("blah.txt", null);
|
||||
Assert.assertNotNull(icon);
|
||||
assertTrue(icon instanceof GIcon);
|
||||
GIcon gIcon = (GIcon) icon;
|
||||
assertEquals("icon.fsbrowser.file.extension.txt", gIcon.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOverlayIcon() {
|
||||
FileIconService fis = FileIconService.getInstance();
|
||||
Assert.assertNotNull(fis.getImage("blah.txt", FileIconService.OVERLAY_FILESYSTEM));
|
||||
Icon icon = fis.getIcon("blah.txt", List.of(FileIconService.FILESYSTEM_OVERLAY_ICON));
|
||||
Assert.assertNotNull(icon);
|
||||
assertTrue(icon instanceof MultiIcon);
|
||||
MultiIcon multiIcon = (MultiIcon) icon;
|
||||
assertEquals(
|
||||
"MultiIcon[icon.fsbrowser.file.extension.txt, icon.fsbrowser.file.overlay.filesystem]",
|
||||
multiIcon.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSubstringIcon() {
|
||||
FileIconService fis = FileIconService.getInstance();
|
||||
Icon icon = fis.getIcon("blah.release.abcx.123", null);
|
||||
Assert.assertNotNull(icon);
|
||||
assertTrue(icon instanceof GIcon);
|
||||
GIcon gIcon = (GIcon) icon;
|
||||
assertEquals("icon.fsbrowser.file.substring.release.", gIcon.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMatch() {
|
||||
FileIconService fis = FileIconService.getInstance();
|
||||
Icon icon = fis.getIcon("aaaaaaaa.bbbbbbbb.cccccccc", null);
|
||||
assertEquals(FileIconService.DEFAULT_ICON, icon);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
|
|||
String name, Class<?> contextType) {
|
||||
super(tool, name, plugin.getName(), contextType);
|
||||
this.plugin = plugin;
|
||||
registerAdjustableFontId(DEFAULT_FONT_ID);
|
||||
|
||||
initializedDataFormatModelClassMap();
|
||||
|
||||
|
|
|
@ -352,8 +352,7 @@ public class DecompileOptions {
|
|||
private final static Color ERROR_COLOR = new GColor("color.fg.decompiler.comment");
|
||||
|
||||
final static String FONT_MSG = "Display.Font";
|
||||
final static String DEFAULT_FONT_ID = "font.decompiler";
|
||||
private Font font;
|
||||
public final static String DEFAULT_FONT_ID = "font.decompiler";
|
||||
|
||||
private final static String CACHED_RESULTS_SIZE_MSG = "Cache Size (Functions)";
|
||||
private final static int SUGGESTED_CACHED_RESULTS_SIZE = 10;
|
||||
|
|
|
@ -111,7 +111,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter
|
|||
|
||||
this.plugin = plugin;
|
||||
this.clipboardProvider = new DecompilerClipboardProvider(plugin, this);
|
||||
|
||||
registerAdjustableFontId(DecompileOptions.DEFAULT_FONT_ID);
|
||||
setConnected(isConnected);
|
||||
|
||||
decompilerOptions = new DecompileOptions();
|
||||
|
|
|
@ -44,7 +44,6 @@ import docking.widgets.textfield.HintTextField;
|
|||
import generic.theme.GIcon;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.app.util.bin.format.pdb.PdbParser;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbIdentifiers;
|
||||
import ghidra.app.util.pdb.pdbapplicator.PdbApplicatorControl;
|
||||
|
@ -892,7 +891,7 @@ public class LoadPdbDialog extends DialogComponentProvider {
|
|||
Color bg = parent.getBackground();
|
||||
// mint a new Color object to avoid it being ignored because the parent handed us a
|
||||
// DerivedColor instance
|
||||
return TempColorUtils.fromRgb(bg.getRGB());
|
||||
return ColorUtils.getColor(bg.getRGB());
|
||||
}
|
||||
return super.getBackground();
|
||||
}
|
||||
|
@ -933,7 +932,7 @@ public class LoadPdbDialog extends DialogComponentProvider {
|
|||
Color bg = parent.getBackground();
|
||||
// mint a new Color object to avoid it being ignored because the parent handed us a
|
||||
// DerivedColor instance
|
||||
return TempColorUtils.fromRgb(bg.getRGB());
|
||||
return ColorUtils.getColor(bg.getRGB());
|
||||
}
|
||||
return super.getBackground();
|
||||
}
|
||||
|
|
|
@ -31,12 +31,13 @@ import docking.widgets.label.GDLabel;
|
|||
import docking.widgets.label.GHtmlLabel;
|
||||
import docking.widgets.textfield.HexIntegerFormatter;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.feature.vt.api.main.VTAssociation;
|
||||
import ghidra.feature.vt.gui.provider.matchtable.NumberRangeProducer;
|
||||
import ghidra.feature.vt.gui.provider.matchtable.NumberRangeSubFilterChecker;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.WebColors;
|
||||
|
||||
public abstract class AbstractAddressRangeFilter<T> extends AncillaryFilter<T>
|
||||
implements NumberRangeSubFilterChecker, NumberRangeProducer {
|
||||
|
@ -122,7 +123,7 @@ public abstract class AbstractAddressRangeFilter<T> extends AncillaryFilter<T>
|
|||
//
|
||||
// Lower Score Panel
|
||||
//
|
||||
String fgColor = TempColorUtils.toString(FG_TOOLTIP_DEFAULT);
|
||||
String fgColor = WebColors.toString(FG_TOOLTIP_DEFAULT);
|
||||
lowerRangePanel = new JPanel(new GridLayout(2, 1));
|
||||
JLabel lowLabel =
|
||||
new GHtmlLabel("<html><font size=\"2\" color=\"" + fgColor + "\">low</font>");
|
||||
|
@ -208,7 +209,7 @@ public abstract class AbstractAddressRangeFilter<T> extends AncillaryFilter<T>
|
|||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Color bg = getBackground();
|
||||
Color disabledColor = TempColorUtils.withAlpha(bg, 100);
|
||||
Color disabledColor = ColorUtils.withAlpha(bg, 100);
|
||||
g.setColor(disabledColor);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
|
|
|
@ -99,14 +99,13 @@ icon.home = go-home.png
|
|||
icon.add = Plus2.png
|
||||
icon.subtract = list-remove.png
|
||||
icon.clear = erase16.png
|
||||
icon.error = error.png
|
||||
icon.error = emblem-important.png
|
||||
icon.delete = icon.error
|
||||
icon.collapse.all = collapse_all.png
|
||||
icon.expand.all = expand_all.png
|
||||
icon.toggle.expand = expand.gif
|
||||
icon.toggle.collapse = collapse.gif
|
||||
icon.configure.filter = exec.png
|
||||
icon.error = emblem-important.png
|
||||
icon.navigate.in = locationIn.gif
|
||||
icon.navigate.out = locationOut.gif
|
||||
icon.not.allowed = dialog-cancel.png
|
||||
|
@ -149,7 +148,8 @@ icon.properties = document-properties.png
|
|||
icon.table = table.png
|
||||
icon.drive = drive.png
|
||||
icon.run = play.png
|
||||
icon.spreadsheet =
|
||||
icon.spreadsheet = application-vnd.oasis.opendocument.spreadsheet-template.png
|
||||
icon.pulldown = menu16.gif
|
||||
icon.window = application_xp.png
|
||||
icon.zoom.in = zoom_in.png
|
||||
icon.zoom.out = zoom_out.png
|
||||
|
@ -193,7 +193,7 @@ icon.widget.table.header.help = info_small.png
|
|||
icon.widget.table.header.help.hovered = info_small_hover.png
|
||||
icon.widget.table.header.pending = hourglass.png
|
||||
|
||||
icon.dialog.error.expandable.report = icon.speadsheet
|
||||
icon.dialog.error.expandable.report = icon.spreadsheet
|
||||
icon.dialog.error.expandable.exception = program_obj.png
|
||||
icon.dialog.error.expandable.frame = StackFrameElement.png
|
||||
icon.dialog.error.expandable.stack = StackFrame_Red.png
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
*/
|
||||
package docking;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.action.*;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import help.HelpDescriptor;
|
||||
|
@ -114,6 +114,8 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext
|
|||
|
||||
private String inceptionInformation;
|
||||
|
||||
private String registeredFontId;
|
||||
|
||||
/**
|
||||
* Creates a new component provider with a default location of {@link WindowPosition#WINDOW}.
|
||||
* @param tool The tool will manage and show this provider
|
||||
|
@ -776,6 +778,41 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext
|
|||
return dockingTool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the provider to adjust the font size for this provider. By default, this method
|
||||
* will adjust the font for the registered font id if it has been registered using
|
||||
* {@link #registeredFontId}. Subclasses can override this method to a more comprehensive
|
||||
* adjustment to multiple fonts if necessary.
|
||||
* @param bigger if true, the font should be made bigger, otherwise the font should be made
|
||||
* smaller
|
||||
*/
|
||||
public void adjustFontSize(boolean bigger) {
|
||||
if (registeredFontId == null) {
|
||||
return;
|
||||
}
|
||||
Font font = Gui.getFont(registeredFontId);
|
||||
if (font == null) {
|
||||
return;
|
||||
}
|
||||
int size = font.getSize();
|
||||
if (bigger) {
|
||||
size += 1;
|
||||
}
|
||||
else {
|
||||
size = Math.max(size - 1, 3);
|
||||
}
|
||||
Gui.setFont(registeredFontId, font.deriveFont((float) size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a fontId for the font that will be automatically adjusted when
|
||||
* {@link #adjustFontSize(boolean)} is called.
|
||||
* @param fontId the id of the theme font to be adjusted
|
||||
*/
|
||||
protected void registerAdjustableFontId(String fontId) {
|
||||
this.registeredFontId = fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + " - " + getTitle() + " - " + getSubTitle();
|
||||
|
@ -885,4 +922,5 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext
|
|||
return inceptionInformation;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import docking.widgets.EmptyBorderButton;
|
|||
import docking.widgets.label.GDLabel;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import generic.theme.Gui;
|
||||
import generic.theme.TempColorUtils;
|
||||
import generic.util.WindowUtilities;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.layout.HorizontalLayout;
|
||||
|
@ -318,14 +317,14 @@ public class StatusBar extends JPanel {
|
|||
delta = -16;
|
||||
}
|
||||
|
||||
Color start = TempColorUtils.fromRgb(value, value, value);
|
||||
Color start = ColorUtils.getColor(value, value, value);
|
||||
fadeColorMap.put(statusLabel.getForeground(), start);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
|
||||
Color from = TempColorUtils.fromRgb(value, value, value);
|
||||
Color from = ColorUtils.getColor(value, value, value);
|
||||
value += delta;
|
||||
Color to = TempColorUtils.fromRgb(value, value, value);
|
||||
Color to = ColorUtils.getColor(value, value, value);
|
||||
fadeColorMap.put(from, to);
|
||||
}
|
||||
}
|
||||
|
@ -404,7 +403,7 @@ public class StatusBar extends JPanel {
|
|||
int red = color.getRed();
|
||||
int green = color.getGreen();
|
||||
int blue = color.getBlue();
|
||||
return TempColorUtils.fromRgb((255 - red), (255 - green), (255 - blue));
|
||||
return ColorUtils.getColor((255 - red), (255 - green), (255 - blue));
|
||||
}
|
||||
|
||||
private void contrastStatusLabelColors() {
|
||||
|
|
|
@ -26,8 +26,8 @@ import docking.DialogComponentProvider;
|
|||
import docking.DockingWindowManager;
|
||||
import docking.widgets.label.GDHtmlLabel;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.WebColors;
|
||||
|
||||
/**
|
||||
* Color editor that is a bit unusual in that its custom component is a button that when pushed,
|
||||
|
@ -88,7 +88,7 @@ public class ColorEditor extends PropertyEditorSupport {
|
|||
private void updateColor(Color newColor) {
|
||||
|
||||
// change the color to a darker value if the color being set is light
|
||||
String colorString = TempColorUtils.toString(ColorUtils.contrastForegroundColor(newColor));
|
||||
String colorString = WebColors.toString(ColorUtils.contrastForegroundColor(newColor));
|
||||
previewLabel.setText(
|
||||
"<HTML><CENTER><I><FONT SIZE=2 COLOR=" + colorString + ">click</FONT></I></CENTER>");
|
||||
|
||||
|
@ -148,8 +148,7 @@ public class ColorEditor extends PropertyEditorSupport {
|
|||
// This could be a ColorUIResource, but Options only support storing Color. So,
|
||||
// manually create a new Color object to avoid saving a ColorUIResource.
|
||||
Color c = colorChooser.getColor();
|
||||
lastUserSelectedColor = TempColorUtils.fromRgba(c.getRed(), c.getGreen(),
|
||||
c.getBlue(), c.getAlpha());
|
||||
lastUserSelectedColor = ColorUtils.getColor(c.getRGB());
|
||||
});
|
||||
colorChooser.setColor(color);
|
||||
}
|
||||
|
|
|
@ -18,13 +18,11 @@ package docking.options.editor;
|
|||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.stream.*;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.widgets.combobox.GComboBox;
|
||||
import docking.widgets.label.GDLabel;
|
||||
|
@ -67,6 +65,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
|||
private GComboBox<Integer> sizeCombo;
|
||||
private GComboBox<String> styleCombo;
|
||||
private ActionListener actionListener = e -> fontChanged();
|
||||
private List<FontWrapper> systemFontNames;
|
||||
|
||||
public FontChooserPanel() {
|
||||
build();
|
||||
|
@ -83,9 +82,10 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
|||
styleCombo.removeActionListener(actionListener);
|
||||
|
||||
FontWrapper fontWrapper = new FontWrapper(font.getName());
|
||||
updateComboBoxModeIfNeeded(fontWrapper);
|
||||
|
||||
int styleChoice = font.getStyle();
|
||||
int size = font.getSize();
|
||||
|
||||
fontCombo.setSelectedItem(fontWrapper);
|
||||
sizeCombo.setSelectedItem(size);
|
||||
styleCombo.setSelectedIndex(styleChoice);
|
||||
|
@ -96,6 +96,16 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
|||
|
||||
}
|
||||
|
||||
private void updateComboBoxModeIfNeeded(FontWrapper fontWrapper) {
|
||||
if (systemFontNames.contains(fontWrapper)) {
|
||||
return;
|
||||
}
|
||||
systemFontNames.add(fontWrapper);
|
||||
DefaultComboBoxModel<FontWrapper> model =
|
||||
new DefaultComboBoxModel<>(systemFontNames.toArray(new FontWrapper[0]));
|
||||
fontCombo.setModel(model);
|
||||
}
|
||||
|
||||
private void build() {
|
||||
setLayout(new BorderLayout());
|
||||
add(buildTopPanel(), BorderLayout.NORTH);
|
||||
|
@ -104,7 +114,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
|||
|
||||
private Component buildTopPanel() {
|
||||
JPanel panel = new JPanel(new FlowLayout(SwingConstants.CENTER, 10, 0));
|
||||
panel.add(buildFontPanel());
|
||||
panel.add(buildFontNamePanel());
|
||||
panel.add(buildSizePanel());
|
||||
panel.add(buildStylePanel());
|
||||
return panel;
|
||||
|
@ -154,7 +164,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
|||
return panel;
|
||||
}
|
||||
|
||||
private Component buildFontPanel() {
|
||||
private Component buildFontNamePanel() {
|
||||
JPanel panel = new JPanel(new GridLayout(2, 1));
|
||||
|
||||
GDLabel fontLabel = new GDLabel("Fonts");
|
||||
|
@ -162,12 +172,8 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
|||
fontLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
panel.add(fontLabel);
|
||||
|
||||
GraphicsEnvironment gEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
Stream<String> stream = Arrays.stream(gEnv.getAvailableFontFamilyNames());
|
||||
FontWrapper[] array = stream.map(s -> new FontWrapper(s)).toArray(FontWrapper[]::new);
|
||||
Arrays.sort(array);
|
||||
|
||||
fontCombo = new GComboBox<>(array);
|
||||
systemFontNames = getSystemFontNames();
|
||||
fontCombo = new GComboBox<>(systemFontNames.toArray(new FontWrapper[0]));
|
||||
fontCombo.setMaximumRowCount(9);
|
||||
fontCombo.addActionListener(actionListener);
|
||||
panel.add(fontCombo);
|
||||
|
@ -175,6 +181,15 @@ public class FontPropertyEditor extends PropertyEditorSupport {
|
|||
return panel;
|
||||
}
|
||||
|
||||
private List<FontWrapper> getSystemFontNames() {
|
||||
GraphicsEnvironment gEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
Stream<String> stream = Arrays.stream(gEnv.getAvailableFontFamilyNames());
|
||||
List<FontWrapper> collect =
|
||||
stream.map(s -> new FontWrapper(s)).collect(Collectors.toList());
|
||||
Collections.sort(collect);
|
||||
return new ArrayList<>(collect);
|
||||
}
|
||||
|
||||
private void fontChanged() {
|
||||
FontWrapper fontWrapper = (FontWrapper) fontCombo.getSelectedItem();
|
||||
String fontNameChoice = fontWrapper.getFontName();
|
||||
|
|
|
@ -28,7 +28,7 @@ import docking.widgets.label.GHtmlLabel;
|
|||
import docking.widgets.label.GLabel;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import generic.theme.GThemeDefaults.Colors.Java;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.layout.VerticalLayout;
|
||||
|
||||
public class SettableColorSwatchChooserPanel extends AbstractColorChooserPanel {
|
||||
|
@ -388,8 +388,7 @@ class MainSwatchPanel extends SwatchPanel {
|
|||
|
||||
colors = new Color[numColors];
|
||||
for (int i = 0; i < numColors; i++) {
|
||||
colors[i] =
|
||||
TempColorUtils.fromRgb(rawValues[(i * 3)], rawValues[(i * 3) + 1],
|
||||
colors[i] = ColorUtils.getColor(rawValues[(i * 3)], rawValues[(i * 3) + 1],
|
||||
rawValues[(i * 3) + 2]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,9 +40,7 @@ import docking.widgets.indexedscrollpane.IndexScrollListener;
|
|||
import docking.widgets.indexedscrollpane.IndexedScrollable;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.*;
|
||||
|
||||
public class FieldPanel extends JPanel
|
||||
implements IndexedScrollable, LayoutModelListener, ChangeListener {
|
||||
|
@ -1154,7 +1152,7 @@ public class FieldPanel extends JPanel
|
|||
}
|
||||
|
||||
private Color blend(Color primary, Color secondary) {
|
||||
return TempColorUtils.blend4(primary, secondary);
|
||||
return ColorUtils.blend(primary, secondary, 0.75);
|
||||
}
|
||||
|
||||
private void paintLayoutBackground(Graphics g, Rectangle rect, AnchoredLayout layout,
|
||||
|
|
|
@ -17,7 +17,7 @@ package docking.widgets.fieldpanel.internal;
|
|||
|
||||
import java.awt.Color;
|
||||
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.datastruct.*;
|
||||
|
||||
public class ColorRangeMap {
|
||||
|
@ -59,12 +59,12 @@ public class ColorRangeMap {
|
|||
return getColor(valueRange.getValue());
|
||||
}
|
||||
|
||||
private Color getColor(int colorValue) {
|
||||
if (lastColorValue == colorValue) {
|
||||
private Color getColor(int rgba) {
|
||||
if (lastColorValue == rgba) {
|
||||
return lastColor;
|
||||
}
|
||||
lastColorValue = colorValue;
|
||||
lastColor = TempColorUtils.fromRgb(colorValue);
|
||||
lastColorValue = rgba;
|
||||
lastColor = ColorUtils.getColor(rgba);
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import java.awt.Color;
|
|||
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.util.ColorUtils;
|
||||
|
||||
/**
|
||||
* Miscellaneous information needed by fields to paint.
|
||||
|
@ -130,7 +130,7 @@ public class PaintContext {
|
|||
}
|
||||
|
||||
private void adjustSelectedHighlightColor() {
|
||||
selectedHighlightColor = TempColorUtils.blend3(selectionColor, highlightColor);
|
||||
selectedHighlightColor = ColorUtils.blend(selectionColor, highlightColor, 0.5);
|
||||
}
|
||||
|
||||
public void setBackgroundColor(Color c) {
|
||||
|
|
|
@ -34,9 +34,9 @@ import docking.widgets.tree.GTreeNode;
|
|||
import docking.widgets.tree.support.GTreeDragNDropHandler;
|
||||
import docking.widgets.tree.support.GTreeNodeTransferable;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.framework.Platform;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class GTreeDragNDropAdapter implements DragSourceListener, DragGestureListener,
|
||||
|
@ -158,7 +158,7 @@ public class GTreeDragNDropAdapter implements DragSourceListener, DragGestureLis
|
|||
Graphics2D g2 = (Graphics2D) graphics;
|
||||
GradientPaint mask;
|
||||
Color treeBg = tree.getBackground();
|
||||
Color transparentTreeBackground = TempColorUtils.withAlpha(treeBg, 100);
|
||||
Color transparentTreeBackground = ColorUtils.withAlpha(treeBg, 100);
|
||||
mask =
|
||||
new GradientPaint(0, 0, transparentTreeBackground, 0, size.height >> 1,
|
||||
Palette.NO_COLOR);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[Defaults]
|
||||
|
||||
// Fonts
|
||||
font.standard = [font]panel.font
|
||||
font.standard = [font]Panel.font
|
||||
font.bold = font.standard[bold]
|
||||
font.italics = font.standard[italic]
|
||||
font.bold.italic = font.standard[bold][italic]
|
||||
|
|
|
@ -107,7 +107,11 @@ public abstract class AbstractThemeReader {
|
|||
|
||||
private IconValue parseIconProperty(String key, String value, int lineNumber) {
|
||||
try {
|
||||
return IconValue.parse(key, value);
|
||||
IconValue parsedValue = IconValue.parse(key, value);
|
||||
if (parsedValue == null) {
|
||||
error(lineNumber, "Could not parse Icon value: " + value);
|
||||
}
|
||||
return parsedValue;
|
||||
}
|
||||
catch (ParseException e) {
|
||||
error(lineNumber,
|
||||
|
|
|
@ -144,7 +144,7 @@ public class FontValue extends ThemeValue<Font> {
|
|||
|
||||
@Override
|
||||
protected Font getUnresolvedReferenceValue(String unresolvedId) {
|
||||
Msg.warn(this, "Could not resolve indirect font for" + unresolvedId +
|
||||
Msg.warn(this, "Could not resolve indirect font for " + unresolvedId +
|
||||
", using last resort default");
|
||||
return LAST_RESORT_DEFAULT;
|
||||
}
|
||||
|
|
|
@ -302,4 +302,17 @@ public class GThemeValueMap {
|
|||
Objects.equals(iconMap, other.iconMap);
|
||||
}
|
||||
|
||||
public void checkForUnresolvedReferences() {
|
||||
// attempting to get the values for all properties, will print warnings if they are unresolved
|
||||
for (ColorValue colorValue : colorMap.values()) {
|
||||
colorValue.get(this);
|
||||
}
|
||||
for (FontValue fontValue : fontMap.values()) {
|
||||
fontValue.get(this);
|
||||
}
|
||||
for (IconValue iconValue : iconMap.values()) {
|
||||
iconValue.get(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -200,6 +200,7 @@ public class Gui {
|
|||
"Error setting LookAndFeel: " + lookAndFeel.getName(), e);
|
||||
}
|
||||
}
|
||||
currentValues.checkForUnresolvedReferences();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -630,6 +631,33 @@ public class Gui {
|
|||
return getIcon(id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an color for the given Id has been defined
|
||||
* @param id the id to check for an existing color.
|
||||
* @return true if an color for the given Id has been defined
|
||||
*/
|
||||
public static boolean hasColor(String id) {
|
||||
return currentValues.containsColor(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an font for the given Id has been defined
|
||||
* @param id the id to check for an existing font.
|
||||
* @return true if an font for the given Id has been defined
|
||||
*/
|
||||
public static boolean hasFont(String id) {
|
||||
return currentValues.containsFont(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an icon for the given Id has been defined
|
||||
* @param id the id to check for an existing icon.
|
||||
* @return true if an icon for the given Id has been defined
|
||||
*/
|
||||
public static boolean hasIcon(String id) {
|
||||
return currentValues.containsIcon(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Icon} registered for the given id. If no icon is registered, returns
|
||||
* the default icon (bomb).
|
||||
|
|
|
@ -125,7 +125,7 @@ public class IconValue extends ThemeValue<Icon> {
|
|||
* @param key the key to associate the parsed value with
|
||||
* @param value the color value to parse
|
||||
* @return an IconValue with the given key and the parsed value
|
||||
* @throws ParseException
|
||||
* @throws ParseException if the value can't be parsed
|
||||
*/
|
||||
public static IconValue parse(String key, String value) throws ParseException {
|
||||
String id = fromExternalId(key);
|
||||
|
@ -139,10 +139,16 @@ public class IconValue extends ThemeValue<Icon> {
|
|||
int modifierIndex = getModifierIndex(value);
|
||||
|
||||
if (modifierIndex < 0) {
|
||||
if (value.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
return new IconValue(id, getIcon(value));
|
||||
}
|
||||
|
||||
String baseIconString = value.substring(0, modifierIndex).trim();
|
||||
if (baseIconString.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
Icon icon = getIcon(baseIconString);
|
||||
String iconModifierString = value.substring(modifierIndex);
|
||||
IconModifier modifier = IconModifier.parse(iconModifierString);
|
||||
|
|
|
@ -1,83 +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 generic.theme;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import ghidra.util.WebColors;
|
||||
|
||||
/**
|
||||
* A class to serve as a placeholder for migrating code. After the migration is complete, uses
|
||||
* of this class can be removed, with the original code being restored in the process.
|
||||
*/
|
||||
public class TempColorUtils {
|
||||
|
||||
public static Color fromRgb(int rgb) {
|
||||
return new Color(rgb);
|
||||
}
|
||||
|
||||
public static Color fromRgba(int rgba) {
|
||||
return new Color(rgba, true);
|
||||
}
|
||||
|
||||
public static Color fromRgb(int r, int g, int b) {
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
|
||||
public static Color fromRgba(int r, int g, int b, int a) {
|
||||
return new Color(r, g, b, a);
|
||||
}
|
||||
|
||||
public static Color fromRgba(float r, float g, float b, float a) {
|
||||
return new Color(r, g, b, a);
|
||||
}
|
||||
|
||||
public static Color withAlpha(Color c, int a) {
|
||||
return new Color(c.getRed(), c.getGreen(), c.getBlue(), a);
|
||||
}
|
||||
|
||||
public static Color blend1(Color c1, Color c2) {
|
||||
int red = (c1.getRed() * 2 + c2.getRed()) / 3;
|
||||
int green = (c1.getGreen() * 2 + c2.getGreen()) / 3;
|
||||
int blue = (c1.getBlue() * 2 + c2.getBlue()) / 3;
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
public static Color blend2(Color c, int value) {
|
||||
int red = (c.getRed() + 3 * value) / 4;
|
||||
int green = (c.getGreen() + 3 * value) / 4;
|
||||
int blue = (c.getBlue() + 3 * value) / 4;
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
public static Color blend3(Color c1, Color c2) {
|
||||
int red = (c1.getRed() + c2.getRed()) / 2;
|
||||
int green = (c1.getGreen() + c2.getGreen()) / 2;
|
||||
int blue = (c1.getBlue() + c2.getBlue()) / 2;
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
public static Color blend4(Color c1, Color c2) {
|
||||
int red = (c1.getRed() * 3 + c2.getRed()) / 4;
|
||||
int green = (c1.getGreen() * 3 + c2.getGreen()) / 4;
|
||||
int blue = (c1.getBlue() * 3 + c2.getBlue()) / 4;
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
public static String toString(Color c) {
|
||||
return WebColors.toString(c, false);
|
||||
}
|
||||
}
|
|
@ -1,30 +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 generic.theme.builtin;
|
||||
|
||||
import javax.swing.LookAndFeel;
|
||||
|
||||
import generic.theme.DiscoverableGTheme;
|
||||
import generic.theme.LafType;
|
||||
|
||||
/**
|
||||
* Built-in GTheme that uses the FlatDarcula {@link LookAndFeel} and the dark application defaults.
|
||||
*/
|
||||
public class FlatDarculaTheme extends DiscoverableGTheme {
|
||||
public FlatDarculaTheme() {
|
||||
super("Flat Darcula Theme", LafType.FLAT_DARCULA, true);
|
||||
}
|
||||
}
|
|
@ -168,28 +168,24 @@ public class ColorUtils {
|
|||
* @param ratio the amount of the first color to include in the final output
|
||||
* @return the new color
|
||||
*/
|
||||
public static Color blend(Color c1, Color c2, float ratio) {
|
||||
public static Color blend(Color c1, Color c2, double ratio) {
|
||||
if (c1 == null) {
|
||||
return c2;
|
||||
}
|
||||
if (c2 == null) {
|
||||
return c1;
|
||||
}
|
||||
float rgb1[] = new float[3];
|
||||
float rgb2[] = new float[3];
|
||||
c1.getColorComponents(rgb1);
|
||||
c2.getColorComponents(rgb2);
|
||||
int red = blend(c1.getRed(), c2.getRed(), ratio);
|
||||
int green = blend(c1.getGreen(), c2.getRed(), ratio);
|
||||
int blue = blend(c1.getBlue(), c2.getBlue(), ratio);
|
||||
int alpha = blend(c1.getAlpha(), c2.getAlpha(), ratio);
|
||||
return new Color(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
float inverse = (float) 1.0 - ratio;
|
||||
|
||||
//@formatter:off
|
||||
Color color = new Color(
|
||||
rgb1[0] * ratio + rgb2[0] * inverse,
|
||||
rgb1[1] * ratio + rgb2[1] * inverse,
|
||||
rgb1[2] * ratio + rgb2[2] * inverse);
|
||||
//@formatter:on
|
||||
|
||||
return color;
|
||||
private static int blend(int colorValue1, int colorValue2, double ratio) {
|
||||
double value = colorValue1 * ratio + colorValue2 * (1.0 - ratio);
|
||||
int result = (int) (value + 0.5);
|
||||
return Math.max(result, 255);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -228,6 +224,68 @@ public class ColorUtils {
|
|||
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the color object given a rgba value that includes the desired alpha value.
|
||||
* @param rgba value where bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are
|
||||
* blue
|
||||
* @return the color object given a rgba value that includes the desired alpha value
|
||||
*/
|
||||
public static Color getColor(int rgba) {
|
||||
return new Color(rgba, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an opaque color object given for the given red, green, and blue values.
|
||||
* @param red the red value (0 - 255)
|
||||
* @param green the green value (0 - 255)
|
||||
* @param blue the blue value (0 - 255)
|
||||
* @return the color object for the given values
|
||||
*/
|
||||
public static Color getColor(int red, int green, int blue) {
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the color object given for the given red, green, blue, and alpha values.
|
||||
* @param red the red value (0 - 255)
|
||||
* @param green the green value (0 - 255)
|
||||
* @param blue the blue value (0 - 255)
|
||||
* @param alpha the alpha (transparency) value (0 - 255) with 0 being fully transparent and 255
|
||||
* being fully opaque opaque
|
||||
* @return the color object for the given values
|
||||
*/
|
||||
public static Color getColor(int red, int green, int blue, int alpha) {
|
||||
return new Color(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an opaque color with the given rgb value. The resulting color will have an alpha
|
||||
* value of 0xff.
|
||||
*
|
||||
* @param rgb the value where bits 16-23 are red, 8-15 are green, 0-7 are blue. Bits 24-31 will
|
||||
* be set to 0xff.
|
||||
* @return an opaque color with the given rgb value
|
||||
|
||||
*/
|
||||
public static Color getOpaqueColor(int rgb) {
|
||||
return new Color(rgb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new color by averaging the red, green, blue, and alpha values from the given
|
||||
* colors.
|
||||
* @param color1 the first color to average
|
||||
* @param color2 the second color to average
|
||||
* @return a new color that is the average of the two given colors
|
||||
*/
|
||||
public static Color average(Color color1, Color color2) {
|
||||
int red = (color1.getRed() + color2.getRed()) / 2;
|
||||
int green = (color1.getGreen() + color2.getGreen()) / 2;
|
||||
int blue = (color1.getBlue() + color2.getBlue()) / 2;
|
||||
int alpha = (color1.getAlpha() + color2.getAlpha()) / 2;
|
||||
return new Color(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blender of colors
|
||||
*/
|
||||
|
|
|
@ -21,7 +21,7 @@ import java.util.Objects;
|
|||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.util.ColorUtils;
|
||||
|
||||
/**
|
||||
* Icon class for for displaying overlapping icons. Icons are drawn in the order they
|
||||
|
@ -148,7 +148,7 @@ public class MultiIcon implements Icon {
|
|||
if (disabled) {
|
||||
// Alpha blend to background
|
||||
Color bgColor = c.getBackground();
|
||||
g.setColor(TempColorUtils.withAlpha(bgColor, 128));
|
||||
g.setColor(ColorUtils.withAlpha(bgColor, 128));
|
||||
g.fillRect(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ public class ThemePropertyFileReaderTest {
|
|||
" icon.a.11 = icon.a.10",
|
||||
" icon.a.12 = icon.a.10[size(17,21)]",
|
||||
" icon.a.13 = core.png[size(17,21)]",
|
||||
" icon.a.14 = icon.a.10{core.png[size(4,4)][move(8, 8)]",
|
||||
" icon.a.14 = icon.a.10{core.png[size(4,4)][move(8, 8)]}",
|
||||
"")));
|
||||
//@formatter:on
|
||||
|
||||
|
@ -151,7 +151,8 @@ public class ThemePropertyFileReaderTest {
|
|||
//@formatter:on
|
||||
List<String> errors = reader.getErrors();
|
||||
assertEquals(1, errors.size());
|
||||
assertEquals("Error parsing file \"test\" at line: 3, Could not parse Color value: sdfsdf",
|
||||
assertEquals(
|
||||
"Error parsing theme file \"test\" at line: 3, Could not parse Color value: sdfsdf",
|
||||
errors.get(0));
|
||||
}
|
||||
|
||||
|
@ -184,6 +185,20 @@ public class ThemePropertyFileReaderTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIconNoRightHandValueError() throws IOException {
|
||||
//@formatter:off
|
||||
ThemePropertyFileReader reader = new ThemePropertyFileReader("test", new StringReader(String.join("\n",
|
||||
"[Defaults]",
|
||||
" icon.b.1 = core.png",
|
||||
" icon.b.2 = ",
|
||||
"")));
|
||||
//@formatter:on
|
||||
List<String> errors = reader.getErrors();
|
||||
assertEquals(1, errors.size());
|
||||
|
||||
}
|
||||
|
||||
private Color getColor(GThemeValueMap values, String id) {
|
||||
ColorValue color = values.getColor(id);
|
||||
return color.get(values);
|
||||
|
|
|
@ -29,9 +29,9 @@ import javax.swing.table.*;
|
|||
|
||||
import docking.widgets.table.GTable;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.framework.main.datatree.DataTreeDragNDropHandler;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.util.ColorUtils;
|
||||
|
||||
public class ProjectDataTableDnDHandler implements DragSourceListener, DragGestureListener {
|
||||
|
||||
|
@ -174,7 +174,7 @@ public class ProjectDataTableDnDHandler implements DragSourceListener, DragGestu
|
|||
Graphics2D g2 = (Graphics2D) graphics;
|
||||
GradientPaint mask;
|
||||
Color treeBackground = table.getBackground();
|
||||
Color transparentTreeBackground = TempColorUtils.withAlpha(treeBackground, 200);
|
||||
Color transparentTreeBackground = ColorUtils.withAlpha(treeBackground, 200);
|
||||
mask = new GradientPaint(0, 0, transparentTreeBackground, 0, size.height >> 1,
|
||||
Palette.NO_COLOR);
|
||||
g2.setPaint(mask);
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.List;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.theme.TempColorUtils;
|
||||
import ghidra.GhidraOptions;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.app.plugin.core.colorizer.ColorizingService;
|
||||
|
@ -38,6 +37,7 @@ import ghidra.framework.plugintool.util.OptionsService;
|
|||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.block.*;
|
||||
import ghidra.util.WebColors;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
|
@ -97,8 +97,8 @@ public class BlockModelScreenShots extends GhidraScreenShotGenerator {
|
|||
ColorizingService colorizer = tool.getService(ColorizingService.class);
|
||||
|
||||
// note: 2 colors that look good together and are just used for this example
|
||||
Color c1 = TempColorUtils.fromRgb(232, 242, 254); // alice blue;
|
||||
Color c2 = TempColorUtils.fromRgb(170, 204, 245); // light sky blue
|
||||
Color c1 = WebColors.ALICE_BLUE;
|
||||
Color c2 = WebColors.LIGHT_SKY_BLUE;
|
||||
Color color = c1;
|
||||
|
||||
BasicBlockModel basicBlockModel = new BasicBlockModel(program);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue