From fdc0c3b5185a9475906cb594abda9f3a499feb0f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 14 Oct 2013 17:14:29 -0400 Subject: [PATCH] more font and prefs work, cleanups and more --- app/src/processing/app/Editor.java | 5 +- app/src/processing/app/EditorStatus.java | 6 + .../processing/app/syntax/JEditTextArea.java | 130 +++++++----------- .../app/syntax/PdeTextAreaDefaults.java | 14 +- .../app/syntax/TextAreaDefaults.java | 8 +- .../app/syntax/TextAreaPainter.java | 73 ++++++---- todo.txt | 51 +++---- 7 files changed, 150 insertions(+), 137 deletions(-) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 0d925f6e6..d3de86914 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -472,8 +472,11 @@ public abstract class Editor extends JFrame implements RunnerListener { * with things in the Preferences window. */ protected void applyPreferences() { + // Update fonts and other items controllable from the prefs + textarea.getPainter().updateAppearance(); + textarea.repaint(); + // All of this code was specific to using an external editor. - // Keeping this around so we can update fonts. /* // // apply the setting for 'use external editor' // boolean external = Preferences.getBoolean("editor.external"); diff --git a/app/src/processing/app/EditorStatus.java b/app/src/processing/app/EditorStatus.java index 361db92d9..4f006d580 100644 --- a/app/src/processing/app/EditorStatus.java +++ b/app/src/processing/app/EditorStatus.java @@ -25,6 +25,7 @@ package processing.app; import java.awt.*; import java.awt.event.*; + import javax.swing.*; @@ -196,6 +197,11 @@ public class EditorStatus extends JPanel { Graphics2D g2 = (Graphics2D) g; if (Toolkit.highResDisplay()) { g2.scale(2, 2); + if (Base.isUsableOracleJava()) { + // Oracle Java looks better with anti-aliasing turned on + g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + } } else { g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); diff --git a/app/src/processing/app/syntax/JEditTextArea.java b/app/src/processing/app/syntax/JEditTextArea.java index 9f46161a8..bc5bb0ed3 100644 --- a/app/src/processing/app/syntax/JEditTextArea.java +++ b/app/src/processing/app/syntax/JEditTextArea.java @@ -131,7 +131,7 @@ public class JEditTextArea extends JComponent // Load the defaults setInputHandler(defaults.inputHandler); setDocument(defaults.document); - editable = defaults.editable; +// editable = defaults.editable; caretVisible = defaults.caretVisible; caretBlinks = defaults.caretBlinks; electricScroll = defaults.electricScroll; @@ -1405,30 +1405,23 @@ public class JEditTextArea extends JComponent * Replaces the selection with the specified text. * @param selectedText The replacement text for the selection */ - public void setSelectedText(String selectedText) - { - if(!editable) - { - throw new InternalError("Text component" - + " read only"); + public void setSelectedText(String selectedText) { + if (!editable) { + throw new InternalError("Text component read only"); } - document.beginCompoundEdit(); - try - { - if(rectSelect) - { + try { + if (rectSelect) { Element map = document.getDefaultRootElement(); - int start = selectionStart - map.getElement(selectionStartLine) - .getStartOffset(); - int end = selectionEnd - map.getElement(selectionEndLine) - .getStartOffset(); + int start = selectionStart - + map.getElement(selectionStartLine).getStartOffset(); + int end = selectionEnd - + map.getElement(selectionEndLine).getStartOffset(); // Certain rectangles satisfy this condition... - if(end < start) - { + if (end < start) { int tmp = end; end = start; start = tmp; @@ -1437,123 +1430,102 @@ public class JEditTextArea extends JComponent int lastNewline = 0; int currNewline = 0; - for(int i = selectionStartLine; i <= selectionEndLine; i++) - { + for (int i = selectionStartLine; i <= selectionEndLine; i++) { Element lineElement = map.getElement(i); int lineStart = lineElement.getStartOffset(); int lineEnd = lineElement.getEndOffset() - 1; int rectStart = Math.min(lineEnd,lineStart + start); - document.remove(rectStart,Math.min(lineEnd - rectStart, - end - start)); + document.remove(rectStart,Math.min(lineEnd - rectStart, end - start)); - if(selectedText == null) - continue; - - currNewline = selectedText.indexOf('\n',lastNewline); - if(currNewline == -1) - currNewline = selectedText.length(); - - document.insertString(rectStart,selectedText - .substring(lastNewline,currNewline),null); - - lastNewline = Math.min(selectedText.length(), - currNewline + 1); + if (selectedText != null) { + currNewline = selectedText.indexOf('\n', lastNewline); + if (currNewline == -1) { + currNewline = selectedText.length(); + } + document.insertString(rectStart, selectedText.substring(lastNewline, currNewline), null); + lastNewline = Math.min(selectedText.length(), currNewline + 1); + } } - if(selectedText != null && - currNewline != selectedText.length()) - { - int offset = map.getElement(selectionEndLine) - .getEndOffset() - 1; - document.insertString(offset,"\n",null); - document.insertString(offset + 1,selectedText - .substring(currNewline + 1),null); + if (selectedText != null && + currNewline != selectedText.length()) { + int offset = map.getElement(selectionEndLine).getEndOffset() - 1; + document.insertString(offset, "\n", null); + document.insertString(offset + 1,selectedText.substring(currNewline + 1), null); + } + } else { + document.remove(selectionStart, selectionEnd - selectionStart); + if (selectedText != null) { + document.insertString(selectionStart, selectedText,null); } } - else - { - document.remove(selectionStart, - selectionEnd - selectionStart); - if(selectedText != null) - { - document.insertString(selectionStart, - selectedText,null); - } - } - } - catch(BadLocationException bl) - { + } catch(BadLocationException bl) { bl.printStackTrace(); - throw new InternalError("Cannot replace" - + " selection"); - } - // No matter what happends... stops us from leaving document - // in a bad state - finally - { + throw new InternalError("Cannot replace selection"); + + } finally { + // No matter what happens... stops us from leaving document in a bad state document.endCompoundEdit(); } - setCaretPosition(selectionEnd); } + /** * Returns true if this text area is editable, false otherwise. */ - public final boolean isEditable() - { + public final boolean isEditable() { return editable; } + /** * Sets if this component is editable. * @param editable True if this text area should be editable, * false otherwise */ - public final void setEditable(boolean editable) - { + public final void setEditable(boolean editable) { this.editable = editable; } + /** * Returns the right click popup menu. */ - public final JPopupMenu getRightClickPopup() - { + public final JPopupMenu getRightClickPopup() { return popup; } + /** * Sets the right click popup menu. * @param popup The popup */ - //public final void setRightClickPopup(EditPopupMenu popup) - public final void setRightClickPopup(JPopupMenu popup) - { + public final void setRightClickPopup(JPopupMenu popup) { this.popup = popup; } /** - * Returns the `magic' caret position. This can be used to preserve + * Returns the 'magic' caret position. This can be used to preserve * the column position when moving up and down lines. */ - public final int getMagicCaretPosition() - { + public final int getMagicCaretPosition() { return magicCaret; } + /** - * Sets the `magic' caret position. This can be used to preserve + * Sets the 'magic' caret position. This can be used to preserve * the column position when moving up and down lines. * @param magicCaret The magic caret position */ - public final void setMagicCaretPosition(int magicCaret) - { + public final void setMagicCaretPosition(int magicCaret) { this.magicCaret = magicCaret; } + /** * Similar to setSelectedText(), but overstrikes the * appropriate number of characters if overwrite mode is enabled. @@ -1993,7 +1965,7 @@ public class JEditTextArea extends JComponent protected boolean caretVisible; protected boolean blink; - protected boolean editable; + protected boolean editable = true; protected int firstLine; protected int visibleLines; diff --git a/app/src/processing/app/syntax/PdeTextAreaDefaults.java b/app/src/processing/app/syntax/PdeTextAreaDefaults.java index 8ab7aae91..33427f864 100644 --- a/app/src/processing/app/syntax/PdeTextAreaDefaults.java +++ b/app/src/processing/app/syntax/PdeTextAreaDefaults.java @@ -24,8 +24,6 @@ package processing.app.syntax; -import java.awt.Font; - import processing.app.*; @@ -182,7 +180,7 @@ public class PdeTextAreaDefaults extends TextAreaDefaults { inputHandler.addKeyBinding(mod + "+ENTER", InputHandler.REPEAT); document = new SyntaxDocument(); - editable = true; +// editable = true; // Set to 0 for revision 0215 because it causes strange jumps // http://code.google.com/p/processing/issues/detail?id=1055 @@ -196,13 +194,16 @@ public class PdeTextAreaDefaults extends TextAreaDefaults { // http://code.google.com/p/processing/issues/detail?id=1275 rows = 5; - //font = Preferences.getFont("editor.font"); + /* String fontFamily = Preferences.get("editor.font.family"); int fontSize = Preferences.getInteger("editor.font.size"); plainFont = new Font(fontFamily, Font.PLAIN, fontSize); boldFont = new Font(fontFamily, Font.BOLD, fontSize); -// System.out.println("font is " + plainFont.getFamily() + " / " + plainFont.getName() + " / " + plainFont.getFontName() + " / " + plainFont.getPSName()); antialias = Preferences.getBoolean("editor.antialias"); + */ + + fgcolor = mode.getColor("editor.fgcolor"); + bgcolor = mode.getColor("editor.bgcolor"); styles = new SyntaxStyle[Token.ID_COUNT]; @@ -229,9 +230,6 @@ public class PdeTextAreaDefaults extends TextAreaDefaults { // area that's not in use by the text (replaced with tildes) styles[Token.INVALID] = mode.getStyle("invalid"); - fgcolor = mode.getColor("editor.fgcolor"); - bgcolor = mode.getColor("editor.bgcolor"); - caretColor = mode.getColor("editor.caret.color"); selectionColor = mode.getColor("editor.selection.color"); lineHighlight = mode.getBoolean("editor.linehighlight"); diff --git a/app/src/processing/app/syntax/TextAreaDefaults.java b/app/src/processing/app/syntax/TextAreaDefaults.java index 746685c03..1c9edb7cd 100644 --- a/app/src/processing/app/syntax/TextAreaDefaults.java +++ b/app/src/processing/app/syntax/TextAreaDefaults.java @@ -20,15 +20,17 @@ import java.awt.*; public class TextAreaDefaults { public InputHandler inputHandler; public SyntaxDocument document; - public boolean editable; +// public boolean editable; public boolean caretVisible; public boolean caretBlinks; public boolean blockCaret; public int electricScroll; + // default/preferred number of rows/cols public int cols; public int rows; + public SyntaxStyle[] styles; public Color caretColor; public Color selectionColor; @@ -40,9 +42,11 @@ public class TextAreaDefaults { public boolean eolMarkers; public boolean paintInvalid; + /* public Font plainFont; public Font boldFont; + public boolean antialias; + */ public Color fgcolor; public Color bgcolor; - public boolean antialias; } diff --git a/app/src/processing/app/syntax/TextAreaPainter.java b/app/src/processing/app/syntax/TextAreaPainter.java index 1c950ce2d..758e48933 100644 --- a/app/src/processing/app/syntax/TextAreaPainter.java +++ b/app/src/processing/app/syntax/TextAreaPainter.java @@ -18,6 +18,7 @@ import javax.swing.ToolTipManager; import javax.swing.text.*; import javax.swing.JComponent; +import processing.app.Preferences; import processing.app.syntax.im.CompositionTextPainter; @@ -52,6 +53,13 @@ public class TextAreaPainter extends JComponent implements TabExpander { // protected int cols; // protected int rows; + // moved from TextAreaDefaults + private Font plainFont; + private Font boldFont; + private boolean antialias; +// private Color fgcolor; +// private Color bgcolor; + protected int tabSize; protected FontMetrics fm; @@ -70,7 +78,7 @@ public class TextAreaPainter extends JComponent implements TabExpander { this.defaults = defaults; setAutoscrolls(true); -// setDoubleBuffered(true); // breaks retina with 7u40 +// setDoubleBuffered(true); setOpaque(true); ToolTipManager.sharedInstance().registerComponent(this); @@ -85,7 +93,7 @@ public class TextAreaPainter extends JComponent implements TabExpander { //// System.out.println("defaults font is " + defaults.font); // setForeground(defaults.fgcolor); // setBackground(defaults.bgcolor); - applyDefaults(); + updateAppearance(); // blockCaret = defaults.blockCaret; // styles = defaults.styles; @@ -104,12 +112,25 @@ public class TextAreaPainter extends JComponent implements TabExpander { } - public void applyDefaults() { - // unfortunately probably can't just do setDefaults() since things aren't quite set up - setFont(defaults.plainFont); -// System.out.println("defaults font is " + defaults.font); - setForeground(defaults.fgcolor); - setBackground(defaults.bgcolor); + public void updateAppearance() { +// // unfortunately probably can't just do setDefaults() since things aren't quite set up +// setFont(defaults.plainFont); +//// System.out.println("defaults font is " + defaults.font); +// setForeground(defaults.fgcolor); +// setBackground(defaults.bgcolor); + + String fontFamily = Preferences.get("editor.font.family"); + int fontSize = Preferences.getInteger("editor.font.size"); + plainFont = new Font(fontFamily, Font.PLAIN, fontSize); + boldFont = new Font(fontFamily, Font.BOLD, fontSize); + antialias = Preferences.getBoolean("editor.antialias"); + + // moved from setFont() override (never quite comfortable w/ that override) + fm = super.getFontMetrics(plainFont); + textArea.recalculateVisibleLines(); + +// fgcolor = mode.getColor("editor.fgcolor"); +// bgcolor = mode.getColor("editor.bgcolor"); } @@ -404,22 +425,23 @@ public class TextAreaPainter extends JComponent implements TabExpander { public FontMetrics getFontMetrics(SyntaxStyle style) { - return getFontMetrics(style.isBold() ? - defaults.boldFont : defaults.plainFont); +// return getFontMetrics(style.isBold() ? +// defaults.boldFont : defaults.plainFont); + return getFontMetrics(style.isBold() ? boldFont : plainFont); } - /** - * Sets the font for this component. This is overridden to update the - * cached font metrics and to recalculate which lines are visible. - * @param font The font - */ - public void setFont(Font font) { -// new Exception().printStackTrace(System.out); - super.setFont(font); - fm = super.getFontMetrics(font); - textArea.recalculateVisibleLines(); - } +// /** +// * Sets the font for this component. This is overridden to update the +// * cached font metrics and to recalculate which lines are visible. +// * @param font The font +// */ +// public void setFont(Font font) { +//// new Exception().printStackTrace(System.out); +// super.setFont(font); +// fm = super.getFontMetrics(font); +// textArea.recalculateVisibleLines(); +// } /** @@ -429,9 +451,12 @@ public class TextAreaPainter extends JComponent implements TabExpander { public void paint(Graphics gfx) { Graphics2D g2 = (Graphics2D) gfx; g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - defaults.antialias ? + antialias ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + + g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, + RenderingHints.VALUE_FRACTIONALMETRICS_ON); tabSize = fm.charWidth(' ') * ((Integer)textArea.getDocument().getProperty(PlainDocument.tabSizeAttribute)).intValue(); @@ -700,12 +725,12 @@ public class TextAreaPainter extends JComponent implements TabExpander { // if(!defaultFont.equals(gfx.getFont())) // gfx.setFont(defaultFont); gfx.setColor(defaults.fgcolor); - gfx.setFont(defaults.plainFont); + gfx.setFont(plainFont); } else { //styles[id].setGraphicsFlags(gfx,defaultFont); SyntaxStyle ss = styles[id]; gfx.setColor(ss.getColor()); - gfx.setFont(ss.isBold() ? defaults.boldFont : defaults.plainFont); + gfx.setFont(ss.isBold() ? boldFont : plainFont); } line.count = length; x = Utilities.drawTabbedText(line, x, y, gfx, this, 0); diff --git a/todo.txt b/todo.txt index 633d2b58b..f05de8980 100644 --- a/todo.txt +++ b/todo.txt @@ -21,8 +21,12 @@ X https://github.com/processing/processing/issues/836 X update with bold version of Source Code Pro X http://www.google.com/fonts#UsePlace:use/Collection:Source+Code+Pro +_ does editor line status work? _ Editor.applyPreferences() -> painter.setFont() removed _ need to instead update defaults, then run from there +_ then call repaint() on the text area? or invalidate()? or the painter? +_ make sure font family change is working +_ make sure fonts can actually update size/etc in prefs cleaning o the first time someone hides a tab, put up a msg explaining what it does @@ -65,21 +69,16 @@ X basically done in more recent releases X fix file selection dialog with MovieMaker X copied from PApplet, but not importing PApplet -X add appbundler.jar, otherwise folks have to include Xcode -_ if they want to build appbundler, they'll need Xcode -_ and the command line tools Preferences > Downloads > Command Line Tools -_ appbundler will have an NPE if the osx binary isn't built -_ also need to have 10.8 version of the SDK (old Xcode won't work) - -_ type in the status area is gross on retina displays and 7u40 -_ type looks a little feeble on OS X with non-retina machines -_ https://github.com/processing/processing/issues/2135 -_ type cut off in dialog boxes on OS X retina machines -_ https://github.com/processing/processing/issues/2116 -_ dialog box icon is fuzzy on OS X retina machines -_ https://github.com/processing/processing/issues/2117 -_ solution might be our own dialog boxes (see 'dialogs' section) - +fonts and prefs +_ slightly gray background +_ spacing problem with large sizes (on retina?) +_ control text size in console +o why aren't prefs from theme.txt showing up in preferences.txt? hrm +o or rather, why can't they be overridden? +X because theme.txt data is a different animal / that's part of the point +_ should fonts at least be in prefs.txt? +_ http://code.google.com/p/processing/issues/detail?id=226 +_ https://github.com/processing/processing/issues/265 _ console font in EditorConsole _ Font font = Preferences.getFont("console.font"); _ fix console font on Windows and Linux with 7u40 @@ -92,6 +91,15 @@ _ but might be a problem on Linux _ where the JRE is often replaced _ and where the font is needed most +_ type in the status area is gross on retina displays and 7u40 +_ type looks a little feeble on OS X with non-retina machines +_ https://github.com/processing/processing/issues/2135 +_ type cut off in dialog boxes on OS X retina machines +_ https://github.com/processing/processing/issues/2116 +_ dialog box icon is fuzzy on OS X retina machines +_ https://github.com/processing/processing/issues/2117 +_ solution might be our own dialog boxes (see 'dialogs' section) + build X remove video library for other platforms in download X update apple.jar file with new version @@ -153,6 +161,11 @@ X once fixed, remove notes from JavaBuild.java X "Are you sure you want to quit?" when switching modes on Oracle JVM X default menu bar is still broken X http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8007267 +X add appbundler.jar, otherwise folks have to include Xcode +_ if they want to build appbundler, they'll need Xcode +_ and the command line tools Preferences > Downloads > Command Line Tools +_ appbundler will have an NPE if the osx binary isn't built +_ also need to have 10.8 version of the SDK (old Xcode won't work) _ change how export is handled _ remove ability to export cross-platform apps @@ -741,14 +754,6 @@ _ move styling to separate constants that are more accessible PDE / Preferences -_ control text size in console -o why aren't prefs from theme.txt showing up in preferences.txt? hrm -o or rather, why can't they be overridden? -X because theme.txt data is a different animal / that's part of the point -_ should fonts at least be in prefs.txt? -_ http://code.google.com/p/processing/issues/detail?id=226 -_ https://github.com/processing/processing/issues/265 - _ the .macosx, .linux, etc prefs should be stripped _ only use them on first load, and merge into preferences.txt _ Editor.applyFrame() may not have a valid 'editor' object to work with