mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Merge remote-tracking branch 'origin/GP-41_dev747368_multiiconbuilder'
This commit is contained in:
commit
2c3ceb59d1
3 changed files with 224 additions and 19 deletions
|
@ -15,6 +15,10 @@
|
|||
*/
|
||||
package resources;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
@ -24,13 +28,12 @@ import resources.icons.TranslateIcon;
|
|||
|
||||
/**
|
||||
* A builder to allow for easier creation of an icon that is composed of a base icon, with
|
||||
* other icons overlayed. The {@link #build()} method returns an {@link ImageIcon}, as this
|
||||
* allows Java's buttons to create analogue disabled icons correctly.
|
||||
* other icons overlaid. The {@link #build()} method returns an {@link ImageIcon}, as this
|
||||
* allows Java's buttons to automatically create disabled icons correctly.
|
||||
*
|
||||
* <P>Note: this class is a work-in-progress. Add more methods for locating overlays as needed.
|
||||
*/
|
||||
public class MultiIconBuilder {
|
||||
|
||||
private MultiIcon multiIcon;
|
||||
private String description;
|
||||
|
||||
|
@ -38,6 +41,28 @@ public class MultiIconBuilder {
|
|||
this.multiIcon = new MultiIcon(Objects.requireNonNull(baseIcon));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified icon as an overlay to the base icon, possibly scaled according
|
||||
* to the specified width and height, in the specified quadrant corner.
|
||||
*
|
||||
* @param icon the icon to overlay
|
||||
* @param w width of the overlaid icon
|
||||
* @param h height of the overlaid icon
|
||||
* @param quandrant corner to place the overlay on
|
||||
* @return this builder (for chaining)
|
||||
*/
|
||||
public MultiIconBuilder addIcon(Icon icon, int w, int h, QUADRANT quandrant) {
|
||||
ImageIcon scaled = ResourceManager.getScaledIcon(icon, w, h);
|
||||
|
||||
int x = (multiIcon.getIconWidth() - scaled.getIconWidth()) * quandrant.x;
|
||||
int y = (multiIcon.getIconHeight() - scaled.getIconHeight()) * quandrant.y;
|
||||
|
||||
TranslateIcon txIcon = new TranslateIcon(scaled, x, y);
|
||||
multiIcon.addIcon(txIcon);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given icon as an overlay to the base icon, to the lower-right
|
||||
*
|
||||
|
@ -45,7 +70,7 @@ public class MultiIconBuilder {
|
|||
* @return this builder
|
||||
*/
|
||||
public MultiIconBuilder addLowerRightIcon(Icon icon) {
|
||||
return addLowerRightIcon(icon, icon.getIconWidth(), icon.getIconHeight());
|
||||
return addIcon(icon, icon.getIconWidth(), icon.getIconHeight(), QUADRANT.LR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,14 +83,7 @@ public class MultiIconBuilder {
|
|||
* @return this builder
|
||||
*/
|
||||
public MultiIconBuilder addLowerRightIcon(Icon icon, int w, int h) {
|
||||
|
||||
ImageIcon scaled = ResourceManager.getScaledIcon(icon, w, h);
|
||||
|
||||
int x = multiIcon.getIconWidth() - scaled.getIconWidth();
|
||||
int y = multiIcon.getIconHeight() - scaled.getIconHeight();
|
||||
TranslateIcon txIcon = new TranslateIcon(scaled, x, y);
|
||||
multiIcon.addIcon(txIcon);
|
||||
return this;
|
||||
return addIcon(icon, w, h, QUADRANT.LR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,7 +93,7 @@ public class MultiIconBuilder {
|
|||
* @return this builder
|
||||
*/
|
||||
public MultiIconBuilder addLowerLeftIcon(Icon icon) {
|
||||
return addLowerLeftIcon(icon, icon.getIconWidth(), icon.getIconHeight());
|
||||
return addIcon(icon, icon.getIconWidth(), icon.getIconHeight(), QUADRANT.LL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,14 +106,34 @@ public class MultiIconBuilder {
|
|||
* @return this builder
|
||||
*/
|
||||
public MultiIconBuilder addLowerLeftIcon(Icon icon, int w, int h) {
|
||||
return addIcon(icon, w, h, QUADRANT.LL);
|
||||
}
|
||||
|
||||
ImageIcon scaled = ResourceManager.getScaledIcon(icon, w, h);
|
||||
/**
|
||||
* Add text overlaid on the base icon, aligned to the specified quadrant.
|
||||
*
|
||||
* @param text Text string to write onto the icon. Probably can only fit a letter or two
|
||||
* @param font The font to use to render the text. You know the size of the base icon, so
|
||||
* you should be able to figure out the size of the font to use for the text
|
||||
* @param color The color to use when rendering the text
|
||||
* @param quandrant The {@link QUADRANT} to align the text to different parts of the icon
|
||||
* @return this builder (for chaining)
|
||||
*/
|
||||
public MultiIconBuilder addText(String text, Font font, Color color, QUADRANT quandrant) {
|
||||
|
||||
int x = 0;
|
||||
int y = multiIcon.getIconHeight() - scaled.getIconHeight();
|
||||
TranslateIcon txIcon = new TranslateIcon(scaled, x, y);
|
||||
multiIcon.addIcon(txIcon);
|
||||
return this;
|
||||
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||
TextLayout tl = new TextLayout(text, font, frc);
|
||||
|
||||
BufferedImage bi = new BufferedImage((int) Math.ceil(tl.getAdvance()),
|
||||
(int) Math.ceil(tl.getAscent() + tl.getDescent()), BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
Graphics2D g2d = (Graphics2D) bi.getGraphics();
|
||||
g2d.setFont(font);
|
||||
g2d.setColor(color);
|
||||
tl.draw(g2d, 0, tl.getAscent());
|
||||
g2d.dispose();
|
||||
|
||||
return addIcon(new ImageIcon(bi), bi.getWidth(), bi.getHeight(), quandrant);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* Enum specifying the quadrant of an overlay, either upper left, upper right, lower left, lower right.
|
||||
*/
|
||||
public enum QUADRANT {
|
||||
UL(0, 0), UR(1, 0), LL(0, 1), LR(1, 1);
|
||||
|
||||
QUADRANT(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
|
||||
/**
|
||||
* String to enum.
|
||||
*
|
||||
* @param s string of either "UL", "UR", "LL", "LR"
|
||||
* @param defaultValue value to return if string is invalid
|
||||
* @return QUADRANT enum
|
||||
*/
|
||||
public static QUADRANT valueOf(String s, QUADRANT defaultValue) {
|
||||
if (s != null) {
|
||||
try {
|
||||
return QUADRANT.valueOf(s.toUpperCase());
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/* ###
|
||||
* 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.BufferedImage;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import resources.MultiIconBuilder;
|
||||
import resources.QUADRANT;
|
||||
|
||||
/**
|
||||
* Minimal tests for MultiIconBuilder. Doesn't test the produced images, just that it didn't cause an exception.
|
||||
* <p>
|
||||
* The showXYZ() methods are present so a human can run them as a test and see the output
|
||||
*/
|
||||
public class MultiIconBuilderTest {
|
||||
|
||||
private ImageIcon makeEmptyIcon(int w, int h, Color color) {
|
||||
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
|
||||
if (color != null) {
|
||||
Graphics g = bi.getGraphics();
|
||||
g.setColor(color);
|
||||
g.fillRect(0, 0, w, h);
|
||||
g.dispose();
|
||||
}
|
||||
return new ImageIcon(bi);
|
||||
}
|
||||
|
||||
private ImageIcon makeQuandrantIcon(int w, int h, Color bgColor, Color lineColor) {
|
||||
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics g = bi.getGraphics();
|
||||
g.setColor(bgColor);
|
||||
g.fillRect(0, 0, w, h);
|
||||
g.setColor(lineColor);
|
||||
g.drawLine(w / 2, 0, w / 2, h);
|
||||
g.drawLine(0, h / 2, w, h / 2);
|
||||
g.dispose();
|
||||
return new ImageIcon(bi);
|
||||
}
|
||||
|
||||
private Font font = new Font("Monospaced", Font.PLAIN, 12);
|
||||
|
||||
//@Test
|
||||
public void showIconText() {
|
||||
for (QUADRANT quad : QUADRANT.values()) {
|
||||
ImageIcon icon =
|
||||
new MultiIconBuilder(makeQuandrantIcon(32, 32, Color.gray, Color.white))
|
||||
.addText("Abcfg", font, Color.red, quad)
|
||||
.build();
|
||||
JOptionPane.showMessageDialog(null, "" + quad + " aligned", "Icon text overlay test",
|
||||
JOptionPane.OK_OPTION, icon);
|
||||
}
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void showIconOverlay() {
|
||||
for (QUADRANT quad : QUADRANT.values()) {
|
||||
ImageIcon icon = new MultiIconBuilder(makeEmptyIcon(32, 32, Color.gray))
|
||||
.addIcon(makeEmptyIcon(8, 8, Color.red), 8, 8, quad)
|
||||
.build();
|
||||
JOptionPane.showMessageDialog(null, "" + quad + " aligned", "Icon_icon overlay test",
|
||||
JOptionPane.OK_OPTION, icon);
|
||||
}
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void showScaledIconOverlay() {
|
||||
for (QUADRANT quad : QUADRANT.values()) {
|
||||
ImageIcon icon = new MultiIconBuilder(makeEmptyIcon(32, 32, Color.gray))
|
||||
.addIcon(makeQuandrantIcon(32, 32, Color.red, Color.black), 14, 14, quad)
|
||||
.build();
|
||||
JOptionPane.showMessageDialog(null, "" + quad + " aligned",
|
||||
"Scaled icon_icon overlay test",
|
||||
JOptionPane.OK_OPTION, icon);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIconOverlay() {
|
||||
// doesn't verify anything other than it doesn't fall down go boom
|
||||
for (QUADRANT quad : QUADRANT.values()) {
|
||||
ImageIcon icon = new MultiIconBuilder(makeEmptyIcon(32, 32, Color.gray))
|
||||
.addIcon(makeQuandrantIcon(32, 32, Color.red, Color.black), 14, 14, quad)
|
||||
.build();
|
||||
icon.getDescription();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIconText() {
|
||||
// doesn't verify anything other than it doesn't fall down go boom
|
||||
for (QUADRANT quad : QUADRANT.values()) {
|
||||
ImageIcon icon =
|
||||
new MultiIconBuilder(makeQuandrantIcon(32, 32, Color.gray, Color.white))
|
||||
.addText("Abcfg", font, Color.red, quad)
|
||||
.build();
|
||||
icon.getDescription();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue