diff --git a/app/build.xml b/app/build.xml index 73b0be464..592c58d29 100644 --- a/app/build.xml +++ b/app/build.xml @@ -100,8 +100,34 @@ + + + + + + + + + + + + + + + + + + + + + + + depends="download-ant, download-jna, download-flatlaf"> @@ -133,6 +159,7 @@ ../core/apple.jar; lib/ant.jar; lib/ant-launcher.jar; + lib/flatlaf.jar; lib/jna.jar; lib/jna-platform.jar" debug="on" @@ -146,13 +173,15 @@ - + - + + + diff --git a/app/lib/.gitignore b/app/lib/.gitignore index 25b443b60..755a82b25 100644 --- a/app/lib/.gitignore +++ b/app/lib/.gitignore @@ -1,7 +1,7 @@ ant.jar ant-launcher.jar +flatlaf.jar + jna.jar jna-platform.jar - -VAqua*.jar \ No newline at end of file diff --git a/app/processing4-app.iml b/app/processing4-app.iml index 946a9d344..62e9a8c3a 100644 --- a/app/processing4-app.iml +++ b/app/processing4-app.iml @@ -55,5 +55,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/processing/app/contrib/StatusPanel.java b/app/src/processing/app/contrib/StatusPanel.java index 8b3cd6f02..4579ed00a 100644 --- a/app/src/processing/app/contrib/StatusPanel.java +++ b/app/src/processing/app/contrib/StatusPanel.java @@ -209,7 +209,7 @@ class StatusPanel extends JPanel { return "body { " + " margin: 0; " + " padding: 0;" + - " font-family: " + Toolkit.getSansFontName() + ", Helvetica, Arial, sans-serif;" + + " font-family: " + Toolkit.getSansFont().getName() + ", Helvetica, Arial, sans-serif;" + " font-size: 11px;" + "}" + "a { color: #444; text-decoration: none; }"; diff --git a/app/src/processing/app/platform/DefaultPlatform.java b/app/src/processing/app/platform/DefaultPlatform.java index c80ebf870..a51c67313 100644 --- a/app/src/processing/app/platform/DefaultPlatform.java +++ b/app/src/processing/app/platform/DefaultPlatform.java @@ -27,10 +27,10 @@ import java.awt.Desktop; import java.awt.Dimension; import java.awt.Font; import java.io.File; -import java.net.URI; import javax.swing.UIManager; import javax.swing.plaf.FontUIResource; +import javax.swing.text.StyleContext; import com.sun.jna.Library; import com.sun.jna.Native; @@ -110,16 +110,34 @@ public class DefaultPlatform { public void setLookAndFeel() throws Exception { String laf = Preferences.get("editor.laf"); if (laf == null || laf.length() == 0) { // normal situation - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + + // dummy font call so that it's registered for the LaF + Toolkit.getSansFont(12, Font.PLAIN); + + com.formdev.flatlaf.FlatLaf.registerCustomDefaultsSource("processing.app.ui"); + UIManager.setLookAndFeel(new com.formdev.flatlaf.FlatLightLaf()); + } else { UIManager.setLookAndFeel(laf); } + /* + UIDefaults defaults = UIManager.getDefaults(); + for (Map.Entry entry : defaults.entrySet()) { + System.out.println(entry.getKey() + " = " + entry.getValue()); + } + */ + // If the default has been overridden in the preferences, set the font String fontName = Preferences.get("ui.font.family"); int fontSize = Preferences.getInteger("ui.font.size"); +// fontName = "Processing Sans Pro"; if (!"Dialog".equals(fontName) || fontSize != 12) { setUIFont(new FontUIResource(fontName, Font.PLAIN, fontSize)); +// setUIFont(new FontUIResource(createFallingFont(fontName, Font.PLAIN, fontSize))); +// setUIFont((FontUIResource) StyleContext.getDefaultStyleContext().getFont(fontName, Font.PLAIN, fontSize)); + // Map attributes = new HashMap<>(); // attributes.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); // Font font = new Font(fontName, Font.PLAIN, fontSize).deriveFont(attributes); @@ -129,9 +147,19 @@ public class DefaultPlatform { // Default was 8x8, but that's not enough with the insets and rounded rect // https://github.com/processing/processing4/issues/473 //System.out.println(UIManager.get("ScrollBar.minimumThumbSize")); - UIManager.put("ScrollBar.minimumThumbSize", new Dimension(8, 24)); + UIManager.put("ScrollBar.minimumThumbSize", new Dimension(16, 24)); } +// // Adapted from https://stackoverflow.com/a/64667581/18247494 +// static Font createFallingFont(final String family, final int style, final int size) { +// return new NonUIResourceFont(StyleContext.getDefaultStyleContext().getFont(family, style, size)); +// } +// +// static class NonUIResourceFont extends Font { +// public NonUIResourceFont(final Font font) { +// super(font); +// } +// } // Rewritten from https://stackoverflow.com/a/7434935 static private void setUIFont(FontUIResource f) { diff --git a/app/src/processing/app/ui/FlatLaf.properties b/app/src/processing/app/ui/FlatLaf.properties new file mode 100644 index 000000000..207eccdfd --- /dev/null +++ b/app/src/processing/app/ui/FlatLaf.properties @@ -0,0 +1 @@ +defaultFont = 14 "Processing Sans Pro", "Open Sans", "Noto Sans", Roboto, Arial \ No newline at end of file diff --git a/app/src/processing/app/ui/PreferencesFrame.java b/app/src/processing/app/ui/PreferencesFrame.java index 22e1c0b17..2f98fb148 100644 --- a/app/src/processing/app/ui/PreferencesFrame.java +++ b/app/src/processing/app/ui/PreferencesFrame.java @@ -134,12 +134,13 @@ public class PreferencesFrame { languageSelection[0] = languages.get(Language.getLanguage()); int i = 1; for (Map.Entry lang : languages.entrySet()) { - if(!lang.getKey().equals(Language.getLanguage())){ + if (!lang.getKey().equals(Language.getLanguage())){ languageSelection[i++] = lang.getValue(); } } languageSelectionBox.setModel(new DefaultComboBoxModel<>(languageSelection)); languageRestartLabel = new JLabel(" (" + Language.text("preferences.requires_restart") + ")"); + languageSelectionBox.setRenderer(new LanguageRenderer()); // Editor and console font [ Source Code Pro ] @@ -548,6 +549,27 @@ public class PreferencesFrame { } + class LanguageRenderer extends JLabel implements ListCellRenderer { + final int fontSize = languageSelectionBox.getFont().getSize(); + final Font sansFont = Toolkit.getSansFont(fontSize, Font.PLAIN); + final Font fallbackFont = new Font("Dialog", Font.PLAIN,fontSize); + + @Override + public Component getListCellRendererComponent(JList list, String text, int index, + boolean isSelected, boolean cellHasFocus) { + if (sansFont.canDisplayUpTo(text) == -1) { + // if the sans font can display the chars, use it + setFont(sansFont); + } else { + // otherwise, use the fallback font (Dialog) + setFont(fallbackFont); + } + setText(text); + return this; + } + } + + /** Callback for the folder selector. */ public void sketchbookCallback(File file) { if (file != null) { // null if cancel or closed diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 5e21f572d..be8ea0b37 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -1147,6 +1147,7 @@ public class Toolkit { } + /* static public String getSansFontName() { if (sansFont == null) { // create a dummy version if the font has never been loaded (rare) @@ -1154,6 +1155,12 @@ public class Toolkit { } return sansFont.getName(); } + */ + + + static public Font getSansFont() { + return getSansFont(0, Font.PLAIN); + } static public Font getSansFont(int size, int style) { @@ -1180,13 +1187,13 @@ public class Toolkit { } } if (style == Font.BOLD) { - if (size == sansBoldFont.getSize()) { + if (size == sansBoldFont.getSize() || size == 0) { return sansBoldFont; } else { return sansBoldFont.deriveFont((float) size); } } else { - if (size == sansFont.getSize()) { + if (size == sansFont.getSize() || size == 0) { return sansFont; } else { return sansFont.deriveFont((float) size); diff --git a/build/build.xml b/build/build.xml index a93725727..b7d4476df 100644 --- a/build/build.xml +++ b/build/build.xml @@ -182,6 +182,7 @@ + @@ -525,6 +526,7 @@ +