mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-2389 ImageIconWrapper refactor
This commit is contained in:
parent
781c765e60
commit
30b14e3baf
15 changed files with 539 additions and 42 deletions
|
@ -29,7 +29,7 @@ import ghidra.program.model.listing.Function;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import resources.MultiIcon;
|
import resources.MultiIcon;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
import resources.icons.ScaledImageIconWrapper;
|
import resources.icons.ScaledImageIcon;
|
||||||
import resources.icons.TranslateIcon;
|
import resources.icons.TranslateIcon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +48,7 @@ public abstract class CompareFunctionsAction extends DockingAction {
|
||||||
private static final ImageIcon COMPARISON_ICON =
|
private static final ImageIcon COMPARISON_ICON =
|
||||||
ResourceManager.loadImage("images/page_white_c.png");
|
ResourceManager.loadImage("images/page_white_c.png");
|
||||||
private static final Icon NEW_ICON = ResourceManager.loadImage("images/bullet_star.png");
|
private static final Icon NEW_ICON = ResourceManager.loadImage("images/bullet_star.png");
|
||||||
private static final Icon SCALED_NEW_ICON = new ScaledImageIconWrapper(NEW_ICON, 16, 16);
|
private static final Icon SCALED_NEW_ICON = new ScaledImageIcon(NEW_ICON, 16, 16);
|
||||||
private static final Icon TRANSLATED_NEW_ICON = new TranslateIcon(SCALED_NEW_ICON, 4, -4);
|
private static final Icon TRANSLATED_NEW_ICON = new TranslateIcon(SCALED_NEW_ICON, 4, -4);
|
||||||
private static final Icon CREATE_NEW_COMPARISON_ICON =
|
private static final Icon CREATE_NEW_COMPARISON_ICON =
|
||||||
new MultiIcon(COMPARISON_ICON, TRANSLATED_NEW_ICON);
|
new MultiIcon(COMPARISON_ICON, TRANSLATED_NEW_ICON);
|
||||||
|
@ -101,8 +101,7 @@ public abstract class CompareFunctionsAction extends DockingAction {
|
||||||
setPopupMenuData(new MenuData(new String[] { "Compare Selected Functions" },
|
setPopupMenuData(new MenuData(new String[] { "Compare Selected Functions" },
|
||||||
getToolBarIcon(), CREATE_COMPARISON_GROUP));
|
getToolBarIcon(), CREATE_COMPARISON_GROUP));
|
||||||
|
|
||||||
ToolBarData newToolBarData =
|
ToolBarData newToolBarData = new ToolBarData(getToolBarIcon(), CREATE_COMPARISON_GROUP);
|
||||||
new ToolBarData(getToolBarIcon(), CREATE_COMPARISON_GROUP);
|
|
||||||
setToolBarData(newToolBarData);
|
setToolBarData(newToolBarData);
|
||||||
|
|
||||||
setHelpLocation(new HelpLocation("FunctionComparison", "Function_Comparison"));
|
setHelpLocation(new HelpLocation("FunctionComparison", "Function_Comparison"));
|
||||||
|
|
|
@ -37,7 +37,7 @@ import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import resources.MultiIcon;
|
import resources.MultiIcon;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
import resources.icons.ScaledImageIconWrapper;
|
import resources.icons.ScaledImageIcon;
|
||||||
import resources.icons.TranslateIcon;
|
import resources.icons.TranslateIcon;
|
||||||
import util.CollectionUtils;
|
import util.CollectionUtils;
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ import util.CollectionUtils;
|
||||||
public class OpenFunctionTableAction extends DockingAction {
|
public class OpenFunctionTableAction extends DockingAction {
|
||||||
|
|
||||||
private static final Icon ADD_ICON = ResourceManager.loadImage("images/Plus.png");
|
private static final Icon ADD_ICON = ResourceManager.loadImage("images/Plus.png");
|
||||||
private static final Icon SCALED_ADD_ICON = new ScaledImageIconWrapper(ADD_ICON, 10, 10);
|
private static final Icon SCALED_ADD_ICON = new ScaledImageIcon(ADD_ICON, 10, 10);
|
||||||
private static final ImageIcon COMPARISON_ICON =
|
private static final ImageIcon COMPARISON_ICON =
|
||||||
ResourceManager.loadImage("images/page_white_c.png");
|
ResourceManager.loadImage("images/page_white_c.png");
|
||||||
private static final Icon TRANSLATED_ADD_ICON = new TranslateIcon(SCALED_ADD_ICON, 8, 1);
|
private static final Icon TRANSLATED_ADD_ICON = new TranslateIcon(SCALED_ADD_ICON, 8, 1);
|
||||||
|
|
|
@ -89,8 +89,8 @@ public class VTPlugin extends Plugin {
|
||||||
protected Icon createIcon() {
|
protected Icon createIcon() {
|
||||||
MultiIcon icon = new MultiIcon(new EmptyIcon(16, 16));
|
MultiIcon icon = new MultiIcon(new EmptyIcon(16, 16));
|
||||||
ImageIcon cancelIcon = ResourceManager.loadImage("images/dialog-cancel.png");
|
ImageIcon cancelIcon = ResourceManager.loadImage("images/dialog-cancel.png");
|
||||||
ScaledImageIconWrapper scaledCancelIcon =
|
ScaledImageIcon scaledCancelIcon =
|
||||||
new ScaledImageIconWrapper(cancelIcon, 13, 13);
|
new ScaledImageIcon(cancelIcon, 13, 13);
|
||||||
TranslateIcon translatedCancelIcon = new TranslateIcon(scaledCancelIcon, 3, 4);
|
TranslateIcon translatedCancelIcon = new TranslateIcon(scaledCancelIcon, 3, 4);
|
||||||
ImageIcon undoIcon = ResourceManager.loadImage("images/undo.png");
|
ImageIcon undoIcon = ResourceManager.loadImage("images/undo.png");
|
||||||
TranslateIcon translatedUndoIcon = new TranslateIcon(undoIcon, 0, -4);
|
TranslateIcon translatedUndoIcon = new TranslateIcon(undoIcon, 0, -4);
|
||||||
|
|
|
@ -31,7 +31,6 @@ import ghidra.util.datastruct.WeakSet;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
import resources.icons.FileBasedIcon;
|
import resources.icons.FileBasedIcon;
|
||||||
import resources.icons.ImageIconWrapper;
|
|
||||||
import utilities.util.reflection.ReflectionUtilities;
|
import utilities.util.reflection.ReflectionUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -493,9 +492,8 @@ public abstract class DockingAction implements DockingActionIf {
|
||||||
}
|
}
|
||||||
|
|
||||||
Icon icon = menuBarData.getMenuIcon();
|
Icon icon = menuBarData.getMenuIcon();
|
||||||
if (icon != null && icon instanceof ImageIconWrapper) {
|
if (icon instanceof FileBasedIcon filebasedIcon) {
|
||||||
ImageIconWrapper wrapper = (ImageIconWrapper) icon;
|
String filename = filebasedIcon.getFilename();
|
||||||
String filename = wrapper.getFilename();
|
|
||||||
buffer.append(" MENU ICON: ").append(filename);
|
buffer.append(" MENU ICON: ").append(filename);
|
||||||
buffer.append('\n');
|
buffer.append('\n');
|
||||||
}
|
}
|
||||||
|
@ -522,9 +520,8 @@ public abstract class DockingAction implements DockingActionIf {
|
||||||
}
|
}
|
||||||
|
|
||||||
Icon icon = popupMenuData.getMenuIcon();
|
Icon icon = popupMenuData.getMenuIcon();
|
||||||
if (icon != null && icon instanceof ImageIconWrapper) {
|
if (icon instanceof FileBasedIcon fileBasedIcon) {
|
||||||
ImageIconWrapper wrapper = (ImageIconWrapper) icon;
|
String filename = fileBasedIcon.getFilename();
|
||||||
String filename = wrapper.getFilename();
|
|
||||||
buffer.append(" POPUP ICON: ").append(filename);
|
buffer.append(" POPUP ICON: ").append(filename);
|
||||||
buffer.append('\n');
|
buffer.append('\n');
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import javax.swing.ImageIcon;
|
||||||
import resources.MultiIcon;
|
import resources.MultiIcon;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
import resources.icons.EmptyIcon;
|
import resources.icons.EmptyIcon;
|
||||||
import resources.icons.ScaledImageIconWrapper;
|
import resources.icons.ScaledImageIcon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An icon that allows sub-icons to be added at key perimeter locations. Each position can
|
* An icon that allows sub-icons to be added at key perimeter locations. Each position can
|
||||||
|
@ -317,7 +317,7 @@ public class BadgedIcon implements Icon {
|
||||||
|
|
||||||
MultiIcon icon = badgeMap.get(pos);
|
MultiIcon icon = badgeMap.get(pos);
|
||||||
|
|
||||||
Icon scaled = new ScaledImageIconWrapper(icon, badgeSize.width, badgeSize.height);
|
Icon scaled = new ScaledImageIcon(icon, badgeSize.width, badgeSize.height);
|
||||||
|
|
||||||
Point badgePaintLoc = getBadgePaintLocation(pos, badgeSize);
|
Point badgePaintLoc = getBadgePaintLocation(pos, badgeSize);
|
||||||
|
|
||||||
|
|
|
@ -324,7 +324,7 @@ public class ResourceManager {
|
||||||
* @return A new, scaled ImageIcon
|
* @return A new, scaled ImageIcon
|
||||||
*/
|
*/
|
||||||
public static ImageIcon getScaledIcon(Icon icon, int width, int height, int hints) {
|
public static ImageIcon getScaledIcon(Icon icon, int width, int height, int hints) {
|
||||||
return new ScaledImageIconWrapper(icon, width, height, hints);
|
return new ScaledImageIcon(icon, width, height, hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -337,7 +337,7 @@ public class ResourceManager {
|
||||||
* @return A new, scaled ImageIcon
|
* @return A new, scaled ImageIcon
|
||||||
*/
|
*/
|
||||||
public static ImageIcon getScaledIcon(Icon icon, int width, int height) {
|
public static ImageIcon getScaledIcon(Icon icon, int width, int height) {
|
||||||
return new ScaledImageIconWrapper(icon, width, height);
|
return new ScaledImageIcon(icon, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -346,7 +346,7 @@ public class ResourceManager {
|
||||||
* @return disabled icon
|
* @return disabled icon
|
||||||
*/
|
*/
|
||||||
public static ImageIcon getDisabledIcon(Icon icon) {
|
public static ImageIcon getDisabledIcon(Icon icon) {
|
||||||
return new DisabledImageIconWrapper(getImageIcon(icon));
|
return new DisabledImageIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -355,7 +355,7 @@ public class ResourceManager {
|
||||||
* @return disabled icon
|
* @return disabled icon
|
||||||
*/
|
*/
|
||||||
public static ImageIcon getDisabledIcon(ImageIcon icon) {
|
public static ImageIcon getDisabledIcon(ImageIcon icon) {
|
||||||
return new DisabledImageIconWrapper(icon);
|
return new DisabledImageIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -367,7 +367,7 @@ public class ResourceManager {
|
||||||
* @return a disabled version of the original icon.
|
* @return a disabled version of the original icon.
|
||||||
*/
|
*/
|
||||||
public static ImageIcon getDisabledIcon(Icon icon, int brightnessPercent) {
|
public static ImageIcon getDisabledIcon(Icon icon, int brightnessPercent) {
|
||||||
return new DisabledImageIconWrapper(icon, brightnessPercent);
|
return new DisabledImageIcon(icon, brightnessPercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -381,7 +381,7 @@ public class ResourceManager {
|
||||||
* @return the new icon
|
* @return the new icon
|
||||||
*/
|
*/
|
||||||
public static ImageIcon getImageIconFromImage(String imageName, Image image) {
|
public static ImageIcon getImageIconFromImage(String imageName, Image image) {
|
||||||
return new ImageIconWrapper(image, imageName);
|
return new DerivedImageIcon(imageName, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -396,7 +396,7 @@ public class ResourceManager {
|
||||||
if (icon instanceof ImageIcon) {
|
if (icon instanceof ImageIcon) {
|
||||||
return (ImageIcon) icon;
|
return (ImageIcon) icon;
|
||||||
}
|
}
|
||||||
return new ImageIconWrapper(icon);
|
return new DerivedImageIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -452,7 +452,7 @@ public class ResourceManager {
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
icon = new ImageIconWrapper(imageBytes, imageName);
|
icon = new BytesImageIcon(imageName, imageBytes);
|
||||||
iconMap.put(imageName, icon);
|
iconMap.put(imageName, icon);
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
@ -476,39 +476,47 @@ public class ResourceManager {
|
||||||
/**
|
/**
|
||||||
* Load the image specified by filename; returns the default bomb icon
|
* Load the image specified by filename; returns the default bomb icon
|
||||||
* if problems occur trying to load the file.
|
* if problems occur trying to load the file.
|
||||||
* <p>
|
|
||||||
*
|
*
|
||||||
* @param filename name of file to load, e.g., "images/home.gif"
|
* @param filename name of file to load, e.g., "images/home.gif"
|
||||||
* @return the image icon stored in the bytes
|
* @return the image icon stored in the bytes
|
||||||
*/
|
*/
|
||||||
public static ImageIcon loadImage(String filename) {
|
public static ImageIcon loadImage(String filename) {
|
||||||
|
|
||||||
// use the wrapper so that images are not loaded until they are needed
|
|
||||||
ImageIcon icon = iconMap.get(filename);
|
ImageIcon icon = iconMap.get(filename);
|
||||||
if (icon != null) {
|
if (icon == null) {
|
||||||
return icon;
|
icon = doLoadIcon(filename, ResourceManager.getDefaultIcon());
|
||||||
|
iconMap.put(filename, icon);
|
||||||
|
}
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImageIcon doLoadIcon(String filename, ImageIcon defaultIcon) {
|
||||||
|
// if only the name of an icon is given, but not a path, check to see if it is
|
||||||
|
// a resource that lives under our "images/" folder
|
||||||
|
if (!filename.contains("/")) {
|
||||||
|
URL url = getResource("images/" + filename);
|
||||||
|
if (url != null) {
|
||||||
|
return new UrlImageIcon(filename, url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// look for it directly with the given path
|
||||||
|
URL url = getResource(filename);
|
||||||
|
if (url != null) {
|
||||||
|
return new UrlImageIcon(filename, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// try using the filename as a file path
|
||||||
File imageFile = new File(filename);
|
File imageFile = new File(filename);
|
||||||
if (imageFile.exists()) {
|
if (imageFile.exists()) {
|
||||||
try {
|
try {
|
||||||
icon = new ImageIconWrapper(imageFile.toURI().toURL());
|
return new UrlImageIcon(filename, imageFile.toURI().toURL());
|
||||||
iconMap.put(filename, icon);
|
|
||||||
return icon;
|
|
||||||
}
|
}
|
||||||
catch (MalformedURLException e) {
|
catch (MalformedURLException e) {
|
||||||
// handled below
|
// handled below
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
URL url = getResource(filename);
|
return defaultIcon;
|
||||||
if (url != null) {
|
|
||||||
icon = new ImageIconWrapper(url);
|
|
||||||
iconMap.put(filename, icon);
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getDefaultIcon();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -547,7 +555,7 @@ public class ResourceManager {
|
||||||
Msg.error(ResourceManager.class,
|
Msg.error(ResourceManager.class,
|
||||||
"Could not find default icon: " + DEFAULT_ICON_FILENAME);
|
"Could not find default icon: " + DEFAULT_ICON_FILENAME);
|
||||||
}
|
}
|
||||||
DEFAULT_ICON = new ImageIconWrapper(url);
|
DEFAULT_ICON = new UrlImageIcon(DEFAULT_ICON_FILENAME, url);
|
||||||
}
|
}
|
||||||
return DEFAULT_ICON;
|
return DEFAULT_ICON;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* ###
|
||||||
|
* 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 resources.icons;
|
||||||
|
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
import generic.util.image.ImageUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link LazyImageIcon} that is created from a byte array
|
||||||
|
*/
|
||||||
|
public class BytesImageIcon extends LazyImageIcon {
|
||||||
|
private byte[] bytes;
|
||||||
|
|
||||||
|
public BytesImageIcon(String name, byte[] imageBytes) {
|
||||||
|
super(name);
|
||||||
|
this.bytes = Objects.requireNonNull(imageBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ImageIcon createImageIcon() {
|
||||||
|
String name = getFilename();
|
||||||
|
Image image = createImage();
|
||||||
|
if (!ImageUtils.waitForImage(name, image)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new ImageIcon(image, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Image createImage() {
|
||||||
|
return Toolkit.getDefaultToolkit().createImage(bytes);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/* ###
|
||||||
|
* 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 resources.icons;
|
||||||
|
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
import generic.util.image.ImageUtils;
|
||||||
|
import resources.ResourceManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link LazyImageIcon} that is created from an {@link Icon} or an {@link Image}
|
||||||
|
*/
|
||||||
|
public class DerivedImageIcon extends LazyImageIcon {
|
||||||
|
private Icon sourceIcon;
|
||||||
|
private Image sourceImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for deriving from an icon
|
||||||
|
* @param icon the source icon
|
||||||
|
*/
|
||||||
|
public DerivedImageIcon(Icon icon) {
|
||||||
|
super(ResourceManager.getIconName(icon));
|
||||||
|
this.sourceIcon = Objects.requireNonNull(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for deriving from an image
|
||||||
|
* @param name the name of the image
|
||||||
|
* @param image the source image
|
||||||
|
*/
|
||||||
|
public DerivedImageIcon(String name, Image image) {
|
||||||
|
super(name);
|
||||||
|
this.sourceImage = Objects.requireNonNull(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ImageIcon createImageIcon() {
|
||||||
|
Image image = createImage();
|
||||||
|
String imageName = getFilename();
|
||||||
|
if (!ImageUtils.waitForImage(imageName, image)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new ImageIcon(image, imageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Image createImage() {
|
||||||
|
if (sourceImage != null) {
|
||||||
|
return sourceImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if sourceImage is null, then sourceIcon can't be null
|
||||||
|
if (sourceIcon instanceof ImageIcon) {
|
||||||
|
return ((ImageIcon) sourceIcon).getImage();
|
||||||
|
}
|
||||||
|
BufferedImage bufferedImage = new BufferedImage(sourceIcon.getIconWidth(),
|
||||||
|
sourceIcon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics graphics = bufferedImage.getGraphics();
|
||||||
|
sourceIcon.paintIcon(null, graphics, 0, 0);
|
||||||
|
graphics.dispose();
|
||||||
|
return bufferedImage;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/* ###
|
||||||
|
* 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 resources.icons;
|
||||||
|
|
||||||
|
import java.awt.Image;
|
||||||
|
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
import generic.util.image.ImageUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link LazyImageIcon} that creates a disabled version of an icon
|
||||||
|
*/
|
||||||
|
public class DisabledImageIcon extends DerivedImageIcon {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The inverse percentage of gray (higher percentage equals less gray) to apply to
|
||||||
|
* the disabled image; higher is brighter
|
||||||
|
*/
|
||||||
|
private int brightnessPercent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct wrapped disabled ImageIcon based upon specified baseIcon.
|
||||||
|
* A 50% brightness will be applied.
|
||||||
|
* @param baseIcon enabled icon to be rendered as disabled
|
||||||
|
*/
|
||||||
|
public DisabledImageIcon(Icon baseIcon) {
|
||||||
|
this(baseIcon, 50); // default to half gray
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct wrapped disabled ImageIcon based upon specified baseIcon
|
||||||
|
* using the specified brightness level
|
||||||
|
* @param baseIcon the icon to create a disabled version of
|
||||||
|
* @param brightnessPercent a brightness level specified using a
|
||||||
|
* value in the range of 0 thru 100.
|
||||||
|
*/
|
||||||
|
public DisabledImageIcon(Icon baseIcon, int brightnessPercent) {
|
||||||
|
super(baseIcon);
|
||||||
|
this.brightnessPercent = brightnessPercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ImageIcon createImageIcon() {
|
||||||
|
Image image = createImage();
|
||||||
|
Image disabledImage = ImageUtils.createDisabledImage(image, brightnessPercent);
|
||||||
|
return new ImageIcon(disabledImage, getFilename());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,6 +22,12 @@ import javax.swing.ImageIcon;
|
||||||
|
|
||||||
import generic.util.image.ImageUtils;
|
import generic.util.image.ImageUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a disabled version of an icon
|
||||||
|
* @deprecated This class has been replaced by {@link DisabledImageIcon} since it
|
||||||
|
* extends {@link ImageIconWrapper} which has also been deprecated.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
public class DisabledImageIconWrapper extends ImageIconWrapper {
|
public class DisabledImageIconWrapper extends ImageIconWrapper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -36,7 +36,13 @@ import resources.ResourceManager;
|
||||||
* it has the added benefit of allowing the use of static initialization
|
* it has the added benefit of allowing the use of static initialization
|
||||||
* of ImageIcons without starting the Swing thread which can cause
|
* of ImageIcons without starting the Swing thread which can cause
|
||||||
* problems when running headless.
|
* problems when running headless.
|
||||||
|
*
|
||||||
|
* @deprecated This class has been replaced by a series of classes that extend
|
||||||
|
* {@link LazyImageIcon}: {@link UrlImageIcon}, {@link DerivedImageIcon}, {@link BytesImageIcon},
|
||||||
|
* {@link DisabledImageIcon}, and {@link ScaledImageIcon}. Pick the one that matches
|
||||||
|
* the constructor that was being used to create an ImageIconWrapper
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
public class ImageIconWrapper extends ImageIcon implements FileBasedIcon {
|
public class ImageIconWrapper extends ImageIcon implements FileBasedIcon {
|
||||||
|
|
||||||
private boolean loaded;
|
private boolean loaded;
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
/* ###
|
||||||
|
* 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 resources.icons;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.ImageObserver;
|
||||||
|
|
||||||
|
import javax.accessibility.AccessibleContext;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
import resources.ResourceManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <code>LazyImageIcon</code> provides the ability to instantiate
|
||||||
|
* an ImageIcon with delayed loading. In addition to delayed loading
|
||||||
|
* it has the added benefit of allowing the use of static initialization
|
||||||
|
* of ImageIcons without starting the Swing thread which can cause
|
||||||
|
* problems when running headless.
|
||||||
|
*/
|
||||||
|
public abstract class LazyImageIcon extends ImageIcon implements FileBasedIcon {
|
||||||
|
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
protected LazyImageIcon(String name) {
|
||||||
|
setDescription(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void init() {
|
||||||
|
if (!loaded) {
|
||||||
|
loaded = true;
|
||||||
|
ImageIcon imageIcon = createImageIcon();
|
||||||
|
if (imageIcon == null) {
|
||||||
|
imageIcon = getDefaultIcon();
|
||||||
|
}
|
||||||
|
super.setImage(imageIcon.getImage());
|
||||||
|
super.setDescription(getDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract ImageIcon createImageIcon();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFilename() {
|
||||||
|
return getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Image getImage() {
|
||||||
|
init();
|
||||||
|
return super.getImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessibleContext getAccessibleContext() {
|
||||||
|
init();
|
||||||
|
return super.getAccessibleContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
init();
|
||||||
|
return super.getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIconHeight() {
|
||||||
|
init();
|
||||||
|
return super.getIconHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIconWidth() {
|
||||||
|
init();
|
||||||
|
return super.getIconWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getImageLoadStatus() {
|
||||||
|
init();
|
||||||
|
return super.getImageLoadStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImageObserver getImageObserver() {
|
||||||
|
init();
|
||||||
|
return super.getImageObserver();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
|
||||||
|
init();
|
||||||
|
super.paintIcon(c, g, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDescription(String description) {
|
||||||
|
super.setDescription(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setImage(Image image) {
|
||||||
|
init();
|
||||||
|
super.setImage(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
init();
|
||||||
|
return super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageIcon getDefaultIcon() {
|
||||||
|
ImageIcon defaultIcon = ResourceManager.getDefaultIcon();
|
||||||
|
if (this == defaultIcon) {
|
||||||
|
// this can happen under just the right conditions when loading the default
|
||||||
|
// icon's bytes fails (probably due to disk or network issues)
|
||||||
|
throw new IllegalStateException("Unexpected failure loading the default icon!");
|
||||||
|
}
|
||||||
|
return defaultIcon; // some sort of initialization has failed
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* ###
|
||||||
|
* 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 resources.icons;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
import generic.util.image.ImageUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link LazyImageIcon} that creates a scaled version of an icon
|
||||||
|
*/
|
||||||
|
public class ScaledImageIcon extends DerivedImageIcon {
|
||||||
|
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
private int hints;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct wrapped scaled ImageIcon based upon specified
|
||||||
|
* baseIcon and desired size. The rendering hints of
|
||||||
|
* {@link Image#SCALE_AREA_AVERAGING} will be applied.
|
||||||
|
* @param baseIcon base icon
|
||||||
|
* @param width new icon width
|
||||||
|
* @param height new icon height
|
||||||
|
*/
|
||||||
|
public ScaledImageIcon(Icon baseIcon, int width, int height) {
|
||||||
|
this(baseIcon, width, height, Image.SCALE_AREA_AVERAGING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct wrapped scaled ImageIcon based upon specified
|
||||||
|
* baseIcon and desired size
|
||||||
|
* @param baseIcon base icon
|
||||||
|
* @param width new icon width
|
||||||
|
* @param height new icon height
|
||||||
|
* @param hints {@link RenderingHints} used by {@link Graphics2D}
|
||||||
|
*/
|
||||||
|
public ScaledImageIcon(Icon baseIcon, int width, int height, int hints) {
|
||||||
|
super(baseIcon);
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.hints = hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ImageIcon createImageIcon() {
|
||||||
|
Image image = createImage();
|
||||||
|
Image scaledImage = ImageUtils.createScaledImage(image, width, height, hints);
|
||||||
|
return new ImageIcon(scaledImage, getFilename());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,6 +22,12 @@ import javax.swing.ImageIcon;
|
||||||
|
|
||||||
import generic.util.image.ImageUtils;
|
import generic.util.image.ImageUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a scaled version of an icon
|
||||||
|
* @deprecated This class has been replaced by {@link ScaledImageIcon} since it
|
||||||
|
* extends {@link ImageIconWrapper} which has also been deprecated.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
public class ScaledImageIconWrapper extends ImageIconWrapper {
|
public class ScaledImageIconWrapper extends ImageIconWrapper {
|
||||||
|
|
||||||
private int width;
|
private int width;
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/* ###
|
||||||
|
* 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 resources.icons;
|
||||||
|
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
import generic.util.image.ImageUtils;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link LazyImageIcon} that is created from a URL to an icon file.
|
||||||
|
*/
|
||||||
|
public class UrlImageIcon extends LazyImageIcon {
|
||||||
|
private URL imageURL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param path the path String used to create the URL
|
||||||
|
* @param url the {@link URL} to an icon resource file
|
||||||
|
*/
|
||||||
|
public UrlImageIcon(String path, URL url) {
|
||||||
|
super(path);
|
||||||
|
this.imageURL = Objects.requireNonNull(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ImageIcon createImageIcon() {
|
||||||
|
String name = getFilename();
|
||||||
|
Image image = createImage();
|
||||||
|
if (image == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!ImageUtils.waitForImage(name, image)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new ImageIcon(image, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Image createImage() {
|
||||||
|
byte[] imageBytes = loadBytesFromURL(imageURL);
|
||||||
|
if (imageBytes == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Toolkit.getDefaultToolkit().createImage(imageBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] loadBytesFromURL(URL url) {
|
||||||
|
try (InputStream is = url.openStream()) {
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
int length = 0;
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
while ((length = is.read(buf)) > 0) {
|
||||||
|
os.write(buf, 0, length);
|
||||||
|
}
|
||||||
|
return os.toByteArray();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
Msg.error(this, "Exception loading image bytes: " + url.toExternalForm(), e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue