swapping out toolbar buttons to be svg, rendered from the theme

This commit is contained in:
Ben Fry
2022-01-12 21:20:58 -05:00
parent 81b3a0e16d
commit 74f5741702
61 changed files with 151 additions and 26 deletions
+16 -2
View File
@@ -732,8 +732,22 @@ public abstract class Mode {
public Image loadImageX(String filename) {
final int res = Toolkit.highResImages() ? 2 : 1;
return loadImage(filename + "-" + res + "x.png");
return loadImage(filename + "-" + Toolkit.highResMultiplier() + "x.png");
}
public String loadString(String filename) {
File file;
if (filename.startsWith("/lib/")) {
// remove the slash from the front
file = Platform.getContentFile(filename.substring(1));
} else {
file = new File(folder, filename);
}
if (!file.exists()) {
return null;
}
return PApplet.join(PApplet.loadStrings(file), "\n");
}
+42 -8
View File
@@ -33,6 +33,8 @@ abstract public class EditorButton extends JComponent
implements MouseListener, MouseMotionListener, ActionListener {
static public final int DIM = Toolkit.zoom(30);
/** The lowercase short name used to load its SVG/PNG image data. */
protected String name;
/** Button's description. */
protected String title;
/** Description of alternate behavior when shift is down. */
@@ -69,18 +71,52 @@ implements MouseListener, MouseMotionListener, ActionListener {
public EditorButton(EditorToolbar parent, String name,
String title, String titleShift, String titleAlt) {
this.name = name;
this.toolbar = parent;
this.title = title;
this.titleShift = titleShift;
this.titleAlt = titleAlt;
Mode mode = toolbar.mode;
updateTheme();
disabledImage = mode.loadImageX(name + "-disabled");
enabledImage = mode.loadImageX(name + "-enabled");
selectedImage = mode.loadImageX(name + "-selected");
pressedImage = mode.loadImageX(name + "-pressed");
rolloverImage = mode.loadImageX(name + "-rollover");
addMouseListener(this);
addMouseMotionListener(this);
}
protected Image renderImage(String state) {
Mode mode = toolbar.mode;
String xmlOrig = mode.loadString(name + ".svg");
if (xmlOrig == null) {
// load image data from PNG files
return mode.loadImageX(name + "-" + state);
}
final String FIELD_COLOR = "#fff";
final String GLYPH_COLOR = "#ff5757";
final String STROKE_COLOR = "silver";
String field = Theme.get("toolbar.button." + state + ".field");
String glyph = Theme.get("toolbar.button." + state + ".glyph");
String stroke = Theme.get("toolbar.button." + state + ".stroke");
String xmlStr = xmlOrig
.replace(FIELD_COLOR, field)
.replace(GLYPH_COLOR, glyph)
.replace(STROKE_COLOR, stroke);
final int px = DIM * Toolkit.highResMultiplier();
return Toolkit.svgToImage(xmlStr, px, px);
}
public void updateTheme() {
disabledImage = renderImage("disabled");
enabledImage = renderImage("enabled");
selectedImage = renderImage("selected");
pressedImage = renderImage("pressed");
rolloverImage = renderImage("rollover");
if (disabledImage == null) {
disabledImage = enabledImage;
@@ -94,8 +130,6 @@ implements MouseListener, MouseMotionListener, ActionListener {
if (rolloverImage == null) {
rolloverImage = enabledImage; // could be pressed image
}
addMouseListener(this);
addMouseMotionListener(this);
}
+5
View File
@@ -98,6 +98,11 @@ public class Theme {
}
static public String get(String attribute) {
return theme.get(attribute);
}
static public boolean getBoolean(String attribute) {
return theme.getBoolean(attribute);
}
+65 -11
View File
@@ -76,8 +76,12 @@ import processing.app.Messages;
import processing.app.Platform;
import processing.app.Preferences;
import processing.app.Util;
import processing.awt.PGraphicsJava2D;
import processing.awt.PShapeJava2D;
import processing.core.PApplet;
import processing.core.PShape;
import processing.data.StringList;
import processing.data.XML;
/**
@@ -155,7 +159,7 @@ public class Toolkit {
/**
* Create a menu item and set its KeyStroke by name (so it can be stored
* in the language settings or the preferences. Syntax is here:
* in the language settings or the preferences). Syntax is here:
* https://docs.oracle.com/javase/8/docs/api/javax/swing/KeyStroke.html#getKeyStroke-java.lang.String-
*/
static public JMenuItem newJMenuItemExt(String base) {
@@ -254,8 +258,8 @@ public class Toolkit {
* 'A'. </li>
* <li> If the first letters are all taken/non-ASCII, then it loops through the
* ASCII letters in the item, widest to narrowest, seeing if any of them is not taken.
* To improve readability, it discriminates against decenders (qypgj), imagining they
* have 2/3 their actual width. (MS guidelines: avoid decenders). It also discriminates
* To improve readability, it discriminates against descenders (qypgj), imagining they
* have 2/3 their actual width. (MS guidelines: avoid descenders). It also discriminates
* against vowels, imagining they have 2/3 their actual width. (MS and Gnome guidelines:
* avoid vowels.) </li>
* <li>Failing that, it will loop left-to-right for an available digit. This is a last
@@ -281,8 +285,9 @@ public class Toolkit {
// The English is http://techbase.kde.org/Projects/Usability/HIG/Keyboard_Accelerators,
// made lowercase.
// Nothing but [a-z] except for '&' before mnemonics and regexes for changable text.
final String[] kdePreDefStrs = { "&file", "&new", "&open", "open&recent",
// Nothing but [a-z] except for '&' before mnemonics and regexes for changeable text.
final String[] kdePreDefStrs = {
"&file", "&new", "&open", "open&recent",
"&save", "save&as", "saveacop&y", "saveas&template", "savea&ll", "reloa&d",
"&print", "printpre&view", "&import", "e&xport", "&closefile",
"clos&eallfiles", "&quit", "&edit", "&undo", "re&do", "cu&t", "&copy",
@@ -298,9 +303,10 @@ public class Toolkit {
"&newbookmarksfolder", "&tools", "&settings", "&toolbars",
"configure&shortcuts", "configuretool&bars", "&configure.*", "&help",
".+&handbook", "&whatsthis", "report&bug", "&aboutprocessing", "about&kde",
"&beenden", "&suchen", // de
"&preferncias", "&sair", // Preferências; pt
"&rechercher" }; // fr
"&beenden", "&suchen", // de
"&preferncias", "&sair", // Preferências; pt
"&rechercher" // fr
};
Pattern[] kdePreDefPats = new Pattern[kdePreDefStrs.length];
for (int i = 0; i < kdePreDefStrs.length; i++) {
kdePreDefPats[i] = Pattern.compile(kdePreDefStrs[i].replace("&",""));
@@ -548,6 +554,18 @@ public class Toolkit {
}
/*
static public String getLibString(String filename) {
File file = Platform.getContentFile("lib/" + filename);
if (file == null || !file.exists()) {
Messages.err("does not exist: " + file);
return null;
}
return PApplet.join(PApplet.loadStrings(file), "\n");
}
*/
/**
* Get an icon of the format base-NN.png where NN is the size, but if it's
* a hidpi display, get the NN*2 version automatically, sized at NN
@@ -629,9 +647,12 @@ public class Toolkit {
static List<Image> iconImages;
// Deprecated version of the function, but can't get rid of it without
// breaking tools and modes (they'd only require a recompile, but they would
// no longer be backwards compatible.
/**
* Deprecated version of the function, but can't get rid of it
* without breaking tools and modes (they'd only require a recompile,
* but they would no longer be backwards compatible).
*/
@Deprecated
static public void setIcon(Frame frame) {
setIcon((Window) frame);
}
@@ -656,6 +677,34 @@ public class Toolkit {
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
static public Image svgToImage(String xmlStr, int wide, int high) {
PGraphicsJava2D pg = new PGraphicsJava2D();
pg.setPrimary(false);
pg.setSize(wide, high);
pg.smooth();
pg.beginDraw();
try {
XML xml = XML.parse(xmlStr);
PShape shape = new PShapeJava2D(xml);
pg.shape(shape, 0, 0, wide, high);
} catch (Exception e) {
e.printStackTrace();
}
pg.endDraw();
return pg.image;
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
static public Shape createRoundRect(float x1, float y1, float x2, float y2,
float tl, float tr, float br, float bl) {
GeneralPath path = new GeneralPath();
@@ -909,6 +958,11 @@ public class Toolkit {
}
static public int highResMultiplier() {
return highResImages() ? 2 : 1;
}
static public boolean isRetina() {
if (retinaProp == null) {
retinaProp = checkRetina();