mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
swapping out toolbar buttons to be svg, rendered from the theme
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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", "©",
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user