Skip to content

[IDE] Add support for user-defined theme in sketchbook folder #7115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions app/src/processing/app/EditorTab.java
Original file line number Diff line number Diff line change
@@ -58,6 +58,7 @@
import java.nio.file.Path;
import java.io.File;

import org.apache.commons.lang3.StringUtils;
import org.fife.ui.autocomplete.AutoCompletion;
import org.fife.ui.autocomplete.DefaultCompletionProvider;
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
@@ -345,6 +346,20 @@ public void applyPreferences() {
}
// apply changes to the font size for the editor
Font editorFont = scale(PreferencesData.getFont("editor.font"));

// check whether a theme-defined editor font is available
Font themeFont = Theme.getFont("editor.font");
if (themeFont != null)
{
// Apply theme font if the editor font has *not* been changed by the user,
// This allows themes to specify an editor font which will only be applied
// if the user hasn't already changed their editor font via preferences.txt
String defaultFontName = StringUtils.defaultIfEmpty(PreferencesData.getDefault("editor.font"), "").split(",")[0];
if (defaultFontName.equals(editorFont.getName())) {
editorFont = new Font(themeFont.getName(), themeFont.getStyle(), editorFont.getSize());
}
}

textarea.setFont(editorFont);
scrollPane.getGutter().setLineNumberFont(editorFont);
}
54 changes: 45 additions & 9 deletions app/src/processing/app/Theme.java
Original file line number Diff line number Diff line change
@@ -61,6 +61,8 @@
* and to make way for future ability to customize.
*/
public class Theme {

static final String THEME_DIR = "theme/";

/**
* Copy of the defaults in case the user mangles a preference.
@@ -73,7 +75,8 @@ public class Theme {

static protected void init() {
try {
table.load(new File(BaseNoGui.getContentFile("lib"), "theme/theme.txt"));
table.load(new File(BaseNoGui.getContentFile("lib"), THEME_DIR + "theme.txt"));
table.load(getThemeFile(THEME_DIR + "theme.txt"));
} catch (Exception te) {
Base.showError(null, tr("Could not read color theme settings.\n"
+ "You'll need to reinstall Arduino."),
@@ -177,6 +180,9 @@ static public Font getFont(String attr) {
String value = getDefault(attr);
set(attr, value);
font = PreferencesHelper.getFont(table, attr);
if (font == null) {
return null;
}
}
return font.deriveFont((float) scale(font.getSize()));
}
@@ -245,11 +251,10 @@ public static Map<String, Object> getStyledFont(String what, Font font) {
*/
static public Image getLibImage(String filename, Component who, int width,
int height) {
File libFolder = BaseNoGui.getContentFile("lib");
Image image = null;

// Use vector image when available
File vectorFile = new File(libFolder, filename + ".svg");
File vectorFile = getThemeFile(filename + ".svg");
if (vectorFile.exists()) {
try {
image = imageFromSVG(vectorFile.toURI().toURL(), width, height);
@@ -259,13 +264,16 @@ static public Image getLibImage(String filename, Component who, int width,
}
}

// Otherwise fall-back to PNG bitmaps
if (image == null) {
File bitmapFile = new File(libFolder, filename + ".png");
File bitmap2xFile = new File(libFolder, filename + "@2x.png");
File bitmapFile = getThemeFile(filename + ".png");

// Otherwise fall-back to PNG bitmaps, allowing user-defined bitmaps to
// override built-in svgs
if (image == null || (!isUserThemeFile(vectorFile) && isUserThemeFile(bitmapFile))) {
File bitmap2xFile = getThemeFile(filename + "@2x.png");

File imageFile;
if ((getScale() > 125 && bitmap2xFile.exists()) || !bitmapFile.exists()) {
if (((getScale() > 125 && bitmap2xFile.exists()) || !bitmapFile.exists())
&& isUserThemeFile(bitmapFile) == isUserThemeFile(bitmap2xFile)) {
imageFile = bitmap2xFile;
} else {
imageFile = bitmapFile;
@@ -298,7 +306,7 @@ static public Image getLibImage(String filename, Component who, int width,
*/
static public Image getThemeImage(String name, Component who, int width,
int height) {
return getLibImage("theme/" + name, who, width, height);
return getLibImage(THEME_DIR + name, who, width, height);
}

private static Image imageFromSVG(URL url, int width, int height)
@@ -324,5 +332,33 @@ static public Graphics2D setupGraphics2D(Graphics graphics) {
}
return g;
}

/**
* Check whether the specified file is a user-defined theme file
*/
static public boolean isUserThemeFile(File file) {
return file.exists() && file.getAbsolutePath().startsWith(BaseNoGui.getSketchbookFolder().getAbsolutePath());
}

/**
* @param name
* @return
*/
static public File getThemeFile(String name) {
File sketchBookThemeFolder = new File(BaseNoGui.getSketchbookFolder(), THEME_DIR);

File themeFile = new File(sketchBookThemeFolder, name);
if (themeFile.exists()) {
return themeFile;
}

if (name.startsWith(THEME_DIR)) {
themeFile = new File(sketchBookThemeFolder, name.substring(THEME_DIR.length()));
if (themeFile.exists()) {
return themeFile;
}
}

return new File(BaseNoGui.getContentFile("lib"), name);
}
}
4 changes: 2 additions & 2 deletions app/src/processing/app/forms/PasswordAuthorizationDialog.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package processing.app.forms;

import processing.app.Base;
import processing.app.Theme;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.io.File;

import static processing.app.I18n.tr;

@@ -34,7 +34,7 @@ public PasswordAuthorizationDialog(Frame parent, String dialogText) {

typePasswordLabel.setText(dialogText);

icon.setIcon(new ImageIcon(new File(Base.getContentFile("lib"), "theme/lock.png").getAbsolutePath()));
icon.setIcon(new ImageIcon(Theme.getThemeFile("theme/lock.png").getAbsolutePath()));

passwordLabel.setText(tr("Password:"));

2 changes: 1 addition & 1 deletion app/src/processing/app/syntax/SketchTextArea.java
Original file line number Diff line number Diff line change
@@ -110,7 +110,7 @@ private void installFeatures() throws IOException {
private void setTheme(String name) throws IOException {
FileInputStream defaultXmlInputStream = null;
try {
defaultXmlInputStream = new FileInputStream(new File(BaseNoGui.getContentFile("lib"), "theme/syntax/" + name + ".xml"));
defaultXmlInputStream = new FileInputStream(processing.app.Theme.getThemeFile("theme/syntax/" + name + ".xml"));
Theme theme = Theme.load(defaultXmlInputStream);
theme.apply(this);
} finally {