From 0eb5ba518ac40343a68cef09a13ecf9c9e5ce0fe Mon Sep 17 00:00:00 2001 From: Jeremy Laviole Date: Tue, 24 Nov 2015 17:55:40 +0100 Subject: [PATCH 01/21] Support of embedded images in SVGs, linked images are supported but should not be avoided if possible. Support of Text in SVGs (partial). Multiline text are also displayed. Text limitations : Inline styles are not supported. Not all fonts are supported (depending on your OS). Tested only on Inkscape SVGs. --- core/src/processing/core/PShape.java | 111 +++++++++++-- core/src/processing/core/PShapeSVG.java | 199 +++++++++++++++++++++++- 2 files changed, 291 insertions(+), 19 deletions(-) diff --git a/core/src/processing/core/PShape.java b/core/src/processing/core/PShape.java index 44ff15115c..03de66203f 100644 --- a/core/src/processing/core/PShape.java +++ b/core/src/processing/core/PShape.java @@ -22,8 +22,23 @@ package processing.core; +import java.awt.Image; +import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; +import java.util.Base64.Decoder; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.nio.charset.StandardCharsets; +import javax.swing.ImageIcon; +import javax.xml.bind.DatatypeConverter; + + import processing.core.PApplet; @@ -106,6 +121,7 @@ public class PShape implements PConstants { /** Texture or image data associated with this shape. */ protected PImage image; + protected String imagePath = null; public static final String OUTSIDE_BEGIN_END_ERROR = "%1$s can only be called between beginShape() and endShape()"; @@ -1645,6 +1661,10 @@ protected void drawPrimitive(PGraphics g) { params[6], params[7]); } else if (kind == RECT) { + + if (imagePath != null){ + loadImage(g); + } if (image != null) { int oldMode = g.imageMode; g.imageMode(CORNER); @@ -1879,6 +1899,63 @@ protected void drawPath(PGraphics g) { g.endShape(close ? CLOSE : OPEN); } + private void loadImage(PGraphics g){ + + if(this.imagePath.startsWith("data:image")){ + loadBase64Image(); + } + + if(this.imagePath.startsWith("file://")){ + loadFileSystemImage(g); + } + this.imagePath = null; + } + + private void loadFileSystemImage(PGraphics g){ + imagePath = imagePath.substring(7); + PImage loadedImage = g.parent.loadImage(imagePath); + if(loadedImage == null){ + System.err.println("Error loading image file: " + imagePath); + }else{ + setTexture(loadedImage); + } + } + + private void loadBase64Image(){ + String[] parts = this.imagePath.split(";base64,"); + String extension = parts[0].substring(11); + String encodedData = parts[1]; + + byte[] decodedBytes = DatatypeConverter.parseBase64Binary(encodedData); + + if(decodedBytes == null){ + System.err.println("Decode Error on image: " + imagePath.substring(0, 20)); + return; + } + + Image awtImage = new ImageIcon(decodedBytes).getImage(); + + if (awtImage instanceof BufferedImage) { + BufferedImage buffImage = (BufferedImage) awtImage; + int space = buffImage.getColorModel().getColorSpace().getType(); + if (space == ColorSpace.TYPE_CMYK) { + return; + } + } + + PImage loadedImage = new PImage(awtImage); + if (loadedImage.width == -1) { + // error... + } + + // if it's a .gif image, test to see if it has transparency + if (extension.equals("gif") || extension.equals("png") || + extension.equals("unknown")) { + loadedImage.checkAlpha(); + } + + setTexture(loadedImage); + } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -2387,14 +2464,14 @@ public void setFill(boolean fill) { /** * ( begin auto-generated from PShape_setFill.xml ) * - * The setFill() method defines the fill color of a PShape. - * This method is used after shapes are created or when a shape is defined explicitly - * (e.g. createShape(RECT, 20, 20, 80, 80)) as shown in the above example. - * When a shape is created with beginShape() and endShape(), its - * attributes may be changed with fill() and stroke() within - * beginShape() and endShape(). However, after the shape is - * created, only the setFill() method can define a new fill value for - * the PShape. + * The setFill() method defines the fill color of a PShape. + * This method is used after shapes are created or when a shape is defined explicitly + * (e.g. createShape(RECT, 20, 20, 80, 80)) as shown in the above example. + * When a shape is created with beginShape() and endShape(), its + * attributes may be changed with fill() and stroke() within + * beginShape() and endShape(). However, after the shape is + * created, only the setFill() method can define a new fill value for + * the PShape. * * ( end auto-generated ) * @@ -2543,14 +2620,14 @@ public void setStroke(boolean stroke) { /** * ( begin auto-generated from PShape_setStroke.xml ) * - * The setStroke() method defines the outline color of a PShape. - * This method is used after shapes are created or when a shape is defined - * explicitly (e.g. createShape(RECT, 20, 20, 80, 80)) as shown in - * the above example. When a shape is created with beginShape() and - * endShape(), its attributes may be changed with fill() and - * stroke() within beginShape() and endShape(). - * However, after the shape is created, only the setStroke() method - * can define a new stroke value for the PShape. + * The setStroke() method defines the outline color of a PShape. + * This method is used after shapes are created or when a shape is defined + * explicitly (e.g. createShape(RECT, 20, 20, 80, 80)) as shown in + * the above example. When a shape is created with beginShape() and + * endShape(), its attributes may be changed with fill() and + * stroke() within beginShape() and endShape(). + * However, after the shape is created, only the setStroke() method + * can define a new stroke value for the PShape. * * ( end auto-generated ) * @@ -3442,4 +3519,4 @@ protected void colorCalcARGB(int argb, float alpha) { calcAlpha = (calcAi != 255); } -} \ No newline at end of file +} diff --git a/core/src/processing/core/PShapeSVG.java b/core/src/processing/core/PShapeSVG.java index bf5cdc2f1f..adc1763bb0 100644 --- a/core/src/processing/core/PShapeSVG.java +++ b/core/src/processing/core/PShapeSVG.java @@ -24,6 +24,9 @@ package processing.core; +import static java.awt.Font.BOLD; +import static java.awt.Font.ITALIC; +import static java.awt.Font.PLAIN; import processing.data.*; // TODO replace these with PMatrix2D @@ -329,6 +332,10 @@ protected PShape parseChild(XML elem) { } else if (name.equals("rect")) { shape = createShape(this, elem, true); shape.parseRect(); + + } else if (name.equals("image")) { + shape = createShape(this, elem, true); + shape.parseImage(); } else if (name.equals("polygon")) { shape = createShape(this, elem, true); @@ -358,8 +365,10 @@ protected PShape parseChild(XML elem) { // return new FontGlyph(this, elem); } else if (name.equals("text")) { // || name.equals("font")) { - PGraphics.showWarning("Text and fonts in SVG files are " + - "not currently supported, convert text to outlines instead."); + return new Text(this, elem); + + } else if (name.equals("tspan")) { + return new LineOfText(this, elem); } else if (name.equals("filter")) { PGraphics.showWarning("Filters are not supported."); @@ -439,8 +448,23 @@ protected void parseRect() { getFloatWithUnit(element, "height", svgHeight) }; } + + + protected void parseImage() { + kind = RECT; + textureMode = NORMAL; + family = PRIMITIVE; + params = new float[] { + getFloatWithUnit(element, "x", svgWidth), + getFloatWithUnit(element, "y", svgHeight), + getFloatWithUnit(element, "width", svgWidth), + getFloatWithUnit(element, "height", svgHeight) + }; + this.imagePath = element.getString("xlink:href"); + } + /** * Parse a polyline or polygon from an SVG file. * Syntax defined at http://www.w3.org/TR/SVG/shapes.html#PointsBNF @@ -1557,8 +1581,179 @@ public RadialGradient(PShapeSVG parent, XML properties) { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + public static float TEXT_QUALITY = 1; + protected PFont parseFont(XML properties) { + +// FontFace fontFace = new FontFace(this, properties); + String fontFamily = null; + float size = 10; + int weight = PLAIN; // 0 + int italic = 0; + + if (properties.hasAttribute("style")) { + String styleText = properties.getString("style"); + String[] styleTokens = PApplet.splitTokens(styleText, ";"); + + //PApplet.println(styleTokens); + for (int i = 0; i < styleTokens.length; i++) { + + String[] tokens = PApplet.splitTokens(styleTokens[i], ":"); + //PApplet.println(tokens); + + tokens[0] = PApplet.trim(tokens[0]); + + if (tokens[0].equals("font-style")) { + // PApplet.println("font-style: " + tokens[1]); + if (tokens[1].contains("italic")) { + italic = ITALIC; + } + } else if (tokens[0].equals("font-variant")) { + // PApplet.println("font-variant: " + tokens[1]); + // setFillOpacity(tokens[1]); + + } else if (tokens[0].equals("font-weight")) { + // PApplet.println("font-weight: " + tokens[1]); + + if (tokens[1].contains("bold")) { + weight = BOLD; + // PApplet.println("Bold weight ! "); + } + + + } else if (tokens[0].equals("font-stretch")) { + // not supported. + + } else if (tokens[0].equals("font-size")) { + // PApplet.println("font-size: " + tokens[1]); + size = Float.parseFloat(tokens[1].split("px")[0]); + // PApplet.println("font-size-parsed: " + size); + } else if (tokens[0].equals("line-height")) { + // not supported + + } else if (tokens[0].equals("font-family")) { + // PApplet.println("Font-family: " + tokens[1]); + fontFamily = tokens[1]; + + } else if (tokens[0].equals("text-align")) { + // not supported + + } else if (tokens[0].equals("letter-spacing")) { + // not supported + + } else if (tokens[0].equals("word-spacing")) { + // not supported + + } else if (tokens[0].equals("writing-mode")) { + // not supported + + } else if (tokens[0].equals("text-anchor")) { + // not supported + + } else { + // Other attributes are not yet implemented + } + } + } + if (fontFamily == null) { + return null; + } + size = size * TEXT_QUALITY; + + return createFont(fontFamily, weight | italic, size, true); + } + + protected PFont createFont(String name, int weight, float size, boolean smooth) { + +// System.out.println("Try to create a font of " + name + " family, " + weight); + java.awt.Font baseFont = new java.awt.Font(name, weight, (int) size); // PFont.findFont(name);ç + +// System.out.println("Resulting family : " + baseFont.getFamily() + " " + baseFont.getStyle()); + PFont outputPFont = new PFont(baseFont.deriveFont(size), smooth, null); + +// System.out.println("Resulting PFont family : " + outputPFont.getName()); + return outputPFont; + } + + public static class Text extends PShapeSVG { + + protected PFont font; + + public Text(PShapeSVG parent, XML properties) { + super(parent, properties, true); + + // get location + float x = Float.parseFloat(properties.getString("x")); + float y = Float.parseFloat(properties.getString("y")); + + if (matrix == null) { + matrix = new PMatrix2D(); + } + matrix.translate(x, y); + + family = GROUP; + + font = parseFont(properties); + } + +// @Override +// public void drawImpl(PGraphics g){ +// } + } + + public static class LineOfText extends PShapeSVG { + String textToDisplay; + PFont font; + + public LineOfText(PShapeSVG parent, XML properties) { + + // TODO: child should ideally be parsed too... + // for inline content. + super(parent, properties, false); + +// // get location + float x = Float.parseFloat(properties.getString("x")); + float y = Float.parseFloat(properties.getString("y")); + + float parentX = Float.parseFloat(parent.element.getString("x")); + float parentY = Float.parseFloat(parent.element.getString("y")); + + if (matrix == null) matrix = new PMatrix2D(); + matrix.translate(x - parentX, (y - parentY) / 2f); + + // get the first properties + parseColors(properties); + font = parseFont(properties); + + // It is a line.. + boolean isALine = properties.getString("role") == "line"; + // NO inline content yet. + if (this.childCount > 0) { + } + + String text = properties.getContent(); + textToDisplay = text; + } + + @Override + public void drawImpl(PGraphics g) { + if (font == null) { + font = ((Text) parent).font; + if (font == null) { + return; + } + } + + pre(g); + g.textFont(font, font.size / TEXT_QUALITY); + g.text(textToDisplay, 0, 0); + post(g); + } + + } + public static class Font extends PShapeSVG { public FontFace face; From d0e016bea63c19d7acbfc7dc1168cffc8508d7cd Mon Sep 17 00:00:00 2001 From: George Bateman Date: Wed, 7 Jun 2017 15:37:32 +0100 Subject: [PATCH 02/21] Add console hiding button Also made the existing copy-message button consistent. --- app/src/processing/app/ui/Editor.java | 11 ++ app/src/processing/app/ui/EditorStatus.java | 113 +++++++++++++++----- 2 files changed, 96 insertions(+), 28 deletions(-) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index be85d5b5bb..36949fbbd8 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -320,6 +320,17 @@ public BasicSplitPaneDivider createDefaultDivider() { status = new EditorStatus(this, Editor.this); return status; } + + + @Override + public void finishDraggingTo(int location) { + super.finishDraggingTo(location); + // JSplitPane issue: if you only make the lower component visible at + // the last minute, its minmum size is ignored. + if (location > splitPane.getMaximumDividerLocation()) { + splitPane.setDividerLocation(splitPane.getMaximumDividerLocation()); + } + } }); box.add(splitPane); diff --git a/app/src/processing/app/ui/EditorStatus.java b/app/src/processing/app/ui/EditorStatus.java index 963867c287..c4db92bae2 100644 --- a/app/src/processing/app/ui/EditorStatus.java +++ b/app/src/processing/app/ui/EditorStatus.java @@ -79,20 +79,22 @@ public class EditorStatus extends BasicSplitPaneDivider { //JPanel { String url; int rightEdge; int mouseX; - boolean urlRollover; + int rolloverState; + static final int ROLLOVER_NONE = 0; + static final int ROLLOVER_URL = 1; + static final int ROLLOVER_COLLAPSE = 2; + static final int ROLLOVER_EMOJI = 3; Font font; FontMetrics metrics; int ascent; // used to draw the clipboard icon - static final int EMOJI_OFFSET = 27; Font emojiFont; - int emojiLeft; - boolean emojiRollover; Image offscreen; int sizeW, sizeH; + boolean collapseState = false; int response; @@ -115,10 +117,10 @@ public void mouseEntered(MouseEvent e) { @Override public void mousePressed(MouseEvent e) { - if (urlRollover) { + if (rolloverState == ROLLOVER_URL) { Platform.openURL(url); - } else if (emojiRollover) { + } else if (rolloverState == ROLLOVER_EMOJI) { if (e.isShiftDown()) { // open the text in a browser window as a search final String fmt = Preferences.get("search.format"); @@ -131,17 +133,28 @@ public void mousePressed(MouseEvent e) { System.out.println("Copied to the clipboard. " + "Use shift-click to search the web instead."); } + + } else if (rolloverState == ROLLOVER_COLLAPSE) { + collapse(!collapseState); } } @Override public void mouseExited(MouseEvent e) { + mouseX = -100; updateMouse(); } }); addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseDragged(MouseEvent e) { + // BasicSplitPaneUI.startDragging gets called even when you click but + // don't drag, so we can't expand the console whenever that gets called + // or the button wouldn't work. + collapse(false); + } @Override public void mouseMoved(MouseEvent e) { @@ -152,13 +165,26 @@ public void mouseMoved(MouseEvent e) { } + void collapse(boolean doCollapse) { + if (collapseState == doCollapse) return; + collapseState = doCollapse; + editor.footer.setVisible(!doCollapse); + splitPane.resetToPreferredSizes(); + } + + void updateMouse() { - if (urlRollover) { - setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } else if (emojiRollover) { + switch (rolloverState) { + case ROLLOVER_EMOJI: + case ROLLOVER_URL: setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } else { + break; + case ROLLOVER_COLLAPSE: + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + break; + case ROLLOVER_NONE: setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + break; } repaint(); } @@ -282,8 +308,8 @@ public void stopIndeterminate() { } + //public void paintComponent(Graphics screen) { public void paint(Graphics screen) { -// public void paint(Graphics screen) { Dimension size = getSize(); if ((size.width != sizeW) || (size.height != sizeH)) { // component has been resized @@ -308,21 +334,31 @@ public void paint(Graphics screen) { g.drawImage(bgImage[mode], 0, 0, sizeW, sizeH, this); - g.setColor(fgColor[mode]); + // What's the mouse over? + if (sizeW - sizeH < mouseX && mouseX < sizeW) { + rolloverState = ROLLOVER_COLLAPSE; + } else if (message != null && !message.isEmpty()) { + if (sizeW - 2*sizeH < mouseX) { + rolloverState = ROLLOVER_EMOJI; + } else if (url != null && mouseX > LEFT_MARGIN && + // calculate right edge of the text for rollovers (otherwise the pane + // cannot be resized up or down whenever a URL is being displayed) + mouseX < (LEFT_MARGIN + g.getFontMetrics().stringWidth(message))) { + rolloverState = ROLLOVER_URL; + } else { + rolloverState = ROLLOVER_NONE; + } + } else { + rolloverState = ROLLOVER_NONE; + } + // https://github.com/processing/processing/issues/3265 if (message != null) { // needs to be set each time on osx g.setFont(font); - // calculate right edge of the text for rollovers (otherwise the pane - // cannot be resized up or down whenever a URL is being displayed) - rightEdge = LEFT_MARGIN + g.getFontMetrics().stringWidth(message); // set the highlight color on rollover so that the user's not surprised // to see the web browser open when they click - urlRollover = (url != null) && - (mouseX > LEFT_MARGIN && mouseX < rightEdge); - if (urlRollover) { - g.setColor(urlColor); - } + g.setColor((rolloverState == ROLLOVER_URL) ? urlColor : fgColor[mode]); g.drawString(message, LEFT_MARGIN, (sizeH + ascent) / 2); } @@ -330,9 +366,9 @@ public void paint(Graphics screen) { //int x = cancelButton.getX(); //int w = cancelButton.getWidth(); int w = Toolkit.getButtonWidth(); - int x = getWidth() - RIGHT_MARGIN - w; - int y = getHeight() / 3; - int h = getHeight() / 3; + int x = getWidth() - Math.max(RIGHT_MARGIN, (int)(sizeH*1.2)) - w; + int y = sizeH / 3; + int h = sizeH / 3; g.setColor(new Color(0x80000000, true)); g.drawRect(x, y, w, h); for (int i = 0; i < 10; i++) { @@ -341,20 +377,41 @@ public void paint(Graphics screen) { } } else if (!message.isEmpty()) { - g.setColor(Color.WHITE); g.setFont(emojiFont); // actual Clipboard character not available [fry 180326] //g.drawString("\uD83D\uDCCB", sizeW - LEFT_MARGIN, (sizeH + ascent) / 2); - // other apps seem to use this one as a hack - emojiLeft = sizeW - Toolkit.zoom(EMOJI_OFFSET); - g.drawString("\u2398", emojiLeft, (sizeH + ascent) / 2); - emojiRollover = mouseX > emojiLeft - 4; + // other apps seem to use this one as a hack: ⎘ + drawButton(g, "\u2398", 1, rolloverState == ROLLOVER_EMOJI); + g.setFont(font); } + // draw collapse/expand button + drawButton(g, collapseState ? "▲" : "▼", 0, rolloverState == ROLLOVER_COLLAPSE); + screen.drawImage(offscreen, 0, 0, sizeW, sizeH, null); } + private final Color whitishTint = new Color(0x40eeeeee, true); + /** + * @param pos A zero-based index with 0 on the right. + */ + private void drawButton(Graphics g, String symbol, int pos, boolean highlight) { + int left = sizeW - (pos + 1) * sizeH; + g.setColor(bgColor[mode]); // Overlap very long errors. + g.fillRect(left, 0, sizeH, sizeH); + if (highlight) { + g.setColor(whitishTint); + g.fillRect(left, 0, sizeH, sizeH); + g.setColor(urlColor); + } else { + g.setColor(fgColor[mode]); + } + g.drawString(symbol, + left + (sizeH - g.getFontMetrics().stringWidth(symbol))/2, + (sizeH + ascent) / 2); + } + public Dimension getPreferredSize() { return getMinimumSize(); } From ec8de86dbf7a62d857f9ef4211dc325267218bee Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Tue, 24 Apr 2018 11:31:27 +0200 Subject: [PATCH 03/21] Change Editor status message only from EDT This adapter invokes all status changes on the EDT instead of worker thread of the Runner. Modifying AWT components from the worker threads may introduce strange bugs and in this case caused UI changes to run out of order, hiding runtime exceptions under problems displayed when cursor moves to the offending line. --- .../app/RunnerListenerEdtAdapter.java | 48 +++++++++++++++++++ java/src/processing/mode/java/Debugger.java | 3 +- java/src/processing/mode/java/JavaEditor.java | 5 +- 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 app/src/processing/app/RunnerListenerEdtAdapter.java diff --git a/app/src/processing/app/RunnerListenerEdtAdapter.java b/app/src/processing/app/RunnerListenerEdtAdapter.java new file mode 100644 index 0000000000..a436eefbca --- /dev/null +++ b/app/src/processing/app/RunnerListenerEdtAdapter.java @@ -0,0 +1,48 @@ +package processing.app; + +import java.awt.EventQueue; + +public class RunnerListenerEdtAdapter implements RunnerListener { + + private RunnerListener wrapped; + + public RunnerListenerEdtAdapter(RunnerListener wrapped) { + this.wrapped = wrapped; + } + + @Override + public void statusError(String message) { + EventQueue.invokeLater(() -> wrapped.statusError(message)); + } + + @Override + public void statusError(Exception exception) { + EventQueue.invokeLater(() -> wrapped.statusError(exception)); + } + + @Override + public void statusNotice(String message) { + EventQueue.invokeLater(() -> wrapped.statusNotice(message)); + } + + @Override + public void startIndeterminate() { + EventQueue.invokeLater(() -> wrapped.startIndeterminate()); + } + + @Override + public void stopIndeterminate() { + EventQueue.invokeLater(() -> wrapped.stopIndeterminate()); + } + + @Override + public void statusHalt() { + EventQueue.invokeLater(() -> wrapped.statusHalt()); + } + + @Override + public boolean isHalted() { + return wrapped.isHalted(); + } +} + diff --git a/java/src/processing/mode/java/Debugger.java b/java/src/processing/mode/java/Debugger.java index ac6835b21e..3fcb069d5d 100644 --- a/java/src/processing/mode/java/Debugger.java +++ b/java/src/processing/mode/java/Debugger.java @@ -39,6 +39,7 @@ import javax.swing.tree.DefaultMutableTreeNode; import processing.app.Messages; +import processing.app.RunnerListenerEdtAdapter; import processing.app.Sketch; import processing.app.SketchCode; import processing.mode.java.debug.*; @@ -201,7 +202,7 @@ public synchronized void startDebug() { //lineMap = LineMapping.generateMapping(srcPath + File.separator + mainClassName + ".java"); log("launching debuggee runtime"); - runtime = new Runner(build, editor); + runtime = new Runner(build, new RunnerListenerEdtAdapter(editor)); VirtualMachine vm = runtime.debug(null); // non-blocking if (vm == null) { loge("error 37: launch failed", null); diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 10c825027f..c95c9094fb 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -1093,10 +1093,11 @@ protected void handleLaunch(boolean present, boolean tweak) { synchronized (runtimeLock) { if (runtimeLaunchRequested) { runtimeLaunchRequested = false; + RunnerListener listener = new RunnerListenerEdtAdapter(JavaEditor.this); if (!tweak) { - runtime = jmode.handleLaunch(sketch, JavaEditor.this, present); + runtime = jmode.handleLaunch(sketch, listener, present); } else { - runtime = jmode.handleTweak(sketch, JavaEditor.this); + runtime = jmode.handleTweak(sketch, listener); } } } From eb9002568922893c6423b15cdc48f301b7248dfc Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Tue, 24 Apr 2018 11:35:14 +0200 Subject: [PATCH 04/21] Print exception message to the console when stack trace is disabled Make sure something is always printed to the console when sketch crashes with exception. Message in the status bar might disappear after moving the cursor. --- app/src/processing/app/SketchException.java | 5 +++++ app/src/processing/app/ui/Editor.java | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/app/src/processing/app/SketchException.java b/app/src/processing/app/SketchException.java index ccf8b924e6..4a32d2e79d 100644 --- a/app/src/processing/app/SketchException.java +++ b/app/src/processing/app/SketchException.java @@ -130,6 +130,11 @@ public void hideStackTrace() { } + public boolean isStackTraceEnabled() { + return showStackTrace; + } + + /** * Nix the java.lang crap out of an exception message * because it scares the children. diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index be85d5b5bb..33513e1de2 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -2900,6 +2900,17 @@ public void statusError(Exception e) { if (e instanceof SketchException) { SketchException re = (SketchException) e; + + // Make sure something is printed into the console + // Status bar is volatile + if (!re.isStackTraceEnabled()) { + System.err.println(re.getMessage()); + } + + // Move the cursor to the line before updating the status bar, otherwise + // status message might get hidden by a potential message caused by moving + // the cursor to a line with warning in it + if (re.hasCodeIndex()) { sketch.setCurrentCode(re.getCodeIndex()); } From 67f805a5decbe354210174e1eb90965f100f9033 Mon Sep 17 00:00:00 2001 From: Floris Date: Fri, 3 Aug 2018 12:20:49 +0200 Subject: [PATCH 05/21] Add a warning to findFont() when a font isn't found (and the default font is used). --- core/src/processing/core/PFont.java | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/core/src/processing/core/PFont.java b/core/src/processing/core/PFont.java index 632cd7ec03..b4b9a0fe69 100644 --- a/core/src/processing/core/PFont.java +++ b/core/src/processing/core/PFont.java @@ -145,6 +145,12 @@ public class PFont implements PConstants { /** True if already tried to find the native AWT version of this font. */ protected boolean fontSearched; + /** + * The name of the font that is used as default when a font isn't found. + * See {@link #findFont(String)} and {@link #loadFonts()} for more info. + */ + static protected String defaultFontName; + /** * Array of the native system fonts. Used to lookup native fonts by their * PostScript name. This is a workaround for a several year old Apple Java @@ -901,6 +907,7 @@ static public void loadFonts() { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); fonts = ge.getAllFonts(); + defaultFontName = new Font("",Font.PLAIN,1).getFontName(); if (PApplet.platform == PConstants.MACOSX) { fontDifferent = new HashMap(); for (Font font : fonts) { @@ -917,6 +924,10 @@ static public void loadFonts() { * Starting with Java 1.5, Apple broke the ability to specify most fonts. * This bug was filed years ago as #4769141 at bugreporter.apple.com. More: * Bug 407. + *
+ * This function displays a warning when the font isn't found and the default font is + * used. + * See: issue #5481 */ static public Font findFont(String name) { loadFonts(); @@ -931,7 +942,14 @@ static public Font findFont(String name) { // } // } } - return new Font(name, Font.PLAIN, 1); + Font font = new Font(name, Font.PLAIN, 1); + if(!defaultFontName.equals(name) && font.getFontName().equals(defaultFontName)) { + System.err.println("Warning: font \"" + name + + "\" is missing or inaccessible on this system. Default font \"" + + defaultFontName + "\" is used."); + + } + return font; } From 508cde1fd7a53e958328e12e937e28028e08b966 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Tue, 15 Jan 2019 13:30:24 -0500 Subject: [PATCH 06/21] set tessGeo when collecting custom vertex attributes --- core/src/processing/opengl/PShapeOpenGL.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/src/processing/opengl/PShapeOpenGL.java b/core/src/processing/opengl/PShapeOpenGL.java index 0a165b0330..c579c8ce30 100644 --- a/core/src/processing/opengl/PShapeOpenGL.java +++ b/core/src/processing/opengl/PShapeOpenGL.java @@ -2828,15 +2828,21 @@ protected void initModified() { protected void tessellate() { if (root == this && parent == null) { // Root shape + boolean initAttr = false; if (polyAttribs == null) { polyAttribs = PGraphicsOpenGL.newAttributeMap(); - collectPolyAttribs(); + initAttr = true; } if (tessGeo == null) { tessGeo = PGraphicsOpenGL.newTessGeometry(pg, polyAttribs, PGraphicsOpenGL.RETAINED); } tessGeo.clear(); + + if (initAttr) { + collectPolyAttribs(); + } + for (int i = 0; i < polyAttribs.size(); i++) { VertexAttribute attrib = polyAttribs.get(i); tessGeo.initAttrib(attrib); @@ -2854,6 +2860,7 @@ protected void tessellate() { protected void collectPolyAttribs() { AttributeMap rootAttribs = root.polyAttribs; + tessGeo = root.tessGeo; if (family == GROUP) { for (int i = 0; i < childCount; i++) { From f05094b81f0e6f263c506ae3378240ed4e5a7e5b Mon Sep 17 00:00:00 2001 From: codeanticode Date: Tue, 15 Jan 2019 13:33:04 -0500 Subject: [PATCH 07/21] create attribute in setAttrib() functions if does not exist, and also fix indexing bug --- core/src/processing/opengl/PShapeOpenGL.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/core/src/processing/opengl/PShapeOpenGL.java b/core/src/processing/opengl/PShapeOpenGL.java index c579c8ce30..c240847512 100644 --- a/core/src/processing/opengl/PShapeOpenGL.java +++ b/core/src/processing/opengl/PShapeOpenGL.java @@ -1761,10 +1761,11 @@ public void setAttrib(String name, int index, float... values) { return; } - VertexAttribute attrib = polyAttribs.get(name); + VertexAttribute attrib = attribImpl(name, VertexAttribute.OTHER, PGL.FLOAT, + values.length); float[] array = inGeo.fattribs.get(name); for (int i = 0; i < values.length; i++) { - array[attrib.size * index + 0] = values[i]; + array[attrib.size * index + i] = values[i]; } markForTessellation(); } @@ -1777,10 +1778,11 @@ public void setAttrib(String name, int index, int... values) { return; } - VertexAttribute attrib = polyAttribs.get(name); + VertexAttribute attrib = attribImpl(name, VertexAttribute.OTHER, PGL.INT, + values.length); int[] array = inGeo.iattribs.get(name); for (int i = 0; i < values.length; i++) { - array[attrib.size * index + 0] = values[i]; + array[attrib.size * index + i] = values[i]; } markForTessellation(); } @@ -1793,10 +1795,11 @@ public void setAttrib(String name, int index, boolean... values) { return; } - VertexAttribute attrib = polyAttribs.get(name); + VertexAttribute attrib = attribImpl(name, VertexAttribute.OTHER, PGL.BOOL, + values.length); byte[] array = inGeo.battribs.get(name); for (int i = 0; i < values.length; i++) { - array[attrib.size * index + 0] = (byte)(values[i]?1:0); + array[attrib.size * index + i] = (byte)(values[i]?1:0); } markForTessellation(); } From f671f16ed8d97351d56d6380bd1a4a04addb22b9 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 17 Jan 2019 08:52:46 -0800 Subject: [PATCH 08/21] temporarily ignore IntelliJ files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 41efa90f56..cd99249298 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ *~ /build/shared/reference.zip +# temporary, until we complete the move to IntelliJ +*.iml +/.idea # via https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm From 7ce606e0f4932bc64f84739888cdf8a3e3833873 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 17 Jan 2019 08:53:11 -0800 Subject: [PATCH 09/21] update out-of-date Help menu links (fixes #5729) --- build/shared/lib/languages/PDE.properties | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build/shared/lib/languages/PDE.properties b/build/shared/lib/languages/PDE.properties index 7acab2a196..37b191509f 100644 --- a/build/shared/lib/languages/PDE.properties +++ b/build/shared/lib/languages/PDE.properties @@ -116,15 +116,15 @@ menu.help.tools_reference = Tools Reference menu.help.empty = (empty) menu.help.online = Online menu.help.getting_started = Getting Started -menu.help.getting_started.url = http://processing.org/learning/gettingstarted/ +menu.help.getting_started.url = https://processing.org/tutorials/gettingstarted/ menu.help.troubleshooting = Troubleshooting -menu.help.troubleshooting.url = http://wiki.processing.org/w/Troubleshooting +menu.help.troubleshooting.url = https://github.com/processing/processing/wiki/troubleshooting menu.help.faq = Frequently Asked Questions -menu.help.faq.url = http://wiki.processing.org/w/FAQ +menu.help.faq.url = https://github.com/processing/processing/wiki/FAQ menu.help.foundation = The Processing Foundation -menu.help.foundation.url = http://processing.org/foundation/ +menu.help.foundation.url = https://processing.foundation/ menu.help.visit = Visit Processing.org -menu.help.visit.url = http://processing.org/ +menu.help.visit.url = https://processing.org/ # --------------------------------------- From 9a3fc521bbc301d289df72742d2e7b493dc1dec3 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 17 Jan 2019 08:53:45 -0800 Subject: [PATCH 10/21] resolve ambiguous import --- java/src/processing/mode/java/preproc/PdePreprocessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/processing/mode/java/preproc/PdePreprocessor.java b/java/src/processing/mode/java/preproc/PdePreprocessor.java index 1b38e14311..f22de1387c 100644 --- a/java/src/processing/mode/java/preproc/PdePreprocessor.java +++ b/java/src/processing/mode/java/preproc/PdePreprocessor.java @@ -27,7 +27,7 @@ package processing.mode.java.preproc; -import java.awt.*; +import java.awt.EventQueue; import java.io.*; import java.util.*; import java.util.regex.MatchResult; From ea7ac8ce0703468e119a84ce8a152472f2fa22f3 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 17 Jan 2019 08:54:00 -0800 Subject: [PATCH 11/21] more notes and updates for recent issues --- core/todo.txt | 2 ++ todo.txt | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index 16378967b2..04f84f551d 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -31,6 +31,8 @@ X Processing 3.4 takes 60 seconds before can edit file X https://github.com/processing/processing/issues/5707 X skip Android's SDK folder when adding sketches X https://github.com/processing/processing/commit/5b653263cc6151f838c11a61689d756901c11e37 +X PShape.attrib() and PShape.setAttrib() are not working +X https://github.com/processing/processing/issues/5560 jakub X Fix freeze when restarting sketch with variables in size diff --git a/todo.txt b/todo.txt index 53bf5e697c..882879304d 100755 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,10 @@ 0266 (3.4.1 or 3.5) X update to Java 8u192 +o processing-java doesn't handle sketch exceptions by quitting the sketch +X https://github.com/processing/processing/issues/5375 +X this is by design/follows PDE behavior _ fix the link to the FAQ in the menu _ https://github.com/processing/processing/issues/5729 -_ processing-java doesn't handle sketch exceptions by quitting the sketch -_ https://github.com/processing/processing/issues/5375 contrib X Updated russian translation, now can choose russian in preferences From 50af488d69ce34b9a8e1bf56eed591d07b1778c9 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 17 Jan 2019 09:12:14 -0800 Subject: [PATCH 12/21] other notes and cleanup --- todo.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/todo.txt b/todo.txt index 882879304d..1d586c976b 100755 --- a/todo.txt +++ b/todo.txt @@ -3,8 +3,8 @@ X update to Java 8u192 o processing-java doesn't handle sketch exceptions by quitting the sketch X https://github.com/processing/processing/issues/5375 X this is by design/follows PDE behavior -_ fix the link to the FAQ in the menu -_ https://github.com/processing/processing/issues/5729 +X fix the link to the FAQ in the menu +X https://github.com/processing/processing/issues/5729 contrib X Updated russian translation, now can choose russian in preferences @@ -17,9 +17,8 @@ X https://github.com/processing/processing/pull/5654 _ Find in Reference disabled for various keywords (draw, for, if, catch, while) _ https://github.com/processing/processing/issues/5562 _ https://github.com/processing/processing/pull/5642 +_ discuss with Casey -_ Examples dialog causes high CPU load -_ https://github.com/processing/processing/issues/5246 _ Welcome screen doesn't size properly for HiDPI screens _ https://github.com/processing/processing/issues/4896 _ Find in Reference disabled for various keywords (draw, for, if, catch, while) From a2834efbac737962f1c86e04243110ff40ef829f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 18 Jan 2019 09:55:43 -0800 Subject: [PATCH 13/21] move to JDK 1.8 instead of 1.6 b/c of Eclipse warnings --- java/libraries/dxf/.settings/org.eclipse.jdt.core.prefs | 9 +++++---- java/libraries/net/.settings/org.eclipse.jdt.core.prefs | 8 +++++--- java/libraries/pdf/.settings/org.eclipse.jdt.core.prefs | 8 +++++--- .../serial/.settings/org.eclipse.jdt.core.prefs | 9 +++++---- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/java/libraries/dxf/.settings/org.eclipse.jdt.core.prefs b/java/libraries/dxf/.settings/org.eclipse.jdt.core.prefs index 2770cf1bf3..87b7a7a3a6 100644 --- a/java/libraries/dxf/.settings/org.eclipse.jdt.core.prefs +++ b/java/libraries/dxf/.settings/org.eclipse.jdt.core.prefs @@ -1,12 +1,13 @@ -#Sat Nov 12 10:56:00 CST 2011 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/java/libraries/net/.settings/org.eclipse.jdt.core.prefs b/java/libraries/net/.settings/org.eclipse.jdt.core.prefs index a11eccb8d4..f256b10aad 100644 --- a/java/libraries/net/.settings/org.eclipse.jdt.core.prefs +++ b/java/libraries/net/.settings/org.eclipse.jdt.core.prefs @@ -1,14 +1,16 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=18 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/java/libraries/pdf/.settings/org.eclipse.jdt.core.prefs b/java/libraries/pdf/.settings/org.eclipse.jdt.core.prefs index f3b4e11d65..160529e9d0 100644 --- a/java/libraries/pdf/.settings/org.eclipse.jdt.core.prefs +++ b/java/libraries/pdf/.settings/org.eclipse.jdt.core.prefs @@ -1,14 +1,16 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=18 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/java/libraries/serial/.settings/org.eclipse.jdt.core.prefs b/java/libraries/serial/.settings/org.eclipse.jdt.core.prefs index f709eac1ee..87b7a7a3a6 100644 --- a/java/libraries/serial/.settings/org.eclipse.jdt.core.prefs +++ b/java/libraries/serial/.settings/org.eclipse.jdt.core.prefs @@ -1,12 +1,13 @@ -#Sat Nov 12 10:56:44 CST 2011 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 From f62b931a30373d1b404ff6579935b92506f503f3 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 18 Jan 2019 09:55:51 -0800 Subject: [PATCH 14/21] remove unnecessary cast --- core/src/processing/core/PApplet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index ca37ca75ae..f4f5d97c6b 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -2455,7 +2455,7 @@ public void handleDraw() { // Get the frame time of the last frame double frameTimeSecs = (now - frameRateLastNanos) / 1e9; // Convert average frames per second to average frame time - double avgFrameTimeSecs = 1.0 / (double) frameRate; + double avgFrameTimeSecs = 1.0 / frameRate; // Calculate exponential moving average of frame time final double alpha = 0.05; avgFrameTimeSecs = (1.0 - alpha) * avgFrameTimeSecs + alpha * frameTimeSecs; From adaf90196bc660ac3537f5d5729852351866023c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 18 Jan 2019 10:35:39 -0800 Subject: [PATCH 15/21] incorporating console collapse button (#5115) --- app/src/processing/app/ui/EditorStatus.java | 84 ++++++++++++--------- todo.txt | 18 ++--- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/app/src/processing/app/ui/EditorStatus.java b/app/src/processing/app/ui/EditorStatus.java index c4db92bae2..481cea81df 100644 --- a/app/src/processing/app/ui/EditorStatus.java +++ b/app/src/processing/app/ui/EditorStatus.java @@ -49,7 +49,7 @@ /** * Panel just below the editing area that contains status messages. */ -public class EditorStatus extends BasicSplitPaneDivider { //JPanel { +public class EditorStatus extends BasicSplitPaneDivider { static final int HIGH = Toolkit.zoom(28); static final int LEFT_MARGIN = Editor.LEFT_GUTTER; static final int RIGHT_MARGIN = Toolkit.zoom(20); @@ -60,11 +60,11 @@ public class EditorStatus extends BasicSplitPaneDivider { //JPanel { Image[] bgImage; @SuppressWarnings("hiding") - static public final int ERROR = 1; + static public final int ERROR = 1; static public final int CURSOR_LINE_ERROR = 2; static public final int WARNING = 3; static public final int CURSOR_LINE_WARNING = 4; - static public final int NOTICE = 0; + static public final int NOTICE = 0; static final int YES = 1; static final int NO = 2; @@ -80,21 +80,36 @@ public class EditorStatus extends BasicSplitPaneDivider { //JPanel { int rightEdge; int mouseX; int rolloverState; - static final int ROLLOVER_NONE = 0; - static final int ROLLOVER_URL = 1; - static final int ROLLOVER_COLLAPSE = 2; - static final int ROLLOVER_EMOJI = 3; + static final int ROLLOVER_NONE = 0; + static final int ROLLOVER_URL = 1; + static final int ROLLOVER_COLLAPSE = 2; + static final int ROLLOVER_CLIPBOARD = 3; Font font; FontMetrics metrics; int ascent; - // used to draw the clipboard icon - Font emojiFont; + // actual Clipboard character not available [fry 180326] + //static final String CLIPBOARD_GLYPH = "\uD83D\uDCCB"; + // other apps seem to use this one as a hack + static final String CLIPBOARD_GLYPH = "\u2398"; + +// static final String COLLAPSE_GLYPH = "\u25B3"; // large up +// static final String EXPAND_GLYPH = "\u25BD"; // large down +// static final String COLLAPSE_GLYPH = "\u25B5"; // small up (unavailable) +// static final String EXPAND_GLYPH = "\u25BF"; // small down (unavailable) + static final String COLLAPSE_GLYPH = "\u25C1"; // left + static final String EXPAND_GLYPH = "\u25B7"; // right +// static final String COLLAPSE_GLYPH = "\u25F8"; // upper-left (unavailable) +// static final String EXPAND_GLYPH = "\u25FF"; // lower-right (unavailable) + + // a font that supports the Unicode glyphs we need + Font glyphFont; Image offscreen; int sizeW, sizeH; - boolean collapseState = false; + int buttonSize; + boolean collapsed = false; int response; @@ -120,7 +135,7 @@ public void mousePressed(MouseEvent e) { if (rolloverState == ROLLOVER_URL) { Platform.openURL(url); - } else if (rolloverState == ROLLOVER_EMOJI) { + } else if (rolloverState == ROLLOVER_CLIPBOARD) { if (e.isShiftDown()) { // open the text in a browser window as a search final String fmt = Preferences.get("search.format"); @@ -135,7 +150,7 @@ public void mousePressed(MouseEvent e) { } } else if (rolloverState == ROLLOVER_COLLAPSE) { - collapse(!collapseState); + setCollapsed(!collapsed); } } @@ -153,7 +168,7 @@ public void mouseDragged(MouseEvent e) { // BasicSplitPaneUI.startDragging gets called even when you click but // don't drag, so we can't expand the console whenever that gets called // or the button wouldn't work. - collapse(false); + setCollapsed(false); } @Override @@ -165,17 +180,18 @@ public void mouseMoved(MouseEvent e) { } - void collapse(boolean doCollapse) { - if (collapseState == doCollapse) return; - collapseState = doCollapse; - editor.footer.setVisible(!doCollapse); - splitPane.resetToPreferredSizes(); + void setCollapsed(boolean newState) { + if (collapsed != newState) { + collapsed = newState; + editor.footer.setVisible(!newState); + splitPane.resetToPreferredSizes(); + } } void updateMouse() { switch (rolloverState) { - case ROLLOVER_EMOJI: + case ROLLOVER_CLIPBOARD: case ROLLOVER_URL: setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); break; @@ -229,8 +245,7 @@ public void updateMode() { }; font = mode.getFont("status.font"); - //emojiFont = new Font("Dialog", Font.PLAIN, 21); - emojiFont = mode.getFont("status.emoji.font"); + glyphFont = mode.getFont("status.emoji.font"); metrics = null; } @@ -319,7 +334,7 @@ public void paint(Graphics screen) { if (offscreen == null) { sizeW = size.width; sizeH = size.height; - +// buttonSize = sizeH; offscreen = Toolkit.offscreenGraphics(this, sizeW, sizeH); } @@ -339,7 +354,7 @@ public void paint(Graphics screen) { rolloverState = ROLLOVER_COLLAPSE; } else if (message != null && !message.isEmpty()) { if (sizeW - 2*sizeH < mouseX) { - rolloverState = ROLLOVER_EMOJI; + rolloverState = ROLLOVER_CLIPBOARD; } else if (url != null && mouseX > LEFT_MARGIN && // calculate right edge of the text for rollovers (otherwise the pane // cannot be resized up or down whenever a URL is being displayed) @@ -377,29 +392,29 @@ public void paint(Graphics screen) { } } else if (!message.isEmpty()) { - g.setFont(emojiFont); - // actual Clipboard character not available [fry 180326] - //g.drawString("\uD83D\uDCCB", sizeW - LEFT_MARGIN, (sizeH + ascent) / 2); - // other apps seem to use this one as a hack: ⎘ - drawButton(g, "\u2398", 1, rolloverState == ROLLOVER_EMOJI); + g.setFont(glyphFont); + drawButton(g, CLIPBOARD_GLYPH, 1, rolloverState == ROLLOVER_CLIPBOARD); g.setFont(font); } // draw collapse/expand button - drawButton(g, collapseState ? "▲" : "▼", 0, rolloverState == ROLLOVER_COLLAPSE); + String collapseGlyph = collapsed ? EXPAND_GLYPH : COLLAPSE_GLYPH; + drawButton(g, collapseGlyph, 0, rolloverState == ROLLOVER_COLLAPSE); screen.drawImage(offscreen, 0, 0, sizeW, sizeH, null); } - private final Color whitishTint = new Color(0x40eeeeee, true); + private final Color whitishTint = new Color(0x20eeeeee, true); + /** * @param pos A zero-based index with 0 on the right. */ private void drawButton(Graphics g, String symbol, int pos, boolean highlight) { int left = sizeW - (pos + 1) * sizeH; - g.setColor(bgColor[mode]); // Overlap very long errors. - g.fillRect(left, 0, sizeH, sizeH); + // Overlap very long errors + g.drawImage(bgImage[mode], left, 0, sizeH, sizeH, this); + if (highlight) { g.setColor(whitishTint); g.fillRect(left, 0, sizeH, sizeH); @@ -408,10 +423,11 @@ private void drawButton(Graphics g, String symbol, int pos, boolean highlight) { g.setColor(fgColor[mode]); } g.drawString(symbol, - left + (sizeH - g.getFontMetrics().stringWidth(symbol))/2, - (sizeH + ascent) / 2); + left + (sizeH - g.getFontMetrics().stringWidth(symbol))/2, + (sizeH + ascent) / 2); } + public Dimension getPreferredSize() { return getMinimumSize(); } diff --git a/todo.txt b/todo.txt index 1d586c976b..ef4c3b4a17 100755 --- a/todo.txt +++ b/todo.txt @@ -14,22 +14,19 @@ X https://github.com/processing/processing/pull/5636 X Examples dialog causes high CPU load X https://github.com/processing/processing/issues/5246 X https://github.com/processing/processing/pull/5654 + +jakub +X Fix sketch exception getting hidden by warning +X https://github.com/processing/processing/pull/5486 +X https://github.com/processing/processing/issues/5412 + + _ Find in Reference disabled for various keywords (draw, for, if, catch, while) _ https://github.com/processing/processing/issues/5562 _ https://github.com/processing/processing/pull/5642 _ discuss with Casey - _ Welcome screen doesn't size properly for HiDPI screens _ https://github.com/processing/processing/issues/4896 -_ Find in Reference disabled for various keywords (draw, for, if, catch, while) -_ https://github.com/processing/processing/issues/5562 -_ "Could not find a examples in the downloaded file" is a poorly worded message - - -jakub -_ Fix sketch exception getting hidden by warning -_ https://github.com/processing/processing/pull/5486 -_ https://github.com/processing/processing/issues/5412 manager @@ -48,6 +45,7 @@ _ mode > add mode > libraries > install video _ did not update the examples window, had to restart pde _ was able to save over the video capture examples b/c they were a library _ lib examples not properly marked as read-only +_ "Could not find a examples in the downloaded file" is a poorly worded message temp From 06666edc7386ff949939da44c5a1d1e20bd23817 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 18 Jan 2019 10:47:01 -0800 Subject: [PATCH 16/21] more cleanup; use buttonSize constant instead of sizeH for clarity --- app/src/processing/app/ui/EditorStatus.java | 51 +++++++++++---------- todo.txt | 37 +++++++-------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/app/src/processing/app/ui/EditorStatus.java b/app/src/processing/app/ui/EditorStatus.java index 481cea81df..db77a932c0 100644 --- a/app/src/processing/app/ui/EditorStatus.java +++ b/app/src/processing/app/ui/EditorStatus.java @@ -66,10 +66,10 @@ public class EditorStatus extends BasicSplitPaneDivider { static public final int CURSOR_LINE_WARNING = 4; static public final int NOTICE = 0; - static final int YES = 1; - static final int NO = 2; + static final int YES = 1; + static final int NO = 2; static final int CANCEL = 3; - static final int OK = 4; + static final int OK = 4; Editor editor; @@ -77,13 +77,15 @@ public class EditorStatus extends BasicSplitPaneDivider { String message = ""; String url; + int rightEdge; int mouseX; - int rolloverState; - static final int ROLLOVER_NONE = 0; - static final int ROLLOVER_URL = 1; - static final int ROLLOVER_COLLAPSE = 2; + + static final int ROLLOVER_NONE = 0; + static final int ROLLOVER_URL = 1; + static final int ROLLOVER_COLLAPSE = 2; static final int ROLLOVER_CLIPBOARD = 3; + int rolloverState; Font font; FontMetrics metrics; @@ -94,6 +96,7 @@ public class EditorStatus extends BasicSplitPaneDivider { // other apps seem to use this one as a hack static final String CLIPBOARD_GLYPH = "\u2398"; + // https://en.wikipedia.org/wiki/Geometric_Shapes // static final String COLLAPSE_GLYPH = "\u25B3"; // large up // static final String EXPAND_GLYPH = "\u25BD"; // large down // static final String COLLAPSE_GLYPH = "\u25B5"; // small up (unavailable) @@ -108,6 +111,7 @@ public class EditorStatus extends BasicSplitPaneDivider { Image offscreen; int sizeW, sizeH; + // size of the glyph buttons (width and height are identical) int buttonSize; boolean collapsed = false; @@ -334,7 +338,7 @@ public void paint(Graphics screen) { if (offscreen == null) { sizeW = size.width; sizeH = size.height; -// buttonSize = sizeH; + buttonSize = sizeH; offscreen = Toolkit.offscreenGraphics(this, sizeW, sizeH); } @@ -349,27 +353,25 @@ public void paint(Graphics screen) { g.drawImage(bgImage[mode], 0, 0, sizeW, sizeH, this); - // What's the mouse over? - if (sizeW - sizeH < mouseX && mouseX < sizeW) { + rolloverState = ROLLOVER_NONE; + if (mouseX > sizeW - buttonSize && mouseX < sizeW) { rolloverState = ROLLOVER_COLLAPSE; + } else if (message != null && !message.isEmpty()) { - if (sizeW - 2*sizeH < mouseX) { + if (sizeW - 2*buttonSize < mouseX) { rolloverState = ROLLOVER_CLIPBOARD; + } else if (url != null && mouseX > LEFT_MARGIN && // calculate right edge of the text for rollovers (otherwise the pane // cannot be resized up or down whenever a URL is being displayed) mouseX < (LEFT_MARGIN + g.getFontMetrics().stringWidth(message))) { rolloverState = ROLLOVER_URL; - } else { - rolloverState = ROLLOVER_NONE; } - } else { - rolloverState = ROLLOVER_NONE; } // https://github.com/processing/processing/issues/3265 if (message != null) { - // needs to be set each time on osx + // font needs to be set each time on osx g.setFont(font); // set the highlight color on rollover so that the user's not surprised // to see the web browser open when they click @@ -381,7 +383,7 @@ public void paint(Graphics screen) { //int x = cancelButton.getX(); //int w = cancelButton.getWidth(); int w = Toolkit.getButtonWidth(); - int x = getWidth() - Math.max(RIGHT_MARGIN, (int)(sizeH*1.2)) - w; + int x = getWidth() - Math.max(RIGHT_MARGIN, (int)(buttonSize*1.2)) - w; int y = sizeH / 3; int h = sizeH / 3; g.setColor(new Color(0x80000000, true)); @@ -405,25 +407,26 @@ public void paint(Graphics screen) { } - private final Color whitishTint = new Color(0x20eeeeee, true); + //private final Color whitishTint = new Color(0x20eeeeee, true); /** - * @param pos A zero-based index with 0 on the right. + * @param pos A zero-based button index with 0 as the rightmost button */ private void drawButton(Graphics g, String symbol, int pos, boolean highlight) { - int left = sizeW - (pos + 1) * sizeH; + int left = sizeW - (pos + 1) * buttonSize; // Overlap very long errors - g.drawImage(bgImage[mode], left, 0, sizeH, sizeH, this); + g.drawImage(bgImage[mode], left, 0, buttonSize, sizeH, this); if (highlight) { - g.setColor(whitishTint); - g.fillRect(left, 0, sizeH, sizeH); + // disabling since this doesn't match any of our other UI +// g.setColor(whitishTint); +// g.fillRect(left, 0, sizeH, sizeH); g.setColor(urlColor); } else { g.setColor(fgColor[mode]); } g.drawString(symbol, - left + (sizeH - g.getFontMetrics().stringWidth(symbol))/2, + left + (buttonSize - g.getFontMetrics().stringWidth(symbol))/2, (sizeH + ascent) / 2); } diff --git a/todo.txt b/todo.txt index ef4c3b4a17..282ef20b5d 100755 --- a/todo.txt +++ b/todo.txt @@ -14,6 +14,8 @@ X https://github.com/processing/processing/pull/5636 X Examples dialog causes high CPU load X https://github.com/processing/processing/issues/5246 X https://github.com/processing/processing/pull/5654 +X console hiding button +X https://github.com/processing/processing/pull/5115 jakub X Fix sketch exception getting hidden by warning @@ -29,6 +31,19 @@ _ Welcome screen doesn't size properly for HiDPI screens _ https://github.com/processing/processing/issues/4896 +nasty ones +_ errors inside setup() aren't coming through at all? +_ seen in Eclipse; have to turn on the debugger +_ "Sketch disappeared" infinite pop up dialogs +_ https://github.com/processing/processing/pull/4808 +_ https://github.com/processing/processing/issues/4805 +_ EventQueue problems with "could not find sketch size" message +_ https://github.com/processing/processing/issues/4893 +_ https://github.com/processing/processing/issues/5030 +_ size(0, 0) just freezes instead of showing an error (as a result) +_ https://github.com/processing/processing/issues/5233 + + manager _ Manager fails to complete install of PythonMode when no windows open _ https://github.com/processing/processing/issues/5309 @@ -69,26 +84,6 @@ _ clean Windows temp folders _ https://github.com/processing/processing/issues/1896 -contrib -_ console hiding button? -_ https://github.com/processing/processing/pull/5115 -_ alternate handling of duplicate library conflicts -_ https://github.com/processing/processing/pull/5126 - - -nasty ones -_ errors inside setup() aren't coming through at all? -_ seen in Eclipse; have to turn on the debugger -_ "Sketch disappeared" infinite pop up dialogs -_ https://github.com/processing/processing/pull/4808 -_ https://github.com/processing/processing/issues/4805 -_ EventQueue problems with "could not find sketch size" message -_ https://github.com/processing/processing/issues/4893 -_ https://github.com/processing/processing/issues/5030 -_ size(0, 0) just freezes instead of showing an error (as a result) -_ https://github.com/processing/processing/issues/5233 - - _ sketch.properties not being written if initial mode is p5.js? _ when creating a sketch within non-Java mode, should write the settings file _ so that it re-loads in the proper environment @@ -709,6 +704,8 @@ _ see how library installation goes, then possibly do same w/ examples PDE / Libraries +_ alternate handling of duplicate library conflicts +_ https://github.com/processing/processing/pull/5126 _ Add a means to specify packages to import in library.properties _ https://github.com/processing/processing/issues/2134 _ need to deal with classpath conflicts From 07dfee2df44c4b4129dda3d380d1e243c049fe63 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 18 Jan 2019 11:05:54 -0800 Subject: [PATCH 17/21] update to Java 8u202 --- build/build.xml | 6 +++--- todo.txt | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/build/build.xml b/build/build.xml index a23317c813..fdd1d9a08a 100644 --- a/build/build.xml +++ b/build/build.xml @@ -71,11 +71,11 @@ value="../../processing-docs/content/examples" /> - - + + - + diff --git a/todo.txt b/todo.txt index 282ef20b5d..6b47d382e3 100755 --- a/todo.txt +++ b/todo.txt @@ -5,6 +5,7 @@ X https://github.com/processing/processing/issues/5375 X this is by design/follows PDE behavior X fix the link to the FAQ in the menu X https://github.com/processing/processing/issues/5729 +X update to Java 8u202 contrib X Updated russian translation, now can choose russian in preferences @@ -39,9 +40,10 @@ _ https://github.com/processing/processing/pull/4808 _ https://github.com/processing/processing/issues/4805 _ EventQueue problems with "could not find sketch size" message _ https://github.com/processing/processing/issues/4893 -_ https://github.com/processing/processing/issues/5030 -_ size(0, 0) just freezes instead of showing an error (as a result) -_ https://github.com/processing/processing/issues/5233 +X https://github.com/processing/processing/pull/5708 +X https://github.com/processing/processing/issues/5030 (duplicate) +_ size(0, 0) just freezes instead of showing an error +X https://github.com/processing/processing/issues/5233 (duplicate) manager From b3763a8f8072d93178cd435ebc6f4a3a0f94adb9 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 18 Jan 2019 11:19:28 -0800 Subject: [PATCH 18/21] prevent infinite "sketch disappeared" warnings (fixes #4805) --- app/src/processing/app/Sketch.java | 43 ++++++++++++++++++------------ todo.txt | 12 ++++----- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 40a3d7fb2b..15882dfb51 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -40,7 +40,9 @@ import java.beans.PropertyChangeListener; import java.io.*; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.*; @@ -1497,29 +1499,36 @@ public void prepareBuild(File targetFolder) throws SketchException { */ + private Set existenceWarnings = new HashSet<>(); + /** - * Make sure the sketch hasn't been moved or deleted by some - * nefarious user. If they did, try to re-create it and save. - * Only checks to see if the main folder is still around, - * but not its contents. + * Make sure the sketch hasn't been moved or deleted by a nefarious user. + * If they did, try to re-create it and save. Only checks whether the + * main folder is still around, but not its contents. */ public void ensureExistence() { if (!folder.exists()) { - // Disaster recovery, try to salvage what's there already. - Messages.showWarning(Language.text("ensure_exist.messages.missing_sketch"), - Language.text("ensure_exist.messages.missing_sketch.description")); - try { - folder.mkdirs(); - modified = true; + // Avoid an infinite loop if we've already warned about this + // https://github.com/processing/processing/issues/4805 + if (!existenceWarnings.contains(folder)) { + existenceWarnings.add(folder); + + // Disaster recovery, try to salvage what's there already. + Messages.showWarning(Language.text("ensure_exist.messages.missing_sketch"), + Language.text("ensure_exist.messages.missing_sketch.description")); + try { + folder.mkdirs(); + modified = true; + + for (int i = 0; i < codeCount; i++) { + code[i].save(); // this will force a save + } + calcModified(); - for (int i = 0; i < codeCount; i++) { - code[i].save(); // this will force a save + } catch (Exception e) { + Messages.showWarning(Language.text("ensure_exist.messages.unrecoverable"), + Language.text("ensure_exist.messages.unrecoverable.description"), e); } - calcModified(); - - } catch (Exception e) { - Messages.showWarning(Language.text("ensure_exist.messages.unrecoverable"), - Language.text("ensure_exist.messages.unrecoverable.description"), e); } } } diff --git a/todo.txt b/todo.txt index 6b47d382e3..a1f4d2dc01 100755 --- a/todo.txt +++ b/todo.txt @@ -22,6 +22,12 @@ jakub X Fix sketch exception getting hidden by warning X https://github.com/processing/processing/pull/5486 X https://github.com/processing/processing/issues/5412 +X EventQueue problems with "could not find sketch size" message +X https://github.com/processing/processing/issues/4893 +X https://github.com/processing/processing/pull/5708 +X https://github.com/processing/processing/issues/5030 (duplicate) +X size(0, 0) just freezes instead of showing an error +X https://github.com/processing/processing/issues/5233 (duplicate) _ Find in Reference disabled for various keywords (draw, for, if, catch, while) @@ -38,12 +44,6 @@ _ seen in Eclipse; have to turn on the debugger _ "Sketch disappeared" infinite pop up dialogs _ https://github.com/processing/processing/pull/4808 _ https://github.com/processing/processing/issues/4805 -_ EventQueue problems with "could not find sketch size" message -_ https://github.com/processing/processing/issues/4893 -X https://github.com/processing/processing/pull/5708 -X https://github.com/processing/processing/issues/5030 (duplicate) -_ size(0, 0) just freezes instead of showing an error -X https://github.com/processing/processing/issues/5233 (duplicate) manager From d1ce74b93d683e5e2b92dc366af033804c761695 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 18 Jan 2019 11:23:50 -0800 Subject: [PATCH 19/21] simpler solution for disappearance warning (#4805) --- app/src/processing/app/Sketch.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 15882dfb51..7d3caf8988 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -40,9 +40,7 @@ import java.beans.PropertyChangeListener; import java.io.*; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.*; @@ -93,6 +91,8 @@ public class Sketch { /** Moved out of Editor and into here for cleaner access. */ private boolean untitled; + /** true if we've posted a "sketch disappeared" warning */ + private boolean disappearedWarning; /** * Used by the command-line version to create a sketch object. @@ -125,6 +125,7 @@ protected void load(String path) { int suffixLength = mode.getDefaultExtension().length() + 1; name = mainFilename.substring(0, mainFilename.length() - suffixLength); folder = new File(new File(path).getParent()); + disappearedWarning = false; load(); } @@ -1199,6 +1200,7 @@ protected void updateInternal(String sketchName, File sketchFolder) { name = sketchName; folder = sketchFolder; + disappearedWarning = false; codeFolder = new File(folder, "code"); dataFolder = new File(folder, "data"); @@ -1499,8 +1501,6 @@ public void prepareBuild(File targetFolder) throws SketchException { */ - private Set existenceWarnings = new HashSet<>(); - /** * Make sure the sketch hasn't been moved or deleted by a nefarious user. * If they did, try to re-create it and save. Only checks whether the @@ -1510,8 +1510,8 @@ public void ensureExistence() { if (!folder.exists()) { // Avoid an infinite loop if we've already warned about this // https://github.com/processing/processing/issues/4805 - if (!existenceWarnings.contains(folder)) { - existenceWarnings.add(folder); + if (!disappearedWarning) { + disappearedWarning = true; // Disaster recovery, try to salvage what's there already. Messages.showWarning(Language.text("ensure_exist.messages.missing_sketch"), @@ -1526,6 +1526,7 @@ public void ensureExistence() { calcModified(); } catch (Exception e) { + // disappearedWarning prevents infinite loop in this scenario Messages.showWarning(Language.text("ensure_exist.messages.unrecoverable"), Language.text("ensure_exist.messages.unrecoverable.description"), e); } From 2e476be5962ff4f33ed8051187f34a11c82c1597 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 18 Jan 2019 11:25:11 -0800 Subject: [PATCH 20/21] wrapping up #4805 and #4808 --- todo.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/todo.txt b/todo.txt index a1f4d2dc01..22b0bcef19 100755 --- a/todo.txt +++ b/todo.txt @@ -6,6 +6,9 @@ X this is by design/follows PDE behavior X fix the link to the FAQ in the menu X https://github.com/processing/processing/issues/5729 X update to Java 8u202 +X "Sketch disappeared" infinite pop up dialogs +X https://github.com/processing/processing/pull/4808 +X https://github.com/processing/processing/issues/4805 contrib X Updated russian translation, now can choose russian in preferences @@ -41,9 +44,6 @@ _ https://github.com/processing/processing/issues/4896 nasty ones _ errors inside setup() aren't coming through at all? _ seen in Eclipse; have to turn on the debugger -_ "Sketch disappeared" infinite pop up dialogs -_ https://github.com/processing/processing/pull/4808 -_ https://github.com/processing/processing/issues/4805 manager From d1cb0c8b105df7d26bda5558d0affec3f1119a26 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 18 Jan 2019 11:44:12 -0800 Subject: [PATCH 21/21] additional cleanup to SVG code after incorporating #4168 --- core/src/processing/core/PShape.java | 19 +--- core/src/processing/core/PShapeSVG.java | 117 +++++++++++++----------- core/todo.txt | 24 +++-- todo.txt | 33 ++++--- 4 files changed, 96 insertions(+), 97 deletions(-) diff --git a/core/src/processing/core/PShape.java b/core/src/processing/core/PShape.java index 2010bf8ff5..b587e3e9b0 100644 --- a/core/src/processing/core/PShape.java +++ b/core/src/processing/core/PShape.java @@ -25,24 +25,13 @@ import java.awt.Image; import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; -import java.util.Base64.Decoder; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.nio.charset.StandardCharsets; + import javax.swing.ImageIcon; import javax.xml.bind.DatatypeConverter; - -import processing.core.PApplet; - - /** * ( begin auto-generated from PShape.xml ) * @@ -1910,7 +1899,7 @@ private void loadImage(PGraphics g){ } this.imagePath = null; } - + private void loadFileSystemImage(PGraphics g){ imagePath = imagePath.substring(7); PImage loadedImage = g.parent.loadImage(imagePath); @@ -1932,7 +1921,7 @@ private void loadBase64Image(){ System.err.println("Decode Error on image: " + imagePath.substring(0, 20)); return; } - + Image awtImage = new ImageIcon(decodedBytes).getImage(); if (awtImage instanceof BufferedImage) { @@ -1953,7 +1942,7 @@ private void loadBase64Image(){ extension.equals("unknown")) { loadedImage.checkAlpha(); } - + setTexture(loadedImage); } diff --git a/core/src/processing/core/PShapeSVG.java b/core/src/processing/core/PShapeSVG.java index 10f75ebd6a..d74253af6e 100644 --- a/core/src/processing/core/PShapeSVG.java +++ b/core/src/processing/core/PShapeSVG.java @@ -334,7 +334,7 @@ protected PShape parseChild(XML elem) { } else if (name.equals("rect")) { shape = createShape(this, elem, true); shape.parseRect(); - + } else if (name.equals("image")) { shape = createShape(this, elem, true); shape.parseImage(); @@ -368,8 +368,8 @@ protected PShape parseChild(XML elem) { } else if (name.equals("text")) { // || name.equals("font")) { return new Text(this, elem); - - } else if (name.equals("tspan")) { + + } else if (name.equals("tspan")) { return new LineOfText(this, elem); } else if (name.equals("filter")) { @@ -450,8 +450,8 @@ protected void parseRect() { getFloatWithUnit(element, "height", svgHeight) }; } - - + + protected void parseImage() { kind = RECT; textureMode = NORMAL; @@ -466,7 +466,7 @@ protected void parseImage() { this.imagePath = element.getString("xlink:href"); } - + /** * Parse a polyline or polygon from an SVG file. * Syntax defined at http://www.w3.org/TR/SVG/shapes.html#PointsBNF @@ -1537,7 +1537,10 @@ public Gradient(PShapeSVG parent, XML properties) { } - public class LinearGradient extends Gradient { + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + static public class LinearGradient extends Gradient { public float x1, y1, x2, y2; public LinearGradient(PShapeSVG parent, XML properties) { @@ -1567,7 +1570,10 @@ public LinearGradient(PShapeSVG parent, XML properties) { } - public class RadialGradient extends Gradient { + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + static public class RadialGradient extends Gradient { public float cx, cy, r; public RadialGradient(PShapeSVG parent, XML properties) { @@ -1596,23 +1602,22 @@ public RadialGradient(PShapeSVG parent, XML properties) { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - public static float TEXT_QUALITY = 1; - protected PFont parseFont(XML properties) { -// FontFace fontFace = new FontFace(this, properties); + +// static private float TEXT_QUALITY = 1; + + static private PFont parseFont(XML properties) { String fontFamily = null; float size = 10; int weight = PLAIN; // 0 int italic = 0; - + if (properties.hasAttribute("style")) { String styleText = properties.getString("style"); String[] styleTokens = PApplet.splitTokens(styleText, ";"); //PApplet.println(styleTokens); for (int i = 0; i < styleTokens.length; i++) { - String[] tokens = PApplet.splitTokens(styleTokens[i], ":"); //PApplet.println(tokens); @@ -1628,13 +1633,13 @@ protected PFont parseFont(XML properties) { // setFillOpacity(tokens[1]); } else if (tokens[0].equals("font-weight")) { - // PApplet.println("font-weight: " + tokens[1]); - - if (tokens[1].contains("bold")) { - weight = BOLD; - // PApplet.println("Bold weight ! "); - } - + // PApplet.println("font-weight: " + tokens[1]); + + if (tokens[1].contains("bold")) { + weight = BOLD; + // PApplet.println("Bold weight ! "); + } + } else if (tokens[0].equals("font-stretch")) { // not supported. @@ -1673,25 +1678,26 @@ protected PFont parseFont(XML properties) { if (fontFamily == null) { return null; } - size = size * TEXT_QUALITY; +// size = size * TEXT_QUALITY; return createFont(fontFamily, weight | italic, size, true); } - protected PFont createFont(String name, int weight, float size, boolean smooth) { - -// System.out.println("Try to create a font of " + name + " family, " + weight); - java.awt.Font baseFont = new java.awt.Font(name, weight, (int) size); // PFont.findFont(name);ç -// System.out.println("Resulting family : " + baseFont.getFamily() + " " + baseFont.getStyle()); - PFont outputPFont = new PFont(baseFont.deriveFont(size), smooth, null); + static protected PFont createFont(String name, int weight, + float size, boolean smooth) { + //System.out.println("Try to create a font of " + name + " family, " + weight); + java.awt.Font baseFont = new java.awt.Font(name, weight, (int) size); -// System.out.println("Resulting PFont family : " + outputPFont.getName()); - return outputPFont; + //System.out.println("Resulting family : " + baseFont.getFamily() + " " + baseFont.getStyle()); + return new PFont(baseFont.deriveFont(size), smooth, null); } - public static class Text extends PShapeSVG { + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + static public class Text extends PShapeSVG { protected PFont font; public Text(PShapeSVG parent, XML properties) { @@ -1709,43 +1715,40 @@ public Text(PShapeSVG parent, XML properties) { family = GROUP; font = parseFont(properties); - } - -// @Override -// public void drawImpl(PGraphics g){ -// } } - public static class LineOfText extends PShapeSVG { + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + static public class LineOfText extends PShapeSVG { String textToDisplay; PFont font; public LineOfText(PShapeSVG parent, XML properties) { - - // TODO: child should ideally be parsed too... - // for inline content. + // TODO: child should ideally be parsed too for inline content. super(parent, properties, false); -// // get location + //get location float x = Float.parseFloat(properties.getString("x")); float y = Float.parseFloat(properties.getString("y")); float parentX = Float.parseFloat(parent.element.getString("x")); float parentY = Float.parseFloat(parent.element.getString("y")); - + if (matrix == null) matrix = new PMatrix2D(); matrix.translate(x - parentX, (y - parentY) / 2f); - - // get the first properties - parseColors(properties); + + // get the first properties + parseColors(properties); font = parseFont(properties); - // It is a line.. - boolean isALine = properties.getString("role") == "line"; - // NO inline content yet. + // cleaned up syntax but removing b/c unused [fry 190118] + //boolean isLine = properties.getString("role").equals("line"); + if (this.childCount > 0) { + // no inline content yet. } String text = properties.getContent(); @@ -1762,14 +1765,18 @@ public void drawImpl(PGraphics g) { } pre(g); - g.textFont(font, font.size / TEXT_QUALITY); +// g.textFont(font, font.size / TEXT_QUALITY); + g.textFont(font, font.size); g.text(textToDisplay, 0, 0); post(g); } - } - - public static class Font extends PShapeSVG { + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + static public class Font extends PShapeSVG { public FontFace face; public Map namedGlyphs; @@ -1790,8 +1797,8 @@ public Font(PShapeSVG parent, XML properties) { horizAdvX = properties.getInt("horiz-adv-x", 0); - namedGlyphs = new HashMap(); - unicodeGlyphs = new HashMap(); + namedGlyphs = new HashMap<>(); + unicodeGlyphs = new HashMap<>(); glyphCount = 0; glyphs = new FontGlyph[elements.length]; @@ -1920,7 +1927,7 @@ protected void drawShape() { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - public static class FontGlyph extends PShapeSVG { // extends Path + static public class FontGlyph extends PShapeSVG { // extends Path public String name; char unicode; int horizAdvX; diff --git a/core/todo.txt b/core/todo.txt index 04f84f551d..42c1e0aefc 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -11,9 +11,8 @@ X had to back this fix out again X Fixes blend mode not being set correctly, fixing #5645 X https://github.com/processing/processing/issues/5645 X https://github.com/processing/processing/pull/5647 -_ NullPointerException in Contribution Manager -_ https://github.com/processing/processing/issues/5524 -_ https://github.com/processing/processing/pull/5742 +X extended SVG support +X https://github.com/processing/processing/pull/4168 gohai X Profile GL3bc is not available on X11GraphicsDevice @@ -47,6 +46,11 @@ X https://github.com/processing/processing/pull/5698 X Recreate FBOs when offscreen PGraphicsOpenGL is resized X https://github.com/processing/processing/pull/5699 +cleaning +o WARNING: GL pipe is running in software mode (Renderer ID=0x1020400) +o is this coming from us? if so, need to provide actions +X haven't seen for a while, maybe fixed + _ NullPointerException at java.awt.Window.init(Window.java:497) when using Airplay _ https://github.com/processing/processing/issues/5620 @@ -72,8 +76,6 @@ _ create icon.png or have an 'icons' folder with multiple sizes contribs -_ extended SVG support -_ https://github.com/processing/processing/pull/4168 _ show a warning when a font isn't what the user expected _ https://github.com/processing/processing/issues/5481 _ https://github.com/processing/processing/pull/5605 @@ -89,20 +91,12 @@ _ Switch to getModifiersEx() and fix the AWT modifiers used in PSurfaceAWT _ this is an easy fix, but need to check impact elsewhere _ does anything else rely on these modifiers? -_ Fix Java 9 incompatibilities inside PSurfaceFX -_ https://github.com/processing/processing/issues/5286 - -_ Hitting ESC in FX2D app on macOS throws IllegalStateException -_ https://github.com/processing/processing/issues/5249 _ when doing createFont, can we add it to the os fonts available? _ add separator option to loadTable() _ https://github.com/processing/processing/issues/5068 -_ WARNING: GL pipe is running in software mode (Renderer ID=0x1020400) -_ is this coming from us? if so, need to provide actions - _ implement sketch scaling into PApplet _ https://github.com/processing/processing/issues/4897 _ Sketches on Windows don't take UI sizing into account @@ -165,6 +159,10 @@ _ https://github.com/processing/processing/issues/3753 javafx +_ Fix Java 11 incompatibilities inside PSurfaceFX +_ https://github.com/processing/processing/issues/5286 +_ Hitting ESC in FX2D app on macOS throws IllegalStateException +_ https://github.com/processing/processing/issues/5249 _ wrong window size with fullScreen() _ https://github.com/processing/processing/issues/4737 _ menu bar not hiding properly in exported applications with FX2D diff --git a/todo.txt b/todo.txt index 22b0bcef19..7db71da76a 100755 --- a/todo.txt +++ b/todo.txt @@ -10,6 +10,13 @@ X "Sketch disappeared" infinite pop up dialogs X https://github.com/processing/processing/pull/4808 X https://github.com/processing/processing/issues/4805 +fixed earlier +X Could not initialize class com.sun.jna.Native on startup (Windows) +X https://github.com/processing/processing/issues/4929 +X closed earlier; fixed as best we could +X sharing usage metrics about libraries +X https://github.com/processing/processing/issues/4708 + contrib X Updated russian translation, now can choose russian in preferences X https://github.com/processing/processing/pull/5619 @@ -20,6 +27,9 @@ X https://github.com/processing/processing/issues/5246 X https://github.com/processing/processing/pull/5654 X console hiding button X https://github.com/processing/processing/pull/5115 +_ NullPointerException in Contribution Manager +_ https://github.com/processing/processing/issues/5524 +_ https://github.com/processing/processing/pull/5742 jakub X Fix sketch exception getting hidden by warning @@ -111,9 +121,6 @@ _ see the 'examples' section below _ how are file associations handled in Linux? (for .pde, .psk) -_ Could not initialize class com.sun.jna.Native on startup (Windows) -_ https://github.com/processing/processing/issues/4929 - _ implement fallback fonts instead of giving up and using Dialog and Mono _ https://github.com/processing/processing/issues/5023 @@ -156,11 +163,6 @@ _ https://github.com/processing/processing/issues/1476#issuecomment-23229990 _ could not write to temporary directory (virus checker problems) _ https://github.com/processing/processing/issues/4757 -_ Export Application fails on machines w/ non-ASCII chars in user name -_ at least give a warning about this? -_ https://github.com/processing/processing/issues/4736 -_ related: https://github.com/processing/processing/issues/3543 - _ fix appbundler problems due to rollback _ https://github.com/processing/processing/issues/3790 _ the rollback re-introduces two bugs (serial export and scrolling) @@ -176,9 +178,6 @@ _ https://github.com/processing/processing/issues/4703 _ right bracket missing error _ https://github.com/processing/processing/issues/4702 -_ sharing usage metrics about libraries -_ https://github.com/processing/processing/issues/4708 - _ library compilations handled oddly _ https://github.com/processing/processing/issues/4630 @@ -222,17 +221,19 @@ _ https://github.com/processing/processing/pull/4097 _ solution is to create a sprite sheet as a psd that'll have better type _ no way we're gonna fix the sizing and spacing for all platforms -_ need docs for translations -_ https://github.com/processing/processing/issues/4018 _ setting a bad font/size causes a crash on startup _ https://github.com/processing/processing/issues/4085 o https://github.com/processing/processing/pull/4087 -more contribs +translations +_ need docs for translations +_ https://github.com/processing/processing/issues/4018 _ question about PDE_pt-br instead of PDE_pt _ https://github.com/processing/processing/issues/4018 + +more contribs _ Saving sketch with the same name as a class _ https://github.com/processing/processing/pull/4033 _ Pasting text into PDE results in "Clipboard does not contain a string" @@ -245,6 +246,10 @@ _ but anything else reports "font sadness" b/c it's using the system JRE _ https://github.com/processing/processing/issues/3543 _ move to javapackager or another option? _ http://www.excelsiorjet.com/kb/35/howto-create-a-single-exe-from-your-java-application +_ Export Application fails on machines w/ non-ASCII chars in user name +_ at least give a warning about this? +_ https://github.com/processing/processing/issues/4736 +_ related: https://github.com/processing/processing/issues/3543 _ mouse events (i.e. toggle breakpoint) seem to be firing twice