GP-2865 created the mirror and flip icon modifiers. Also, updated undo/redo icons

This commit is contained in:
ghidragon 2022-11-22 15:58:28 -05:00
parent 8d6cf5e310
commit 75c2c08654
8 changed files with 149 additions and 14 deletions

View file

@ -85,6 +85,7 @@ src/main/resources/images/menu16.gif||GHIDRA||reviewed||END|
src/main/resources/images/note-red.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/resources/images/note.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/resources/images/note.yellow.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/resources/images/oxygen-edit-redo.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/resources/images/page.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/page_code.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/page_excel.png||FAMFAMFAM Icons - CC 2.5||||END|
@ -92,7 +93,6 @@ src/main/resources/images/page_go.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/page_green.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/play.png||GHIDRA||||END|
src/main/resources/images/preferences-system-windows.png||Tango Icons - Public Domain||||END|
src/main/resources/images/redo.png||Crystal Clear Icons - LGPL 2.1||||END|
src/main/resources/images/software-update-available.png||Tango Icons - Public Domain|||tango icon set|END|
src/main/resources/images/table.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
src/main/resources/images/tag.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
@ -100,7 +100,6 @@ src/main/resources/images/text_lowercase.png||FAMFAMFAM Icons - CC 2.5|||famfamf
src/main/resources/images/textfield_rename.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
src/main/resources/images/tip.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/resources/images/trash-empty.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/resources/images/undo.png||Crystal Clear Icons - LGPL 2.1||||END|
src/main/resources/images/user-home.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/resources/images/view-filter.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/resources/images/warning.help.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|

View file

@ -100,8 +100,12 @@ icon.subtract = list-remove.png
icon.toggle.expand = expand.gif
icon.toggle.collapse = collapse.gif
icon.undo = undo.png
icon.redo = redo.png
// the oxygen-edit-redo.png image is not centered vertically in its 16x16 icon. To center it we
// create an empty 16x16 base and then move down by 3 pixels
icon.undo = EMPTY_ICON{oxygen-edit-redo.png[mirror][move(0,3)]}
icon.redo = EMPTY_ICON{oxygen-edit-redo.png[move(0,3)]}
icon.font = text_lowercase.png
icon.rename = textfield_rename.png
icon.check = check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 692 B

View file

@ -26,8 +26,7 @@ import javax.swing.Icon;
import resources.MultiIcon;
import resources.ResourceManager;
import resources.icons.RotateIcon;
import resources.icons.TranslateIcon;
import resources.icons.*;
/**
* Class that can transform one icon into another. Useful for scaling, translating, disabling,
@ -39,6 +38,8 @@ public class IconModifier {
Point translation;
boolean disabled;
Integer rotation;
boolean mirror; // mirrors the image left to right
boolean flip; // flips the image upside down
List<IconValue> overlayIconValues = null;
/**
@ -47,12 +48,17 @@ public class IconModifier {
* @param translation if non-null, translates an icon by this amount
* @param rotation if non-null, the amount in degrees to rotate the icon
* @param disabled if true, creates a disabled version of the icon
* @param mirror if true, the image will have its x values swapped (left to right)
* @param flip if true, the image will have its y values swapped (turned upside down)
*/
public IconModifier(Dimension size, Point translation, Integer rotation, boolean disabled) {
public IconModifier(Dimension size, Point translation, Integer rotation,
boolean disabled, boolean mirror, boolean flip) {
this.size = size;
this.translation = translation;
this.rotation = rotation;
this.disabled = disabled;
this.mirror = mirror;
this.flip = flip;
}
private IconModifier() {
@ -92,6 +98,20 @@ public class IconModifier {
disabled = true;
}
/**
* Sets the modifier to flip the icon side to side
*/
public void setMirror() {
mirror = true;
}
/**
* Sets the modifier to flip the icon side to side
*/
public void setFlip() {
flip = true;
}
/**
* Modifies the given icon by the any of the modifiers set.
* @param icon the icon to be modified
@ -107,8 +127,14 @@ public class IconModifier {
if (disabled) {
modified = ResourceManager.getDisabledIcon(modified);
}
if (mirror) {
modified = new ReflectedIcon(modified, true);
}
if (flip) {
modified = new ReflectedIcon(modified, false);
}
if (rotation != null) {
modified = new RotateIcon(icon, rotation);
modified = new RotateIcon(modified, rotation);
}
if (translation != null) {
modified = new TranslateIcon(modified, translation.x, translation.y);
@ -132,6 +158,12 @@ public class IconModifier {
if (size != null) {
builder.append("[" + "size(" + size.width + "," + size.height + ")]");
}
if (mirror) {
builder.append("[mirror]");
}
if (flip) {
builder.append("[flip]");
}
if (rotation != null) {
builder.append("[rotate(" + rotation + ")]");
}
@ -195,6 +227,12 @@ public class IconModifier {
else if (modifierString.startsWith("move")) {
parseMoveModifier(modifier, modifierString);
}
else if (modifierString.startsWith("mirror")) {
parseMirrorModifier(modifier, modifierString);
}
else if (modifierString.startsWith("flip")) {
parseFlipModifier(modifier, modifierString);
}
else if (modifierString.startsWith("rotate")) {
parseRotateModifier(modifier, modifierString);
}
@ -228,7 +266,7 @@ public class IconModifier {
private boolean hadModifications() {
return size != null || translation != null || overlayIconValues != null ||
rotation != null || disabled;
rotation != null || disabled || mirror || flip;
}
private static void parseDisabledModifier(IconModifier modifier, String modifierString)
@ -239,6 +277,22 @@ public class IconModifier {
modifier.setDisabled();
}
private static void parseMirrorModifier(IconModifier modifier, String modifierString)
throws ParseException {
if (!modifierString.equals("mirror")) {
throw new ParseException("Illegal Icon modifier: " + modifier, 0);
}
modifier.setMirror();
}
private static void parseFlipModifier(IconModifier modifier, String modifierString)
throws ParseException {
if (!modifierString.equals("flip")) {
throw new ParseException("Illegal Icon modifier: " + modifier, 0);
}
modifier.setFlip();
}
private static void parseRotateModifier(IconModifier modifier, String modifierString)
throws ParseException {
String argsString = modifierString.substring("rotate".length());

View file

@ -0,0 +1,62 @@
/* ###
* 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.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.Icon;
import javax.swing.ImageIcon;
/**
* {@link LazyImageIcon} that creates a reflected version of an icon. This creates a version of the
* icon which has had either its x values reflected (left to right) or its y values reflected
* (upside down)
*/
public class ReflectedIcon extends DerivedImageIcon {
private boolean leftToRight;
/**
* Construct a icon that is reflected either left to right or upside down.
* @param baseIcon base icon
* @param leftToRight true flips x values, false flips y values
*/
public ReflectedIcon(Icon baseIcon, boolean leftToRight) {
super(baseIcon);
this.leftToRight = leftToRight;
}
@Override
protected ImageIcon createImageIcon() {
Icon sourceIcon = getSourceIcon();
Image image = createImage();
int width = sourceIcon.getIconWidth();
int height = sourceIcon.getIconHeight();
BufferedImage flippedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = (Graphics2D) flippedImage.getGraphics();
if (leftToRight) {
graphics.drawImage(image, width, 0, -width, height, null);
}
else {
graphics.drawImage(image, 0, height, width, -height, null);
}
graphics.dispose();
return new ImageIcon(flippedImage, getFilename());
}
}

View file

@ -83,6 +83,20 @@ public class IconModifierTest {
assertNotEquals(baseIcon, modifiedIcon);
}
@Test
public void testMirrorModifier() throws Exception {
IconModifier modifier = IconModifier.parse("[mirror]");
Icon modifiedIcon = modifier.modify(baseIcon, values);
assertNotEquals(baseIcon, modifiedIcon);
}
@Test
public void testFlipModifier() throws Exception {
IconModifier modifier = IconModifier.parse("[flip]");
Icon modifiedIcon = modifier.modify(baseIcon, values);
assertNotEquals(baseIcon, modifiedIcon);
}
@Test
public void testOverlayIcon() throws Exception {
IconModifier modifier = IconModifier.parse("{images/flag.png}");
@ -179,11 +193,13 @@ public class IconModifierTest {
@Test
public void testGetSerializationString() {
//@formatter:off
assertEquals("[size(5,9)]", new IconModifier(new Dimension(5,9), null, null, false).getSerializationString());
assertEquals("[move(8,7)]", new IconModifier(null, new Point(8,7), null,false).getSerializationString());
assertEquals("[disabled]", new IconModifier(null, null, null, true).getSerializationString());
assertEquals("[size(5,0)][move(8,7)][disabled]", new IconModifier(new Dimension(5,0), new Point(8,7), null, true).getSerializationString());
assertEquals("[rotate(90)]", new IconModifier(null, null, 90, false).getSerializationString());
assertEquals("[size(5,9)]", new IconModifier(new Dimension(5,9), null, null, false, false, false).getSerializationString());
assertEquals("[move(8,7)]", new IconModifier(null, new Point(8,7), null,false, false, false).getSerializationString());
assertEquals("[disabled]", new IconModifier(null, null, null, true, false, false).getSerializationString());
assertEquals("[size(5,0)][move(8,7)][disabled]", new IconModifier(new Dimension(5,0), new Point(8,7), null, true, false, false).getSerializationString());
assertEquals("[rotate(90)]", new IconModifier(null, null, 90, false, false, false).getSerializationString());
assertEquals("[mirror]", new IconModifier(null, null, null, false, true, false).getSerializationString());
assertEquals("[flip]", new IconModifier(null, null, null, false, false, true).getSerializationString());
//@formatter:on
}
}