major theme updates, moving theme out of Mode, pieces in place for dynamic updates

This commit is contained in:
Ben Fry
2021-07-07 18:07:23 -04:00
parent 83da053301
commit b87cf162eb
31 changed files with 449 additions and 251 deletions
+3
View File
@@ -185,6 +185,9 @@ public class Base {
// run static initialization that grabs all the prefs
Preferences.init();
// get colors for ui elements (after prefs, since depends on font choices)
Theme.init();
if (!SingleInstance.alreadyRunning(args)) {
// Set the look and feel before opening the window
try {
+11 -6
View File
@@ -190,11 +190,12 @@ public abstract class Mode {
}
/**
* Setup additional elements that are only required when running with a GUI,
* rather than from the command-line. Note that this will not be called when
* the Mode is used from the command line (because Base will be null).
*/
// /**
// * Setup additional elements that are only required when running with a GUI,
// * rather than from the command-line. Note that this will not be called when
// * the Mode is used from the command line (because Base will be null).
// */
/*
public void setupGUI() {
try {
// First load the default theme data for the whole PDE.
@@ -226,6 +227,7 @@ public abstract class Mode {
"Could not load theme.txt, please re-install Processing", e);
}
}
*/
public File getContentFile(String path) {
@@ -795,12 +797,14 @@ public abstract class Mode {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
/*
// Get attributes/values from the theme.txt file. To discourage burying this
// kind of information in code where it doesn't belong (and is difficult to
// track down), these don't have a "default" option as a second parameter.
/** @since 3.0a6 */
// removing, this doesn't seem to have been in use
/// @since 3.0a6
public String getString(String attribute) {
return theme.get(attribute);
}
@@ -878,6 +882,7 @@ public abstract class Mode {
// }
return outgoing;
}
*/
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+6 -1
View File
@@ -106,7 +106,12 @@ public class Settings {
public void save() {
PrintWriter writer = PApplet.createWriter(file);
save(file); // save back to the original file
}
public void save(File outputFile) {
PrintWriter writer = PApplet.createWriter(outputFile);
for (String key : table.keySet()) {
writer.println(key + "=" + table.get(key));
@@ -141,14 +141,6 @@ public class ContributionManager {
/**
* Non-blocking call to download and install a contribution in a new thread.
*
* @param url
* Direct link to the contribution.
* @param toBeReplaced
* The Contribution that will be replaced by this library being
* installed (e.g. an advertised version of a contribution, or the
* old version of a contribution that is being updated). Must not be
* null.
*/
static void downloadAndInstall(final Base base,
final URL url,
@@ -28,6 +28,7 @@ import javax.swing.*;
import processing.app.*;
import processing.app.ui.Editor;
import processing.app.ui.Theme;
import processing.app.ui.Toolkit;
@@ -109,9 +110,11 @@ public class ManagerFrame {
frame.setResizable(true);
Container c = frame.getContentPane();
c.add(tabs);
c.setBackground(base.getDefaultMode().getColor("manager.tab.background"));
// Container c = frame.getContentPane();
// c.add(tabs);
// c.setBackground(Theme.getColor("manager.tab.background"));
frame.getContentPane().add(tabs);
updateTheme();
frame.validate();
frame.repaint();
@@ -124,6 +127,11 @@ public class ManagerFrame {
}
protected void updateTheme() {
frame.getContentPane().setBackground(Theme.getColor("manager.tab.background"));
}
/**
* Close the window after an OK or Cancel.
*/
@@ -142,20 +150,16 @@ public class ManagerFrame {
}
});
// handle window closing commands for ctrl/cmd-W or hitting ESC.
Toolkit.registerWindowCloseKeys(frame.getRootPane(), new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
disposeFrame();
}
});
Toolkit.registerWindowCloseKeys(frame.getRootPane(), actionEvent -> disposeFrame());
frame.getContentPane().addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
//System.out.println(e);
KeyStroke wc = Toolkit.WINDOW_CLOSE_KEYSTROKE;
if ((e.getKeyCode() == KeyEvent.VK_ESCAPE)
|| (KeyStroke.getKeyStrokeForEvent(e).equals(wc))) {
disposeFrame();
}
//System.out.println(e);
KeyStroke wc = Toolkit.WINDOW_CLOSE_KEYSTROKE;
if ((e.getKeyCode() == KeyEvent.VK_ESCAPE)
|| (KeyStroke.getKeyStrokeForEvent(e).equals(wc))) {
disposeFrame();
}
}
});
}
@@ -40,6 +40,7 @@ import javax.swing.border.EmptyBorder;
import processing.app.Base;
import processing.app.Mode;
import processing.app.ui.Theme;
import processing.app.ui.Toolkit;
@@ -100,14 +101,14 @@ public class ManagerTabs extends Box {
// But use the default (Java) mode settings just in case.
mode = base.getDefaultMode();
textColor[SELECTED] = mode.getColor("manager.tab.text.selected.color");
textColor[UNSELECTED] = mode.getColor("manager.tab.text.unselected.color");
font = mode.getFont("manager.tab.text.font");
textColor[SELECTED] = Theme.getColor("manager.tab.text.selected.color");
textColor[UNSELECTED] = Theme.getColor("manager.tab.text.unselected.color");
font = Theme.getFont("manager.tab.text.font");
tabColor[SELECTED] = mode.getColor("manager.tab.selected.color");
tabColor[UNSELECTED] = mode.getColor("manager.tab.unselected.color");
tabColor[SELECTED] = Theme.getColor("manager.tab.selected.color");
tabColor[UNSELECTED] = Theme.getColor("manager.tab.unselected.color");
gradient = mode.makeGradient("manager.tab", Toolkit.zoom(400), HIGH);
gradient = Theme.makeGradient("manager.tab", Toolkit.zoom(400), HIGH);
setBorder(new EmptyBorder(BORDER, BORDER, BORDER, BORDER));
@@ -80,7 +80,7 @@ public class ModeContribution extends LocalContribution {
* @param className name of class and full package, or null to use default
*/
public ModeContribution(Base base, File folder,
String className) throws Exception {
String className) throws Exception {
super(folder);
className = initLoader(base, className);
if (className != null) {
@@ -89,9 +89,9 @@ public class ModeContribution extends LocalContribution {
Constructor<?> con = modeClass.getConstructor(Base.class, File.class);
mode = (Mode) con.newInstance(base, folder);
mode.setClassLoader(loader);
if (base != null) {
mode.setupGUI();
}
// if (base != null) {
// mode.setupGUI();
// }
}
}
@@ -183,11 +183,11 @@ public class JEditTextArea extends JComponent
}
public void updateAppearance() {
public void updateTheme() {
// This default version will update the fonts and not much else.
// It's expected to always be overridden by the PdeTextArea version,
// but it's here if a Mode author *really* must avoid PdeTextArea.
painter.updateAppearance();
painter.updateTheme();
repaint();
}
@@ -29,6 +29,7 @@ import java.util.Map;
import processing.app.Mode;
import processing.app.ui.Editor;
import processing.app.ui.Theme;
/**
@@ -62,7 +63,7 @@ public class PdeTextArea extends JEditTextArea {
// load settings from theme.txt
Mode mode = editor.getMode();
gutterGradient = mode.makeGradient("editor", Editor.LEFT_GUTTER, 500);
gutterGradient = Theme.makeGradient("editor", Editor.LEFT_GUTTER, 500);
}
@@ -84,8 +85,8 @@ public class PdeTextArea extends JEditTextArea {
*/
@Override
public void updateAppearance() {
((PdeTextAreaPainter) painter).updateAppearance(editor.getMode());
public void updateTheme() {
((PdeTextAreaPainter) painter).updateTheme();
repaint();
}
@@ -26,6 +26,7 @@
package processing.app.syntax;
import processing.app.*;
import processing.app.ui.Theme;
/**
@@ -50,45 +51,45 @@ public class PdeTextAreaDefaults extends TextAreaDefaults {
rows = 5;
styles = new SyntaxStyle[Token.ID_COUNT];
updateAppearance(mode);
updateTheme();
}
protected void updateAppearance(Mode mode) {
fgcolor = mode.getColor("editor.fgcolor");
bgcolor = mode.getColor("editor.bgcolor");
protected void updateTheme() {
fgcolor = Theme.getColor("editor.fgcolor");
bgcolor = Theme.getColor("editor.bgcolor");
styles[Token.COMMENT1] = mode.getStyle("comment1");
styles[Token.COMMENT2] = mode.getStyle("comment2");
styles[Token.COMMENT1] = Theme.getStyle("comment1");
styles[Token.COMMENT2] = Theme.getStyle("comment2");
styles[Token.KEYWORD1] = mode.getStyle("keyword1");
styles[Token.KEYWORD2] = mode.getStyle("keyword2");
styles[Token.KEYWORD3] = mode.getStyle("keyword3");
styles[Token.KEYWORD4] = mode.getStyle("keyword4");
styles[Token.KEYWORD5] = mode.getStyle("keyword5");
styles[Token.KEYWORD6] = mode.getStyle("keyword6");
styles[Token.KEYWORD1] = Theme.getStyle("keyword1");
styles[Token.KEYWORD2] = Theme.getStyle("keyword2");
styles[Token.KEYWORD3] = Theme.getStyle("keyword3");
styles[Token.KEYWORD4] = Theme.getStyle("keyword4");
styles[Token.KEYWORD5] = Theme.getStyle("keyword5");
styles[Token.KEYWORD6] = Theme.getStyle("keyword6");
styles[Token.FUNCTION1] = mode.getStyle("function1");
styles[Token.FUNCTION2] = mode.getStyle("function2");
styles[Token.FUNCTION3] = mode.getStyle("function3");
styles[Token.FUNCTION4] = mode.getStyle("function4");
styles[Token.FUNCTION1] = Theme.getStyle("function1");
styles[Token.FUNCTION2] = Theme.getStyle("function2");
styles[Token.FUNCTION3] = Theme.getStyle("function3");
styles[Token.FUNCTION4] = Theme.getStyle("function4");
styles[Token.LITERAL1] = mode.getStyle("literal1");
styles[Token.LITERAL2] = mode.getStyle("literal2");
styles[Token.LITERAL1] = Theme.getStyle("literal1");
styles[Token.LITERAL2] = Theme.getStyle("literal2");
styles[Token.LABEL] = mode.getStyle("label");
styles[Token.OPERATOR] = mode.getStyle("operator");
styles[Token.LABEL] = Theme.getStyle("label");
styles[Token.OPERATOR] = Theme.getStyle("operator");
// area that's not in use by the text (replaced with tildes)
styles[Token.INVALID] = mode.getStyle("invalid");
styles[Token.INVALID] = Theme.getStyle("invalid");
caretColor = mode.getColor("editor.caret.color");
selectionColor = mode.getColor("editor.selection.color");
lineHighlight = mode.getBoolean("editor.linehighlight");
lineHighlightColor = mode.getColor("editor.linehighlight.color");
bracketHighlight = mode.getBoolean("editor.brackethighlight");
bracketHighlightColor = mode.getColor("editor.brackethighlight.color");
eolMarkers = mode.getBoolean("editor.eolmarkers");
eolMarkerColor = mode.getColor("editor.eolmarkers.color");
caretColor = Theme.getColor("editor.caret.color");
selectionColor = Theme.getColor("editor.selection.color");
lineHighlight = Theme.getBoolean("editor.linehighlight");
lineHighlightColor = Theme.getColor("editor.linehighlight.color");
bracketHighlight = Theme.getBoolean("editor.brackethighlight");
bracketHighlightColor = Theme.getColor("editor.brackethighlight.color");
eolMarkers = Theme.getBoolean("editor.eolmarkers");
eolMarkerColor = Theme.getColor("editor.eolmarkers.color");
}
}
@@ -33,9 +33,9 @@ import javax.swing.text.BadLocationException;
import javax.swing.text.Segment;
import javax.swing.text.Utilities;
import processing.app.Mode;
import processing.app.Problem;
import processing.app.ui.Editor;
import processing.app.ui.Theme;
/**
@@ -87,25 +87,26 @@ public class PdeTextAreaPainter extends TextAreaPainter {
* minor additions or overrides added in a Mode's own theme.txt file.
*/
//public void setMode(Mode mode) {
protected void updateAppearance(Mode mode) {
errorUnderlineColor = mode.getColor("editor.error.underline.color");
warningUnderlineColor = mode.getColor("editor.warning.underline.color");
@Override
protected void updateTheme() {
errorUnderlineColor = Theme.getColor("editor.error.underline.color");
warningUnderlineColor = Theme.getColor("editor.warning.underline.color");
gutterTextFont = mode.getFont("editor.gutter.text.font");
gutterTextColor = mode.getColor("editor.gutter.text.color");
gutterTextFont = Theme.getFont("editor.gutter.text.font");
gutterTextColor = Theme.getColor("editor.gutter.text.color");
gutterPastColor = new Color(gutterTextColor.getRed(),
gutterTextColor.getGreen(),
gutterTextColor.getBlue(),
96);
gutterLineHighlightColor = mode.getColor("editor.gutter.linehighlight.color");
gutterLineHighlightColor = Theme.getColor("editor.gutter.linehighlight.color");
// pull in changes for syntax style, as well as foreground and background color
if (defaults instanceof PdeTextAreaDefaults) {
((PdeTextAreaDefaults) defaults).updateAppearance(mode);
((PdeTextAreaDefaults) defaults).updateTheme();
}
// needs to happen after PdeTextAreaDefaults.updateAppearance(mode)
super.updateAppearance();
// needs to happen *after* PdeTextAreaDefaults.updateTheme()
super.updateTheme();
}
@@ -10,6 +10,7 @@
package processing.app.syntax;
import java.awt.Color;
import java.util.StringTokenizer;
/**
@@ -32,6 +33,21 @@ public class SyntaxStyle {
this.bold = bold;
}
static public SyntaxStyle fromString(String str) {
StringTokenizer st = new StringTokenizer(str, ",");
String s = st.nextToken();
if (s.indexOf("#") == 0) s = s.substring(1);
Color color = new Color(Integer.parseInt(s, 16));
s = st.nextToken();
boolean bold = s.contains("bold");
//boolean italic = s.contains("italic");
return new SyntaxStyle(color, bold);
}
/** Returns the color specified in this style. */
public Color getColor() {
@@ -73,11 +73,11 @@ public class TextAreaPainter extends JComponent implements TabExpander {
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
updateAppearance();
updateTheme();
}
protected void updateAppearance() {
protected void updateTheme() {
setForeground(defaults.fgcolor);
setBackground(defaults.bgcolor);
+46 -34
View File
@@ -247,7 +247,6 @@ public abstract class Editor extends JFrame implements RunnerListener {
// if (pta != null) {
// pta.setMode(mode);
// }
updateAppearance();
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, upper, footer);
@@ -272,7 +271,6 @@ public abstract class Editor extends JFrame implements RunnerListener {
return status;
}
@Override
public void finishDraggingTo(int location) {
super.finishDraggingTo(location);
@@ -304,6 +302,9 @@ public abstract class Editor extends JFrame implements RunnerListener {
contentPain.setTransferHandler(new FileDropHandler());
// set all fonts and colors
updateTheme();
// Finish preparing Editor
pack();
@@ -345,19 +346,6 @@ public abstract class Editor extends JFrame implements RunnerListener {
}
public void updateAppearance() {
/*
PdeTextArea pta = getPdeTextArea();
// will be null if a subclass has overridden createTextArea()
// to return something besides a PdeTextArea
if (pta != null) {
pta.updateAppearance();
}
*/
textarea.updateAppearance();
}
protected JEditTextArea createTextArea() {
return new JEditTextArea(new PdeTextAreaDefaults(mode),
new PdeInputHandler(this));
@@ -552,6 +540,9 @@ public abstract class Editor extends JFrame implements RunnerListener {
}
/**
* Rebuild the Toolbar after turning debug on/off.
*/
public void rebuildToolbar() {
toolbar.rebuild();
toolbar.revalidate(); // necessary to handle sub-components
@@ -580,11 +571,39 @@ public abstract class Editor extends JFrame implements RunnerListener {
* with things in the Preferences window.
*/
public void applyPreferences() {
// Update fonts and other items controllable from the prefs
// textarea.getPainter().updateAppearance();
// textarea.repaint();
textarea.updateAppearance();
console.updateAppearance();
// Even though this is only updating the theme (colors, icons), subclasses
// use this to apply other preferences (i.e. error checking changes in Java Mode).
updateTheme();
// // Update fonts and other items controllable from the prefs
//// textarea.getPainter().updateAppearance();
//// textarea.repaint();
// textarea.updateTheme();
// console.updateTheme();
}
public void updateTheme() {
/*
PdeTextArea pta = getPdeTextArea();
// will be null if a subclass has overridden createTextArea()
// to return something besides a PdeTextArea
if (pta != null) {
pta.updateAppearance();
}
*/
header.updateTheme();
toolbar.updateTheme();
textarea.updateTheme();
errorColumn.updateTheme();
status.updateTheme();
console.updateTheme();
errorTable.updateTheme();
toolTipFont = Toolkit.getSansFont(Toolkit.zoom(9), Font.PLAIN);
toolTipTextColor = Theme.getColor("errors.selection.fgcolor");
toolTipWarningColor = Theme.getColor("errors.selection.warning.bgcolor");
toolTipErrorColor = Theme.getColor("errors.selection.error.bgcolor");
}
@@ -2973,28 +2992,21 @@ public abstract class Editor extends JFrame implements RunnerListener {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
static Font font;
static Color textColor;
static Color bgColorWarning;
static Color bgColorError;
static Font toolTipFont;
static Color toolTipTextColor;
static Color toolTipWarningColor;
static Color toolTipErrorColor;
public void statusToolTip(JComponent comp, String message, boolean error) {
if (font == null) {
font = Toolkit.getSansFont(Toolkit.zoom(9), Font.PLAIN);
textColor = mode.getColor("errors.selection.fgcolor");
bgColorWarning = mode.getColor("errors.selection.warning.bgcolor");
bgColorError = mode.getColor("errors.selection.error.bgcolor");
}
Color bgColor = error ? bgColorError : bgColorWarning;
Color bgColor = error ? toolTipErrorColor : toolTipWarningColor;
int m = Toolkit.zoom(3);
String css =
String.format("margin: %d %d %d %d; ", -m, -m, -m, -m) +
String.format("padding: %d %d %d %d; ", m, m, m, m) +
"background: #" + PApplet.hex(bgColor.getRGB(), 8).substring(2) + ";" +
"font-family: " + font.getFontName() + ", sans-serif;" +
"font-size: " + font.getSize() + "px;";
"font-family: " + toolTipFont.getFontName() + ", sans-serif;" +
"font-size: " + toolTipFont.getSize() + "px;";
String content =
"<html> <div style='" + css + "'>" + message + "</div> </html>";
comp.setToolTipText(content);
+4 -4
View File
@@ -133,7 +133,7 @@ public class EditorConsole extends JScrollPane {
/**
* Update the font family and sizes based on the Preferences window.
*/
protected void updateAppearance() {
protected void updateTheme() {
Font font = Preferences.getFont("editor.font.family", "console.font.size", Font.PLAIN);
StyleConstants.setFontFamily(stdStyle, font.getFamily());
@@ -157,9 +157,9 @@ public class EditorConsole extends JScrollPane {
consoleDoc.setParagraphAttributes(0, 0, standard, true);
// build styles for different types of console output
Color bgColor = mode.getColor("console.color");
Color fgColorOut = mode.getColor("console.output.color");
Color fgColorErr = mode.getColor("console.error.color");
Color bgColor = Theme.getColor("console.color");
Color fgColorOut = Theme.getColor("console.output.color");
Color fgColorErr = Theme.getColor("console.error.color");
// Make things line up with the Editor above. If this is ever removed,
// setBorder(null) should be called instead. The defaults are nasty.
+8 -8
View File
@@ -163,20 +163,20 @@ public class EditorFooter extends Box {
public void updateMode() {
Mode mode = editor.getMode();
textColor[SELECTED] = mode.getColor("footer.text.selected.color");
textColor[UNSELECTED] = mode.getColor("footer.text.unselected.color");
font = mode.getFont("footer.text.font");
textColor[SELECTED] = Theme.getColor("footer.text.selected.color");
textColor[UNSELECTED] = Theme.getColor("footer.text.unselected.color");
font = Theme.getFont("footer.text.font");
tabColor[SELECTED] = mode.getColor("footer.tab.selected.color");
tabColor[UNSELECTED] = mode.getColor("footer.tab.unselected.color");
tabColor[SELECTED] = Theme.getColor("footer.tab.selected.color");
tabColor[UNSELECTED] = Theme.getColor("footer.tab.unselected.color");
updateColor = mode.getColor("footer.updates.color");
updateColor = Theme.getColor("footer.updates.color");
gradient = mode.makeGradient("footer", 400, HIGH);
gradient = Theme.makeGradient("footer", 400, HIGH);
// Set the default background color in case the window size reported
// incorrectly by the OS, or we miss an update event of some kind
// https://github.com/processing/processing/issues/3919
bgColor = mode.getColor("footer.gradient.bottom");
bgColor = Theme.getColor("footer.gradient.bottom");
setBackground(bgColor);
}
+10 -12
View File
@@ -97,7 +97,7 @@ public class EditorHeader extends JComponent {
public EditorHeader(Editor eddie) {
this.editor = eddie;
updateMode();
updateTheme();
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
@@ -141,21 +141,19 @@ public class EditorHeader extends JComponent {
}
public void updateMode() {
Mode mode = editor.getMode();
public void updateTheme() {
textColor[SELECTED] = Theme.getColor("header.text.selected.color");
textColor[UNSELECTED] = Theme.getColor("header.text.unselected.color");
font = Theme.getFont("header.text.font");
textColor[SELECTED] = mode.getColor("header.text.selected.color");
textColor[UNSELECTED] = mode.getColor("header.text.unselected.color");
font = mode.getFont("header.text.font");
tabColor[SELECTED] = Theme.getColor("header.tab.selected.color");
tabColor[UNSELECTED] = Theme.getColor("header.tab.unselected.color");
tabColor[SELECTED] = mode.getColor("header.tab.selected.color");
tabColor[UNSELECTED] = mode.getColor("header.tab.unselected.color");
arrowColor = mode.getColor("header.tab.arrow.color");
arrowColor = Theme.getColor("header.tab.arrow.color");
//modifiedColor = mode.getColor("editor.selection.color");
modifiedColor = mode.getColor("header.tab.modified.color");
modifiedColor = Theme.getColor("header.tab.modified.color");
gradient = mode.makeGradient("header", 400, HIGH);
gradient = Theme.makeGradient("header", 400, HIGH);
}
+16 -17
View File
@@ -125,7 +125,7 @@ public class EditorStatus extends BasicSplitPaneDivider {
super(ui);
this.editor = editor;
empty();
updateMode();
updateTheme();
addMouseListener(new MouseAdapter() {
@@ -219,27 +219,26 @@ public class EditorStatus extends BasicSplitPaneDivider {
}
public void updateMode() {
Mode mode = editor.getMode();
urlColor = mode.getColor("status.url.fgcolor");
protected void updateTheme() {
urlColor = Theme.getColor("status.url.fgcolor");
fgColor = new Color[] {
mode.getColor("status.notice.fgcolor"),
mode.getColor("status.error.fgcolor"),
mode.getColor("status.error.fgcolor"),
mode.getColor("status.warning.fgcolor"),
mode.getColor("status.warning.fgcolor")
Theme.getColor("status.notice.fgcolor"),
Theme.getColor("status.error.fgcolor"),
Theme.getColor("status.error.fgcolor"),
Theme.getColor("status.warning.fgcolor"),
Theme.getColor("status.warning.fgcolor")
};
bgColor = new Color[] {
mode.getColor("status.notice.bgcolor"),
mode.getColor("status.error.bgcolor"),
mode.getColor("status.error.bgcolor"),
mode.getColor("status.warning.bgcolor"),
mode.getColor("status.warning.bgcolor")
Theme.getColor("status.notice.bgcolor"),
Theme.getColor("status.error.bgcolor"),
Theme.getColor("status.error.bgcolor"),
Theme.getColor("status.warning.bgcolor"),
Theme.getColor("status.warning.bgcolor")
};
Mode mode = editor.getMode();
bgImage = new Image[] {
mode.loadImage("/lib/status/notice.png"),
mode.loadImage("/lib/status/error.png"),
@@ -248,8 +247,8 @@ public class EditorStatus extends BasicSplitPaneDivider {
mode.loadImage("/lib/status/warning.png")
};
font = mode.getFont("status.font");
glyphFont = mode.getFont("status.emoji.font");
font = Theme.getFont("status.font");
glyphFont = Theme.getFont("status.emoji.font");
metrics = null;
}
+26 -24
View File
@@ -78,8 +78,6 @@ abstract public class EditorToolbar extends JPanel implements KeyListener {
base = editor.getBase();
mode = editor.getMode();
gradient = mode.makeGradient("toolbar", Toolkit.zoom(400), HIGH);
rebuild();
}
@@ -92,8 +90,6 @@ abstract public class EditorToolbar extends JPanel implements KeyListener {
box.add(Box.createHorizontalStrut(Editor.LEFT_GUTTER));
rolloverLabel = new JLabel();
rolloverLabel.setFont(mode.getFont("toolbar.rollover.font"));
rolloverLabel.setForeground(mode.getColor("toolbar.rollover.color"));
for (EditorButton button : buttons) {
box.add(button);
@@ -122,6 +118,16 @@ abstract public class EditorToolbar extends JPanel implements KeyListener {
setLayout(new BorderLayout());
add(box, BorderLayout.CENTER);
updateTheme();
}
public void updateTheme() {
gradient = Theme.makeGradient("toolbar", Toolkit.zoom(400), HIGH);
rolloverLabel.setFont(Theme.getFont("toolbar.rollover.font"));
rolloverLabel.setForeground(Theme.getColor("toolbar.rollover.color"));
}
@@ -298,32 +304,32 @@ abstract public class EditorToolbar extends JPanel implements KeyListener {
Color backgroundColor;
Color outlineColor;
@SuppressWarnings("deprecation")
public ModeSelector() {
title = mode.getTitle(); //.toUpperCase();
titleFont = mode.getFont("mode.title.font");
titleColor = mode.getColor("mode.title.color");
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent event) {
JPopupMenu popup = editor.getModePopup();
popup.show(ModeSelector.this, event.getX(), event.getY());
}
});
updateTheme();
}
public void updateTheme() {
titleFont = Theme.getFont("mode.title.font");
titleColor = Theme.getColor("mode.title.color");
// getGraphics() is null and no offscreen yet
titleWidth = getToolkit().getFontMetrics(titleFont).stringWidth(title);
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent event) {
JPopupMenu popup = editor.getModePopup();
popup.show(ModeSelector.this, event.getX(), event.getY());
}
});
//background = mode.getGradient("reversed", 100, EditorButton.DIM);
backgroundColor = mode.getColor("mode.background.color");
outlineColor = mode.getColor("mode.outline.color");
backgroundColor = Theme.getColor("mode.background.color");
outlineColor = Theme.getColor("mode.outline.color");
}
@Override
public void paintComponent(Graphics screen) {
// Toolkit.debugOpacity(this);
Dimension size = getSize();
width = 0;
if (width != size.width || height != size.height) {
@@ -334,10 +340,6 @@ abstract public class EditorToolbar extends JPanel implements KeyListener {
Graphics g = offscreen.getGraphics();
Graphics2D g2 = Toolkit.prepareGraphics(g);
//Toolkit.clearGraphics(g, width, height);
// g.clearRect(0, 0, width, height);
// g.setColor(Color.GREEN);
// g.fillRect(0, 0, width, height);
g.setFont(titleFont);
if (titleAscent == 0) {
+26 -20
View File
@@ -39,7 +39,6 @@ import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import processing.app.Language;
import processing.app.Mode;
import processing.app.Problem;
@@ -73,11 +72,12 @@ public class ErrorTable extends JTable {
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.editor = editor;
JTableHeader header = getTableHeader();
//JTableHeader header = getTableHeader();
//Mode mode = editor.getMode();
//header.setDefaultRenderer(new GradyHeaderRenderer(mode));
//setDefaultRenderer(Object.class, new GradyRowRenderer(mode));
updateTheme();
Mode mode = editor.getMode();
header.setDefaultRenderer(new GradyHeaderRenderer(mode));
setDefaultRenderer(Object.class, new GradyRowRenderer(mode));
//setShowGrid(false);
setIntercellSpacing(new Dimension(0, 0));
@@ -116,12 +116,18 @@ public class ErrorTable extends JTable {
}
});
header.setReorderingAllowed(false);
getTableHeader().setReorderingAllowed(false);
setFillsViewportHeight(true);
ToolTipManager.sharedInstance().registerComponent(this);
}
protected void updateTheme() {
getTableHeader().setDefaultRenderer(new GradyHeaderRenderer());
setDefaultRenderer(Object.class, new GradyRowRenderer());
}
public void clearRows() {
DefaultTableModel dtm = (DefaultTableModel) getModel();
dtm.setRowCount(0);
@@ -145,12 +151,12 @@ public class ErrorTable extends JTable {
static class GradyHeaderRenderer extends JLabel implements TableCellRenderer {
public GradyHeaderRenderer(Mode mode) {
setFont(mode.getFont("errors.header.font"));
public GradyHeaderRenderer() {
setFont(Theme.getFont("errors.header.font"));
setAlignmentX(LEFT_ALIGNMENT);
setForeground(mode.getColor("errors.header.fgcolor"));
setBackground(mode.getColor("errors.header.bgcolor"));
setForeground(Theme.getColor("errors.header.fgcolor"));
setBackground(Theme.getColor("errors.header.bgcolor"));
setOpaque(true);
}
@@ -191,19 +197,19 @@ public class ErrorTable extends JTable {
Color errorIndicatorColor;
Color warningIndicatorColor;
public GradyRowRenderer(Mode mode) {
setFont(mode.getFont("errors.row.font"));
public GradyRowRenderer() {
setFont(Theme.getFont("errors.row.font"));
setAlignmentX(LEFT_ALIGNMENT);
textColor = mode.getColor("errors.row.fgcolor");
bgColor = mode.getColor("errors.row.bgcolor");
textColorSelected = mode.getColor("errors.selection.fgcolor");
bgColorSelected = mode.getColor("errors.selection.bgcolor");
bgColorError = mode.getColor("errors.selection.error.bgcolor");
bgColorWarning = mode.getColor("errors.selection.warning.bgcolor");
textColor = Theme.getColor("errors.row.fgcolor");
bgColor = Theme.getColor("errors.row.bgcolor");
textColorSelected = Theme.getColor("errors.selection.fgcolor");
bgColorSelected = Theme.getColor("errors.selection.bgcolor");
bgColorError = Theme.getColor("errors.selection.error.bgcolor");
bgColorWarning = Theme.getColor("errors.selection.warning.bgcolor");
errorIndicatorColor = mode.getColor("errors.indicator.error.color");
warningIndicatorColor = mode.getColor("errors.indicator.warning.color");
errorIndicatorColor = Theme.getColor("errors.indicator.error.color");
warningIndicatorColor = Theme.getColor("errors.indicator.warning.color");
setOpaque(true);
}
+1 -1
View File
@@ -183,7 +183,7 @@ public class ExamplesFrame extends JFrame {
}
// Special cell renderer that takes the UI zoom into account
tree.setCellRenderer(new ZoomTreeCellRenderer(mode));
tree.setCellRenderer(new ZoomTreeCellRenderer());
JScrollPane treePane = new JScrollPane(tree);
treePane.setPreferredSize(Toolkit.zoom(250, 300));
+7 -6
View File
@@ -54,8 +54,6 @@ import processing.core.PApplet;
public class MarkerColumn extends JPanel {
protected Editor editor;
// static final int WIDE = 12;
private Color errorColor;
private Color warningColor;
@@ -66,16 +64,13 @@ public class MarkerColumn extends JPanel {
public MarkerColumn(Editor editor, int height) {
this.editor = editor;
Mode mode = editor.getMode();
errorColor = mode.getColor("editor.column.error.color");
warningColor = mode.getColor("editor.column.warning.color");
updateTheme();
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
scrollToMarkerAt(e.getY());
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(final MouseEvent e) {
showMarkerHover(e.getY());
@@ -84,6 +79,12 @@ public class MarkerColumn extends JPanel {
}
protected void updateTheme() {
errorColor = Theme.getColor("editor.column.error.color");
warningColor = Theme.getColor("editor.column.warning.color");
}
@Override
public void repaint() {
recalculateMarkerPositions();
@@ -119,7 +119,7 @@ public class SketchbookFrame extends JFrame {
}
// Special cell renderer that takes the UI zoom into account
tree.setCellRenderer(new ZoomTreeCellRenderer(mode));
tree.setCellRenderer(new ZoomTreeCellRenderer());
// Check whether sketch book is empty or not
TreeModel treeModel = tree.getModel();
+140
View File
@@ -0,0 +1,140 @@
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Processing project - http://processing.org
Copyright (c) 2021 The Processing Foundation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package processing.app.ui;
import processing.app.Base;
import processing.app.Messages;
import processing.app.Platform;
import processing.app.Settings;
import processing.app.syntax.SyntaxStyle;
import processing.core.PApplet;
import processing.core.PConstants;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
public class Theme {
static Settings theme;
static public void init() {
load();
}
static public void load() {
try {
File inputFile = Platform.getContentFile("lib/theme.txt");
if (inputFile == null) {
throw new RuntimeException("Missing required file (theme.txt), you may need to reinstall.");
}
// First load the default theme data for the whole PDE.
theme = new Settings(inputFile);
/*
// The mode-specific theme.txt file should only contain additions,
// and in extremely rare cases, it might override entries from the
// main theme. Do not override for style changes unless they are
// objectively necessary for your Mode.
File modeTheme = new File(folder, "theme/theme.txt");
if (modeTheme.exists()) {
// Override the built-in settings with what the theme provides
theme.load(modeTheme);
}
*/
// https://github.com/processing/processing/issues/5445
File sketchbookTheme = getSketchbookFile();
// new File(Base.getSketchbookFolder(), "theme.txt");
if (sketchbookTheme.exists()) {
theme.load(sketchbookTheme);
}
// other things that have to be set explicitly for the defaults
theme.setColor("run.window.bgcolor", SystemColor.control);
} catch (IOException e) {
Messages.showError("Problem loading theme.txt",
"Could not load theme.txt, please re-install Processing", e);
}
}
static public void save() {
theme.save(getSketchbookFile());
}
static public File getSketchbookFile() {
return new File(Base.getSketchbookFolder(), "theme.txt");
}
static public boolean getBoolean(String attribute) {
return theme.getBoolean(attribute);
}
static public int getInteger(String attribute) {
return theme.getInteger(attribute);
}
static public Color getColor(String attribute) {
return theme.getColor(attribute);
}
static public Font getFont(String attribute) {
return theme.getFont(attribute);
}
static public SyntaxStyle getStyle(String attribute) {
//String str = Preferences.get("editor.token." + attribute + ".style");
String str = theme.get("editor.token." + attribute + ".style");
if (str == null) {
throw new IllegalArgumentException("No style found for " + attribute);
}
return SyntaxStyle.fromString(str);
}
static public Image makeGradient(String attribute, int wide, int high) {
int top = getColor(attribute + ".gradient.top").getRGB();
int bot = getColor(attribute + ".gradient.bottom").getRGB();
BufferedImage outgoing =
new BufferedImage(wide, high, BufferedImage.TYPE_INT_RGB);
int[] row = new int[wide];
WritableRaster wr = outgoing.getRaster();
for (int i = 0; i < high; i++) {
int rgb = PApplet.lerpColor(top, bot, i / (float)(high-1), PConstants.RGB);
Arrays.fill(row, rgb);
wr.setDataElements(0, i, wide, 1, row);
}
return outgoing;
}
}
@@ -33,8 +33,8 @@ import processing.app.Mode;
public class ZoomTreeCellRenderer extends DefaultTreeCellRenderer {
public ZoomTreeCellRenderer(Mode mode) {
setFont(mode.getFont("tree.font"));
public ZoomTreeCellRenderer() {
setFont(Theme.getFont("tree.font"));
}
@Override
-32
View File
@@ -247,38 +247,6 @@ editor.laf.linux = javax.swing.plaf.nimbus.NimbusLookAndFeel
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# TEXT - KEYWORDS, LITERALS
# For an explanation of these tags, see Token.java:
# processing/app/src/processing/app/syntax/Token.java
editor.token.function1.style = #006699,plain
editor.token.function2.style = #006699,plain
editor.token.function3.style = #669900,plain
editor.token.function4.style = #006699,bold
editor.token.keyword1.style = #33997e,plain
editor.token.keyword2.style = #33997e,plain
editor.token.keyword3.style = #669900,plain
editor.token.keyword4.style = #d94a7a,plain
editor.token.keyword5.style = #e2661a,plain
editor.token.keyword6.style = #33997e,plain
editor.token.literal1.style = #7D4793,plain
editor.token.literal2.style = #718a62,plain
editor.token.operator.style = #006699,plain
editor.token.label.style = #666666,bold
editor.token.comment1.style = #666666,plain
editor.token.comment2.style = #666666,plain
editor.token.invalid.style = #666666,bold
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# which platforms to export by default
#export.application.platform.windows = true
#export.application.platform.macosx = true
+33 -1
View File
@@ -53,7 +53,7 @@ buttons.bgcolor = #000000
## size of divider between editing area and the console
#divider.size = 0
## the larger divider on windows is ugly with the little arrows
## this makes it large enough to see (mouse changes) and use,
## this makes it large enough to see (mouse changes) and use,
## but keeps it from being annoyingly obtrusive
#divider.size.windows = 2
@@ -174,3 +174,35 @@ manager.tab.background = #132638
# tree for Examples and Sketchbook windows
tree.font = processing.sans,plain,12
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# TEXT - KEYWORDS, LITERALS
# For an explanation of these tags, see Token.java:
# processing/app/src/processing/app/syntax/Token.java
editor.token.function1.style = #006699,plain
editor.token.function2.style = #006699,plain
editor.token.function3.style = #669900,plain
editor.token.function4.style = #006699,bold
editor.token.keyword1.style = #33997e,plain
editor.token.keyword2.style = #33997e,plain
editor.token.keyword3.style = #669900,plain
editor.token.keyword4.style = #d94a7a,plain
editor.token.keyword5.style = #e2661a,plain
editor.token.keyword6.style = #33997e,plain
editor.token.literal1.style = #7D4793,plain
editor.token.literal2.style = #718a62,plain
editor.token.operator.style = #006699,plain
editor.token.label.style = #666666,bold
editor.token.comment1.style = #666666,plain
editor.token.comment2.style = #666666,plain
editor.token.invalid.style = #666666,bold
@@ -21,9 +21,11 @@ public class ThemeEngine implements Tool {
public void run() {
//setVisible(true);
//Preferences.init();
for (Editor editor : base.getEditors()) {
System.out.println("Updating settings for " + editor.getSketch().getName());
editor.applyPreferences();
System.out.println("Updating theme for " + editor.getSketch().getName());
//editor.applyPreferences();
editor.updateTheme();
}
}
}
+1 -1
View File
@@ -50,7 +50,7 @@ class ASTViewer {
return super.convertValueToText(value, selected, expanded, leaf, row, hasFocus);
}
};
tree.setCellRenderer(new ZoomTreeCellRenderer(editor.getMode()));
tree.setCellRenderer(new ZoomTreeCellRenderer());
window.addComponentListener(new ComponentAdapter() {
@Override
public void componentHidden(ComponentEvent e) {
+1 -1
View File
@@ -82,7 +82,7 @@ class ShowUsage {
JScrollPane sp2 = new JScrollPane();
tree = new JTree();
ZoomTreeCellRenderer renderer =
new ZoomTreeCellRenderer(editor.getMode());
new ZoomTreeCellRenderer();
tree.setCellRenderer(renderer);
renderer.setLeafIcon(null);
renderer.setClosedIcon(null);
+9
View File
@@ -18,6 +18,15 @@ X trying to save the user from themselves here is just messier than needed
X opt to open a new editor window rather than weird error messages
X https://github.com/processing/processing4/issues/189
X add ProRes 4444 support to Movie Maker
X major theme changes
X move theme out of Mode and into its own Theme class
X remove setMode()/updateAppearance(), replace with updateTheme()
X Theme has static access, update throughout the code
X pieces in place to handle updates to theme while still running
X ignore theme.txt for Modes (no longer a Mode thing)
X move syntax colors out of preferences.txt and into theme.txt
X (because it can also be accessed via the sketchbook)
_ https://github.com/processing/processing/wiki/Dark-Theme-for-PDE
api changes
X Editor.applyPreferences() was protected, now public