From a8c9830f9a601dbb537f8ff927f45bb0cd53a7f5 Mon Sep 17 00:00:00 2001 From: Akarshit Wal Date: Mon, 28 Sep 2015 19:43:40 +0530 Subject: [PATCH 001/917] Added the remove filter feature --- .../app/contrib/ContributionTab.java | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/contrib/ContributionTab.java b/app/src/processing/app/contrib/ContributionTab.java index 9e005bc408..08f3655b44 100644 --- a/app/src/processing/app/contrib/ContributionTab.java +++ b/app/src/processing/app/contrib/ContributionTab.java @@ -23,6 +23,7 @@ package processing.app.contrib; import java.awt.Color; +import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; import java.awt.event.*; @@ -350,9 +351,9 @@ protected void setFilterText(String filter) { } - //TODO: this is causing a lot of bugs as the hint is wrongly firing applyFilter() class FilterField extends JTextField { Icon searchIcon; + JButton removeFilter; List filters; JLabel filterLabel; @@ -366,19 +367,40 @@ public FilterField () { setFont(Toolkit.getSansFont(14, Font.PLAIN)); searchIcon = Toolkit.getLibIconX("manager/search"); filterLabel.setIcon(searchIcon); + removeFilter = new JButton("X"); // TODO icon should be initialized here + removeFilter.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2)); + removeFilter.setBorderPainted(false); + removeFilter.setContentAreaFilled(false); + removeFilter.setCursor(Cursor.getDefaultCursor()); + removeFilter.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + setText(""); + filterField.requestFocusInWindow(); + } + }); //searchIcon = new ImageIcon(java.awt.Toolkit.getDefaultToolkit().getImage("NSImage://NSComputerTemplate")); setOpaque(false); //setBorder(BorderFactory.createMatteBorder(0, 33, 0, 0, searchIcon)); GroupLayout fl = new GroupLayout(this); setLayout(fl); - fl.setHorizontalGroup(fl.createSequentialGroup().addComponent(filterLabel)); + fl.setHorizontalGroup(fl + .createSequentialGroup() + .addComponent(filterLabel) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, + GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) + .addComponent(removeFilter)); + fl.setVerticalGroup(fl.createSequentialGroup() .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) + .addGroup(fl.createParallelGroup() .addComponent(filterLabel) + .addComponent(removeFilter)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)); + removeFilter.setVisible(false); filters = new ArrayList(); @@ -398,14 +420,17 @@ public void focusGained(FocusEvent focusEvent) { getDocument().addDocumentListener(new DocumentListener() { public void removeUpdate(DocumentEvent e) { + removeFilter.setVisible(!getText().isEmpty()); applyFilter(); } public void insertUpdate(DocumentEvent e) { + removeFilter.setVisible(!getText().isEmpty()); applyFilter(); } public void changedUpdate(DocumentEvent e) { + removeFilter.setVisible(!getText().isEmpty()); applyFilter(); } }); From 84e5ca16e6497affd0a9602a5d93487c3f933e2c Mon Sep 17 00:00:00 2001 From: Akarshit Wal Date: Thu, 1 Oct 2015 22:29:10 +0530 Subject: [PATCH 002/917] Core libraries added to the count of updates --- app/src/processing/app/contrib/ContributionListing.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/processing/app/contrib/ContributionListing.java b/app/src/processing/app/contrib/ContributionListing.java index cf35ff628c..bd3460d645 100644 --- a/app/src/processing/app/contrib/ContributionListing.java +++ b/app/src/processing/app/contrib/ContributionListing.java @@ -580,6 +580,11 @@ public int countUpdates(Base base) { count++; } } + for (Library lib : base.getActiveEditor().getMode().coreLibraries) { + if (hasUpdates(lib)) { + count++; + } + } for (ToolContribution tc : base.getToolContribs()) { if (hasUpdates(tc)) { count++; From 9aaba9717780155346b4baeed0f667d4b914e197 Mon Sep 17 00:00:00 2001 From: Akarshit Wal Date: Sun, 1 Nov 2015 04:20:53 +0530 Subject: [PATCH 003/917] fixes the removal of redundant contribution and update related issues --- app/src/processing/app/contrib/ListPanel.java | 17 +++++++++--- .../app/contrib/UpdateListPanel.java | 27 +++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index 3d9a4fa874..5d41c96989 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -488,7 +488,6 @@ public void run() { }); } - public void contributionChanged(final Contribution oldContrib, final Contribution newContrib) { // TODO: this should already be on EDT, check it [jv] @@ -515,15 +514,25 @@ public void run() { }); } - public void filterLibraries(List filteredContributions) { synchronized (visibleContributions) { visibleContributions.clear(); - for (Contribution contribution : filteredContributions) { + for (Contribution contribution : panelByContribution.keySet()) { if (contribution.getType() == contributionTab.contribType) { - visibleContributions.add(contribution); + if (filteredContributions.contains(contribution)) { + if (panelByContribution.keySet().contains(contribution)) { + visibleContributions.add(contribution); + } + } } } +// for (Contribution contribution : filteredContributions) { +// if (contribution.getType() == contributionTab.contribType) { +// if(panelByContribution.keySet().contains(contribution)){ +// visibleContributions.add(contribution); +// } +// } +// } updatePanelOrdering(visibleContributions); } } diff --git a/app/src/processing/app/contrib/UpdateListPanel.java b/app/src/processing/app/contrib/UpdateListPanel.java index f5d292fac0..f60fb9702e 100644 --- a/app/src/processing/app/contrib/UpdateListPanel.java +++ b/app/src/processing/app/contrib/UpdateListPanel.java @@ -229,6 +229,9 @@ public void run() { if (!panelByContribution.containsKey(contribution)) { panelByContribution.put(contribution, newPanel); } + synchronized (visibleContributions) { + visibleContributions.add(contribution); + } if (newPanel != null) { newPanel.setContribution(contribution); add(newPanel); @@ -240,4 +243,28 @@ public void run() { }); } } + + @Override + public void contributionChanged(final Contribution oldContrib, + final Contribution newContrib) { + // TODO: this should already be on EDT, check it [jv] + EventQueue.invokeLater(new Runnable() { + public void run() { + synchronized (panelByContribution) { + DetailPanel panel = panelByContribution.get(oldContrib); + if (panel == null) { + contributionAdded(newContrib); + } else { + panelByContribution.remove(oldContrib); + } + } + synchronized (visibleContributions) { + if (visibleContributions.contains(oldContrib)) { + visibleContributions.remove(oldContrib); + } + updatePanelOrdering(visibleContributions); + } + } + }); + } } \ No newline at end of file From cdce741623c8423101cd3ba77b6304378c18d264 Mon Sep 17 00:00:00 2001 From: Akarshit Wal Date: Sun, 1 Nov 2015 04:23:48 +0530 Subject: [PATCH 004/917] added few todos for future --- app/src/processing/app/contrib/ContributionListing.java | 2 ++ app/src/processing/app/contrib/ListPanel.java | 1 + 2 files changed, 3 insertions(+) diff --git a/app/src/processing/app/contrib/ContributionListing.java b/app/src/processing/app/contrib/ContributionListing.java index cf35ff628c..d24b71a5b6 100644 --- a/app/src/processing/app/contrib/ContributionListing.java +++ b/app/src/processing/app/contrib/ContributionListing.java @@ -51,6 +51,8 @@ public class ContributionListing { List advertisedContributions; Map> librariesByCategory; Map librariesByImportHeader; + // TODO: Every contribution is getting added twice + // and nothing is replaced ever. List allContributions; boolean listDownloaded; boolean listDownloadFailed; diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index 5d41c96989..e0b60650d4 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -526,6 +526,7 @@ public void filterLibraries(List filteredContributions) { } } } + // TODO: Make the following loop work for optimization // for (Contribution contribution : filteredContributions) { // if (contribution.getType() == contributionTab.contribType) { // if(panelByContribution.keySet().contains(contribution)){ From 0eb5ba518ac40343a68cef09a13ecf9c9e5ce0fe Mon Sep 17 00:00:00 2001 From: Jeremy Laviole Date: Tue, 24 Nov 2015 17:55:40 +0100 Subject: [PATCH 005/917] 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 9c04369f789b80dee0f8105ecb88cd2ab1e1e479 Mon Sep 17 00:00:00 2001 From: Akarshit Wal Date: Fri, 11 Dec 2015 11:21:26 +0530 Subject: [PATCH 006/917] Added the cross icon --- app/src/processing/app/contrib/ContributionTab.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/processing/app/contrib/ContributionTab.java b/app/src/processing/app/contrib/ContributionTab.java index 08f3655b44..129da5cda1 100644 --- a/app/src/processing/app/contrib/ContributionTab.java +++ b/app/src/processing/app/contrib/ContributionTab.java @@ -367,7 +367,7 @@ public FilterField () { setFont(Toolkit.getSansFont(14, Font.PLAIN)); searchIcon = Toolkit.getLibIconX("manager/search"); filterLabel.setIcon(searchIcon); - removeFilter = new JButton("X"); // TODO icon should be initialized here + removeFilter = new JButton(Toolkit.getLibIconX("manager/remove")); removeFilter.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2)); removeFilter.setBorderPainted(false); removeFilter.setContentAreaFilled(false); From 3bccc174b8f80f53fe08feb4e0b03eb975a591ec Mon Sep 17 00:00:00 2001 From: Suhaib Khan Date: Sat, 27 Feb 2016 21:51:32 +0530 Subject: [PATCH 007/917] Adding missing docs and keywords for TableRow. Signed-off-by: Suhaib Khan --- core/src/processing/data/TableRow.java | 79 +++++++++++++++++++++++--- java/keywords.txt | 9 +++ 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/core/src/processing/data/TableRow.java b/core/src/processing/data/TableRow.java index 87e288825f..9071c2af83 100644 --- a/core/src/processing/data/TableRow.java +++ b/core/src/processing/data/TableRow.java @@ -36,8 +36,17 @@ public interface TableRow { * @param columnName title of the column to reference */ public int getInt(String columnName); - + /** + * @webref tablerow:method + * @brief Get a long value from the specified column + * @param column ID number of the column to reference + * @see TableRow#getFloat(int) + * @see TableRow#getString(int) + */ public long getLong(int column); + /** + * @param columnName title of the column to reference + */ public long getLong(String columnName); /** @@ -52,8 +61,17 @@ public interface TableRow { * @param columnName title of the column to reference */ public float getFloat(String columnName); - + /** + * @webref tablerow:method + * @brief Get a double value from the specified column + * @param column ID number of the column to reference + * @see TableRow#getInt(int) + * @see TableRow#getString(int) + */ public double getDouble(int column); + /** + * @param columnName title of the column to reference + */ public double getDouble(String columnName); /** @@ -83,8 +101,18 @@ public interface TableRow { * @param columnName title of the target column */ public void setInt(String columnName, int value); - + /** + * @webref tablerow:method + * @brief Store a long value in the specified column + * @param column ID number of the target column + * @param value value to assign + * @see TableRow#setFloat(int, float) + * @see TableRow#setString(int, String) + */ public void setLong(int column, long value); + /** + * @param columnName title of the target column + */ public void setLong(String columnName, long value); /** @@ -100,16 +128,53 @@ public interface TableRow { * @param columnName title of the target column */ public void setFloat(String columnName, float value); - + /** + * @webref tablerow:method + * @brief Store a double value in the specified column + * @param column ID number of the target column + * @param value value to assign + * @see TableRow#setFloat(int, float) + * @see TableRow#setString(int, String) + */ public void setDouble(int column, double value); + /** + * @param columnName title of the target column + */ public void setDouble(String columnName, double value); - + /** + * @webref tablerow:method + * @brief Get the column count. + * @return count of all columns + */ public int getColumnCount(); + /** + * @webref tablerow:method + * @brief Get the column type. + * @param columnName title of the target column + * @return type of the column + */ public int getColumnType(String columnName); + /** + * @param column ID number of the target column + */ public int getColumnType(int column); - + /** + * @webref tablerow:method + * @brief Get the all column types. + * @return list of all column types + */ public int[] getColumnTypes(); - + /** + * @webref tablerow:method + * @brief Get the column title. + * @param column ID number of the target column + * @return title of the column + */ public String getColumnTitle(int column); + /** + * @webref tablerow:method + * @brief Get the all column titles. + * @return list of all column titles + */ public String[] getColumnTitles(); } diff --git a/java/keywords.txt b/java/keywords.txt index fb8da82ade..ad9bcdb183 100644 --- a/java/keywords.txt +++ b/java/keywords.txt @@ -866,9 +866,18 @@ TableRow KEYWORD5 TableRow getFloat FUNCTION2 TableRow_getFloat_ getInt FUNCTION2 TableRow_getInt_ getString FUNCTION2 TableRow_getString_ +getLong FUNCTION2 TableRow_getLong_ +getDouble FUNCTION2 TableRow_getDouble_ setFloat FUNCTION2 TableRow_setFloat_ setInt FUNCTION2 TableRow_setInt_ setString FUNCTION2 TableRow_setString_ +setLong FUNCTION2 TableRow_setLong_ +setDouble FUNCTION2 TableRow_setDouble_ +getColumnCount FUNCTION2 TableRow_getColumnCount_ +getColumnType FUNCTION2 TableRow_getColumnType_ +getColumnTypes FUNCTION2 TableRow_getColumnTypes_ +getColumnTitle FUNCTION2 TableRow_getColumnTitle_ +getColumnTitles FUNCTION2 TableRow_getColumnTitles_ tan FUNCTION1 tan_ TAU LITERAL2 TAU text FUNCTION1 text_ From 552650264e955cdc58691e754f9228946bb7ad30 Mon Sep 17 00:00:00 2001 From: Akarshit Wal Date: Sun, 28 Feb 2016 17:09:41 +0530 Subject: [PATCH 008/917] Changed the access modifier of get() --- core/src/processing/data/JSONArray.java | 2 +- core/src/processing/data/JSONObject.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/processing/data/JSONArray.java b/core/src/processing/data/JSONArray.java index 0ec016d3f9..b1c155f857 100644 --- a/core/src/processing/data/JSONArray.java +++ b/core/src/processing/data/JSONArray.java @@ -263,7 +263,7 @@ private Object opt(int index) { * @return An object value. * @throws JSONException If there is no value for the index. */ - private Object get(int index) { + public Object get(int index) { Object object = opt(index); if (object == null) { throw new RuntimeException("JSONArray[" + index + "] not found."); diff --git a/core/src/processing/data/JSONObject.java b/core/src/processing/data/JSONObject.java index 8b8d2f170d..cedf11e864 100644 --- a/core/src/processing/data/JSONObject.java +++ b/core/src/processing/data/JSONObject.java @@ -540,7 +540,7 @@ static protected String doubleToString(double d) { * @return The object associated with the key. * @throws JSONException if the key is not found. */ - private Object get(String key) { + public Object get(String key) { if (key == null) { throw new RuntimeException("Null key."); } From 14a1ba979199fe0ad2ddd6acda9c580886d316f7 Mon Sep 17 00:00:00 2001 From: Akarshit Wal Date: Sun, 28 Feb 2016 21:28:50 +0530 Subject: [PATCH 009/917] Changed the access modifier of put() and putOnce() --- core/src/processing/data/JSONObject.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/processing/data/JSONObject.java b/core/src/processing/data/JSONObject.java index cedf11e864..2d27c8f1fe 100644 --- a/core/src/processing/data/JSONObject.java +++ b/core/src/processing/data/JSONObject.java @@ -1302,7 +1302,7 @@ public JSONObject setJSONArray(String key, JSONArray value) { * @throws JSONException If the value is non-finite number * or if the key is null. */ - private JSONObject put(String key, Object value) { + public JSONObject put(String key, Object value) { String pooled; if (key == null) { throw new RuntimeException("Null key."); @@ -1335,7 +1335,7 @@ private JSONObject put(String key, Object value) { * @return his. * @throws JSONException if the key is a duplicate */ - private JSONObject putOnce(String key, Object value) { + public JSONObject putOnce(String key, Object value) { if (key != null && value != null) { if (this.opt(key) != null) { throw new RuntimeException("Duplicate key \"" + key + "\""); From 71cca0d46925b6fb2b877a786fe8400f5857b0f4 Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 27 May 2016 07:02:26 +0200 Subject: [PATCH 010/917] Decouple Editor fonts from JVM This makes it easier to run Processing with a custom or globally installed copy of the the VM, where before Processing wouldn't start because of missing fonts (font sadness). This proposal would add a second copy of the fonts to the Linux tar-ball, and fall back to this one as a last resort. I have only tested registerFont() on Linux, where it seems to be working (Font in TextAreaPainter.updateAppearance does not fall back to monospaced). On OS X this does not seem to work currently (UnsatisfiedLinkError: sun.font.FreetypeFontScaler.initIDs). --- app/src/processing/app/ui/Toolkit.java | 15 +++++++++++++++ build/build.xml | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index e30b9f98a5..8bc4d4b9c3 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -975,10 +975,14 @@ static public Font getSansFont(int size, int style) { * the Preferences window, and can be used by HTMLEditorKit for WebFrame). */ static private Font createFont(String filename, int size) throws IOException, FontFormatException { + boolean registerFont = false; + // Can't use Base.getJavaHome(), because if we're not using our local JRE, // we likely have bigger problems with how things are running. File fontFile = new File(System.getProperty("java.home"), "lib/fonts/" + filename); if (!fontFile.exists()) { + // any of the fallbacks below is a custom location, so try to register the font as well + registerFont = true; // if we're debugging from Eclipse, grab it from the work folder (user.dir is /app) fontFile = new File(System.getProperty("user.dir"), "../build/shared/lib/fonts/" + filename); } @@ -986,6 +990,10 @@ static private Font createFont(String filename, int size) throws IOException, Fo // if we're debugging the new Java Mode from Eclipse, paths are different fontFile = new File(System.getProperty("user.dir"), "../../shared/lib/fonts/" + filename); } + if (!fontFile.exists()) { + // this if for Linux, where we're shipping a second copy of the fonts outside of java + fontFile = Platform.getContentFile("lib/fonts/" + filename); + } if (!fontFile.exists()) { String msg = "Could not find required fonts. "; // This gets the JAVA_HOME for the *local* copy of the JRE installed with @@ -1003,6 +1011,13 @@ static private Font createFont(String filename, int size) throws IOException, Fo BufferedInputStream input = new BufferedInputStream(new FileInputStream(fontFile)); Font font = Font.createFont(Font.TRUETYPE_FONT, input); input.close(); + + // this makes Font() work for font files in custom locations + if (registerFont) { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + ge.registerFont(font); + } + return font.deriveFont((float) size); } diff --git a/build/build.xml b/build/build.xml index eaaf4dc94f..30c9b05b55 100644 --- a/build/build.xml +++ b/build/build.xml @@ -756,7 +756,10 @@ - + + + + From 9a678ee32caabafeabce3a784544c8775d10b148 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 27 Aug 2016 11:01:16 -0400 Subject: [PATCH 011/917] testing out a lookup function --- core/src/processing/data/Table.java | 24 ++++++++++++++++++++++-- core/todo.txt | 2 ++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index 5d86e45bbe..796491dc5b 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -4418,13 +4418,13 @@ public FloatDict getFloatDict(String keyColumnName, String valueColumnName) { public FloatDict getFloatDict(int keyColumn, int valueColumn) { return new FloatDict(getStringColumn(keyColumn), - getFloatColumn(valueColumn)); + getFloatColumn(valueColumn)); } public StringDict getStringDict(String keyColumnName, String valueColumnName) { return new StringDict(getStringColumn(keyColumnName), - getStringColumn(valueColumnName)); + getStringColumn(valueColumnName)); } @@ -4434,6 +4434,26 @@ public StringDict getStringDict(int keyColumn, int valueColumn) { } + public Map getRowMap(String columnName) { + int col = getColumnIndex(columnName); + return (col == -1) ? null : getRowMap(col); + } + + + public Map getRowMap(int column) { + Map outgoing = new HashMap<>(); + for (int row = 0; row < getRowCount(); row++) { + String id = getString(row, column); + outgoing.put(id, new RowPointer(this, row)); + } +// for (TableRow row : rows()) { +// String id = row.getString(column); +// outgoing.put(id, row); +// } + return outgoing; + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . diff --git a/core/todo.txt b/core/todo.txt index 6c82a318eb..aa0e230643 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,6 +1,8 @@ 0253 (3.2.1) X implement defaultUncaughtExceptionHandler X helps avoid needing to double-quit OS X applications +X add getRowMap() function +_ do we want rows() to not be transient? started From edd9ea36bb5551bce55d85350116efc23a987b96 Mon Sep 17 00:00:00 2001 From: gohai Date: Sun, 28 Aug 2016 16:31:15 +0200 Subject: [PATCH 012/917] Use fonts in lib/fonts instead of the JVM location for all OS --- build/build.xml | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/build/build.xml b/build/build.xml index 30c9b05b55..b1140e02a2 100644 --- a/build/build.xml +++ b/build/build.xml @@ -611,17 +611,10 @@ - + - - - - - @@ -756,9 +749,6 @@ - - - @@ -860,11 +850,6 @@ --> - - - - - - + @@ -1122,10 +1107,6 @@ --> - - - - Date: Sat, 30 Jul 2016 10:36:06 +0200 Subject: [PATCH 013/917] IO: Add PHONY target to Makefile --- java/libraries/io/src/native/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/libraries/io/src/native/Makefile b/java/libraries/io/src/native/Makefile index f33218a6c4..c35acf87ef 100644 --- a/java/libraries/io/src/native/Makefile +++ b/java/libraries/io/src/native/Makefile @@ -16,3 +16,5 @@ iface.h: clean: rm -f $(TARGET) $(OBJS) + +.PHONY: iface.h clean From 2f59e274ca6903fb2e3abeb2e1b21c7944c0547a Mon Sep 17 00:00:00 2001 From: gohai Date: Sat, 30 Jul 2016 10:39:47 +0200 Subject: [PATCH 014/917] IO: Tweaks to SoftwareServo JavaDoc --- java/libraries/io/src/processing/io/SoftwareServo.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/java/libraries/io/src/processing/io/SoftwareServo.java b/java/libraries/io/src/processing/io/SoftwareServo.java index feece76e2a..db5cbdcbef 100644 --- a/java/libraries/io/src/processing/io/SoftwareServo.java +++ b/java/libraries/io/src/processing/io/SoftwareServo.java @@ -83,8 +83,7 @@ public void attach(int pin) { /** - * Attaches a servo motor to a GPIO pin - * @param pin GPIO pin + * Attaches a servo motor to a GPIO pin using custom pulse widths * @param minPulse minimum pulse width in microseconds (default: 544, same as on Arduino) * @param maxPulse maximum pulse width in microseconds (default: 2400, same as on Arduino) * @webref @@ -98,7 +97,7 @@ public void attach(int pin, int minPulse, int maxPulse) { /** - * Move a servo motor to a given orientation + * Moves a servo motor to a given orientation * @param angle angle in degrees (controls speed and direction on continuous-rotation servos) * @webref */ From a3c5d2d91eb345e40c5095b66eec7f2851272017 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 28 Aug 2016 14:26:40 -0400 Subject: [PATCH 015/917] a little font cleaning --- app/src/processing/app/ui/Toolkit.java | 46 ++------------------------ 1 file changed, 3 insertions(+), 43 deletions(-) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index e30b9f98a5..5ed3c1a4b4 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -55,6 +55,7 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.regex.Pattern; import javax.swing.Action; @@ -763,47 +764,6 @@ static private boolean checkRetina() { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -// static Font monoFont; -// static Font plainFont; -// static Font boldFont; -// -// -// static public Font getMonoFont(int size) { -// if (monoFont == null) { -// try { -// monoFont = createFont("DroidSansMono.ttf", size); -// } catch (Exception e) { -// monoFont = new Font("Monospaced", Font.PLAIN, size); -// } -// } -// return monoFont; -// } -// -// -// static public Font getPlainFont(int size) { -// if (plainFont == null) { -// try { -// plainFont = createFont("DroidSans.ttf", size); -// } catch (Exception e) { -// plainFont = new Font("SansSerif", Font.PLAIN, size); -// } -// } -// return plainFont; -// } -// -// -// static public Font getBoldFont(int size) { -// if (boldFont == null) { -// try { -// boldFont = createFont("DroidSans-Bold.ttf", size); -// } catch (Exception e) { -// boldFont = new Font("SansSerif", Font.BOLD, size); -// } -// } -// return boldFont; -// } - - static final char GREEK_SMALL_LETTER_ALPHA = '\u03B1'; // α static final char GREEK_CAPITAL_LETTER_OMEGA = '\u03A9'; // ω @@ -813,7 +773,7 @@ static private List getMonoFontList() { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); Font[] fonts = ge.getAllFonts(); - ArrayList outgoing = new ArrayList(); + List outgoing = new ArrayList(); // Using AffineTransform.getScaleInstance(100, 100) doesn't change sizes FontRenderContext frc = new FontRenderContext(new AffineTransform(), @@ -855,7 +815,7 @@ static private List getMonoFontList() { static public String[] getMonoFontFamilies() { - HashSet families = new HashSet(); + Set families = new HashSet<>(); for (Font font : getMonoFontList()) { families.add(font.getFamily()); } From 8702bdb31ed9ee4398a5a969e4802daf2186d6cd Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 28 Aug 2016 14:30:08 -0400 Subject: [PATCH 016/917] rolling over for the next release (late) --- app/src/processing/app/Base.java | 4 ++-- core/done.txt | 5 +++++ core/todo.txt | 4 +--- done.txt | 13 +++++++++++++ todo.txt | 17 ++++++----------- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 6088c1d11e..74607bd096 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -55,9 +55,9 @@ public class Base { // Added accessors for 0218 because the UpdateCheck class was not properly // updating the values, due to javac inlining the static final values. - static private final int REVISION = 253; + static private final int REVISION = 254; /** This might be replaced by main() if there's a lib/version.txt file. */ - static private String VERSION_NAME = "0253"; //$NON-NLS-1$ + static private String VERSION_NAME = "0254"; //$NON-NLS-1$ /** Set true if this a proper release rather than a numbered revision. */ /** True if heavy debugging error/log messages are enabled */ diff --git a/core/done.txt b/core/done.txt index a4d16b206d..28933ab2a6 100644 --- a/core/done.txt +++ b/core/done.txt @@ -1,3 +1,8 @@ +0253 (3.2.1) +X implement defaultUncaughtExceptionHandler +X helps avoid needing to double-quit OS X applications + + 0252 (3.2) X some Table cleanup based on other CSV parsing work X use StandardCharsets.UTF_8 instead of getting encoding by name diff --git a/core/todo.txt b/core/todo.txt index aa0e230643..c37d20d1b0 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,6 +1,4 @@ -0253 (3.2.1) -X implement defaultUncaughtExceptionHandler -X helps avoid needing to double-quit OS X applications +0254 (3.2.2 or 3.3) X add getRowMap() function _ do we want rows() to not be transient? diff --git a/done.txt b/done.txt index e912bfeffc..8637e28c57 100644 --- a/done.txt +++ b/done.txt @@ -1,3 +1,16 @@ +0253 (3.2.1) +X "Could not replace preferences.old" error message +X https://github.com/processing/processing/issues/4626 +X Version 3.2 won't run from paths with spaces on Windows +X https://github.com/processing/processing/issues/4623 +X might be ext.dirs trouble with spaces in path names? +X or the backwards slashes? +X fixes for Python Mode crashing on startup +X disable ext.dirs on Linux export and set jna.nosys as well +X Java not included properly with 32-bit Linux export +X JavaInputHandler not registering + + 0252 (3.2) X Processing .jar files in CLASSPATH can cause startup crash X https://github.com/processing/processing/issues/4128 diff --git a/todo.txt b/todo.txt index 5e7d747376..d0aced5433 100755 --- a/todo.txt +++ b/todo.txt @@ -1,14 +1,9 @@ -0253 (3.2.1) -X "Could not replace preferences.old" error message -X https://github.com/processing/processing/issues/4626 -X Version 3.2 won't run from paths with spaces on Windows -X https://github.com/processing/processing/issues/4623 -X might be ext.dirs trouble with spaces in path names? -X or the backwards slashes? -X fixes for Python Mode crashing on startup -X disable ext.dirs on Linux export and set jna.nosys as well -X Java not included properly with 32-bit Linux export -X JavaInputHandler not registering +0254 (3.2.2 or 3.3) + + +gohai +X Simplify font situation to make it possible to use vanilla JRE trees +X https://github.com/processing/processing/pull/4639 _ library compilations handled oddly From 1624daa470eb17dac4618ff5d6a1b96a6ade5855 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 28 Aug 2016 14:40:26 -0400 Subject: [PATCH 017/917] simplify by using StringList --- app/src/processing/app/ui/Toolkit.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 408e2886dd..3e53009e00 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -74,6 +74,7 @@ import processing.app.Platform; import processing.app.Preferences; import processing.app.Util; +import processing.data.StringList; /** @@ -815,13 +816,12 @@ static private List getMonoFontList() { static public String[] getMonoFontFamilies() { - Set families = new HashSet<>(); + StringList families = new StringList(); for (Font font : getMonoFontList()) { - families.add(font.getFamily()); + families.appendUnique(font.getFamily()); } - String[] names = families.toArray(new String[0]); - Arrays.sort(names); - return names; + families.sort(); + return families.array(); } From dde59dda8e51da711ae07c4ee0c996ba5c6832dc Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 28 Aug 2016 14:40:48 -0400 Subject: [PATCH 018/917] cleanup and force load of mono font (#4639) --- .../app/syntax/TextAreaPainter.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/app/src/processing/app/syntax/TextAreaPainter.java b/app/src/processing/app/syntax/TextAreaPainter.java index 5e8836fdb7..251e6cb8ba 100644 --- a/app/src/processing/app/syntax/TextAreaPainter.java +++ b/app/src/processing/app/syntax/TextAreaPainter.java @@ -10,8 +10,15 @@ */ package processing.app.syntax; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.RenderingHints; import java.awt.event.MouseEvent; -import java.awt.*; import javax.swing.ToolTipManager; import javax.swing.text.*; @@ -19,6 +26,7 @@ import processing.app.Preferences; import processing.app.syntax.im.CompositionTextPainter; +import processing.app.ui.Toolkit; /** @@ -107,12 +115,13 @@ public TextAreaPainter(JEditTextArea textArea, TextAreaDefaults defaults) { 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); + // Ensure that our monospaced font is loaded + // https://github.com/processing/processing/pull/4639 + Toolkit.getMonoFontName(); + String fontFamily = Preferences.get("editor.font.family"); int fontSize = Preferences.getInteger("editor.font.size"); plainFont = new Font(fontFamily, Font.PLAIN, fontSize); @@ -124,16 +133,11 @@ public void updateAppearance() { } boldFont = new Font(fontFamily, Font.BOLD, fontSize); antialias = Preferences.getBoolean("editor.smooth"); -// System.out.println(plainFont.getFamily()); -// System.out.println(plainFont); // moved from setFont() override (never quite comfortable w/ that override) fm = super.getFontMetrics(plainFont); tabSize = fm.charWidth(' ') * Preferences.getInteger("editor.tabs.size"); textArea.recalculateVisibleLines(); - -// fgcolor = mode.getColor("editor.fgcolor"); -// bgcolor = mode.getColor("editor.bgcolor"); } From 8fccff2c8378ac3b55510b8842422871df03a6ad Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 28 Aug 2016 14:42:18 -0400 Subject: [PATCH 019/917] updates from gohai --- todo.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/todo.txt b/todo.txt index d0aced5433..ee788524b9 100755 --- a/todo.txt +++ b/todo.txt @@ -4,6 +4,8 @@ gohai X Simplify font situation to make it possible to use vanilla JRE trees X https://github.com/processing/processing/pull/4639 +X Trivial updates for ARM +X https://github.com/processing/processing/pull/4640 _ library compilations handled oddly From b70a4f8cd85cb37c862eda552b889f39b5314372 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 28 Aug 2016 14:43:22 -0400 Subject: [PATCH 020/917] unused imports and commented code --- app/src/processing/app/ui/Toolkit.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 3e53009e00..8f26edbf2a 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -52,10 +52,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; -import java.util.HashSet; import java.util.List; import java.util.Locale; -import java.util.Set; import java.util.regex.Pattern; import javax.swing.Action; @@ -81,17 +79,8 @@ * Utility functions for base that require a java.awt.Toolkit object. These * are broken out from Base as we start moving toward the possibility of the * code running in headless mode. - * @author fry */ public class Toolkit { - /* - static public final String PROMPT_YES = Language.text("prompt.yes"); - static public final String PROMPT_NO = Language.text("prompt.no"); - static public final String PROMPT_CANCEL = Language.text("prompt.cancel"); - static public final String PROMPT_OK = Language.text("prompt.ok"); - static public final String PROMPT_BROWSE = Language.text("prompt.browse"); - */ - static final java.awt.Toolkit awtToolkit = java.awt.Toolkit.getDefaultToolkit(); From d7d5ab0cc9797cd2e675940884817aeb737e3f76 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 28 Aug 2016 14:53:01 -0400 Subject: [PATCH 021/917] about those fonts... --- todo.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/todo.txt b/todo.txt index ee788524b9..3842424911 100755 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,7 @@ 0254 (3.2.2 or 3.3) - +X more font tweaks to make mono fonts work properly after #4639 +_ update the Linux notes based on where we land on this +_ https://github.com/processing/processing/wiki/Supported-Platforms#linux gohai X Simplify font situation to make it possible to use vanilla JRE trees From 87b63415068dd1e9cdc49919a9ebb0645fbc735c Mon Sep 17 00:00:00 2001 From: gohai Date: Sun, 28 Aug 2016 20:56:35 +0200 Subject: [PATCH 022/917] Cleanup createFont --- app/src/processing/app/ui/Toolkit.java | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 3e53009e00..1dabce62e6 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -929,7 +929,7 @@ static public Font getSansFont(int size, int style) { /** - * Get a font from the JRE lib/fonts folder. Our default fonts are also + * Get a font from the lib/fonts folder. Our default fonts are also * installed there so that the monospace (and others) can be used by other * font listing calls (i.e. it appears in the list of monospace fonts in * the Preferences window, and can be used by HTMLEditorKit for WebFrame). @@ -937,23 +937,15 @@ static public Font getSansFont(int size, int style) { static private Font createFont(String filename, int size) throws IOException, FontFormatException { boolean registerFont = false; - // Can't use Base.getJavaHome(), because if we're not using our local JRE, - // we likely have bigger problems with how things are running. + // try the JRE font directory first File fontFile = new File(System.getProperty("java.home"), "lib/fonts/" + filename); + + // else fall back to our own content dir if (!fontFile.exists()) { - // any of the fallbacks below is a custom location, so try to register the font as well - registerFont = true; - // if we're debugging from Eclipse, grab it from the work folder (user.dir is /app) - fontFile = new File(System.getProperty("user.dir"), "../build/shared/lib/fonts/" + filename); - } - if (!fontFile.exists()) { - // if we're debugging the new Java Mode from Eclipse, paths are different - fontFile = new File(System.getProperty("user.dir"), "../../shared/lib/fonts/" + filename); - } - if (!fontFile.exists()) { - // this if for Linux, where we're shipping a second copy of the fonts outside of java fontFile = Platform.getContentFile("lib/fonts/" + filename); + registerFont = true; } + if (!fontFile.exists()) { String msg = "Could not find required fonts. "; // This gets the JAVA_HOME for the *local* copy of the JRE installed with @@ -968,11 +960,11 @@ static private Font createFont(String filename, int size) throws IOException, Fo Messages.showError("Font Sadness", msg, null); } + BufferedInputStream input = new BufferedInputStream(new FileInputStream(fontFile)); Font font = Font.createFont(Font.TRUETYPE_FONT, input); input.close(); - // this makes Font() work for font files in custom locations if (registerFont) { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); ge.registerFont(font); From f685491ecc1c48b9d5ba7b33229e3ff21effc15f Mon Sep 17 00:00:00 2001 From: codeanticode Date: Tue, 30 Aug 2016 02:20:24 -0400 Subject: [PATCH 023/917] keep current user-provided FBO --- .../processing/opengl/PGraphicsOpenGL.java | 65 +++++++++++-------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 5c17d87b57..5ac46f99ba 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -1667,42 +1667,51 @@ protected void endReadPixels() { protected void beginPixelsOp(int op) { FrameBuffer pixfb = null; + FrameBuffer currfb = getCurrentFB(); if (primaryGraphics) { - if (op == OP_READ) { - if (pgl.isFBOBacked() && pgl.isMultisampled()) { - // Making sure the back texture is up-to-date... - pgl.syncBackTexture(); - // ...because the read framebuffer uses it as the color buffer (the - // draw framebuffer is MSAA so it cannot be read from it). - pixfb = readFramebuffer; - } else { - pixfb = drawFramebuffer; + FrameBuffer rfb = readFramebuffer; + FrameBuffer dfb = drawFramebuffer; + if ((currfb == rfb) || (currfb == dfb)) { + // Not user-provided FB, need to check if the correct FB is current. + if (op == OP_READ) { + if (pgl.isFBOBacked() && pgl.isMultisampled()) { + // Making sure the back texture is up-to-date... + pgl.syncBackTexture(); + // ...because the read framebuffer uses it as the color buffer (the + // draw framebuffer is MSAA so it cannot be read from it). + pixfb = rfb; + } else { + pixfb = dfb; + } + } else if (op == OP_WRITE) { + // We can write to the draw framebuffer irrespective of whether is + // FBO-baked or multisampled. + pixfb = dfb; } - } else if (op == OP_WRITE) { - // We can write to the draw framebuffer irrespective of whether is - // FBO-baked or multisampled. - pixfb = drawFramebuffer; } } else { FrameBuffer ofb = offscreenFramebuffer; FrameBuffer mfb = multisampleFramebuffer; - if (op == OP_READ) { - if (offscreenMultisample) { - // Making sure the offscreen FBO is up-to-date - int mask = PGL.COLOR_BUFFER_BIT; - if (hints[ENABLE_BUFFER_READING]) { - mask |= PGL.DEPTH_BUFFER_BIT | PGL.STENCIL_BUFFER_BIT; - } - if (ofb != null && mfb != null) { - mfb.copy(ofb, mask); + if ((currfb == ofb) || (currfb == mfb)) { + // Not user-provided FB, need to check if the correct FB is current. + if (op == OP_READ) { + if (offscreenMultisample) { + // Making sure the offscreen FBO is up-to-date + int mask = PGL.COLOR_BUFFER_BIT; + if (hints[ENABLE_BUFFER_READING]) { + mask |= PGL.DEPTH_BUFFER_BIT | PGL.STENCIL_BUFFER_BIT; + } + if (ofb != null && mfb != null) { + mfb.copy(ofb, mask); + } } + // We always read the screen pixels from the color FBO. + pixfb = ofb; + } else if (op == OP_WRITE) { + // We can write directly to the color FBO, or to the multisample FBO + // if multisampling is enabled. + pixfb = offscreenMultisample ? mfb : ofb; } - // We always read the screen pixels from the color FBO. - pixfb = ofb; - } else if (op == OP_WRITE) { - // We can write directly to the color FBO, or to the multisample FBO - // if multisampling is enabled. - pixfb = offscreenMultisample ? mfb : ofb; } } From 39471f8209961fe5b7867dbbc34d7b698af99e9f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 30 Aug 2016 09:29:47 -0400 Subject: [PATCH 024/917] fix quoting problem in IntDict.toJSON() --- core/src/processing/data/IntDict.java | 2 +- core/todo.txt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/processing/data/IntDict.java b/core/src/processing/data/IntDict.java index 965fedb4df..e50d1b55d4 100644 --- a/core/src/processing/data/IntDict.java +++ b/core/src/processing/data/IntDict.java @@ -666,7 +666,7 @@ public void write(PrintWriter writer) { public String toJSON() { StringList items = new StringList(); for (int i = 0; i < size(); i++) { - items.append("\"" + JSONObject.quote(keys[i]) + "\": " + values[i]); + items.append(JSONObject.quote(keys[i])+ ": " + values[i]); } return "{ " + items.join(", ") + " }"; } diff --git a/core/todo.txt b/core/todo.txt index c37d20d1b0..96c666f60a 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,7 +1,11 @@ 0254 (3.2.2 or 3.3) +X fix quoting problem in IntDict.toJSON() X add getRowMap() function _ do we want rows() to not be transient? +andres +X Automatic handling of screen FBOs breaks readPixels() for user-provided FBO +X https://github.com/processing/processing/issues/4643 started X add toJSON() method to IntDict From dd8ef38ac4552b9b6db869a5a6851d3a8fb7e293 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 2 Sep 2016 12:10:59 -0400 Subject: [PATCH 025/917] add getRenderer() to SurfaceInfo (fixes #4441) --- core/todo.txt | 2 ++ .../src/processing/mode/java/preproc/SurfaceInfo.java | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index 96c666f60a..d2bffdf3f5 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,5 +1,7 @@ 0254 (3.2.2 or 3.3) X fix quoting problem in IntDict.toJSON() +X add getRenderer() to SurfaceInfo +X https://github.com/processing/processing/issues/4441 X add getRowMap() function _ do we want rows() to not be transient? diff --git a/java/src/processing/mode/java/preproc/SurfaceInfo.java b/java/src/processing/mode/java/preproc/SurfaceInfo.java index 6e5f57f0b8..04834de8b2 100644 --- a/java/src/processing/mode/java/preproc/SurfaceInfo.java +++ b/java/src/processing/mode/java/preproc/SurfaceInfo.java @@ -138,4 +138,15 @@ public boolean hasSettings() { public String getSettings() { return statements.join(" "); } + + + // Added for Android Mode to check whether OpenGL is in use + // https://github.com/processing/processing/issues/4441 + /** + * Return the renderer specified (null if none specified). + * @since 3.2.2 + */ + public String getRenderer() { + return renderer; + } } From e8b474b33c648146fdf8744a4a5f53e5cd779af6 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 8 Sep 2016 03:46:50 -0400 Subject: [PATCH 026/917] notes --- app/src/processing/app/ui/Editor.java | 2 ++ todo.txt | 16 ++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 5f210c164f..fd2de22be7 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -2781,6 +2781,8 @@ protected SizeRequirements calculateMinorAxisRequirements( /** * Grab current contents of the sketch window, advance the console, * stop any other running sketches... not in that order. + * It's essential that this function be called by any Mode subclass, + * otherwise current edits may not be stored for getProgram(). */ public void prepareRun() { internalCloseRunner(); diff --git a/todo.txt b/todo.txt index 3842424911..75b7a76a41 100755 --- a/todo.txt +++ b/todo.txt @@ -8,6 +8,8 @@ X Simplify font situation to make it possible to use vanilla JRE trees X https://github.com/processing/processing/pull/4639 X Trivial updates for ARM X https://github.com/processing/processing/pull/4640 +X Remove all the extra hoops for loading fonts +X https://github.com/processing/processing/pull/4641 _ library compilations handled oddly @@ -40,6 +42,14 @@ _ Pasting code from editor to empty editor produces Exception _ https://github.com/processing/processing/issues/4522 _ possible infinite loop on modified externally _ https://github.com/processing/processing/issues/3965 +_ PDE and sketches are 2x smaller on high-res Windows machines +_ https://github.com/processing/processing/issues/2411 +_ System.setProperty("sun.java2d.dpiaware", "false"); +_ though that seems broken in Java 8: http://superuser.com/a/1007783 +_ modi +_ until we fix it.. +_ call this from JNA? https://msdn.microsoft.com/en-us/library/windows/desktop/dn302122(v=vs.85).aspx +_ or modify the manifest/app? https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx medium _ detect changes in case with libraries @@ -50,10 +60,6 @@ _ hidpi scaling via font changes? _ http://stackoverflow.com/a/34152675 _ hi-dpi support on Linux _ https://github.com/processing/processing/issues/4183 -_ PDE and sketches are 2x smaller on high-res Windows machines -_ https://github.com/processing/processing/issues/2411 -_ System.setProperty("sun.java2d.dpiaware", "false"); -_ though that seems broken in Java 8: http://superuser.com/a/1007783 _ did we lose settings.path because it was too buggy? _ https://github.com/processing/processing/issues/3948 _ Library path mismatch between processing-java and export @@ -879,8 +885,6 @@ _ p5 assets need to be licensed differently from the source DIST / Windows -_ PDE and sketches are 2x smaller on high-res Windows 8 machines -_ https://github.com/processing/processing/issues/2411 _ does launching p5 from inside the .zip folder cause it to quit immediately? _ how can we provide an error message here? _ how to handle double-clicked files on windows? From f695da510fe1512aa9e24ad089758daf6225913e Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 8 Sep 2016 12:09:49 -0400 Subject: [PATCH 027/917] make Find in Reference default to built-in PApplet methods (fixes #4224) --- app/src/processing/app/Mode.java | 8 +++++++- todo.txt | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/processing/app/Mode.java b/app/src/processing/app/Mode.java index 3bdbeebc75..c7ceb1e2e2 100644 --- a/app/src/processing/app/Mode.java +++ b/app/src/processing/app/Mode.java @@ -166,7 +166,13 @@ protected void loadKeywords(File keywordFile, if (htmlFilename.endsWith("_")) { keyword += "_"; } - keywordToReference.put(keyword, htmlFilename); + // Allow the bare size() command to override the lookup + // for StringList.size() and others, but not vice-versa. + // https://github.com/processing/processing/issues/4224 + boolean seen = keywordToReference.containsKey(keyword); + if (!seen || (seen && keyword.equals(htmlFilename))) { + keywordToReference.put(keyword, htmlFilename); + } } } } diff --git a/todo.txt b/todo.txt index 75b7a76a41..66f152cfc7 100755 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,8 @@ 0254 (3.2.2 or 3.3) +X Find in reference for size() opens StringList.size() +X https://github.com/processing/processing/issues/4224 +X though that's still imperfect: +X https://github.com/processing/processing/issues/4655 X more font tweaks to make mono fonts work properly after #4639 _ update the Linux notes based on where we land on this _ https://github.com/processing/processing/wiki/Supported-Platforms#linux From ee539102a3ce649effd3b6456a7341216e905d16 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 10 Sep 2016 22:22:57 -0400 Subject: [PATCH 028/917] limit rollovers on EditorStatus to the text portion --- app/src/processing/app/Platform.java | 2 +- app/src/processing/app/ui/EditorStatus.java | 52 ++++++++++++++++++--- build/shared/lib/theme.txt | 1 + todo.txt | 1 + 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/app/src/processing/app/Platform.java b/app/src/processing/app/Platform.java index 91ea3c3d12..02b24c1421 100644 --- a/app/src/processing/app/Platform.java +++ b/app/src/processing/app/Platform.java @@ -150,7 +150,7 @@ static public void openURL(String url) { } catch (Exception e) { Messages.showWarning("Problem Opening URL", - "Could not open the URL\n" + url, e); + "Could not open the URL\n" + url, e); } } diff --git a/app/src/processing/app/ui/EditorStatus.java b/app/src/processing/app/ui/EditorStatus.java index 73269775c0..aca1bc047c 100644 --- a/app/src/processing/app/ui/EditorStatus.java +++ b/app/src/processing/app/ui/EditorStatus.java @@ -33,6 +33,7 @@ import java.awt.Image; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; import javax.swing.plaf.basic.BasicSplitPaneDivider; import javax.swing.plaf.basic.BasicSplitPaneUI; @@ -50,6 +51,7 @@ public class EditorStatus extends BasicSplitPaneDivider { //JPanel { static final int LEFT_MARGIN = Editor.LEFT_GUTTER; static final int RIGHT_MARGIN = 20; + Color urlColor; Color[] fgColor; Color[] bgColor; Image[] bgImage; @@ -72,7 +74,11 @@ public class EditorStatus extends BasicSplitPaneDivider { //JPanel { int mode; String message; + String url; + int rightEdge; + int mouseX; + boolean inside; Font font; FontMetrics metrics; @@ -98,21 +104,48 @@ public EditorStatus(BasicSplitPaneUI ui, Editor editor) { updateMode(); addMouseListener(new MouseAdapter() { + + @Override public void mouseEntered(MouseEvent e) { - if (url != null) { - setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } + updateMouse(); } + @Override public void mousePressed(MouseEvent e) { - if (url != null) { + //if (url != null) { + if (inside) { Platform.openURL(url); } } + + @Override + public void mouseExited(MouseEvent e) { + updateMouse(); + } + + }); + + addMouseMotionListener(new MouseMotionAdapter() { + + @Override + public void mouseMoved(MouseEvent e) { + mouseX = e.getX(); + updateMouse(); + } }); } + void updateMouse() { + if (inside) { + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } else { + setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + } + repaint(); + } + + static String findURL(String message) { String[] m = PApplet.match(message, "http\\S+"); if (m != null) { @@ -125,6 +158,8 @@ static String findURL(String message) { public void updateMode() { Mode mode = editor.getMode(); + urlColor = mode.getColor("status.url.fgcolor"); + fgColor = new Color[] { mode.getColor("status.notice.fgcolor"), mode.getColor("status.error.fgcolor"), @@ -240,7 +275,7 @@ public void paint(Graphics screen) { if (offscreen == null) { sizeW = size.width; sizeH = size.height; -// setButtonBounds(); + if (Toolkit.highResDisplay()) { offscreen = createImage(sizeW*2, sizeH*2); } else { @@ -257,15 +292,18 @@ public void paint(Graphics screen) { ascent = metrics.getAscent(); } - //g.setColor(bgColor[mode]); - //g.fillRect(0, 0, sizeW, sizeH); g.drawImage(bgImage[mode], 0, 0, sizeW, sizeH, this); g.setColor(fgColor[mode]); // https://github.com/processing/processing/issues/3265 if (message != null) { g.setFont(font); // needs to be set each time on osx + inside = (mouseX > LEFT_MARGIN && mouseX < rightEdge); + if (inside) { + g.setColor(urlColor); + } g.drawString(message, LEFT_MARGIN, (sizeH + ascent) / 2); + rightEdge = LEFT_MARGIN + g.getFontMetrics().stringWidth(message); } if (indeterminate) { diff --git a/build/shared/lib/theme.txt b/build/shared/lib/theme.txt index 06101c6a0c..5be58de3dd 100644 --- a/build/shared/lib/theme.txt +++ b/build/shared/lib/theme.txt @@ -6,6 +6,7 @@ status.error.fgcolor = #ffffff status.error.bgcolor = #9E0A0A status.warning.bgcolor = #EF8115 status.warning.fgcolor = #FFFFFF +status.url.fgcolor = #cccccc status.font = processing.sans,plain,13 # HEADER TABS diff --git a/todo.txt b/todo.txt index 66f152cfc7..59a92fa89e 100755 --- a/todo.txt +++ b/todo.txt @@ -3,6 +3,7 @@ X Find in reference for size() opens StringList.size() X https://github.com/processing/processing/issues/4224 X though that's still imperfect: X https://github.com/processing/processing/issues/4655 +X limit rollovers on EditorStatus to the text portion X more font tweaks to make mono fonts work properly after #4639 _ update the Linux notes based on where we land on this _ https://github.com/processing/processing/wiki/Supported-Platforms#linux From a0f2c5a78879b9ac39e0e492b13d93947a7be2b9 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 10 Sep 2016 22:33:44 -0400 Subject: [PATCH 029/917] cleaning unused lines --- app/src/processing/app/ui/EditorStatus.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/src/processing/app/ui/EditorStatus.java b/app/src/processing/app/ui/EditorStatus.java index aca1bc047c..fed91bbcf6 100644 --- a/app/src/processing/app/ui/EditorStatus.java +++ b/app/src/processing/app/ui/EditorStatus.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2012-15 The Processing Foundation + Copyright (c) 2012-16 The Processing Foundation Copyright (c) 2004-12 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology @@ -87,10 +87,6 @@ public class EditorStatus extends BasicSplitPaneDivider { //JPanel { Image offscreen; int sizeW, sizeH; -// JButton cancelButton; -// JButton okButton; -// JTextField editField; - int response; boolean indeterminate; @@ -112,7 +108,6 @@ public void mouseEntered(MouseEvent e) { @Override public void mousePressed(MouseEvent e) { - //if (url != null) { if (inside) { Platform.openURL(url); } From 90341654b7bc28805551c11f254c9160dfd69db9 Mon Sep 17 00:00:00 2001 From: jshrake Date: Sat, 10 Sep 2016 21:25:21 -0700 Subject: [PATCH 030/917] Call glGetProgramiv to retrieve program log length Calling glGetShaderiv to retrieve the program log length produces a GL_INVALID_OPERATION error and length < 0, preventing the return of the actual info log. This fix replaces the call to glGetShaderiv with glGetProgramiv. Closes #4659 --- core/src/processing/opengl/PJOGL.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/opengl/PJOGL.java b/core/src/processing/opengl/PJOGL.java index 9a429f8005..9c579032e9 100644 --- a/core/src/processing/opengl/PJOGL.java +++ b/core/src/processing/opengl/PJOGL.java @@ -1701,7 +1701,7 @@ public void getProgramiv(int program, int pname, IntBuffer params) { @Override public String getProgramInfoLog(int program) { int[] val = { 0 }; - gl2.glGetShaderiv(program, GL2ES2.GL_INFO_LOG_LENGTH, val, 0); + gl2.glGetProgramiv(program, GL2ES2.GL_INFO_LOG_LENGTH, val, 0); int length = val[0]; if (0 < length) { From 3b02c41dab587c8608fe4f9e608d5c39924be54e Mon Sep 17 00:00:00 2001 From: Guo Yunhe Date: Sun, 11 Sep 2016 20:32:25 +0300 Subject: [PATCH 031/917] Translate Chinese --- build/shared/lib/languages/PDE_zh.properties | 52 +++++++++++++------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/build/shared/lib/languages/PDE_zh.properties b/build/shared/lib/languages/PDE_zh.properties index 6e97ee4188..4df050f90e 100644 --- a/build/shared/lib/languages/PDE_zh.properties +++ b/build/shared/lib/languages/PDE_zh.properties @@ -48,7 +48,7 @@ menu.edit.use_selection_for_find = 使用当前选定查找 # | Sketch | menu.sketch.run = 运行 menu.sketch.present = 展示模式 -menu.sketch.tweak = Tweak +menu.sketch.tweak = 调整 menu.sketch.stop = 停止 # --- menu.library = 引用库文件... @@ -62,7 +62,23 @@ menu.sketch.add_file = 添加文件... # | File | Edit | Sketch | Debug | Tools | Help | # | Debug | -# ... +# | File | Edit | Sketch | Debug | Tools | Help | +# | Debug | +menu.debug = 调试 +menu.debug.enable = 启用调试器 +menu.debug.disable = 禁用调试器 +# --- +menu.debug.toggle_breakpoint = 切换断点 +# --- +# used for both menus and toolbars +menu.debug.step = 单步 (Step) +menu.debug.step_into = 单步进入 (Step Into) +menu.debug.step_out = 单步跳出 (Step Out) +menu.debug.continue = 继续 +# --- +#menu.debug.variable_inspector = Variable Inspector +menu.debug.show_variables = 显示变量 +menu.debug.hide_variables = 隐藏变量 # | File | Edit | Sketch | Debug | Tools | Help | # | Tools | @@ -129,8 +145,8 @@ preferences.language = 语言 preferences.editor_and_console_font = 编辑器和控制台字体 preferences.editor_and_console_font.tip = \ 为编辑器和控制台选择字体.
\ -Only monospaced (fixed-width) fonts may be used,
\ -though the list may be imperfect. +只允许使用等宽字体,
\ +此列表可能不完全。 preferences.editor_font_size = 编辑器字体大小 preferences.console_font_size = 控制台字体大小 preferences.background_color = 展示模式时的背景颜色 @@ -140,27 +156,27 @@ preferences.background_color.tip = \ 可从速写本菜单中访问. preferences.use_smooth_text = 在编辑器窗口中使用平滑字体 preferences.enable_complex_text_input = 启用复杂字体输入 -preferences.enable_complex_text_input_example = i.e. Japanese +preferences.enable_complex_text_input_example = 例如日文 preferences.continuously_check = 不断检查错误 preferences.show_warnings = 显示警告 -preferences.code_completion = Code completion -preferences.trigger_with = Trigger with -preferences.cmd_space = space +preferences.code_completion = 代码补全 +preferences.trigger_with = 触发开关 +preferences.cmd_space = 空格 preferences.increase_max_memory = 增加最大内存至 preferences.delete_previous_folder_on_export = 当导出时删除先前的文件夹 preferences.hide_toolbar_background_image = 隐藏标签/工具栏背景图片 preferences.check_for_updates_on_startup = 在启动时检查有无更新 -preferences.run_sketches_on_display = Run sketches on display +preferences.run_sketches_on_display = 在此显示器中运行速写本 preferences.run_sketches_on_display.tip = \ Sets the display where sketches are initially placed.
\ As usual, if the sketch window is moved, it will re-open
\ at the same location, however when running in present
\ (full screen) mode, this display will always be used. preferences.automatically_associate_pde_files = 自动关联 .pde 文件通过 Processing -preferences.launch_programs_in = Launch programs in +preferences.launch_programs_in = 加载程序的模式 preferences.launch_programs_in.mode = 模式 preferences.file = 更多选项可直接编辑该文件 -preferences.file.hint = 请在Processing不在运行时编辑该文件 +preferences.file.hint = 请在 Processing 未运行时编辑该文件 # Sketchbook Location (Frame) sketchbook_location = 选择新速写本位置 @@ -187,7 +203,7 @@ find.find = 搜索: find.replace_with = 替换为: find.ignore_case = 忽略大小写 find.all_tabs = 所有标签 -find.wrap_around = Wrap Around +find.wrap_around = 循环遍历 find.btn.replace_all = 全部替换 find.btn.replace = 替换 find.btn.find_and_replace = 搜索 & 替换 @@ -238,8 +254,8 @@ editor.header.rename = 重命名 editor.header.delete = 删除 editor.header.previous_tab = 前一个标签 editor.header.next_tab = 后一个标签 -editor.header.delete.warning.title = Yeah, no. -editor.header.delete.warning.text = You can't delete the last tab of the last open sketch. +editor.header.delete.warning.title = 这样不行 +editor.header.delete.warning.text = 无法删除最后一个速写本的最后一个标签 # Tabs editor.tab.new = 新文件名 @@ -248,10 +264,10 @@ editor.tab.rename = 新文件名 editor.tab.rename.description = 新文件名称 # Sketch -editor.sketch.rename.description = New name for sketch +editor.sketch.rename.description = 速写本的新名称 -editor.status.autoformat.no_changes = No changes necessary for Auto Format. -editor.status.autoformat.finished = Auto Format finished. +editor.status.autoformat.no_changes = 自动格式化不需要做更改。 +editor.status.autoformat.finished = 自动格式化完成。 editor.status.find_reference.select_word_first = First select a word to find in the reference. editor.status.find_reference.not_available = No reference available for "%s". editor.status.drag_and_drop.files_added.0 = No files were added to the sketch. @@ -275,7 +291,7 @@ contrib.install = 安装 contrib.progress.starting = 开始 contrib.progress.downloading = 下载 contrib.download_error = 下载时出现问题. -contrib.unsupported_operating_system = 你当前的操作系统似乎不被支持. 你应该访问 %s's 该库文件地址得到更多信息. +contrib.unsupported_operating_system = 你当前的操作系统似乎不被支持. 你应该访问 %s 获取更多信息. # --------------------------------------- From cc267f764596d932cc76ce988e4889c8f773129a Mon Sep 17 00:00:00 2001 From: Guo Yunhe Date: Sun, 11 Sep 2016 20:37:05 +0300 Subject: [PATCH 032/917] Translate Chinese --- build/shared/lib/languages/PDE_zh.properties | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build/shared/lib/languages/PDE_zh.properties b/build/shared/lib/languages/PDE_zh.properties index 4df050f90e..6c2223bfa9 100644 --- a/build/shared/lib/languages/PDE_zh.properties +++ b/build/shared/lib/languages/PDE_zh.properties @@ -268,11 +268,11 @@ editor.sketch.rename.description = 速写本的新名称 editor.status.autoformat.no_changes = 自动格式化不需要做更改。 editor.status.autoformat.finished = 自动格式化完成。 -editor.status.find_reference.select_word_first = First select a word to find in the reference. -editor.status.find_reference.not_available = No reference available for "%s". -editor.status.drag_and_drop.files_added.0 = No files were added to the sketch. -editor.status.drag_and_drop.files_added.1 = One file added to the sketch. -editor.status.drag_and_drop.files_added.n = %d files added to the sketch. +editor.status.find_reference.select_word_first = 请首先选择要查找的关键字。 +editor.status.find_reference.not_available = 没有找到 "%s" 的引用。 +editor.status.drag_and_drop.files_added.0 = 未将任何文件添加到速写本。 +editor.status.drag_and_drop.files_added.1 = 将 1 个文件添加到速写本。 +editor.status.drag_and_drop.files_added.n = 将 %d 个文件添加到速写本。 editor.status.saving = 保存中... editor.status.saving.done = 保存完成. editor.status.saving.canceled = 取消保存. From 0abee5af6ad3b11cf2b73bb794b8a97c157c4762 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Sep 2016 03:45:23 -0400 Subject: [PATCH 033/917] notes about status bar change w/ urls --- todo.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/todo.txt b/todo.txt index 59a92fa89e..b24b62f5bc 100755 --- a/todo.txt +++ b/todo.txt @@ -4,6 +4,10 @@ X https://github.com/processing/processing/issues/4224 X though that's still imperfect: X https://github.com/processing/processing/issues/4655 X limit rollovers on EditorStatus to the text portion +X clicking the status area when it has a url is problematic +X because it's also the vertical separator +X at least change it to only cover the text? +X add a rollover so people know what it's doing? X more font tweaks to make mono fonts work properly after #4639 _ update the Linux notes based on where we land on this _ https://github.com/processing/processing/wiki/Supported-Platforms#linux @@ -16,6 +20,9 @@ X https://github.com/processing/processing/pull/4640 X Remove all the extra hoops for loading fonts X https://github.com/processing/processing/pull/4641 +contrib +X Chinese translation updates +X https://github.com/processing/processing/pull/4661 _ library compilations handled oddly _ https://github.com/processing/processing/issues/4630 From 6ce19e7a12985d2e3f446afd5d32a4f8ce7fab46 Mon Sep 17 00:00:00 2001 From: tpltnt Date: Tue, 20 Sep 2016 15:26:07 +0200 Subject: [PATCH 034/917] more flexible interpreter path --- build/macosx/language_gen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/macosx/language_gen.py b/build/macosx/language_gen.py index 463d28fd63..5b216ee4f8 100755 --- a/build/macosx/language_gen.py +++ b/build/macosx/language_gen.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python import os, re From 9f14315a2cc04b3e403b9485840665cf0bb6dfea Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 20 Sep 2016 15:09:42 -0400 Subject: [PATCH 035/917] make this more portable --- build/jre/build.xml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/build/jre/build.xml b/build/jre/build.xml index 4fdbee5f0e..e91209903f 100644 --- a/build/jre/build.xml +++ b/build/jre/build.xml @@ -2,6 +2,18 @@ + + + + + + + - + nowarn="true"> + From 87f21903477ec528398fcd578a9e37c04eeafdbb Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 20 Sep 2016 15:15:23 -0400 Subject: [PATCH 036/917] more generic, cleaning up dirs --- build/jre/build.xml | 8 ++++++-- core/build.xml | 7 +++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/build/jre/build.xml b/build/jre/build.xml index e91209903f..db3c84e6e7 100644 --- a/build/jre/build.xml +++ b/build/jre/build.xml @@ -2,12 +2,15 @@ + + + - + @@ -22,7 +25,8 @@ debug="true" includeantruntime="true" nowarn="true"> - + + diff --git a/core/build.xml b/core/build.xml index 93b8f1d9c5..4a9d56a455 100644 --- a/core/build.xml +++ b/core/build.xml @@ -20,11 +20,14 @@ classpath="methods/methods.jar" /> + + + - + @@ -50,7 +53,7 @@ library/gluegen-rt.jar" nowarn="true"> - + From 4f1b34beace8f6b114c139d7f09e683006ac3d03 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 20 Sep 2016 15:24:58 -0400 Subject: [PATCH 037/917] incorporate PR --- core/todo.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index d2bffdf3f5..bccd284bf7 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -5,6 +5,11 @@ X https://github.com/processing/processing/issues/4441 X add getRowMap() function _ do we want rows() to not be transient? +contrib +X Call glGetProgramiv to retrieve program log length +X https://github.com/processing/processing/issues/4659 +X https://github.com/processing/processing/pull/4660 + andres X Automatic handling of screen FBOs breaks readPixels() for user-provided FBO X https://github.com/processing/processing/issues/4643 From 7fa3ea8d59ec864709199c6d122b06931b4fb2a8 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 25 Sep 2016 22:40:42 -0400 Subject: [PATCH 038/917] new bug with TRIANGLE_STRIP and PShape --- core/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index bccd284bf7..12e7309f0a 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -21,6 +21,9 @@ _ do the same for the other data classes _ note the difference between this and toJSONObject() or toJSONArray() _ or is that the better way to handle it? hm +_ TRIANGLE_STRIP not working correctly with createShape() and default renderer +_ https://github.com/processing/processing/issues/4678 + _ should we drop the 'default' prefix from the ex handler so it's not static? _ http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html _ listPaths(), listFiles()? From faeb919996b1a0ebb2c07458f9568b76d39d9cda Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 4 Oct 2016 13:53:48 -0400 Subject: [PATCH 039/917] avoid crash when closing an app window (fixes #4690) --- core/src/processing/opengl/PSurfaceJOGL.java | 9 +++++++++ core/todo.txt | 2 ++ 2 files changed, 11 insertions(+) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 7e5e15b662..d7f871f253 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -58,6 +58,7 @@ import com.jogamp.opengl.GLException; import com.jogamp.opengl.GLProfile; import com.jogamp.nativewindow.MutableGraphicsConfiguration; +import com.jogamp.nativewindow.WindowClosingProtocol; import com.jogamp.newt.Display; import com.jogamp.newt.Display.PointerIcon; import com.jogamp.newt.MonitorDevice; @@ -68,6 +69,7 @@ import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.util.FPSAnimator; + import processing.core.PApplet; import processing.core.PConstants; import processing.core.PGraphics; @@ -314,6 +316,12 @@ protected void initGL() { protected void initWindow() { window = GLWindow.create(screen, pgl.getCaps()); + // Make sure that we pass the window close through to exit(), otherwise + // we're likely to have OpenGL try to shut down halfway through rendering + // a frame. Particularly problematic for complex/slow apps. + // https://github.com/processing/processing/issues/4690 + window.setDefaultCloseOperation(WindowClosingProtocol.WindowClosingMode.DO_NOTHING_ON_CLOSE); + // if (displayDevice == null) { // // @@ -955,6 +963,7 @@ public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent arg0) { @Override public void windowDestroyed(com.jogamp.newt.event.WindowEvent arg0) { + sketch.exit(); } @Override diff --git a/core/todo.txt b/core/todo.txt index 12e7309f0a..1b5bcf99c2 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -2,6 +2,8 @@ X fix quoting problem in IntDict.toJSON() X add getRenderer() to SurfaceInfo X https://github.com/processing/processing/issues/4441 +X Exceptions thrown in OpenGL apps when hitting window close box +X https://github.com/processing/processing/issues/4690 X add getRowMap() function _ do we want rows() to not be transient? From ef9dba33b96dc673d647b00d48f2bae7536d51f9 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Wed, 5 Oct 2016 22:18:51 -0400 Subject: [PATCH 040/917] fix edge closing in quad strips, fixes #4656 --- .../processing/opengl/PGraphicsOpenGL.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 5ac46f99ba..574e27fa9f 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -8423,9 +8423,9 @@ void addTrianglesEdges() { int i1 = 3 * i + 1; int i2 = 3 * i + 2; - addEdge(i0, i1, true, false); + addEdge(i0, i1, true, false); addEdge(i1, i2, false, false); - addEdge(i2, i0, false, false); + addEdge(i2, i0, false, false); closeEdge(i2, i0); } } @@ -8436,9 +8436,9 @@ void addTriangleFanEdges() { int i1 = i; int i2 = i + 1; - addEdge(i0, i1, true, false); + addEdge(i0, i1, true, false); addEdge(i1, i2, false, false); - addEdge(i2, i0, false, false); + addEdge(i2, i0, false, false); closeEdge(i2, i0); } } @@ -8455,9 +8455,9 @@ void addTriangleStripEdges() { i2 = i - 1; } - addEdge(i0, i1, true, false); + addEdge(i0, i1, true, false); addEdge(i1, i2, false, false); - addEdge(i2, i0, false, false); + addEdge(i2, i0, false, false); closeEdge(i2, i0); } } @@ -8469,7 +8469,7 @@ void addQuadsEdges() { int i2 = 4 * i + 2; int i3 = 4 * i + 3; - addEdge(i0, i1, true, false); + addEdge(i0, i1, true, false); addEdge(i1, i2, false, false); addEdge(i2, i3, false, false); addEdge(i3, i0, false, false); @@ -8484,10 +8484,10 @@ void addQuadStripEdges() { int i2 = 2 * qd + 1; int i3 = 2 * qd; - addEdge(i0, i1, true, false); + addEdge(i0, i1, true, false); addEdge(i1, i2, false, false); - addEdge(i2, i3, false, false); - addEdge(i3, i0, false, true); + addEdge(i2, i3, false, false); + addEdge(i3, i0, false, false); closeEdge(i3, i0); } } From 0bfc88dc226965ee22129942e8da090a199962ea Mon Sep 17 00:00:00 2001 From: codeanticode Date: Thu, 6 Oct 2016 00:07:54 -0400 Subject: [PATCH 041/917] pre-apply PShape transformation, fixes #4662 --- core/src/processing/opengl/PShapeOpenGL.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/processing/opengl/PShapeOpenGL.java b/core/src/processing/opengl/PShapeOpenGL.java index 45811bbaff..c3c8bf5850 100644 --- a/core/src/processing/opengl/PShapeOpenGL.java +++ b/core/src/processing/opengl/PShapeOpenGL.java @@ -1410,7 +1410,7 @@ protected void transform(int type, float... args) { } break; } - matrix.apply(transform); + matrix.preApply(transform); pushTransform(); if (tessellated) applyMatrixImpl(transform); } @@ -2035,8 +2035,8 @@ protected void setStrokeImpl(boolean stroke) { if (is2D() && parent != null) { ((PShapeOpenGL)parent).strokedTexture(stroke && image != null); } - - this.stroke = stroke; + + this.stroke = stroke; } } From 05208c2625060c43103e03d1b939a65b34858d8b Mon Sep 17 00:00:00 2001 From: codeanticode Date: Thu, 6 Oct 2016 23:10:23 -0400 Subject: [PATCH 042/917] separate current from default camera properties, fixes #4609 --- .../processing/opengl/PGraphicsOpenGL.java | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 574e27fa9f..a1fc96f2b1 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -225,6 +225,12 @@ public class PGraphicsOpenGL extends PGraphics { /** Aspect ratio of camera's view. */ public float cameraAspect; + /** Default camera properties. */ + public float defCameraFOV; + public float defCameraX, defCameraY, defCameraZ; + public float defCameraNear, defCameraFar; + public float defCameraAspect; + /** Distance between camera eye and center. */ protected float eyeDist; @@ -595,13 +601,21 @@ public void setSize(int iwidth, int iheight) { updatePixelSize(); // init perspective projection based on new dimensions - cameraFOV = 60 * DEG_TO_RAD; // at least for now - cameraX = width / 2.0f; - cameraY = height / 2.0f; - cameraZ = cameraY / ((float) Math.tan(cameraFOV / 2.0f)); - cameraNear = cameraZ / 10.0f; - cameraFar = cameraZ * 10.0f; - cameraAspect = (float) width / (float) height; + defCameraFOV = 60 * DEG_TO_RAD; // at least for now + defCameraX = width / 2.0f; + defCameraY = height / 2.0f; + defCameraZ = defCameraY / ((float) Math.tan(defCameraFOV / 2.0f)); + defCameraNear = defCameraZ / 10.0f; + defCameraFar = defCameraZ * 10.0f; + defCameraAspect = (float) width / (float) height; + + cameraFOV = defCameraFOV; + cameraX = defCameraX; + cameraY = defCameraY; + cameraZ = defCameraZ; + cameraNear = defCameraNear; + cameraFar = defCameraFar; + cameraAspect = defCameraAspect; sized = true; } @@ -4336,7 +4350,8 @@ public void endCamera() { */ @Override public void camera() { - camera(cameraX, cameraY, cameraZ, cameraX, cameraY, 0, 0, 1, 0); + camera(defCameraX, defCameraY, defCameraZ, defCameraX, defCameraY, + 0, 0, 1, 0); } @@ -4400,6 +4415,10 @@ public void camera() { public void camera(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) { + cameraX = eyeX; + cameraY = eyeY; + cameraZ = eyeZ; + // Calculating Z vector float z0 = eyeX - centerX; float z1 = eyeY - centerY; @@ -4557,7 +4576,7 @@ public void ortho(float left, float right, */ @Override public void perspective() { - perspective(cameraFOV, cameraAspect, cameraNear, cameraFar); + perspective(defCameraFOV, defCameraAspect, defCameraNear, defCameraFar); } @@ -4586,6 +4605,11 @@ public void frustum(float left, float right, float bottom, float top, // Flushing geometry with a different perspective configuration. flush(); + cameraFOV = 2 * (float) Math.atan2(top, znear); + cameraAspect = left / bottom; + cameraNear = znear; + cameraFar = zfar; + float n2 = 2 * znear; float w = right - left; float h = top - bottom; From 0b3cbab5399ba50e2918c00e35dddfaf152d8d3e Mon Sep 17 00:00:00 2001 From: codeanticode Date: Fri, 7 Oct 2016 05:37:29 -0400 Subject: [PATCH 043/917] remove second dispose() call --- core/src/processing/opengl/PSurfaceJOGL.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index d7f871f253..955a8d2265 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -894,7 +894,7 @@ public void display(GLAutoDrawable drawable) { } } public void dispose(GLAutoDrawable drawable) { - sketch.dispose(); +// sketch.dispose(); } public void init(GLAutoDrawable drawable) { pgl.getGL(drawable); From 89fd67a29a1ce5b5bd44efc348daffd6d9b50c85 Mon Sep 17 00:00:00 2001 From: Federico Bond Date: Sat, 8 Oct 2016 22:07:30 -0300 Subject: [PATCH 044/917] Update spanish translation --- build/shared/lib/languages/PDE_es.properties | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/build/shared/lib/languages/PDE_es.properties b/build/shared/lib/languages/PDE_es.properties index 93c0feb394..1387535c4b 100644 --- a/build/shared/lib/languages/PDE_es.properties +++ b/build/shared/lib/languages/PDE_es.properties @@ -320,6 +320,10 @@ editor.header.next_tab = Pestaña siguiente editor.header.delete.warning.title = No editor.header.delete.warning.text = No puedes eliminar la última pestaña del último sketch abierto +# PopUp menu +editor.popup.show_usage = Mostrar uso... +editor.popup.rename = Renombrar... + # Tabs editor.tab.new = Nuevo nombre editor.tab.new.description = Nombre para el archivo nuevo @@ -375,6 +379,7 @@ editor.status.type_mismatch = Discrepancia de tipos, "%s" no coincide con "%s" editor.status.unused_variable = El valor de la variable local "%s" no se utiliza editor.status.uninitialized_variable = Puede que la variable local "%s" no haya sido inicializada editor.status.no_effect_assignment = La asignación a la variable "%s" no tiene ningún efecto +editor.status.hiding_enclosing_type = Las clase "%s" no puede tener el mismo nombre que el sketch o su clase envolvente # Footer buttons editor.footer.errors = Errores @@ -533,6 +538,8 @@ contrib.import.errors.link = Error: La biblioteca %s tiene un enlace de descarga warn.delete = Eliminar warn.delete.sketch = ¿Seguro que deseas eliminar este sketch? warn.delete.file = ¿Seguro que deseas eliminar "%s"? +warn.cannot_change_mode.title = No se puede cambiar el modo +warn.cannot_change_mode.body = No se puede cambiar el modo porque\nel modo "%s" no es compatible con el modo actual. # --------------------------------------- @@ -573,8 +580,8 @@ movie_maker.orig_size_tooltip = Marca esta casilla si el directorio ya contiene movie_maker.error.avoid_tiff = Prueba usar imagenes TGA o PNG en lugar de TIFF. movie_maker.error.badnumbers = El ancho y alto deben ser números enteros mayores que cero; las imagenes por segundo deben ser un número mayor a cero. -movie_maker.error.cant_read = No se pudo leer %s. -movie_maker.error.cant_read_maybe_bad = No se pudo leer %s; puede que esté corrupto. +movie_maker.error.cannot_read = No se pudo leer %s. +movie_maker.error.cannot_read_maybe_bad = No se pudo leer %s; puede que esté corrupto. movie_maker.error.movie_failed = Falló la creación de la película QuickTime. movie_maker.error.need_input = Debes especificar el directorio con los archivos de imagen, el archivo de sonido, o ambos. movie_maker.error.no_images_found = No se encontraron archivos de imagen. From 6d065e82ca418b7471c39def7b71d462392d08ad Mon Sep 17 00:00:00 2001 From: codeanticode Date: Wed, 12 Oct 2016 15:38:34 -0400 Subject: [PATCH 045/917] coalesce glClear calls, fixes #4694 --- core/src/processing/opengl/PGL.java | 19 ++++++++++++++----- .../processing/opengl/PGraphicsOpenGL.java | 8 +------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index e04de7500d..324c39ff9b 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -636,13 +636,22 @@ public boolean insideStopButton(float x, float y) { // Frame rendering - protected void clearBackground(float r, float g, float b, float a, boolean depth) { - if (depth) { + protected void clearBackground(float r, float g, float b, float a, + boolean depth, boolean stencil) { + clearColor(r, g, b, a); + if (depth && stencil) { + clearDepth(1); + clearStencil(0); + clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT); + } else if (depth) { clearDepth(1); - clear(PGL.DEPTH_BUFFER_BIT); + clear(DEPTH_BUFFER_BIT | COLOR_BUFFER_BIT); + } else if (stencil) { + clearStencil(0); + clear(STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT); + } else { + clear(PGL.COLOR_BUFFER_BIT); } - clearColor(r, g, b, a); - clear(PGL.COLOR_BUFFER_BIT); if (0 < sketch.frameCount) { clearColor = true; } diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index a1fc96f2b1..8ed8d36cd5 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -5325,7 +5325,7 @@ protected void backgroundImpl(PImage image) { protected void backgroundImpl() { flush(); pgl.clearBackground(backgroundR, backgroundG, backgroundB, backgroundA, - !hints[DISABLE_DEPTH_MASK]); + !hints[DISABLE_DEPTH_MASK], true); loaded = false; } @@ -6888,12 +6888,6 @@ protected void setGLSettings() { normalX = normalY = 0; normalZ = 1; - // Clear depth and stencil buffers. - pgl.depthMask(true); - pgl.clearDepth(1); - pgl.clearStencil(0); - pgl.clear(PGL.DEPTH_BUFFER_BIT | PGL.STENCIL_BUFFER_BIT); - if (hints[DISABLE_DEPTH_MASK]) { pgl.depthMask(false); } else { From e012099099a3c3fba03387c089f4d156cb7b7c90 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Wed, 12 Oct 2016 16:25:54 -0400 Subject: [PATCH 046/917] extra logic to make sure that the depth buffer is always clear at the beginning of a new frame --- core/src/processing/opengl/PGL.java | 40 +++++++++++++++++++ .../processing/opengl/PGraphicsOpenGL.java | 2 + 2 files changed, 42 insertions(+) diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index 324c39ff9b..e628b59606 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -272,6 +272,13 @@ public abstract class PGL { protected boolean clearColor = false; protected boolean pclearColor; + protected boolean clearDepth = false; + protected boolean pclearDepth; + + protected boolean clearStencil = false; + protected boolean pclearStencil; + + // ........................................................ // Error messages @@ -636,6 +643,23 @@ public boolean insideStopButton(float x, float y) { // Frame rendering + protected void clearDepthStencil() { + if (!pclearDepth && !pclearStencil) { + depthMask(true); + clearDepth(1); + clearStencil(0); + clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT); + } else if (!pclearDepth) { + depthMask(true); + clearDepth(1); + clear(DEPTH_BUFFER_BIT); + } else if (!pclearStencil) { + clearStencil(0); + clear(STENCIL_BUFFER_BIT); + } + } + + protected void clearBackground(float r, float g, float b, float a, boolean depth, boolean stencil) { clearColor(r, g, b, a); @@ -643,12 +667,22 @@ protected void clearBackground(float r, float g, float b, float a, clearDepth(1); clearStencil(0); clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT); + if (0 < sketch.frameCount) { + clearDepth = true; + clearStencil = true; + } } else if (depth) { clearDepth(1); clear(DEPTH_BUFFER_BIT | COLOR_BUFFER_BIT); + if (0 < sketch.frameCount) { + clearDepth = true; + } } else if (stencil) { clearStencil(0); clear(STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT); + if (0 < sketch.frameCount) { + clearStencil = true; + } } else { clear(PGL.COLOR_BUFFER_BIT); } @@ -669,6 +703,12 @@ protected void beginRender() { pclearColor = clearColor; clearColor = false; + pclearDepth = clearDepth; + clearColor = false; + + pclearStencil = clearStencil; + clearStencil = false; + if (SINGLE_BUFFERED && sketch.frameCount == 1) { restoreFirstFrame(); } diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 8ed8d36cd5..fcfeb4911e 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -1645,6 +1645,8 @@ protected void restoreGL() { pgl.activeTexture(PGL.TEXTURE0); + pgl.clearDepthStencil(); + if (hints[DISABLE_DEPTH_MASK]) { pgl.depthMask(false); } else { From 6dbc82546e1c2403bec85a092e554d1b9d8456bb Mon Sep 17 00:00:00 2001 From: codeanticode Date: Wed, 12 Oct 2016 16:29:00 -0400 Subject: [PATCH 047/917] added resolution uniform --- core/src/processing/opengl/PShader.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/processing/opengl/PShader.java b/core/src/processing/opengl/PShader.java index 61129b184b..545a5acecc 100644 --- a/core/src/processing/opengl/PShader.java +++ b/core/src/processing/opengl/PShader.java @@ -122,6 +122,7 @@ public class PShader implements PConstants { protected int ppixelsLoc; protected int ppixelsUnit; protected int viewportLoc; + protected int resolutionLoc; // Uniforms only for lines and points protected int perspectiveLoc; @@ -1148,6 +1149,7 @@ protected void loadUniforms() { projectionMatLoc = getUniformLoc("projectionMatrix"); viewportLoc = getUniformLoc("viewport"); + resolutionLoc = getUniformLoc("resolution"); ppixelsLoc = getUniformLoc("ppixels"); normalMatLoc = getUniformLoc("normalMatrix"); @@ -1199,6 +1201,12 @@ protected void setCommonUniforms() { setUniformValue(viewportLoc, x, y, w, h); } + if (-1 < resolutionLoc) { + float w = currentPG.viewport.get(2); + float h = currentPG.viewport.get(3); + setUniformValue(resolutionLoc, w, h); + } + if (-1 < ppixelsLoc) { ppixelsUnit = getLastTexUnit() + 1; setUniformValue(ppixelsLoc, ppixelsUnit); From 5ffec75724324ec0cfabb3e1bdbb1c7a88119ccf Mon Sep 17 00:00:00 2001 From: codeanticode Date: Wed, 12 Oct 2016 17:43:27 -0400 Subject: [PATCH 048/917] put clearDepthStencil() in the right spot --- core/src/processing/opengl/PGraphicsOpenGL.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index fcfeb4911e..78d674ab88 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -1645,8 +1645,6 @@ protected void restoreGL() { pgl.activeTexture(PGL.TEXTURE0); - pgl.clearDepthStencil(); - if (hints[DISABLE_DEPTH_MASK]) { pgl.depthMask(false); } else { @@ -6890,6 +6888,8 @@ protected void setGLSettings() { normalX = normalY = 0; normalZ = 1; + pgl.clearDepthStencil(); + if (hints[DISABLE_DEPTH_MASK]) { pgl.depthMask(false); } else { From 11a2db9d2c30235af3dfcbef8e1be78199fa1948 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Thu, 13 Oct 2016 16:36:40 -0400 Subject: [PATCH 049/917] implements PShape PDF recording in P2D, fixes #4647 --- core/src/processing/opengl/PShapeOpenGL.java | 95 +++++++++++++++++++- 1 file changed, 91 insertions(+), 4 deletions(-) diff --git a/core/src/processing/opengl/PShapeOpenGL.java b/core/src/processing/opengl/PShapeOpenGL.java index c3c8bf5850..8fc32a10e2 100644 --- a/core/src/processing/opengl/PShapeOpenGL.java +++ b/core/src/processing/opengl/PShapeOpenGL.java @@ -4664,10 +4664,97 @@ public void draw(PGraphics g) { post(gl); } } else { - // The renderer is not PGraphicsOpenGL, which probably means that - // the draw() method is being called by the recorder. We just use - // the default draw implementation from the parent class. - super.draw(g); + if (family == GEOMETRY) { + inGeoToVertices(); + } + pre(g); + drawImpl(g); + post(g); + } + } + + + private void inGeoToVertices() { + if (inGeo.codeCount == 0) { + for (int i = 0; i < inGeo.vertexCount; i++) { + int index = 3 * i; + float x = inGeo.vertices[index++]; + float y = inGeo.vertices[index ]; + super.vertex(x, y); + } + } else { + int v; + float x, y; + float cx, cy; + float x2, y2, x3, y3, x4, y4; + int idx = 0; + boolean brk = false; + + for (int j = 0; j < inGeo.codeCount; j++) { + if (brk) { + brk = false; + super.endContour(); + } + + switch (inGeo.codes[j]) { + + case VERTEX: + v = 3 * idx; + x = inGeo.vertices[v++]; + y = inGeo.vertices[v ]; + + super.vertex(x, y); + + idx++; + break; + + case QUADRATIC_VERTEX: + v = 3 * idx; + cx = inGeo.vertices[v++]; + cy = inGeo.vertices[v]; + + v = 3 * (idx + 1); + x3 = inGeo.vertices[v++]; + y3 = inGeo.vertices[v]; + + super.quadraticVertex(cx, cy, x3, y3); + + idx += 2; + break; + + case BEZIER_VERTEX: + v = 3 * idx; + x2 = inGeo.vertices[v++]; + y2 = inGeo.vertices[v ]; + + v = 3 * (idx + 1); + x3 = inGeo.vertices[v++]; + y3 = inGeo.vertices[v ]; + + v = 3 * (idx + 2); + x4 = inGeo.vertices[v++]; + y4 = inGeo.vertices[v ]; + + super.bezierVertex(x2, y2, x3, y3, x4, y4); + + idx += 3; + break; + + case CURVE_VERTEX: + v = 3 * idx; + x = inGeo.vertices[v++]; + y = inGeo.vertices[v ]; + + super.curveVertex(x, y); + + idx++; + break; + + case BREAK: + brk = true; + super.beginContour(); + } + } } } From 7445d10718a9b2cdbf7c3b3469d37928e93695dd Mon Sep 17 00:00:00 2001 From: codeanticode Date: Fri, 14 Oct 2016 00:06:22 -0400 Subject: [PATCH 050/917] handle contours --- core/src/processing/opengl/PShapeOpenGL.java | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/core/src/processing/opengl/PShapeOpenGL.java b/core/src/processing/opengl/PShapeOpenGL.java index 8fc32a10e2..8cce642c58 100644 --- a/core/src/processing/opengl/PShapeOpenGL.java +++ b/core/src/processing/opengl/PShapeOpenGL.java @@ -4675,6 +4675,8 @@ public void draw(PGraphics g) { private void inGeoToVertices() { + vertexCount = 0; + vertexCodeCount = 0; if (inGeo.codeCount == 0) { for (int i = 0; i < inGeo.vertexCount; i++) { int index = 3 * i; @@ -4688,21 +4690,15 @@ private void inGeoToVertices() { float cx, cy; float x2, y2, x3, y3, x4, y4; int idx = 0; - boolean brk = false; + boolean insideContour = false; for (int j = 0; j < inGeo.codeCount; j++) { - if (brk) { - brk = false; - super.endContour(); - } - switch (inGeo.codes[j]) { case VERTEX: v = 3 * idx; x = inGeo.vertices[v++]; y = inGeo.vertices[v ]; - super.vertex(x, y); idx++; @@ -4751,10 +4747,16 @@ private void inGeoToVertices() { break; case BREAK: - brk = true; - super.beginContour(); + if (insideContour) { + super.endContourImpl(); + } + super.beginContourImpl(); + insideContour = true; } } + if (insideContour) { + super.endContourImpl(); + } } } From e55dff565036dfa99e3e7846a523614a1a59e992 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 18 Oct 2016 22:47:47 -0400 Subject: [PATCH 051/917] todo notes and switch to 8u112 --- build/build.xml | 5 ++--- core/todo.txt | 15 +++++++++++++++ todo.txt | 11 +++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/build/build.xml b/build/build.xml index b1140e02a2..af092f7d7c 100644 --- a/build/build.xml +++ b/build/build.xml @@ -57,10 +57,9 @@ - - - + + diff --git a/core/todo.txt b/core/todo.txt index 1b5bcf99c2..2a21450fa1 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -15,6 +15,16 @@ X https://github.com/processing/processing/pull/4660 andres X Automatic handling of screen FBOs breaks readPixels() for user-provided FBO X https://github.com/processing/processing/issues/4643 +X PGraphicsOpenGL: camera info not updated +X https://github.com/processing/processing/issues/4609 +X Fix PShape, updateTessellation, matrix transformations +X https://github.com/processing/processing/issues/4662 +X QUAD_STRIP as child shape draws extra lines +X https://github.com/processing/processing/issues/4656 +X remove extra glClear() calls +X https://github.com/processing/processing/issues/4694 +X PShapes do not show up in PDF with P2D renderer +X https://github.com/processing/processing/issues/4647 started X add toJSON() method to IntDict @@ -22,6 +32,11 @@ X had to use JSONObject.quote() to wrap the text _ do the same for the other data classes _ note the difference between this and toJSONObject() or toJSONArray() _ or is that the better way to handle it? hm +_ Add options to saveJSONArray documentation (enhancement) +_ https://github.com/processing/processing/issues/4683 + +_ NPE thrown when using textMode(SHAPE) with a .vlw font +_ https://github.com/processing/processing/issues/4680 _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 diff --git a/todo.txt b/todo.txt index b24b62f5bc..cad77a04d1 100755 --- a/todo.txt +++ b/todo.txt @@ -8,9 +8,14 @@ X clicking the status area when it has a url is problematic X because it's also the vertical separator X at least change it to only cover the text? X add a rollover so people know what it's doing? +X switch to 8u112 for building X more font tweaks to make mono fonts work properly after #4639 _ update the Linux notes based on where we land on this _ https://github.com/processing/processing/wiki/Supported-Platforms#linux +_ "Could not open the url" when clicking on the error message +_ https://github.com/processing/processing/issues/4695 +_ launch4j bug with minimum JRE version (set to 102 for folks who have 101?) +_ https://github.com/processing/processing/issues/4682 gohai X Simplify font situation to make it possible to use vanilla JRE trees @@ -23,9 +28,15 @@ X https://github.com/processing/processing/pull/4641 contrib X Chinese translation updates X https://github.com/processing/processing/pull/4661 +X Spanish translation updates +X https://github.com/processing/processing/pull/4697 + _ library compilations handled oddly _ https://github.com/processing/processing/issues/4630 +_ missing version number putting 'null' in the ui +_ https://github.com/processing/processing-docs/issues/478 +_ https://github.com/processing/processing/issues/4696 _ update launch4j to 3.9 _ https://sourceforge.net/projects/launch4j/files/launch4j-3/3.9/ From 7bdf0910090686cc3b5b50e79fd07f6f4d8a271a Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Wed, 19 Oct 2016 13:39:15 +0300 Subject: [PATCH 052/917] Add 'Jump to Declaration' to PDE right-click menu --- build/shared/lib/languages/PDE.properties | 1 + build/shared/lib/languages/PDE_uk.properties | 1 + java/src/processing/mode/java/pdex/PDEX.java | 11 +++++++++++ 3 files changed, 13 insertions(+) diff --git a/build/shared/lib/languages/PDE.properties b/build/shared/lib/languages/PDE.properties index f1c3eedb14..b70ae466f7 100644 --- a/build/shared/lib/languages/PDE.properties +++ b/build/shared/lib/languages/PDE.properties @@ -312,6 +312,7 @@ editor.header.delete.warning.title = Yeah, no. editor.header.delete.warning.text = You cannot delete the main tab of the only open sketch. # PopUp menu +editor.popup.jump_to_declaration = Jump to Declaration editor.popup.show_usage = Show Usage... editor.popup.rename = Rename... diff --git a/build/shared/lib/languages/PDE_uk.properties b/build/shared/lib/languages/PDE_uk.properties index 07ce05aa55..8ed7188b64 100644 --- a/build/shared/lib/languages/PDE_uk.properties +++ b/build/shared/lib/languages/PDE_uk.properties @@ -316,6 +316,7 @@ editor.header.delete.warning.title = Хех, ні. editor.header.delete.warning.text = Не можна видалити головну вкладку єдиного відкритого ескізу. # PopUp menu +editor.popup.jump_to_declaration = Перейти до визначення editor.popup.show_usage = Показати використання... editor.popup.rename = Перейменувати... diff --git a/java/src/processing/mode/java/pdex/PDEX.java b/java/src/processing/mode/java/pdex/PDEX.java index 6182faed36..0cd9e0a72c 100644 --- a/java/src/processing/mode/java/pdex/PDEX.java +++ b/java/src/processing/mode/java/pdex/PDEX.java @@ -22,6 +22,7 @@ import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; +import java.awt.event.ActionEvent; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.InputEvent; @@ -205,6 +206,10 @@ private class InspectMode { // Add listeners + JMenuItem showUsageItem = new JMenuItem(Language.text("editor.popup.jump_to_declaration")); + showUsageItem.addActionListener(e -> handleInspect()); + editor.getTextArea().getRightClickPopup().add(showUsageItem); + editor.getJavaTextArea().getPainter().addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { @@ -273,6 +278,12 @@ public void keyReleased(KeyEvent e) { } + void handleInspect() { + int off = editor.getSelectionStart(); + int tabIndex = editor.getSketch().getCurrentCodeIndex(); + + pps.whenDoneBlocking(ps -> handleInspect(ps, tabIndex, off)); + } // Thread: EDT void handleInspect(MouseEvent evt) { From 0ee25372a0ae056cc0c705da079a79e56280cc2a Mon Sep 17 00:00:00 2001 From: jordirosa Date: Fri, 21 Oct 2016 14:14:35 +0200 Subject: [PATCH 053/917] The translation would actually say "Open sketches folder", as if this menu option opened the generic folder where all the sketches are stored by default. But what it actually does is opening the folder of the sketch we are working on. That's why I think this translation is incorrect, and the correct one would be "Mostrar carpeta del sketch". --- build/shared/lib/languages/PDE_es.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/shared/lib/languages/PDE_es.properties b/build/shared/lib/languages/PDE_es.properties index 1387535c4b..1d99dabaf1 100644 --- a/build/shared/lib/languages/PDE_es.properties +++ b/build/shared/lib/languages/PDE_es.properties @@ -60,7 +60,7 @@ menu.library.contributed = Contribuidas menu.library.no_core_libraries = el modo no tiene bibliotecas incluidas # --- menu.sketch = Sketch -menu.sketch.show_sketch_folder = Mostrar carpeta de sketches +menu.sketch.show_sketch_folder = Mostrar carpeta del sketch menu.sketch.add_file = Añadir archivo # | File | Edit | Sketch | Debug | Tools | Help | From 4c57d6287a7a11c4e41ee546c8eb2a99135f6849 Mon Sep 17 00:00:00 2001 From: Rostyslav Zatserkovnyi Date: Sun, 23 Oct 2016 17:59:36 +0300 Subject: [PATCH 054/917] Fix null versions in the contribution manager --- .../processing/app/contrib/DetailPanel.java | 2 +- .../processing/app/contrib/StatusPanel.java | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index 4cf327165d..1df2f7a78b 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -461,7 +461,7 @@ public void setContribution(Contribution contrib) { desc.append("
"); String version = contrib.getPrettyVersion(); - if (version != null) { + if (version != null && !version.equals("null")) { desc.append(version); } desc.append("
"); diff --git a/app/src/processing/app/contrib/StatusPanel.java b/app/src/processing/app/contrib/StatusPanel.java index 57d5ce5aa6..93a8a3772d 100644 --- a/app/src/processing/app/contrib/StatusPanel.java +++ b/app/src/processing/app/contrib/StatusPanel.java @@ -259,12 +259,24 @@ public void update(DetailPanel panel) { if (panel.getContrib().isCompatible(Base.getRevision())) { if (installButton.isEnabled()) { - updateLabel.setText(latestVersion + " available"); + if (latestVersion != null) { + updateLabel.setText(latestVersion + " available"); + } else { + updateLabel.setText("Available"); + } } else { - updateLabel.setText(currentVersion + " installed"); + if (currentVersion != null && !currentVersion.equals("null")) { + updateLabel.setText(currentVersion + " installed"); + } else { + updateLabel.setText("Installed"); + } } } else { - updateLabel.setText(currentVersion + " not compatible"); + if (currentVersion != null && !currentVersion.equals("null")) { + updateLabel.setText(currentVersion + " not compatible"); + } else { + updateLabel.setText("Not compatible"); + } } if (latestVersion != null) { From 8a3a183f327a5ee680e1932dd9f123491f75a8b9 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 26 Oct 2016 14:00:52 -0400 Subject: [PATCH 055/917] deal with version number weirdness from Oracle --- build/build.xml | 6 ++++-- todo.txt | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/build/build.xml b/build/build.xml index af092f7d7c..82dec6cec8 100644 --- a/build/build.xml +++ b/build/build.xml @@ -57,9 +57,11 @@ + - - + + diff --git a/todo.txt b/todo.txt index cad77a04d1..ac8ca829a6 100755 --- a/todo.txt +++ b/todo.txt @@ -16,6 +16,8 @@ _ "Could not open the url" when clicking on the error message _ https://github.com/processing/processing/issues/4695 _ launch4j bug with minimum JRE version (set to 102 for folks who have 101?) _ https://github.com/processing/processing/issues/4682 +_ sharing usage metrics about libraries +_ https://github.com/processing/processing/issues/4708 gohai X Simplify font situation to make it possible to use vanilla JRE trees @@ -32,11 +34,15 @@ X Spanish translation updates X https://github.com/processing/processing/pull/4697 +_ clicking "Update" button in contrib manager shows non-retina version of icon +_ https://github.com/processing/processing/issues/4715 + _ library compilations handled oddly _ https://github.com/processing/processing/issues/4630 _ missing version number putting 'null' in the ui _ https://github.com/processing/processing-docs/issues/478 _ https://github.com/processing/processing/issues/4696 +_ https://github.com/processing/processing/pull/4712 _ update launch4j to 3.9 _ https://sourceforge.net/projects/launch4j/files/launch4j-3/3.9/ From a79a57727f654d4a8ce7ba9816c7a93b7333b203 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Fri, 28 Oct 2016 14:41:42 -0700 Subject: [PATCH 056/917] Added related reference to point() --- core/src/processing/core/PGraphics.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 9b2e18cdbc..3ff63bdad9 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -2408,6 +2408,7 @@ protected void curveVertexSegment(float x1, float y1, float z1, * @webref shape:2d_primitives * @param x x-coordinate of the point * @param y y-coordinate of the point + * @see PGraphics#stroke(int) */ public void point(float x, float y) { beginShape(POINTS); From 0036e15f2ed2012dd77c7d3276da95f0397d27ba Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Fri, 28 Oct 2016 14:45:43 -0700 Subject: [PATCH 057/917] Added related reference to point() --- core/src/processing/core/PApplet.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 048276d8a1..dcd9ee7818 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -11390,6 +11390,7 @@ public void curveVertex(float x, float y, float z) { * @webref shape:2d_primitives * @param x x-coordinate of the point * @param y y-coordinate of the point + * @see PGraphics#stroke(int) */ public void point(float x, float y) { if (recorder != null) recorder.point(x, y); From a43f724a8a8ea2757d11536bbde7d9416ecb451f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 09:38:00 -0400 Subject: [PATCH 058/917] make note about 8u111 --- todo.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/todo.txt b/todo.txt index ac8ca829a6..17b6b42fa9 100755 --- a/todo.txt +++ b/todo.txt @@ -9,6 +9,8 @@ X because it's also the vertical separator X at least change it to only cover the text? X add a rollover so people know what it's doing? X switch to 8u112 for building +X switch down to 8u111 because of different build numbers +X https://github.com/processing/processing/commit/8a3a183f327a5ee680e1932dd9f123491f75a8b9 X more font tweaks to make mono fonts work properly after #4639 _ update the Linux notes based on where we land on this _ https://github.com/processing/processing/wiki/Supported-Platforms#linux From 286ebb50024914422782d1abbb4848a771a6a7bd Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 09:38:44 -0400 Subject: [PATCH 059/917] deal with url rollover bugs in the status bar (fixes #4695) --- app/src/processing/app/ui/EditorStatus.java | 20 +++++++++++++------- todo.txt | 4 ++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/src/processing/app/ui/EditorStatus.java b/app/src/processing/app/ui/EditorStatus.java index fed91bbcf6..e59c726dd6 100644 --- a/app/src/processing/app/ui/EditorStatus.java +++ b/app/src/processing/app/ui/EditorStatus.java @@ -78,7 +78,7 @@ public class EditorStatus extends BasicSplitPaneDivider { //JPanel { String url; int rightEdge; int mouseX; - boolean inside; + boolean urlRollover; Font font; FontMetrics metrics; @@ -108,7 +108,7 @@ public void mouseEntered(MouseEvent e) { @Override public void mousePressed(MouseEvent e) { - if (inside) { + if (urlRollover) { Platform.openURL(url); } } @@ -132,7 +132,7 @@ public void mouseMoved(MouseEvent e) { void updateMouse() { - if (inside) { + if (urlRollover) { setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } else { setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); @@ -292,13 +292,19 @@ public void paint(Graphics screen) { g.setColor(fgColor[mode]); // https://github.com/processing/processing/issues/3265 if (message != null) { - g.setFont(font); // needs to be set each time on osx - inside = (mouseX > LEFT_MARGIN && mouseX < rightEdge); - if (inside) { + // 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.drawString(message, LEFT_MARGIN, (sizeH + ascent) / 2); - rightEdge = LEFT_MARGIN + g.getFontMetrics().stringWidth(message); } if (indeterminate) { diff --git a/todo.txt b/todo.txt index 17b6b42fa9..c6074765f4 100755 --- a/todo.txt +++ b/todo.txt @@ -14,8 +14,8 @@ X https://github.com/processing/processing/commit/8a3a183f327a5ee680e1932dd9f1 X more font tweaks to make mono fonts work properly after #4639 _ update the Linux notes based on where we land on this _ https://github.com/processing/processing/wiki/Supported-Platforms#linux -_ "Could not open the url" when clicking on the error message -_ https://github.com/processing/processing/issues/4695 +X "Could not open the url" when clicking on the error message +X https://github.com/processing/processing/issues/4695 _ launch4j bug with minimum JRE version (set to 102 for folks who have 101?) _ https://github.com/processing/processing/issues/4682 _ sharing usage metrics about libraries From 6bdc5ebdc9a66691af89d3a28fef223d88b652ce Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 09:45:15 -0400 Subject: [PATCH 060/917] more todo notes --- todo.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/todo.txt b/todo.txt index c6074765f4..cbb09c0d9d 100755 --- a/todo.txt +++ b/todo.txt @@ -12,12 +12,17 @@ X switch to 8u112 for building X switch down to 8u111 because of different build numbers X https://github.com/processing/processing/commit/8a3a183f327a5ee680e1932dd9f123491f75a8b9 X more font tweaks to make mono fonts work properly after #4639 -_ update the Linux notes based on where we land on this -_ https://github.com/processing/processing/wiki/Supported-Platforms#linux +X update the Linux notes based on where we land on this +X https://github.com/processing/processing/wiki/Supported-Platforms#linux X "Could not open the url" when clicking on the error message X https://github.com/processing/processing/issues/4695 + +_ update launch4j to 3.9 +_ https://sourceforge.net/projects/launch4j/files/launch4j-3/3.9/ _ launch4j bug with minimum JRE version (set to 102 for folks who have 101?) _ https://github.com/processing/processing/issues/4682 + +_ fix the library reporting scripts on the server _ sharing usage metrics about libraries _ https://github.com/processing/processing/issues/4708 @@ -46,8 +51,6 @@ _ https://github.com/processing/processing-docs/issues/478 _ https://github.com/processing/processing/issues/4696 _ https://github.com/processing/processing/pull/4712 -_ update launch4j to 3.9 -_ https://sourceforge.net/projects/launch4j/files/launch4j-3/3.9/ _ editor windows always open on display 1 _ https://github.com/processing/processing/issues/1566 From 1c2787c28401caa5eac12c9be95d497690a637b0 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 09:58:43 -0400 Subject: [PATCH 061/917] cleaning up/testing #4712 --- app/src/processing/app/contrib/Contribution.java | 5 ++++- app/src/processing/app/contrib/DetailPanel.java | 2 +- app/src/processing/app/contrib/StatusPanel.java | 4 ++-- todo.txt | 4 ++++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/contrib/Contribution.java b/app/src/processing/app/contrib/Contribution.java index 4b01c106e1..67c58789cd 100644 --- a/app/src/processing/app/contrib/Contribution.java +++ b/app/src/processing/app/contrib/Contribution.java @@ -158,21 +158,24 @@ public int getVersion() { } - // "1.0.2" + // "1.0.2" or null if not present public String getPrettyVersion() { return prettyVersion; } + // 1402805757 public long getLastUpdated() { return lastUpdated; } + // 0 public int getMinRevision() { return minRevision; } + // 227 public int getMaxRevision() { return maxRevision; diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index 1df2f7a78b..4cf327165d 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -461,7 +461,7 @@ public void setContribution(Contribution contrib) { desc.append("
"); String version = contrib.getPrettyVersion(); - if (version != null && !version.equals("null")) { + if (version != null) { desc.append(version); } desc.append("
"); diff --git a/app/src/processing/app/contrib/StatusPanel.java b/app/src/processing/app/contrib/StatusPanel.java index 93a8a3772d..a048be660e 100644 --- a/app/src/processing/app/contrib/StatusPanel.java +++ b/app/src/processing/app/contrib/StatusPanel.java @@ -265,14 +265,14 @@ public void update(DetailPanel panel) { updateLabel.setText("Available"); } } else { - if (currentVersion != null && !currentVersion.equals("null")) { + if (currentVersion != null) { updateLabel.setText(currentVersion + " installed"); } else { updateLabel.setText("Installed"); } } } else { - if (currentVersion != null && !currentVersion.equals("null")) { + if (currentVersion != null) { updateLabel.setText(currentVersion + " not compatible"); } else { updateLabel.setText("Not compatible"); diff --git a/todo.txt b/todo.txt index cbb09c0d9d..b31d340719 100755 --- a/todo.txt +++ b/todo.txt @@ -39,6 +39,10 @@ X Chinese translation updates X https://github.com/processing/processing/pull/4661 X Spanish translation updates X https://github.com/processing/processing/pull/4697 +X Spanish "open sketch folder" fix +X https://github.com/processing/processing/pull/4710 +X Contribution Manager showing 'null' for PeasyCam version +X https://github.com/processing/processing/pull/4712 _ clicking "Update" button in contrib manager shows non-retina version of icon From 6f3caeb1917afef2ea4e3aca9ba22f5fd4d10a85 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 10:02:21 -0400 Subject: [PATCH 062/917] handle extensions list properly (fixes #4615) --- .../com/oracle/appbundler/BundleDocument.java | 34 +++++++++---------- todo.txt | 2 ++ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/build/macosx/appbundler/src/com/oracle/appbundler/BundleDocument.java b/build/macosx/appbundler/src/com/oracle/appbundler/BundleDocument.java index 94fdde05ec..536732f6a9 100644 --- a/build/macosx/appbundler/src/com/oracle/appbundler/BundleDocument.java +++ b/build/macosx/appbundler/src/com/oracle/appbundler/BundleDocument.java @@ -18,7 +18,7 @@ * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * + * */ package com.oracle.appbundler; @@ -43,22 +43,22 @@ static private String capitalizeFirst(String string) { stringArray[0] = Character.toUpperCase(stringArray[0]); return new String(stringArray); } - + public void setExtensions(String extensionsList) { if(extensionsList == null) { throw new BuildException("Extensions can't be null"); } - + extensions = extensionsList.split(","); - for (String extension : extensions) { - extension.trim().toLowerCase(); + for (int i = 0; i < extensions.length; i++) { + extensions[i] = extensions[i].trim().toLowerCase(); } } - + public void setIcon(File icon) { this.icon = icon; } - + public void setName(String name) { this.name = name; } @@ -66,7 +66,7 @@ public void setName(String name) { public void setRole(String role) { this.role = capitalizeFirst(role); } - + public void setIsPackage(String isPackageString) { if(isPackageString.trim().equalsIgnoreCase("true")) { this.isPackage = true; @@ -74,20 +74,20 @@ public void setIsPackage(String isPackageString) { this.isPackage = false; } } - + // public String getIcon() { // return icon; // } - + public String getIconName() { return icon.getName(); } - - + + public File getIconFile() { return icon; } - + public String getName() { return name; } @@ -95,15 +95,15 @@ public String getName() { public String getRole() { return role; } - + public String[] getExtensions() { return extensions; } - + public boolean hasIcon() { return icon != null; } - + public boolean isPackage() { return isPackage; } @@ -115,7 +115,7 @@ public String toString() { for(String extension : extensions) { s.append(extension).append(" "); } - + return s.toString(); } } diff --git a/todo.txt b/todo.txt index b31d340719..15658462e0 100755 --- a/todo.txt +++ b/todo.txt @@ -16,6 +16,8 @@ X update the Linux notes based on where we land on this X https://github.com/processing/processing/wiki/Supported-Platforms#linux X "Could not open the url" when clicking on the error message X https://github.com/processing/processing/issues/4695 +X fix extensions handling in CFBundleDocument code from appbundler +X https://github.com/processing/processing/issues/4615 _ update launch4j to 3.9 _ https://sourceforge.net/projects/launch4j/files/launch4j-3/3.9/ From de66e5e8e7a12d88f5412af8dffff651ac009d2b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 10:04:14 -0400 Subject: [PATCH 063/917] fix formatting per our guidelines --- .../com/oracle/appbundler/BundleDocument.java | 136 +++++++++--------- 1 file changed, 70 insertions(+), 66 deletions(-) diff --git a/build/macosx/appbundler/src/com/oracle/appbundler/BundleDocument.java b/build/macosx/appbundler/src/com/oracle/appbundler/BundleDocument.java index 536732f6a9..7e26d4391c 100644 --- a/build/macosx/appbundler/src/com/oracle/appbundler/BundleDocument.java +++ b/build/macosx/appbundler/src/com/oracle/appbundler/BundleDocument.java @@ -32,90 +32,94 @@ * Represent a CFBundleDocument. */ public class BundleDocument { - private String name = "editor"; - private String role = ""; - private File icon = null; - private String[] extensions; - private boolean isPackage = false; - - static private String capitalizeFirst(String string) { - char[] stringArray = string.toCharArray(); - stringArray[0] = Character.toUpperCase(stringArray[0]); - return new String(stringArray); - } + private String name = "editor"; + private String role = ""; + private File icon = null; + private String[] extensions; + private boolean isPackage = false; - public void setExtensions(String extensionsList) { - if(extensionsList == null) { - throw new BuildException("Extensions can't be null"); - } - extensions = extensionsList.split(","); - for (int i = 0; i < extensions.length; i++) { - extensions[i] = extensions[i].trim().toLowerCase(); - } - } + static private String capitalizeFirst(String string) { + char[] stringArray = string.toCharArray(); + stringArray[0] = Character.toUpperCase(stringArray[0]); + return new String(stringArray); + } - public void setIcon(File icon) { - this.icon = icon; - } - public void setName(String name) { - this.name = name; + public void setExtensions(String extensionsList) { + if (extensionsList == null) { + throw new BuildException("Extensions can't be null"); } - public void setRole(String role) { - this.role = capitalizeFirst(role); + extensions = extensionsList.split(","); + for (int i = 0; i < extensions.length; i++) { + extensions[i] = extensions[i].trim().toLowerCase(); } + } - public void setIsPackage(String isPackageString) { - if(isPackageString.trim().equalsIgnoreCase("true")) { - this.isPackage = true; - } else { - this.isPackage = false; - } - } -// public String getIcon() { -// return icon; -// } + public void setIcon(File icon) { + this.icon = icon; + } - public String getIconName() { - return icon.getName(); - } + public void setName(String name) { + this.name = name; + } - public File getIconFile() { - return icon; - } - public String getName() { - return name; - } + public void setRole(String role) { + this.role = capitalizeFirst(role); + } - public String getRole() { - return role; - } - public String[] getExtensions() { - return extensions; - } + public void setIsPackage(String isPackageString) { + this.isPackage = isPackageString.trim().equalsIgnoreCase("true"); + } - public boolean hasIcon() { - return icon != null; - } - public boolean isPackage() { - return isPackage; - } + public String getIconName() { + return icon.getName(); + } + + + public File getIconFile() { + return icon; + } + + + public String getName() { + return name; + } + + + public String getRole() { + return role; + } + + + public String[] getExtensions() { + return extensions; + } + + + public boolean hasIcon() { + return icon != null; + } + + + public boolean isPackage() { + return isPackage; + } - @Override - public String toString() { - StringBuilder s = new StringBuilder(getName()); - s.append(" ").append(getRole()).append(" ").append(getIconName()). append(" "); - for(String extension : extensions) { - s.append(extension).append(" "); - } - return s.toString(); + @Override + public String toString() { + StringBuilder s = new StringBuilder(getName()); + s.append(" ").append(getRole()).append(" ").append(getIconName()).append(" "); + for (String extension : extensions) { + s.append(extension).append(" "); } + return s.toString(); + } } From 8c82daa37bd4fb256d7a5ddfe712730d8ef9b9e9 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 10:16:19 -0400 Subject: [PATCH 064/917] update launch4j to 3.9, fixes #4682 --- java/application/launch4j/head/guihead.o | Bin 5259 -> 5311 bytes java/application/launch4j/head/head.o | Bin 34472 -> 35879 bytes java/application/launch4j/launch4j.jar | Bin 187752 -> 197676 bytes todo.txt | 9 ++++----- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/java/application/launch4j/head/guihead.o b/java/application/launch4j/head/guihead.o index 9cc215d9ac04109a46742156d1800aa692893228..7cff132218273deec9fb5fdc56419fea6c20d1de 100644 GIT binary patch delta 1584 zcmX|>U1(Eh7{}j}oSY__CP7bZhusqOs7*JkXF4~T9bSwvB#4gQh#x5SW_~aksVE3h z(sOY*i|EbAx0^9RQ%5aYqsZEz7qzJP0iuE3^%|NTE7 z?{nT$Cvzzi$ttR#-?|f#`JEfXLJVRt5MfOmz@M}bJ34!I=5|Vnp9wtG$cgVZ1oX(6 zlLbtHDG0$5;-prA(as zd#+jy3Nfl0IFvA_Y$-MJeqgs5=exu# zZL~VYn^5EksdDB;W(-5ON6iYRkhuIjg(>9>U3qom74>X-IIAj?_3DLs8y|w(o9X#O zYOPQYyMKrDjw;StyNd_=@bbUpSbmu0+QhWyU7}uUs#^=CT2H-|qv3ltL>G{*11?)y z+ovpYk7+-(q+sFg+D1_EU#eETu+&}A^z(AFQ6=8@3)IH+sy+OotV-N^M&7|CjS%5J zYWiO}UK$IZRFvk@o>@U9|2wV+eM6e~$EUNP)zEY?0-~lgF$$tfp^IA}x?h@j;`=5+ z^H@vb14*$j1JYUh29#zk>uXy;3xvqSvKzRNw}17ifj=K8{3*V3XbaoLIduvoi>w5}3*T36Ft&N_ahz7cg~Ifbv%v$ delta 1496 zcmX|>TWkzb7{|}-&Q7nfYac44NU{FsJIp?u{hj~$?sI0c2`5q6CdrKd zLMJL~l8b|kUBxC{Ng6ZoSI^ka}N<#>Vc} zWLwq9k(ORE$r)j18M%!|EXBvzf7ghW#7bV=#d50F|W1tDNp}bmAUaC~hUBCP)mvI!L zLNNfeKDZBlncI*4-~>~!W#J$ufN@Zhq5n~WsF7!;Vw@iGdXOraGIXBbIW>epiD!v- z_Sl_bJX5O-a#@()evGqJNq#zkOw~^2IkpZp!V5|KOgyq%H2bcex7#%J&S+dOBY9LB zdisOctQYXSWD$uTe5zFIY*g)#W^eFmvU?%W(EJ_!jTEs^gLsmw$(|NHH}YYkT&4>$ zQsw>##H+9T7ULjofCr_yb-Rm{J<<~QlyY=h5+>Bb$QDrM8f;i5>#nUh8K3S>!nvq{?yY9Kly$b?&;XIKEuq2rgHHVV>68}qaY zP$Oyn0ArIu3X6g2i0VL#>2wZgCD9tsZXHOpxdmkEbiCIS_k)t8^?();odvZJ-2#bX z9)jkQ_5>u7dVjP*50 z^f?R?B~;+e6j~G{0@i`V!{P6(&~(pkHAv)G4{AmZQ)O-5aVJQm+YOpeB^&@PAWD07 z$2>ac(It@Z9RP^}2SK8kCm?Z;K7&N$ub>q(DRdbql2ip5|7>D3b?%DrwyMMER>FnC X_XWRMd~y523j@utGx}eIM+1KWG*K)j diff --git a/java/application/launch4j/head/head.o b/java/application/launch4j/head/head.o index a8522f7c8381fa293bca11be384a44b5166213f5..d5d63d666684ab90013bf72c023c27280e3a5f8e 100644 GIT binary patch literal 35879 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 literal 34472 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 diff --git a/java/application/launch4j/launch4j.jar b/java/application/launch4j/launch4j.jar index 7b3d72287c2e9f733fe7eb6e0d2e76b00f0ad861..6daad70f7a903f628519daf3791e8e4cc2897106 100644 GIT binary patch delta 66285 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 P_{jh+lzgTDC&2ta*z-ZA delta 56122 zcmZU418^o?v~6tLwkNi2JDG`Xv*To9+qTV#ZQBz~>`5khziz#H_kDHh>(yHaRo$n1 z@72{22&bL!NXl~H5O5%W|CCayBomORAr${U^1MO(eV)V(O8So=$pDn-UjY0i`A1a@ zN{9M4_{aIbKa8XXQ1ql984&*~ZW06->%U&SU|;?P4q(jxpF3`v5jq$_(j*w%zc%Y& z-~I&x;QxZA0&sVze?(3AaHZh?qG7~5h<}kK+K>Na3|OxJ$%^rcAph0Mk(B-?d!$hR z&rX4+;6HRn-}s+h`Ij$X|9Wh*HUH<4!aemLG81SAhxvQni-z~D6ll?5UCLn3y^grOW#E2NUZ8p72T=F_slJFawzjxz;COKTZkm|YM%1b zYIL_D7G;$-H{KdOF3oCsmJM5%AD+$KU2Hi|SFa~Oc6~md`{JH=jw-Z>0k9w63st0` zpS1S*w+asl+cjqF7lB*FEv9}#-m4)4x}B1P03<|@i}C>hx}BQAAO5gAMf-;1o_Q2N zUF4ga_)S3A^Z4x_jjh*!Fl1|PnpNV38zUZn@j)p!Uj*dy7j8k)FUVG&+JoeHf))EJ zh;de9a?8PZVXg!Nhj?KezOsX5luxkZPTDhqMf**7g4AVstH2E;=GSC%e%jTqiJE>o zqjdcF2lTuvd$b)dmDzp@!>ex9gZ_xS@rPV)zVN%LP1n-3*RnSPu)TE$R)qLqeL(&} zIPXkql-Nr`_8;v*rK5wgg^av$$9MffHs|-y$gh(;FrbC1Y$>8d0awN3fe)C(}yqsMifz*7pRX&%0mW_`Mvn`r}G!$WcS z5`VX)cgMD5Qf0ke<@1RA^W`K6_sz57oGUwPnd?N&QlQ7KHHlSVQ^sK}r=HdMVAG_8 zwjgx>bms9vd#PA|ZYssbZ1tIXQXwsBt7gd4Jb^|k#c@Hv-C@xiAW1o(qHx5aqCRhbOt9uSo8?7LoXeHc$V^y2%c#;r=>&jldrl5@>g-e(M7c{2)er zhXqO%!GV4ku&R%^Blsl+mC_;#sED4E{MV3H1^48PAV3*{(U_hNj7R(O%~5!`e75TMxU)cJsA+DmBKg(goeE z;i)rZaZwF>Q#-A}_^FbE8s8JLj@4&an=1PwI>(qsQ@M!vS9K(6@J~1mny~U8QDHCz zKvXDcmt54N94+LrV%*_V7LnOzuj5YvEV(P0tUvCeoK)yIQ6(O7gr(FOCRWs`Ex!>^ zN8lNXcL1*-ZK!+zk7rGC@d(;2Nh&|X2wEN2a2szfx3p!;r8 zu!`}gP!4;ZUQ8Z+(TfIS9=tYV9EF+10*J(75l6ILax1b`CyM`$vZ_8;5&T&cC zr2M)JRK_2X6;7;>^~vGtgJq6eULf5-2$!CGj{P+;yWDC)f?J@!^Rc={6QGKCJ#a3R z>oAoL?nF*EUsCD~r=K=W)S#JD)--;lSG~4f_to^V7>#{GN)h6lXEo0sEoS3Y`fbh9LBQID?8sV?=x=Q8S}(;fMf>6t30%`#U(iQ{EQ@nb*H%Kx zqQADw(3^Q3S9-stPkpCWzPUMqG`qCF&L|Yn3tHLP>%24jMIAts5|h^iR+`#q)>ax_ zzpB$9^0XK#7V7m>-5f6Qo_oHRmO7w>C78+`HRgdf3J256)d|z);s!9$V#KoHL6hR8 z2|$%N!C=ObKGe_p2F~J;MWfdqua5C99jJF_q!)on>PNJJeAq%`!hU_%gFon!R_kvt zmw&%w9Z;g?4<48ua%F!TxBzQa+2?@VcQ#)@4!yUh;8s;=4|`vvY4n2G=cm(4J1!s+ zx7%c?>`Xl=KrZ}UZwa7hN$^t~7@^h?gw1nASUGW2Cc1m;6`RAfWcgj;-p;X*8N|eq zu}5S$F;+^LAAfm6C2#}LHJuR&A$Pftko<|N{Pd0k

X?Ng*4F5RHm+bWE7+dw$WF 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 z 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

kydpC{8fj8% z)~&^?@)Ym^{X=MkH;#RHx$fmIU=nIn@$tx-K(14d3vu`$0OBhZW)>A{8V;6 z1eVKmBAv~S-gIt{vM1K0B#JT8`7>L3bek46;^r#~7)(p{_O^0Jx9J&|J!gS=Kl z-ivhn2BJAaz)y%DX0Tp&E%LGOq`B1B=Lb)^oOp^C*2$?d>~*j~v(`rB-Ird&|K8TX z8hOi9Cm6z;z$Vj#mXaZEE2kgi;I5Qc-mW?FM|_&s(ze?4;$~_5UtGOqP+iN`1qvI7 zjk~+MySuvtcXzk2gS)%CySuvucZU!pK(OF}$9K+35~t^Owa0+I_>Hgv?MdiR{HEmBjC+aU-QBQ zL}P@-4HqvPsG$e_e@Al+Qrm>Jbc}&bJhCN_mw`m!$8`E_eT zb!iM%(7~$-jzjF!C!EUFV4}G8f*Ma1XoryCs{mg#5;RVVGakj-JW)hRt_4VGnF~D9i~3G3QzQ&@2<^1{y+|rk0#yW>bv*3XzcjO%VJq}BBtrP=I|al#^qsQyukT>K*lnhOXpUS9 zmo{$2+&9$^)W+^KWJPla(mSJgA=EKLIBr~S#je8USZ+3k9Z7y+ZvuS#X7=Zd<>);x zab;B9!?rrJr+506L06a=1wv`HyF?(`fEf!%;-^WI;$x8+CYrJRQ-g z>o`%HUl}W|%ltBo`6G0yu$738ugm3f_jT}^66{TV-8EFlo0sGcLMPwR$)Xw2bD(KtC}jdilW#|O zsx}l2$T?>l_+a?i%*HX;3@QiRLQ(D?qbcPg=VDqs;yU54mlZ-syi30g)a`fo2nKU$=dD;XfR8R#q{M@m(V2$Z*1Aa_1S0p%{%?*0!ScC=P6`R2D z5J4;u;E!+#I@t25J#aqyg@0o$7@=4GS;6lSv<_$5Ei8?`GMK)^npp_)f&_P0x)G2p z3$K3?;9ww@smQio2pD;5WSHm+X!Dx%SBdcM;CZ*x#ZJ z&<0+Wd8c3efJ&Q@?G-Q}tOzDGp(BzACQdwGB`6|jZ)K`sV=`VILHVI_1DY8BubErtSpuh4<#Yz z`&)us6(UL`HT807=p~Tg2q-lfGhOS$mKq>J3 zYXE$rTkK_Sf}ta=+^;lkW}%PADK{fWJ~D)E!KF@t4<=euUM-eyZ8jqS3#)-^yx}QKkG>CW832#j`C<=NFME?@x%iD|7ISyu1CE5L^#XIG0^c5QGxaAF^n?0qx&^ zk$=A(pZ=xKr(s}naFY$VNj3RSa4t{(E{GmJVP<6IOBd$7ATAkO(cy8-n!!I%X&ewc zJokZA`*9G@c_nm-_HDXtA2qdGq)hkaHf)?sEuVOA(Xgm}BMh*~60Trxozu#+aGeBB zpC;sqPaW_9iW%wR5sD0YDVDPN9yzkXcY!ZW3TSNi^UeOW{?2&1phh z5;E?h);hY$=&J9eST9w)HF44^9)6cNM`4-c@j@4KDtV?F8Xb<8=B~=UY7SMcK)Dw@ zdS=VsK5-W_+cRNvOL{fru0^?v)bq;e_TisFG^8CDJ%yTW%H&c8@0Io^Wy}z21bcrx z-KO0!<5<#Ij9WcfL&kZmJNJqR3zPej=fafvvikw{-;Qcy0RU4P4FE1Z;0}P@Zb%Pc_~$F_aZG^Te}K2! zl{o>S|L(5y0IdIAN(cZh{;e2s2m==W-GvheT>X3PRThB#@9VHWNu|L5dDFZKAno6? zwi~YM!Z~ zi=wa;)&KGIf;d2<<$h1HA}OysE*o>&5tz-VVD4_tN|&z3H^#yw zynQu7Na*EKkN?P8cn}yCjz2VV7I@g}BcXjGkJ8fp`#qrX6 zODvNXO9h~THIU%_62}&v78buc#qPGC8Pp6uzE|>OJ zumCCHf4wnsKlATlIEDVoRxGyh(b{Na8%~9|nQqf-+~IVq>P&W$>NMb+!WCCuI9VMN z*i+N6_MQO?OMTdI%nqvwBHH{uK{=fu6h;|rSi^aqmeFX@`|_dHLCelDA07aqnv+yc zjYoy3Kw5rK8E7+O?QID%#`1x1^R6p2HYP%VHZ)G;sd)cFipY%EBc?i>6lj6+a~o8_ zA+E79c%V^O20grASo-XcWS>nM<}9}8*QSxNZr9$LA;_WEk=kZ7h3nIXE5j|F2 zu&_z;tD`$GyuFn-O*We=<6$og&9JG3jJ=T)4Xo|4a}`~*^ZTN&o)gR75Mod~F>r9L z!Kkebs2V8Y8-jQY$%DD+oMYS%F#=H1G3V{UMDxN<={=OPZim@aRSa*yR+hjtDN^5o zp5980Wn;|YsQTn#8GMLGU8Yop49PsmXMz$aPWuFx+BVWHchvv=I`m2bc~iI;`VS2$Z%G=(Rd$y`?ok!G+Msg56U!1 zvVhSWDQd{E+q&DOU8ycxPW^7S*38|CmG<1rT-%qvCb_CU5mxCNtXxO_x}!Px5;Oz9 z*jj{pb2~~(XRhBJww;Xz8h<#ebxNu7>Nm7JcB=Sw9qIizI0FZ@3R;Q1G}=r%EmFM% zj5@2BK*m4yzi(6>`$VN>I!?wAVJBI!3+~-+ohJ<(O9U+W+FzFS5)-uNXvL@gD%b12 z^CirY$AFST3dAOCFZs$=o7o7Z%(+ZTRBP|>=eM=z?2hx)nLW!wRsX);!)j71x;cHt zY14?@wO;Cz0vG_fyIy&%GaDF3u$enQTr%)P3le~e5vx^gUkNIv_kS-K^y6cv+8uyG zuQwB^Cz8QXs5x*$|K&|{6B@~UBXdZPZghkn=-hb#D?>G2ea29e@r1RP`9zc^u@Hi| z+R%?SP=mppdg+HYH3B__hKY{E1@-g&cPnay%{g!&sm&NNEWY}#Z>nf4x?1#*& zok3pE<7AV=u}?8Kl{fK;@)Mlm_#|iBAn;aHhPEBnBmC!))0oe zNEp5;D))&fkQ4jk$qAM+pX@C}4c5suW*+)2%k-g0pY0>|HyhR?3~TcFzES; z{hq_ck~Z}Xv(PGngA^pjLG%~O>ah2dgyX!AY9`;Mkn(=q$nNms_RsR~h|p^alJY=i zG`u%Qc?L9^c#JfbV2c?OPLgDbeV~`Lb0$%U?me(sS`N;|L7NsP|D(|;@VQX-T#k9~_(l2MJLuRWnVA3xa_GpROC6Xwd4Ku|iD*^aLi9VlhWyO^X5d zo|$*`X*2B}#^;>&z=0-;(&(m$?)PUMK>>siILjtvb>xAhJ_7TsF{sZ6CW2BP0z*eq zF(&%MAz{>bc_22(zlvK3N*&4MG36tb~yw(;&z4upMwRSRM0tEc5&Is!2QFq`7AYeXsckVa6wp0?rR{~ zhM^QsN&|sK&~sYh$)2^=u0cEZObHpsb6yR&W&y}W{E7BI)-v5JvHADV^QW~8RFGHG zjg<>4+4Cs`1pkCHdPohc?TM4z^HkVi`RN+e!P6}d?2sus-rEP1XH{xmt@B<@uLZ*gJHAls7h;#-GGHWa$$UhE z@F0JrXo!SQ#hUu;i(>pg#i9c-nc17Txs_@< zs4t121k`D$*`ipZ`r~5yB)0Xnz(#$#S>WK+u#%{Iwpm0D4HQbrwtuwGVh&?s;`0Bh z#`)P4V(7xXkhXuKj-KT0Y<0i>dEG(=(;n1wMq3+Yp$o$|?Km5yjqyQAWnsG4Gu$2{ zM5YqR!0=T#bwMr@$iM=<#DsJkx*M+|z`3FQ>^;Sp5~QHmek{UoMkA8ZNw`h`2j1q? z-H8d*XHaqD`ol3gC{?9dp2E$x@ND2H&ACzzBOsi4)aky~P*1HMKRS5}l%IYv{&5YV#q6&u49}c&cz$!-nke_?u(d{vA2fz)H6gG;(E5i29`KrI#(%QF)G`s=BNn?IY`$`owIHDZ%+(tUbm?G$&9{=+m$gFC`S(P1wDUft6F-Dii*7DQyk(#jvOL2O=;!GEJ?ppt;zkq8(JsEwY zDf`qLm-!~gWXL4*1;4dNhLZ9K6C>>DVBkED3C;$WjtvMhQ(8DD+!qZW1fHDxT-_E8 zAEiv7X!20fIkZ!XdktIuDYxZnINVE{!fItJ>-_^PfA>tt0vrlmmurY~#|qTLUGP>^ z(&|sDq+&xnp#6{;E72s;yZ>^eNtl~fw|SA~GnvKUY+)qYhKO-nh!hJAsydM3%09s~ zMNA;PacBi`*UGt#K3^UzH-aYmdiX1T`sK$2iXeKur~T6ESe=X$G;GhD%JAFjZ&y<~ z&ea63`9mVo6{EB$Pj4uZ-;rUxs&FTCzr-W5sk~@FQ9G|q0B7(PR5owL@thU!AKpUu z^Xf-cb_jK6Bv$^KSISSOmmi8PFLBSC)>Ef;)E<%`Z>K^t&XK;McDR1$9kKFS;ysD< z>m9N7+I*6~=(WFwpz!7vtC3;`V`+3*;&@Em)5p%DGJ+y)fJv>@Gw9%u;C@&|{yN<- z*e;bxiWwAwA1QFE&m9nZ_8$bTCO?`Wm=JK_`%Gaj5j}Yk;*2YloRgdPt3R4=op+3X zl4M-alRtPPTFE@9Ehwue!_GS+b2UPqUh*~)V zYW@vnvE2X!|L$^o0(Sph;`#!R{|%%W0sv?Kp2ZCW4E{qWmA)GRxcJYw6Y}>VW%N%_ zTVKd@lNlSNkJ?r?CZ|l>Xgf+m4yKzz~LMQ z5)Z_S>6fq2i9(?=_pLp2o)G1)Ki}MKd4c(@H>-#_+P0_F4z65JnL3HLa*Ij!9&o%9IyFvM}&{DmPtl(TA4tyM!>9beE*!=SgnIMKN$~1za z5>NSoa%oOkqsCV@i@UwvQ-It`G>%q|FfJb9@+oiTedNgi9VW==g(`z+_oZLPra}q@O>~@v2cM!2v9~kSbbO=X zbZXKUYT^pf@p5YqxgwV~cHj<3P2jtFw|W5CjOAQX`gbYL@xF}=dc(d{X8~HBfpnvE z7L+fU+eO~tWCV0>{r{8kp{D3Z@%zl^@B;sl6~`C=KIoS=x;Dzk4n;!)6RBiPylo>E zD_K%O!IKzNi5PkVbm3z74uiZ7u>0)lwgI{J!9nl!6Ab#bwA@>%e>sn9@ge6O{O{^V zdAX-0x*A6TZ@_vldo#P+$xV0jV?7A;fj&UwPhE^eO@FpRZ$|%OE)ba!!}DSR+{b8E zX7$Ue1VK(iTjUI)^oLmp#5SWznM2+H`|~VnPjue=p}uP#LRHLAe5sMeNo^$J>&7>u z8$EP^3yYb}Fy1?%ETL48V}Y95aT%_RhhH97*ooyaOKjn@usy0pPh_3Wsg@QZ0IQ)>L&DN~j%>%O+aRZd#lq$( z4iH^7=>llY;SYh!&&4la8`|1pmr?`Wf1c z@ilkRG2p=rWp(C(DN1J9eU zT=cYUq(Z!Wt=zc|XPi%7(}WVYI7@PjE47<{UeiU5CjR_hpELIYMs08iOGL^(9I014 zmN6I{ch22Z6Ht3mr6B){uC?vJ5fq-4ZZBk&m4;M2@cnqfj<3$vcDZxR*=2xUPYo&6 zJS!Pqz*AU!anDs53h#Kcqb`@3fSGR+KMG;^*laz8@)-r?;!ZFMM=RuHy3hjCCi)8X zl)>R`=b(7P0<+XtP5W#f$#6m?*EZer&v(6{*2-TcT7Hj8R{Fu;D3Ko@yghFjY z*7xdjRlxEswjC3_*?X6Ec+_@h+L34LRD7?$@J2_BPflnj!$`jA!JueGSoB&JL|py_ z$an24DYx&zPuT*{G7ox3%-4)$36dLRQ%Af?S>hEW^%>$U;~L+|ottS9d{FJ0RGKPY zAO@Qi+f{bv;Jce)84n8&a$J>)%PcRE*PqyJPgHv;^th2}8@_!5p@NW^_Y171@2}p{ zeprcP;Ww|RJibf-Y!P%7Db|xli@9mvNXR-Aw8v?feCh8H-2Ke+wEMLagqBr?W?`df z$V`!oiZE-75T!?i?j!#4FmAf2x*s(0#LyqY)64t2%>w-?tFUAo=A~xkQQaO!W%XAl{B#{rLFNOnb)%azViw}wI)15{7 zV$oq`cxVn#8qtu%Wq1}P=NuNh@1o;N4!NfGnIpb*2Q$e?!_h(}d>0VuvLTKu?r~XT zj7S}9Xdy6wfVN#x)B)Rfe+R!@12ttS}L^Mr>5V2m%R@&&re5xVZiQmnpi@rhbi>uE#YPHqU?ZY#|@M?Qg&=8@t&K%ie5wNUomj&Llv*;Z|XDxgfp}dSYr@b zY}ukDNxFa!wj#b8C#n<`=A?swD`J+B!QEt0`fa~$(*9AFFBJ}V23I$|>*(EN5xwPn zA1WJJ;KiU`ruW(ilalbxi||As*QC=(&vVgt{;ae}UTBtObV5eB`Y6Mhb!K{1lL=}& z(+0c)rFL4a5eXyD36r=Y>jI{B{C zjZ)2`BN`g8GKft0?{Cwh>1;(*$t%-N{~rvr)CVBsx0pfu$qIC-ke{c2z7pB{#-@){ zDt=V2r?XZL*}5RA-~S9dLu4CQ)uy0F6empW`|Nt8^MSUh=6J=D`kbg=`+}Vr>H0OquLN^QKNt*(Q@*& zMIRY-IYMuq`UfdS$8OC@VJ^x%22*%!_U}e6URZ_#Zhq=QWtM1Dh9C6&*CxZ8Vp83DiI1VOX-wZxw z&*Rfg-~$5#bF^@0cC%zopGg65f((?Gj4=X~xV31Ypy}v}NEC2#7ZJzP(a?jFGJqU| z#zQ;uK8c5`iEZDo-%&x(ks|3{P{P+sj!x-gb~w{jbpTE}!kue+Clba>BKux_`L_Lf-E6T)))| zSM)M?9@MSSeW5+6e+ncPCRa#r2D5B~eO`H}qXKfgi8v9odb&SpU2^cUEnE9lb(V@5 zy>VouhrtHpzx?RLe!VO>kZweBmuWD9s?pA-i{dC}Ft;wahe4cUDM*^YCxjRIjW#wF z3*k|t?}66+q65>o1>TDR;>Qi@XkF;1M1A2hJN~Mp9X?4xc6^sQv|E zDbY~b*;VcLzWSbs_^}>brDpepq%_4yO{7{-qJJp;q@ zJw7KW%!xG9lkrv8ucc$S+h8KwNZ9i{-bhOCH?D+}U%l1CIUx=jOU{U!@2_1T!Ecuye7Dv@vqI84R=hXmdK$n!2X7sNgX&&LRK6 zO(v|C*SI1G^)j6Y@y>9}f6ZzkrIhM`r9qDFVv&K0Nr;3y4-?l?^Xw4MO~d@fWd`eo z2JPAr7_cqR?=v{bd$v`X6IhpL)|2casxyG&6pCg?@R78}HgvKPxz zS>!la38^4Y6^^hMK zfJQ8~hx`O6*6Ak~(d4HYY9~5kAHNtJAH;=pvu!4rS||>|u<<1%T^ELUz!AeOcWs5S zV_@RQ>2y`|Wmi>V*4#fV$9379G)r+=RmsjaVBP6z<&%Ecg;{j0K}ih-0Ho9boNk^{ z*w%75X?+?Kj;GK3n_;qPX(73*Gbw4@Af0*~J04P9z3*qMvn_V(T0_qIJBxP!x$PpK z@5=C$NI#^Vmuk*4)w^y2pLIgI?c zZC%zGKxq+X_>rnxnXT2b#?tRT=(&g23(ujZx^p*W7&w(t8!R<3CJvR&$Im67+++H_ z?~KBMW18CXd&;)F$Wm~`=rYwbw3}49()S>bNXYgg@CursyD~%DhG%^4X{L9qnqcyY#eE{??aA^R1 zUZ{NX`hmdef`LV*2Mmlx<^u#MkkKJM)Mxnt3i-PB+Y9j*^=m>;4F7my$f1A@^p3aw zEDe$$Hx9NfXSZW-S5=N^Exu(jIy3?=bNEb&OHn@^5n2cteRFEMeE9r-Lgh_y1@i4o@z_Db zw1!uk;Ut-WW~J8`o?WJ0IO!GPq-bD3i78)VZS3w_IKz!1E9XD^}?Je2ef z7}fp597dH;{30U_9%L^nK}yGHShBIna+u5NHx|VM1J!cWAE^1CT+t`+?uAm->_S}= zHz}5QxUWZ3|U zmm3}6zO>82uqC_|Y^p^Jnb^r?F}N8H^;siz@73{jNf3cNx(Zx3&E#dpUvvaCQ$zhB+*e90UxV_5#PSP1+61{=H`R#;xX+0%&vFr^@b^>1zi(`0@_SwV z?Rz!ja(aLM%lWN(J@!DLt{P_~7AMSEeU#C^$P}qv(?5#e^+{n$NSigjo0S2ypBE&F zDcFHJniR!+U8>J8ebBcYP(Xq%sYN-PO5>_pBXy%Pm=z=-E|J0ra@QT?6W`O_$>a__ z=EI%F-aa4-Zo8QG8|3oOe+90wBVl(LEjtunWgKrr8M^mYY1VG|t~TUQ&Q;tlKv@2q zm~)tJ93c$Ti%iaxabyX>-UfiIc#<0l`qb(j-JEvT+hoz^I?7C(aPlbEUWXb=#=yd| zsa<*b6g$KXcT7%|DcCX1)<__fWak{TJ7|BDU8dncBk9a_P;Mfw0aer1cXMYD=3Ia5 zR`#&Wz9Ear=~WXnTtAR|udelW1EW#cYkQ)biw-E(;E@bC@q(2ftZn@r$vSTHR90&+*$N5q;h=I!yOSgecHHpHqZSym}hUV|PvA zD|3b6{i{>^ggr9tNhwFfv-u(HXt0c4@4CaLzLrY%U(U&Zhm4D0`!97&_=zz#zw2=^ zg4*y}UO@Gcp3RS5d_EKmhxLw3_1n`9Kl6`Ii7b_IgoN;bCR}p2fVfGXi}od*!-95k zaETb*SbhzkGc!=``fo2j9Ly^{D~NEyRIjEUI2^Uea+pVCMJZQ^^iu?G8Djp`E&6); zERO|t1y^{$tfdVj<+=Accf*bL=?mq2r-B*etsLkZYL=ZV5@s<@@~Sfw++q^eyBH3s z?+42}+6ASUA1wDmZ@3KAO2{IXRCa^~DD;KAOdV8U^$UdA@>D69<9Ij&DX4hQwXpV= z`cSVh@=c2;fGdAf{6jgz#tzxtRvK{m1f%v>KcL!=jAtl-ily+|0FG%0XS7gT5O~@! zte#|&;0Qo(m`ZQltu65P#?iO^Qmn|YL0_#&B3;P%g2>b|NSe+_fCeBl^}!N=!8nHO zPzk%DRXr=TNp|5kxeb)M1G3pe3j87v3ijz&qQT!r|LyQVz^mfze!AWa(CPgt0NPYN z2-Ng%o&e}{q{7bt5LKd3zo<;W56?ZHrY6!Cbw|R)XisSvnMJOD|0(JMUV^!x^r_ztYzi4Lu zOXQTBn_fOM=tM$w427h)%kMpOV7}+@cH1xwTQF-EcUzlv5G>5zptdI5p-IioM}tW= z%=)V=a5GA?$<1^yL3-Zx)=9z@z6i6BBx`}J6^4!~IAcg0b4gTS$c!%{I!By>cEM6( z20C$!KwLU@m#u^;XcmPJ%CE1H-jzw*Y4(m+k+=B+bROqGs4>Q>rVN3bl40-v@eynj z)gIbSW96NhZSFaGSe~5R1}`~XqoDBW!m9# zKz>L~xX`5cTx;Sl(ZL0=<<=su+tXGd%yKL^hcBDtFR-FK1(TWNC~aL0sfKcE)4BQC z-GcnyQ82$)nlsr&bqcEu{`z~CV+mQqVUKuQ{Vq8%TftLGJZ>4MATh5#Ct1l3UdZ$L zTDpE-IW==`H1Toc)^7AVi5xH(ltM#xymSLyG?0A0{(NnEgVP>?qmsb;903=;_^W~CFpmpmaaS5xkQ6KPK5)OKg=aVm>gu!YXQ3hA?88Nn-o$; zJa)U{&X#nh#~Q`6bek+90YiqU*(0N+DcaM{Z0X8BF--9=%#hxw0QYk`<5G#DNrCOB zOC(A-kfuP(WIGEhL)gU;(6des zDe<=JCx|yqLS19PQ|1;N@9wr8qq-X2 z?TxxEEm|zU_u00v{N&%P8rFA>5vt$u|NB>$x^Uaz^oj8Sp!vl1`!~ywj*|o+`nR-Q z`vuNlV`W9ys;Ou4NOS@v?Hd`LOh$-;hzMm+k}(Gg7F;wqrjey#Qs86{&z;yntyZ;1 zW%r_3ZEJRgWHdsu@%iGcmV<+V-A=czokMkNcI(UExv$BYvX*4U{qe_jR^3+JCw)F| z!!Sf-MV&;-aEcc3ab+S>p`b;K$rc?v#WF+ORGH#m0#S%IQhq)$>GB>#(-wHI?sUg4 zeCc=IHdHd~3)9Kw-D2gu0vprnCBhO%;vQA|m3YKuOBi`ocN{|cN8}+d8YZ44V@vYi zxWrG2KSz-Hq1x2SaRua!-|)20G$vQrGHYF8l{5(wWNXLVdIYpjia|bkV|Slj`_tp6 z8pGq~{shd+9ZKa;Oz}q+Eizf7hC+kW)V4hm<&sPbzRcX-K9ytCXBu-WhK~2QlX&?> z>cwCT`&7)#cek#w*&ez~VDvpbYDb!UwTHH({hQO}zCN*IjC{4nwy|sHEkx3zt9-F* zzn1Avb_dFRIyGNn4MDpU+2zrua|sKXl=CN+Hs6yfX%(}_M03UM&$ho4^0m5^kD27Q zU1Qm_$)Te@ce%$k)w*%#*Df6s;E%d^nlF=^w@tRJO>aRNhr@ctrO&12-nk3qGbj9H zZ}Km!xNKh3FIkfGZ_N1ZhG$fCQ_5$+Fy5IV%sgw+^tE%}pb&JEDt3l|XH>eBx?Oy; z!e=llXxJz9&7Rqa{&g*~W({Esap+7c)@jk38l4qaaiId!E+XTm1M?Fxv}E?mB@HsS zfzSbIoDd;f!NShBXn1XG6#o@ zc(KcP3^Zfe*(^wP8g66@0=1bM?;@w2a^CTC_WN_>TLiv2ZnAr$@lvK2?gDOBZ^q&0 zgGdiI!6ht%-mf|csXc;Uk*kk9afB9l!WdHq(DN0uqWqggSJsf&WnakMoMZwyP2d&G z-28Y{6_qkFJ)$&rT3~T zymo@>Cc%V5B`v%Jty&N6tzQ~jEwfebIJZREn|5PDE%Nlu?XG)xU_y9p{N~TG*uQO^ zVvPeG4NN@gbz=J?w!s+Pb(FGBR8xtI!xiW;h>7FEaz_*9&Va+M@Q0$-McWn*4}5{8 z2Tb&MUY|6Do1@E?G#u7Rv8lLhZ9J@}wT>m2q?QiNMM}mM;w!UwgLS(s7hRj~e3H^% zBr-W}h^e;`9V9c5_+hbgR8CnH35Mz_r!N|^f}%*<;Z$07!miv16uvApw(+0(&f>@r z>SdPxXmjQ$IhAUUlq~-K(m=>6nbZOoI{&5|I_VC2itzs9XjFcaUVx8@hK9_m4B%!& z$XX~p@Scwe#p7$F_JPWa$`y05v@RxuZf|3MMjm5R@8kV4;OI;h?9_@G9W7~ULy#&^ zFX1SmD{()EVqpKdC}qnUEJ{z5AE4mCxHMxg{xbrL^kl;@dra^Fecw@`m{6NPy^@W&B{t|} zLkMP(I`L!~e(BlA#LA9I(jrb}Qaemxq%+9dG{EY;!#|76y9Gr*m3r{a%`fV`XLD0w zWzEul7F&E7gr|wr56&hNG}xnDkOw65jotyFBk0CnQ6>XwP+5Ze6#Wo=^YYlOk#`*D z3Ej&@K?U4E-&jNLQ>L!10xOG0#m({?reLqTbi}^QUE`{VM+v(G9J``6O!gx!{JQwK zj2-k;8W&T+4)H$IYsNQCip`52r+Kiws+%?7J0ECx-zkU^BtK#6*+T{Y4D5@2!~yy9 z?*(#Z@R>i3A@(KbnPd^RbOZGG?D;X;4g(_`oMK^;Py!Jh_hLpV7gUNZBnKiNSfN}= zJc{pKh6V?0+l3uGptHvIxV)M7M%_mSTOH@uPJdNIyXx0M@6GNlc;^p3UiZ?NNl~O7 zOcdq30{ikGhtFY7gaoVI(ExD4ub_^PqY>dRbp0!q%V^gS(82={9q?hnRuiFx${|HM2k-*!Ndo@3z;S~%W>}!U&;pe zu*aVQdB!pt^s8<}md|U?u%eD_Xw4Zj6b7GZ7^>enPEms>N@a<-qO{T{pFkYwtvnMJ z0Yv()seQo&Ke%QN3$TRY!Y`t>_KBm~;}x51lErq8*;!}D4K8CdcXr5@f&_SuYo1^f zgIqU{6Ay6WFufKTZdv74#fJ-=794C+Wf6~?GE*$grm{;d6YK-5CZE4&W}Z+QU&lYG z>M*7*o?q%rL~&;Gi)b7XczsU!P9vR`jk@Zuc-n+6L0IOXreqjb1l~Mx(VvVp- z18Q%afbWcZg*U%}?}8tL``l0QG-tp7b&41CJ(Kx4$OA@~ye5+aLeMX^r@6PbK~UjI z!sAjmY5QU|TvutHsPYm!-p5J-#2a_;-hmh5JAc2`weV9u^hflE!!>9iaxb02(cDn| z`uhQ{IB(ABMgLpi;0HP!3<>E~)mmoUJBCGF&b6!t^>bQo2b++|LZq74=7mki)gs<` zB%cY4N6{d0l&`QD7w8T}*sZ>@caSag1bSk2}nj{k5hl3&+Rr zZ*kYAI8YTUtUu;6n#FrvZoLm@r~Zi0SJ~SpZMwL|A$(13f&lFj^m)tq!{w)4^B$U| zb`lkc*%1t^jn<}GGFU!#nP8;D!;o$52=2&}ddZhZ4w3yqN(gs(;gLS}MLI?cNHOEy z>eZ?Nhf)s{3kRHeJB{Z&g*6DMh5rclP^6!sQ49KE2+KV(6Rv?o8^ivvjEYdB!|>-t zdc78!9fpCixf1?fduMB4#jZ=fV;M@GzFrUoEI0?Eg5@xY^f%w zfBW)BO;;l2s>~NWec%i9uYxIpx+dC3t3X+DLHBK|N(K;6%bYzN&uFT#00CbnxD;s> zr%`eIF9n53=UAM?g@f4GH!QsxNA$6#(Qy*)B*K*A4%>``OmK4;EtTI)Mh|pxj7(WG zuksR_F&xpmy!5_?nX$tJ43 zdiqWxuaGIy$0k&>duC&;nxe!IX}X9S#Z#1htrz!{8gZJb!3Xis5cMBtf2gaLhX#Fi z>0|An2#+S^RQ$H@v(mvvHAuoZWcvtU^+RqWP4bn)v$V49!G=FP*eX&`(P+Nw(IwiD z8u5a(CTgL^wJg7mpp3f+Z~8JqR{C*bO&^H~anF4J^`fYia*Md$2(#3veJC!+!M(Zk z*!|kuOY|heE_qH)OsJ%8Lyc-vG964zp5LRU8DAcC{y2YG)gOE%@jDTjp{hUnN=i6V z?v%eJKI3Ze0*-DZ!rD#vEEEp!nBBkl)n*1122STd7%lvjqb+|5{$)~oUHQoW_%DZ$ zD7rs7I)@E*EKxz!s!&!>_&s=5&;sdS_fs&%(bI-k>rEoO);B}Gq5J~!->M3_)`CbX zB9Er};>GihL!wIMYMTn-i(l5+ZJ?nlBR9eEq1|B|3Y7Sg+vdN1;}WreV7V&)n?bn@ zk~@Hl#rspcSYb3gh%^r|8BAEjgNC^)zx0s!wo0KNy<&^K87PYBtwhFbPS&@$C%yC+ zf}_}jK=HD;_(8p}-&oit;HuaZBpPIC+T5gB){ORJyrc?~W(6+mvOgalrlM>G`?P$s z2*yUqF3`zQ-mdWXX_`=0dciZ8Ay_Q|s5w6l>Y|avGv|K(NvyyAyO+Q`v~^-pZ%4e+ z`u=0?sa_G*uNBka?v7=zBwc%rXzFUo1lf7o0Hb85%uT(zhpd&nz4oDYwc0wh>gvX> ze5F6w_o}M!F0u8Jfi;>Wzc3ELYQsD5AJoBXyf(pFP1{&Sv(2d@`j*h$rCinaLHtX( z5y+IMHI~3x%$3?l^{w@&<_Gm`V6d4u4)kA5o!YSv6;;S#k}y$V_0EcMkXXR!NSE|; zHO>WDR#+RpVHXlnZy?p;221UTC;`)td9m|A^viF1_)>pS(pP?Tew#Nztd> z?yQ26>GRp{xPL>L%0cs(4E?Hcpz`WxnXWLqGhIW8wHvgqJmo@sZ>XJ#@&!eLl3ahd zuaWfy22+2^I+*~z5xgQ?^TGEhtoztY!#FpSDlXS{nwYk+Z(gfa2%iIQ|Wt}5n`AN;w5F0O^vF8@dSn_uxB2%Z}jeh zo{)x*+JBN`oqsE3i)!J_)~Wz(Dw2D)wr?n89ph|P6^&MDDavSJrm3<@q#io zhRg!j%MS2TU%J0)CKOT5q?kWQy}#)#&*8UDH1*=casvT+%6 z@*SZ;$JM(Pk4{+#M94jO><-P=chB})glAgcH*@@yjx&8%@LJCM6ECg!fIfMjaml#L z7RLeC-kq+dg{W#fWH?W>A94lTdG0NW!50<7XlUn_Eoqv*;DHWp%1(x)o_=&zz03$Q zrdMV0i*q4%in#j_yAhZWgsv1b9aMgP;eMpXJvigiY3bu6s9mBsU3v8sQ^6=S%m~6| zt%#qr%i6z9xKa!q_9E+}ile8KjyBA=?<)LWGiC`J%!V zX$~;HPxw9T1fkXmfKEA-Rj=SSgsPX6jC8s!}q-JnHgU9o8QmR z>v{g?|19Tu&pR{Da{uH0z24^r-}d;FAKvnvmmXvMC}lZ96oJmB}Yea zYU0UlLtiybIAD}_MzJ|fq4|~JjObfPbGY%I>f)m&r=O%oW2@pjc9OyCd{-veS$dTV z@!g@(z3z|hi6X}r4fQPZ&F7vi6|Txr4Blr}`Q*uYZuO|n4eA|hpB_(ac$=)<{A1lZ zpX%GGs~vjxCr0#?)?VH|UOPCkOszXse8)*}#BbG-px#`|?dwyr(`Ft$HIwTSt$D01 zLNY9UoZ`*xJsTHo>GA3PGk-`%_Wh&Fc7)ZGx1{JlRqQZ&kRst7|K8A4uK%Z7 zSDD8;$E?Y-g{h5GZ6!O5O2hNUsH=Z&th5>X-sHvCP|qCq%WbA^6`g@O#+Q>!P5!X) z-JBEUBgnBYPFFu3>F+abL-4MOEeblqBJZ~a$4rGayDpw{-nGDP$>^w=)?*vYHf_v2 zk(}mLf3|2}N$~Q3l7Iq_ad!^B8fG1Q@ty%P$L#cw0>_wT$#(KilA)xpbwg z)+&qhC@$SqdsTT>{f+Z>7Pb*N=Q7>&bCnk>Z*1uPD2hA5F0|jh_1QZ2cswsL#5#WN z(;+Qg?^o{Lm};I_=>Y%7TN+o|=`j0^Wx?!pqv*J!4+A5x=A|>Qw-!d4uA6UPfosp4 zE;$ogy+2+n*G$m1vwPd~B0raJ9j>;)FSWut18mo4<+_GDc5G}tmeA|6Wln;^2tDER zHHNO<*DYt~x;eSjxZjLUepAS4Ua;v@`@@%qdwr4~w)-@nn8hETz2*03_eGNB{@q@S zljEv0EW%QP#&4aYRrf4#$gkhdi_TarIJ3e9xoUjgKHe+GKhI1MoS&CEEKMt>{>H_i zXX2o!ylXG2tG67FJ=E}g{*>Yblx7U)^E}{1P2-Ki=uNtFmur>y>8p?`j}Ms=W5=nl zHxyV6THnwVSz@?2sX-LC>zl4!iT2E-k9(6d>t1y?Uz;>xLQ|T!>UQ;%mPJa%wLfkg z`CYw*m#x`(*Z0B|Wn+QYb^C7yp)O_liQ)psUsNNF%6$3jl`Y`d#$%p?grnnjE4b)v zRJ-+8liB__J|8(MOo#L2 zac(~Hpcf9{a0$}IMiQh=6mAk^L#{w!M001_ct{PhqvF9A87mSrVq$}s9`Z+$Me64pdTrQO#Vt0 zrr=et(P$dve{x#aJ)l#C)mMBugvCk~p21gMqp>tdGV0*ks{q;zAY%sTB<_BV>}ilj zWTVD2a7qtMnlnKA@boum0`2|b@TmGMU~z|m(wYG}u~5WbGE{#0-l%@Y)Ef%ZBhQ%^uAa{g`dcurw7Z@hJHS{ggMbD5>B$B^BA8 z;9_1mL`B)cHszpkI4KgJ8qMewN@@FU|I4}HasaqIiV<8*x+wOX2}vV`+;(V?axoxJ z{i`Tq&eKM%FKXbr62zqg41X?+p%%?6!uncf2_3pbJ3hYx84~wmD!{$OYof?XU7S&Y zbcpnCN@|)(Nky--w6IO3EF7zMpgE95YkY60;C1h0-6xea2^=4CL8>P@mZyn(s$_PLP#Vn_wC4FsHCjW*+J0+E zhy?C}2-x1;j=^4@Poc3z6*3|0Gpc}t{Tif(IH3v|5a}gKT2uj2hko`{szGY^9;EuB z+7Bc9X~HSZosXc=6-9hf>Fc9wpWd2N85hGIC`?Z-eWB2}y&9Pkn?^O1CvCKJZjDSD zOG%gZ($bM^wkqEIMw-HfLzJ)n1?hVXW0(~q$d^NKQw?&aQ_<{x-TeY|yD{9A%pt8> z6^GQqTCY-VU=@@BD>Wu;KI;+417~N$ztxNxtP%}^7wfUP|EgNEvhT5CFjE6rw`Vl7 zH36Zy>|L?^GdoA%V7T zVQXOCducf_j+bZP-IwAeU*NQP%Lb%JQ!`FhV?bAKB+!@!*;ta&0CB4biCA!oJsdkX zNG;AAo)-`TWtj%Sz>`4!N){;S z`sZh4LPOPj;^v))N9TOafsX%{N1&!(kUkA%97@4pjmoE>PBez z`oeEP1{aDe4XVb00nPhJLA5Y{8B)Z&;qbA_utS>ZeZt^17XaJ{Kg^yn`_ivbVk0u5 zjm)`fc#8u=(L@-ErZ9{cH1@-9(?BY?tr1xnQjagj_E3yQzu*w6-e|{yn`D&~+XUTq zt+OAWvLW1+{4Uw!;2j0n(?b9etuXQFi#bxmmd!|m)PrX;01|r#0^*zD9Sr5sP|fRy zOJE3~2JEQ}k1z*ke?`^@zslYRjQI*wg-S#!-HpnaCfT>ApnM^Wg16w=GmSwKGK7N9 zA-?Ff0D+MjO@QMasD6+K5>M&Qk03fp3*yuHYW>4GJrTTXgr4+f5Nl!2Cg?t!Z?bp6 z|NRC8N_vD~-9%)7#ouIEs-Sdlc$97o9^H!6i9a5#Abx2|iS_ZOR%!JVHELX10gvfx zV0Qw;X00U!)x+XeWI-6ZDTY&Hh`1vVGB1Dcp;>*|#t&$0frdF2x!K~#HksR(+JND2 zJ4#}TZRemt|9Z@%Z_0|j4AtxmJ;WUULdRjFb~J&wvalV9<~R~pCWatYx(Mj*VQkFB zh$z5`;J>sZHySG6W(dY8W>tT1l~d~|OGgeLhGyf&lDhcem{U+x9nyM?xq?qlIw=zly0O>JEGq@zy2&ZPz^uK z%KB*;e$|bf=#PNZ8h5PLgR~HI6i7{}Rqm!VLEn<*ff*}UNuaRES*I^@`Pw?T3#s)@ zvRA6`+**Q%<#yWiP)ctE$5;=A-Me5tUTiP2rfm;gq0+~tvVm}=U^J4pO@~3v2tUB% zXra!ZXf@36Bti7e{2b`i$`~0^Iv146I88>)n>)}5WXA-=mNlD03Uc7&sy?@>ggBDT zk=|q%*c@GSNJKT($5m_&`IvAJfzB9YpBmFq_kP_o$B5p$* zKAjiFH-0kf@H Date: Sat, 29 Oct 2016 10:17:25 -0400 Subject: [PATCH 065/917] move some lines --- todo.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/todo.txt b/todo.txt index 86c60bbea5..42f05377ec 100755 --- a/todo.txt +++ b/todo.txt @@ -23,10 +23,6 @@ X https://sourceforge.net/projects/launch4j/files/launch4j-3/3.9/ X launch4j bug with minimum JRE version (set to 102 for folks who have 101?) X https://github.com/processing/processing/issues/4682 -_ fix the library reporting scripts on the server -_ sharing usage metrics about libraries -_ https://github.com/processing/processing/issues/4708 - gohai X Simplify font situation to make it possible to use vanilla JRE trees X https://github.com/processing/processing/pull/4639 @@ -46,6 +42,10 @@ X Contribution Manager showing 'null' for PeasyCam version X https://github.com/processing/processing/pull/4712 +_ fix the library reporting scripts on the server +_ sharing usage metrics about libraries +_ https://github.com/processing/processing/issues/4708 + _ clicking "Update" button in contrib manager shows non-retina version of icon _ https://github.com/processing/processing/issues/4715 @@ -56,7 +56,6 @@ _ https://github.com/processing/processing-docs/issues/478 _ https://github.com/processing/processing/issues/4696 _ https://github.com/processing/processing/pull/4712 - _ editor windows always open on display 1 _ https://github.com/processing/processing/issues/1566 From 24a4264ec40b90f9603e7aefe25deb68bc6ab295 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 10:38:04 -0400 Subject: [PATCH 066/917] add notes about getRowMap() --- core/src/processing/data/Table.java | 13 +++++++++++++ core/todo.txt | 8 +++++--- todo.txt | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index 796491dc5b..4f6ede76cb 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -4440,6 +4440,19 @@ public Map getRowMap(String columnName) { } + /** + * Return a mapping that connects the entry from a column back to the row + * from which it came. For instance: + *

+   * Table t = loadTable("country-data.tsv", "header");
+   * // use the contents of the 'country' column to index the table
+   * Map lookup = t.getRowMap("country");
+   * // get the row that has "us" in the "country" column:
+   * TableRow usRow = lookup.get("us");
+   * // get an entry from the 'population' column
+   * int population = usRow.getInt("population");
+   * 
+ */ public Map getRowMap(int column) { Map outgoing = new HashMap<>(); for (int row = 0; row < getRowCount(); row++) { diff --git a/core/todo.txt b/core/todo.txt index 2a21450fa1..1c7a3f316f 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -5,7 +5,11 @@ X https://github.com/processing/processing/issues/4441 X Exceptions thrown in OpenGL apps when hitting window close box X https://github.com/processing/processing/issues/4690 X add getRowMap() function -_ do we want rows() to not be transient? +o do we want rows() to not be transient? +X write docs for getRowMap() +o Add options to saveJSONArray documentation (enhancement) +o https://github.com/processing/processing/issues/4683 +X made note in the docs repo contrib X Call glGetProgramiv to retrieve program log length @@ -32,8 +36,6 @@ X had to use JSONObject.quote() to wrap the text _ do the same for the other data classes _ note the difference between this and toJSONObject() or toJSONArray() _ or is that the better way to handle it? hm -_ Add options to saveJSONArray documentation (enhancement) -_ https://github.com/processing/processing/issues/4683 _ NPE thrown when using textMode(SHAPE) with a .vlw font _ https://github.com/processing/processing/issues/4680 diff --git a/todo.txt b/todo.txt index 42f05377ec..ff80bb6e70 100755 --- a/todo.txt +++ b/todo.txt @@ -20,7 +20,7 @@ X fix extensions handling in CFBundleDocument code from appbundler X https://github.com/processing/processing/issues/4615 X update launch4j to 3.9 X https://sourceforge.net/projects/launch4j/files/launch4j-3/3.9/ -X launch4j bug with minimum JRE version (set to 102 for folks who have 101?) +X exported application doesn't work with latest jre X https://github.com/processing/processing/issues/4682 gohai From 9de90312628cf1a79e691fc9582af850740e26ef Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 10:51:38 -0400 Subject: [PATCH 067/917] go back to textMode(MODEL) is native font not available for textMode(SHAPE) fixes #4680 --- core/src/processing/opengl/PGraphicsOpenGL.java | 6 ++++++ core/todo.txt | 2 ++ 2 files changed, 8 insertions(+) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 78d674ab88..157d251182 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -3567,6 +3567,12 @@ protected void handleTextSize(float size) { @Override protected void textLineImpl(char buffer[], int start, int stop, float x, float y) { + + if (textMode == SHAPE && textFont.getNative() == null) { + showWarning("textMode(SHAPE) not available for .vlw fonts, " + + "use an .otf or .ttf instead."); + textMode(MODEL); + } if (textMode == MODEL) { textTex = getFontTexture(textFont); diff --git a/core/todo.txt b/core/todo.txt index 1c7a3f316f..051c590887 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -10,6 +10,8 @@ X write docs for getRowMap() o Add options to saveJSONArray documentation (enhancement) o https://github.com/processing/processing/issues/4683 X made note in the docs repo +X go back to textMode(MODEL) is native font not available for textMode(SHAPE) +X https://github.com/processing/processing/issues/4680 contrib X Call glGetProgramiv to retrieve program log length From c4c2cf89fb86df4c4d0afceee7809ef4a061f697 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 11:07:59 -0400 Subject: [PATCH 068/917] more notes and get()/put() stuff with JSON --- core/src/processing/data/JSONObject.java | 6 +++--- core/todo.txt | 12 +++++------- todo.txt | 4 ++++ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/core/src/processing/data/JSONObject.java b/core/src/processing/data/JSONObject.java index 4c4d263293..1c15b3aa12 100644 --- a/core/src/processing/data/JSONObject.java +++ b/core/src/processing/data/JSONObject.java @@ -897,9 +897,9 @@ public boolean hasKey(String key) { /** - * Determine if the value associated with the key is null or if there is + * Determine if the value associated with the key is null or if there is * no value. - * + * * @webref * @param key A key string. * @return true if there is no value associated with the key or if @@ -1334,7 +1334,7 @@ public JSONObject put(String key, Object value) { * @throws RuntimeException if the key is a duplicate, or if * {@link #put(String,Object)} throws. */ - public JSONObject putOnce(String key, Object value) { + private JSONObject putOnce(String key, Object value) { if (key != null && value != null) { if (this.opt(key) != null) { throw new RuntimeException("Duplicate key \"" + key + "\""); diff --git a/core/todo.txt b/core/todo.txt index 051c590887..3413a4c514 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -12,11 +12,16 @@ o https://github.com/processing/processing/issues/4683 X made note in the docs repo X go back to textMode(MODEL) is native font not available for textMode(SHAPE) X https://github.com/processing/processing/issues/4680 +X NPE thrown when using textMode(SHAPE) with a .vlw font +X https://github.com/processing/processing/issues/4680 contrib X Call glGetProgramiv to retrieve program log length X https://github.com/processing/processing/issues/4659 X https://github.com/processing/processing/pull/4660 +X JSONObject get() method is private +X https://github.com/processing/processing/issues/4334 +X https://github.com/processing/processing/pull/4336 andres X Automatic handling of screen FBOs breaks readPixels() for user-provided FBO @@ -39,9 +44,6 @@ _ do the same for the other data classes _ note the difference between this and toJSONObject() or toJSONArray() _ or is that the better way to handle it? hm -_ NPE thrown when using textMode(SHAPE) with a .vlw font -_ https://github.com/processing/processing/issues/4680 - _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 @@ -53,10 +55,6 @@ _ https://github.com/processing/processing/issues/4622 _ option to disable OpenGL ES on Linux? _ https://github.com/processing/processing/issues/4584 -_ JSONObject get() method is private -_ https://github.com/processing/processing/issues/4334 -_ https://github.com/processing/processing/pull/4336 - _ textAlign(CENTER) and pixelDensity(2) aligning incorrectly with Java2D _ https://github.com/processing/processing/issues/4020 _ add increment() that takes IntDict to merge things diff --git a/todo.txt b/todo.txt index ff80bb6e70..cd83a648ab 100755 --- a/todo.txt +++ b/todo.txt @@ -40,8 +40,12 @@ X Spanish "open sketch folder" fix X https://github.com/processing/processing/pull/4710 X Contribution Manager showing 'null' for PeasyCam version X https://github.com/processing/processing/pull/4712 +X https://github.com/processing/processing/issues/4696 +_ Application Exports report as "Damaged" on macOS Sierra +_ https://github.com/processing/processing/issues/4705 + _ fix the library reporting scripts on the server _ sharing usage metrics about libraries _ https://github.com/processing/processing/issues/4708 From beef7c006d560d3887336b42206e83fea767e308 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 29 Oct 2016 11:12:39 -0400 Subject: [PATCH 069/917] deal with pedantic code analyzer (fixes #4670) --- java/src/processing/mode/java/JavaEditor.java | 8 ++------ todo.txt | 2 ++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index c45a29263b..202f2c19a6 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -2764,11 +2764,9 @@ static private String replaceString(String str, int start, int end, String put) //private int howManyInts(ArrayList handles[]) static private int howManyInts(List> handles) { int count = 0; - //for (int i=0; i list : handles) { - //for (Handle n : handles[i]) { for (Handle n : list) { - if (n.type == "int" || n.type == "hex" || n.type == "webcolor") { + if ("int".equals(n.type) || "hex".equals(n.type) || "webcolor".equals(n.type)) { count++; } } @@ -2780,11 +2778,9 @@ static private int howManyInts(List> handles) { //private int howManyFloats(ArrayList handles[]) static private int howManyFloats(List> handles) { int count = 0; - //for (int i=0; i list : handles) { - //for (Handle n : handles[i]) { for (Handle n : list) { - if (n.type == "float") { + if ("float".equals(n.type)) { count++; } } diff --git a/todo.txt b/todo.txt index cd83a648ab..1314798aa2 100755 --- a/todo.txt +++ b/todo.txt @@ -22,6 +22,8 @@ X update launch4j to 3.9 X https://sourceforge.net/projects/launch4j/files/launch4j-3/3.9/ X exported application doesn't work with latest jre X https://github.com/processing/processing/issues/4682 +X string comparison fix +X https://github.com/processing/processing/issues/4670 gohai X Simplify font situation to make it possible to use vanilla JRE trees From db6095e04634a187960cecc28572e3c240375b61 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Sun, 30 Oct 2016 10:23:16 -0300 Subject: [PATCH 070/917] do not call handleDraw() after the sketch is finished --- core/src/processing/opengl/PSurfaceJOGL.java | 22 +++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 955a8d2265..ccf31ac402 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -874,18 +874,20 @@ public void display(GLAutoDrawable drawable) { requestFocus(); } - pgl.getGL(drawable); - int pframeCount = sketch.frameCount; - sketch.handleDraw(); - if (pframeCount == sketch.frameCount) { - // This hack allows the FBO layer to be swapped normally even if - // the sketch is no looping, otherwise background artifacts will occur. - pgl.beginRender(); - pgl.endRender(sketch.sketchWindowColor()); + if (!sketch.finished) { + pgl.getGL(drawable); + int pframeCount = sketch.frameCount; + sketch.handleDraw(); + if (pframeCount == sketch.frameCount || sketch.finished) { + // This hack allows the FBO layer to be swapped normally even if + // the sketch is no looping or finished because it does not call draw(), + // otherwise background artifacts may occur (depending on the hardware/drivers). + pgl.beginRender(); + pgl.endRender(sketch.sketchWindowColor()); + } + PGraphicsOpenGL.completeFinishedPixelTransfers(); } - PGraphicsOpenGL.completeFinishedPixelTransfers(); - if (sketch.exitCalled()) { PGraphicsOpenGL.completeAllPixelTransfers(); From 4da26d107cd9036de0bb4f13466699b9b92e6e2e Mon Sep 17 00:00:00 2001 From: codeanticode Date: Sun, 30 Oct 2016 10:56:52 -0300 Subject: [PATCH 071/917] removed redundant sphere stroke edges --- core/src/processing/opengl/PGraphicsOpenGL.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 157d251182..892ac69903 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -9131,7 +9131,6 @@ int[] addSphere(float r, int detailU, int detailV, indices[indCount + 3 * i + 1] = i0; indices[indCount + 3 * i + 2] = i0 + 1; - addEdge(i0, i0 + 1, true, true); addEdge(i0, i1, true, true); } indCount += 3 * detailU; From 85f40f1e4fbeb1512e68800d60d4ce55240b6c47 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 30 Oct 2016 15:45:57 -0400 Subject: [PATCH 072/917] notes about fixes from Andres --- core/todo.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index 3413a4c514..6cd34c0c36 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -36,6 +36,10 @@ X remove extra glClear() calls X https://github.com/processing/processing/issues/4694 X PShapes do not show up in PDF with P2D renderer X https://github.com/processing/processing/issues/4647 +X Some semi-transparent edges of sphere() meshes rendered in higher density +X https://github.com/processing/processing/issues/4720 +X P2D and P3D not stopping with empty draw() blocks +X https://github.com/processing/processing/issues/4722 started X add toJSON() method to IntDict From 3cd5779398e390eb00ff5de3a0b790d1c23dbb87 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 30 Oct 2016 16:12:40 -0400 Subject: [PATCH 073/917] clean up toString() and implement toJSON() consistently --- core/src/processing/data/FloatDict.java | 35 +++++++++++++----------- core/src/processing/data/FloatList.java | 21 +++++++------- core/src/processing/data/IntDict.java | 14 +--------- core/src/processing/data/IntList.java | 21 +++++++------- core/src/processing/data/StringDict.java | 23 +++++++++------- core/src/processing/data/StringList.java | 25 +++++++++-------- core/todo.txt | 11 +++++--- 7 files changed, 74 insertions(+), 76 deletions(-) diff --git a/core/src/processing/data/FloatDict.java b/core/src/processing/data/FloatDict.java index cfb9adc996..5c01e3d208 100644 --- a/core/src/processing/data/FloatDict.java +++ b/core/src/processing/data/FloatDict.java @@ -149,8 +149,8 @@ public Iterator iterator() { } }; } - - + + // Use this to iterate when you want to be able to remove elements along the way public Iterator keyIterator() { return new Iterator() { @@ -211,8 +211,8 @@ public Iterator iterator() { } }; } - - + + public Iterator valueIterator() { return new Iterator() { int index = -1; @@ -370,7 +370,7 @@ private void checkMinMax(String functionName) { public int minIndex() { //checkMinMax("minIndex"); if (count == 0) return -1; - + // Will still return NaN if there are 1 or more entries, and they're all NaN float m = Float.NaN; int mi = -1; @@ -592,7 +592,7 @@ public void sortValuesReverse(boolean stable) { } - protected void sortImpl(final boolean useKeys, final boolean reverse, + protected void sortImpl(final boolean useKeys, final boolean reverse, final boolean stable) { Sort s = new Sort() { @Override @@ -704,17 +704,20 @@ public void write(PrintWriter writer) { } + /** + * Return this dictionary as a String in JSON format. + */ + public String toJSON() { + StringList items = new StringList(); + for (int i = 0; i < count; i++) { + items.append(JSONObject.quote(keys[i])+ ": " + values[i]); + } + return "{ " + items.join(", ") + " }"; + } + + @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getSimpleName() + " size=" + size() + " { "); - for (int i = 0; i < size(); i++) { - if (i != 0) { - sb.append(", "); - } - sb.append("\"" + keys[i] + "\": " + values[i]); - } - sb.append(" }"); - return sb.toString(); + return getClass().getSimpleName() + " size=" + size() + " " + toJSON(); } } diff --git a/core/src/processing/data/FloatList.java b/core/src/processing/data/FloatList.java index daf01cbfe4..c3ee4c2870 100644 --- a/core/src/processing/data/FloatList.java +++ b/core/src/processing/data/FloatList.java @@ -879,23 +879,22 @@ public String join(String separator) { public void print() { - for (int i = 0; i < size(); i++) { + for (int i = 0; i < count; i++) { System.out.format("[%d] %f%n", i, data[i]); } } + /** + * Return this dictionary as a String in JSON format. + */ + public String toJSON() { + return "[ " + join(", ") + " ]"; + } + + @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getSimpleName() + " size=" + size() + " [ "); - for (int i = 0; i < size(); i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(i + ": " + data[i]); - } - sb.append(" ]"); - return sb.toString(); + return getClass().getSimpleName() + " size=" + size() + " " + toJSON(); } } diff --git a/core/src/processing/data/IntDict.java b/core/src/processing/data/IntDict.java index e50d1b55d4..1f21b4b3f6 100644 --- a/core/src/processing/data/IntDict.java +++ b/core/src/processing/data/IntDict.java @@ -665,7 +665,7 @@ public void write(PrintWriter writer) { */ public String toJSON() { StringList items = new StringList(); - for (int i = 0; i < size(); i++) { + for (int i = 0; i < count; i++) { items.append(JSONObject.quote(keys[i])+ ": " + values[i]); } return "{ " + items.join(", ") + " }"; @@ -675,17 +675,5 @@ public String toJSON() { @Override public String toString() { return getClass().getSimpleName() + " size=" + size() + " " + toJSON(); - /* - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getSimpleName() + " size=" + size() + " { "); - for (int i = 0; i < size(); i++) { - if (i != 0) { - sb.append(", "); - } - sb.append("\"" + keys[i] + "\": " + values[i]); - } - sb.append(" }"); - return sb.toString(); - */ } } diff --git a/core/src/processing/data/IntList.java b/core/src/processing/data/IntList.java index 5147d75691..2d833dcf01 100644 --- a/core/src/processing/data/IntList.java +++ b/core/src/processing/data/IntList.java @@ -867,23 +867,22 @@ public String join(String separator) { public void print() { - for (int i = 0; i < size(); i++) { + for (int i = 0; i < count; i++) { System.out.format("[%d] %d%n", i, data[i]); } } + /** + * Return this dictionary as a String in JSON format. + */ + public String toJSON() { + return "[ " + join(", ") + " ]"; + } + + @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getSimpleName() + " size=" + size() + " [ "); - for (int i = 0; i < size(); i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(i + ": " + data[i]); - } - sb.append(" ]"); - return sb.toString(); + return getClass().getSimpleName() + " size=" + size() + " " + toJSON(); } } diff --git a/core/src/processing/data/StringDict.java b/core/src/processing/data/StringDict.java index 1e2128a121..5231c44d43 100644 --- a/core/src/processing/data/StringDict.java +++ b/core/src/processing/data/StringDict.java @@ -475,17 +475,20 @@ public void write(PrintWriter writer) { } + /** + * Return this dictionary as a String in JSON format. + */ + public String toJSON() { + StringList items = new StringList(); + for (int i = 0; i < count; i++) { + items.append(JSONObject.quote(keys[i])+ ": " + JSONObject.quote(values[i])); + } + return "{ " + items.join(", ") + " }"; + } + + @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getSimpleName() + " size=" + size() + " { "); - for (int i = 0; i < size(); i++) { - if (i != 0) { - sb.append(", "); - } - sb.append("\"" + keys[i] + "\": \"" + values[i] + "\""); - } - sb.append(" }"); - return sb.toString(); + return getClass().getSimpleName() + " size=" + size() + " " + toJSON(); } } diff --git a/core/src/processing/data/StringList.java b/core/src/processing/data/StringList.java index 215bc7adb2..9f21f3c3e0 100644 --- a/core/src/processing/data/StringList.java +++ b/core/src/processing/data/StringList.java @@ -750,23 +750,26 @@ public String join(String separator) { public void print() { - for (int i = 0; i < size(); i++) { + for (int i = 0; i < count; i++) { System.out.format("[%d] %s%n", i, data[i]); } } + /** + * Return this dictionary as a String in JSON format. + */ + public String toJSON() { + StringList temp = new StringList(); + for (String item : this) { + temp.append(JSONObject.quote(item)); + } + return "[ " + temp.join(", ") + " ]"; + } + + @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getSimpleName() + " size=" + size() + " [ "); - for (int i = 0; i < size(); i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(i + ": \"" + data[i] + "\""); - } - sb.append(" ]"); - return sb.toString(); + return getClass().getSimpleName() + " size=" + size() + " " + toJSON(); } } diff --git a/core/todo.txt b/core/todo.txt index 6cd34c0c36..b50bd8abe9 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -44,24 +44,27 @@ X https://github.com/processing/processing/issues/4722 started X add toJSON() method to IntDict X had to use JSONObject.quote() to wrap the text -_ do the same for the other data classes -_ note the difference between this and toJSONObject() or toJSONArray() -_ or is that the better way to handle it? hm +X do the same for the other data classes +o note the difference between this and toJSONObject() or toJSONArray() +o or is that the better way to handle it? hm +X we can add JSONObject and JSONArray later perhaps +X keep toJSONObject() for turning XxxxList into a numbered lookup _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 _ should we drop the 'default' prefix from the ex handler so it's not static? _ http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html + _ listPaths(), listFiles()? _ https://github.com/processing/processing/issues/4622 +_ add increment() that takes IntDict to merge things _ option to disable OpenGL ES on Linux? _ https://github.com/processing/processing/issues/4584 _ textAlign(CENTER) and pixelDensity(2) aligning incorrectly with Java2D _ https://github.com/processing/processing/issues/4020 -_ add increment() that takes IntDict to merge things _ should fullScreen() set width and height to displayWidth/Height _ or is that being set/unset used for any state info? From fa62fd270d6bbdf2286f7f1e0dddfbcf14dc9a49 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 30 Oct 2016 16:35:08 -0400 Subject: [PATCH 074/917] writing release notes --- build/shared/revisions.txt | 118 +++++++++++++++++++++++++++++++++++++ core/todo.txt | 18 +++--- todo.txt | 2 +- 3 files changed, 128 insertions(+), 10 deletions(-) diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index 758accc7fb..789e21ab54 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -1,3 +1,121 @@ +PROCESSING 3.2.2 (REV 0254) - 30 October 2016 + +Lots of bug fixes. + + +[ fixes ] + ++ Find in reference for size() opens StringList.size() + https://github.com/processing/processing/issues/4224 + https://github.com/processing/processing/issues/4655 + ++ Limit rollovers on EditorStatus to the text portion. Clicking the status + area when a URL was showing was problematic because it's also the separator + used to adjust the relative size of the two panels. + ++ Switch to Java 8u111. Not using 8u112 because the build numbers are + different depending on the platform, and no 112 fixes are known useful. + ++ Errant "Could not open the URL" when clicking on error messages + https://github.com/processing/processing/issues/4695 + ++ Fix extensions handling in CFBundleDocument code from appbundler + https://github.com/processing/processing/issues/4615 + ++ Update launch4j to 3.9, fixing a problem with exported applications + on Windows reporting "This application requires a Java Runtime Environment + 1.8.0_74", when 1.8.0_101 or later were installed. + https://github.com/processing/processing/issues/4682 + ++ Minor String comparison fix for Tweak mode + https://github.com/processing/processing/issues/4670 + ++ Fix quoting problem in IntDict.toJSON() + ++ Add getRenderer() to SurfaceInfo for Andres + https://github.com/processing/processing/issues/4441 + ++ Exceptions thrown in OpenGL apps when hitting the window's close box + https://github.com/processing/processing/issues/4690 + ++ Add getRowMap() function to Table + ++ Go back to textMode(MODEL) is native font not available for textMode(SHAPE) + https://github.com/processing/processing/issues/4680 + ++ NPE thrown when using textMode(SHAPE) with a .vlw font + https://github.com/processing/processing/issues/4680 + ++ Add toJSON() method to the data classes (IntDict, FloatDict, StringDict, + IntList, FloatList, and StringList). Returns an object of one of those + six types as a JSON-formatted String. For something more like the old + toString() behavior, use print(). + + +[ gottfried's goodness ] + ++ Simplify font situation to make it possible to use vanilla JRE trees + https://github.com/processing/processing/pull/4639 + https://github.com/processing/processing/pull/4641 + ++ Updates for ARM + https://github.com/processing/processing/pull/4640 + + +[ andres can do anything ] + ++ Automatic handling of screen FBOs breaks readPixels() for user-provided FBO + https://github.com/processing/processing/issues/4643 + ++ PGraphicsOpenGL: camera info not updated + https://github.com/processing/processing/issues/4609 + ++ Fix PShape, updateTessellation, matrix transformations + https://github.com/processing/processing/issues/4662 + ++ QUAD_STRIP as child shape draws extra lines + https://github.com/processing/processing/issues/4656 + ++ Remove extra glClear() calls + https://github.com/processing/processing/issues/4694 + ++ PShapes do not show up in PDF with P2D renderer + https://github.com/processing/processing/issues/4647 + ++ Some semi-transparent edges of sphere() meshes rendered in higher density + https://github.com/processing/processing/issues/4720 + ++ P2D and P3D not stopping with empty draw() blocks + https://github.com/processing/processing/issues/4722 + + +[ other contributed fixes ] + ++ Chinese translation updates + https://github.com/processing/processing/pull/4661 + ++ Spanish translation updates + https://github.com/processing/processing/pull/4697 + ++ Spanish "open sketch folder" fix + https://github.com/processing/processing/pull/4710 + ++ Contribution Manager showing 'null' for PeasyCam version + https://github.com/processing/processing/pull/4712 + https://github.com/processing/processing/issues/4696 + ++ Call glGetProgramiv to retrieve program log length + https://github.com/processing/processing/issues/4659 + https://github.com/processing/processing/pull/4660 + ++ JSONObject get() method is private + https://github.com/processing/processing/issues/4334 + https://github.com/processing/processing/pull/4336 + + +. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + PROCESSING 3.2.1 (REV 0253) - 19 August 2016 Fixes for a couple major bugs that showed up in the last release. diff --git a/core/todo.txt b/core/todo.txt index b50bd8abe9..8df4f17db2 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,4 +1,4 @@ -0254 (3.2.2 or 3.3) +0254 (3.2.2) X fix quoting problem in IntDict.toJSON() X add getRenderer() to SurfaceInfo X https://github.com/processing/processing/issues/4441 @@ -14,6 +14,13 @@ X go back to textMode(MODEL) is native font not available for textMode(SHAPE) X https://github.com/processing/processing/issues/4680 X NPE thrown when using textMode(SHAPE) with a .vlw font X https://github.com/processing/processing/issues/4680 +X add toJSON() method to IntDict +X had to use JSONObject.quote() to wrap the text +X do the same for the other data classes +o note the difference between this and toJSONObject() or toJSONArray() +o or is that the better way to handle it? hm +X we can add JSONObject and JSONArray later perhaps +X keep toJSONObject() for turning XxxxList into a numbered lookup contrib X Call glGetProgramiv to retrieve program log length @@ -41,14 +48,6 @@ X https://github.com/processing/processing/issues/4720 X P2D and P3D not stopping with empty draw() blocks X https://github.com/processing/processing/issues/4722 -started -X add toJSON() method to IntDict -X had to use JSONObject.quote() to wrap the text -X do the same for the other data classes -o note the difference between this and toJSONObject() or toJSONArray() -o or is that the better way to handle it? hm -X we can add JSONObject and JSONArray later perhaps -X keep toJSONObject() for turning XxxxList into a numbered lookup _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 @@ -65,6 +64,7 @@ _ https://github.com/processing/processing/issues/4584 _ textAlign(CENTER) and pixelDensity(2) aligning incorrectly with Java2D _ https://github.com/processing/processing/issues/4020 +_ calling textSize() fixes it _ should fullScreen() set width and height to displayWidth/Height _ or is that being set/unset used for any state info? diff --git a/todo.txt b/todo.txt index 1314798aa2..1139aac9b2 100755 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,4 @@ -0254 (3.2.2 or 3.3) +0254 (3.2.2) X Find in reference for size() opens StringList.size() X https://github.com/processing/processing/issues/4224 X though that's still imperfect: From 6c4cce6ce208637f5f65758516e19fb39087e98c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 30 Oct 2016 17:43:05 -0400 Subject: [PATCH 075/917] starting the next release --- app/src/processing/app/Base.java | 4 +-- core/done.txt | 51 ++++++++++++++++++++++++++++++++ core/todo.txt | 50 +------------------------------ done.txt | 47 +++++++++++++++++++++++++++++ todo.txt | 46 +--------------------------- 5 files changed, 102 insertions(+), 96 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 74607bd096..d246006ce1 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -55,9 +55,9 @@ public class Base { // Added accessors for 0218 because the UpdateCheck class was not properly // updating the values, due to javac inlining the static final values. - static private final int REVISION = 254; + static private final int REVISION = 255; /** This might be replaced by main() if there's a lib/version.txt file. */ - static private String VERSION_NAME = "0254"; //$NON-NLS-1$ + static private String VERSION_NAME = "0255"; //$NON-NLS-1$ /** Set true if this a proper release rather than a numbered revision. */ /** True if heavy debugging error/log messages are enabled */ diff --git a/core/done.txt b/core/done.txt index 28933ab2a6..81e6759e34 100644 --- a/core/done.txt +++ b/core/done.txt @@ -1,3 +1,54 @@ +0254 (3.2.2) +X fix quoting problem in IntDict.toJSON() +X add getRenderer() to SurfaceInfo +X https://github.com/processing/processing/issues/4441 +X Exceptions thrown in OpenGL apps when hitting window close box +X https://github.com/processing/processing/issues/4690 +X add getRowMap() function +o do we want rows() to not be transient? +X write docs for getRowMap() +o Add options to saveJSONArray documentation (enhancement) +o https://github.com/processing/processing/issues/4683 +X made note in the docs repo +X go back to textMode(MODEL) is native font not available for textMode(SHAPE) +X https://github.com/processing/processing/issues/4680 +X NPE thrown when using textMode(SHAPE) with a .vlw font +X https://github.com/processing/processing/issues/4680 +X add toJSON() method to IntDict +X had to use JSONObject.quote() to wrap the text +X do the same for the other data classes +o note the difference between this and toJSONObject() or toJSONArray() +o or is that the better way to handle it? hm +X we can add JSONObject and JSONArray later perhaps +X keep toJSONObject() for turning XxxxList into a numbered lookup + +contrib +X Call glGetProgramiv to retrieve program log length +X https://github.com/processing/processing/issues/4659 +X https://github.com/processing/processing/pull/4660 +X JSONObject get() method is private +X https://github.com/processing/processing/issues/4334 +X https://github.com/processing/processing/pull/4336 + +andres +X Automatic handling of screen FBOs breaks readPixels() for user-provided FBO +X https://github.com/processing/processing/issues/4643 +X PGraphicsOpenGL: camera info not updated +X https://github.com/processing/processing/issues/4609 +X Fix PShape, updateTessellation, matrix transformations +X https://github.com/processing/processing/issues/4662 +X QUAD_STRIP as child shape draws extra lines +X https://github.com/processing/processing/issues/4656 +X remove extra glClear() calls +X https://github.com/processing/processing/issues/4694 +X PShapes do not show up in PDF with P2D renderer +X https://github.com/processing/processing/issues/4647 +X Some semi-transparent edges of sphere() meshes rendered in higher density +X https://github.com/processing/processing/issues/4720 +X P2D and P3D not stopping with empty draw() blocks +X https://github.com/processing/processing/issues/4722 + + 0253 (3.2.1) X implement defaultUncaughtExceptionHandler X helps avoid needing to double-quit OS X applications diff --git a/core/todo.txt b/core/todo.txt index 8df4f17db2..9801857068 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,52 +1,4 @@ -0254 (3.2.2) -X fix quoting problem in IntDict.toJSON() -X add getRenderer() to SurfaceInfo -X https://github.com/processing/processing/issues/4441 -X Exceptions thrown in OpenGL apps when hitting window close box -X https://github.com/processing/processing/issues/4690 -X add getRowMap() function -o do we want rows() to not be transient? -X write docs for getRowMap() -o Add options to saveJSONArray documentation (enhancement) -o https://github.com/processing/processing/issues/4683 -X made note in the docs repo -X go back to textMode(MODEL) is native font not available for textMode(SHAPE) -X https://github.com/processing/processing/issues/4680 -X NPE thrown when using textMode(SHAPE) with a .vlw font -X https://github.com/processing/processing/issues/4680 -X add toJSON() method to IntDict -X had to use JSONObject.quote() to wrap the text -X do the same for the other data classes -o note the difference between this and toJSONObject() or toJSONArray() -o or is that the better way to handle it? hm -X we can add JSONObject and JSONArray later perhaps -X keep toJSONObject() for turning XxxxList into a numbered lookup - -contrib -X Call glGetProgramiv to retrieve program log length -X https://github.com/processing/processing/issues/4659 -X https://github.com/processing/processing/pull/4660 -X JSONObject get() method is private -X https://github.com/processing/processing/issues/4334 -X https://github.com/processing/processing/pull/4336 - -andres -X Automatic handling of screen FBOs breaks readPixels() for user-provided FBO -X https://github.com/processing/processing/issues/4643 -X PGraphicsOpenGL: camera info not updated -X https://github.com/processing/processing/issues/4609 -X Fix PShape, updateTessellation, matrix transformations -X https://github.com/processing/processing/issues/4662 -X QUAD_STRIP as child shape draws extra lines -X https://github.com/processing/processing/issues/4656 -X remove extra glClear() calls -X https://github.com/processing/processing/issues/4694 -X PShapes do not show up in PDF with P2D renderer -X https://github.com/processing/processing/issues/4647 -X Some semi-transparent edges of sphere() meshes rendered in higher density -X https://github.com/processing/processing/issues/4720 -X P2D and P3D not stopping with empty draw() blocks -X https://github.com/processing/processing/issues/4722 +0255 (3.2.3 or 3.3) _ TRIANGLE_STRIP not working correctly with createShape() and default renderer diff --git a/done.txt b/done.txt index 8637e28c57..adf4ff3de5 100644 --- a/done.txt +++ b/done.txt @@ -1,3 +1,50 @@ +0254 (3.2.2) +X Find in reference for size() opens StringList.size() +X https://github.com/processing/processing/issues/4224 +X though that's still imperfect: +X https://github.com/processing/processing/issues/4655 +X limit rollovers on EditorStatus to the text portion +X clicking the status area when it has a url is problematic +X because it's also the vertical separator +X at least change it to only cover the text? +X add a rollover so people know what it's doing? +X switch to 8u112 for building +X switch down to 8u111 because of different build numbers +X https://github.com/processing/processing/commit/8a3a183f327a5ee680e1932dd9f123491f75a8b9 +X more font tweaks to make mono fonts work properly after #4639 +X update the Linux notes based on where we land on this +X https://github.com/processing/processing/wiki/Supported-Platforms#linux +X "Could not open the url" when clicking on the error message +X https://github.com/processing/processing/issues/4695 +X fix extensions handling in CFBundleDocument code from appbundler +X https://github.com/processing/processing/issues/4615 +X update launch4j to 3.9 +X https://sourceforge.net/projects/launch4j/files/launch4j-3/3.9/ +X exported application doesn't work with latest jre +X https://github.com/processing/processing/issues/4682 +X string comparison fix +X https://github.com/processing/processing/issues/4670 + +gohai +X Simplify font situation to make it possible to use vanilla JRE trees +X https://github.com/processing/processing/pull/4639 +X Trivial updates for ARM +X https://github.com/processing/processing/pull/4640 +X Remove all the extra hoops for loading fonts +X https://github.com/processing/processing/pull/4641 + +contrib +X Chinese translation updates +X https://github.com/processing/processing/pull/4661 +X Spanish translation updates +X https://github.com/processing/processing/pull/4697 +X Spanish "open sketch folder" fix +X https://github.com/processing/processing/pull/4710 +X Contribution Manager showing 'null' for PeasyCam version +X https://github.com/processing/processing/pull/4712 +X https://github.com/processing/processing/issues/4696 + + 0253 (3.2.1) X "Could not replace preferences.old" error message X https://github.com/processing/processing/issues/4626 diff --git a/todo.txt b/todo.txt index 1139aac9b2..de41ca8894 100755 --- a/todo.txt +++ b/todo.txt @@ -1,48 +1,4 @@ -0254 (3.2.2) -X Find in reference for size() opens StringList.size() -X https://github.com/processing/processing/issues/4224 -X though that's still imperfect: -X https://github.com/processing/processing/issues/4655 -X limit rollovers on EditorStatus to the text portion -X clicking the status area when it has a url is problematic -X because it's also the vertical separator -X at least change it to only cover the text? -X add a rollover so people know what it's doing? -X switch to 8u112 for building -X switch down to 8u111 because of different build numbers -X https://github.com/processing/processing/commit/8a3a183f327a5ee680e1932dd9f123491f75a8b9 -X more font tweaks to make mono fonts work properly after #4639 -X update the Linux notes based on where we land on this -X https://github.com/processing/processing/wiki/Supported-Platforms#linux -X "Could not open the url" when clicking on the error message -X https://github.com/processing/processing/issues/4695 -X fix extensions handling in CFBundleDocument code from appbundler -X https://github.com/processing/processing/issues/4615 -X update launch4j to 3.9 -X https://sourceforge.net/projects/launch4j/files/launch4j-3/3.9/ -X exported application doesn't work with latest jre -X https://github.com/processing/processing/issues/4682 -X string comparison fix -X https://github.com/processing/processing/issues/4670 - -gohai -X Simplify font situation to make it possible to use vanilla JRE trees -X https://github.com/processing/processing/pull/4639 -X Trivial updates for ARM -X https://github.com/processing/processing/pull/4640 -X Remove all the extra hoops for loading fonts -X https://github.com/processing/processing/pull/4641 - -contrib -X Chinese translation updates -X https://github.com/processing/processing/pull/4661 -X Spanish translation updates -X https://github.com/processing/processing/pull/4697 -X Spanish "open sketch folder" fix -X https://github.com/processing/processing/pull/4710 -X Contribution Manager showing 'null' for PeasyCam version -X https://github.com/processing/processing/pull/4712 -X https://github.com/processing/processing/issues/4696 +0255 (3.2.3 or 3.3) _ Application Exports report as "Damaged" on macOS Sierra From 2d23d736353b9c3d52d86a613cdb8c6f5d8d184b Mon Sep 17 00:00:00 2001 From: codeanticode Date: Wed, 2 Nov 2016 20:52:03 -0300 Subject: [PATCH 076/917] use alternative regex in point and line shader autodetect, fixes #4725 --- core/src/processing/opengl/PShader.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/processing/opengl/PShader.java b/core/src/processing/opengl/PShader.java index 545a5acecc..8a8da15a94 100644 --- a/core/src/processing/opengl/PShader.java +++ b/core/src/processing/opengl/PShader.java @@ -51,8 +51,12 @@ public class PShader implements PConstants { static protected String pointShaderAttrRegexp = "attribute *vec2 *offset"; + static protected String pointShaderAttrRegexp2 = + "in *vec2 *offset;"; static protected String lineShaderAttrRegexp = "attribute *vec4 *direction"; + static protected String lineShaderAttrRegexp2 = + "in *vec4 *direction"; static protected String pointShaderDefRegexp = "#define *PROCESSING_POINT_SHADER"; static protected String lineShaderDefRegexp = @@ -1016,9 +1020,11 @@ protected void dispose() { static protected int getShaderType(String[] source, int defaultType) { for (int i = 0; i < source.length; i++) { String line = source[i].trim(); - if (PApplet.match(line, pointShaderAttrRegexp) != null) + if (PApplet.match(line, pointShaderAttrRegexp) != null || + PApplet.match(line, pointShaderAttrRegexp2) != null) return PShader.POINT; - else if (PApplet.match(line, lineShaderAttrRegexp) != null) + else if (PApplet.match(line, lineShaderAttrRegexp) != null || + PApplet.match(line, lineShaderAttrRegexp2) != null) return PShader.LINE; else if (PApplet.match(line, pointShaderDefRegexp) != null) return PShader.POINT; From 9b3b2033c42f7d300f280592ae9f82b14441fb5f Mon Sep 17 00:00:00 2001 From: codeanticode Date: Wed, 2 Nov 2016 20:57:51 -0300 Subject: [PATCH 077/917] some cosmetic changes --- core/src/processing/opengl/PShader.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/core/src/processing/opengl/PShader.java b/core/src/processing/opengl/PShader.java index 8a8da15a94..951fcb1eea 100644 --- a/core/src/processing/opengl/PShader.java +++ b/core/src/processing/opengl/PShader.java @@ -51,11 +51,11 @@ public class PShader implements PConstants { static protected String pointShaderAttrRegexp = "attribute *vec2 *offset"; - static protected String pointShaderAttrRegexp2 = + static protected String pointShaderInRegexp = "in *vec2 *offset;"; static protected String lineShaderAttrRegexp = "attribute *vec4 *direction"; - static protected String lineShaderAttrRegexp2 = + static protected String lineShaderInRegexp = "in *vec4 *direction"; static protected String pointShaderDefRegexp = "#define *PROCESSING_POINT_SHADER"; @@ -1020,11 +1020,13 @@ protected void dispose() { static protected int getShaderType(String[] source, int defaultType) { for (int i = 0; i < source.length; i++) { String line = source[i].trim(); - if (PApplet.match(line, pointShaderAttrRegexp) != null || - PApplet.match(line, pointShaderAttrRegexp2) != null) + if (PApplet.match(line, pointShaderAttrRegexp) != null) return PShader.POINT; - else if (PApplet.match(line, lineShaderAttrRegexp) != null || - PApplet.match(line, lineShaderAttrRegexp2) != null) + else if (PApplet.match(line, pointShaderInRegexp) != null) + return PShader.POINT; + else if (PApplet.match(line, lineShaderAttrRegexp) != null) + return PShader.LINE; + else if (PApplet.match(line, lineShaderInRegexp) != null) return PShader.LINE; else if (PApplet.match(line, pointShaderDefRegexp) != null) return PShader.POINT; From 657f03499a38ca94617e0101458f5cb68b04c303 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Thu, 3 Nov 2016 10:15:41 -0300 Subject: [PATCH 078/917] check point and line attributes at the end, so that defines can override autodetection --- core/src/processing/opengl/PShader.java | 27 +++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/core/src/processing/opengl/PShader.java b/core/src/processing/opengl/PShader.java index 951fcb1eea..d5f8f1d531 100644 --- a/core/src/processing/opengl/PShader.java +++ b/core/src/processing/opengl/PShader.java @@ -1020,19 +1020,8 @@ protected void dispose() { static protected int getShaderType(String[] source, int defaultType) { for (int i = 0; i < source.length; i++) { String line = source[i].trim(); - if (PApplet.match(line, pointShaderAttrRegexp) != null) - return PShader.POINT; - else if (PApplet.match(line, pointShaderInRegexp) != null) - return PShader.POINT; - else if (PApplet.match(line, lineShaderAttrRegexp) != null) - return PShader.LINE; - else if (PApplet.match(line, lineShaderInRegexp) != null) - return PShader.LINE; - else if (PApplet.match(line, pointShaderDefRegexp) != null) - return PShader.POINT; - else if (PApplet.match(line, lineShaderDefRegexp) != null) - return PShader.LINE; - else if (PApplet.match(line, colorShaderDefRegexp) != null) + + if (PApplet.match(line, colorShaderDefRegexp) != null) return PShader.COLOR; else if (PApplet.match(line, lightShaderDefRegexp) != null) return PShader.LIGHT; @@ -1046,6 +1035,18 @@ else if (PApplet.match(line, triShaderAttrRegexp) != null) return PShader.POLY; else if (PApplet.match(line, quadShaderAttrRegexp) != null) return PShader.POLY; + else if (PApplet.match(line, pointShaderDefRegexp) != null) + return PShader.POINT; + else if (PApplet.match(line, lineShaderDefRegexp) != null) + return PShader.LINE; + else if (PApplet.match(line, pointShaderAttrRegexp) != null) + return PShader.POINT; + else if (PApplet.match(line, pointShaderInRegexp) != null) + return PShader.POINT; + else if (PApplet.match(line, lineShaderAttrRegexp) != null) + return PShader.LINE; + else if (PApplet.match(line, lineShaderInRegexp) != null) + return PShader.LINE; } return defaultType; } From f26417ee037832e1ef4b61f8c8809960e4b7b2d8 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 10:10:04 -0400 Subject: [PATCH 079/917] Use the version number if they've left the prettyVersion field blank --- app/src/processing/app/contrib/LocalContribution.java | 4 ++++ core/todo.txt | 5 +++++ todo.txt | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/app/src/processing/app/contrib/LocalContribution.java b/app/src/processing/app/contrib/LocalContribution.java index dc182b9bb9..10af1009f9 100644 --- a/app/src/processing/app/contrib/LocalContribution.java +++ b/app/src/processing/app/contrib/LocalContribution.java @@ -86,7 +86,11 @@ public LocalContribution(File folder) { System.err.println("Please contact the library author to fix it according to the guidelines."); } + // Use the version number if they've left the prettyVersion field blank prettyVersion = properties.get("prettyVersion"); + if (prettyVersion == null || prettyVersion.length() == 0) { + prettyVersion = Integer.toString(version); + } try { lastUpdated = Long.parseLong(properties.get("lastUpdated")); diff --git a/core/todo.txt b/core/todo.txt index 9801857068..e72a1fdb5a 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,6 +1,11 @@ 0255 (3.2.3 or 3.3) +andres +X automatic detection of POINT and LINE shaders fails +X https://github.com/processing/processing/issues/4725 + + _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 diff --git a/todo.txt b/todo.txt index de41ca8894..e3eb5e9dd3 100755 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,13 @@ 0255 (3.2.3 or 3.3) +X if prettyVersion is blank (or null?), just use version (Firmata) +contribs +_ 'version' should be x.y or x.y.z, not some extra long string +_ enforce this by disallowing spaces? on the import script? +_ why is the updates panel completely empty? +_ was there already a bug filed for this? + _ Application Exports report as "Damaged" on macOS Sierra _ https://github.com/processing/processing/issues/4705 From 0bbcfec0331d57ccc46ecee024053d3341346b4c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 10:11:20 -0400 Subject: [PATCH 080/917] make the problem clearer --- app/src/processing/app/contrib/LocalContribution.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/processing/app/contrib/LocalContribution.java b/app/src/processing/app/contrib/LocalContribution.java index 10af1009f9..e2d27c9c49 100644 --- a/app/src/processing/app/contrib/LocalContribution.java +++ b/app/src/processing/app/contrib/LocalContribution.java @@ -82,7 +82,7 @@ public LocalContribution(File folder) { try { version = Integer.parseInt(properties.get("version")); } catch (NumberFormatException e) { - System.err.println("The version number for the “" + name + "” library is not set properly."); + System.err.println("The version number for the “" + name + "” library is not a number."); System.err.println("Please contact the library author to fix it according to the guidelines."); } From e81a5b9796bda99ffbd05dfec769b013a4bf575b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 10:36:52 -0400 Subject: [PATCH 081/917] clean up this maze of pretty version handling --- app/src/processing/app/Base.java | 2 +- .../app/contrib/AvailableContribution.java | 27 ++++++++++--------- .../processing/app/contrib/Contribution.java | 8 +++++- .../app/contrib/ContributionListing.java | 5 ++-- .../processing/app/contrib/DetailPanel.java | 11 ++++---- .../app/contrib/LocalContribution.java | 13 +++++---- .../processing/app/contrib/StatusPanel.java | 16 ++++++----- .../app/contrib/UpdateListPanel.java | 4 +-- todo.txt | 5 ++++ 9 files changed, 52 insertions(+), 39 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index d246006ce1..33d456d385 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -823,7 +823,7 @@ public byte[] getInstalledContribsInfo() { String entry = c.getTypeName() + "=" + PApplet.urlEncode(String.format("name=%s\nurl=%s\nrevision=%d\nversion=%s", c.getName(), c.getUrl(), - c.getVersion(), c.getPrettyVersion())); + c.getVersion(), c.getBenignVersion())); entries.append(entry); } String joined = diff --git a/app/src/processing/app/contrib/AvailableContribution.java b/app/src/processing/app/contrib/AvailableContribution.java index 7d15eafb3d..c36cffa8ae 100644 --- a/app/src/processing/app/contrib/AvailableContribution.java +++ b/app/src/processing/app/contrib/AvailableContribution.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2013-15 The Processing Foundation + Copyright (c) 2013-16 The Processing Foundation Copyright (c) 2011-12 Ben Fry and Casey Reas This program is free software; you can redistribute it and/or modify @@ -49,9 +49,9 @@ public AvailableContribution(ContributionType type, StringDict params) { imports = parseImports(params); name = params.get("name"); authors = params.get("authors"); - if (authors == null) { - authors = params.get("authorList"); - } +// if (authors == null) { +// authors = params.get("authorList"); +// } url = params.get("url"); sentence = params.get("sentence"); paragraph = params.get("paragraph"); @@ -62,6 +62,9 @@ public AvailableContribution(ContributionType type, StringDict params) { } prettyVersion = params.get("prettyVersion"); + if (prettyVersion != null && prettyVersion.length() == 0) { + prettyVersion = null; + } String lastUpdatedStr = params.get("lastUpdated"); if (lastUpdatedStr != null) { @@ -231,9 +234,6 @@ public ContributionType getType() { * manager. However, it also ensures that valid fields in the properties file * aren't overwritten, since the properties file may be more recent than the * contributions.txt file. - * - * @param propFile - * @return */ public boolean writePropertiesFile(File propFile) { try { @@ -256,9 +256,9 @@ public boolean writePropertiesFile(File propFile) { StringList importsList = parseImports(properties); String authors = properties.get(AUTHORS_PROPERTY); - if (authors == null) { - authors = properties.get("authorList"); // before 3.0a11 - } +// if (authors == null) { +// authors = properties.get("authorList"); // before 3.0a11 +// } if (authors == null || authors.isEmpty()) { authors = getAuthorList(); } @@ -283,13 +283,14 @@ public boolean writePropertiesFile(File propFile) { version = Integer.parseInt(properties.get("version")); } catch (NumberFormatException e) { version = getVersion(); - System.err.println("The version number for “" + name + "” is not set properly."); + System.err.println("The version number for “" + name + "” is not a number."); System.err.println("Please contact the author to fix it according to the guidelines."); } String prettyVersion = properties.get("prettyVersion"); - if (prettyVersion == null || prettyVersion.isEmpty()) - prettyVersion = getPrettyVersion(); + if (prettyVersion != null && prettyVersion.isEmpty()) { + prettyVersion = null; + } String compatibleContribsList = null; if (getType() == ContributionType.EXAMPLES) { diff --git a/app/src/processing/app/contrib/Contribution.java b/app/src/processing/app/contrib/Contribution.java index 67c58789cd..22a6e718a8 100644 --- a/app/src/processing/app/contrib/Contribution.java +++ b/app/src/processing/app/contrib/Contribution.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2013-15 The Processing Foundation + Copyright (c) 2013-16 The Processing Foundation Copyright (c) 2011-12 Ben Fry and Casey Reas This program is free software; you can redistribute it and/or modify @@ -164,6 +164,12 @@ public String getPrettyVersion() { } + // returns prettyVersion, or "" if null + public String getBenignVersion() { + return (prettyVersion != null) ? prettyVersion : ""; + } + + // 1402805757 public long getLastUpdated() { return lastUpdated; diff --git a/app/src/processing/app/contrib/ContributionListing.java b/app/src/processing/app/contrib/ContributionListing.java index cf35ff628c..5bae8d6942 100644 --- a/app/src/processing/app/contrib/ContributionListing.java +++ b/app/src/processing/app/contrib/ContributionListing.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2013-15 The Processing Foundation + Copyright (c) 2013-16 The Processing Foundation Copyright (c) 2011-12 Ben Fry and Casey Reas This program is free software; you can redistribute it and/or modify @@ -500,7 +500,7 @@ protected boolean hasUpdates(Contribution contribution) { } - protected String getLatestVersion(Contribution contribution) { + protected String getLatestPrettyVersion(Contribution contribution) { Contribution newestContrib = getAvailableContribution(contribution); if (newestContrib == null) { return null; @@ -509,7 +509,6 @@ protected String getLatestVersion(Contribution contribution) { } - protected boolean hasDownloadedLatestList() { return listDownloaded; } diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index 4cf327165d..69adc841e6 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -460,9 +460,9 @@ public void setContribution(Contribution contrib) { } desc.append("
"); - String version = contrib.getPrettyVersion(); - if (version != null) { - desc.append(version); + String prettyVersion = contrib.getPrettyVersion(); + if (prettyVersion != null) { + desc.append(prettyVersion); } desc.append("
"); @@ -493,8 +493,9 @@ public void setContribution(Contribution contrib) { if (lastUpdatedUTC != 0) { DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.MEDIUM); Date lastUpdatedDate = new Date(lastUpdatedUTC); - if (version != null && !version.isEmpty()) + if (prettyVersion != null) { desc.append(", "); + } desc.append("Last Updated on " + dateFormatter.format(lastUpdatedDate)); } @@ -510,7 +511,7 @@ public void setContribution(Contribution contrib) { // versionText.append("To finish an update, reinstall this contribution after restarting."); ; } else { - String latestVersion = contribListing.getLatestVersion(contrib); + String latestVersion = contribListing.getLatestPrettyVersion(contrib); if (latestVersion != null) { versionText.append("New version (" + latestVersion + ") available."); } else { diff --git a/app/src/processing/app/contrib/LocalContribution.java b/app/src/processing/app/contrib/LocalContribution.java index e2d27c9c49..0bfa6a988d 100644 --- a/app/src/processing/app/contrib/LocalContribution.java +++ b/app/src/processing/app/contrib/LocalContribution.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2013-15 The Processing Foundation + Copyright (c) 2013-16 The Processing Foundation Copyright (c) 2011-12 Ben Fry and Casey Reas This program is free software; you can redistribute it and/or modify @@ -72,9 +72,9 @@ public LocalContribution(File folder) { } // changing to 'authors' in 3.0a11 authors = properties.get(AUTHORS_PROPERTY); - if (authors == null) { - authors = properties.get("authorList"); - } +// if (authors == null) { +// authors = properties.get("authorList"); +// } url = properties.get("url"); sentence = properties.get("sentence"); paragraph = properties.get("paragraph"); @@ -86,10 +86,9 @@ public LocalContribution(File folder) { System.err.println("Please contact the library author to fix it according to the guidelines."); } - // Use the version number if they've left the prettyVersion field blank prettyVersion = properties.get("prettyVersion"); - if (prettyVersion == null || prettyVersion.length() == 0) { - prettyVersion = Integer.toString(version); + if (prettyVersion != null && prettyVersion.length() == 0) { + prettyVersion = null; } try { diff --git a/app/src/processing/app/contrib/StatusPanel.java b/app/src/processing/app/contrib/StatusPanel.java index a048be660e..4ad400d281 100644 --- a/app/src/processing/app/contrib/StatusPanel.java +++ b/app/src/processing/app/contrib/StatusPanel.java @@ -249,13 +249,13 @@ public void update(DetailPanel panel) { !panel.updateInProgress); String latestVersion = - contributionListing.getLatestVersion(panel.getContrib()); + contributionListing.getLatestPrettyVersion(panel.getContrib()); String currentVersion = panel.getContrib().getPrettyVersion(); - installButton.setEnabled(!panel.getContrib().isInstalled() - && contributionListing.hasDownloadedLatestList() - && panel.getContrib().isCompatible(Base.getRevision()) - && !panel.installInProgress); + installButton.setEnabled(!panel.getContrib().isInstalled() && + contributionListing.hasDownloadedLatestList() && + panel.getContrib().isCompatible(Base.getRevision()) && + !panel.installInProgress); if (panel.getContrib().isCompatible(Base.getRevision())) { if (installButton.isEnabled()) { @@ -285,9 +285,12 @@ public void update(DetailPanel panel) { latestVersion = "Update"; } + // why was this here? [fry 161103] + /* if (currentVersion == null) { currentVersion = ""; } + */ if (updateButton.isEnabled()) { updateButton.setText(latestVersion); @@ -295,8 +298,7 @@ public void update(DetailPanel panel) { updateButton.setText("Update"); } - removeButton.setEnabled(panel.getContrib().isInstalled() - && !panel.removeInProgress); + removeButton.setEnabled(panel.getContrib().isInstalled() && !panel.removeInProgress); progressPanel.add(panel.installProgressBar); progressPanel.setVisible(false); updateLabel.setVisible(true); diff --git a/app/src/processing/app/contrib/UpdateListPanel.java b/app/src/processing/app/contrib/UpdateListPanel.java index d03216a079..0995eb1576 100644 --- a/app/src/processing/app/contrib/UpdateListPanel.java +++ b/app/src/processing/app/contrib/UpdateListPanel.java @@ -209,8 +209,8 @@ void updatePanelOrdering(Set contributionsSet) { icon, "" + fontFace + entry.getName() + "", name, - entry.getPrettyVersion(), - contributionTab.contribListing.getLatestVersion(entry) + entry.getBenignVersion(), + contributionTab.contribListing.getLatestPrettyVersion(entry) }); } UpdateContributionTab tab = (UpdateContributionTab) contributionTab; diff --git a/todo.txt b/todo.txt index e3eb5e9dd3..44c687d218 100755 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,11 @@ 0255 (3.2.3 or 3.3) X if prettyVersion is blank (or null?), just use version (Firmata) + // Use the version number if they've left the prettyVersion field blank + if (prettyVersion == null || prettyVersion.length() == 0) { + prettyVersion = Integer.toString(version); + } + contribs _ 'version' should be x.y or x.y.z, not some extra long string From fef224369a1e7b1ad22f36afe502c015e557d75c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 10:38:23 -0400 Subject: [PATCH 082/917] cleanups --- app/src/processing/app/contrib/StatusPanel.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/src/processing/app/contrib/StatusPanel.java b/app/src/processing/app/contrib/StatusPanel.java index 4ad400d281..c28755067a 100644 --- a/app/src/processing/app/contrib/StatusPanel.java +++ b/app/src/processing/app/contrib/StatusPanel.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2013-15 The Processing Foundation + Copyright (c) 2013-16 The Processing Foundation Copyright (c) 2011-12 Ben Fry and Casey Reas This program is free software; you can redistribute it and/or modify @@ -285,13 +285,6 @@ public void update(DetailPanel panel) { latestVersion = "Update"; } - // why was this here? [fry 161103] - /* - if (currentVersion == null) { - currentVersion = ""; - } - */ - if (updateButton.isEnabled()) { updateButton.setText(latestVersion); } else { From 5b26338d71258d9d7b97036c0b10e93f4e9ed51b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 11:16:32 -0400 Subject: [PATCH 083/917] ensure that update.id is set before checking for contrib updates --- app/src/processing/app/Base.java | 2 +- app/src/processing/app/UpdateCheck.java | 8 ++++++-- todo.txt | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 33d456d385..ce7550fa33 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -827,7 +827,7 @@ public byte[] getInstalledContribsInfo() { entries.append(entry); } String joined = - "id=" + Preferences.get("update.id") + "&" + entries.join("&"); + "id=" + UpdateCheck.getUpdateID() + "&" + entries.join("&"); // StringBuilder sb = new StringBuilder(); // try { // // Truly ridiculous attempt to shove everything into a GET request. diff --git a/app/src/processing/app/UpdateCheck.java b/app/src/processing/app/UpdateCheck.java index fd43088ab9..f76f3750af 100644 --- a/app/src/processing/app/UpdateCheck.java +++ b/app/src/processing/app/UpdateCheck.java @@ -83,7 +83,7 @@ public void run() { } - public void updateCheck() throws IOException, InterruptedException { + static public long getUpdateID() { // generate a random id in case none exists yet Random r = new Random(); long id = r.nextLong(); @@ -94,8 +94,12 @@ public void updateCheck() throws IOException, InterruptedException { } else { Preferences.set("update.id", String.valueOf(id)); } + return id; + } - String info = PApplet.urlEncode(id + "\t" + + + public void updateCheck() throws IOException, InterruptedException { + String info = PApplet.urlEncode(getUpdateID() + "\t" + PApplet.nf(Base.getRevision(), 4) + "\t" + System.getProperty("java.version") + "\t" + System.getProperty("java.vendor") + "\t" + diff --git a/todo.txt b/todo.txt index 44c687d218..0719e646bc 100755 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,5 @@ 0255 (3.2.3 or 3.3) +X ensure that update.id is set before checking for contrib updates X if prettyVersion is blank (or null?), just use version (Firmata) // Use the version number if they've left the prettyVersion field blank From affc6bb0fac4a33be7c80f06c7a966675c257232 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 11:25:23 -0400 Subject: [PATCH 084/917] what is this method? --- app/src/processing/app/UpdateCheck.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/processing/app/UpdateCheck.java b/app/src/processing/app/UpdateCheck.java index f76f3750af..5103f5d856 100644 --- a/app/src/processing/app/UpdateCheck.java +++ b/app/src/processing/app/UpdateCheck.java @@ -83,6 +83,11 @@ public void run() { } + /** + * Turned into a separate method so that anyone needed update.id will get + * a legit answer. Had a problem with the contribs script where the id + * wouldn't be set so a null id would be sent to the contribs server. + */ static public long getUpdateID() { // generate a random id in case none exists yet Random r = new Random(); From b75ebd6086841b8299389288d35673d51c8d9a47 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 11:38:39 -0400 Subject: [PATCH 085/917] this won't fix the image size problem --- app/src/processing/app/ui/Toolkit.java | 35 ++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 1560032599..9abd6fae1f 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -502,6 +502,7 @@ static public ImageIcon getIconX(File dir, String base, int size) { // System.err.println("does not exist: " + file); return null; } + ImageIcon outgoing = new ImageIcon(file.getAbsolutePath()) { @Override public int getIconWidth() { @@ -513,6 +514,40 @@ public int getIconHeight() { return super.getIconHeight() / scale; } + /* + @Override + public Image getImage() { + Image actual = super.getImage(); + + return new Image() { + @Override + public int getWidth(ImageObserver observer) { + return actual.getWidth(observer) / scale; + } + + @Override + public int getHeight(ImageObserver observer) { + return actual.getHeight(observer) / scale; + } + + @Override + public ImageProducer getSource() { + return actual.getSource(); + } + + @Override + public Graphics getGraphics() { + return actual.getGraphics(); + } + + @Override + public Object getProperty(String name, ImageObserver observer) { + return actual.getProperty(filename, observer); + } + }; + } + */ + @Override public synchronized void paintIcon(Component c, Graphics g, int x, int y) { ImageObserver imageObserver = getImageObserver(); From 725969c7ecea2067af5671ed07672853c89299b0 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 11:39:55 -0400 Subject: [PATCH 086/917] notes about the retina bug --- todo.txt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/todo.txt b/todo.txt index 0719e646bc..812ed6ed07 100755 --- a/todo.txt +++ b/todo.txt @@ -2,12 +2,6 @@ X ensure that update.id is set before checking for contrib updates X if prettyVersion is blank (or null?), just use version (Firmata) - // Use the version number if they've left the prettyVersion field blank - if (prettyVersion == null || prettyVersion.length() == 0) { - prettyVersion = Integer.toString(version); - } - - contribs _ 'version' should be x.y or x.y.z, not some extra long string _ enforce this by disallowing spaces? on the import script? @@ -23,6 +17,8 @@ _ https://github.com/processing/processing/issues/4708 _ clicking "Update" button in contrib manager shows non-retina version of icon _ https://github.com/processing/processing/issues/4715 +_ problem is because AquaButtonUI is calling getImage() (not getIcon()) +_ can be debugging from inside the getIconX() code in Toolkit _ library compilations handled oddly _ https://github.com/processing/processing/issues/4630 From 2770f1971b906bb1f77ff63412a431eb6991ad78 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 19:08:07 -0400 Subject: [PATCH 087/917] non-retina versions of button icons showing up in contribs (fixes #4715) --- .../app/contrib/ContributionTab.java | 22 +--------- app/src/processing/app/contrib/ListPanel.java | 2 +- .../processing/app/contrib/StatusPanel.java | 10 ++--- .../app/contrib/UpdateStatusPanel.java | 25 ++++++++++- app/src/processing/app/ui/Toolkit.java | 43 +++++++++++++++++++ todo.txt | 24 ++++++++--- 6 files changed, 90 insertions(+), 36 deletions(-) diff --git a/app/src/processing/app/contrib/ContributionTab.java b/app/src/processing/app/contrib/ContributionTab.java index 1a0ab72a1e..86cbe5a0c8 100644 --- a/app/src/processing/app/contrib/ContributionTab.java +++ b/app/src/processing/app/contrib/ContributionTab.java @@ -74,18 +74,6 @@ public ContributionTab(ManagerFrame dialog, ContributionType type) { this.contribDialog = dialog; this.contribType = type; - /* - if (type == ContributionType.MODE) { - title = Language.text("contrib.manager_title.mode"); - } else if (type == ContributionType.TOOL) { - title = Language.text("contrib.manager_title.tool"); - } else if (type == ContributionType.LIBRARY) { - title = Language.text("contrib.manager_title.library"); - } else if (type == ContributionType.EXAMPLES) { - title = Language.text("contrib.manager_title.examples"); - } - */ - filter = new Contribution.Filter() { public boolean matches(Contribution contrib) { return contrib.getType() == contribType; @@ -228,7 +216,7 @@ protected void buildErrorPanel() { StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER); doc.setParagraphAttributes(0, doc.getLength(), center, false); - closeButton = new JButton(Toolkit.getLibIconX("manager/close")); + closeButton = Toolkit.createIconButton("manager/close"); closeButton.setContentAreaFilled(false); closeButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -354,7 +342,6 @@ protected void setFilterText(String filter) { //TODO: this is causing a lot of bugs as the hint is wrongly firing applyFilter() class FilterField extends JTextField { - Icon searchIcon; List filters; JLabel filterLabel; @@ -366,11 +353,8 @@ public FilterField () { filterLabel.setOpaque(false); setFont(Toolkit.getSansFont(14, Font.PLAIN)); - searchIcon = Toolkit.getLibIconX("manager/search"); - filterLabel.setIcon(searchIcon); - //searchIcon = new ImageIcon(java.awt.Toolkit.getDefaultToolkit().getImage("NSImage://NSComputerTemplate")); + filterLabel.setIcon(Toolkit.getLibIconX("manager/search")); setOpaque(false); - //setBorder(BorderFactory.createMatteBorder(0, 33, 0, 0, searchIcon)); GroupLayout fl = new GroupLayout(this); setLayout(fl); @@ -387,13 +371,11 @@ public FilterField () { addFocusListener(new FocusListener() { public void focusLost(FocusEvent focusEvent) { if (getText().isEmpty()) { -// setBorder(BorderFactory.createMatteBorder(0, 33, 0, 0, searchIcon)); filterLabel.setVisible(true); } } public void focusGained(FocusEvent focusEvent) { -// setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0)); filterLabel.setVisible(false); } }); diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index 02caceaf73..47ef717bab 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -538,7 +538,7 @@ public void filterLibraries(List filteredContributions) { // for (Contribution contribution : filteredContributions) { // if (contribution.getType() == contributionTab.contribType) { // if(panelByContribution.keySet().contains(contribution)){ -// visibleContributions.add(contribution); +// visibleContributions.add(contribution); // } // } // } diff --git a/app/src/processing/app/contrib/StatusPanel.java b/app/src/processing/app/contrib/StatusPanel.java index c28755067a..9505b1df7d 100644 --- a/app/src/processing/app/contrib/StatusPanel.java +++ b/app/src/processing/app/contrib/StatusPanel.java @@ -104,8 +104,8 @@ public void hyperlinkUpdate(HyperlinkEvent e) { } } }); - installButton = new JButton("Install", installIcon); - installButton.setDisabledIcon(installIcon); + installButton = Toolkit.createIconButton("Install", installIcon); + //installButton.setDisabledIcon(installIcon); installButton.setFont(buttonFont); installButton.setHorizontalAlignment(SwingConstants.LEFT); installButton.addActionListener(new ActionListener() { @@ -126,8 +126,7 @@ public void actionPerformed(ActionEvent e) { updateLabel.setFont(buttonFont); updateLabel.setHorizontalAlignment(SwingConstants.CENTER); - updateButton = new JButton("Update", updateIcon); - updateButton.setDisabledIcon(updateIcon); + updateButton = Toolkit.createIconButton("Update", updateIcon); updateButton.setFont(buttonFont); updateButton.setHorizontalAlignment(SwingConstants.LEFT); updateButton.addActionListener(new ActionListener() { @@ -140,8 +139,7 @@ public void actionPerformed(ActionEvent e) { } }); - removeButton = new JButton("Remove", removeIcon); - removeButton.setDisabledIcon(removeIcon); + removeButton = Toolkit.createIconButton("Remove", removeIcon); removeButton.setFont(buttonFont); removeButton.setHorizontalAlignment(SwingConstants.LEFT); removeButton.addActionListener(new ActionListener() { diff --git a/app/src/processing/app/contrib/UpdateStatusPanel.java b/app/src/processing/app/contrib/UpdateStatusPanel.java index d8aef30e62..b47b584cb7 100644 --- a/app/src/processing/app/contrib/UpdateStatusPanel.java +++ b/app/src/processing/app/contrib/UpdateStatusPanel.java @@ -1,3 +1,23 @@ +/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2013-16 The Processing Foundation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ package processing.app.contrib; import java.awt.Color; @@ -6,19 +26,19 @@ import java.awt.event.ActionListener; import javax.swing.GroupLayout; -import javax.swing.JButton; import javax.swing.LayoutStyle; import javax.swing.SwingConstants; import processing.app.ui.Toolkit; + public class UpdateStatusPanel extends StatusPanel { public UpdateStatusPanel(UpdateContributionTab tab, int width) { super(); this.contributionTab = tab; - updateButton = new JButton("Update All", Toolkit.getLibIconX("manager/update")); + updateButton = Toolkit.createIconButton("Update All", "manager/update"); updateButton.setFont(Toolkit.getSansFont(14, Font.PLAIN)); updateButton.setHorizontalAlignment(SwingConstants.LEFT); updateButton.setVisible(true); @@ -48,6 +68,7 @@ public void actionPerformed(ActionEvent e) { .addComponent(updateButton)); } + public void update() { updateButton.setEnabled(contributionTab.hasUpdates()); } diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 9abd6fae1f..d6c20911ec 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -57,7 +57,9 @@ import java.util.regex.Pattern; import javax.swing.Action; +import javax.swing.Icon; import javax.swing.ImageIcon; +import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; import javax.swing.JMenu; @@ -514,6 +516,20 @@ public int getIconHeight() { return super.getIconHeight() / scale; } + /* + @Override + public Image getImage() { + //javax.swing.LookAndFeel -> creates a synthetic disabled icon + //com.apple.laf.AquaButtonUI + new Exception().printStackTrace(); + return super.getImage(); + } + + private Image getImageImpl() { + return super.getImage(); + } + */ + /* @Override public Image getImage() { @@ -575,6 +591,33 @@ static public ImageIcon getLibIconX(String base, int size) { } + /** + * Create a JButton with an icon, and set its disabled and pressed images + * to be the same image, so that 2x versions of the icon work properly. + */ + static public JButton createIconButton(String title, String base) { + ImageIcon icon = Toolkit.getLibIconX(base); + return createIconButton(title, icon); + } + + + /** Same as above, but with no text title (follows JButton constructor) */ + static public JButton createIconButton(String base) { + return createIconButton(null, base); + } + + + static public JButton createIconButton(String title, Icon icon) { + JButton button = new JButton(title, icon); + button.setDisabledIcon(icon); + button.setPressedIcon(icon); + return button; + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + static List iconImages; diff --git a/todo.txt b/todo.txt index 812ed6ed07..1cc6f6d7be 100755 --- a/todo.txt +++ b/todo.txt @@ -1,25 +1,35 @@ 0255 (3.2.3 or 3.3) X ensure that update.id is set before checking for contrib updates X if prettyVersion is blank (or null?), just use version (Firmata) +X clicking "Update" button in contrib manager shows non-retina version of icon +X https://github.com/processing/processing/issues/4715 +o problem is because AquaButtonUI is calling getImage() (not getIcon()) +o can be debugging from inside the getIconX() code in Toolkit +X just needed to use setPressedIcon(), setDisabledIcon() +X also found some other issues around the icon handling contribs +X Up-to-date status disappears after filter is removed +X https://github.com/processing/processing/issues/4084 +X Updates tab blank after adding, removing, updating a contribution +X https://github.com/processing/processing/issues/4082 +X https://github.com/processing/processing/issues/4704 +X Fixes the removal of redundant contribution and update related issues +X https://github.com/processing/processing/pull/4086 + + _ 'version' should be x.y or x.y.z, not some extra long string _ enforce this by disallowing spaces? on the import script? -_ why is the updates panel completely empty? -_ was there already a bug filed for this? _ Application Exports report as "Damaged" on macOS Sierra _ https://github.com/processing/processing/issues/4705 +_ could provide script to un-quarrantine +_ xattr -d -r com.apple.quarantine _ fix the library reporting scripts on the server _ sharing usage metrics about libraries _ https://github.com/processing/processing/issues/4708 -_ clicking "Update" button in contrib manager shows non-retina version of icon -_ https://github.com/processing/processing/issues/4715 -_ problem is because AquaButtonUI is calling getImage() (not getIcon()) -_ can be debugging from inside the getIconX() code in Toolkit - _ library compilations handled oddly _ https://github.com/processing/processing/issues/4630 _ missing version number putting 'null' in the ui From 69b49060d0340e1d870d6d9f6dd313011cf74ff1 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 19:20:04 -0400 Subject: [PATCH 088/917] track down the source of null entries in pretty version (see #4696, #4712) --- .../processing/app/contrib/AvailableContribution.java | 9 ++++----- app/src/processing/app/contrib/Contribution.java | 11 +++++++++++ app/src/processing/app/contrib/LocalContribution.java | 5 +---- todo.txt | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/src/processing/app/contrib/AvailableContribution.java b/app/src/processing/app/contrib/AvailableContribution.java index c36cffa8ae..9c78b831ac 100644 --- a/app/src/processing/app/contrib/AvailableContribution.java +++ b/app/src/processing/app/contrib/AvailableContribution.java @@ -61,10 +61,7 @@ public AvailableContribution(ContributionType type, StringDict params) { version = PApplet.parseInt(versionStr, 0); } - prettyVersion = params.get("prettyVersion"); - if (prettyVersion != null && prettyVersion.length() == 0) { - prettyVersion = null; - } + setPrettyVersion(params.get("prettyVersion")); String lastUpdatedStr = params.get("lastUpdated"); if (lastUpdatedStr != null) { @@ -337,7 +334,9 @@ public boolean writePropertiesFile(File propFile) { writer.println("sentence=" + sentence); writer.println("paragraph=" + paragraph); writer.println("version=" + version); - writer.println("prettyVersion=" + prettyVersion); + if (prettyVersion != null) { + writer.println("prettyVersion=" + prettyVersion); + } writer.println("lastUpdated=" + lastUpdated); writer.println("minRevision=" + minRev); writer.println("maxRevision=" + maxRev); diff --git a/app/src/processing/app/contrib/Contribution.java b/app/src/processing/app/contrib/Contribution.java index 22a6e718a8..0e26380dee 100644 --- a/app/src/processing/app/contrib/Contribution.java +++ b/app/src/processing/app/contrib/Contribution.java @@ -158,6 +158,17 @@ public int getVersion() { } + public void setPrettyVersion(String pretty) { + if (pretty != null) { + // some entries were written as "null", causing that to show in the ui + if (pretty.equals("null") || pretty.length() == 0) { + pretty = null; + } + } + prettyVersion = pretty; + } + + // "1.0.2" or null if not present public String getPrettyVersion() { return prettyVersion; diff --git a/app/src/processing/app/contrib/LocalContribution.java b/app/src/processing/app/contrib/LocalContribution.java index 0bfa6a988d..20c7176b01 100644 --- a/app/src/processing/app/contrib/LocalContribution.java +++ b/app/src/processing/app/contrib/LocalContribution.java @@ -86,10 +86,7 @@ public LocalContribution(File folder) { System.err.println("Please contact the library author to fix it according to the guidelines."); } - prettyVersion = properties.get("prettyVersion"); - if (prettyVersion != null && prettyVersion.length() == 0) { - prettyVersion = null; - } + setPrettyVersion(properties.get("prettyVersion")); try { lastUpdated = Long.parseLong(properties.get("lastUpdated")); diff --git a/todo.txt b/todo.txt index 1cc6f6d7be..459ea75ca6 100755 --- a/todo.txt +++ b/todo.txt @@ -7,6 +7,7 @@ o problem is because AquaButtonUI is calling getImage() (not getIcon()) o can be debugging from inside the getIconX() code in Toolkit X just needed to use setPressedIcon(), setDisabledIcon() X also found some other issues around the icon handling +X fix the library reporting scripts on the server contribs X Up-to-date status disappears after filter is removed @@ -26,7 +27,6 @@ _ https://github.com/processing/processing/issues/4705 _ could provide script to un-quarrantine _ xattr -d -r com.apple.quarantine -_ fix the library reporting scripts on the server _ sharing usage metrics about libraries _ https://github.com/processing/processing/issues/4708 From 884910d991aeffdd81b96554ce8f164c7ba68d4e Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Nov 2016 19:20:39 -0400 Subject: [PATCH 089/917] these are now fixed --- todo.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/todo.txt b/todo.txt index 459ea75ca6..fe5532bef3 100755 --- a/todo.txt +++ b/todo.txt @@ -8,6 +8,10 @@ o can be debugging from inside the getIconX() code in Toolkit X just needed to use setPressedIcon(), setDisabledIcon() X also found some other issues around the icon handling X fix the library reporting scripts on the server +X missing version number putting 'null' in the ui +X https://github.com/processing/processing-docs/issues/478 +X https://github.com/processing/processing/issues/4696 +X https://github.com/processing/processing/pull/4712 contribs X Up-to-date status disappears after filter is removed @@ -32,10 +36,6 @@ _ https://github.com/processing/processing/issues/4708 _ library compilations handled oddly _ https://github.com/processing/processing/issues/4630 -_ missing version number putting 'null' in the ui -_ https://github.com/processing/processing-docs/issues/478 -_ https://github.com/processing/processing/issues/4696 -_ https://github.com/processing/processing/pull/4712 _ editor windows always open on display 1 _ https://github.com/processing/processing/issues/1566 From 2a77ed8ff9149381f208b836c9676afcda4719e6 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Fri, 4 Nov 2016 09:05:36 -0300 Subject: [PATCH 090/917] framerate warning --- core/src/processing/opengl/PSurfaceJOGL.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index ccf31ac402..6a799517e2 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -839,6 +839,10 @@ public void setSmooth(int level) { public void setFrameRate(float fps) { + if (fps < 1) { + PGraphics.showWarning("The OpenGL renderers cannot have a frame rate lower than 1.\nYour sketch will run at 1 frame per second."); + fps = 1; + } if (animator != null) { animator.stop(); animator.setFPS((int)fps); From 931bdbfc49b8a53bcb737f512855d99c2c4ae586 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 5 Nov 2016 14:05:07 -0400 Subject: [PATCH 091/917] trying to clean up DetailPanel --- .../processing/app/contrib/DetailPanel.java | 132 +++++++----------- app/src/processing/app/ui/Toolkit.java | 12 +- core/src/processing/core/PApplet.java | 6 + core/todo.txt | 2 + java/src/processing/mode/java/Compiler.java | 4 +- todo.txt | 22 +-- 6 files changed, 85 insertions(+), 93 deletions(-) diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index 69adc841e6..703e1b0412 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -62,6 +62,8 @@ * Panel that expands and gives a brief overview of a library when clicked. */ class DetailPanel extends JPanel { + Base base; + static public final String REMOVE_RESTART_MESSAGE = String.format("%s", Language.text("contrib.messages.remove_restart")); @@ -104,7 +106,9 @@ public Contribution getContrib() { private JButton installRemoveButton; private JPopupMenu contextMenu; private JMenuItem openFolder; + private JPanel barButtonCardPane; + private CardLayout barButtonCardLayout; private ActionListener removeActionListener; private ActionListener installActionListener; @@ -123,6 +127,8 @@ public Contribution getContrib() { } listPanel = contributionListPanel; + // TODO this accessor is dreadful + base = listPanel.contributionTab.editor.getBase(); barButtonCardPane = new JPanel(); enableHyperlinks = false; @@ -130,10 +136,8 @@ public Contribution getContrib() { conditionalHyperlinkOpener = new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { - if (enableHyperlinks) { - if (e.getURL() != null) { - Platform.openURL(e.getURL().toString()); - } + if (enableHyperlinks && e.getURL() != null) { + Platform.openURL(e.getURL().toString()); } } } @@ -228,26 +232,19 @@ private void addPaneComponents() { if (UIManager.getLookAndFeel().getID().equals("Nimbus")) { descriptionPane.setBackground(new Color(0, 0, 0, 0)); } -// stripTextSelectionListeners(descriptionBlock); descriptionPane.setBorder(new EmptyBorder(4, 7, 7, 7)); descriptionPane.setHighlighter(null); add(descriptionPane, BorderLayout.CENTER); - JPanel updateBox = new JPanel(); //new BoxLayout(filterPanel, BoxLayout.X_AXIS) + JPanel updateBox = new JPanel(); updateBox.setLayout(new BorderLayout()); notificationLabel = new JLabel(); notificationLabel.setInheritsPopupMenu(true); notificationLabel.setVisible(false); notificationLabel.setOpaque(false); - // not needed after changing to JLabel -// notificationBlock.setContentType("text/html"); -// notificationBlock.setHighlighter(null); -// setTextStyle(notificationBlock); -// notificationLabel.setFont(new Font("Verdana", Font.ITALIC, 10)); notificationLabel.setFont(Toolkit.getSansFont(12, Font.PLAIN)); -// stripTextSelectionListeners(notificationBlock); { updateButton = new JButton("Update"); @@ -279,7 +276,8 @@ public void actionPerformed(ActionEvent e) { rightPane.setMinimumSize(new Dimension(DetailPanel.BUTTON_WIDTH, 1)); add(rightPane, BorderLayout.EAST); - barButtonCardPane.setLayout(new CardLayout()); + barButtonCardLayout = new CardLayout(); + barButtonCardPane.setLayout(barButtonCardLayout); barButtonCardPane.setInheritsPopupMenu(true); barButtonCardPane.setOpaque(false); barButtonCardPane.setMinimumSize(new Dimension(DetailPanel.BUTTON_WIDTH, 1)); @@ -312,7 +310,6 @@ public void actionPerformed(ActionEvent e) { JPanel barPane = new JPanel(); barPane.setOpaque(false); -// barPane.add(installProgressBar); JPanel buttonPane = new JPanel(); buttonPane.setOpaque(false); @@ -320,8 +317,7 @@ public void actionPerformed(ActionEvent e) { barButtonCardPane.add(buttonPane, BUTTON_CONSTRAINT); barButtonCardPane.add(barPane, PROGRESS_BAR_CONSTRAINT); - - ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, BUTTON_CONSTRAINT); + barButtonCardLayout.show(barButtonCardPane, BUTTON_CONSTRAINT); rightPane.add(barButtonCardPane); @@ -355,7 +351,6 @@ private void reorganizePaneComponents() { rightPane.setMinimumSize(new Dimension(DetailPanel.BUTTON_WIDTH, 1)); add(rightPane, BorderLayout.EAST); - if (updateButton.isVisible() && !removeInProgress && !contrib.isDeletionFlagged()) { JPanel updateRemovePanel = new JPanel(); updateRemovePanel.setLayout(new FlowLayout()); @@ -368,21 +363,18 @@ private void reorganizePaneComponents() { JPanel barPane = new JPanel(); barPane.setOpaque(false); barPane.setInheritsPopupMenu(true); -// barPane.add(installProgressBar); rightPane.add(barPane); - if (updateInProgress) - ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); - - } - else { + if (updateInProgress) { + barButtonCardLayout.show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); + } + } else { updateBox.add(updateButton, BorderLayout.EAST); barButtonCardPane.removeAll(); JPanel barPane = new JPanel(); barPane.setOpaque(false); barPane.setInheritsPopupMenu(true); -// barPane.add(installProgressBar); JPanel buttonPane = new JPanel(); buttonPane.setOpaque(false); @@ -391,34 +383,33 @@ private void reorganizePaneComponents() { barButtonCardPane.add(buttonPane, BUTTON_CONSTRAINT); barButtonCardPane.add(barPane, PROGRESS_BAR_CONSTRAINT); - if (installInProgress || removeInProgress || updateInProgress) - ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); - else - ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, BUTTON_CONSTRAINT); - + if (installInProgress || removeInProgress || updateInProgress) { + barButtonCardLayout.show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); + } else { + barButtonCardLayout.show(barButtonCardPane, BUTTON_CONSTRAINT); + } rightPane.add(barButtonCardPane); } - Dimension d = installProgressBar.getPreferredSize(); - Dimension d2 = installRemoveButton.getPreferredSize(); - d.width = DetailPanel.BUTTON_WIDTH; - d.height = Math.max(d.height,d2.height); - rightPane.setMinimumSize(d); - rightPane.setPreferredSize(d); + Dimension progressDim = installProgressBar.getPreferredSize(); + Dimension installDim = installRemoveButton.getPreferredSize(); + progressDim.width = DetailPanel.BUTTON_WIDTH; + progressDim.height = Math.max(progressDim.height, installDim.height); + rightPane.setMinimumSize(progressDim); + rightPane.setPreferredSize(progressDim); } private void setExpandListener(Component component, MouseListener expandListener) { - if (component instanceof JButton) { - // This will confuse the button, causing it to stick on OS X - // https://github.com/processing/processing/issues/3172 - return; - } - component.addMouseListener(expandListener); - if (component instanceof Container) { - for (Component child : ((Container) component).getComponents()) { - setExpandListener(child, expandListener); + // If it's a JButton, adding the listener will make this stick on OS X + // https://github.com/processing/processing/issues/3172 + if (!(component instanceof JButton)) { + component.addMouseListener(expandListener); + if (component instanceof Container) { + for (Component child : ((Container) component).getComponents()) { + setExpandListener(child, expandListener); + } } } } @@ -427,8 +418,9 @@ private void setExpandListener(Component component, private void blurContributionPanel(Component component) { component.setFocusable(false); component.setEnabled(false); - if (component instanceof JComponent) + if (component instanceof JComponent) { ((JComponent) component).setToolTipText(INCOMPATIBILITY_BLUR); + } if (component instanceof Container) { for (Component child : ((Container) component).getComponents()) { blurContributionPanel(child); @@ -589,10 +581,11 @@ public void cancelAction() { resetInstallProgressBarState(); installRemoveButton.setEnabled(!contrib.isUpdateFlagged()); - ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, BUTTON_CONSTRAINT); + barButtonCardLayout.show(barButtonCardPane, BUTTON_CONSTRAINT); installInProgress = false; - if(updateInProgress) + if (updateInProgress) { updateInProgress = !updateInProgress; + } updateButton.setVisible(contribListing.hasUpdates(contrib) && !contrib.isUpdateFlagged()); setSelected(true); } @@ -607,10 +600,11 @@ public void finishedAction() { if (isError()) { listPanel.contributionTab.statusPanel.setErrorMessage(Language.text("contrib.download_error")); } - ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, BUTTON_CONSTRAINT); + barButtonCardLayout.show(barButtonCardPane, BUTTON_CONSTRAINT); installInProgress = false; - if(updateInProgress) + if (updateInProgress) { updateInProgress = !updateInProgress; + } updateButton.setVisible(contribListing.hasUpdates(contrib) && !contrib.isUpdateFlagged()); setSelected(true); } @@ -620,8 +614,7 @@ public void cancelAction() { } }; - ContributionManager.downloadAndInstall(listPanel.contributionTab.editor.getBase(), - downloadUrl, ad, + ContributionManager.downloadAndInstall(base, downloadUrl, ad, downloadProgress, installProgress, listPanel.contributionTab.statusPanel); @@ -629,26 +622,11 @@ public void cancelAction() { Messages.showWarning(Language.text("contrib.errors.install_failed"), Language.text("contrib.errors.malformed_url"), e); // not sure why we'd re-enable the button if it had an error... -// installRemoveButton.setEnabled(true); + //installRemoveButton.setEnabled(true); } } - // This doesn't actually seem to work? - /* - static void stripTextSelectionListeners(JEditorPane editorPane) { - for (MouseListener listener : editorPane.getMouseListeners()) { - String className = listener.getClass().getName(); - if (className.endsWith("MutableCaretEvent") || - className.endsWith("DragListener") || - className.endsWith("BasicCaret")) { - editorPane.removeMouseListener(listener); - } - } - } - */ - - protected void resetInstallProgressBarState() { installProgressBar.setString(Language.text("contrib.progress.starting")); installProgressBar.setIndeterminate(false); @@ -763,14 +741,15 @@ static String toHtmlLinks(String stringIn) { * Sets coloring based on whether installed or not; * also makes ugly blue HTML links into the specified color (black). */ - static void setForegroundStyle(JTextPane textPane, boolean installed, boolean selected) { + static void setForegroundStyle(JTextPane textPane, + boolean installed, boolean selected) { Document doc = textPane.getDocument(); if (doc instanceof HTMLDocument) { HTMLDocument html = (HTMLDocument) doc; StyleSheet stylesheet = html.getStyleSheet(); - String c = (installed && !selected) ? "#555555" : "#000000"; // slightly grayed when installed -// String c = "#000000"; // just make them both black + // slightly grayed when installed + String c = (installed && !selected) ? "#555555" : "#000000"; stylesheet.addRule("body { color:" + c + "; }"); stylesheet.addRule("a { color:" + c + "; }"); } @@ -784,7 +763,7 @@ static void setTextStyle(JTextPane textPane) { StyleSheet stylesheet = html.getStyleSheet(); stylesheet.addRule("body { " + " margin: 0; padding: 0;" + - " font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;" + + " font-family: " + Toolkit.getSansFontName() + ", Arial, Helvetica, sans-serif;" + " font-size: 100%;" + "font-size: 0.95em; " + "}"); } @@ -808,7 +787,7 @@ static void setSelectionStyle(JTextPane textPane, boolean selected) { public void install() { listPanel.contributionTab.statusPanel.clearMessage(); installInProgress = true; - ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); + barButtonCardLayout.show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); if (contrib instanceof AvailableContribution) { installContribution((AvailableContribution) contrib); contribListing.replaceContribution(contrib, contrib); @@ -817,7 +796,6 @@ public void install() { public void update() { - listPanel.contributionTab.statusPanel.clearMessage(); updateInProgress = true; if (contrib.getType().requiresRestart()) { @@ -851,12 +829,7 @@ public void cancelAction() { boolean isModeActive = false; if (contrib.getType() == ContributionType.MODE) { ModeContribution m = (ModeContribution) contrib; - //Iterator iter = listPanel.contribManager.editor.getBase().getEditors().iterator(); - //while (iter.hasNext()) { - // TODO there's gotta be a cleaner way to do this accessor - Base base = listPanel.contributionTab.editor.getBase(); for (Editor e : base.getEditors()) { - //Editor e = iter.next(); if (e.getMode().equals(m.getMode())) { isModeActive = true; break; @@ -872,8 +845,7 @@ public void cancelAction() { } }; ((LocalContribution) contrib) - .removeContribution(listPanel.contributionTab.editor.getBase(), - progress, listPanel.contributionTab.statusPanel); + .removeContribution(base, progress, listPanel.contributionTab.statusPanel); } else { updateButton.setEnabled(false); installRemoveButton.setEnabled(false); diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index d6c20911ec..d8378acd43 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -900,7 +900,8 @@ static public String[] getMonoFontFamilies() { static public String getMonoFontName() { if (monoFont == null) { - getMonoFont(12, Font.PLAIN); // load a dummy version + // create a dummy version if the font has never been loaded (rare) + getMonoFont(12, Font.PLAIN); } return monoFont.getName(); } @@ -950,6 +951,15 @@ static public Font getMonoFont(int size, int style) { } + static public String getSansFontName() { + if (sansFont == null) { + // create a dummy version if the font has never been loaded (rare) + getSansFont(12, Font.PLAIN); + } + return sansFont.getName(); + } + + static public Font getSansFont(int size, int style) { if (sansFont == null) { try { diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index dcd9ee7818..1f5790b79e 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -1194,6 +1194,7 @@ static public int displayDensity(int display) { * */ public void pixelDensity(int density) { + println(density + " " + this.pixelDensity); if (density != this.pixelDensity) { if (insideSettings("pixelDensity", density)) { if (density != 1 && density != 2) { @@ -1205,6 +1206,11 @@ public void pixelDensity(int density) { } else { this.pixelDensity = density; } + } else { + System.err.println("not inside settings"); + // this should only be reachable when not running in the PDE, + // so saying it's a settings()--not just setup()--issue should be ok + throw new RuntimeException("pixelDensity() can only be used inside settings()"); } } } diff --git a/core/todo.txt b/core/todo.txt index e72a1fdb5a..d06732855f 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -4,6 +4,8 @@ andres X automatic detection of POINT and LINE shaders fails X https://github.com/processing/processing/issues/4725 +X show warning when frameRate() less than 1 is called with P2D and P3D +X https://github.com/processing/processing/issues/4716 _ TRIANGLE_STRIP not working correctly with createShape() and default renderer diff --git a/java/src/processing/mode/java/Compiler.java b/java/src/processing/mode/java/Compiler.java index c62b4c000a..43095c893a 100644 --- a/java/src/processing/mode/java/Compiler.java +++ b/java/src/processing/mode/java/Compiler.java @@ -211,8 +211,8 @@ public void close() { } String suggestion = importSuggestions.get(what); if (suggestion != null) { System.err.println("You may need to add \"import " + suggestion + ";\" to the top of your sketch."); - System.err.println("To make sketches more portable, imports that are not part of the Processing API have been removed from Processing 2.0."); - System.err.println("See the changes page for more information: http://wiki.processing.org/w/Changes"); + System.err.println("To make sketches more portable, imports that are not part of the Processing API were removed in Processing 2."); + System.err.println("See the changes page for more information: https://github.com/processing/processing/wiki/Changes"); } } diff --git a/todo.txt b/todo.txt index fe5532bef3..7854022cf9 100755 --- a/todo.txt +++ b/todo.txt @@ -12,6 +12,9 @@ X missing version number putting 'null' in the ui X https://github.com/processing/processing-docs/issues/478 X https://github.com/processing/processing/issues/4696 X https://github.com/processing/processing/pull/4712 +o replace appbundler with the Java 8 packager +o appbundler is no longer being developed by Oracle, switch to "packager" +X https://github.com/processing/processing/issues/3071 contribs X Up-to-date status disappears after filter is removed @@ -22,6 +25,15 @@ X https://github.com/processing/processing/issues/4704 X Fixes the removal of redundant contribution and update related issues X https://github.com/processing/processing/pull/4086 +_ fix appbundler problems due to rollback +_ https://github.com/processing/processing/issues/3790 +_ the rollback re-introduces two bugs (serial export and scrolling) +_ and any other changes later than 16 November 2014: +_ https://github.com/processing/processing/commits/master/build/macosx/appbundler.jar +_ https://github.com/processing/processing/commits/master/build/macosx/appbundler/native/main.m +_ https://github.com/processing/processing/commit/fa27b983e76fdbc5c4c1451a1f0d854c652b1639 +_ https://bitbucket.org/infinitekind/appbundler + _ 'version' should be x.y or x.y.z, not some extra long string _ enforce this by disallowing spaces? on the import script? @@ -916,16 +928,6 @@ DIST / Mac OS X _ client properties _ https://developer.apple.com/library/mac/technotes/tn2007/tn2196.html _ built-in images: http://nadeausoftware.com/articles/2008/12/mac_java_tip_how_access_mac_specific_nsimage_icons -_ replace appbundler with the Java 8 packager -_ https://github.com/processing/processing/issues/3071 -_ fix appbundler problems due to rollback -_ https://github.com/processing/processing/issues/3790 -_ appbundler is no longer being developed by Oracle, switch to "packager" -_ this re-introduces two bugs (serial export and scrolling) -_ and any other changes later than 16 November 2014: -_ https://github.com/processing/processing/commits/master/build/macosx/appbundler.jar -_ https://github.com/processing/processing/commits/master/build/macosx/appbundler/native/main.m -_ https://github.com/processing/processing/commit/fa27b983e76fdbc5c4c1451a1f0d854c652b1639 _ Update QuickLook plugin for Processing 3 _ https://github.com/processing/processing/issues/3261 _ Find a long-term solution for OS X bundler to address signing/symlink issues From 77306eef827493e5a584c665b21bc41ba791c752 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 5 Nov 2016 14:28:08 -0400 Subject: [PATCH 092/917] more cleanup attempts --- .../processing/app/contrib/DetailPanel.java | 111 ++++++++++++------ 1 file changed, 72 insertions(+), 39 deletions(-) diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index 703e1b0412..fbe3e76fdc 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -96,6 +96,10 @@ public Contribution getContrib() { return contrib; } + private LocalContribution getLocalContrib() { + return (LocalContribution) contrib; + } + private boolean alreadySelected; private boolean enableHyperlinks; private HyperlinkListener conditionalHyperlinkOpener; @@ -151,9 +155,9 @@ public void actionPerformed(ActionEvent e) { undoActionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { - listPanel.contributionTab.statusPanel.clearMessage(); + clearStatusMessage(); if (contrib instanceof LocalContribution) { - LocalContribution installed = (LocalContribution) contrib; + LocalContribution installed = getLocalContrib(); installed.setDeletionFlag(false); contribListing.replaceContribution(contrib, contrib); // ?? Iterator contribsListIter = contribListing.allContributions.iterator(); @@ -204,9 +208,8 @@ public void mousePressed(MouseEvent e) { if (contrib.isCompatible(Base.getRevision())) { listPanel.setSelectedPanel(DetailPanel.this); } else { - final String msg = contrib.getName() - + " is not compatible with this version of Processing"; - listPanel.contributionTab.statusPanel.setErrorMessage(msg); + setErrorMessage(contrib.getName() + + " cannot be used with this version of Processing"); } } }); @@ -557,13 +560,31 @@ public void setContribution(Contribution contrib) { private void installContribution(AvailableContribution info) { if (info.link == null) { - listPanel.contributionTab.statusPanel.setErrorMessage(Language.interpolate("contrib.unsupported_operating_system", info.getType())); + setErrorMessage(Language.interpolate("contrib.unsupported_operating_system", info.getType())); } else { installContribution(info, info.link); } } + private void finishInstall(boolean error) { + // Finished installing library + resetInstallProgressBarState(); + installRemoveButton.setEnabled(!contrib.isUpdateFlagged()); + + if (error) { + setErrorMessage(Language.text("contrib.download_error")); + } + barButtonCardLayout.show(barButtonCardPane, BUTTON_CONSTRAINT); + installInProgress = false; + if (updateInProgress) { + updateInProgress = !updateInProgress; + } + updateButton.setVisible(contribListing.hasUpdates(contrib) && !contrib.isUpdateFlagged()); + setSelected(true); + } + + private void installContribution(AvailableContribution ad, String url) { installRemoveButton.setEnabled(false); @@ -577,6 +598,8 @@ public void finishedAction() { } public void cancelAction() { + finishInstall(false); + /* // Finished installing library resetInstallProgressBarState(); installRemoveButton.setEnabled(!contrib.isUpdateFlagged()); @@ -588,15 +611,19 @@ public void cancelAction() { } updateButton.setVisible(contribListing.hasUpdates(contrib) && !contrib.isUpdateFlagged()); setSelected(true); + */ } }; ContribProgressBar installProgress = new ContribProgressBar(installProgressBar) { public void finishedAction() { + finishInstall(isError()); + /* // Finished installing library resetInstallProgressBarState(); installRemoveButton.setEnabled(!contrib.isUpdateFlagged()); + // fwiw, this block wasn't part of the cancelAction() code if (isError()) { listPanel.contributionTab.statusPanel.setErrorMessage(Language.text("contrib.download_error")); } @@ -607,6 +634,7 @@ public void finishedAction() { } updateButton.setVisible(contribListing.hasUpdates(contrib) && !contrib.isUpdateFlagged()); setSelected(true); + */ } public void cancelAction() { @@ -616,7 +644,7 @@ public void cancelAction() { ContributionManager.downloadAndInstall(base, downloadUrl, ad, downloadProgress, installProgress, - listPanel.contributionTab.statusPanel); + getStatusPanel()); } catch (MalformedURLException e) { Messages.showWarning(Language.text("contrib.errors.install_failed"), @@ -785,7 +813,7 @@ static void setSelectionStyle(JTextPane textPane, boolean selected) { public void install() { - listPanel.contributionTab.statusPanel.clearMessage(); + clearStatusMessage(); installInProgress = true; barButtonCardLayout.show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); if (contrib instanceof AvailableContribution) { @@ -796,7 +824,7 @@ public void install() { public void update() { - listPanel.contributionTab.statusPanel.clearMessage(); + clearStatusMessage(); updateInProgress = true; if (contrib.getType().requiresRestart()) { installRemoveButton.setEnabled(false); @@ -817,13 +845,14 @@ public void finishedAction() { @Override public void cancelAction() { resetInstallProgressBarState(); - listPanel.contributionTab.statusPanel.setMessage(""); + //listPanel.contributionTab.statusPanel.setMessage(""); + clearStatusMessage(); updateInProgress = false; installRemoveButton.setEnabled(true); if (contrib.isDeletionFlagged()) { - ((LocalContribution)contrib).setUpdateFlag(true); - ((LocalContribution)contrib).setDeletionFlag(false); - contribListing.replaceContribution(contrib,contrib); + getLocalContrib().setUpdateFlag(true); + getLocalContrib().setDeletionFlag(false); + contribListing.replaceContribution(contrib, contrib); } boolean isModeActive = false; @@ -844,58 +873,49 @@ public void cancelAction() { } } }; - ((LocalContribution) contrib) - .removeContribution(base, progress, listPanel.contributionTab.statusPanel); + getLocalContrib().removeContribution(base, progress, getStatusPanel()); } else { updateButton.setEnabled(false); installRemoveButton.setEnabled(false); - AvailableContribution ad = contribListing.getAvailableContribution(contrib); - String url = ad.link; - installContribution(ad, url); + AvailableContribution ad = + contribListing.getAvailableContribution(contrib); + installContribution(ad, ad.link); } } public void remove() { - - listPanel.contributionTab.statusPanel.clearMessage(); + clearStatusMessage(); if (contrib.isInstalled() && contrib instanceof LocalContribution) { removeInProgress = true; - ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); + barButtonCardLayout.show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); updateButton.setEnabled(false); installRemoveButton.setEnabled(false); installProgressBar.setVisible(true); installProgressBar.setIndeterminate(true); ContribProgressBar monitor = new ContribProgressBar(installProgressBar) { - public void finishedAction() { - // Finished uninstalling the library + private void preAction() { resetInstallProgressBarState(); removeInProgress = false; installRemoveButton.setEnabled(true); - reorganizePaneComponents(); setSelected(true); // Needed for smooth working. Dunno why, though... } - public void cancelAction() { - resetInstallProgressBarState(); - removeInProgress = false; - installRemoveButton.setEnabled(true); + public void finishedAction() { + // Finished uninstalling the library + preAction(); + } - reorganizePaneComponents(); - setSelected(true); + public void cancelAction() { + preAction(); - ContributionTab contributionTab = listPanel.contributionTab; boolean isModeActive = false; if (contrib.getType() == ContributionType.MODE) { ModeContribution m = (ModeContribution) contrib; - // TODO there's gotta be a cleaner way to do this accessor - for (Editor e : contributionTab.editor.getBase().getEditors()) { - //Iterator iter = listPanel.contribManager.editor.getBase().getEditors().iterator(); - //while (iter.hasNext()) { - //Editor e = iter.next(); + for (Editor e : base.getEditors()) { if (e.getMode().equals(m.getMode())) { isModeActive = true; break; @@ -910,10 +930,23 @@ public void cancelAction() { } } }; - ContributionTab contributionTab = listPanel.contributionTab; - LocalContribution localContrib = (LocalContribution) contrib; - localContrib.removeContribution(contributionTab.editor.getBase(), monitor, contributionTab.statusPanel); + getLocalContrib().removeContribution(base, monitor, getStatusPanel()); } + } + + + // TODO this is gross [fry 161105] + private StatusPanel getStatusPanel() { + return listPanel.contributionTab.statusPanel; + } + + + private void clearStatusMessage() { + getStatusPanel().clearMessage(); + } + + private void setErrorMessage(String message) { + getStatusPanel().setErrorMessage(message); } } From 999993d2d60bd863ea60ee50837efefd4399f116 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 5 Nov 2016 14:57:10 -0400 Subject: [PATCH 093/917] clear out the excessive hyperlink stuff --- .../processing/app/contrib/DetailPanel.java | 101 +++++++++--------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index fbe3e76fdc..12f1272336 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2013-15 The Processing Foundation + Copyright (c) 2013-16 The Processing Foundation Copyright (c) 2011-12 Ben Fry and Casey Reas This program is free software; you can redistribute it and/or modify @@ -48,22 +48,16 @@ import processing.app.ui.Toolkit; -// TODO clean up accessors (too many cases of several de-references for basic tasks -// TODO hyperlink listener seems far too complicated for what it does, -// and why have a 'null' version rather than detecting whether selected or not // TODO don't add/remove listeners for install/remove/undo based on function, // just keep track of current behavior and call that. too many things can go wrong. // TODO get rid of huge actionPerformed() blocks with anonymous classes, // just make handleInstall(), etc methods and a single actionPerformed // for the button that calls the necessary behavior (see prev note) -// TODO switch to the built-in fonts (available from Toolkit) rather than verdana et al /** * Panel that expands and gives a brief overview of a library when clicked. */ class DetailPanel extends JPanel { - Base base; - static public final String REMOVE_RESTART_MESSAGE = String.format("%s", Language.text("contrib.messages.remove_restart")); @@ -102,7 +96,7 @@ private LocalContribution getLocalContrib() { private boolean alreadySelected; private boolean enableHyperlinks; - private HyperlinkListener conditionalHyperlinkOpener; + //private HyperlinkListener conditionalHyperlinkOpener; private JTextPane descriptionPane; private JLabel notificationLabel; private JButton updateButton; @@ -131,22 +125,8 @@ private LocalContribution getLocalContrib() { } listPanel = contributionListPanel; - // TODO this accessor is dreadful - base = listPanel.contributionTab.editor.getBase(); barButtonCardPane = new JPanel(); - enableHyperlinks = false; - alreadySelected = false; - conditionalHyperlinkOpener = new HyperlinkListener() { - public void hyperlinkUpdate(HyperlinkEvent e) { - if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { - if (enableHyperlinks && e.getURL() != null) { - Platform.openURL(e.getURL().toString()); - } - } - } - }; - installActionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { install(); @@ -238,6 +218,20 @@ private void addPaneComponents() { descriptionPane.setBorder(new EmptyBorder(4, 7, 7, 7)); descriptionPane.setHighlighter(null); + descriptionPane.addHyperlinkListener(new HyperlinkListener() { + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + // for 3.2.3, added the isSelected() prompt here, rather than + // adding/removing the listener repeatedly + if (isSelected()) { + if (enableHyperlinks && e.getURL() != null) { + Platform.openURL(e.getURL().toString()); + } + } + } + } + }); + add(descriptionPane, BorderLayout.CENTER); JPanel updateBox = new JPanel(); @@ -642,7 +636,7 @@ public void cancelAction() { } }; - ContributionManager.downloadAndInstall(base, downloadUrl, ad, + ContributionManager.downloadAndInstall(getBase(), downloadUrl, ad, downloadProgress, installProgress, getStatusPanel()); @@ -663,9 +657,11 @@ protected void resetInstallProgressBarState() { } + /* static final HyperlinkListener NULL_HYPERLINK_LISTENER = new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { } }; + */ /** @@ -686,6 +682,7 @@ public void setSelected(boolean isSelected) { installRemoveButton.setEnabled(installRemoveButton.getText().equals(Language.text("contrib.remove")) ||!contribListing.hasListDownloadFailed()); reorganizePaneComponents(); + /* descriptionPane.removeHyperlinkListener(NULL_HYPERLINK_LISTENER); descriptionPane.removeHyperlinkListener(conditionalHyperlinkOpener); if (isSelected()) { @@ -695,6 +692,7 @@ public void setSelected(boolean isSelected) { descriptionPane.addHyperlinkListener(NULL_HYPERLINK_LISTENER); // descriptionPane.setEditable(true); } + */ // Update style of hyperlinks setSelectionStyle(descriptionPane, isSelected()); @@ -855,17 +853,7 @@ public void cancelAction() { contribListing.replaceContribution(contrib, contrib); } - boolean isModeActive = false; - if (contrib.getType() == ContributionType.MODE) { - ModeContribution m = (ModeContribution) contrib; - for (Editor e : base.getEditors()) { - if (e.getMode().equals(m.getMode())) { - isModeActive = true; - break; - } - } - } - if (isModeActive) { + if (isModeActive(contrib)) { updateButton.setEnabled(true); } else { // TODO: remove or uncomment if the button was added @@ -873,7 +861,7 @@ public void cancelAction() { } } }; - getLocalContrib().removeContribution(base, progress, getStatusPanel()); + getLocalContrib().removeContribution(getBase(), progress, getStatusPanel()); } else { updateButton.setEnabled(false); installRemoveButton.setEnabled(false); @@ -881,7 +869,6 @@ public void cancelAction() { contribListing.getAvailableContribution(contrib); installContribution(ad, ad.link); } - } @@ -912,17 +899,7 @@ public void finishedAction() { public void cancelAction() { preAction(); - boolean isModeActive = false; - if (contrib.getType() == ContributionType.MODE) { - ModeContribution m = (ModeContribution) contrib; - for (Editor e : base.getEditors()) { - if (e.getMode().equals(m.getMode())) { - isModeActive = true; - break; - } - } - } - if (isModeActive) { + if (isModeActive(contrib)) { updateButton.setEnabled(true); } else { // TODO: remove or uncomment if the button was added @@ -930,14 +907,38 @@ public void cancelAction() { } } }; - getLocalContrib().removeContribution(base, monitor, getStatusPanel()); + getLocalContrib().removeContribution(getBase(), monitor, getStatusPanel()); + } + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + // Can't be called from the constructor because the path isn't set all the + // way down. However, it's not Base changes over time. More importantly, + // though, is that the functions being called in Base are somewhat suspect + // since they're contribution-related, and should perhaps live closer. + private Base getBase() { + return listPanel.contributionTab.editor.getBase(); + } + + + private boolean isModeActive(Contribution contrib) { + if (contrib.getType() == ContributionType.MODE) { + ModeContribution m = (ModeContribution) contrib; + for (Editor e : getBase().getEditors()) { + if (e.getMode().equals(m.getMode())) { + return true; + } + } } + return false; } - // TODO this is gross [fry 161105] private StatusPanel getStatusPanel() { - return listPanel.contributionTab.statusPanel; + return listPanel.contributionTab.statusPanel; // TODO this is gross [fry] } From 2ba6e907b72736429ff5f52e5913bc35b160d580 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 5 Nov 2016 15:23:45 -0400 Subject: [PATCH 094/917] break out these enormous functions for readability --- .../processing/app/contrib/DetailPanel.java | 221 +++++++++--------- 1 file changed, 114 insertions(+), 107 deletions(-) diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index 12f1272336..6344b3bc82 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -48,8 +48,6 @@ import processing.app.ui.Toolkit; -// TODO don't add/remove listeners for install/remove/undo based on function, -// just keep track of current behavior and call that. too many things can go wrong. // TODO get rid of huge actionPerformed() blocks with anonymous classes, // just make handleInstall(), etc methods and a single actionPerformed // for the button that calls the necessary behavior (see prev note) @@ -108,9 +106,9 @@ private LocalContribution getLocalContrib() { private JPanel barButtonCardPane; private CardLayout barButtonCardLayout; - private ActionListener removeActionListener; - private ActionListener installActionListener; - private ActionListener undoActionListener; + static private final String installText = Language.text("contrib.install"); + static private final String removeText = Language.text("contrib.remove"); + static private final String undoText = Language.text("contrib.undo"); boolean updateInProgress; boolean installInProgress; @@ -127,42 +125,9 @@ private LocalContribution getLocalContrib() { listPanel = contributionListPanel; barButtonCardPane = new JPanel(); - installActionListener = new ActionListener() { - public void actionPerformed(ActionEvent e) { - install(); - } - }; - - undoActionListener = new ActionListener() { - public void actionPerformed(ActionEvent e) { - clearStatusMessage(); - if (contrib instanceof LocalContribution) { - LocalContribution installed = getLocalContrib(); - installed.setDeletionFlag(false); - contribListing.replaceContribution(contrib, contrib); // ?? - Iterator contribsListIter = contribListing.allContributions.iterator(); - boolean toBeRestarted = false; - while (contribsListIter.hasNext()) { - Contribution contribElement = contribsListIter.next(); - if (contrib.getType().equals(contribElement.getType())) { - if (contribElement.isDeletionFlagged() || - contribElement.isUpdateFlagged()) { - toBeRestarted = !toBeRestarted; - break; - } - } - } - // TODO: remove or uncomment if the button was added - //listPanel.contributionTab.restartButton.setVisible(toBeRestarted); - } - } - }; - - removeActionListener = new ActionListener() { - public void actionPerformed(ActionEvent arg) { - remove(); - } - }; +// installText = Language.text("contrib.install"); +// removeText = Language.text("contrib.remove"); +// undoText = Language.text("contrib.undo"); contextMenu = new JPopupMenu(); openFolder = new JMenuItem("Open Folder"); @@ -296,6 +261,18 @@ public void actionPerformed(ActionEvent e) { installRemoveButton = new JButton(" "); installRemoveButton.setInheritsPopupMenu(true); + installRemoveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String mode = installRemoveButton.getText(); + if (mode.equals(installText)) { + install(); + } else if (mode.equals(removeText)) { + remove(); + } else if (mode.equals(undoText)) { + undo(); + } + } + }); Dimension installButtonDimensions = installRemoveButton.getPreferredSize(); installButtonDimensions.width = DetailPanel.BUTTON_WIDTH; @@ -520,26 +497,19 @@ public void setContribution(Contribution contrib) { updateButton.setVisible((contribListing.hasUpdates(contrib) && !contrib.isUpdateFlagged() && !contrib.isDeletionFlagged()) || updateInProgress); } - installRemoveButton.removeActionListener(installActionListener); - installRemoveButton.removeActionListener(removeActionListener); - installRemoveButton.removeActionListener(undoActionListener); - if (contrib.isDeletionFlagged()) { - installRemoveButton.addActionListener(undoActionListener); - installRemoveButton.setText(Language.text("contrib.undo")); + installRemoveButton.setText(undoText); + } else if (contrib.isInstalled()) { - installRemoveButton.addActionListener(removeActionListener); - installRemoveButton.setText(Language.text("contrib.remove")); + installRemoveButton.setText(removeText); installRemoveButton.setVisible(true); installRemoveButton.setEnabled(!contrib.isUpdateFlagged()); reorganizePaneComponents(); } else { - installRemoveButton.addActionListener(installActionListener); - installRemoveButton.setText(Language.text("contrib.install")); + installRemoveButton.setText(installText); } contextMenu.removeAll(); - if (contrib.isInstalled()) { contextMenu.add(openFolder); setComponentPopupMenu(contextMenu); @@ -552,6 +522,7 @@ public void setContribution(Contribution contrib) { } } + private void installContribution(AvailableContribution info) { if (info.link == null) { setErrorMessage(Language.interpolate("contrib.unsupported_operating_system", info.getType())); @@ -562,7 +533,6 @@ private void installContribution(AvailableContribution info) { private void finishInstall(boolean error) { - // Finished installing library resetInstallProgressBarState(); installRemoveButton.setEnabled(!contrib.isUpdateFlagged()); @@ -572,7 +542,7 @@ private void finishInstall(boolean error) { barButtonCardLayout.show(barButtonCardPane, BUTTON_CONSTRAINT); installInProgress = false; if (updateInProgress) { - updateInProgress = !updateInProgress; + updateInProgress = false; } updateButton.setVisible(contribListing.hasUpdates(contrib) && !contrib.isUpdateFlagged()); setSelected(true); @@ -829,38 +799,7 @@ public void update() { installProgressBar.setVisible(true); installProgressBar.setIndeterminate(true); - ContribProgressBar progress = new ContribProgressBar(installProgressBar) { - public void finishedAction() { - // Finished uninstalling the library - resetInstallProgressBarState(); - updateButton.setEnabled(false); - AvailableContribution ad = - contribListing.getAvailableContribution(contrib); - String url = ad.link; - installContribution(ad, url); - } - - @Override - public void cancelAction() { - resetInstallProgressBarState(); - //listPanel.contributionTab.statusPanel.setMessage(""); - clearStatusMessage(); - updateInProgress = false; - installRemoveButton.setEnabled(true); - if (contrib.isDeletionFlagged()) { - getLocalContrib().setUpdateFlag(true); - getLocalContrib().setDeletionFlag(false); - contribListing.replaceContribution(contrib, contrib); - } - - if (isModeActive(contrib)) { - updateButton.setEnabled(true); - } else { - // TODO: remove or uncomment if the button was added - //listPanel.contributionTab.restartButton.setVisible(true); - } - } - }; + ContribProgressBar progress = new UpdateProgressBar(installProgressBar); getLocalContrib().removeContribution(getBase(), progress, getStatusPanel()); } else { updateButton.setEnabled(false); @@ -872,6 +811,43 @@ public void cancelAction() { } + class UpdateProgressBar extends ContribProgressBar { + public UpdateProgressBar(JProgressBar progressBar) { + super(progressBar); + } + + public void finishedAction() { + resetInstallProgressBarState(); + updateButton.setEnabled(false); + AvailableContribution ad = + contribListing.getAvailableContribution(contrib); + String url = ad.link; + installContribution(ad, url); + } + + @Override + public void cancelAction() { + resetInstallProgressBarState(); + //listPanel.contributionTab.statusPanel.setMessage(""); // same as clear? + clearStatusMessage(); + updateInProgress = false; + installRemoveButton.setEnabled(true); + if (contrib.isDeletionFlagged()) { + getLocalContrib().setUpdateFlag(true); + getLocalContrib().setDeletionFlag(false); + contribListing.replaceContribution(contrib, contrib); + } + + if (isModeActive(contrib)) { + updateButton.setEnabled(true); + } else { + // TODO: remove or uncomment if the button was added + //listPanel.contributionTab.restartButton.setVisible(true); + } + } + } + + public void remove() { clearStatusMessage(); if (contrib.isInstalled() && contrib instanceof LocalContribution) { @@ -882,32 +858,63 @@ public void remove() { installProgressBar.setVisible(true); installProgressBar.setIndeterminate(true); - ContribProgressBar monitor = new ContribProgressBar(installProgressBar) { - private void preAction() { - resetInstallProgressBarState(); - removeInProgress = false; - installRemoveButton.setEnabled(true); - reorganizePaneComponents(); - setSelected(true); // Needed for smooth working. Dunno why, though... - } + ContribProgressBar monitor = new RemoveProgressBar(installProgressBar); + getLocalContrib().removeContribution(getBase(), monitor, getStatusPanel()); + } + } - public void finishedAction() { - // Finished uninstalling the library - preAction(); - } - public void cancelAction() { - preAction(); + class RemoveProgressBar extends ContribProgressBar { + public RemoveProgressBar(JProgressBar progressBar) { + super(progressBar); + } + + private void preAction() { + resetInstallProgressBarState(); + removeInProgress = false; + installRemoveButton.setEnabled(true); + reorganizePaneComponents(); + setSelected(true); // Needed for smooth working. Dunno why, though... + } + + public void finishedAction() { + // Finished uninstalling the library + preAction(); + } + + public void cancelAction() { + preAction(); + + if (isModeActive(contrib)) { + updateButton.setEnabled(true); + } else { + // TODO: remove or uncomment if the button was added + //contributionTab.restartButton.setVisible(true); + } + } + } + - if (isModeActive(contrib)) { - updateButton.setEnabled(true); - } else { - // TODO: remove or uncomment if the button was added - //contributionTab.restartButton.setVisible(true); + private void undo() { + clearStatusMessage(); + if (contrib instanceof LocalContribution) { + LocalContribution installed = getLocalContrib(); + installed.setDeletionFlag(false); + contribListing.replaceContribution(contrib, contrib); // ?? + Iterator contribsListIter = contribListing.allContributions.iterator(); + boolean toBeRestarted = false; + while (contribsListIter.hasNext()) { + Contribution contribElement = contribsListIter.next(); + if (contrib.getType().equals(contribElement.getType())) { + if (contribElement.isDeletionFlagged() || + contribElement.isUpdateFlagged()) { + toBeRestarted = !toBeRestarted; + break; } } - }; - getLocalContrib().removeContribution(getBase(), monitor, getStatusPanel()); + } + // TODO: remove or uncomment if the button was added + //listPanel.contributionTab.restartButton.setVisible(toBeRestarted); } } From b3f1970ccd56633b53494083a99f7eba31c5729c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 5 Nov 2016 15:25:50 -0400 Subject: [PATCH 095/917] remove some dead code, finish the general cleaning --- .../processing/app/contrib/DetailPanel.java | 40 +------------------ 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index 6344b3bc82..33de5b2885 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -48,10 +48,6 @@ import processing.app.ui.Toolkit; -// TODO get rid of huge actionPerformed() blocks with anonymous classes, -// just make handleInstall(), etc methods and a single actionPerformed -// for the button that calls the necessary behavior (see prev note) - /** * Panel that expands and gives a brief overview of a library when clicked. */ @@ -125,10 +121,6 @@ private LocalContribution getLocalContrib() { listPanel = contributionListPanel; barButtonCardPane = new JPanel(); -// installText = Language.text("contrib.install"); -// removeText = Language.text("contrib.remove"); -// undoText = Language.text("contrib.undo"); - contextMenu = new JPopupMenu(); openFolder = new JMenuItem("Open Folder"); openFolder.addActionListener(new ActionListener() { @@ -558,47 +550,17 @@ private void installContribution(AvailableContribution ad, String url) { ContribProgressBar downloadProgress = new ContribProgressBar(installProgressBar) { public void finishedAction() { - // Finished downloading library + // nothing? } public void cancelAction() { finishInstall(false); - /* - // Finished installing library - resetInstallProgressBarState(); - installRemoveButton.setEnabled(!contrib.isUpdateFlagged()); - - barButtonCardLayout.show(barButtonCardPane, BUTTON_CONSTRAINT); - installInProgress = false; - if (updateInProgress) { - updateInProgress = !updateInProgress; - } - updateButton.setVisible(contribListing.hasUpdates(contrib) && !contrib.isUpdateFlagged()); - setSelected(true); - */ } }; ContribProgressBar installProgress = new ContribProgressBar(installProgressBar) { public void finishedAction() { finishInstall(isError()); - /* - // Finished installing library - resetInstallProgressBarState(); - installRemoveButton.setEnabled(!contrib.isUpdateFlagged()); - - // fwiw, this block wasn't part of the cancelAction() code - if (isError()) { - listPanel.contributionTab.statusPanel.setErrorMessage(Language.text("contrib.download_error")); - } - barButtonCardLayout.show(barButtonCardPane, BUTTON_CONSTRAINT); - installInProgress = false; - if (updateInProgress) { - updateInProgress = !updateInProgress; - } - updateButton.setVisible(contribListing.hasUpdates(contrib) && !contrib.isUpdateFlagged()); - setSelected(true); - */ } public void cancelAction() { From c898459e1e5bdf149075313ee48913fd5d56dff3 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 6 Nov 2016 14:01:53 -0500 Subject: [PATCH 096/917] add note about the manager code --- todo.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/todo.txt b/todo.txt index 7854022cf9..1d11e20342 100755 --- a/todo.txt +++ b/todo.txt @@ -15,6 +15,7 @@ X https://github.com/processing/processing/pull/4712 o replace appbundler with the Java 8 packager o appbundler is no longer being developed by Oracle, switch to "packager" X https://github.com/processing/processing/issues/3071 +X major clean-ups to the Contribution Manager code contribs X Up-to-date status disappears after filter is removed @@ -25,6 +26,7 @@ X https://github.com/processing/processing/issues/4704 X Fixes the removal of redundant contribution and update related issues X https://github.com/processing/processing/pull/4086 + _ fix appbundler problems due to rollback _ https://github.com/processing/processing/issues/3790 _ the rollback re-introduces two bugs (serial export and scrolling) @@ -34,7 +36,6 @@ _ https://github.com/processing/processing/commits/master/build/macosx/appbund _ https://github.com/processing/processing/commit/fa27b983e76fdbc5c4c1451a1f0d854c652b1639 _ https://bitbucket.org/infinitekind/appbundler - _ 'version' should be x.y or x.y.z, not some extra long string _ enforce this by disallowing spaces? on the import script? From fc1ba860f715caf3bd7a962c43cf6e2b76e55823 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 6 Nov 2016 21:27:00 -0500 Subject: [PATCH 097/917] todo notes --- core/todo.txt | 1 + todo.txt | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index d06732855f..9c6d385de7 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,4 +1,5 @@ 0255 (3.2.3 or 3.3) +_ add StringDict.Entry class for iterating andres diff --git a/todo.txt b/todo.txt index 1d11e20342..ab82a4c8d0 100755 --- a/todo.txt +++ b/todo.txt @@ -36,6 +36,9 @@ _ https://github.com/processing/processing/commits/master/build/macosx/appbund _ https://github.com/processing/processing/commit/fa27b983e76fdbc5c4c1451a1f0d854c652b1639 _ https://bitbucket.org/infinitekind/appbundler +_ settings() present and pixelDensity() is in setup(), nothing set/no error +_ https://github.com/processing/processing/issues/4703 + _ 'version' should be x.y or x.y.z, not some extra long string _ enforce this by disallowing spaces? on the import script? @@ -695,6 +698,8 @@ _ e.g. ocd is broken in 0125 because of method signature changes PDE / Manager +_ proper error handling when downloading contribs listing +_ https://github.com/processing/processing/issues/4732 _ update CM entries when sketchbook location changes _ https://github.com/processing/processing/issues/3927 _ ugly white gap at the top of scroll bar From 2d8a80c88f269be2887d070a63059a579c72bda1 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 6 Nov 2016 21:27:25 -0500 Subject: [PATCH 098/917] catching openURL() issues on macOS --- .../processing/app/platform/MacPlatform.java | 18 ++++++++++++++++++ app/src/processing/app/ui/Editor.java | 1 + 2 files changed, 19 insertions(+) diff --git a/app/src/processing/app/platform/MacPlatform.java b/app/src/processing/app/platform/MacPlatform.java index 8fab34e6d7..b3fd404d97 100644 --- a/app/src/processing/app/platform/MacPlatform.java +++ b/app/src/processing/app/platform/MacPlatform.java @@ -22,9 +22,11 @@ package processing.app.platform; +import java.awt.Desktop; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.net.URI; import com.apple.eio.FileManager; @@ -62,6 +64,7 @@ public void saveLanguage(String language) { } } + public void initBase(Base base) { super.initBase(base); System.setProperty("apple.laf.useScreenMenuBar", "true"); @@ -127,6 +130,21 @@ public File getDefaultSketchbookFolder() throws Exception { // } + public void openURL(String url) throws Exception { + try { + Desktop.getDesktop().browse(new URI(url)); + } catch (IOException e) { + // Deal with a situation where the browser hangs on macOS + // https://github.com/fathominfo/processing-p5js-mode/issues/4 + if (e.getMessage().contains("Error code: -600")) { + throw new RuntimeException("Could not open the sketch, please restart your browser or computer"); + } else { + throw e; + } + } + } + + /* public void openURL(String url) throws Exception { if (PApplet.javaVersion < 1.6f) { diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index fd2de22be7..b4baaa71ac 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -2579,6 +2579,7 @@ protected void handleOpenInternal(String path) throws EditorException { Preferences.save(); } + /** * Set the title of the PDE window based on the current sketch, i.e. * something like "sketch_070752a - Processing 0126" From 7499d9514cc6518f063d02f9af9ff038d23afe53 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 6 Nov 2016 21:28:01 -0500 Subject: [PATCH 099/917] make a note about the browser hanging --- todo.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/todo.txt b/todo.txt index ab82a4c8d0..9296aca40b 100755 --- a/todo.txt +++ b/todo.txt @@ -16,6 +16,8 @@ o replace appbundler with the Java 8 packager o appbundler is no longer being developed by Oracle, switch to "packager" X https://github.com/processing/processing/issues/3071 X major clean-ups to the Contribution Manager code +X Deal with a situation where the browser hangs on macOS +X https://github.com/fathominfo/processing-p5js-mode/issues/4 contribs X Up-to-date status disappears after filter is removed From 94c53e4b047ec8cd199953632e47c5fa1093eb35 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 6 Nov 2016 21:35:04 -0500 Subject: [PATCH 100/917] be clearer --- todo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/todo.txt b/todo.txt index 9296aca40b..73500473ab 100755 --- a/todo.txt +++ b/todo.txt @@ -16,7 +16,7 @@ o replace appbundler with the Java 8 packager o appbundler is no longer being developed by Oracle, switch to "packager" X https://github.com/processing/processing/issues/3071 X major clean-ups to the Contribution Manager code -X Deal with a situation where the browser hangs on macOS +X warn user to restart browser when it hangs on macOS X https://github.com/fathominfo/processing-p5js-mode/issues/4 contribs From 370d4c75987ba69ae0a3c316977a619927fe0b19 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 7 Nov 2016 06:19:13 -0500 Subject: [PATCH 101/917] write release notes for 3.2.3 --- build/shared/revisions.txt | 56 ++++++++++++++++++++++++++++++++++++++ core/todo.txt | 4 +-- todo.txt | 4 ++- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index 789e21ab54..67cbbfee2a 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -1,3 +1,59 @@ +PROCESSING 3.2.3 (REV 0255) - 7 November 2016 + +Lots of fixes to the Contribution Manager and a couple OpenGL tweaks. + + +[ contributions manager ] + ++ If prettyVersion isn't present, just use version number + ++ Ensure that update.id is set before checking for contrib updates + ++ Clicking "Update" button in contrib manager shows non-retina version of icon + https://github.com/processing/processing/issues/4715 + Other instances of the double-size icon found, should be fixed now + ++ Fix the library reporting scripts on the server + ++ Missing version number putting 'null' in the UI + https://github.com/processing/processing-docs/issues/478 + https://github.com/processing/processing/issues/4696 + https://github.com/processing/processing/pull/4712 + ++ Major clean-ups to the Contribution Manager code + + +[ contributions to the manager ] + ++ Up-to-date status disappears after filter is removed (contributed) + https://github.com/processing/processing/issues/4084 + ++ Updates tab blank after adding, removing, updating a contribution + https://github.com/processing/processing/issues/4082 + https://github.com/processing/processing/issues/4704 + ++ Fixes the removal of redundant contribution and update related issues + https://github.com/processing/processing/pull/4086 + + +[ another fix ] + ++ Warn user to restart browser when it hangs on macOS + https://github.com/fathominfo/processing-p5js-mode/issues/4 + + +[ opengl improvements ] + ++ Automatic detection of POINT and LINE shaders fails + https://github.com/processing/processing/issues/4725 + ++ Show warning when frameRate() less than 1 is called with P2D and P3D + https://github.com/processing/processing/issues/4716 + + +. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + PROCESSING 3.2.2 (REV 0254) - 30 October 2016 Lots of bug fixes. diff --git a/core/todo.txt b/core/todo.txt index 9c6d385de7..17b1a01e7f 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,6 +1,4 @@ 0255 (3.2.3 or 3.3) -_ add StringDict.Entry class for iterating - andres X automatic detection of POINT and LINE shaders fails @@ -9,6 +7,8 @@ X show warning when frameRate() less than 1 is called with P2D and P3D X https://github.com/processing/processing/issues/4716 +_ add StringDict.Entry class for iterating + _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 diff --git a/todo.txt b/todo.txt index 73500473ab..bc32d1787f 100755 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,4 @@ -0255 (3.2.3 or 3.3) +0255 (3.2.3) X ensure that update.id is set before checking for contrib updates X if prettyVersion is blank (or null?), just use version (Firmata) X clicking "Update" button in contrib manager shows non-retina version of icon @@ -28,6 +28,8 @@ X https://github.com/processing/processing/issues/4704 X Fixes the removal of redundant contribution and update related issues X https://github.com/processing/processing/pull/4086 +0256 (3.2.4 or 3.3) + _ fix appbundler problems due to rollback _ https://github.com/processing/processing/issues/3790 From 2cf6bd79e001f0d3aebb7663d39de7cbda0789c0 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 7 Nov 2016 06:42:03 -0500 Subject: [PATCH 102/917] starting the next release --- app/src/processing/app/Base.java | 4 ++-- core/done.txt | 9 +++++++++ core/todo.txt | 8 +------- done.txt | 31 +++++++++++++++++++++++++++++++ todo.txt | 30 ------------------------------ 5 files changed, 43 insertions(+), 39 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index ce7550fa33..71490cb0e7 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -55,9 +55,9 @@ public class Base { // Added accessors for 0218 because the UpdateCheck class was not properly // updating the values, due to javac inlining the static final values. - static private final int REVISION = 255; + static private final int REVISION = 256; /** This might be replaced by main() if there's a lib/version.txt file. */ - static private String VERSION_NAME = "0255"; //$NON-NLS-1$ + static private String VERSION_NAME = "0256"; //$NON-NLS-1$ /** Set true if this a proper release rather than a numbered revision. */ /** True if heavy debugging error/log messages are enabled */ diff --git a/core/done.txt b/core/done.txt index 81e6759e34..d87755923c 100644 --- a/core/done.txt +++ b/core/done.txt @@ -1,3 +1,12 @@ +0255 (3.2.3) + +andres +X automatic detection of POINT and LINE shaders fails +X https://github.com/processing/processing/issues/4725 +X show warning when frameRate() less than 1 is called with P2D and P3D +X https://github.com/processing/processing/issues/4716 + + 0254 (3.2.2) X fix quoting problem in IntDict.toJSON() X add getRenderer() to SurfaceInfo diff --git a/core/todo.txt b/core/todo.txt index 17b1a01e7f..c6899284eb 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,10 +1,4 @@ -0255 (3.2.3 or 3.3) - -andres -X automatic detection of POINT and LINE shaders fails -X https://github.com/processing/processing/issues/4725 -X show warning when frameRate() less than 1 is called with P2D and P3D -X https://github.com/processing/processing/issues/4716 +0256 (3.2.4 or 3.3) _ add StringDict.Entry class for iterating diff --git a/done.txt b/done.txt index adf4ff3de5..1ac0c6a7eb 100644 --- a/done.txt +++ b/done.txt @@ -1,3 +1,34 @@ +0255 (3.2.3) +X ensure that update.id is set before checking for contrib updates +X if prettyVersion is blank (or null?), just use version (Firmata) +X clicking "Update" button in contrib manager shows non-retina version of icon +X https://github.com/processing/processing/issues/4715 +o problem is because AquaButtonUI is calling getImage() (not getIcon()) +o can be debugging from inside the getIconX() code in Toolkit +X just needed to use setPressedIcon(), setDisabledIcon() +X also found some other issues around the icon handling +X fix the library reporting scripts on the server +X missing version number putting 'null' in the ui +X https://github.com/processing/processing-docs/issues/478 +X https://github.com/processing/processing/issues/4696 +X https://github.com/processing/processing/pull/4712 +o replace appbundler with the Java 8 packager +o appbundler is no longer being developed by Oracle, switch to "packager" +X https://github.com/processing/processing/issues/3071 +X major clean-ups to the Contribution Manager code +X warn user to restart browser when it hangs on macOS +X https://github.com/fathominfo/processing-p5js-mode/issues/4 + +contribs +X Up-to-date status disappears after filter is removed +X https://github.com/processing/processing/issues/4084 +X Updates tab blank after adding, removing, updating a contribution +X https://github.com/processing/processing/issues/4082 +X https://github.com/processing/processing/issues/4704 +X Fixes the removal of redundant contribution and update related issues +X https://github.com/processing/processing/pull/4086 + + 0254 (3.2.2) X Find in reference for size() opens StringList.size() X https://github.com/processing/processing/issues/4224 diff --git a/todo.txt b/todo.txt index bc32d1787f..23cc9beed2 100755 --- a/todo.txt +++ b/todo.txt @@ -1,33 +1,3 @@ -0255 (3.2.3) -X ensure that update.id is set before checking for contrib updates -X if prettyVersion is blank (or null?), just use version (Firmata) -X clicking "Update" button in contrib manager shows non-retina version of icon -X https://github.com/processing/processing/issues/4715 -o problem is because AquaButtonUI is calling getImage() (not getIcon()) -o can be debugging from inside the getIconX() code in Toolkit -X just needed to use setPressedIcon(), setDisabledIcon() -X also found some other issues around the icon handling -X fix the library reporting scripts on the server -X missing version number putting 'null' in the ui -X https://github.com/processing/processing-docs/issues/478 -X https://github.com/processing/processing/issues/4696 -X https://github.com/processing/processing/pull/4712 -o replace appbundler with the Java 8 packager -o appbundler is no longer being developed by Oracle, switch to "packager" -X https://github.com/processing/processing/issues/3071 -X major clean-ups to the Contribution Manager code -X warn user to restart browser when it hangs on macOS -X https://github.com/fathominfo/processing-p5js-mode/issues/4 - -contribs -X Up-to-date status disappears after filter is removed -X https://github.com/processing/processing/issues/4084 -X Updates tab blank after adding, removing, updating a contribution -X https://github.com/processing/processing/issues/4082 -X https://github.com/processing/processing/issues/4704 -X Fixes the removal of redundant contribution and update related issues -X https://github.com/processing/processing/pull/4086 - 0256 (3.2.4 or 3.3) From a8cd65f1dd774147e5243d8787581b87065824bf Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 7 Nov 2016 18:13:38 -0500 Subject: [PATCH 103/917] only require reference when building dist --- build/build.xml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/build/build.xml b/build/build.xml index 82dec6cec8..7238516e44 100644 --- a/build/build.xml +++ b/build/build.xml @@ -305,7 +305,7 @@ - +
@@ -382,9 +382,15 @@ - + + + + + + Date: Mon, 7 Nov 2016 18:14:23 -0500 Subject: [PATCH 104/917] set text style properly for Contribution Manager error message --- .../processing/app/contrib/ContributionTab.java | 14 ++++++++------ app/src/processing/app/contrib/DetailPanel.java | 6 +++--- todo.txt | 2 ++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/app/src/processing/app/contrib/ContributionTab.java b/app/src/processing/app/contrib/ContributionTab.java index 86cbe5a0c8..9bd2dfd444 100644 --- a/app/src/processing/app/contrib/ContributionTab.java +++ b/app/src/processing/app/contrib/ContributionTab.java @@ -30,7 +30,6 @@ import javax.swing.*; import javax.swing.event.*; -import javax.swing.text.*; import processing.app.*; import processing.app.ui.Editor; @@ -200,21 +199,24 @@ protected void buildErrorPanel() { layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); errorPanel.setLayout(layout); -// errorPanel.setBorder(BorderFactory.createMatteBorder(2, 0, 0, 0, Color.BLACK)); errorMessage = new JTextPane(); errorMessage.setEditable(false); errorMessage.setContentType("text/html"); - errorMessage.setText("Could not connect to the Processing server.
" + errorMessage.setText("
Could not connect to the Processing server.
" + "Contributions cannot be installed or updated without an Internet connection.
" - + "Please verify your network connection again, then try connecting again."); - errorMessage.setFont(Toolkit.getSansFont(14, Font.PLAIN)); - errorMessage.setMaximumSize(new Dimension(550, 50)); + + "Please verify your network connection again, then try connecting again.
"); + DetailPanel.setTextStyle(errorMessage, "1em"); + Dimension dim = new Dimension(550, 60); + errorMessage.setMaximumSize(dim); + errorMessage.setMinimumSize(dim); errorMessage.setOpaque(false); + /* StyledDocument doc = errorMessage.getStyledDocument(); SimpleAttributeSet center = new SimpleAttributeSet(); StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER); doc.setParagraphAttributes(0, doc.getLength(), center, false); + */ closeButton = Toolkit.createIconButton("manager/close"); closeButton.setContentAreaFilled(false); diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index 33de5b2885..f62f953cdf 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -167,7 +167,7 @@ private void addPaneComponents() { margin.bottom = 0; descriptionPane.setMargin(margin); descriptionPane.setContentType("text/html"); - setTextStyle(descriptionPane); + setTextStyle(descriptionPane, "0.95em"); descriptionPane.setOpaque(false); if (UIManager.getLookAndFeel().getID().equals("Nimbus")) { descriptionPane.setBackground(new Color(0, 0, 0, 0)); @@ -714,7 +714,7 @@ static void setForegroundStyle(JTextPane textPane, } - static void setTextStyle(JTextPane textPane) { + static void setTextStyle(JTextPane textPane, String fontSize) { Document doc = textPane.getDocument(); if (doc instanceof HTMLDocument) { HTMLDocument html = (HTMLDocument) doc; @@ -722,7 +722,7 @@ static void setTextStyle(JTextPane textPane) { stylesheet.addRule("body { " + " margin: 0; padding: 0;" + " font-family: " + Toolkit.getSansFontName() + ", Arial, Helvetica, sans-serif;" + - " font-size: 100%;" + "font-size: 0.95em; " + + " font-size: 100%;" + "font-size: " + fontSize + "; " + "}"); } } diff --git a/todo.txt b/todo.txt index 23cc9beed2..3511896e3a 100755 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,6 @@ 0256 (3.2.4 or 3.3) +X only require reference.zip (and internet connection) when building dist +X set text style properly for Contribution Manager error message _ fix appbundler problems due to rollback From 46f0869c463aacfb043372bf12566949c3222de8 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 7 Nov 2016 19:03:23 -0500 Subject: [PATCH 105/917] more bug notes --- todo.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/todo.txt b/todo.txt index 3511896e3a..8a78950a4b 100755 --- a/todo.txt +++ b/todo.txt @@ -12,6 +12,10 @@ _ https://github.com/processing/processing/commits/master/build/macosx/appbund _ https://github.com/processing/processing/commit/fa27b983e76fdbc5c4c1451a1f0d854c652b1639 _ https://bitbucket.org/infinitekind/appbundler +_ Drew's freeze on startup +_ No PDE window opens when started on MacOS X 10.11 +_ https://github.com/processing/processing/issues/4735 + _ settings() present and pixelDensity() is in setup(), nothing set/no error _ https://github.com/processing/processing/issues/4703 @@ -674,6 +678,8 @@ _ e.g. ocd is broken in 0125 because of method signature changes PDE / Manager +_ Progress bar height on macOS is too thin +_ https://github.com/processing/processing/issues/4734 _ proper error handling when downloading contribs listing _ https://github.com/processing/processing/issues/4732 _ update CM entries when sketchbook location changes From 4e7337d3263d8865a6c88b371da09ba8cf126e5f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 8 Nov 2016 10:51:34 -0500 Subject: [PATCH 106/917] more debug messages, trying to sort out startup hang --- app/src/processing/app/Base.java | 42 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 71490cb0e7..a0497b17a3 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -61,8 +61,8 @@ public class Base { /** Set true if this a proper release rather than a numbered revision. */ /** True if heavy debugging error/log messages are enabled */ - static public boolean DEBUG = false; -// static public boolean DEBUG = true; +// static public boolean DEBUG = false; + static public boolean DEBUG = true; static private boolean commandLine; @@ -185,7 +185,6 @@ static private void createAndShowGUI(String[] args) { // Get the sketchbook path, and make sure it's set properly locateSketchbookFolder(); - // Create a location for untitled sketches try { untitledFolder = Util.createTempFolder("untitled", "sketches", null); @@ -196,9 +195,11 @@ static private void createAndShowGUI(String[] args) { "That's gonna prevent us from continuing.", e); } - Messages.log("about to create base..."); //$NON-NLS-1$ + Messages.log("About to create Base..."); //$NON-NLS-1$ try { final Base base = new Base(args); + Messages.log("Base() constructor succeeded"); + // Prevent more than one copy of the PDE from running. SingleInstance.startServer(base); @@ -206,18 +207,18 @@ static private void createAndShowGUI(String[] args) { // shows up on top, and doesn't prevent an editor window from opening. if (Preferences.getBoolean("welcome.show")) { final boolean prompt = sketchbookPrompt; - EventQueue.invokeLater(new Runnable() { - public void run() { - try { - new Welcome(base, prompt); - } catch (IOException e) { - Messages.showTrace("Unwelcoming", - "Please report this error to\n" + - "https://github.com/processing/processing/issues", e, false); - } - } - }); +// EventQueue.invokeLater(new Runnable() { +// public void run() { + try { + new Welcome(base, prompt); + } catch (IOException e) { + Messages.showTrace("Unwelcoming", + "Please report this error to\n" + + "https://github.com/processing/processing/issues", e, false); + } } +// }); +// } } catch (Throwable t) { // Catch-all to pick up badness during startup. @@ -229,7 +230,7 @@ public void run() { Messages.showTrace("We're off on the wrong foot", "An error occurred during startup.", t, true); } - Messages.log("done creating base..."); //$NON-NLS-1$ + Messages.log("Done creating Base..."); //$NON-NLS-1$ } } @@ -314,6 +315,8 @@ public Base(String[] args) throws Exception { // Check if any files were passed in on the command line for (int i = 0; i < args.length; i++) { + Messages.logf("Parsing command line... args[%d] = '%s'", i, args[i]); + String path = args[i]; // Fix a problem with systems that use a non-ASCII languages. Paths are // being passed in with 8.3 syntax, which makes the sketch loader code @@ -323,6 +326,7 @@ public Base(String[] args) throws Exception { try { File file = new File(args[i]); path = file.getCanonicalPath(); + Messages.logf("Changing %s to canonical %s", i, args[i], path); } catch (IOException e) { e.printStackTrace(); } @@ -334,10 +338,10 @@ public Base(String[] args) throws Exception { // Create a new empty window (will be replaced with any files to be opened) if (!opened) { -// System.out.println("opening a new window"); + Messages.log("Calling handleNew() to open a new window"); handleNew(); -// } else { -// System.out.println("something else was opened"); + } else { + Messages.log("No handleNew(), something passed on the command line"); } // check for updates From b37a6bca1a141f54b8605f01b70d8dc443e82886 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 8 Nov 2016 13:49:54 -0500 Subject: [PATCH 107/917] more error handling and logging to sort out #4735 --- java/src/processing/mode/java/runner/Runner.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index be8845a478..871020e728 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -33,6 +33,7 @@ import java.awt.GraphicsEnvironment; import java.awt.Point; import java.io.*; +import java.net.ConnectException; import java.util.*; import com.sun.jdi.*; @@ -220,21 +221,29 @@ public boolean launchVirtualMachine(boolean present, String[] args) { // while (!available) { while (true) { try { + Messages.log(getClass().getName() + " attempting to attach to VM"); vm = connector.attach(arguments); // vm = connector.attach(arguments); if (vm != null) { + Messages.log(getClass().getName() + " attached to the VM"); // generateTrace(); // available = true; return true; } - } catch (IOException e) { + } catch (ConnectException ce) { + // This will fire ConnectException (socket not available) until + // the VM finishes starting up and opens its socket for us. + Messages.log(getClass().getName() + " socket for VM not ready"); // System.out.println("waiting"); // e.printStackTrace(); try { Thread.sleep(100); - } catch (InterruptedException e1) { - e1.printStackTrace(sketchErr); + } catch (InterruptedException ie) { + Messages.loge(getClass().getName() + " interrupted", ie); +// ie.printStackTrace(sketchErr); } + } catch (IOException e) { + Messages.loge(getClass().getName() + " while attaching to VM", e); } } // } catch (IOException exc) { From fe01b57798fc837eb7a0a1ff36f543debd8bb97c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 8 Nov 2016 13:51:14 -0500 Subject: [PATCH 108/917] don't punish everyone for this debugging work --- app/src/processing/app/Base.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index a0497b17a3..6186af3a26 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -61,8 +61,8 @@ public class Base { /** Set true if this a proper release rather than a numbered revision. */ /** True if heavy debugging error/log messages are enabled */ -// static public boolean DEBUG = false; - static public boolean DEBUG = true; + static public boolean DEBUG = false; +// static public boolean DEBUG = true; static private boolean commandLine; From c9a995e528ec430c99a4104b6ad0d6a1b5540f09 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 8 Nov 2016 13:52:32 -0500 Subject: [PATCH 109/917] pondering a better solution for DEBUG --- todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/todo.txt b/todo.txt index 8a78950a4b..9e46c0fb55 100755 --- a/todo.txt +++ b/todo.txt @@ -3,6 +3,9 @@ X only require reference.zip (and internet connection) when building dist X set text style properly for Contribution Manager error message +_ move the DEBUG flag into an external file or preferences.txt +_ will help us with debugging w/ others as well + _ fix appbundler problems due to rollback _ https://github.com/processing/processing/issues/3790 _ the rollback re-introduces two bugs (serial export and scrolling) From 54bfcda09d782c82269ee88becc03aefb2769da1 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 8 Nov 2016 14:00:15 -0500 Subject: [PATCH 110/917] notes about additional bugs --- core/todo.txt | 5 +++++ todo.txt | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index c6899284eb..b19f909c63 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -60,7 +60,12 @@ _ https://github.com/processing/processing/issues/3753 javafx +_ mouseWheel() not working with FX2D +_ https://github.com/processing/processing/issues/4169 +_ wrong window size with fullScreen() +_ https://github.com/processing/processing/issues/4737 _ menu bar not hiding properly in exported applications with FX2D +_ https://github.com/processing/processing/issues/4527 _ hideMenuBar() called from setup() works fine _ just call it around setup time? _ the --hide-stop option not working (FX only? traces?) diff --git a/todo.txt b/todo.txt index 9e46c0fb55..7a770241c9 100755 --- a/todo.txt +++ b/todo.txt @@ -3,6 +3,11 @@ X only require reference.zip (and internet connection) when building dist X set text style properly for Contribution Manager error message +_ 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 + _ move the DEBUG flag into an external file or preferences.txt _ will help us with debugging w/ others as well From c6c433ff57c7e60faf5f477591a49691ec70ed6c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 9 Nov 2016 11:07:23 -0500 Subject: [PATCH 111/917] oh, permissions... i blame windows --- java/src/processing/mode/java/JavaBuild.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 java/src/processing/mode/java/JavaBuild.java diff --git a/java/src/processing/mode/java/JavaBuild.java b/java/src/processing/mode/java/JavaBuild.java old mode 100755 new mode 100644 From da0efeb07db94ddfaacacb1a483d89730ec80af3 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 9 Nov 2016 11:52:48 -0500 Subject: [PATCH 112/917] detect changes to /etc/hosts and warn user (#4738) --- .../processing/mode/java/runner/Runner.java | 27 +++++++++++++++++++ todo.txt | 10 ++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index 871020e728..9d1dad83d4 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -34,6 +34,8 @@ import java.awt.Point; import java.io.*; import java.net.ConnectException; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.*; import com.sun.jdi.*; @@ -82,6 +84,8 @@ public Runner(JavaBuild build, RunnerListener listener) throws SketchException { // this.sketch = sketch; this.build = build; + checkLocalHost(); + if (listener instanceof Editor) { this.editor = (Editor) listener; sketchErr = editor.getConsole().getErr(); @@ -116,6 +120,29 @@ public Runner(JavaBuild build, RunnerListener listener) throws SketchException { } + /** + * Has the user screwed up their hosts file? + * https://github.com/processing/processing/issues/4738 + */ + private void checkLocalHost() throws SketchException { + try { + InetAddress address = InetAddress.getByName("localhost"); + if (!address.getHostAddress().equals("127.0.0.1")) { + System.err.println("Your computer is not properly mapping 'localhost' to '127.0.0.1',"); + System.err.println("which prevents sketches from working properly because 'localhost'"); + System.err.println("is needed to connect the PDE to your sketch while it's running."); + System.err.println("If you don't recall making this change, or know how to fix it:"); + System.err.println("https://www.google.com/search?q=add+localhost+to+hosts+file+" + Platform.getName()); + throw new SketchException("Cannot run due to changes in your 'hosts' file. " + + "See the console for details.", false); + } + + } catch (UnknownHostException e) { + e.printStackTrace(); + } + } + + public VirtualMachine launch(String[] args) { if (launchVirtualMachine(false, args)) { generateTrace(); diff --git a/todo.txt b/todo.txt index 7a770241c9..931fde4407 100755 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,12 @@ 0256 (3.2.4 or 3.3) X only require reference.zip (and internet connection) when building dist X set text style properly for Contribution Manager error message +X Detect changes to 'hosts' file in case users modify/remove localhost +_ No sketch window opens after hitting Run if hosts file changed +_ https://github.com/processing/processing/issues/4738 +_ https://github.com/processing/processing/issues/4735 +X https://github.com/processing/processing/issues/1868 +X https://github.com/processing/processing/issues/3123 _ Export Application fails on machines w/ non-ASCII chars in user name @@ -20,10 +26,6 @@ _ https://github.com/processing/processing/commits/master/build/macosx/appbund _ https://github.com/processing/processing/commit/fa27b983e76fdbc5c4c1451a1f0d854c652b1639 _ https://bitbucket.org/infinitekind/appbundler -_ Drew's freeze on startup -_ No PDE window opens when started on MacOS X 10.11 -_ https://github.com/processing/processing/issues/4735 - _ settings() present and pixelDensity() is in setup(), nothing set/no error _ https://github.com/processing/processing/issues/4703 From 2e19cc56723749fbde55b4a5cb2ec86d3bb03ec4 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 9 Nov 2016 11:57:19 -0500 Subject: [PATCH 113/917] notes about hosts --- todo.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/todo.txt b/todo.txt index 931fde4407..5114684789 100755 --- a/todo.txt +++ b/todo.txt @@ -2,11 +2,11 @@ X only require reference.zip (and internet connection) when building dist X set text style properly for Contribution Manager error message X Detect changes to 'hosts' file in case users modify/remove localhost -_ No sketch window opens after hitting Run if hosts file changed -_ https://github.com/processing/processing/issues/4738 -_ https://github.com/processing/processing/issues/4735 +X https://github.com/processing/processing/issues/4738 +X No sketch window opens after hitting Run if hosts file changed X https://github.com/processing/processing/issues/1868 X https://github.com/processing/processing/issues/3123 +X https://github.com/processing/processing/issues/4735 _ Export Application fails on machines w/ non-ASCII chars in user name From ab86906f78cab0bc5983281f5a74b7c04de7b535 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 9 Nov 2016 17:23:50 -0500 Subject: [PATCH 114/917] set DEBUG flag using external file --- app/src/processing/app/Base.java | 16 ++++++++++++---- app/src/processing/app/Messages.java | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 6186af3a26..433d10d010 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -44,6 +44,7 @@ import processing.app.ui.*; import processing.core.*; import processing.data.StringList; +import sun.security.x509.IssuingDistributionPointExtension; /** @@ -60,9 +61,12 @@ public class Base { static private String VERSION_NAME = "0256"; //$NON-NLS-1$ /** Set true if this a proper release rather than a numbered revision. */ - /** True if heavy debugging error/log messages are enabled */ - static public boolean DEBUG = false; -// static public boolean DEBUG = true; + /** + * True if heavy debugging error/log messages are enabled. Set to true + * if an empty file named 'debug' is found in the settings folder. + * See implementation in createAndShowGUI(). + */ + static public boolean DEBUG; static private boolean commandLine; @@ -129,7 +133,6 @@ static private void createAndShowGUI(String[] args) { String version = PApplet.loadStrings(versionFile)[0]; if (!version.equals(VERSION_NAME)) { VERSION_NAME = version; -// RELEASE = true; } } } catch (Exception e) { @@ -138,6 +141,11 @@ static private void createAndShowGUI(String[] args) { Platform.init(); + // Set the debug flag based on a file being present in the settings folder + File debugFile = getSettingsFile("debug"); + // if it's a directory, it's a leftover from older releases + DEBUG = debugFile.exists() && !debugFile.isDirectory(); + // Use native popups so they don't look so crappy on OS X JPopupMenu.setDefaultLightWeightPopupEnabled(false); diff --git a/app/src/processing/app/Messages.java b/app/src/processing/app/Messages.java index 07e1a62472..72f757d67d 100644 --- a/app/src/processing/app/Messages.java +++ b/app/src/processing/app/Messages.java @@ -335,7 +335,7 @@ static public void loge(String message, Throwable e) { static public void loge(String message) { if (Base.DEBUG) { - System.out.println(message); + System.err.println(message); } } } \ No newline at end of file From 49b08465b900dbefeaed0a53a9d99026ef0e1839 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 9 Nov 2016 17:24:01 -0500 Subject: [PATCH 115/917] remove the Java logger in favor of built-in logging --- java/src/processing/mode/java/Debugger.java | 178 ++++++++++---------- 1 file changed, 91 insertions(+), 87 deletions(-) diff --git a/java/src/processing/mode/java/Debugger.java b/java/src/processing/mode/java/Debugger.java index 496cbb96ca..131fe5faa0 100644 --- a/java/src/processing/mode/java/Debugger.java +++ b/java/src/processing/mode/java/Debugger.java @@ -2,7 +2,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2012-15 The Processing Foundation + Copyright (c) 2012-16 The Processing Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 @@ -33,12 +33,11 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.JTree; // needed for javadocs import javax.swing.tree.DefaultMutableTreeNode; +import processing.app.Messages; import processing.app.Sketch; import processing.app.SketchCode; import processing.mode.java.debug.*; @@ -195,28 +194,28 @@ public synchronized void startDebug() { Sketch sketch = editor.getSketch(); JavaBuild build = new JavaBuild(sketch); - log(Level.INFO, "building sketch: {0}", sketch.getName()); + log("building sketch: " + sketch.getName()); //LineMapping.addLineNumbers(sketch); // annotate // mainClassName = build.build(false); mainClassName = build.build(true); //LineMapping.removeLineNumbers(sketch); // annotate - log(Level.INFO, "class: {0}", mainClassName); + log("class: " + mainClassName); // folder with assembled/preprocessed src srcPath = build.getSrcFolder().getPath(); - log(Level.INFO, "build src: {0}", srcPath); + log("build src: " + srcPath); // folder with compiled code (.class files) - log(Level.INFO, "build bin: {0}", build.getBinFolder().getPath()); + log("build bin: " + build.getBinFolder().getPath()); if (mainClassName != null) { // generate the source line mapping //lineMap = LineMapping.generateMapping(srcPath + File.separator + mainClassName + ".java"); - log(Level.INFO, "launching debuggee runtime"); + log("launching debuggee runtime"); runtime = new Runner(build, editor); VirtualMachine vm = runtime.debug(null); // non-blocking if (vm == null) { - log(Level.SEVERE, "error 37: launch failed"); + loge("error 37: launch failed", null); } // start receiving vm events @@ -239,7 +238,7 @@ public synchronized void startDebug() { public synchronized void stopDebug() { editor.variableInspector().lock(); if (runtime != null) { - log(Level.INFO, "closing runtime"); + Messages.log("closing runtime"); runtime.close(); runtime = null; //build = null; @@ -383,7 +382,7 @@ synchronized void setBreakpoint(LineID line) { return; } breakpoints.add(new LineBreakpoint(line, this)); - log(Level.INFO, "set breakpoint on line {0}", line); + log("set breakpoint on line " + line); } @@ -411,16 +410,16 @@ void removeBreakpoint(int lineIdx) { if (bp != null) { bp.remove(); breakpoints.remove(bp); - log(Level.INFO, "removed breakpoint {0}", bp); + log("removed breakpoint " + bp); } } /** Remove all breakpoints. */ synchronized void clearBreakpoints() { - //TODO: handle busy-ness correctly + // TODO: handle busy-ness correctly if (isBusy()) { - log(Level.WARNING, "busy"); + log("busy"); return; } @@ -436,9 +435,9 @@ synchronized void clearBreakpoints() { * @param tabFilename the tab's file name */ synchronized void clearBreakpoints(String tabFilename) { - //TODO: handle busy-ness correctly + // TODO: handle busy-ness correctly if (isBusy()) { - log(Level.WARNING, "busy"); + log("busy"); return; } @@ -535,7 +534,7 @@ synchronized List getBreakpoints(String tabFilename) { */ public synchronized void vmEvent(EventSet es) { for (Event e : es) { - log(Level.INFO, "*** VM Event: {0}", e.toString()); + log("*** VM Event: " + e); if (e instanceof VMStartEvent) { vmStartEvent(); @@ -561,7 +560,7 @@ public synchronized void vmEvent(EventSet es) { private void vmStartEvent() { // break on main class load - log(Level.INFO, "requesting event on main class load: {0}", mainClassName); + log("requesting event on main class load: " + mainClassName); ClassPrepareRequest mainClassPrepare = runtime.vm().eventRequestManager().createClassPrepareRequest(); mainClassPrepare.addClassFilter(mainClassName); mainClassPrepare.enable(); @@ -569,7 +568,7 @@ private void vmStartEvent() { // break on loading custom classes for (SketchCode tab : editor.getSketch().getCode()) { if (tab.isExtension("java")) { - log(Level.INFO, "requesting event on class load: {0}", tab.getPrettyName()); + log("requesting event on class load: " + tab.getPrettyName()); ClassPrepareRequest customClassPrepare = runtime.vm().eventRequestManager().createClassPrepareRequest(); customClassPrepare.addClassFilter(tab.getPrettyName()); customClassPrepare.enable(); @@ -587,11 +586,11 @@ private void vmClassPrepareEvent(ClassPrepareEvent ce) { if (rt.name().equals(mainClassName)) { //printType(rt); mainClass = rt; - log(Level.INFO, "main class load: {0}", rt.name()); + log("main class load: " + rt.name()); started = true; // now that main class is loaded, we're started } else { classes.add(rt); // save loaded classes - log(Level.INFO, "class load: {0}", rt.name()); + log("class load: {0}" + rt.name()); } // notify listeners @@ -694,7 +693,7 @@ protected void stepOutIntoViewOrContinue() { continueDebug(); } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); } } @@ -748,7 +747,7 @@ protected void printStackTrace(ThreadReference t) { System.out.println(i++ + ": " + f.toString()); } } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); } } @@ -857,9 +856,9 @@ protected void printLocalVariables(ThreadReference t) { } } } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); } catch (AbsentInformationException ex) { - System.out.println("local variable information not available"); + log("local variable information not available"); } } @@ -876,7 +875,7 @@ protected void updateVariableInspector(ThreadReference t) { try { if (t.frameCount() == 0) { // TODO: needs to be handled in a better way: - log(Level.WARNING, "call stack empty"); + log("call stack empty"); } else { final VariableInspector vi = editor.variableInspector(); // first get data @@ -901,7 +900,7 @@ public void run() { }); } } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); } } @@ -920,7 +919,7 @@ protected String thisName(ThreadReference t) { return ref == null ? "" : ref.referenceType().name(); } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); return ""; } } @@ -940,7 +939,7 @@ protected String currentLocation(ThreadReference t) { return locationToString(t.frame(0).location()); } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); return ""; } } @@ -984,9 +983,9 @@ protected List getLocals(ThreadReference t, int depth) { } } } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); } catch (AbsentInformationException ex) { - log(Level.WARNING, "local variable information not available", ex); + loge("local variable information not available", ex); } return vars; } @@ -1009,7 +1008,7 @@ protected List getThisFields(ThreadReference t, int depth, return getFields(thisObj, depth, includeInherited); } } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); } return new ArrayList<>(); } @@ -1098,7 +1097,7 @@ protected List getStackTrace(ThreadReference t) { stack.add(new DefaultMutableTreeNode(locationToString(f.location()))); } } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); } return stack; } @@ -1131,7 +1130,7 @@ protected void printThis(ThreadReference t) { } } } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); } } @@ -1150,7 +1149,7 @@ protected void printSourceLocation(ThreadReference t) { printSourceLocation(l); } } catch (IncompatibleThreadStateException ex) { - log(Level.SEVERE, null, ex); + logitse(ex); } } @@ -1166,7 +1165,7 @@ protected void printSourceLocation(Location l) { System.out.println(getSourceLine(l.sourcePath(), l.lineNumber(), 2)); } catch (AbsentInformationException ex) { - log(Level.SEVERE, null, ex); + log("absent information", ex); } } @@ -1180,7 +1179,7 @@ protected void printSourceLocation(Location l) { */ protected String getSourceLine(String filePath, int lineNo, int radius) { if (lineNo == -1) { - log(Level.SEVERE, "invalid line number: {0}", lineNo); + loge("invalid line number: " + lineNo, null); return ""; } //System.out.println("getting line: " + lineNo); @@ -1211,7 +1210,7 @@ protected String getSourceLine(String filePath, int lineNo, int radius) { return f.getName() + ":" + lineNo; } catch (IOException ex) { - log(Level.SEVERE, null, ex); + loge("other io exception", ex); return ""; } } @@ -1248,7 +1247,7 @@ protected LineID locationToLineID(Location l) { return javaToSketchLine(new LineID(l.sourceName(), l.lineNumber() - 1)); } catch (AbsentInformationException ex) { - log(Level.SEVERE, null, ex); + loge("absent information", ex); return null; } } @@ -1384,30 +1383,39 @@ protected void stopTrackingLineChanges() { } - static private void log(Level level, String msg) { - Logger.getLogger(Debugger.class.getName()).log(level, msg); + private void log(String msg, Object... args) { + if (args != null && args.length != 0) { + Messages.logf(getClass().getName() + " " + msg, args); + } else { + Messages.log(getClass().getName() + " " + msg); + } } - static private void log(Level level, String msg, Object obj) { - Logger.getLogger(Debugger.class.getName()).log(level, msg, obj); + private void loge(String msg, Throwable t) { + if (t != null) { + Messages.loge(getClass().getName() + " " + msg, t); + } else { + Messages.loge(getClass().getName() + " " + msg); + } + } + + + private void logitse(Throwable t) { + Messages.loge("incompatible thread state?", t); } /** * Interface for VM callbacks. - * - * @author Martin Leopold */ protected interface VMEventListener { - - /** - * Receive an event from the VM. Events are sent in batches. See - * documentation of EventSet for more information. - * - * @param es Set of events - */ - void vmEvent(EventSet es); + /** + * Receive an event from the VM. Events are sent in batches. See + * documentation of EventSet for more information. + * @param es Set of events + */ + void vmEvent(EventSet es); } @@ -1418,40 +1426,36 @@ protected interface VMEventListener { * @author Martin Leopold */ protected static class VMEventReader extends Thread { - - EventQueue eventQueue; - VMEventListener listener; - - /** - * Construct a VMEventReader. Needs to be kicked off with start() once - * constructed. - * - * @param eventQueue The queue to read events from. Can be obtained from a - * VirtualMachine via eventQueue(). - * @param listener the listener to forward events to. - */ - public VMEventReader(EventQueue eventQueue, VMEventListener listener) { - super("VM Event Thread"); - this.eventQueue = eventQueue; - this.listener = listener; - } - - @Override - public void run() { - try { - while (true) { - EventSet eventSet = eventQueue.remove(); - listener.vmEvent(eventSet); - /* - * for (Event e : eventSet) { System.out.println("VM Event: " + - * e.toString()); } - */ - } - } catch (VMDisconnectedException e) { - Logger.getLogger(VMEventReader.class.getName()).log(Level.INFO, "VMEventReader quit on VM disconnect"); - } catch (Exception e) { - Logger.getLogger(VMEventReader.class.getName()).log(Level.SEVERE, "VMEventReader quit", e); - } + EventQueue eventQueue; + VMEventListener listener; + + /** + * Construct a VMEventReader. Needs to be kicked off with start() once + * constructed. + * + * @param eventQueue The queue to read events from. Can be obtained from a + * VirtualMachine via eventQueue(). + * @param listener the listener to forward events to. + */ + public VMEventReader(EventQueue eventQueue, VMEventListener listener) { + super("VM Event Thread"); + this.eventQueue = eventQueue; + this.listener = listener; + } + + @Override + public void run() { + try { + while (true) { + EventSet eventSet = eventQueue.remove(); + listener.vmEvent(eventSet); + // for (Event e : eventSet) { System.out.println("VM Event: " + e.toString()); } + } + } catch (VMDisconnectedException e) { + Messages.log("VMEventReader quit on VM disconnect"); + } catch (Exception e) { + Messages.loge("VMEventReader quit", e); } + } } } From 3e6a158266edfa082793c87c9fd3edf0ff07f323 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 9 Nov 2016 20:47:14 -0500 Subject: [PATCH 116/917] oh, Eclipse... --- app/src/processing/app/Base.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 433d10d010..4bb8668def 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -44,7 +44,6 @@ import processing.app.ui.*; import processing.core.*; import processing.data.StringList; -import sun.security.x509.IssuingDistributionPointExtension; /** From 212ae6a2ee90b74d300662c8a2214b40b7636d7d Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 9 Nov 2016 21:13:06 -0500 Subject: [PATCH 117/917] fix copyrights, remove authors per guidelines, replace logging --- app/src/processing/app/Messages.java | 4 +- .../mode/java/debug/ArrayFieldNode.java | 84 ++- .../mode/java/debug/ClassLoadListener.java | 38 +- .../processing/mode/java/debug/FieldNode.java | 71 +- .../mode/java/debug/LineBreakpoint.java | 386 +++++------ .../mode/java/debug/LineHighlight.java | 212 +++--- .../processing/mode/java/debug/LineID.java | 456 +++++++------ .../mode/java/debug/LocalVariableNode.java | 82 ++- .../mode/java/debug/VariableNode.java | 616 +++++++++--------- 9 files changed, 979 insertions(+), 970 deletions(-) diff --git a/app/src/processing/app/Messages.java b/app/src/processing/app/Messages.java index 72f757d67d..8f6eaae3ef 100644 --- a/app/src/processing/app/Messages.java +++ b/app/src/processing/app/Messages.java @@ -327,7 +327,9 @@ static public void logf(String message, Object... args) { static public void loge(String message, Throwable e) { if (Base.DEBUG) { - System.err.println(message); + if (message != null) { + System.err.println(message); + } e.printStackTrace(); } } diff --git a/java/src/processing/mode/java/debug/ArrayFieldNode.java b/java/src/processing/mode/java/debug/ArrayFieldNode.java index ec5423729a..ac7d6a08da 100644 --- a/java/src/processing/mode/java/debug/ArrayFieldNode.java +++ b/java/src/processing/mode/java/debug/ArrayFieldNode.java @@ -1,21 +1,22 @@ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* -Part of the Processing project - http://processing.org -Copyright (c) 2012-15 The Processing Foundation + Part of the Processing project - http://processing.org -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. + Copyright (c) 2012-16 The Processing Foundation -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2, as published by the Free Software Foundation. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, Inc. -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package processing.mode.java.debug; @@ -24,45 +25,38 @@ import com.sun.jdi.ClassNotLoadedException; import com.sun.jdi.InvalidTypeException; import com.sun.jdi.Value; -import java.util.logging.Level; -import java.util.logging.Logger; + +import processing.app.Messages; /** * Specialized {@link VariableNode} for representing single fields in an array. * Overrides {@link #setValue} to properly change the value of the encapsulated * array field. - * - * @author Martin Leopold */ public class ArrayFieldNode extends VariableNode { - - protected ArrayReference array; - protected int index; - - /** - * Construct an {@link ArrayFieldNode}. - * - * @param name the name - * @param type the type - * @param value the value - * @param array a reference to the array - * @param index the index inside the array - */ - public ArrayFieldNode(String name, String type, Value value, ArrayReference array, int index) { - super(name, type, value); - this.array = array; - this.index = index; - } - - @Override - public void setValue(Value value) { - try { - array.setValue(index, value); - } catch (InvalidTypeException ex) { - Logger.getLogger(ArrayFieldNode.class.getName()).log(Level.SEVERE, null, ex); - } catch (ClassNotLoadedException ex) { - Logger.getLogger(ArrayFieldNode.class.getName()).log(Level.SEVERE, null, ex); - } - this.value = value; + protected ArrayReference array; + protected int index; + + + /** + * Construct an {@link ArrayFieldNode}. + */ + public ArrayFieldNode(String name, String type, Value value, ArrayReference array, int index) { + super(name, type, value); + this.array = array; + this.index = index; + } + + + @Override + public void setValue(Value value) { + try { + array.setValue(index, value); + } catch (InvalidTypeException ex) { + Messages.loge(null, ex); + } catch (ClassNotLoadedException ex) { + Messages.loge(null, ex); } + this.value = value; + } } diff --git a/java/src/processing/mode/java/debug/ClassLoadListener.java b/java/src/processing/mode/java/debug/ClassLoadListener.java index bee6ffa471..1dd4a288d5 100644 --- a/java/src/processing/mode/java/debug/ClassLoadListener.java +++ b/java/src/processing/mode/java/debug/ClassLoadListener.java @@ -1,40 +1,38 @@ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* -Part of the Processing project - http://processing.org -Copyright (c) 2012-15 The Processing Foundation + Part of the Processing project - http://processing.org -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. + Copyright (c) 2012-16 The Processing Foundation -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2, as published by the Free Software Foundation. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, Inc. -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package processing.mode.java.debug; import com.sun.jdi.ReferenceType; + /** * Listener to be notified when a class is loaded in the debugger. Used by * {@link LineBreakpoint}s to activate themselves as soon as the respective * class is loaded. - * - * @author Martin Leopold */ public interface ClassLoadListener { - /** - * Event handler called when a class is loaded. - * - * @param theClass the class - */ - public void classLoaded(ReferenceType theClass); + /** + * Event handler called when a class is loaded. + */ + public void classLoaded(ReferenceType theClass); } diff --git a/java/src/processing/mode/java/debug/FieldNode.java b/java/src/processing/mode/java/debug/FieldNode.java index 76b4bc2ad1..cae4d7178b 100644 --- a/java/src/processing/mode/java/debug/FieldNode.java +++ b/java/src/processing/mode/java/debug/FieldNode.java @@ -2,11 +2,12 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2012-15 The Processing Foundation - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. + Copyright (c) 2012-16 The Processing Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,8 +15,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package processing.mode.java.debug; @@ -25,46 +26,40 @@ import com.sun.jdi.InvalidTypeException; import com.sun.jdi.ObjectReference; import com.sun.jdi.Value; -import java.util.logging.Level; -import java.util.logging.Logger; + +import processing.app.Messages; /** * Specialized {@link VariableNode} for representing fields. Overrides * {@link #setValue} to properly change the value of the encapsulated field. - * - * @author Martin Leopold */ public class FieldNode extends VariableNode { - protected Field field; - protected ObjectReference obj; + protected Field field; + protected ObjectReference obj; + + + /** + * Construct a {@link FieldNode}. + * @param obj a reference to the object containing the field + */ + public FieldNode(String name, String type, Value value, Field field, + ObjectReference obj) { + super(name, type, value); + this.field = field; + this.obj = obj; + } - - /** - * Construct a {@link FieldNode}. - * - * @param name the name - * @param type the type - * @param value the value - * @param field the field - * @param obj a reference to the object containing the field - */ - public FieldNode(String name, String type, Value value, Field field, ObjectReference obj) { - super(name, type, value); - this.field = field; - this.obj = obj; - } - - @Override - public void setValue(Value value) { - try { - obj.setValue(field, value); - } catch (InvalidTypeException ex) { - Logger.getLogger(FieldNode.class.getName()).log(Level.SEVERE, null, ex); - } catch (ClassNotLoadedException ex) { - Logger.getLogger(FieldNode.class.getName()).log(Level.SEVERE, null, ex); - } - this.value = value; + @Override + public void setValue(Value value) { + try { + obj.setValue(field, value); + } catch (InvalidTypeException ite) { + Messages.loge(null, ite); + } catch (ClassNotLoadedException cnle) { + Messages.loge(null, cnle); } + this.value = value; + } } diff --git a/java/src/processing/mode/java/debug/LineBreakpoint.java b/java/src/processing/mode/java/debug/LineBreakpoint.java index 5272270e5e..584b780a3a 100644 --- a/java/src/processing/mode/java/debug/LineBreakpoint.java +++ b/java/src/processing/mode/java/debug/LineBreakpoint.java @@ -1,28 +1,27 @@ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* -Part of the Processing project - http://processing.org -Copyright (c) 2012-15 The Processing Foundation + Part of the Processing project - http://processing.org -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. + Copyright (c) 2012-16 The Processing Foundation -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2, as published by the Free Software Foundation. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, Inc. -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package processing.mode.java.debug; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; import processing.app.Messages; import processing.mode.java.Debugger; @@ -32,201 +31,210 @@ import com.sun.jdi.ReferenceType; import com.sun.jdi.request.BreakpointRequest; + /** * Model/Controller of a line breakpoint. Can be set before or while debugging. * Adds a highlight using the debuggers view ({@link DebugEditor}). - * - * @author Martin Leopold */ public class LineBreakpoint implements ClassLoadListener { - - protected Debugger dbg; // the debugger - protected LineID line; // the line this breakpoint is set on - protected BreakpointRequest bpr; // the request on the VM's event request manager - protected ReferenceType theClass; // the class containing this breakpoint, null when not yet loaded - - /** - * Create a {@link LineBreakpoint}. If in a debug session, will try to - * immediately set the breakpoint. If not in a debug session or the - * corresponding class is not yet loaded the breakpoint will activate on - * class load. - * - * @param line the line id to create the breakpoint on - * @param dbg the {@link Debugger} - */ - public LineBreakpoint(LineID line, Debugger dbg) { - this.line = line; - line.startTracking(dbg.getEditor().getTab(line.fileName()).getDocument()); - this.dbg = dbg; - theClass = dbg.getClass(className()); // try to get the class immediately, may return null if not yet loaded - set(); // activate the breakpoint (show highlight, attach if debugger is running) - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.INFO, "LBP Created " +toString() + " class: " + className(), new Object[]{}); + protected Debugger dbg; // the debugger + protected LineID line; // the line this breakpoint is set on + protected BreakpointRequest bpr; // the request on the VM's event request manager + protected ReferenceType theClass; // the class containing this breakpoint, null when not yet loaded + + + /** + * Create a {@link LineBreakpoint}. If in a debug session, will try to + * immediately set the breakpoint. If not in a debug session or the + * corresponding class is not yet loaded the breakpoint will activate on + * class load. + * + * @param line the line id to create the breakpoint on + * @param dbg the {@link Debugger} + */ + public LineBreakpoint(LineID line, Debugger dbg) { + this.line = line; + line.startTracking(dbg.getEditor().getTab(line.fileName()).getDocument()); + this.dbg = dbg; + theClass = dbg.getClass(className()); // try to get the class immediately, may return null if not yet loaded + set(); // activate the breakpoint (show highlight, attach if debugger is running) + Messages.log("LBP Created " + toString() + " class: " + className()); + } + + + /** + * Create a {@link LineBreakpoint} on a line in the current tab. + * @param lineIdx the line index of the current tab to create the breakpoint + */ + // TODO: remove and replace by {@link #LineBreakpoint(LineID line, Debugger dbg)} + public LineBreakpoint(int lineIdx, Debugger dbg) { + this(dbg.getEditor().getLineIDInCurrentTab(lineIdx), dbg); + } + + + /** + * Get the line id this breakpoint is on. + */ + public LineID lineID() { + return line; + } + + + /** + * Test if this breakpoint is on a certain line. + * + * @param testLine the line id to test + * @return true if this breakpoint is on the given line + */ + public boolean isOnLine(LineID testLine) { + return line.equals(testLine); + } + + + /** + * Attach this breakpoint to the VM. Creates and enables a + * {@link BreakpointRequest}. VM needs to be paused. + */ + protected void attach() { + if (!dbg.isPaused()) { + log("can't attach breakpoint, debugger not paused"); + return; } - /** - * Create a {@link LineBreakpoint} on a line in the current tab. - * - * @param lineIdx the line index of the current tab to create the breakpoint - * on - * @param dbg the {@link Debugger} - */ - // TODO: remove and replace by {@link #LineBreakpoint(LineID line, Debugger dbg)} - public LineBreakpoint(int lineIdx, Debugger dbg) { - this(dbg.getEditor().getLineIDInCurrentTab(lineIdx), dbg); + if (theClass == null) { + log("can't attach breakpoint, class not loaded: " + className()); + return; } - /** - * Get the line id this breakpoint is on. - * - * @return the line id - */ - public LineID lineID() { - return line; + // find line in java space + LineID javaLine = dbg.sketchToJavaLine(line); + if (javaLine == null) { + log("couldn't find line " + line + " in the java code"); + return; } - - /** - * Test if this breakpoint is on a certain line. - * - * @param testLine the line id to test - * @return true if this breakpoint is on the given line - */ - public boolean isOnLine(LineID testLine) { - return line.equals(testLine); + try { + log("BPs of class: " + theClass + ", line " + (javaLine.lineIdx() + 1)); + List locations = theClass.locationsOfLine(javaLine.lineIdx() + 1); + if (locations.isEmpty()) { + log("no location found for line " + line + " -> " + javaLine); + return; + } + // use first found location + bpr = dbg.vm().eventRequestManager().createBreakpointRequest(locations.get(0)); + bpr.enable(); + log("attached breakpoint to " + line + " -> " + javaLine); + } catch (AbsentInformationException ex) { + Messages.loge(null, ex); } + } - /** - * Attach this breakpoint to the VM. Creates and enables a - * {@link BreakpointRequest}. VM needs to be paused. - */ - protected void attach() { - if (!dbg.isPaused()) { - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.WARNING, "can't attach breakpoint, debugger not paused"); - return; - } - - if (theClass == null) { - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.WARNING, "can't attach breakpoint, class not loaded: {0}", className()); - return; - } - - // find line in java space - LineID javaLine = dbg.sketchToJavaLine(line); - if (javaLine == null) { - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.WARNING, "couldn't find line {0} in the java code", line); - return; - } - try { - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.WARNING, "BPs of class: {0} , line " + (javaLine.lineIdx() + 1), new Object[]{theClass}); - List locations = theClass.locationsOfLine(javaLine.lineIdx() + 1); - if (locations.isEmpty()) { - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.WARNING, "no location found for line {0} -> {1}", new Object[]{line, javaLine}); - return; - } - // use first found location - bpr = dbg.vm().eventRequestManager().createBreakpointRequest(locations.get(0)); - bpr.enable(); - Logger.getLogger(LineBreakpoint.class.getName()).log(Level.INFO, "attached breakpoint to {0} -> {1}", new Object[]{line, javaLine}); - } catch (AbsentInformationException ex) { - Logger.getLogger(Debugger.class.getName()).log(Level.SEVERE, null, ex); - } - } - /** - * Detach this breakpoint from the VM. Deletes the - * {@link BreakpointRequest}. - */ - protected void detach() { - if (bpr != null) { - dbg.vm().eventRequestManager().deleteEventRequest(bpr); - bpr = null; - } + /** + * Detach this breakpoint from the VM. Deletes the + * {@link BreakpointRequest}. + */ + protected void detach() { + if (bpr != null) { + dbg.vm().eventRequestManager().deleteEventRequest(bpr); + bpr = null; } - - /** - * Set this breakpoint. Adds the line highlight. If Debugger is paused also - * attaches the breakpoint by calling {@link #attach()}. - */ - protected void set() { - dbg.addClassLoadListener(this); // class may not yet be loaded - dbg.getEditor().addBreakpointedLine(line); - if (theClass != null && dbg.isPaused()) { // class is loaded - // immediately activate the breakpoint - attach(); - } - if (dbg.getEditor().isInCurrentTab(line)) { - dbg.getEditor().getSketch().setModified(true); - } + } + + + /** + * Set this breakpoint. Adds the line highlight. If Debugger is paused + * also attaches the breakpoint by calling {@link #attach()}. + */ + protected void set() { + dbg.addClassLoadListener(this); // class may not yet be loaded + dbg.getEditor().addBreakpointedLine(line); + if (theClass != null && dbg.isPaused()) { // class is loaded + // immediately activate the breakpoint + attach(); } - - /** - * Remove this breakpoint. Clears the highlight and detaches the breakpoint - * if the debugger is paused. - */ - public void remove() { - dbg.removeClassLoadListener(this); - //System.out.println("removing " + line.lineIdx()); - dbg.getEditor().removeBreakpointedLine(line.lineIdx()); - if (dbg.isPaused()) { - // immediately remove the breakpoint - detach(); - } - line.stopTracking(); - if (dbg.getEditor().isInCurrentTab(line)) { - dbg.getEditor().getSketch().setModified(true); - } + if (dbg.getEditor().isInCurrentTab(line)) { + dbg.getEditor().getSketch().setModified(true); + } + } + + + /** + * Remove this breakpoint. Clears the highlight and detaches + * the breakpoint if the debugger is paused. + */ + public void remove() { + dbg.removeClassLoadListener(this); + //System.out.println("removing " + line.lineIdx()); + dbg.getEditor().removeBreakpointedLine(line.lineIdx()); + if (dbg.isPaused()) { + // immediately remove the breakpoint + detach(); + } + line.stopTracking(); + if (dbg.getEditor().isInCurrentTab(line)) { + dbg.getEditor().getSketch().setModified(true); + } + } + + + @Override + public String toString() { + return line.toString(); + } + + + /** + * Get the name of the class this breakpoint belongs to. Needed for + * fetching the right location to create a breakpoint request. + * @return the class name + */ + protected String className() { + if (line.fileName().endsWith(".pde")) { + // standard tab + ReferenceType mainClass = dbg.getMainClass(); + //System.out.println(dbg.getMainClass().name()); + if (mainClass == null) { + return null; + } + return dbg.getMainClass().name(); } -// public void enable() { -// } -// -// public void disable() { -// } - @Override - public String toString() { - return line.toString(); + if (line.fileName().endsWith(".java")) { + // pure java tab + return line.fileName().substring(0, line.fileName().lastIndexOf(".java")); + } + return null; + } + + + /** + * Event handler called when a class is loaded in the debugger. Causes the + * breakpoint to be attached, if its class was loaded. + * + * @param theClass the class that was just loaded. + */ + @Override + public void classLoaded(ReferenceType theClass) { + // check if our class is being loaded + Messages.log("Class Loaded: " + theClass.name()); + if (theClass.name().equals(className())) { + this.theClass = theClass; + attach(); } + for (ReferenceType ct : theClass.nestedTypes()) { + Messages.log("Nested " + ct.name()); + } + } - /** - * Get the name of the class this breakpoint belongs to. Needed for fetching - * the right location to create a breakpoint request. - * - * @return the class name - */ - protected String className() { - if (line.fileName().endsWith(".pde")) { - // standard tab - ReferenceType mainClass = dbg.getMainClass(); - //System.out.println(dbg.getMainClass().name()); - if (mainClass == null) { - return null; - } - return dbg.getMainClass().name(); - } - - if (line.fileName().endsWith(".java")) { - // pure java tab - return line.fileName().substring(0, line.fileName().lastIndexOf(".java")); - } - return null; - } + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + - /** - * Event handler called when a class is loaded in the debugger. Causes the - * breakpoint to be attached, if its class was loaded. - * - * @param theClass the class that was just loaded. - */ - @Override - public void classLoaded(ReferenceType theClass) { - // check if our class is being loaded - Messages.log("Class Loaded: " + theClass.name()); - if (theClass.name().equals(className())) { - this.theClass = theClass; - attach(); - } - for (ReferenceType ct : theClass.nestedTypes()) { - Messages.log("Nested " + ct.name()); - } + private void log(String msg, Object... args) { + if (args != null && args.length != 0) { + Messages.logf(getClass().getName() + " " + msg, args); + } else { + Messages.log(getClass().getName() + " " + msg); } + } } diff --git a/java/src/processing/mode/java/debug/LineHighlight.java b/java/src/processing/mode/java/debug/LineHighlight.java index 789d4ba966..66856f8292 100644 --- a/java/src/processing/mode/java/debug/LineHighlight.java +++ b/java/src/processing/mode/java/debug/LineHighlight.java @@ -1,21 +1,22 @@ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* -Part of the Processing project - http://processing.org -Copyright (c) 2012-15 The Processing Foundation + Part of the Processing project - http://processing.org -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. + Copyright (c) 2012-16 The Processing Foundation -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2, as published by the Free Software Foundation. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, Inc. -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package processing.mode.java.debug; @@ -29,23 +30,17 @@ /** * Model/Controller for a highlighted source code line. Implements a custom * background color and a text based marker placed in the left-hand gutter area. - * - * @author Martin Leopold */ public class LineHighlight { - protected final JavaEditor editor; // the view, used for highlighting lines by setting a background color protected final LineID lineID; // the id of the line protected String marker; // protected int priority = 0; protected static final Set allHighlights = new HashSet<>(); - + /** * Create a {@link LineHighlight}. - * - * @param lineID the line id to highlight - * @param editor the {@link JavaEditor} */ public LineHighlight(LineID lineID, JavaEditor editor) { this.lineID = lineID; @@ -56,10 +51,10 @@ public LineHighlight(LineID lineID, JavaEditor editor) { allHighlights.add(this); } - + protected static boolean isHighestPriority(LineHighlight hl) { for (LineHighlight check : allHighlights) { - if (check.getLineID().equals(hl.getLineID()) && + if (check.getLineID().equals(hl.getLineID()) && check.priority() > hl.priority()) { return false; } @@ -67,107 +62,114 @@ protected static boolean isHighestPriority(LineHighlight hl) { return true; } - + public void setPriority(int p) { this.priority = p; } - + public int priority() { return priority; } - - /** - * Create a {@link LineHighlight} on the current tab. - * - * @param lineIdx the line index on the current tab to highlight - * @param editor the {@link JavaEditor} - */ - // TODO: Remove and replace by {@link #LineHighlight(LineID lineID, JavaEditor editor)} - public LineHighlight(int lineIdx, JavaEditor editor) { - this(editor.getLineIDInCurrentTab(lineIdx), editor); - } - /** - * Set a text based marker displayed in the left hand gutter area of this - * highlighted line. - * - * @param marker the marker text - */ - public void setMarker(String marker) { - this.marker = marker; - paint(); - } + /** + * Create a {@link LineHighlight} on the current tab. + * + * @param lineIdx the line index on the current tab to highlight + * @param editor the {@link JavaEditor} + */ + // TODO: Remove and replace by {@link #LineHighlight(LineID lineID, JavaEditor editor)} + public LineHighlight(int lineIdx, JavaEditor editor) { + this(editor.getLineIDInCurrentTab(lineIdx), editor); + } - /** - * Retrieve the line id of this {@link LineHighlight}. - * - * @return the line id - */ - public LineID getLineID() { - return lineID; - } - /** - * Test if this highlight is on a certain line. - * - * @param testLine the line to test - * @return true if this highlight is on the given line - */ - public boolean isOnLine(LineID testLine) { - return lineID.equals(testLine); - } + /** + * Set a text based marker displayed in the left hand gutter area of this + * highlighted line. + * + * @param marker the marker text + */ + public void setMarker(String marker) { + this.marker = marker; + paint(); + } + + + /** + * Retrieve the line id of this {@link LineHighlight}. + * + * @return the line id + */ + public LineID getLineID() { + return lineID; + } + + + /** + * Test if this highlight is on a certain line. + * + * @param testLine the line to test + * @return true if this highlight is on the given line + */ + public boolean isOnLine(LineID testLine) { + return lineID.equals(testLine); + } - /** - * Event handler for line number changes (due to editing). Will remove the - * highlight from the old line number and repaint it at the new location. - * - * @param line the line that has changed - * @param oldLineIdx the old line index (0-based) - * @param newLineIdx the new line index (0-based) - */ - public void lineChanged(LineID line, int oldLineIdx, int newLineIdx) { - // clear old line - if (editor.isInCurrentTab(new LineID(line.fileName(), oldLineIdx))) { - editor.getJavaTextArea().clearGutterText(oldLineIdx); - } - - // paint new line - // but only if it's on top -> fixes current line being hidden by breakpoint moving it down. - // lineChanged events seem to come in inverse order of startTracking the LineID. (and bp is created first...) - if (LineHighlight.isHighestPriority(this)) { - paint(); - } + + /** + * Event handler for line number changes (due to editing). Will remove the + * highlight from the old line number and repaint it at the new location. + * + * @param line the line that has changed + * @param oldLineIdx the old line index (0-based) + * @param newLineIdx the new line index (0-based) + */ + public void lineChanged(LineID line, int oldLineIdx, int newLineIdx) { + // clear old line + if (editor.isInCurrentTab(new LineID(line.fileName(), oldLineIdx))) { + editor.getJavaTextArea().clearGutterText(oldLineIdx); } - /** - * Notify this line highlight that it is no longer used. Call this for - * cleanup before the {@link LineHighlight} is discarded. - */ - public void dispose() { - lineID.removeListener(this); - lineID.stopTracking(); - allHighlights.remove(this); + // paint new line + // but only if it's on top -> fixes current line being hidden by breakpoint moving it down. + // lineChanged events seem to come in inverse order of startTracking the LineID. (and bp is created first...) + if (LineHighlight.isHighestPriority(this)) { + paint(); } + } + - /** - * (Re-)paint this line highlight. - */ - public void paint() { - if (editor.isInCurrentTab(lineID)) { - if (marker != null) { - editor.getJavaTextArea().setGutterText(lineID.lineIdx(), marker); - } - } + /** + * Notify this line highlight that it is no longer used. Call this for + * cleanup before the {@link LineHighlight} is discarded. + */ + public void dispose() { + lineID.removeListener(this); + lineID.stopTracking(); + allHighlights.remove(this); + } + + + /** + * (Re-)paint this line highlight. + */ + public void paint() { + if (editor.isInCurrentTab(lineID)) { + if (marker != null) { + editor.getJavaTextArea().setGutterText(lineID.lineIdx(), marker); + } } + } + - /** - * Clear this line highlight. - */ - public void clear() { - if (editor.isInCurrentTab(lineID)) { - editor.getJavaTextArea().clearGutterText(lineID.lineIdx()); - } + /** + * Clear this line highlight. + */ + public void clear() { + if (editor.isInCurrentTab(lineID)) { + editor.getJavaTextArea().clearGutterText(lineID.lineIdx()); } + } } diff --git a/java/src/processing/mode/java/debug/LineID.java b/java/src/processing/mode/java/debug/LineID.java index e7c066110c..251a29ceee 100644 --- a/java/src/processing/mode/java/debug/LineID.java +++ b/java/src/processing/mode/java/debug/LineID.java @@ -1,29 +1,29 @@ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* -Part of the Processing project - http://processing.org -Copyright (c) 2012-15 The Processing Foundation + Part of the Processing project - http://processing.org -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. + Copyright (c) 2012-16 The Processing Foundation -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2, as published by the Free Software Foundation. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, Inc. -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package processing.mode.java.debug; import java.util.HashSet; import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; + import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.BadLocationException; @@ -31,251 +31,247 @@ import javax.swing.text.Element; import javax.swing.text.Position; +import processing.app.Messages; + + /** * Describes an ID for a code line. Comprised of a file name and a (0-based) * line number. Can track changes to the line number due to text editing by * attaching a {@link Document}. Registered {@link LineListener}s are notified * of changes to the line number. - * - * @author Martin Leopold */ public class LineID implements DocumentListener { + protected String fileName; // the filename + protected int lineIdx; // the line number, 0-based + protected Document doc; // the Document to use for line number tracking + protected Position pos; // the Position acquired during line number tracking + protected Set listeners = new HashSet(); // listeners for line number changes - protected String fileName; // the filename - protected int lineIdx; // the line number, 0-based - protected Document doc; // the Document to use for line number tracking - protected Position pos; // the Position acquired during line number tracking - protected Set listeners = new HashSet(); // listeners for line number changes - public LineID(String fileName, int lineIdx) { - this.fileName = fileName; - this.lineIdx = lineIdx; - } + public LineID(String fileName, int lineIdx) { + this.fileName = fileName; + this.lineIdx = lineIdx; + } - /** - * Get the file name of this line. - * - * @return the file name - */ - public String fileName() { - return fileName; - } - /** - * Get the (0-based) line number of this line. - * - * @return the line index (i.e. line number, starting at 0) - */ - public synchronized int lineIdx() { - return lineIdx; - } + /** + * Get the file name of this line. + * + * @return the file name + */ + public String fileName() { + return fileName; + } - @Override - public int hashCode() { - return toString().hashCode(); - } - /** - * Test whether this {@link LineID} is equal to another object. Two - * {@link LineID}'s are equal when both their fileName and lineNo are equal. - * - * @param obj the object to test for equality - * @return {@code true} if equal - */ - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final LineID other = (LineID) obj; - if ((this.fileName == null) ? (other.fileName != null) : !this.fileName.equals(other.fileName)) { - return false; - } - if (this.lineIdx != other.lineIdx) { - return false; - } - return true; - } + /** + * Get the (0-based) line number of this line. + * + * @return the line index (i.e. line number, starting at 0) + */ + public synchronized int lineIdx() { + return lineIdx; + } - /** - * Output a string representation in the form fileName:lineIdx+1. Note this - * uses a 1-based line number as is customary for human-readable line - * numbers. - * - * @return the string representation of this line ID - */ - @Override - public String toString() { - return fileName + ":" + (lineIdx + 1); - } -// /** -// * Retrieve a copy of this line ID. -// * -// * @return the copy -// */ -// @Override -// public LineID clone() { -// return new LineID(fileName, lineIdx); -// } - - /** - * Attach a {@link Document} to enable line number tracking when editing. - * The position to track is before the first non-whitespace character on the - * line. Edits happening before that position will cause the line number to - * update accordingly. Multiple {@link #startTracking} calls will replace - * the tracked document. Whoever wants a tracked line should track it and - * add itself as listener if necessary. - * ({@link LineHighlight}, {@link LineBreakpoint}) - * - * @param doc the {@link Document} to use for line number tracking - */ - public synchronized void startTracking(Document doc) { - //System.out.println("tracking: " + this); - if (doc == null) { - return; // null arg - } - if (doc == this.doc) { - return; // already tracking that doc - } - try { - Element line = doc.getDefaultRootElement().getElement(lineIdx); - if (line == null) { - return; // line doesn't exist - } - String lineText = doc.getText(line.getStartOffset(), line.getEndOffset() - line.getStartOffset()); - // set tracking position at (=before) first non-white space character on line, - // or, if the line consists of entirely white spaces, just before the newline - // character - pos = doc.createPosition(line.getStartOffset() + nonWhiteSpaceOffset(lineText)); - this.doc = doc; - doc.addDocumentListener(this); - } catch (BadLocationException ex) { - Logger.getLogger(LineID.class.getName()).log(Level.SEVERE, null, ex); - pos = null; - this.doc = null; - } - } + @Override + public int hashCode() { + return toString().hashCode(); + } - /** - * Notify this {@link LineID} that it is no longer in use. Will stop - * position tracking. Call this when this {@link LineID} is no longer - * needed. - */ - public synchronized void stopTracking() { - if (doc != null) { - doc.removeDocumentListener(this); - doc = null; - } - } - /** - * Update the tracked position. Will notify listeners if line number has - * changed. - */ - protected synchronized void updatePosition() { - if (doc != null && pos != null) { - // track position - int offset = pos.getOffset(); - int oldLineIdx = lineIdx; - lineIdx = doc.getDefaultRootElement().getElementIndex(offset); // offset to lineNo - if (lineIdx != oldLineIdx) { - for (LineHighlight l : listeners) { - if (l != null) { - l.lineChanged(this, oldLineIdx, lineIdx); - } else { - listeners.remove(l); // remove null listener - } - } - } - } + /** + * Test whether this {@link LineID} is equal to another object. Two + * {@link LineID}'s are equal when both their fileName and lineNo are equal. + * + * @param obj the object to test for equality + * @return {@code true} if equal + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; } - - /** - * Add listener to be notified when the line number changes. - * - * @param l the listener to add - */ - public void addListener(LineHighlight l) { - listeners.add(l); + if (getClass() != obj.getClass()) { + return false; + } + final LineID other = (LineID) obj; + if ((this.fileName == null) ? (other.fileName != null) : !this.fileName.equals(other.fileName)) { + return false; } + if (this.lineIdx != other.lineIdx) { + return false; + } + return true; + } + + + /** + * Output a string representation in the form fileName:lineIdx+1. Note this + * uses a 1-based line number as is customary for human-readable line + * numbers. + * + * @return the string representation of this line ID + */ + @Override + public String toString() { + return fileName + ":" + (lineIdx + 1); + } - /** - * Remove a listener for line number changes. - * - * @param l the listener to remove - */ - public void removeListener(LineHighlight l) { - listeners.remove(l); + + /** + * Attach a {@link Document} to enable line number tracking when editing. + * The position to track is before the first non-whitespace character on the + * line. Edits happening before that position will cause the line number to + * update accordingly. Multiple {@link #startTracking} calls will replace + * the tracked document. Whoever wants a tracked line should track it and + * add itself as listener if necessary. + * ({@link LineHighlight}, {@link LineBreakpoint}) + * + * @param doc the {@link Document} to use for line number tracking + */ + public synchronized void startTracking(Document doc) { + //System.out.println("tracking: " + this); + if (doc == null) { + return; // null arg + } + if (doc == this.doc) { + return; // already tracking that doc + } + try { + Element line = doc.getDefaultRootElement().getElement(lineIdx); + if (line == null) { + return; // line doesn't exist + } + String lineText = doc.getText(line.getStartOffset(), line.getEndOffset() - line.getStartOffset()); + // set tracking position at (=before) first non-white space character on line, + // or, if the line consists of entirely white spaces, just before the newline + // character + pos = doc.createPosition(line.getStartOffset() + nonWhiteSpaceOffset(lineText)); + this.doc = doc; + doc.addDocumentListener(this); + } catch (BadLocationException ex) { + Messages.loge(null, ex); + pos = null; + this.doc = null; } + } - /** - * Calculate the offset of the first non-whitespace character in a string. - * - * @param str the string to examine - * @return offset of first non-whitespace character in str - */ - protected static int nonWhiteSpaceOffset(String str) { - for (int i = 0; i < str.length(); i++) { - if (!Character.isWhitespace(str.charAt(i))) { - return i; - } - } - - /* If we've reached here, that implies the line consists of purely white - * space. So return at a position just after the whitespace (i.e., - * just before the newline). - * - * The " - 1" part resolves issue #3552 - */ - return str.length() - 1; + + /** + * Notify this {@link LineID} that it is no longer in use. Will stop + * position tracking. Call this when this {@link LineID} is no longer + * needed. + */ + public synchronized void stopTracking() { + if (doc != null) { + doc.removeDocumentListener(this); + doc = null; } + } + - /** - * Called when the {@link Document} registered using {@link #startTracking} - * is edited. This happens when text is inserted or removed. - * - * @param de - */ - protected void editEvent(DocumentEvent de) { - //System.out.println("document edit @ " + de.getOffset()); - if (de.getOffset() <= pos.getOffset()) { - updatePosition(); - //System.out.println("updating, new line no: " + lineNo); + /** + * Update the tracked position. Will notify listeners if line number has + * changed. + */ + protected synchronized void updatePosition() { + if (doc != null && pos != null) { + // track position + int offset = pos.getOffset(); + int oldLineIdx = lineIdx; + lineIdx = doc.getDefaultRootElement().getElementIndex(offset); // offset to lineNo + if (lineIdx != oldLineIdx) { + for (LineHighlight l : listeners) { + if (l != null) { + l.lineChanged(this, oldLineIdx, lineIdx); + } else { + listeners.remove(l); // remove null listener + } } + } } + } - /** - * {@link DocumentListener} callback. Called when text is inserted. - * - * @param de - */ - @Override - public void insertUpdate(DocumentEvent de) { - editEvent(de); - } - /** - * {@link DocumentListener} callback. Called when text is removed. - * - * @param de - */ - @Override - public void removeUpdate(DocumentEvent de) { - editEvent(de); + /** + * Add listener to be notified when the line number changes. + * + * @param l the listener to add + */ + public void addListener(LineHighlight l) { + listeners.add(l); + } + + + /** + * Remove a listener for line number changes. + * + * @param l the listener to remove + */ + public void removeListener(LineHighlight l) { + listeners.remove(l); + } + + + /** + * Calculate the offset of the first non-whitespace character in a string. + * @param str the string to examine + * @return offset of first non-whitespace character in str + */ + protected static int nonWhiteSpaceOffset(String str) { + for (int i = 0; i < str.length(); i++) { + if (!Character.isWhitespace(str.charAt(i))) { + return i; + } } - /** - * {@link DocumentListener} callback. Called when attributes are changed. - * Not used. - * - * @param de - */ - @Override - public void changedUpdate(DocumentEvent de) { - // not needed. + // If we've reached here, that implies the line consists of purely white + // space. So return at a position just after the whitespace (i.e., + // just before the newline). + // + // The " - 1" part resolves issue #3552 + return str.length() - 1; + } + + + /** + * Called when the {@link Document} registered using {@link #startTracking} + * is edited. This happens when text is inserted or removed. + */ + protected void editEvent(DocumentEvent de) { + //System.out.println("document edit @ " + de.getOffset()); + if (de.getOffset() <= pos.getOffset()) { + updatePosition(); + //System.out.println("updating, new line no: " + lineNo); } + } + + + /** + * {@link DocumentListener} callback. Called when text is inserted. + */ + @Override + public void insertUpdate(DocumentEvent de) { + editEvent(de); + } + + + /** + * {@link DocumentListener} callback. Called when text is removed. + */ + @Override + public void removeUpdate(DocumentEvent de) { + editEvent(de); + } + + + /** + * {@link DocumentListener} callback. Called when attributes are changed. + * Not used. + */ + @Override + public void changedUpdate(DocumentEvent de) { + // not needed. + } } diff --git a/java/src/processing/mode/java/debug/LocalVariableNode.java b/java/src/processing/mode/java/debug/LocalVariableNode.java index 435a230f67..39c42a2a72 100644 --- a/java/src/processing/mode/java/debug/LocalVariableNode.java +++ b/java/src/processing/mode/java/debug/LocalVariableNode.java @@ -1,21 +1,22 @@ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* -Part of the Processing project - http://processing.org -Copyright (c) 2012-15 The Processing Foundation + Part of the Processing project - http://processing.org -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. + Copyright (c) 2012-16 The Processing Foundation -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2, as published by the Free Software Foundation. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, Inc. -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package processing.mode.java.debug; @@ -25,45 +26,36 @@ import com.sun.jdi.LocalVariable; import com.sun.jdi.StackFrame; import com.sun.jdi.Value; -import java.util.logging.Level; -import java.util.logging.Logger; + +import processing.app.Messages; + /** - * Specialized {@link VariableNode} for representing local variables. Overrides - * {@link #setValue} to properly change the value of the encapsulated local - * variable. - * - * @author Martin Leopold + * Specialized {@link VariableNode} for representing local variables. + * Overrides {@link #setValue} to properly change the value of the + * encapsulated local variable. */ public class LocalVariableNode extends VariableNode { + protected LocalVariable var; + protected StackFrame frame; - protected LocalVariable var; - protected StackFrame frame; - /** - * Construct a {@link LocalVariableNode}. - * - * @param name the name - * @param type the type - * @param value the value - * @param var the local variable - * @param frame the stack frame containing the local variable - */ - public LocalVariableNode(String name, String type, Value value, LocalVariable var, StackFrame frame) { - super(name, type, value); - this.var = var; - this.frame = frame; - } + public LocalVariableNode(String name, String type, Value value, LocalVariable var, StackFrame frame) { + super(name, type, value); + this.var = var; + this.frame = frame; + } + - @Override - public void setValue(Value value) { - try { - frame.setValue(var, value); - } catch (InvalidTypeException ex) { - Logger.getLogger(LocalVariableNode.class.getName()).log(Level.SEVERE, null, ex); - } catch (ClassNotLoadedException ex) { - Logger.getLogger(LocalVariableNode.class.getName()).log(Level.SEVERE, null, ex); - } - this.value = value; + @Override + public void setValue(Value value) { + try { + frame.setValue(var, value); + } catch (InvalidTypeException ex) { + Messages.loge(null, ex); + } catch (ClassNotLoadedException ex) { + Messages.loge(null, ex); } + this.value = value; + } } diff --git a/java/src/processing/mode/java/debug/VariableNode.java b/java/src/processing/mode/java/debug/VariableNode.java index e370f7da11..d9ad2e5f4b 100644 --- a/java/src/processing/mode/java/debug/VariableNode.java +++ b/java/src/processing/mode/java/debug/VariableNode.java @@ -1,21 +1,22 @@ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* -Part of the Processing project - http://processing.org -Copyright (c) 2012-15 The Processing Foundation + Part of the Processing project - http://processing.org -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. + Copyright (c) 2012-16 The Processing Foundation -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2, as published by the Free Software Foundation. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, Inc. -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package processing.mode.java.debug; @@ -33,329 +34,350 @@ /** * Model for a variable in the variable inspector. Has a type and name and - * optionally a value. Can have sub-variables (as is the case for objects, and - * arrays). - * - * @author Martin Leopold + * optionally a value. Can have sub-variables (as is the case for objects, + * and arrays). */ public class VariableNode implements MutableTreeNode { - - public static final int TYPE_UNKNOWN = -1; - public static final int TYPE_OBJECT = 0; - public static final int TYPE_ARRAY = 1; - public static final int TYPE_INTEGER = 2; - public static final int TYPE_FLOAT = 3; - public static final int TYPE_BOOLEAN = 4; - public static final int TYPE_CHAR = 5; - public static final int TYPE_STRING = 6; - public static final int TYPE_LONG = 7; - public static final int TYPE_DOUBLE = 8; - public static final int TYPE_BYTE = 9; - public static final int TYPE_SHORT = 10; - public static final int TYPE_VOID = 11; - protected String type; - protected String name; - protected Value value; - protected List children = new ArrayList(); - protected MutableTreeNode parent; - - /** - * Construct a {@link VariableNode}. - * @param name the name - * @param type the type - * @param value the value - */ - public VariableNode(String name, String type, Value value) { - this.name = name; - this.type = type; - this.value = value; + public static final int TYPE_UNKNOWN = -1; + public static final int TYPE_OBJECT = 0; + public static final int TYPE_ARRAY = 1; + public static final int TYPE_INTEGER = 2; + public static final int TYPE_FLOAT = 3; + public static final int TYPE_BOOLEAN = 4; + public static final int TYPE_CHAR = 5; + public static final int TYPE_STRING = 6; + public static final int TYPE_LONG = 7; + public static final int TYPE_DOUBLE = 8; + public static final int TYPE_BYTE = 9; + public static final int TYPE_SHORT = 10; + public static final int TYPE_VOID = 11; + + protected String type; + protected String name; + protected Value value; + protected List children = new ArrayList(); + protected MutableTreeNode parent; + + + /** + * Construct a {@link VariableNode}. + * @param name the name + * @param type the type + * @param value the value + */ + public VariableNode(String name, String type, Value value) { + this.name = name; + this.type = type; + this.value = value; + } + + + public void setValue(Value value) { + this.value = value; + } + + + public Value getValue() { + return value; + } + + + /** + * Get a String representation of this variable nodes value. + * + * @return a String representing the value. + */ + public String getStringValue() { + String str; + if (value != null) { + if (getType() == TYPE_OBJECT) { + str = "instance of " + type; + } else if (getType() == TYPE_ARRAY) { + //instance of int[5] (id=998) --> instance of int[5] + str = value.toString().substring(0, value.toString().lastIndexOf(" ")); + } else if (getType() == TYPE_STRING) { + str = ((StringReference) value).value(); // use original string value (without quotes) + } else { + str = value.toString(); + } + } else { + str = "null"; } + return str; + } - public void setValue(Value value) { - this.value = value; - } - public Value getValue() { - return value; - } + public String getTypeName() { + return type; + } - /** - * Get a String representation of this variable nodes value. - * - * @return a String representing the value. - */ - public String getStringValue() { - String str; - if (value != null) { - if (getType() == TYPE_OBJECT) { - str = "instance of " + type; - } else if (getType() == TYPE_ARRAY) { - //instance of int[5] (id=998) --> instance of int[5] - str = value.toString().substring(0, value.toString().lastIndexOf(" ")); - } else if (getType() == TYPE_STRING) { - str = ((StringReference) value).value(); // use original string value (without quotes) - } else { - str = value.toString(); - } - } else { - str = "null"; - } - return str; - } - public String getTypeName() { - return type; + public int getType() { + if (type == null) { + return TYPE_UNKNOWN; } - - public int getType() { - if (type == null) { - return TYPE_UNKNOWN; - } - if (type.endsWith("[]")) { - return TYPE_ARRAY; - } - if (type.equals("int")) { - return TYPE_INTEGER; - } - if (type.equals("long")) { - return TYPE_LONG; - } - if (type.equals("byte")) { - return TYPE_BYTE; - } - if (type.equals("short")) { - return TYPE_SHORT; - } - if (type.equals("float")) { - return TYPE_FLOAT; - } - if (type.equals("double")) { - return TYPE_DOUBLE; - } - if (type.equals("char")) { - return TYPE_CHAR; - } - if (type.equals("java.lang.String")) { - return TYPE_STRING; - } - if (type.equals("boolean")) { - return TYPE_BOOLEAN; - } - if (type.equals("void")) { - return TYPE_VOID; //TODO: check if this is correct - } - return TYPE_OBJECT; + if (type.endsWith("[]")) { + return TYPE_ARRAY; } - - public String getName() { - return name; + if (type.equals("int")) { + return TYPE_INTEGER; } - - public void setName(String name) { - this.name = name; + if (type.equals("long")) { + return TYPE_LONG; } - - /** - * Add a {@link VariableNode} as child. - * - * @param c the {@link VariableNode} to add. - */ - public void addChild(VariableNode c) { - children.add(c); - c.setParent(this); + if (type.equals("byte")) { + return TYPE_BYTE; } - - /** - * Add multiple {@link VariableNode}s as children. - * - * @param children the list of {@link VariableNode}s to add. - */ - public void addChildren(List children) { - for (VariableNode child : children) { - addChild(child); - } + if (type.equals("short")) { + return TYPE_SHORT; } - - @Override - public TreeNode getChildAt(int i) { - return children.get(i); + if (type.equals("float")) { + return TYPE_FLOAT; } - - @Override - public int getChildCount() { - return children.size(); + if (type.equals("double")) { + return TYPE_DOUBLE; } - - @Override - public TreeNode getParent() { - return parent; + if (type.equals("char")) { + return TYPE_CHAR; } - - @Override - public int getIndex(TreeNode tn) { - return children.indexOf(tn); + if (type.equals("java.lang.String")) { + return TYPE_STRING; } - - @Override - public boolean getAllowsChildren() { - if (value == null) { - return false; - } - - // handle strings - if (getType() == TYPE_STRING) { - return false; - } - - // handle arrays - if (getType() == TYPE_ARRAY) { - ArrayReference array = (ArrayReference) value; - return array.length() > 0; - } - // handle objects - if (getType() == TYPE_OBJECT) { // this also rules out null - // check if this object has any fields - ObjectReference obj = (ObjectReference) value; - return !obj.referenceType().visibleFields().isEmpty(); - } - - return false; + if (type.equals("boolean")) { + return TYPE_BOOLEAN; } - - /** - * This controls the default icon and disclosure triangle. - * - * @return true, will show "folder" icon and disclosure triangle. - */ - @Override - public boolean isLeaf() { - //return children.size() == 0; - return !getAllowsChildren(); + if (type.equals("void")) { + return TYPE_VOID; //TODO: check if this is correct } + return TYPE_OBJECT; + } - @Override - public Enumeration children() { - return Collections.enumeration(children); - } - /** - * Get a String representation of this {@link VariableNode}. - * - * @return the name of the variable (for sorting to work). - */ - @Override - public String toString() { - return getName(); // for sorting - } + public String getName() { + return name; + } - /** - * Get a String description of this {@link VariableNode}. Contains the type, - * name and value. - * - * @return the description - */ - public String getDescription() { - String str = ""; - if (type != null) { - str += type + " "; - } - str += name; - str += " = " + getStringValue(); - return str; - } - @Override - public void insert(MutableTreeNode mtn, int i) { - children.add(i, this); + public void setName(String name) { + this.name = name; + } + + + /** + * Add a {@link VariableNode} as child. + * + * @param c the {@link VariableNode} to add. + */ + public void addChild(VariableNode c) { + children.add(c); + c.setParent(this); + } + + + /** + * Add multiple {@link VariableNode}s as children. + * + * @param children the list of {@link VariableNode}s to add. + */ + public void addChildren(List children) { + for (VariableNode child : children) { + addChild(child); } + } + + + @Override + public TreeNode getChildAt(int i) { + return children.get(i); + } - @Override - public void remove(int i) { - MutableTreeNode mtn = children.remove(i); - if (mtn != null) { - mtn.setParent(null); - } + + @Override + public int getChildCount() { + return children.size(); + } + + + @Override + public TreeNode getParent() { + return parent; + } + + + @Override + public int getIndex(TreeNode tn) { + return children.indexOf(tn); + } + + + @Override + public boolean getAllowsChildren() { + if (value == null) { + return false; } - @Override - public void remove(MutableTreeNode mtn) { - children.remove(mtn); - mtn.setParent(null); + // handle strings + if (getType() == TYPE_STRING) { + return false; } - /** - * Remove all children from this {@link VariableNode}. - */ - public void removeAllChildren() { - for (MutableTreeNode mtn : children) { - mtn.setParent(null); - } - children.clear(); + // handle arrays + if (getType() == TYPE_ARRAY) { + ArrayReference array = (ArrayReference) value; + return array.length() > 0; + } + // handle objects + if (getType() == TYPE_OBJECT) { // this also rules out null + // check if this object has any fields + ObjectReference obj = (ObjectReference) value; + return !obj.referenceType().visibleFields().isEmpty(); } - @Override - public void setUserObject(Object o) { - if (o instanceof Value) { - value = (Value) o; - } + return false; + } + + + /** + * This controls the default icon and disclosure triangle. + * + * @return true, will show "folder" icon and disclosure triangle. + */ + @Override + public boolean isLeaf() { + //return children.size() == 0; + return !getAllowsChildren(); + } + + + @Override + public Enumeration children() { + return Collections.enumeration(children); + } + + + /** + * Get a String representation of this {@link VariableNode}. + * + * @return the name of the variable (for sorting to work). + */ + @Override + public String toString() { + return getName(); // for sorting + } + + + /** + * Get a String description of this {@link VariableNode}. Contains the type, + * name and value. + * + * @return the description + */ + public String getDescription() { + String str = ""; + if (type != null) { + str += type + " "; } + str += name; + str += " = " + getStringValue(); + return str; + } + - @Override - public void removeFromParent() { - parent.remove(this); - this.parent = null; + @Override + public void insert(MutableTreeNode mtn, int i) { + children.add(i, this); + } + + + @Override + public void remove(int i) { + MutableTreeNode mtn = children.remove(i); + if (mtn != null) { + mtn.setParent(null); } + } + - @Override - public void setParent(MutableTreeNode mtn) { - parent = mtn; + @Override + public void remove(MutableTreeNode mtn) { + children.remove(mtn); + mtn.setParent(null); + } + + + /** + * Remove all children from this {@link VariableNode}. + */ + public void removeAllChildren() { + for (MutableTreeNode mtn : children) { + mtn.setParent(null); } + children.clear(); + } + - /** - * Test for equality. To be equal, two {@link VariableNode}s need to have - * equal type, name and value. - * - * @param obj the object to test for equality with this {@link VariableNode} - * @return true if the given object is equal to this {@link VariableNode} - */ - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final VariableNode other = (VariableNode) obj; - if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) { - //System.out.println("type not equal"); - return false; - } - if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { - //System.out.println("name not equal"); - return false; - } - if (this.value != other.value && (this.value == null || !this.value.equals(other.value))) { - //System.out.println("value not equal"); - return false; - } -// if (this.parent != other.parent && (this.parent == null || !this.parent.equals(other.parent))) { -// System.out.println("parent not equal: " + this.parent + "/" + other.parent); -// return false; -// } - return true; + @Override + public void setUserObject(Object o) { + if (o instanceof Value) { + value = (Value) o; } + } + + + @Override + public void removeFromParent() { + parent.remove(this); + this.parent = null; + } + - /** - * Returns a hash code based on type, name and value. - */ - @Override - public int hashCode() { - int hash = 3; - hash = 97 * hash + (this.type != null ? this.type.hashCode() : 0); - hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0); - hash = 97 * hash + (this.value != null ? this.value.hashCode() : 0); -// hash = 97 * hash + (this.parent != null ? this.parent.hashCode() : 0); - return hash; + @Override + public void setParent(MutableTreeNode mtn) { + parent = mtn; + } + + + /** + * Test for equality. To be equal, two {@link VariableNode}s need to have + * equal type, name and value. + * + * @param obj the object to test for equality with this {@link VariableNode} + * @return true if the given object is equal to this {@link VariableNode} + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final VariableNode other = (VariableNode) obj; + if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) { + //System.out.println("type not equal"); + return false; + } + if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { + //System.out.println("name not equal"); + return false; + } + if (this.value != other.value && (this.value == null || !this.value.equals(other.value))) { + //System.out.println("value not equal"); + return false; } + return true; + } + + + /** + * Returns a hash code based on type, name and value. + */ + @Override + public int hashCode() { + int hash = 3; + hash = 97 * hash + (this.type != null ? this.type.hashCode() : 0); + hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0); + hash = 97 * hash + (this.value != null ? this.value.hashCode() : 0); + return hash; + } } From 6268f6c36d2a3f61749f3791b1f922890c06e28c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 9 Nov 2016 21:20:51 -0500 Subject: [PATCH 118/917] remove other logging references --- java/src/processing/mode/java/JavaEditor.java | 16 +++++++--------- java/src/processing/mode/java/JavaMode.java | 9 +++------ .../processing/mode/java/VariableInspector.java | 16 +++++----------- 3 files changed, 15 insertions(+), 26 deletions(-) diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 202f2c19a6..40814d83d5 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -9,8 +9,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.*; import javax.swing.border.*; @@ -220,7 +218,7 @@ public void actionPerformed(ActionEvent e) { stopItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (isDebuggerEnabled()) { - Logger.getLogger(JavaEditor.class.getName()).log(Level.INFO, "Invoked 'Stop' menu item"); + Messages.log("Invoked 'Stop' menu item"); debugger.stopDebug(); } else { handleStop(); @@ -1144,22 +1142,22 @@ public void handleStop() { public void handleStep(int modifiers) { if (modifiers == 0) { - Logger.getLogger(getClass().getName()).log(Level.INFO, "Invoked 'Step Over' menu item"); + Messages.log("Invoked 'Step Over' menu item"); debugger.stepOver(); } else if ((modifiers & ActionEvent.SHIFT_MASK) != 0) { - Logger.getLogger(getClass().getName()).log(Level.INFO, "Invoked 'Step Into' menu item"); + Messages.log("Invoked 'Step Into' menu item"); debugger.stepInto(); } else if ((modifiers & ActionEvent.ALT_MASK) != 0) { - Logger.getLogger(getClass().getName()).log(Level.INFO, "Invoked 'Step Out' menu item"); + Messages.log("Invoked 'Step Out' menu item"); debugger.stepOut(); } } public void handleContinue() { - Logger.getLogger(JavaEditor.class.getName()).log(Level.INFO, "Invoked 'Continue' menu item"); + Messages.log("Invoked 'Continue' menu item"); debugger.continueDebug(); } @@ -1399,7 +1397,7 @@ public void actionPerformed(ActionEvent e) { Toolkit.newJMenuItem(Language.text("menu.debug.toggle_breakpoint"), 'B'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - Logger.getLogger(JavaEditor.class.getName()).log(Level.INFO, "Invoked 'Toggle Breakpoint' menu item"); + Messages.log("Invoked 'Toggle Breakpoint' menu item"); // TODO wouldn't getCaretLine() do the same thing with less effort? toggleBreakpoint(getCurrentLineID().lineIdx()); } @@ -1603,7 +1601,7 @@ protected void addBreakpointComments(String tabFilename) { tab.setProgram(code); tab.save(); } catch (IOException ex) { - Logger.getLogger(JavaEditor.class.getName()).log(Level.SEVERE, null, ex); + Messages.loge(null, ex); } } diff --git a/java/src/processing/mode/java/JavaMode.java b/java/src/processing/mode/java/JavaMode.java index 365fa3e6de..58423decb7 100644 --- a/java/src/processing/mode/java/JavaMode.java +++ b/java/src/processing/mode/java/JavaMode.java @@ -30,10 +30,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.logging.FileHandler; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.SwingUtilities; @@ -56,7 +52,7 @@ public Editor createEditor(Base base, String path, public JavaMode(Base base, File folder) { super(base, folder); - initLogger(); +// initLogger(); loadPreferences(); } @@ -263,7 +259,7 @@ public String getSearchPath() { // Merged from ExperimentalMode - + /* void initLogger() { final boolean VERBOSE_LOGGING = true; final int LOG_SIZE = 512 * 1024; // max log file size (in bytes) @@ -293,6 +289,7 @@ void initLogger() { Logger.getLogger(JavaMode.class.getName()).log(Level.SEVERE, null, ex); } } + */ //ImageIcon classIcon, fieldIcon, methodIcon, localVarIcon; diff --git a/java/src/processing/mode/java/VariableInspector.java b/java/src/processing/mode/java/VariableInspector.java index e9e30a4e73..f0cdde4f6d 100644 --- a/java/src/processing/mode/java/VariableInspector.java +++ b/java/src/processing/mode/java/VariableInspector.java @@ -26,8 +26,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.*; import javax.swing.event.TreeExpansionEvent; @@ -40,17 +38,12 @@ import com.sun.jdi.Value; import processing.app.Language; +import processing.app.Messages; import processing.app.Mode; import processing.mode.java.debug.VariableNode; public class VariableInspector extends JDialog { -// static public final int GAP = 13; - -// EditorButton continueButton; -// EditorButton stepButton; -// EditorButton breakpointButton; - // The tray will be placed at this amount from the top of the editor window, // and extend to this amount from the bottom of the editor window. static final int VERTICAL_OFFSET = 64; @@ -441,11 +434,12 @@ public void setValueFor(Object o, int i, Object o1) { break; } } catch (NumberFormatException ex) { - Logger.getLogger(VariableRowModel.class.getName()).log(Level.INFO, "invalid value entered for {0}: {1}", new Object[]{var.getName(), stringValue}); + Messages.log(getClass().getName() + " invalid value entered for " + + var.getName() + " -> " + stringValue); } if (value != null) { var.setValue(value); - Logger.getLogger(VariableRowModel.class.getName()).log(Level.INFO, "new value set: {0}", var.getStringValue()); + Messages.log(getClass().getName() + " new value set: " + var.getStringValue()); } } @@ -483,7 +477,7 @@ private ImageIcon[][] loadIcons(String fileName) { Mode mode = editor.getMode(); File file = mode.getContentFile(fileName); if (!file.exists()) { - Logger.getLogger(OutlineRenderer.class.getName()).log(Level.SEVERE, "icon file not found: {0}", file.getAbsolutePath()); + Messages.log(getClass().getName(), "icon file not found: " + file.getAbsolutePath()); return null; } Image allIcons = mode.loadImage(fileName); From d491e3e05de6d189a1dc4f51e05e169f0357e212 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 9 Nov 2016 21:25:28 -0500 Subject: [PATCH 119/917] remove old debug folder, other cleanups --- app/src/processing/app/Base.java | 8 ++++++-- build/build.xml | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 4bb8668def..d112849013 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -142,8 +142,12 @@ static private void createAndShowGUI(String[] args) { // Set the debug flag based on a file being present in the settings folder File debugFile = getSettingsFile("debug"); - // if it's a directory, it's a leftover from older releases - DEBUG = debugFile.exists() && !debugFile.isDirectory(); + if (debugFile.isDirectory()) { + // if it's a directory, it's a leftover from older releases, clear it + Util.removeDir(debugFile); + } else if (debugFile.exists()) { + DEBUG = true; + } // Use native popups so they don't look so crappy on OS X JPopupMenu.setDefaultLightWeightPopupEnabled(false); diff --git a/build/build.xml b/build/build.xml index 7238516e44..adc15e6581 100644 --- a/build/build.xml +++ b/build/build.xml @@ -387,7 +387,7 @@ - + Date: Wed, 9 Nov 2016 21:38:56 -0500 Subject: [PATCH 120/917] notes about recent changes --- todo.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/todo.txt b/todo.txt index 5114684789..584f7059bd 100755 --- a/todo.txt +++ b/todo.txt @@ -7,6 +7,9 @@ X No sketch window opens after hitting Run if hosts file changed X https://github.com/processing/processing/issues/1868 X https://github.com/processing/processing/issues/3123 X https://github.com/processing/processing/issues/4735 +X move the DEBUG flag into an external file or preferences.txt +X will help us with debugging w/ others as well +X replace java.util.logging code with built-in logging _ Export Application fails on machines w/ non-ASCII chars in user name @@ -14,9 +17,6 @@ _ at least give a warning about this? _ https://github.com/processing/processing/issues/4736 _ related: https://github.com/processing/processing/issues/3543 -_ move the DEBUG flag into an external file or preferences.txt -_ will help us with debugging w/ others as well - _ fix appbundler problems due to rollback _ https://github.com/processing/processing/issues/3790 _ the rollback re-introduces two bugs (serial export and scrolling) From 7ee23cf75457ab0b169d4e3ded678a7706875770 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 10 Nov 2016 03:15:11 -0500 Subject: [PATCH 121/917] a little organizing --- todo.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/todo.txt b/todo.txt index 584f7059bd..81ea7fda7d 100755 --- a/todo.txt +++ b/todo.txt @@ -10,6 +10,9 @@ X https://github.com/processing/processing/issues/4735 X move the DEBUG flag into an external file or preferences.txt X will help us with debugging w/ others as well X replace java.util.logging code with built-in logging +_ blank window on startup where the "welcome" screen should be +_ https://github.com/processing/processing/issues/3933 +_ this may be fixed (removed invokeLater() on startup), unconfirmed _ Export Application fails on machines w/ non-ASCII chars in user name @@ -29,9 +32,6 @@ _ https://bitbucket.org/infinitekind/appbundler _ settings() present and pixelDensity() is in setup(), nothing set/no error _ https://github.com/processing/processing/issues/4703 -_ 'version' should be x.y or x.y.z, not some extra long string -_ enforce this by disallowing spaces? on the import script? - _ Application Exports report as "Damaged" on macOS Sierra _ https://github.com/processing/processing/issues/4705 _ could provide script to un-quarrantine @@ -49,9 +49,6 @@ _ https://github.com/processing/processing/issues/1566 _ allow modes to specify their own base file name _ need to move "is this a sketch?" handling into Mode -_ blank window on startup where the "welcome" screen should be -_ https://github.com/processing/processing/issues/3933 - _ modify line number color when no lines extend that far? _ https://github.com/processing/processing/pull/4560 _ text gutter doesn't seem to be hidpi @@ -688,6 +685,8 @@ _ e.g. ocd is broken in 0125 because of method signature changes PDE / Manager +_ 'version' should be x.y or x.y.z, not some extra long string +_ enforce this by disallowing spaces? on the import script? _ Progress bar height on macOS is too thin _ https://github.com/processing/processing/issues/4734 _ proper error handling when downloading contribs listing From c1831717d9d0a20f3f34df8bab84c19c4e532163 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 10 Nov 2016 03:44:18 -0500 Subject: [PATCH 122/917] moving local fields to inline --- app/src/processing/app/contrib/ContributionTab.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app/src/processing/app/contrib/ContributionTab.java b/app/src/processing/app/contrib/ContributionTab.java index bf855ea9bd..447f0eb08d 100644 --- a/app/src/processing/app/contrib/ContributionTab.java +++ b/app/src/processing/app/contrib/ContributionTab.java @@ -344,22 +344,18 @@ protected void setFilterText(String filter) { class FilterField extends JTextField { - Icon searchIcon; - JButton removeFilter; List filters; - JLabel filterLabel; public FilterField () { super(""); - filterLabel = new JLabel("Filter"); + JLabel filterLabel = new JLabel("Filter"); filterLabel.setFont(Toolkit.getSansFont(14, Font.PLAIN)); filterLabel.setOpaque(false); setFont(Toolkit.getSansFont(14, Font.PLAIN)); - searchIcon = Toolkit.getLibIconX("manager/search"); - filterLabel.setIcon(searchIcon); - removeFilter = new JButton(Toolkit.getLibIconX("manager/remove")); + filterLabel.setIcon(Toolkit.getLibIconX("manager/search")); + JButton removeFilter = Toolkit.createIconButton("manager/remove"); removeFilter.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2)); removeFilter.setBorderPainted(false); removeFilter.setContentAreaFilled(false); From 592bbc8d72ba46968b9ab1d1d20634f6575040e9 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 10 Nov 2016 07:59:33 -0500 Subject: [PATCH 123/917] note the filter commits --- todo.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/todo.txt b/todo.txt index 81ea7fda7d..e83c4f6ecb 100755 --- a/todo.txt +++ b/todo.txt @@ -14,6 +14,9 @@ _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 _ this may be fixed (removed invokeLater() on startup), unconfirmed +contrib +X Added the remove filter feature +X https://github.com/processing/processing/pull/3890 _ Export Application fails on machines w/ non-ASCII chars in user name _ at least give a warning about this? @@ -106,6 +109,8 @@ _ patch to core classpath by Manindra? _ spacing of the updates number/circle in the lower right is off _ https://github.com/processing/processing/issues/4094 _ 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 From 7067a3391056204671496ed0c403d67f81462fad Mon Sep 17 00:00:00 2001 From: Suhaib Khan Date: Thu, 10 Nov 2016 21:45:02 +0530 Subject: [PATCH 124/917] Removing manually added keywords --- java/keywords.txt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/java/keywords.txt b/java/keywords.txt index ad9bcdb183..fb8da82ade 100644 --- a/java/keywords.txt +++ b/java/keywords.txt @@ -866,18 +866,9 @@ TableRow KEYWORD5 TableRow getFloat FUNCTION2 TableRow_getFloat_ getInt FUNCTION2 TableRow_getInt_ getString FUNCTION2 TableRow_getString_ -getLong FUNCTION2 TableRow_getLong_ -getDouble FUNCTION2 TableRow_getDouble_ setFloat FUNCTION2 TableRow_setFloat_ setInt FUNCTION2 TableRow_setInt_ setString FUNCTION2 TableRow_setString_ -setLong FUNCTION2 TableRow_setLong_ -setDouble FUNCTION2 TableRow_setDouble_ -getColumnCount FUNCTION2 TableRow_getColumnCount_ -getColumnType FUNCTION2 TableRow_getColumnType_ -getColumnTypes FUNCTION2 TableRow_getColumnTypes_ -getColumnTitle FUNCTION2 TableRow_getColumnTitle_ -getColumnTitles FUNCTION2 TableRow_getColumnTitles_ tan FUNCTION1 tan_ TAU LITERAL2 TAU text FUNCTION1 text_ From 177d26629036582a94799c32f0e2940483242f61 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 10 Nov 2016 11:57:22 -0500 Subject: [PATCH 125/917] add a note about #4333 --- core/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index b19f909c63..7c9fe89999 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,5 +1,8 @@ 0256 (3.2.4 or 3.3) +contribs +X Adding missing docs and keywords for TableRow +X https://github.com/processing/processing/pull/4333 _ add StringDict.Entry class for iterating From e5b2182533fd57a487c8f6849d754260d8409f10 Mon Sep 17 00:00:00 2001 From: REAS Date: Thu, 10 Nov 2016 10:39:47 -0800 Subject: [PATCH 126/917] Removing TableRow methods from Web Reference, but keeping the data for the JavaDoc --- core/src/processing/data/TableRow.java | 35 ++++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/core/src/processing/data/TableRow.java b/core/src/processing/data/TableRow.java index 0eed565613..75e348d873 100644 --- a/core/src/processing/data/TableRow.java +++ b/core/src/processing/data/TableRow.java @@ -21,6 +21,7 @@ public interface TableRow { * @see TableRow#getFloat(int) */ public String getString(int column); + /** * @param columnName title of the column to reference */ @@ -34,19 +35,22 @@ public interface TableRow { * @see TableRow#getString(int) */ public int getInt(int column); + /** * @param columnName title of the column to reference */ public int getInt(String columnName); + /** - * @webref tablerow:method * @brief Get a long value from the specified column * @param column ID number of the column to reference * @see TableRow#getFloat(int) * @see TableRow#getString(int) */ + public long getLong(int column); - /** + + /** * @param columnName title of the column to reference */ public long getLong(String columnName); @@ -59,18 +63,20 @@ public interface TableRow { * @see TableRow#getString(int) */ public float getFloat(int column); + /** * @param columnName title of the column to reference */ public float getFloat(String columnName); - /** - * @webref tablerow:method + + /** * @brief Get a double value from the specified column * @param column ID number of the column to reference * @see TableRow#getInt(int) * @see TableRow#getString(int) */ public double getDouble(int column); + /** * @param columnName title of the column to reference */ @@ -99,12 +105,13 @@ public interface TableRow { * @see TableRow#setString(int, String) */ public void setInt(int column, int value); + /** * @param columnName title of the target column */ public void setInt(String columnName, int value); - /** - * @webref tablerow:method + + /** * @brief Store a long value in the specified column * @param column ID number of the target column * @param value value to assign @@ -112,6 +119,7 @@ public interface TableRow { * @see TableRow#setString(int, String) */ public void setLong(int column, long value); + /** * @param columnName title of the target column */ @@ -126,12 +134,13 @@ public interface TableRow { * @see TableRow#setString(int, String) */ public void setFloat(int column, float value); + /** * @param columnName title of the target column */ public void setFloat(String columnName, float value); - /** - * @webref tablerow:method + + /** * @brief Store a double value in the specified column * @param column ID number of the target column * @param value value to assign @@ -139,33 +148,37 @@ public interface TableRow { * @see TableRow#setString(int, String) */ public void setDouble(int column, double value); + /** * @param columnName title of the target column */ public void setDouble(String columnName, double value); + /** * @webref tablerow:method * @brief Get the column count. * @return count of all columns */ public int getColumnCount(); + /** - * @webref tablerow:method * @brief Get the column type. * @param columnName title of the target column * @return type of the column */ public int getColumnType(String columnName); + /** * @param column ID number of the target column */ public int getColumnType(int column); + /** - * @webref tablerow:method * @brief Get the all column types. * @return list of all column types */ public int[] getColumnTypes(); + /** * @webref tablerow:method * @brief Get the column title. @@ -173,8 +186,8 @@ public interface TableRow { * @return title of the column */ public String getColumnTitle(int column); + /** - * @webref tablerow:method * @brief Get the all column titles. * @return list of all column titles */ From 39421747200aad1a201387f5296da8d503598f07 Mon Sep 17 00:00:00 2001 From: REAS Date: Thu, 10 Nov 2016 13:40:00 -0800 Subject: [PATCH 127/917] Remove periods (.) from @brief descriptions in TableRow.java --- core/src/processing/data/TableRow.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/processing/data/TableRow.java b/core/src/processing/data/TableRow.java index 75e348d873..3ac59fe4c8 100644 --- a/core/src/processing/data/TableRow.java +++ b/core/src/processing/data/TableRow.java @@ -174,7 +174,7 @@ public interface TableRow { public int getColumnType(int column); /** - * @brief Get the all column types. + * @brief Get the all column types * @return list of all column types */ public int[] getColumnTypes(); @@ -188,7 +188,7 @@ public interface TableRow { public String getColumnTitle(int column); /** - * @brief Get the all column titles. + * @brief Get the all column titles * @return list of all column titles */ public String[] getColumnTitles(); From 8426f034d5375e8f30cb7b2bb308a75264cde747 Mon Sep 17 00:00:00 2001 From: REAS Date: Thu, 10 Nov 2016 14:59:59 -0800 Subject: [PATCH 128/917] Fresh keywords from Reference updates/additions --- java/keywords.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/java/keywords.txt b/java/keywords.txt index fb8da82ade..a59b071766 100644 --- a/java/keywords.txt +++ b/java/keywords.txt @@ -315,6 +315,14 @@ substring FUNCTION2 String_substring_ toLowerCase FUNCTION2 String_toLowerCase_ toUpperCase FUNCTION2 String_toUpperCase_ +getDouble FUNCTION2 +getLong FUNCTION2 +getColumnTitles FUNCTION2 +getColumnTypes FUNCTION2 +getColumnType FUNCTION2 +setDouble FUNCTION2 +setLong FUNCTION2 + length KEYWORD2 String @@ -441,6 +449,7 @@ curveTightness FUNCTION1 curveTightness_ curveVertex FUNCTION1 curveVertex_ day FUNCTION1 day_ degrees FUNCTION1 degrees_ +delay FUNCTION1 delay_ directionalLight FUNCTION1 directionalLight_ displayDensity FUNCTION1 displayDensity_ displayHeight KEYWORD4 displayHeight @@ -565,6 +574,7 @@ getJSONArray FUNCTION2 JSONArray_getJSONArray_ getJSONObject FUNCTION2 JSONArray_getJSONObject_ getString FUNCTION2 JSONArray_getString_ getStringArray FUNCTION2 JSONArray_getStringArray_ +isNull FUNCTION2 JSONArray_isNull_ remove FUNCTION2 JSONArray_remove_ setBoolean FUNCTION2 JSONArray_setBoolean_ setFloat FUNCTION2 JSONArray_setFloat_ @@ -580,6 +590,7 @@ getInt FUNCTION2 JSONObject_getInt_ getJSONArray FUNCTION2 JSONObject_getJSONArray_ getJSONObject FUNCTION2 JSONObject_getJSONObject_ getString FUNCTION2 JSONObject_getString_ +isNull FUNCTION2 JSONObject_isNull_ setBoolean FUNCTION2 JSONObject_setBoolean_ setFloat FUNCTION2 JSONObject_setFloat_ setInt FUNCTION2 JSONObject_setInt_ @@ -863,6 +874,8 @@ setInt FUNCTION2 Table_setInt_ setString FUNCTION2 Table_setString_ trim FUNCTION2 Table_trim_ TableRow KEYWORD5 TableRow +getColumnCount FUNCTION2 TableRow_getColumnCount_ +getColumnTitle FUNCTION2 TableRow_getColumnTitle_ getFloat FUNCTION2 TableRow_getFloat_ getInt FUNCTION2 TableRow_getInt_ getString FUNCTION2 TableRow_getString_ From cf5e6b313587e20564a2098c859f6f6c5ec523ca Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 10 Nov 2016 18:21:23 -0500 Subject: [PATCH 129/917] write docs for exec() (fixes #4740) --- core/src/processing/core/PApplet.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 1f5790b79e..e093e3a948 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -3482,6 +3482,27 @@ static public Process launch(String... args) { } + /** + * Pass a set of arguments directly to the command line. Uses Java's + * Runtime.exec() + * method. This is different from the launch() + * method, which uses the operating system's launcher to open the files. + * It's always a good idea to use a full path to the executable here. + *
+   * exec("/usr/bin/say", "-v", "Pipe Organ", "welcome to the command line");
+   * 
+ * Or if you want to wait until it's completed, something like this: + *
+   * Process p = exec("/usr/bin/say", "waiting until done");
+   * try {
+   *   int result = p.waitFor();
+   *   println("the process returned " + result);
+   * } catch (InterruptedException e) { }
+   * 
+ * You can also get the system output and error streams from the Process + * object, but that's more that we'd like to cover here. + * @return a Process object + */ static public Process exec(String... args) { try { return Runtime.getRuntime().exec(args); From 3d7988cb5c51f6ff1d41738ac1b5d53bf8b41b99 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 10 Nov 2016 18:29:20 -0500 Subject: [PATCH 130/917] note about the docs --- core/todo.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index 7c9fe89999..66f63e15e8 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,4 +1,6 @@ 0256 (3.2.4 or 3.3) +X write exec() documentation +X https://github.com/processing/processing/issues/4740 contribs X Adding missing docs and keywords for TableRow From 8ae2a69071606d4dbe582675d18a779e0930bf52 Mon Sep 17 00:00:00 2001 From: REAS Date: Thu, 10 Nov 2016 15:32:51 -0800 Subject: [PATCH 131/917] Parameter descriptions for saveJSONArray and saveJSONObject --- core/src/processing/core/PApplet.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index e093e3a948..a290f4c9ad 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -5936,6 +5936,8 @@ static public JSONObject loadJSONObject(File file) { /** * @webref output:files + * @param json the JSONObject to save + * @param filename the name of the file to save to * @see JSONObject * @see JSONArray * @see PApplet#loadJSONObject(String) @@ -5947,7 +5949,7 @@ public boolean saveJSONObject(JSONObject json, String filename) { } /** - * @nowebref + * @param options "compact" and "indent=N", replace N with the number of spaces */ public boolean saveJSONObject(JSONObject json, String filename, String options) { return json.save(saveFile(filename), options); @@ -5985,6 +5987,8 @@ static public JSONArray loadJSONArray(File file) { /** * @webref output:files + * @param json the JSONArray to save + * @param filename the name of the file to save to * @see JSONObject * @see JSONArray * @see PApplet#loadJSONObject(String) @@ -5995,7 +5999,9 @@ public boolean saveJSONArray(JSONArray json, String filename) { return saveJSONArray(json, filename, null); } - + /** + * @param options "compact" and "indent=N", replace N with the number of spaces + */ public boolean saveJSONArray(JSONArray json, String filename, String options) { return json.save(saveFile(filename), options); } From 41e9d33d592fd847b77f2b241e40981dc63cd4d3 Mon Sep 17 00:00:00 2001 From: REAS Date: Thu, 10 Nov 2016 20:51:48 -0800 Subject: [PATCH 132/917] Attempt to correct reference for nfc() --- core/src/processing/core/PApplet.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index a290f4c9ad..30e2d6c012 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -9588,7 +9588,6 @@ static public String nf(float num, int left, int right) { } /** - * @param num[] the number(s) to format * @param right number of digits to the right of the decimal point */ static public String[] nfc(float num[], int right) { From 179eb30ae7a8b893887e5fc9c4381a913e0b9a75 Mon Sep 17 00:00:00 2001 From: REAS Date: Thu, 10 Nov 2016 21:55:37 -0800 Subject: [PATCH 133/917] Add reference info for sort() method for Table class --- core/src/processing/data/Table.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index 4f6ede76cb..17aab1245f 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -4214,12 +4214,21 @@ void read(DataInputStream input) throws IOException { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - + /** + * Sorts (orders) a table based on the values in a column. + * + * @webref table:method + * @brief Orders a table based on the values in a column + * @param columnName the name of the column to sort + * @see Table#trim() + */ public void sort(String columnName) { sort(getColumnIndex(columnName), false); } - + /** + * @param column the column ID, e.g. 0, 1, 2 + */ public void sort(int column) { sort(column, false); } From e1c9a5e0828854a388fb14e57556cf52cf64b7d6 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 11 Nov 2016 06:11:56 -0500 Subject: [PATCH 134/917] remove debug information, oops --- 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 e093e3a948..7905f688f2 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -1194,7 +1194,7 @@ static public int displayDensity(int display) { * */ public void pixelDensity(int density) { - println(density + " " + this.pixelDensity); + //println(density + " " + this.pixelDensity); if (density != this.pixelDensity) { if (insideSettings("pixelDensity", density)) { if (density != 1 && density != 2) { From dc36abb52767c7e6f300cf2670b3cb711a0f1d79 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 14 Nov 2016 20:29:38 -0500 Subject: [PATCH 135/917] add listPaths(), listFiles() (fixes #4622) --- core/src/processing/core/PApplet.java | 131 +++++++++++++++++++++++++- core/todo.txt | 8 +- 2 files changed, 133 insertions(+), 6 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 8b2d9cd91b..fe94c6f418 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -5949,7 +5949,7 @@ public boolean saveJSONObject(JSONObject json, String filename) { } /** - * @param options "compact" and "indent=N", replace N with the number of spaces + * @param options "compact" and "indent=N", replace N with the number of spaces */ public boolean saveJSONObject(JSONObject json, String filename, String options) { return json.save(saveFile(filename), options); @@ -6000,7 +6000,7 @@ public boolean saveJSONArray(JSONArray json, String filename) { } /** - * @param options "compact" and "indent=N", replace N with the number of spaces + * @param options "compact" and "indent=N", replace N with the number of spaces */ public boolean saveJSONArray(JSONArray json, String filename, String options) { return json.save(saveFile(filename), options); @@ -6529,6 +6529,133 @@ static private void selectCallback(File selectedFile, + ////////////////////////////////////////////////////////////// + + // LISTING DIRECTORIES + + + public String[] listPaths(String path, String... options) { + File[] list = listFiles(path, options); + + int offset = 0; + for (String opt : options) { + if (opt.equals("relative")) { + if (!path.endsWith(File.pathSeparator)) { + path += File.pathSeparator; + } + offset = path.length(); + break; + } + } + String[] outgoing = new String[list.length]; + for (int i = 0; i < list.length; i++) { + // as of Java 1.8, substring(0) returns the original object + outgoing[i] = list[i].getAbsolutePath().substring(offset); + } + return outgoing; + } + + + public File[] listFiles(String path, String... options) { + File file = new File(path); + // if not an absolute path, make it relative to the sketch folder + if (!file.isAbsolute()) { + file = sketchFile(path); + } + return listFiles(file, options); + } + + + // "relative" -> no effect with the Files version, but important for listPaths + // "recursive" + // "extension=js" or "extensions=js|csv|txt" (no dot) + // "directories" -> only directories + // "files" -> only files + // "hidden" -> include hidden files (prefixed with .) disabled by default + static public File[] listFiles(File base, String... options) { + boolean recursive = false; + String[] extensions = null; + boolean directories = true; + boolean files = true; + boolean hidden = false; + + for (String opt : options) { + if (opt.equals("recursive")) { + recursive = true; + } else if (opt.startsWith("extension=")) { + extensions = new String[] { opt.substring(10) }; + } else if (opt.startsWith("extensions=")) { + extensions = split(opt.substring(10), ','); + } else if (opt.equals("files")) { + directories = false; + } else if (opt.equals("directories")) { + files = false; + } else if (opt.equals("hidden")) { + hidden = true; + } else if (opt.equals("relative")) { + // ignored + } else { + throw new RuntimeException(opt + " is not a listFiles() option"); + } + } + + if (extensions != null) { + for (int i = 0; i < extensions.length; i++) { + extensions[i] = "." + extensions[i]; + } + } + + if (!files && !directories) { + // just make "only files" and "only directories" mean... both + files = true; + directories = true; + } + + if (!base.canRead()) { + return null; + } + + List outgoing = new ArrayList<>(); + listFilesImpl(base, recursive, extensions, hidden, directories, files, outgoing); + return outgoing.toArray(new File[0]); + } + + + static void listFilesImpl(File folder, boolean recursive, + String[] extensions, boolean hidden, + boolean directories, boolean files, + List list) { + File[] items = folder.listFiles(); + if (items != null) { + for (File item : items) { + String name = item.getName(); + if (!hidden && name.charAt(0) == '.') { + continue; + } + if (item.isDirectory()) { + if (recursive) { + listFilesImpl(item, recursive, extensions, hidden, directories, files, list); + } + if (directories) { + list.add(item); + } + } else if (files) { + if (extensions == null) { + list.add(item); + } else { + for (String ext : extensions) { + if (item.getName().toLowerCase().endsWith(ext)) { + list.add(item); + } + } + } + } + } + } + } + + + ////////////////////////////////////////////////////////////// // EXTENSIONS diff --git a/core/todo.txt b/core/todo.txt index 66f63e15e8..913d1798f6 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,11 +1,15 @@ 0256 (3.2.4 or 3.3) X write exec() documentation X https://github.com/processing/processing/issues/4740 +X add listPaths(), listFiles() +X https://github.com/processing/processing/issues/4622 +_ needs documentation contribs X Adding missing docs and keywords for TableRow X https://github.com/processing/processing/pull/4333 +_ add increment() that takes IntDict to merge things _ add StringDict.Entry class for iterating _ TRIANGLE_STRIP not working correctly with createShape() and default renderer @@ -14,10 +18,6 @@ _ https://github.com/processing/processing/issues/4678 _ should we drop the 'default' prefix from the ex handler so it's not static? _ http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html -_ listPaths(), listFiles()? -_ https://github.com/processing/processing/issues/4622 -_ add increment() that takes IntDict to merge things - _ option to disable OpenGL ES on Linux? _ https://github.com/processing/processing/issues/4584 From 22de0d1d3ed9285d9a79f9bdbbd94d1f644be8cf Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 14 Nov 2016 20:37:16 -0500 Subject: [PATCH 136/917] add increment() method that takes IntDict to merge another dictionary --- core/src/processing/data/IntDict.java | 12 ++++++++++++ core/todo.txt | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/core/src/processing/data/IntDict.java b/core/src/processing/data/IntDict.java index 1f21b4b3f6..accdf73937 100644 --- a/core/src/processing/data/IntDict.java +++ b/core/src/processing/data/IntDict.java @@ -319,6 +319,18 @@ public void increment(String key) { } + /** + * Merge another dictionary into this one. Calling this increment() + * since it doesn't make sense in practice for the other dictionary types, + * even though it's technically an add(). + */ + public void increment(IntDict dict) { + for (int i = 0; i < dict.count; i++) { + add(dict.key(i), dict.value(i)); + } + } + + /** * @webref intdict:method * @brief Add to a value diff --git a/core/todo.txt b/core/todo.txt index 913d1798f6..91b76b8616 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -4,12 +4,14 @@ X https://github.com/processing/processing/issues/4740 X add listPaths(), listFiles() X https://github.com/processing/processing/issues/4622 _ needs documentation +X add increment() method that takes IntDict to merge another dictionary +X Calling this increment() since it doesn't make sense in practice for +X the other dictionary types, even though it's technically an add() contribs X Adding missing docs and keywords for TableRow X https://github.com/processing/processing/pull/4333 -_ add increment() that takes IntDict to merge things _ add StringDict.Entry class for iterating _ TRIANGLE_STRIP not working correctly with createShape() and default renderer From 616df818b6aa012f0ad27c4d2f4a8e409acbf5a4 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 14 Nov 2016 20:38:17 -0500 Subject: [PATCH 137/917] wish list --- core/todo.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/core/todo.txt b/core/todo.txt index 91b76b8616..60f91f8171 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -39,6 +39,7 @@ _ how to handle the touch api _ figure our size(img.width, img.height) situation X just make loadImage() work in settings _ update the wiki and reference +_ size() function that scales to screen, keeps aspect, re-scales mouse coords known From 6b8e56fdda4363ae8d680aa456863053e454f478 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 14 Nov 2016 21:27:21 -0500 Subject: [PATCH 138/917] add suport for iterating over dictionary entries, cleaning up todo list --- core/src/processing/data/FloatDict.java | 49 ++++++++++++++++++++++++ core/src/processing/data/IntDict.java | 49 ++++++++++++++++++++++++ core/src/processing/data/StringDict.java | 49 ++++++++++++++++++++++++ core/todo.txt | 11 ++---- 4 files changed, 150 insertions(+), 8 deletions(-) diff --git a/core/src/processing/data/FloatDict.java b/core/src/processing/data/FloatDict.java index 5c01e3d208..81bbd99a60 100644 --- a/core/src/processing/data/FloatDict.java +++ b/core/src/processing/data/FloatDict.java @@ -127,6 +127,55 @@ public void clear() { } + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + public class Entry { + public String key; + public float value; + + Entry(String key, float value) { + this.key = key; + this.value = value; + } + } + + + public Iterable entries() { + return new Iterable() { + + public Iterator iterator() { + return entryIterator(); + } + }; + } + + + public Iterator entryIterator() { + return new Iterator() { + int index = -1; + + public void remove() { + removeIndex(index); + index--; + } + + public Entry next() { + Entry e = new Entry(keys[index], values[index]); + index++; + return e; + } + + public boolean hasNext() { + return index+1 < size(); + } + }; + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + public String key(int index) { return keys[index]; } diff --git a/core/src/processing/data/IntDict.java b/core/src/processing/data/IntDict.java index accdf73937..57d045d4cd 100644 --- a/core/src/processing/data/IntDict.java +++ b/core/src/processing/data/IntDict.java @@ -128,6 +128,55 @@ public void clear() { } + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + public class Entry { + public String key; + public int value; + + Entry(String key, int value) { + this.key = key; + this.value = value; + } + } + + + public Iterable entries() { + return new Iterable() { + + public Iterator iterator() { + return entryIterator(); + } + }; + } + + + public Iterator entryIterator() { + return new Iterator() { + int index = -1; + + public void remove() { + removeIndex(index); + index--; + } + + public Entry next() { + Entry e = new Entry(keys[index], values[index]); + index++; + return e; + } + + public boolean hasNext() { + return index+1 < size(); + } + }; + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + public String key(int index) { return keys[index]; } diff --git a/core/src/processing/data/StringDict.java b/core/src/processing/data/StringDict.java index 5231c44d43..3768f69537 100644 --- a/core/src/processing/data/StringDict.java +++ b/core/src/processing/data/StringDict.java @@ -129,6 +129,55 @@ public void clear() { } + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + public class Entry { + public String key; + public String value; + + Entry(String key, String value) { + this.key = key; + this.value = value; + } + } + + + public Iterable entries() { + return new Iterable() { + + public Iterator iterator() { + return entryIterator(); + } + }; + } + + + public Iterator entryIterator() { + return new Iterator() { + int index = -1; + + public void remove() { + removeIndex(index); + index--; + } + + public Entry next() { + Entry e = new Entry(keys[index], values[index]); + index++; + return e; + } + + public boolean hasNext() { + return index+1 < size(); + } + }; + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + public String key(int index) { return keys[index]; } diff --git a/core/todo.txt b/core/todo.txt index 60f91f8171..0f7c8f2e19 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,18 +1,19 @@ 0256 (3.2.4 or 3.3) X write exec() documentation X https://github.com/processing/processing/issues/4740 + +api additions X add listPaths(), listFiles() X https://github.com/processing/processing/issues/4622 -_ needs documentation X add increment() method that takes IntDict to merge another dictionary X Calling this increment() since it doesn't make sense in practice for X the other dictionary types, even though it's technically an add() +X add Entry class for iterating StringDict, IntDict, FloatDict contribs X Adding missing docs and keywords for TableRow X https://github.com/processing/processing/pull/4333 -_ add StringDict.Entry class for iterating _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 @@ -109,7 +110,6 @@ _ https://www.linkedin.com/pulse/oracle-just-removed-javafx-support-arm-jan-sn opengl questions -_ hard crash at 1920x1080, mirrored, Casey's GT 650M 1GB _ exitCalled() and exitActual made public by Andres, breaks Python _ also not API we want to expose, so sort this out _ or maybe we're fine b/c now FX2D needs it as well @@ -191,11 +191,6 @@ _ at least with the Java2D renderer _ don't override the window icon w/ p5 logo if already set -retina/hidpi -_ no high-dpi support for core on Windows -_ https://github.com/processing/processing/issues/2411 - - decisions/misc _ Separately, if we wanted, we could add a method that can safely do drawing calls, but that won't be any faster or make use of more processors the way that `thread()` does. _ need reference update for createShape() From 1ae78116c115c76dc15c8ea821549eaa6f728235 Mon Sep 17 00:00:00 2001 From: REAS Date: Tue, 15 Nov 2016 11:28:51 -0800 Subject: [PATCH 139/917] Attempt to separate number formatting parameters into arrays (nums) and primitive data (num) --- core/src/processing/core/PApplet.java | 139 ++++++++++++++++---------- 1 file changed, 84 insertions(+), 55 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index fe94c6f418..e6a48e8433 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -9502,14 +9502,6 @@ static public String[] nf(float[] num) { static private int int_nf_digits; static private boolean int_nf_commas; - static public String[] nf(int num[], int digits) { - String formatted[] = new String[num.length]; - for (int i = 0; i < formatted.length; i++) { - formatted[i] = nf(num[i], digits); - } - return formatted; - } - /** * ( begin auto-generated from nf.xml ) * @@ -9525,13 +9517,25 @@ static public String[] nf(int num[], int digits) { * * ( end auto-generated ) * @webref data:string_functions - * @param num the number(s) to format + * @param nums the numbers to format * @param digits number of digits to pad with zero * @see PApplet#nfs(float, int, int) * @see PApplet#nfp(float, int, int) * @see PApplet#nfc(float, int) * @see int(float) */ + static public String[] nf(int nums[], int digits) { + String formatted[] = new String[nums.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nf(nums[i], digits); + } + return formatted; + } + + /** + * @param num the number to format + * @param digits number of digits to pad with zero + */ static public String nf(int num, int digits) { if ((int_nf != null) && (int_nf_digits == digits) && @@ -9547,38 +9551,35 @@ static public String nf(int num, int digits) { return int_nf.format(num); } -/** + /** * ( begin auto-generated from nfc.xml ) * * Utility function for formatting numbers into strings and placing * appropriate commas to mark units of 1000. There are two versions, one * for formatting ints and one for formatting an array of ints. The value * for the digits parameter should always be a positive integer. - *

+ *

* For a non-US locale, this will insert periods instead of commas, or * whatever is apprioriate for that region. * * ( end auto-generated ) - * @webref data:string_functions - * @param num the number(s) to format - * @see PApplet#nf(float, int, int) - * @see PApplet#nfp(float, int, int) - * @see PApplet#nfs(float, int, int) - */ - static public String[] nfc(int num[]) { - String formatted[] = new String[num.length]; + * @webref data:string_functions + * @param nums the numbers to format + * @see PApplet#nf(float, int, int) + * @see PApplet#nfp(float, int, int) + * @see PApplet#nfs(float, int, int) + */ + static public String[] nfc(int nums[]) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfc(num[i]); + formatted[i] = nfc(nums[i]); } return formatted; } /** - * nfc() or "number format with commas". This is an unfortunate misnomer - * because in locales where a comma is not the separator for numbers, it - * won't actually be outputting a comma, it'll use whatever makes sense for - * the locale. + * @param num the number to format */ static public String nfc(int num) { if ((int_nf != null) && @@ -9615,7 +9616,7 @@ static public String nfc(int num) { * * ( end auto-generated ) * @webref data:string_functions - * @param num the number(s) to format + * @param num the number to format * @param digits number of digits to pad with zeroes * @see PApplet#nf(float, int, int) * @see PApplet#nfp(float, int, int) @@ -9625,10 +9626,14 @@ static public String nfs(int num, int digits) { return (num < 0) ? nf(num, digits) : (' ' + nf(num, digits)); } - static public String[] nfs(int num[], int digits) { - String formatted[] = new String[num.length]; + /** + * @param nums the numbers to format + * @param digits number of digits to pad with zeroes + */ + static public String[] nfs(int nums[], int digits) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfs(num[i], digits); + formatted[i] = nfs(nums[i], digits); } return formatted; } @@ -9651,7 +9656,7 @@ static public String[] nfs(int num[], int digits) { * * ( end auto-generated ) * @webref data:string_functions - * @param num the number(s) to format + * @param num the number to format * @param digits number of digits to pad with zeroes * @see PApplet#nf(float, int, int) * @see PApplet#nfs(float, int, int) @@ -9660,11 +9665,14 @@ static public String[] nfs(int num[], int digits) { static public String nfp(int num, int digits) { return (num < 0) ? nf(num, digits) : ('+' + nf(num, digits)); } - - static public String[] nfp(int num[], int digits) { - String formatted[] = new String[num.length]; + /** + * @param nums the numbers to format + * @param digits number of digits to pad with zeroes + */ + static public String[] nfp(int nums[], int digits) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfp(num[i], digits); + formatted[i] = nfp(nums[i], digits); } return formatted; } @@ -9680,18 +9688,24 @@ static public String[] nfp(int num[], int digits) { static private int float_nf_left, float_nf_right; static private boolean float_nf_commas; - static public String[] nf(float num[], int left, int right) { - String formatted[] = new String[num.length]; + /** + * @param nums the numbers to format + * @param left number of digits to the left of the decimal point + * @param right number of digits to the right of the decimal point + */ + static public String[] nf(float nums[], int left, int right) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nf(num[i], left, right); + formatted[i] = nf(nums[i], left, right); } return formatted; } -/** - * @param num[] the number(s) to format - * @param left number of digits to the left of the decimal point - * @param right number of digits to the right of the decimal point - */ + + /** + * @param num the number to format + * @param left number of digits to the left of the decimal point + * @param right number of digits to the right of the decimal point + */ static public String nf(float num, int left, int right) { if ((float_nf != null) && (float_nf_left == left) && @@ -9714,18 +9728,22 @@ static public String nf(float num, int left, int right) { return float_nf.format(num); } -/** - * @param right number of digits to the right of the decimal point - */ - static public String[] nfc(float num[], int right) { - String formatted[] = new String[num.length]; + /** + * @param nums the numbers to format + * @param right number of digits to the right of the decimal point + */ + static public String[] nfc(float nums[], int right) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfc(num[i], right); + formatted[i] = nfc(nums[i], right); } return formatted; } - + /** + * @param num the number to format + * @param right number of digits to the right of the decimal point + */ static public String nfc(float num, int right) { if ((float_nf != null) && (float_nf_left == 0) && @@ -9749,34 +9767,45 @@ static public String nfc(float num, int right) { /** - * @param num[] the number(s) to format + * @param nums the numbers to format * @param left the number of digits to the left of the decimal point * @param right the number of digits to the right of the decimal point */ - static public String[] nfs(float num[], int left, int right) { - String formatted[] = new String[num.length]; + static public String[] nfs(float nums[], int left, int right) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfs(num[i], left, right); + formatted[i] = nfs(nums[i], left, right); } return formatted; } + /** + * @param num the number to format + * @param left the number of digits to the left of the decimal point + * @param right the number of digits to the right of the decimal point + */ static public String nfs(float num, int left, int right) { return (num < 0) ? nf(num, left, right) : (' ' + nf(num, left, right)); } /** + * @param nums the number to format * @param left the number of digits to the left of the decimal point * @param right the number of digits to the right of the decimal point */ - static public String[] nfp(float num[], int left, int right) { - String formatted[] = new String[num.length]; + static public String[] nfp(float nums[], int left, int right) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfp(num[i], left, right); + formatted[i] = nfp(nums[i], left, right); } return formatted; } + /** + * @param num the number to format + * @param left the number of digits to the left of the decimal point + * @param right the number of digits to the right of the decimal point + */ static public String nfp(float num, int left, int right) { return (num < 0) ? nf(num, left, right) : ('+' + nf(num, left, right)); } From e379c703ca56f89b6f4ca50efdfe72900ac00927 Mon Sep 17 00:00:00 2001 From: REAS Date: Tue, 15 Nov 2016 12:08:19 -0800 Subject: [PATCH 140/917] Working toward fixing reference for nf() --- core/src/processing/core/PApplet.java | 53 ++++++++++++--------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index e6a48e8433..fbf7b01a56 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -9476,28 +9476,6 @@ static final public String[] str(float x[]) { // INT NUMBER FORMATTING - - static public String nf(float num) { - int inum = (int) num; - if (num == inum) { - return str(inum); - } - return str(num); - } - - - static public String[] nf(float[] num) { - String[] outgoing = new String[num.length]; - for (int i = 0; i < num.length; i++) { - outgoing[i] = nf(num[i]); - } - return outgoing; - } - - - /** - * Integer number formatter. - */ static private NumberFormat int_nf; static private int int_nf_digits; static private boolean int_nf_commas; @@ -9517,13 +9495,34 @@ static public String[] nf(float[] num) { * * ( end auto-generated ) * @webref data:string_functions - * @param nums the numbers to format - * @param digits number of digits to pad with zero + * @param num the number to format * @see PApplet#nfs(float, int, int) * @see PApplet#nfp(float, int, int) * @see PApplet#nfc(float, int) * @see int(float) */ + static public String nf(float num) { + int inum = (int) num; + if (num == inum) { + return str(inum); + } + return str(num); + } + + /** + * @param nums the numbers to format + */ + static public String[] nf(int[] nums) { + String[] outgoing = new String[nums.length]; + for (int i = 0; i < nums.length; i++) { + outgoing[i] = nf(nums[i]); + } + return outgoing; + } + + /** + * @param digits number of digits to pad with zero + */ static public String[] nf(int nums[], int digits) { String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { @@ -9532,10 +9531,6 @@ static public String[] nf(int nums[], int digits) { return formatted; } - /** - * @param num the number to format - * @param digits number of digits to pad with zero - */ static public String nf(int num, int digits) { if ((int_nf != null) && (int_nf_digits == digits) && @@ -9703,8 +9698,6 @@ static public String[] nf(float nums[], int left, int right) { /** * @param num the number to format - * @param left number of digits to the left of the decimal point - * @param right number of digits to the right of the decimal point */ static public String nf(float num, int left, int right) { if ((float_nf != null) && From efc836915124dd1079a133e3ee4296955f40c91f Mon Sep 17 00:00:00 2001 From: REAS Date: Tue, 15 Nov 2016 12:12:12 -0800 Subject: [PATCH 141/917] Next step to correcting reference for nf() --- core/src/processing/core/PApplet.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index fbf7b01a56..05470bf67d 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -9684,7 +9684,6 @@ static public String[] nfp(int nums[], int digits) { static private boolean float_nf_commas; /** - * @param nums the numbers to format * @param left number of digits to the left of the decimal point * @param right number of digits to the right of the decimal point */ @@ -9696,9 +9695,6 @@ static public String[] nf(float nums[], int left, int right) { return formatted; } - /** - * @param num the number to format - */ static public String nf(float num, int left, int right) { if ((float_nf != null) && (float_nf_left == left) && From e8e2aed39306a8c586b7302007d559c81ce184ec Mon Sep 17 00:00:00 2001 From: REAS Date: Tue, 15 Nov 2016 12:25:43 -0800 Subject: [PATCH 142/917] Returning code at top of INT NUMBER FORMATTING to prior state --- core/src/processing/core/PApplet.java | 48 ++++++++++++++------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 05470bf67d..5f469833fc 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -9476,6 +9476,26 @@ static final public String[] str(float x[]) { // INT NUMBER FORMATTING + static public String nf(float num) { + int inum = (int) num; + if (num == inum) { + return str(inum); + } + return str(num); + } + + static public String[] nf(float[] nums) { + String[] outgoing = new String[nums.length]; + for (int i = 0; i < nums.length; i++) { + outgoing[i] = nf(nums[i]); + } + return outgoing; + } + + /** + * Integer number formatter. + */ + static private NumberFormat int_nf; static private int int_nf_digits; static private boolean int_nf_commas; @@ -9495,34 +9515,14 @@ static final public String[] str(float x[]) { * * ( end auto-generated ) * @webref data:string_functions - * @param num the number to format + * @param nums the numbers to format + * @param digits number of digits to pad with zero * @see PApplet#nfs(float, int, int) * @see PApplet#nfp(float, int, int) * @see PApplet#nfc(float, int) * @see int(float) */ - static public String nf(float num) { - int inum = (int) num; - if (num == inum) { - return str(inum); - } - return str(num); - } - - /** - * @param nums the numbers to format - */ - static public String[] nf(int[] nums) { - String[] outgoing = new String[nums.length]; - for (int i = 0; i < nums.length; i++) { - outgoing[i] = nf(nums[i]); - } - return outgoing; - } - /** - * @param digits number of digits to pad with zero - */ static public String[] nf(int nums[], int digits) { String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { @@ -9531,6 +9531,9 @@ static public String[] nf(int nums[], int digits) { return formatted; } + /** + * @param num the number to format + */ static public String nf(int num, int digits) { if ((int_nf != null) && (int_nf_digits == digits) && @@ -9678,7 +9681,6 @@ static public String[] nfp(int nums[], int digits) { // FLOAT NUMBER FORMATTING - static private NumberFormat float_nf; static private int float_nf_left, float_nf_right; static private boolean float_nf_commas; From 6a2ed252b3bb5574857ad2ff8fe52eca60abcdd9 Mon Sep 17 00:00:00 2001 From: REAS Date: Tue, 15 Nov 2016 13:15:49 -0800 Subject: [PATCH 143/917] More changes to PApplet to fix web reference for number formatting, but not yet fixing the JavaDoc --- core/src/processing/core/PApplet.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 5f469833fc..b0b72aad87 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -9626,7 +9626,6 @@ static public String nfs(int num, int digits) { /** * @param nums the numbers to format - * @param digits number of digits to pad with zeroes */ static public String[] nfs(int nums[], int digits) { String formatted[] = new String[nums.length]; @@ -9665,7 +9664,6 @@ static public String nfp(int num, int digits) { } /** * @param nums the numbers to format - * @param digits number of digits to pad with zeroes */ static public String[] nfp(int nums[], int digits) { String formatted[] = new String[nums.length]; @@ -9720,7 +9718,6 @@ static public String nf(float num, int left, int right) { } /** - * @param nums the numbers to format * @param right number of digits to the right of the decimal point */ static public String[] nfc(float nums[], int right) { @@ -9731,10 +9728,6 @@ static public String[] nfc(float nums[], int right) { return formatted; } - /** - * @param num the number to format - * @param right number of digits to the right of the decimal point - */ static public String nfc(float num, int right) { if ((float_nf != null) && (float_nf_left == 0) && @@ -9771,7 +9764,6 @@ static public String[] nfs(float nums[], int left, int right) { } /** - * @param num the number to format * @param left the number of digits to the left of the decimal point * @param right the number of digits to the right of the decimal point */ @@ -9780,7 +9772,6 @@ static public String nfs(float num, int left, int right) { } /** - * @param nums the number to format * @param left the number of digits to the left of the decimal point * @param right the number of digits to the right of the decimal point */ @@ -9792,11 +9783,6 @@ static public String[] nfp(float nums[], int left, int right) { return formatted; } - /** - * @param num the number to format - * @param left the number of digits to the left of the decimal point - * @param right the number of digits to the right of the decimal point - */ static public String nfp(float num, int left, int right) { return (num < 0) ? nf(num, left, right) : ('+' + nf(num, left, right)); } From e4265797e99af88d0968faa2fbe7e7c56bbe0e00 Mon Sep 17 00:00:00 2001 From: REAS Date: Tue, 15 Nov 2016 13:29:13 -0800 Subject: [PATCH 144/917] Fixes for nfs(), helps the Reference at the expense of the JavaDoc --- core/src/processing/core/PApplet.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index b0b72aad87..b10ac209cb 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -9751,7 +9751,6 @@ static public String nfc(float num, int right) { /** - * @param nums the numbers to format * @param left the number of digits to the left of the decimal point * @param right the number of digits to the right of the decimal point */ @@ -9763,10 +9762,6 @@ static public String[] nfs(float nums[], int left, int right) { return formatted; } - /** - * @param left the number of digits to the left of the decimal point - * @param right the number of digits to the right of the decimal point - */ static public String nfs(float num, int left, int right) { return (num < 0) ? nf(num, left, right) : (' ' + nf(num, left, right)); } From 4336026bfafd8ba043e6646746f9608952e4a686 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Wed, 16 Nov 2016 01:36:20 +0100 Subject: [PATCH 145/917] Fix nested type constructors raising error Replace non-capturing groups by positive lookahead and lookbehind, because they don't consume the source String and allow for first and last group to overlap when two constructors are directly nested. Fixes #4652 --- java/src/processing/mode/java/pdex/SourceUtils.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/java/src/processing/mode/java/pdex/SourceUtils.java b/java/src/processing/mode/java/pdex/SourceUtils.java index 66703b246d..8a1a206934 100644 --- a/java/src/processing/mode/java/pdex/SourceUtils.java +++ b/java/src/processing/mode/java/pdex/SourceUtils.java @@ -55,8 +55,12 @@ public static List parseProgramImports(CharSequence source, + // Positive lookahead and lookbehind are needed to match all type constructors + // in code like `int(byte(245))` where first bracket matches as last + // group in "^int(" but also as a first group in "(byte(". Lookahead and + // lookbehind won't consume the shared character. public static final Pattern TYPE_CONSTRUCTOR_REGEX = - Pattern.compile("(?:^|\\W)(int|char|float|boolean|byte)(?:\\s*\\()", + Pattern.compile("(?<=^|\\W)(int|char|float|boolean|byte)(?=\\s*\\()", Pattern.MULTILINE); public static List replaceTypeConstructors(CharSequence source) { From 7d723541f87e2e598d622d967849f7f45cf71ac1 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 16 Nov 2016 17:12:42 -0500 Subject: [PATCH 146/917] several XML fixes and adding print() --- core/src/processing/data/XML.java | 32 +++++++++++++++++++++++++++---- core/todo.txt | 18 +++++++++-------- todo.txt | 9 +++++++++ 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/core/src/processing/data/XML.java b/core/src/processing/data/XML.java index fbe6f3b673..12b35cdbd6 100644 --- a/core/src/processing/data/XML.java +++ b/core/src/processing/data/XML.java @@ -231,7 +231,18 @@ public XML(String name) { protected XML(XML parent, Node node) { this.node = node; this.parent = parent; -// this.name = node.getNodeName(); + + for (String attr : parent.listAttributes()) { + if (attr.startsWith("xmlns")) { + // Copy namespace attributes to the kids, otherwise this XML + // can no longer be printed (or manipulated in most ways). + // Only do this when it's an Element, otherwise it's trying to set + // attributes on text notes (interstitial content). + if (node instanceof Element) { + setString(attr, parent.getString(attr)); + } + } + } } @@ -1094,10 +1105,18 @@ public String format(int indent) { String outgoing = stringWriter.toString(); // Add the XML declaration to the top if it's not there already - if (!outgoing.startsWith(decl)) { - return decl + sep + outgoing; - } else { + if (outgoing.startsWith(decl)) { + int declen = decl.length(); + int seplen = sep.length(); + if (outgoing.length() > declen + seplen && + !outgoing.substring(declen, declen + seplen).equals(sep)) { + // make sure there's a line break between the XML decl and the code + return outgoing.substring(0, decl.length()) + + sep + outgoing.substring(decl.length()); + } return outgoing; + } else { + return decl + sep + outgoing; } } catch (Exception e) { @@ -1107,6 +1126,11 @@ public String format(int indent) { } + public void print() { + PApplet.println(format(2)); + } + + /** * Return the XML document formatted with two spaces for indents. * Chosen to do this since it's the most common case (e.g. with println()). diff --git a/core/todo.txt b/core/todo.txt index 0f7c8f2e19..c98e94cf0e 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,6 +1,8 @@ 0256 (3.2.4 or 3.3) X write exec() documentation X https://github.com/processing/processing/issues/4740 +X add xmlns to elements procured from getChild() +X make sure newline is added after XML header when formatting api additions X add listPaths(), listFiles() @@ -9,11 +11,16 @@ X add increment() method that takes IntDict to merge another dictionary X Calling this increment() since it doesn't make sense in practice for X the other dictionary types, even though it's technically an add() X add Entry class for iterating StringDict, IntDict, FloatDict +X add XML.print() method (prints with indent of 2) contribs X Adding missing docs and keywords for TableRow X https://github.com/processing/processing/pull/4333 +cleaning +o probably should also check to make sure PApplet running JVM 8 +X or compile against 1.8 and force it? + _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 @@ -299,11 +306,6 @@ _ will need documentation _ negative indices so that we can work relative to the end in data classes? _ add Double and Long versions of the data classes? _ add requestFocus() method to PApplet (or surface?) -o destroy() removed, but bring back? is that better than dispose()? -_ destroy() only called dispose(), so no difference -_ Python Mode has a hook for when it's called -_ probably should also check to make sure PApplet running JVM 8 -_ or compile against 1.8 and force it? @@ -371,6 +373,9 @@ _ is there a way to catch cmd-q when running a sketch? _ so that it could avoid quitting if the sketch hasn't been stopped _ or if the sketch window is foremost _ maybe a hack where a new menubar is added? +o destroy() removed, but bring back? is that better than dispose()? +_ destroy() only called dispose(), so no difference +_ Python Mode has a hook for when it's called CORE / PFont and text() @@ -701,9 +706,6 @@ _ . Textblock _ \ Knob _ \ Progress bar _ \ Toggle -_ implement JSON class -_ http://www.xml.com/lpt/a/1658 -_ http://www.json.org/java/ _ add shader support _ createColor() instead of color()? _ route all exceptions through PException and catch method diff --git a/todo.txt b/todo.txt index e83c4f6ecb..1d199c72d7 100755 --- a/todo.txt +++ b/todo.txt @@ -18,6 +18,12 @@ contrib X Added the remove filter feature X https://github.com/processing/processing/pull/3890 +jakub +X println(int(byte(245))) throwing error +X https://github.com/processing/processing/issues/4652 +X https://github.com/processing/processing/pull/4744 + + _ 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 @@ -35,6 +41,9 @@ _ https://bitbucket.org/infinitekind/appbundler _ settings() present and pixelDensity() is in setup(), nothing set/no error _ https://github.com/processing/processing/issues/4703 +_ right bracket missing error +_ https://github.com/processing/processing/issues/4702 + _ Application Exports report as "Damaged" on macOS Sierra _ https://github.com/processing/processing/issues/4705 _ could provide script to un-quarrantine From c6d50c0d11df396c430269b88ebb3453f95b72ff Mon Sep 17 00:00:00 2001 From: REAS Date: Tue, 22 Nov 2016 19:35:12 -0800 Subject: [PATCH 147/917] Clarification for image() reference based on Issue #500 --- core/src/processing/core/PGraphics.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 3ff63bdad9..02b9919c7b 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -3754,8 +3754,8 @@ public void imageMode(int mode) { * * @webref image:loading_displaying * @param img the image to display - * @param a x-coordinate of the image - * @param b y-coordinate of the image + * @param a x-coordinate of the image by default + * @param b y-coordinate of the image by default * @see PApplet#loadImage(String, String) * @see PImage * @see PGraphics#imageMode(int) @@ -3783,8 +3783,8 @@ public void image(PImage img, float a, float b) { } /** - * @param c width to display the image - * @param d height to display the image + * @param c width to display the image by default + * @param d height to display the image by default */ public void image(PImage img, float a, float b, float c, float d) { image(img, a, b, c, d, 0, 0, img.width, img.height); From 2d1bdaf266b67af8c166d0cd4bb78d2993786f43 Mon Sep 17 00:00:00 2001 From: REAS Date: Tue, 22 Nov 2016 20:03:35 -0800 Subject: [PATCH 148/917] Remove CATEGORY as a parameter for Table.addColumn() pointed out in processing/processing-docs#501 --- core/src/processing/data/Table.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index 17aab1245f..307b9df67a 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -1790,7 +1790,7 @@ public void addColumn(String title) { /** - * @param type the type to be used for the new column: INT, LONG, FLOAT, DOUBLE, STRING, or CATEGORY + * @param type the type to be used for the new column: INT, LONG, FLOAT, DOUBLE, or STRING */ public void addColumn(String title, int type) { insertColumn(columns.length, title, type); From f9cb361801fe8f927ff7619625b4d80029d645ac Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 24 Nov 2016 22:16:40 +0100 Subject: [PATCH 149/917] Fix hex color regex Same problem as with type constructors #4744 Fixes #4752 --- java/src/processing/mode/java/pdex/SourceUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/processing/mode/java/pdex/SourceUtils.java b/java/src/processing/mode/java/pdex/SourceUtils.java index 8a1a206934..531c8a3ed9 100644 --- a/java/src/processing/mode/java/pdex/SourceUtils.java +++ b/java/src/processing/mode/java/pdex/SourceUtils.java @@ -84,7 +84,7 @@ public static List replaceTypeConstructors(CharSequence source) { public static final Pattern HEX_LITERAL_REGEX = - Pattern.compile("(?:^|\\W)(#[A-Fa-f0-9]{6})(?:\\W|$)"); + Pattern.compile("(?<=^|\\W)(#[A-Fa-f0-9]{6})(?=\\W|$)"); public static List replaceHexLiterals(CharSequence source) { // Find all #[webcolor] and replace with 0xff[webcolor] From fa611901b88c245620df8c0497b6fb9b684d4c5a Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 29 Nov 2016 11:43:44 -0500 Subject: [PATCH 150/917] notes about github updates --- todo.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/todo.txt b/todo.txt index 1d199c72d7..4e4ad69056 100755 --- a/todo.txt +++ b/todo.txt @@ -22,7 +22,17 @@ jakub X println(int(byte(245))) throwing error X https://github.com/processing/processing/issues/4652 X https://github.com/processing/processing/pull/4744 - +X 'web colors' next to each other fail to parse in certain situations +X https://github.com/processing/processing/issues/4752 +X https://github.com/processing/processing/pull/4753 + +_ Broken characters in the Welcome Page and the Contribution Manager +_ looks like a failure to load the Source Sans font +_ https://github.com/processing/processing/issues/4747 +_ what happens if font loading fails? +_ are there conflicts between version in lib and OS? +_ are we still installing fonts into ext? +_ fixed by rolling back to 8u92, broken since 8u102 in 3.1.2 _ Export Application fails on machines w/ non-ASCII chars in user name _ at least give a warning about this? From cd6063c860822ec31f4aaef24d1f10762568b7d0 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 30 Nov 2016 12:09:34 -0500 Subject: [PATCH 151/917] documentation auto-update --- core/src/processing/core/PApplet.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index b10ac209cb..2f2818fad8 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -12322,8 +12322,8 @@ public void imageMode(int mode) { * * @webref image:loading_displaying * @param img the image to display - * @param a x-coordinate of the image - * @param b y-coordinate of the image + * @param a x-coordinate of the image by default + * @param b y-coordinate of the image by default * @see PApplet#loadImage(String, String) * @see PImage * @see PGraphics#imageMode(int) @@ -12338,8 +12338,8 @@ public void image(PImage img, float a, float b) { /** - * @param c width to display the image - * @param d height to display the image + * @param c width to display the image by default + * @param d height to display the image by default */ public void image(PImage img, float a, float b, float c, float d) { if (recorder != null) recorder.image(img, a, b, c, d); From 8e3f08310a9bd3d7e8777cc3ecb0c5bddcb8ac2f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 1 Dec 2016 07:26:18 -0500 Subject: [PATCH 152/917] trying to debug proxy issues --- app/src/processing/app/SingleInstance.java | 13 +++++++++---- todo.txt | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/SingleInstance.java b/app/src/processing/app/SingleInstance.java index e04678ce67..d9409d1526 100644 --- a/app/src/processing/app/SingleInstance.java +++ b/app/src/processing/app/SingleInstance.java @@ -57,12 +57,15 @@ static boolean alreadyRunning(String[] args) { static void startServer(final Base base) { try { - final ServerSocket ss = new ServerSocket(0, 0, InetAddress.getByName(null)); + Messages.log("Opening SingleInstance socket"); + final ServerSocket ss = + new ServerSocket(0, 0, InetAddress.getLoopbackAddress()); Preferences.set(SERVER_PORT, "" + ss.getLocalPort()); final String key = "" + Math.random(); Preferences.set(SERVER_KEY, key); Preferences.save(); + Messages.log("Starting SingleInstance thread"); new Thread(new Runnable() { public void run() { while (true) { @@ -119,15 +122,17 @@ public void run() { static boolean sendArguments(String[] args) { //, long timeout) { try { + Messages.log("Checking to see if Processing is already running"); int port = Preferences.getInteger(SERVER_PORT); String key = Preferences.get(SERVER_KEY); Socket socket = null; try { - socket = new Socket(InetAddress.getByName(null), port); + socket = new Socket(InetAddress.getLoopbackAddress(), port); } catch (Exception ignored) { } if (socket != null) { + Messages.log("Processing is already running, sending command line"); PrintWriter writer = PApplet.createWriter(socket.getOutputStream()); writer.println(key); for (String arg : args) { @@ -138,9 +143,9 @@ static boolean sendArguments(String[] args) { //, long timeout) { return true; } } catch (IOException e) { - System.err.println("Error sending commands to other instance."); - e.printStackTrace(); + Messages.loge("Error sending commands to other instance", e); } + Messages.log("Processing is not already running (or could not connect)"); return false; } } diff --git a/todo.txt b/todo.txt index 4e4ad69056..2d5e86a9ac 100755 --- a/todo.txt +++ b/todo.txt @@ -13,6 +13,8 @@ X replace java.util.logging code with built-in logging _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 _ this may be fixed (removed invokeLater() on startup), unconfirmed +_ could not write to temporary directory +_ https://github.com/processing/processing/issues/4757 contrib X Added the remove filter feature From 0c363ae7857c432c05da3bd8de2c7e17292a20c6 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 1 Dec 2016 07:38:19 -0500 Subject: [PATCH 153/917] use debug.txt instead of debug; add pref to disable system proxy --- app/src/processing/app/Base.java | 6 ++++-- app/src/processing/app/Preferences.java | 11 +++++++---- build/shared/lib/defaults.txt | 2 ++ todo.txt | 1 + 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index d112849013..5b2f0fe99e 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -141,11 +141,13 @@ static private void createAndShowGUI(String[] args) { Platform.init(); // Set the debug flag based on a file being present in the settings folder - File debugFile = getSettingsFile("debug"); + File debugFile = getSettingsFile("debug.txt"); + /* if (debugFile.isDirectory()) { // if it's a directory, it's a leftover from older releases, clear it Util.removeDir(debugFile); - } else if (debugFile.exists()) { + } else*/ + if (debugFile.exists()) { DEBUG = true; } diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index 12abb56f4f..edc41abe77 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -68,7 +68,7 @@ static public void init() { load(Base.getLibStream(DEFAULTS_FILE)); } catch (Exception e) { Messages.showError(null, "Could not read default settings.\n" + - "You'll need to reinstall Processing.", e); + "You'll need to reinstall Processing.", e); } // Clone the defaults, then override any them with the user's preferences. @@ -109,9 +109,12 @@ static public void init() { PApplet.useNativeSelect = Preferences.getBoolean("chooser.files.native"); //$NON-NLS-1$ - // Use the system proxy settings by default - // https://github.com/processing/processing/issues/2643 - System.setProperty("java.net.useSystemProxies", "true"); + // Adding option to disable this in case it's getting in the way + if (get("proxy.system").equals("true")) { + // Use the system proxy settings by default + // https://github.com/processing/processing/issues/2643 + System.setProperty("java.net.useSystemProxies", "true"); + } // Set HTTP, HTTPS, and SOCKS proxies for individuals // who want/need to override the system setting diff --git a/build/shared/lib/defaults.txt b/build/shared/lib/defaults.txt index f1663073b1..f5380d3598 100644 --- a/build/shared/lib/defaults.txt +++ b/build/shared/lib/defaults.txt @@ -347,6 +347,8 @@ proxy.socks.port= # Example of usage (replace 'http' with 'https' or 'socks' as needed) #proxy.http.host=proxy.example.com #proxy.http.port=8080 +# Whether to use the system proxy by default +proxy.system=true # PDE X pdex.autoSave.autoSaveByDefault=true diff --git a/todo.txt b/todo.txt index 2d5e86a9ac..0218f649bb 100755 --- a/todo.txt +++ b/todo.txt @@ -9,6 +9,7 @@ X https://github.com/processing/processing/issues/3123 X https://github.com/processing/processing/issues/4735 X move the DEBUG flag into an external file or preferences.txt X will help us with debugging w/ others as well +X change to debug.txt; too confusing with the folder thing X replace java.util.logging code with built-in logging _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 From 2a28dab68a2a5b604cc3d022bd5624ec8742daf6 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 3 Dec 2016 09:20:57 -0500 Subject: [PATCH 154/917] splitting Console for better recording --- app/src/processing/app/Console.java | 504 ++++++++++++++++++++++++++++ 1 file changed, 504 insertions(+) create mode 100644 app/src/processing/app/Console.java diff --git a/app/src/processing/app/Console.java b/app/src/processing/app/Console.java new file mode 100644 index 0000000000..b5f5b94964 --- /dev/null +++ b/app/src/processing/app/Console.java @@ -0,0 +1,504 @@ +/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-10 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app.ui; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.event.*; +import java.io.*; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.swing.*; +import javax.swing.border.MatteBorder; +import javax.swing.text.*; + +import processing.app.*; +import processing.core.PApplet; + + +/** + * Message console that sits below the editing area. + *

+ * Be careful when debugging this class, because if it's throwing exceptions, + * don't take over System.err, and debug while watching just System.out + * or just call println() or whatever directly to systemOut or systemErr. + *

+ * Also note that encodings will not work properly when run from Eclipse. This + * means that if you use non-ASCII characters in a println() or some such, + * the characters won't print properly in the Processing and/or Eclipse console. + * It seems that Eclipse's console-grabbing and that of Processing don't + * get along with one another. Use 'ant run' to work on encoding-related issues. + */ +public class EditorConsole extends JScrollPane { + Editor editor; + + Timer flushTimer; + + JTextPane consoleTextPane; + BufferedStyledDocument consoleDoc; + + MutableAttributeSet stdStyle; + MutableAttributeSet errStyle; + + int maxLineCount; + + PrintStream sketchOut; + PrintStream sketchErr; + + // Single static instance shared because there's only one real System.out. + // Within the input handlers, the currentConsole variable will be used to + // echo things to the correct location. + + static PrintStream systemOut; + static PrintStream systemErr; + + static PrintStream consoleOut; + static PrintStream consoleErr; + + static OutputStream stdoutFile; + static OutputStream stderrFile; + + static EditorConsole currentConsole; + + // For 0185, moved the first init to this static { } block, so that we never + // have a situation that causes systemOut/Err to not be set properly. + static { + systemOut = System.out; + systemErr = System.err; + + // placing everything inside a try block because this can be a dangerous + // time for the lights to blink out and crash for and obscure reason. + try { + // Create output files that will have a randomized name. Has to + // be randomized otherwise another instance of Processing (or one of its + // sister IDEs) might collide with the file causing permissions problems. + // The files and folders are not deleted on exit because they may be + // needed for debugging or bug reporting. + SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd"); + String randy = PApplet.nf((int) (1000 * Math.random()), 4); + String stamp = formatter.format(new Date()) + "_" + randy; + + File consoleDir = Base.getSettingsFile("console"); + consoleDir.mkdirs(); + File outFile = new File(consoleDir, stamp + ".out"); + stdoutFile = new FileOutputStream(outFile); + File errFile = new File(consoleDir, stamp + ".err"); + stderrFile = new FileOutputStream(errFile); + + consoleOut = new PrintStream(new EditorConsoleStream(false, null)); + consoleErr = new PrintStream(new EditorConsoleStream(true, null)); + + System.setOut(consoleOut); + System.setErr(consoleErr); + +// } catch (Exception e) { +// stdoutFile = null; +// stderrFile = null; +// +// e.printStackTrace(); +// Base.showWarning("Console Error", +// "A problem occurred while trying to open the\n" + +// "files used to store the console output.", e); + } catch (Exception e) { + stdoutFile = null; + stderrFile = null; + + consoleOut = null; + consoleErr = null; + + System.setOut(systemOut); + System.setErr(systemErr); + + e.printStackTrace(systemErr); + } + } + + + public EditorConsole(Editor editor) { + this.editor = editor; + + maxLineCount = Preferences.getInteger("console.length"); + + consoleDoc = new BufferedStyledDocument(10000, maxLineCount); + consoleTextPane = new JTextPane(consoleDoc); + consoleTextPane.setEditable(false); + + updateMode(); + + // add the jtextpane to this scrollpane + this.setViewportView(consoleTextPane); + + sketchOut = new PrintStream(new EditorConsoleStream(false, this)); + sketchErr = new PrintStream(new EditorConsoleStream(true, this)); + + startTimer(); + } + + + protected void flush() { + // only if new text has been added + if (consoleDoc.hasAppendage) { + // insert the text that's been added in the meantime + consoleDoc.insertAll(); + // always move to the end of the text as it's added + consoleTextPane.setCaretPosition(consoleDoc.getLength()); + } + } + + + /** + * Start the timer that handles flushing the console text. Has to be started + * and stopped/cleared because the Timer thread will keep a reference to its + * Editor around even after the Editor has been closed, leaking memory. + */ + protected void startTimer() { + if (flushTimer == null) { + // periodically post buffered messages to the console + // should the interval come from the preferences file? + flushTimer = new Timer(250, new ActionListener() { + public void actionPerformed(ActionEvent evt) { + flush(); + } + }); + flushTimer.start(); + } + } + + + protected void stopTimer() { + if (flushTimer != null) { + flush(); // clear anything that's there + flushTimer.stop(); + flushTimer = null; + } + } + + + public PrintStream getOut() { + return sketchOut; + } + + + public PrintStream getErr() { + return sketchErr; + } + + + /** + * Update the font family and sizes based on the Preferences window. + */ + protected void updateAppearance() { + String fontFamily = Preferences.get("editor.font.family"); + int fontSize = Preferences.getInteger("console.font.size"); + StyleConstants.setFontFamily(stdStyle, fontFamily); + StyleConstants.setFontSize(stdStyle, fontSize); + StyleConstants.setFontFamily(errStyle, fontFamily); + StyleConstants.setFontSize(errStyle, fontSize); + clear(); // otherwise we'll have mixed fonts + } + + + /** + * Change coloring, fonts, etc in response to a mode change. + */ + protected void updateMode() { + Mode mode = editor.getMode(); + + // necessary? + MutableAttributeSet standard = new SimpleAttributeSet(); + StyleConstants.setAlignment(standard, StyleConstants.ALIGN_LEFT); + consoleDoc.setParagraphAttributes(0, 0, standard, true); + + Font font = Preferences.getFont("console.font"); + + // build styles for different types of console output + Color bgColor = mode.getColor("console.color"); + Color fgColorOut = mode.getColor("console.output.color"); + Color fgColorErr = mode.getColor("console.error.color"); + + // Make things line up with the Editor above. If this is ever removed, + // setBorder(null) should be called instead. The defaults are nasty. + setBorder(new MatteBorder(0, Editor.LEFT_GUTTER, 0, 0, bgColor)); + + stdStyle = new SimpleAttributeSet(); + StyleConstants.setForeground(stdStyle, fgColorOut); + StyleConstants.setBackground(stdStyle, bgColor); + StyleConstants.setFontSize(stdStyle, font.getSize()); + StyleConstants.setFontFamily(stdStyle, font.getFamily()); + StyleConstants.setBold(stdStyle, font.isBold()); + StyleConstants.setItalic(stdStyle, font.isItalic()); + + errStyle = new SimpleAttributeSet(); + StyleConstants.setForeground(errStyle, fgColorErr); + StyleConstants.setBackground(errStyle, bgColor); + StyleConstants.setFontSize(errStyle, font.getSize()); + StyleConstants.setFontFamily(errStyle, font.getFamily()); + StyleConstants.setBold(errStyle, font.isBold()); + StyleConstants.setItalic(errStyle, font.isItalic()); + + if (UIManager.getLookAndFeel().getID().equals("Nimbus")) { + getViewport().setBackground(bgColor); + consoleTextPane.setOpaque(false); + consoleTextPane.setBackground(new Color(0, 0, 0, 0)); + } else { + consoleTextPane.setBackground(bgColor); + } + + // calculate height of a line of text in pixels + // and size window accordingly + FontMetrics metrics = this.getFontMetrics(font); + int height = metrics.getAscent() + metrics.getDescent(); + int lines = Preferences.getInteger("console.lines"); //, 4); + int sizeFudge = 6; //10; // unclear why this is necessary, but it is + setPreferredSize(new Dimension(1024, (height * lines) + sizeFudge)); + setMinimumSize(new Dimension(1024, (height * 4) + sizeFudge)); + } + + + static public void setEditor(Editor editor) { + if (currentConsole != null) { + currentConsole.stopTimer(); // allow to be garbage collected + } + currentConsole = editor.console; + currentConsole.startTimer(); + } + + + /** + * Close the streams so that the temporary files can be deleted. + *

+ * File.deleteOnExit() cannot be used because the stdout and stderr + * files are inside a folder, and have to be deleted before the + * folder itself is deleted, which can't be guaranteed when using + * the deleteOnExit() method. + */ + public static void handleQuit() { + // replace original streams to remove references to console's streams + System.setOut(systemOut); + System.setErr(systemErr); + + try { + // close the PrintStream + if (consoleOut != null) consoleOut.close(); + if (consoleErr != null) consoleErr.close(); + + // also have to close the original FileOutputStream + // otherwise it won't be shut down completely + if (stdoutFile != null) stdoutFile.close(); + if (stderrFile != null) stderrFile.close(); + + } catch (IOException e) { + e.printStackTrace(systemErr); + } + } + + + synchronized public void message(String what, boolean err) { + if (err) { + systemErr.print(what); + } else { + systemOut.print(what); + } + + if (err && (what.contains("invalid context 0x0") || (what.contains("invalid drawable")))) { + // Respectfully declining... This is a quirk of more recent releases of + // Java on Mac OS X, but is widely reported as the source of any other + // bug or problem that a user runs into. It may well be a Processing + // bug, but until we know, we're suppressing the messages. + } else if (err && what.contains("Make pbuffer:")) { + // Remove initalization warning from LWJGL. + } else if (err && what.contains("XInitThreads() called for concurrent")) { + // "Info: XInitThreads() called for concurrent Thread support" message on Linux + } else if (!err && what.contains("Listening for transport dt_socket at address")) { + // Message from the JVM about the socket launch for debug + // Listening for transport dt_socket at address: 8727 + } else { + // Append a piece of text to the console. Swing components are NOT + // thread-safe, and since the MessageSiphon instantiates new threads, + // and in those callbacks, they often print output to stdout and stderr, + // which are wrapped by EditorConsoleStream and eventually leads to + // EditorConsole.appendText(), which directly updates the Swing text + // components, causing deadlock. Updates are buffered to the console and + // displayed at regular intervals on Swing's event-dispatching thread. + // (patch by David Mellis) + consoleDoc.appendString(what, err ? errStyle : stdStyle); + } + } + + + public void clear() { + try { + consoleDoc.remove(0, consoleDoc.getLength()); + } catch (BadLocationException e) { + // ignore the error otherwise this will cause an infinite loop + // maybe not a good idea in the long run? + } + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + private static class EditorConsoleStream extends OutputStream { + final boolean err; // whether stderr or stdout + final byte single[] = new byte[1]; + EditorConsole console; + + public EditorConsoleStream(boolean err, EditorConsole console) { + this.err = err; + this.console = console; + } + + public void close() { } + + public void flush() { } + + public void write(byte b[]) { // appears never to be used + write(b, 0, b.length); + } + + public void write(byte b[], int offset, int length) { + if (console != null) { + console.message(new String(b, offset, length), err); + } else if (currentConsole != null) { + currentConsole.message(new String(b, offset, length), err); + } else { + // If no console is present, still need to write this to the actual + // System.out or System.err. Otherwise we can't !#$!% debug anything. + if (err) { + systemErr.write(b, offset, length); + } else { + systemOut.write(b, offset, length); + } + } + + final OutputStream echo = err ? stderrFile : stdoutFile; + if (echo != null) { + try { + echo.write(b, offset, length); + echo.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public void write(int b) { + single[0] = (byte) b; + write(single, 0, 1); + } + } +} + + +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + +/** + * Buffer updates to the console and output them in batches. For info, see: + * http://java.sun.com/products/jfc/tsc/articles/text/element_buffer and + * http://javatechniques.com/public/java/docs/gui/jtextpane-speed-part2.html + * appendString() is called from multiple threads, and insertAll from the + * swing event thread, so they need to be synchronized + */ +class BufferedStyledDocument extends DefaultStyledDocument { + List elements = new ArrayList(); + int maxLineLength, maxLineCount; + int currentLineLength = 0; + boolean needLineBreak = false; + boolean hasAppendage = false; + + public BufferedStyledDocument(int maxLineLength, int maxLineCount) { + this.maxLineLength = maxLineLength; + this.maxLineCount = maxLineCount; + } + + /** buffer a string for insertion at the end of the DefaultStyledDocument */ + public synchronized void appendString(String str, AttributeSet a) { + // do this so that it's only updated when needed (otherwise console + // updates every 250 ms when an app isn't even running.. see bug 180) + hasAppendage = true; + + // process each line of the string + while (str.length() > 0) { + // newlines within an element have (almost) no effect, so we need to + // replace them with proper paragraph breaks (start and end tags) + if (needLineBreak || currentLineLength > maxLineLength) { + elements.add(new ElementSpec(a, ElementSpec.EndTagType)); + elements.add(new ElementSpec(a, ElementSpec.StartTagType)); + currentLineLength = 0; + } + + if (str.indexOf('\n') == -1) { + elements.add(new ElementSpec(a, ElementSpec.ContentType, + str.toCharArray(), 0, str.length())); + currentLineLength += str.length(); + needLineBreak = false; + str = str.substring(str.length()); // eat the string + } else { + elements.add(new ElementSpec(a, ElementSpec.ContentType, + str.toCharArray(), 0, str.indexOf('\n') + 1)); + needLineBreak = true; + str = str.substring(str.indexOf('\n') + 1); // eat the line + } + } + } + + /** insert the buffered strings */ + public synchronized void insertAll() { + ElementSpec[] elementArray = new ElementSpec[elements.size()]; + elements.toArray(elementArray); + + try { + // check how many lines have been used so far + // if too many, shave off a few lines from the beginning + Element element = super.getDefaultRootElement(); + int lineCount = element.getElementCount(); + int overage = lineCount - maxLineCount; + if (overage > 0) { + // if 1200 lines, and 1000 lines is max, + // find the position of the end of the 200th line + //systemOut.println("overage is " + overage); + Element lineElement = element.getElement(overage); + if (lineElement == null) return; // do nuthin + + int endOffset = lineElement.getEndOffset(); + // remove to the end of the 200th line + super.remove(0, endOffset); + } + super.insert(super.getLength(), elementArray); + + } catch (BadLocationException e) { + // ignore the error otherwise this will cause an infinite loop + // maybe not a good idea in the long run? + } + elements.clear(); + hasAppendage = false; + } +} From b6ab4f95820f646cd3d6b43a7bd47997c1295800 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 3 Dec 2016 15:46:26 -0500 Subject: [PATCH 155/917] split gui and non-gui portions of console for earlier startup --- app/src/processing/app/Base.java | 5 + app/src/processing/app/Console.java | 456 +++++-------------- app/src/processing/app/ui/Editor.java | 8 +- app/src/processing/app/ui/EditorConsole.java | 141 +++--- core/todo.txt | 2 + 5 files changed, 194 insertions(+), 418 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 5b2f0fe99e..5df968ed4b 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -139,6 +139,8 @@ static private void createAndShowGUI(String[] args) { } Platform.init(); + // call after Platform.init() because we need the settings folder + Console.startup(); // Set the debug flag based on a file being present in the settings folder File debugFile = getSettingsFile("debug.txt"); @@ -1474,6 +1476,9 @@ public boolean handleQuit() { // Save out the current prefs state Preferences.save(); + // Finished with this guy + Console.shutdown(); + if (!Platform.isMacOS()) { // If this was fired from the menu or an AppleEvent (the Finder), // then Mac OS X will send the terminate signal itself. diff --git a/app/src/processing/app/Console.java b/app/src/processing/app/Console.java index b5f5b94964..178fce7161 100644 --- a/app/src/processing/app/Console.java +++ b/app/src/processing/app/Console.java @@ -3,7 +3,8 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2004-10 Ben Fry and Casey Reas + Copyright (c) 2012-16 The Processing Foundation + Copyright (c) 2004-12 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology This program is free software; you can redistribute it and/or modify @@ -21,25 +22,11 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -package processing.app.ui; +package processing.app; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.event.*; import java.io.*; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Date; -import java.util.List; - -import javax.swing.*; -import javax.swing.border.MatteBorder; -import javax.swing.text.*; - -import processing.app.*; -import processing.core.PApplet; /** @@ -55,76 +42,87 @@ * It seems that Eclipse's console-grabbing and that of Processing don't * get along with one another. Use 'ant run' to work on encoding-related issues. */ -public class EditorConsole extends JScrollPane { - Editor editor; - - Timer flushTimer; - - JTextPane consoleTextPane; - BufferedStyledDocument consoleDoc; - - MutableAttributeSet stdStyle; - MutableAttributeSet errStyle; - - int maxLineCount; - - PrintStream sketchOut; - PrintStream sketchErr; +public class Console { +// PrintStream sketchOut; +// PrintStream sketchErr; // Single static instance shared because there's only one real System.out. // Within the input handlers, the currentConsole variable will be used to // echo things to the correct location. + /** The original System.out */ static PrintStream systemOut; + /** The original System.err */ static PrintStream systemErr; + /** Our replacement System.out */ static PrintStream consoleOut; + /** Our replacement System.err */ static PrintStream consoleErr; + /** All stdout also written to a file */ static OutputStream stdoutFile; + /** All stderr also written to a file */ static OutputStream stderrFile; - static EditorConsole currentConsole; + /** stdout listener for the currently active Editor */ + static OutputStream editorOut; + /** stderr listener for the currently active Editor */ + static OutputStream editorErr; + - // For 0185, moved the first init to this static { } block, so that we never - // have a situation that causes systemOut/Err to not be set properly. - static { + static public void startup() { systemOut = System.out; systemErr = System.err; // placing everything inside a try block because this can be a dangerous // time for the lights to blink out and crash for and obscure reason. try { - // Create output files that will have a randomized name. Has to - // be randomized otherwise another instance of Processing (or one of its - // sister IDEs) might collide with the file causing permissions problems. - // The files and folders are not deleted on exit because they may be - // needed for debugging or bug reporting. - SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd"); - String randy = PApplet.nf((int) (1000 * Math.random()), 4); - String stamp = formatter.format(new Date()) + "_" + randy; + SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd_HHmmss"); + // Moving away from a random string in 0256 (and adding hms) because + // the random digits looked like times anyway, causing confusion. + //String randy = String.format("%04d", (int) (1000 * Math.random())); + //final String stamp = formatter.format(new Date()) + "_" + randy; + final String stamp = formatter.format(new Date()); File consoleDir = Base.getSettingsFile("console"); - consoleDir.mkdirs(); + if (consoleDir.exists()) { + // clear old debug files + File[] stdFiles = consoleDir.listFiles(new FileFilter() { + final String todayPrefix = stamp.substring(0, 4); + + public boolean accept(File file) { + if (!file.isDirectory()) { + String name = file.getName(); + if (name.endsWith(".err") || name.endsWith(".out")) { + // don't delete any of today's debug messages + return !name.startsWith(todayPrefix); + } + } + return false; + } + }); + // Remove any files that aren't from today + for (File file : stdFiles) { + file.delete(); + } + } else { + consoleDir.mkdirs(); + } + File outFile = new File(consoleDir, stamp + ".out"); stdoutFile = new FileOutputStream(outFile); File errFile = new File(consoleDir, stamp + ".err"); stderrFile = new FileOutputStream(errFile); - consoleOut = new PrintStream(new EditorConsoleStream(false, null)); - consoleErr = new PrintStream(new EditorConsoleStream(true, null)); +// consoleOut = new PrintStream(new EditorConsoleStream(false, null)); +// consoleErr = new PrintStream(new EditorConsoleStream(true, null)); + consoleOut = new PrintStream(new ConsoleStream(false)); + consoleErr = new PrintStream(new ConsoleStream(true)); System.setOut(consoleOut); System.setErr(consoleErr); -// } catch (Exception e) { -// stdoutFile = null; -// stderrFile = null; -// -// e.printStackTrace(); -// Base.showWarning("Console Error", -// "A problem occurred while trying to open the\n" + -// "files used to store the console output.", e); } catch (Exception e) { stdoutFile = null; stderrFile = null; @@ -135,159 +133,31 @@ public class EditorConsole extends JScrollPane { System.setOut(systemOut); System.setErr(systemErr); - e.printStackTrace(systemErr); + e.printStackTrace(); } } - public EditorConsole(Editor editor) { - this.editor = editor; - - maxLineCount = Preferences.getInteger("console.length"); - - consoleDoc = new BufferedStyledDocument(10000, maxLineCount); - consoleTextPane = new JTextPane(consoleDoc); - consoleTextPane.setEditable(false); - - updateMode(); - - // add the jtextpane to this scrollpane - this.setViewportView(consoleTextPane); - - sketchOut = new PrintStream(new EditorConsoleStream(false, this)); - sketchErr = new PrintStream(new EditorConsoleStream(true, this)); - - startTimer(); - } - - - protected void flush() { - // only if new text has been added - if (consoleDoc.hasAppendage) { - // insert the text that's been added in the meantime - consoleDoc.insertAll(); - // always move to the end of the text as it's added - consoleTextPane.setCaretPosition(consoleDoc.getLength()); - } + static public void setEditor(OutputStream out, OutputStream err) { + editorOut = out; + editorErr = err; } - /** - * Start the timer that handles flushing the console text. Has to be started - * and stopped/cleared because the Timer thread will keep a reference to its - * Editor around even after the Editor has been closed, leaking memory. - */ - protected void startTimer() { - if (flushTimer == null) { - // periodically post buffered messages to the console - // should the interval come from the preferences file? - flushTimer = new Timer(250, new ActionListener() { - public void actionPerformed(ActionEvent evt) { - flush(); - } - }); - flushTimer.start(); - } - } - - - protected void stopTimer() { - if (flushTimer != null) { - flush(); // clear anything that's there - flushTimer.stop(); - flushTimer = null; - } - } - - - public PrintStream getOut() { - return sketchOut; - } - - - public PrintStream getErr() { - return sketchErr; - } - - - /** - * Update the font family and sizes based on the Preferences window. - */ - protected void updateAppearance() { - String fontFamily = Preferences.get("editor.font.family"); - int fontSize = Preferences.getInteger("console.font.size"); - StyleConstants.setFontFamily(stdStyle, fontFamily); - StyleConstants.setFontSize(stdStyle, fontSize); - StyleConstants.setFontFamily(errStyle, fontFamily); - StyleConstants.setFontSize(errStyle, fontSize); - clear(); // otherwise we'll have mixed fonts - } - +// public Console() { +// sketchOut = new PrintStream(new EditorConsoleStream(false, this)); +// sketchErr = new PrintStream(new EditorConsoleStream(true, this)); +// } - /** - * Change coloring, fonts, etc in response to a mode change. - */ - protected void updateMode() { - Mode mode = editor.getMode(); - - // necessary? - MutableAttributeSet standard = new SimpleAttributeSet(); - StyleConstants.setAlignment(standard, StyleConstants.ALIGN_LEFT); - consoleDoc.setParagraphAttributes(0, 0, standard, true); - - Font font = Preferences.getFont("console.font"); - - // build styles for different types of console output - Color bgColor = mode.getColor("console.color"); - Color fgColorOut = mode.getColor("console.output.color"); - Color fgColorErr = mode.getColor("console.error.color"); - - // Make things line up with the Editor above. If this is ever removed, - // setBorder(null) should be called instead. The defaults are nasty. - setBorder(new MatteBorder(0, Editor.LEFT_GUTTER, 0, 0, bgColor)); - - stdStyle = new SimpleAttributeSet(); - StyleConstants.setForeground(stdStyle, fgColorOut); - StyleConstants.setBackground(stdStyle, bgColor); - StyleConstants.setFontSize(stdStyle, font.getSize()); - StyleConstants.setFontFamily(stdStyle, font.getFamily()); - StyleConstants.setBold(stdStyle, font.isBold()); - StyleConstants.setItalic(stdStyle, font.isItalic()); - - errStyle = new SimpleAttributeSet(); - StyleConstants.setForeground(errStyle, fgColorErr); - StyleConstants.setBackground(errStyle, bgColor); - StyleConstants.setFontSize(errStyle, font.getSize()); - StyleConstants.setFontFamily(errStyle, font.getFamily()); - StyleConstants.setBold(errStyle, font.isBold()); - StyleConstants.setItalic(errStyle, font.isItalic()); - - if (UIManager.getLookAndFeel().getID().equals("Nimbus")) { - getViewport().setBackground(bgColor); - consoleTextPane.setOpaque(false); - consoleTextPane.setBackground(new Color(0, 0, 0, 0)); - } else { - consoleTextPane.setBackground(bgColor); - } - // calculate height of a line of text in pixels - // and size window accordingly - FontMetrics metrics = this.getFontMetrics(font); - int height = metrics.getAscent() + metrics.getDescent(); - int lines = Preferences.getInteger("console.lines"); //, 4); - int sizeFudge = 6; //10; // unclear why this is necessary, but it is - setPreferredSize(new Dimension(1024, (height * lines) + sizeFudge)); - setMinimumSize(new Dimension(1024, (height * 4) + sizeFudge)); - } +// public PrintStream getOut() { +// return sketchOut; +// } - static public void setEditor(Editor editor) { - if (currentConsole != null) { - currentConsole.stopTimer(); // allow to be garbage collected - } - currentConsole = editor.console; - currentConsole.startTimer(); - } +// public PrintStream getErr() { +// return sketchErr; +// } /** @@ -298,66 +168,29 @@ static public void setEditor(Editor editor) { * folder itself is deleted, which can't be guaranteed when using * the deleteOnExit() method. */ - public static void handleQuit() { + static public void shutdown() { // replace original streams to remove references to console's streams System.setOut(systemOut); System.setErr(systemErr); - try { - // close the PrintStream - if (consoleOut != null) consoleOut.close(); - if (consoleErr != null) consoleErr.close(); - - // also have to close the original FileOutputStream - // otherwise it won't be shut down completely - if (stdoutFile != null) stdoutFile.close(); - if (stderrFile != null) stderrFile.close(); - - } catch (IOException e) { - e.printStackTrace(systemErr); - } - } - - - synchronized public void message(String what, boolean err) { - if (err) { - systemErr.print(what); - } else { - systemOut.print(what); - } + cleanup(consoleOut); + cleanup(consoleErr); - if (err && (what.contains("invalid context 0x0") || (what.contains("invalid drawable")))) { - // Respectfully declining... This is a quirk of more recent releases of - // Java on Mac OS X, but is widely reported as the source of any other - // bug or problem that a user runs into. It may well be a Processing - // bug, but until we know, we're suppressing the messages. - } else if (err && what.contains("Make pbuffer:")) { - // Remove initalization warning from LWJGL. - } else if (err && what.contains("XInitThreads() called for concurrent")) { - // "Info: XInitThreads() called for concurrent Thread support" message on Linux - } else if (!err && what.contains("Listening for transport dt_socket at address")) { - // Message from the JVM about the socket launch for debug - // Listening for transport dt_socket at address: 8727 - } else { - // Append a piece of text to the console. Swing components are NOT - // thread-safe, and since the MessageSiphon instantiates new threads, - // and in those callbacks, they often print output to stdout and stderr, - // which are wrapped by EditorConsoleStream and eventually leads to - // EditorConsole.appendText(), which directly updates the Swing text - // components, causing deadlock. Updates are buffered to the console and - // displayed at regular intervals on Swing's event-dispatching thread. - // (patch by David Mellis) - consoleDoc.appendString(what, err ? errStyle : stdStyle); - } + // also have to close the original FileOutputStream + // otherwise it won't be shut down completely + cleanup(stdoutFile); + cleanup(stderrFile); } - public void clear() { + static private void cleanup(OutputStream output) { try { - consoleDoc.remove(0, consoleDoc.getLength()); - } catch (BadLocationException e) { - // ignore the error otherwise this will cause an infinite loop - // maybe not a good idea in the long run? + if (output != null) { + output.flush(); + output.close(); + } + } catch (IOException e) { + e.printStackTrace(); } } @@ -365,14 +198,12 @@ public void clear() { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - private static class EditorConsoleStream extends OutputStream { - final boolean err; // whether stderr or stdout - final byte single[] = new byte[1]; - EditorConsole console; + static class ConsoleStream extends OutputStream { + boolean err; // whether stderr or stdout + byte single[] = new byte[1]; - public EditorConsoleStream(boolean err, EditorConsole console) { + public ConsoleStream(boolean err) { this.err = err; - this.console = console; } public void close() { } @@ -384,20 +215,34 @@ public void write(byte b[]) { // appears never to be used } public void write(byte b[], int offset, int length) { - if (console != null) { - console.message(new String(b, offset, length), err); - } else if (currentConsole != null) { - currentConsole.message(new String(b, offset, length), err); + // First write to the original stdout/stderr + if (err) { + systemErr.write(b, offset, length); } else { - // If no console is present, still need to write this to the actual - // System.out or System.err. Otherwise we can't !#$!% debug anything. + systemOut.write(b, offset, length); + } + + // Write to the files that are storing this information + writeFile(b, offset, length); + + // Write to the console of the current Editor, if any + try { if (err) { - systemErr.write(b, offset, length); + if (editorErr != null) { + editorErr.write(b, offset, length); + } } else { - systemOut.write(b, offset, length); + if (editorOut != null) { + editorOut.write(b, offset, length); + } } + } catch (IOException e) { + // Avoid this function being called in a recursive, infinite loop + e.printStackTrace(systemErr); } + } + public void writeFile(byte b[], int offset, int length) { final OutputStream echo = err ? stderrFile : stdoutFile; if (echo != null) { try { @@ -414,91 +259,4 @@ public void write(int b) { write(single, 0, 1); } } -} - - -// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - -/** - * Buffer updates to the console and output them in batches. For info, see: - * http://java.sun.com/products/jfc/tsc/articles/text/element_buffer and - * http://javatechniques.com/public/java/docs/gui/jtextpane-speed-part2.html - * appendString() is called from multiple threads, and insertAll from the - * swing event thread, so they need to be synchronized - */ -class BufferedStyledDocument extends DefaultStyledDocument { - List elements = new ArrayList(); - int maxLineLength, maxLineCount; - int currentLineLength = 0; - boolean needLineBreak = false; - boolean hasAppendage = false; - - public BufferedStyledDocument(int maxLineLength, int maxLineCount) { - this.maxLineLength = maxLineLength; - this.maxLineCount = maxLineCount; - } - - /** buffer a string for insertion at the end of the DefaultStyledDocument */ - public synchronized void appendString(String str, AttributeSet a) { - // do this so that it's only updated when needed (otherwise console - // updates every 250 ms when an app isn't even running.. see bug 180) - hasAppendage = true; - - // process each line of the string - while (str.length() > 0) { - // newlines within an element have (almost) no effect, so we need to - // replace them with proper paragraph breaks (start and end tags) - if (needLineBreak || currentLineLength > maxLineLength) { - elements.add(new ElementSpec(a, ElementSpec.EndTagType)); - elements.add(new ElementSpec(a, ElementSpec.StartTagType)); - currentLineLength = 0; - } - - if (str.indexOf('\n') == -1) { - elements.add(new ElementSpec(a, ElementSpec.ContentType, - str.toCharArray(), 0, str.length())); - currentLineLength += str.length(); - needLineBreak = false; - str = str.substring(str.length()); // eat the string - } else { - elements.add(new ElementSpec(a, ElementSpec.ContentType, - str.toCharArray(), 0, str.indexOf('\n') + 1)); - needLineBreak = true; - str = str.substring(str.indexOf('\n') + 1); // eat the line - } - } - } - - /** insert the buffered strings */ - public synchronized void insertAll() { - ElementSpec[] elementArray = new ElementSpec[elements.size()]; - elements.toArray(elementArray); - - try { - // check how many lines have been used so far - // if too many, shave off a few lines from the beginning - Element element = super.getDefaultRootElement(); - int lineCount = element.getElementCount(); - int overage = lineCount - maxLineCount; - if (overage > 0) { - // if 1200 lines, and 1000 lines is max, - // find the position of the end of the 200th line - //systemOut.println("overage is " + overage); - Element lineElement = element.getElement(overage); - if (lineElement == null) return; // do nuthin - - int endOffset = lineElement.getEndOffset(); - // remove to the end of the 200th line - super.remove(0, endOffset); - } - super.insert(super.getLength(), elementArray); - - } catch (BadLocationException e) { - // ignore the error otherwise this will cause an infinite loop - // maybe not a good idea in the long run? - } - elements.clear(); - hasAppendage = false; - } -} +} \ No newline at end of file diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index b4baaa71ac..fee7ae1813 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -182,25 +182,21 @@ public void windowClosing(WindowEvent e) { // When bringing a window to front, let the Base know addWindowListener(new WindowAdapter() { -// int importIndex; public void windowActivated(WindowEvent e) { base.handleActivated(Editor.this); fileMenu.insert(Recent.getMenu(), 2); Toolkit.setMenuMnemsInside(fileMenu); - //sketchMenu.insert(mode.getImportMenu(), 5); mode.insertImportMenu(sketchMenu); - //sketchMenu.insert(mode.getImportMenu(), importIndex); Toolkit.setMenuMnemsInside(sketchMenu); mode.insertToolbarRecentMenu(); } public void windowDeactivated(WindowEvent e) { + // TODO call handleActivated(null)? or do we run the risk of the + // deactivate call for old window being called after the activate? fileMenu.remove(Recent.getMenu()); -// JMenu importMenu = mode.getImportMenu(); -// importIndex = sketchMenu.getComponentZOrder(mode.getImportMenu()); -// sketchMenu.remove(mode.getImportMenu()); mode.removeImportMenu(sketchMenu); mode.removeToolbarRecentMenu(); } diff --git a/app/src/processing/app/ui/EditorConsole.java b/app/src/processing/app/ui/EditorConsole.java index b5f5b94964..2699758917 100644 --- a/app/src/processing/app/ui/EditorConsole.java +++ b/app/src/processing/app/ui/EditorConsole.java @@ -3,7 +3,8 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2004-10 Ben Fry and Casey Reas + Copyright (c) 2012-16 The Processing Foundation + Copyright (c) 2004-12 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology This program is free software; you can redistribute it and/or modify @@ -27,19 +28,20 @@ import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; -import java.awt.event.*; -import java.io.*; -import java.text.SimpleDateFormat; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.ArrayList; -import java.util.Date; import java.util.List; import javax.swing.*; import javax.swing.border.MatteBorder; import javax.swing.text.*; -import processing.app.*; -import processing.core.PApplet; +import processing.app.Console; +import processing.app.Mode; +import processing.app.Preferences; /** @@ -71,6 +73,7 @@ public class EditorConsole extends JScrollPane { PrintStream sketchOut; PrintStream sketchErr; + /* // Single static instance shared because there's only one real System.out. // Within the input handlers, the currentConsole variable will be used to // echo things to the correct location. @@ -83,9 +86,11 @@ public class EditorConsole extends JScrollPane { static OutputStream stdoutFile; static OutputStream stderrFile; + */ - static EditorConsole currentConsole; + static EditorConsole current; + /* // For 0185, moved the first init to this static { } block, so that we never // have a situation that causes systemOut/Err to not be set properly. static { @@ -138,6 +143,7 @@ public class EditorConsole extends JScrollPane { e.printStackTrace(systemErr); } } + */ public EditorConsole(Editor editor) { @@ -154,8 +160,10 @@ public EditorConsole(Editor editor) { // add the jtextpane to this scrollpane this.setViewportView(consoleTextPane); - sketchOut = new PrintStream(new EditorConsoleStream(false, this)); - sketchErr = new PrintStream(new EditorConsoleStream(true, this)); +// sketchOut = new PrintStream(new EditorConsoleStream(false, this)); +// sketchErr = new PrintStream(new EditorConsoleStream(true, this)); + sketchOut = new PrintStream(new EditorConsoleStream(false)); + sketchErr = new PrintStream(new EditorConsoleStream(true)); startTimer(); } @@ -282,49 +290,58 @@ protected void updateMode() { static public void setEditor(Editor editor) { - if (currentConsole != null) { - currentConsole.stopTimer(); // allow to be garbage collected + if (current != null) { + current.stopTimer(); // allow to be garbage collected } - currentConsole = editor.console; - currentConsole.startTimer(); + editor.console.setCurrent(); } - /** - * Close the streams so that the temporary files can be deleted. - *

- * File.deleteOnExit() cannot be used because the stdout and stderr - * files are inside a folder, and have to be deleted before the - * folder itself is deleted, which can't be guaranteed when using - * the deleteOnExit() method. - */ - public static void handleQuit() { - // replace original streams to remove references to console's streams - System.setOut(systemOut); - System.setErr(systemErr); - - try { - // close the PrintStream - if (consoleOut != null) consoleOut.close(); - if (consoleErr != null) consoleErr.close(); + void setCurrent() { + current = this; //editor.console; + startTimer(); + Console.setEditor(sketchOut, sketchErr); + } - // also have to close the original FileOutputStream - // otherwise it won't be shut down completely - if (stdoutFile != null) stdoutFile.close(); - if (stderrFile != null) stderrFile.close(); - } catch (IOException e) { - e.printStackTrace(systemErr); - } - } +// /** +// * Close the streams so that the temporary files can be deleted. +// *

+// * File.deleteOnExit() cannot be used because the stdout and stderr +// * files are inside a folder, and have to be deleted before the +// * folder itself is deleted, which can't be guaranteed when using +// * the deleteOnExit() method. +// */ +// public static void handleQuit() { +// // replace original streams to remove references to console's streams +// System.setOut(systemOut); +// System.setErr(systemErr); +// +// try { +// // close the PrintStream +// if (consoleOut != null) consoleOut.close(); +// if (consoleErr != null) consoleErr.close(); +// +// // also have to close the original FileOutputStream +// // otherwise it won't be shut down completely +// if (stdoutFile != null) stdoutFile.close(); +// if (stderrFile != null) stderrFile.close(); +// +// } catch (IOException e) { +// e.printStackTrace(systemErr); +// } +// } synchronized public void message(String what, boolean err) { + // now handled in Console + /* if (err) { - systemErr.print(what); + Console.systemErr.print(what); } else { - systemOut.print(what); + Console.systemOut.print(what); } + */ if (err && (what.contains("invalid context 0x0") || (what.contains("invalid drawable")))) { // Respectfully declining... This is a quirk of more recent releases of @@ -362,12 +379,13 @@ public void clear() { } + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - private static class EditorConsoleStream extends OutputStream { - final boolean err; // whether stderr or stdout - final byte single[] = new byte[1]; + /* + static class EditorConsoleStream extends OutputStream { + boolean err; EditorConsole console; public EditorConsoleStream(boolean err, EditorConsole console) { @@ -375,14 +393,6 @@ public EditorConsoleStream(boolean err, EditorConsole console) { this.console = console; } - public void close() { } - - public void flush() { } - - public void write(byte b[]) { // appears never to be used - write(b, 0, b.length); - } - public void write(byte b[], int offset, int length) { if (console != null) { console.message(new String(b, offset, length), err); @@ -397,21 +407,26 @@ public void write(byte b[], int offset, int length) { systemOut.write(b, offset, length); } } + writeEcho(b, offset, length); + } + } + */ - final OutputStream echo = err ? stderrFile : stdoutFile; - if (echo != null) { - try { - echo.write(b, offset, length); - echo.flush(); - } catch (IOException e) { - e.printStackTrace(); - } - } + + class EditorConsoleStream extends OutputStream { + boolean err; + + public EditorConsoleStream(boolean err) { + this.err = err; + } + + public void write(byte b[], int offset, int length) { + message(new String(b, offset, length), err); } + // doesn't appear to be called (but must be implemented) public void write(int b) { - single[0] = (byte) b; - write(single, 0, 1); + write(new byte[] { (byte) b }, 0, 1); } } } diff --git a/core/todo.txt b/core/todo.txt index c98e94cf0e..0816473032 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -21,6 +21,8 @@ cleaning o probably should also check to make sure PApplet running JVM 8 X or compile against 1.8 and force it? +_ no prompt shows with selectInput() on 10.11 and 10.12 +_ https://github.com/processing/processing/issues/4758 _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 From ed82ac5b73754d09b2574240a9c87694366e3484 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 3 Dec 2016 17:11:23 -0500 Subject: [PATCH 156/917] make a note of the gui changes --- todo.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/todo.txt b/todo.txt index 0218f649bb..444a7929e4 100755 --- a/todo.txt +++ b/todo.txt @@ -11,6 +11,7 @@ X move the DEBUG flag into an external file or preferences.txt X will help us with debugging w/ others as well X change to debug.txt; too confusing with the folder thing X replace java.util.logging code with built-in logging +X split gui and non-gui portions of console for earlier startup _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 _ this may be fixed (removed invokeLater() on startup), unconfirmed From ea821097e1ab972a39cc390b5b8b630dec69c67a Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 4 Dec 2016 20:56:51 +0100 Subject: [PATCH 157/917] Extract state from TokenMarker TokenMarker now serves as a holder for keyword list and to provide marking logic. I extracted the rest into TokenMarkerState. Each tab now has its own state, preventing bugs by leaking TokenMarker state between tabs amd Editor instances. There is no need to recompile any Modes, however TokenMarker should be redesigned in the next major version and Modes updated accordingly. For more details read TokenMarkerState header. --- .../processing/app/syntax/JEditTextArea.java | 8 +- .../app/syntax/PdeTextAreaPainter.java | 4 +- .../processing/app/syntax/SyntaxDocument.java | 12 +- .../app/syntax/TextAreaPainter.java | 6 +- .../processing/app/syntax/TokenMarker.java | 383 +++--------------- .../app/syntax/TokenMarkerState.java | 266 ++++++++++++ 6 files changed, 347 insertions(+), 332 deletions(-) create mode 100644 app/src/processing/app/syntax/TokenMarkerState.java diff --git a/app/src/processing/app/syntax/JEditTextArea.java b/app/src/processing/app/syntax/JEditTextArea.java index d2ef145a97..010db63cd5 100644 --- a/app/src/processing/app/syntax/JEditTextArea.java +++ b/app/src/processing/app/syntax/JEditTextArea.java @@ -620,7 +620,7 @@ public final int offsetToX(int line, int offset) { * @param offset The offset, from the start of the line */ public int _offsetToX(int line, int offset) { - TokenMarker tokenMarker = getTokenMarker(); + TokenMarkerState tokenMarker = getTokenMarker(); // Use painter's cached info for speed FontMetrics fm = painter.getFontMetrics(); @@ -682,7 +682,7 @@ public int _offsetToX(int line, int offset) { * @param x The x co-ordinate */ public int xToOffset(int line, int x) { - TokenMarker tokenMarker = getTokenMarker(); + TokenMarkerState tokenMarker = getTokenMarker(); /* Use painter's cached info for speed */ FontMetrics fm = painter.getFontMetrics(); @@ -855,7 +855,7 @@ public void setDocument(SyntaxDocument document, * Returns the document's token marker. Equivalent to calling * getDocument().getTokenMarker(). */ - public final TokenMarker getTokenMarker() { + public final TokenMarkerState getTokenMarker() { return document.getTokenMarker(); } @@ -1680,7 +1680,7 @@ private void emitAsHTML(StringBuilder cf, int line, SyntaxDocument doc) { int segmentOffset = segment.offset; int segmentCount = segment.count; - TokenMarker tokenMarker = doc.getTokenMarker(); + TokenMarkerState tokenMarker = doc.getTokenMarker(); // If syntax coloring is disabled, do simple translation if (tokenMarker == null) { for (int j = 0; j < segmentCount; j++) { diff --git a/app/src/processing/app/syntax/PdeTextAreaPainter.java b/app/src/processing/app/syntax/PdeTextAreaPainter.java index 290cdfc414..24232f23e1 100644 --- a/app/src/processing/app/syntax/PdeTextAreaPainter.java +++ b/app/src/processing/app/syntax/PdeTextAreaPainter.java @@ -113,7 +113,7 @@ public void setMode(Mode mode) { * @param x horizontal position */ @Override - protected void paintLine(Graphics gfx, int line, int x, TokenMarker marker) { + protected void paintLine(Graphics gfx, int line, int x, TokenMarkerState marker) { try { // TODO This line is causing NPEs randomly ever since I added the // toggle for Java Mode/Debugger toolbar. [Manindra] @@ -346,4 +346,4 @@ public Editor getEditor() { public PdeTextArea getPdeTextArea() { return (PdeTextArea) textArea; } -} \ No newline at end of file +} diff --git a/app/src/processing/app/syntax/SyntaxDocument.java b/app/src/processing/app/syntax/SyntaxDocument.java index 25b50d69a0..cead844394 100644 --- a/app/src/processing/app/syntax/SyntaxDocument.java +++ b/app/src/processing/app/syntax/SyntaxDocument.java @@ -27,7 +27,7 @@ public class SyntaxDocument extends PlainDocument * of this document up into tokens. May return null if this * document is not to be colorized. */ - public TokenMarker getTokenMarker() + public TokenMarkerState getTokenMarker() { return tokenMarker; } @@ -40,9 +40,11 @@ public TokenMarker getTokenMarker() */ public void setTokenMarker(TokenMarker tm) { - tokenMarker = tm; - if(tm == null) + if (tm == null) { + tokenMarker = null; return; + } + tokenMarker = tm.createStateInstance(); tokenMarker.insertLines(0,getDefaultRootElement() .getElementCount()); tokenizeLines(); @@ -67,7 +69,7 @@ public void tokenizeLines() */ public void tokenizeLines(int start, int len) { - if(tokenMarker == null || !tokenMarker.supportsMultilineTokens()) + if(tokenMarker == null || !tokenMarker.marker.supportsMultilineTokens()) return; Segment lineSegment = new Segment(); @@ -118,7 +120,7 @@ public void endCompoundEdit() {} public void addUndoableEdit(UndoableEdit edit) {} // protected members - protected TokenMarker tokenMarker; + protected TokenMarkerState tokenMarker; /** * We overwrite this method to update the token marker diff --git a/app/src/processing/app/syntax/TextAreaPainter.java b/app/src/processing/app/syntax/TextAreaPainter.java index 251e6cb8ba..fd7c23da2f 100644 --- a/app/src/processing/app/syntax/TextAreaPainter.java +++ b/app/src/processing/app/syntax/TextAreaPainter.java @@ -488,7 +488,7 @@ public void paint(Graphics gfx) { int lastInvalid = firstLine + (clipRect.y + clipRect.height - 1) / height; try { - TokenMarker tokenMarker = textArea.getDocument().getTokenMarker(); + TokenMarkerState tokenMarker = textArea.getDocument().getTokenMarker(); int x = textArea.getHorizontalOffset(); for (int line = firstInvalid; line <= lastInvalid; line++) { @@ -611,7 +611,7 @@ public Segment getCurrentLine() { // Font defaultFont = getFont(); // Color defaultColor = getForeground(); protected void paintLine(Graphics gfx, int line, int x, - TokenMarker tokenMarker) { + TokenMarkerState tokenMarker) { currentLineIndex = line; int y = textArea.lineToY(line); @@ -671,7 +671,7 @@ protected void paintPlainLine(Graphics gfx, int line, int x, int y) { // int line, Font defaultFont, // Color defaultColor, int x, int y) { protected void paintSyntaxLine(Graphics gfx, int line, int x, int y, - TokenMarker tokenMarker) { + TokenMarkerState tokenMarker) { textArea.getLineText(currentLineIndex, currentLine); currentLineTokens = tokenMarker.markTokens(currentLine, currentLineIndex); diff --git a/app/src/processing/app/syntax/TokenMarker.java b/app/src/processing/app/syntax/TokenMarker.java index 0e414e901e..57d76e6b7b 100644 --- a/app/src/processing/app/syntax/TokenMarker.java +++ b/app/src/processing/app/syntax/TokenMarker.java @@ -15,7 +15,7 @@ * A token marker that splits lines of text into tokens. Each token carries * a length field and an indentification tag that can be mapped to a color * for painting that token.

- * + *

* For performance reasons, the linked list of tokens is reused after each * line is tokenized. Therefore, the return value of markTokens * should only be used for immediate painting. Notably, it cannot be @@ -23,321 +23,68 @@ * * @author Slava Pestov */ -public abstract class TokenMarker -{ - abstract public void addColoring(String keyword, String coloring); - - /** - * A wrapper for the lower-level markTokensImpl method - * that is called to split a line up into tokens. - * @param line The line - * @param lineIndex The line number - */ - public Token markTokens(Segment line, int lineIndex) - { - if(lineIndex >= length) - { - throw new IllegalArgumentException("Tokenizing invalid line: " - + lineIndex); - } - - lastToken = null; - - LineInfo info = lineInfo[lineIndex]; - LineInfo prev; - if(lineIndex == 0) - prev = null; - else - prev = lineInfo[lineIndex - 1]; - - byte oldToken = info.token; - byte token = markTokensImpl(prev == null ? - Token.NULL : prev.token,line,lineIndex); - - info.token = token; - - /* - * This is a foul hack. It stops nextLineRequested - * from being cleared if the same line is marked twice. - * - * Why is this necessary? It's all JEditTextArea's fault. - * When something is inserted into the text, firing a - * document event, the insertUpdate() method shifts the - * caret (if necessary) by the amount inserted. - * - * All caret movement is handled by the select() method, - * which eventually pipes the new position to scrollTo() - * and calls repaint(). - * - * Note that at this point in time, the new line hasn't - * yet been painted; the caret is moved first. - * - * scrollTo() calls offsetToX(), which tokenizes the line - * unless it is being called on the last line painted - * (in which case it uses the text area's painter cached - * token list). What scrollTo() does next is irrelevant. - * - * After scrollTo() has done it's job, repaint() is - * called, and eventually we end up in paintLine(), whose - * job is to paint the changed line. It, too, calls - * markTokens(). - * - * The problem was that if the line started a multiline - * token, the first markTokens() (done in offsetToX()) - * would set nextLineRequested (because the line end - * token had changed) but the second would clear it - * (because the line was the same that time) and therefore - * paintLine() would never know that it needed to repaint - * subsequent lines. - * - * This bug took me ages to track down, that's why I wrote - * all the relevant info down so that others wouldn't - * duplicate it. - */ - if(!(lastLine == lineIndex && nextLineRequested)) - nextLineRequested = (oldToken != token); - - lastLine = lineIndex; - - addToken(0,Token.END); - - return firstToken; - } - - /** - * An abstract method that splits a line up into tokens. It - * should parse the line, and call addToken() to - * add syntax tokens to the token list. Then, it should return - * the initial token type for the next line.

- * - * For example if the current line contains the start of a - * multiline comment that doesn't end on that line, this method - * should return the comment token type so that it continues on - * the next line. - * - * @param token The initial token type for this line - * @param line The line to be tokenized - * @param lineIndex The index of the line in the document, - * starting at 0 - * @return The initial token type for the next line - */ - protected abstract byte markTokensImpl(byte token, Segment line, - int lineIndex); - - /** - * Returns if the token marker supports tokens that span multiple - * lines. If this is true, the object using this token marker is - * required to pass all lines in the document to the - * markTokens() method (in turn).

- * - * The default implementation returns true; it should be overridden - * to return false on simpler token markers for increased speed. - */ - public boolean supportsMultilineTokens() - { - return true; - } - - /** - * Informs the token marker that lines have been inserted into - * the document. This inserts a gap in the lineInfo - * array. - * @param index The first line number - * @param lines The number of lines - */ - public void insertLines(int index, int lines) - { - if(lines <= 0) - return; - length += lines; - ensureCapacity(length); - int len = index + lines; - System.arraycopy(lineInfo,index,lineInfo,len, - lineInfo.length - len); - - for(int i = index + lines - 1; i >= index; i--) - { - lineInfo[i] = new LineInfo(); - } - } - - /** - * Informs the token marker that line have been deleted from - * the document. This removes the lines in question from the - * lineInfo array. - * @param index The first line number - * @param lines The number of lines - */ - public void deleteLines(int index, int lines) - { - if (lines <= 0) - return; - int len = index + lines; - length -= lines; - System.arraycopy(lineInfo,len,lineInfo, - index,lineInfo.length - len); - } - - /** - * Returns the number of lines in this token marker. - */ - public int getLineCount() - { - return length; - } - - /** - * Returns true if the next line should be repainted. This - * will return true after a line has been tokenized that starts - * a multiline token that continues onto the next line. - */ - public boolean isNextLineRequested() - { - return nextLineRequested; - } - - // protected members - - /** - * The first token in the list. This should be used as the return - * value from markTokens(). - */ - protected Token firstToken; - - /** - * The last token in the list. New tokens are added here. - * This should be set to null before a new line is to be tokenized. - */ - protected Token lastToken; - - /** - * An array for storing information about lines. It is enlarged and - * shrunk automatically by the insertLines() and - * deleteLines() methods. - */ - protected LineInfo[] lineInfo; - - /** - * The number of lines in the model being tokenized. This can be - * less than the length of the lineInfo array. - */ - protected int length; - - /** - * The last tokenized line. - */ - protected int lastLine; - - /** - * True if the next line should be painted. - */ - protected boolean nextLineRequested; - - /** - * Creates a new TokenMarker. This DOES NOT create - * a lineInfo array; an initial call to insertLines() - * does that. - */ - protected TokenMarker() - { - lastLine = -1; - } - - /** - * Ensures that the lineInfo array can contain the - * specified index. This enlarges it if necessary. No action is - * taken if the array is large enough already.

- * - * It should be unnecessary to call this under normal - * circumstances; insertLine() should take care of - * enlarging the line info array automatically. - * - * @param index The array index - */ - protected void ensureCapacity(int index) - { - if(lineInfo == null) - lineInfo = new LineInfo[index + 1]; - else if(lineInfo.length <= index) - { - LineInfo[] lineInfoN = new LineInfo[(index + 1) * 2]; - System.arraycopy(lineInfo,0,lineInfoN,0, - lineInfo.length); - lineInfo = lineInfoN; - } - } - - /** - * Adds a token to the token list. - * @param length The length of the token - * @param id The id of the token - */ - protected void addToken(int length, byte id) - { - if(id >= Token.INTERNAL_FIRST && id <= Token.INTERNAL_LAST) - throw new InternalError("Invalid id: " + id); - - if(length == 0 && id != Token.END) - return; - - if(firstToken == null) - { - firstToken = new Token(length,id); - lastToken = firstToken; - } - else if(lastToken == null) - { - lastToken = firstToken; - firstToken.length = length; - firstToken.id = id; - } - else if(lastToken.next == null) - { - lastToken.next = new Token(length,id); - lastToken = lastToken.next; - } - else - { - lastToken = lastToken.next; - lastToken.length = length; - lastToken.id = id; - } - } - - /** - * Inner class for storing information about tokenized lines. - */ - private static class LineInfo - { - /** - * Creates a new LineInfo object with token = Token.NULL - * and obj = null. - */ - public LineInfo() - { - } - - /** - * Creates a new LineInfo object with the specified - * parameters. - */ -// public LineInfo(byte token, Object obj) -// { -// this.token = token; -// this.obj = obj; -// } - - /** - * The id of the last token of the line. - */ - public byte token; - - /** - * This is for use by the token marker implementations - * themselves. It can be used to store anything that - * is an object and that needs to exist on a per-line - * basis. - */ -// public Object obj; - } +public abstract class TokenMarker { + + public interface TokenListener { + void addToken(int length, byte id); + } + + // Only needed during markTokensImpl() call so addToken() can be forwarded + private TokenListener tokenListener = null; + + public final void setTokenListener(TokenListener listener) { + this.tokenListener = listener; + } + + public final TokenMarkerState createStateInstance() { + return new TokenMarkerState(this); + } + + /** + * Creates a new TokenMarker. This DOES NOT create + * a lineInfo array; an initial call to insertLines() + * does that. + */ + protected TokenMarker() { } + + abstract public void addColoring(String keyword, String coloring); + + /** + * An abstract method that splits a line up into tokens. It + * should parse the line, and call addToken() to + * add syntax tokens to the token list. Then, it should return + * the initial token type for the next line.

+ *

+ * For example if the current line contains the start of a + * multiline comment that doesn't end on that line, this method + * should return the comment token type so that it continues on + * the next line. + * + * @param token The initial token type for this line + * @param line The line to be tokenized + * @param lineIndex The index of the line in the document, + * starting at 0 + * @return The initial token type for the next line + */ + protected abstract byte markTokensImpl(byte token, Segment line, + int lineIndex); + + protected final void addToken(int length, byte id) { + if (tokenListener != null) { + tokenListener.addToken(length, id); + } + } + + /** + * Returns if the token marker supports tokens that span multiple + * lines. If this is true, the object using this token marker is + * required to pass all lines in the document to the + * markTokens() method (in turn).

+ *

+ * The default implementation returns true; it should be overridden + * to return false on simpler token markers for increased speed. + */ + public boolean supportsMultilineTokens() { + return true; + } } diff --git a/app/src/processing/app/syntax/TokenMarkerState.java b/app/src/processing/app/syntax/TokenMarkerState.java new file mode 100644 index 0000000000..8b20b2603c --- /dev/null +++ b/app/src/processing/app/syntax/TokenMarkerState.java @@ -0,0 +1,266 @@ +package processing.app.syntax; + +import javax.swing.text.Segment; + +/** + * This class serves only as a workaround to preserve API and should be removed + * in the next major version. Base TokenMarker which serves as superclass for + * token markes for various modes is stateful, but single instance was shared + * between all tabs and Editors. This caused inherent bugs by leaking state + * between contexts. + * + * TokenMarker subclasses now serve two purposes: they keep keyword list and + * they override markTokensImpl to provide the marking logic. + * + * Since each tab and Editor should have it's own token marker state, I extracted + * most of the fields and associated metods working with them from TokenMarker + * into this class, and allowed TokenMarker to create instances of this class + * when requested. + * + * The way marking logic is handled is unfortunate, since markTokensImpl is + * expected to call addToken() of TokenMarker superclass instead of – for + * example - returning a List of tokens. I worked around this by plugging in + * TokenMarkerState instance as listener before markTokensImpl is called. + * This behavior is safe since TokenMarker is always operated from Event + * Dispatch Thread and no multithreading is involved. + * + * This allows having only single instance of TokenMarker in a way it was + * intended before while keeping state separate for each tab. + * + * In the next major version TokenMarker shound be redesigned with following + * requirements in mind: + * - Single instance of keyword list and other common data, initialized by Mode + * - Each tab should have its own instance of TokenMarker containing its state + * - Support multiple flavors for different doc types + * - Other modes should provide logic in a way which is compatible with + * multiple states (pure function? Function object?). + * Currently state, logic and keywords list are tied together into one + * TokenMarker instance, which leads to need for this workaround. + */ +public class TokenMarkerState { + + protected TokenMarker marker; + + protected TokenMarkerState(TokenMarker marker) { + this.marker = marker; + } + + /** + * The first token in the list. This should be used as the return + * value from markTokens(). + */ + protected Token firstToken; + + /** + * The last token in the list. New tokens are added here. + * This should be set to null before a new line is to be tokenized. + */ + protected Token lastToken; + + /** + * An array for storing information about lines. It is enlarged and + * shrunk automatically by the insertLines() and + * deleteLines() methods. + */ + protected byte[] lineInfo; + + /** + * The number of lines in the model being tokenized. This can be + * less than the length of the lineInfo array. + */ + protected int length; + + /** + * The last tokenized line. + */ + protected int lastLine = -1; + + /** + * True if the next line should be painted. + */ + protected boolean nextLineRequested; + + /** + * A wrapper for the lower-level markTokensImpl method + * that is called to split a line up into tokens. + * + * @param line The line + * @param lineIndex The line number + */ + public Token markTokens(Segment line, int lineIndex) { + if (lineIndex >= length) { + throw new IllegalArgumentException("Tokenizing invalid line: " + + lineIndex); + } + + marker.setTokenListener(this::addToken); + + lastToken = null; + + byte prev = (lineIndex == 0) ? Token.NULL : lineInfo[lineIndex - 1]; + + byte oldToken = lineInfo[lineIndex]; + byte token = marker.markTokensImpl(prev, line, lineIndex); + + marker.setTokenListener(null); + + lineInfo[lineIndex] = token; + + /* + * This is a foul hack. It stops nextLineRequested + * from being cleared if the same line is marked twice. + * + * Why is this necessary? It's all JEditTextArea's fault. + * When something is inserted into the text, firing a + * document event, the insertUpdate() method shifts the + * caret (if necessary) by the amount inserted. + * + * All caret movement is handled by the select() method, + * which eventually pipes the new position to scrollTo() + * and calls repaint(). + * + * Note that at this point in time, the new line hasn't + * yet been painted; the caret is moved first. + * + * scrollTo() calls offsetToX(), which tokenizes the line + * unless it is being called on the last line painted + * (in which case it uses the text area's painter cached + * token list). What scrollTo() does next is irrelevant. + * + * After scrollTo() has done it's job, repaint() is + * called, and eventually we end up in paintLine(), whose + * job is to paint the changed line. It, too, calls + * markTokens(). + * + * The problem was that if the line started a multiline + * token, the first markTokens() (done in offsetToX()) + * would set nextLineRequested (because the line end + * token had changed) but the second would clear it + * (because the line was the same that time) and therefore + * paintLine() would never know that it needed to repaint + * subsequent lines. + * + * This bug took me ages to track down, that's why I wrote + * all the relevant info down so that others wouldn't + * duplicate it. + */ + if (!(lastLine == lineIndex && nextLineRequested)) { + nextLineRequested = (oldToken != token); + } + + lastLine = lineIndex; + + addToken(0, Token.END); + + return firstToken; + } + + /** + * Informs the token marker that lines have been inserted into + * the document. This inserts a gap in the lineInfo + * array. + * + * @param index The first line number + * @param lines The number of lines + */ + public void insertLines(int index, int lines) { + if (lines <= 0) + return; + length += lines; + ensureCapacity(length); + int len = index + lines; + System.arraycopy(lineInfo, index, lineInfo, len, + lineInfo.length - len); + + for (int i = index + lines - 1; i >= index; i--) { + lineInfo[i] = Token.NULL; + } + } + + /** + * Informs the token marker that line have been deleted from + * the document. This removes the lines in question from the + * lineInfo array. + * + * @param index The first line number + * @param lines The number of lines + */ + public void deleteLines(int index, int lines) { + if (lines <= 0) + return; + int len = index + lines; + length -= lines; + System.arraycopy(lineInfo, len, lineInfo, + index, lineInfo.length - len); + } + + /** + * Returns the number of lines in this token marker. + */ + public int getLineCount() { + return length; + } + + /** + * Returns true if the next line should be repainted. This + * will return true after a line has been tokenized that starts + * a multiline token that continues onto the next line. + */ + public boolean isNextLineRequested() { + return nextLineRequested; + } + + /** + * Ensures that the lineInfo array can contain the + * specified index. This enlarges it if necessary. No action is + * taken if the array is large enough already.

+ *

+ * It should be unnecessary to call this under normal + * circumstances; insertLine() should take care of + * enlarging the line info array automatically. + * + * @param index The array index + */ + protected void ensureCapacity(int index) { + if (lineInfo == null) { + lineInfo = new byte[index + 1]; + } else if (lineInfo.length <= index) { + byte[] lineInfoN = new byte[(index + 1) * 2]; + System.arraycopy(lineInfo, 0, lineInfoN, 0, + lineInfo.length); + lineInfo = lineInfoN; + } + } + + /** + * Adds a token to the token list. + * + * @param length The length of the token + * @param id The id of the token + */ + protected void addToken(int length, byte id) { + if (id >= Token.INTERNAL_FIRST && id <= Token.INTERNAL_LAST) { + throw new InternalError("Invalid id: " + id); + } + + if (length == 0 && id != Token.END) { + return; + } + + if (firstToken == null) { + firstToken = new Token(length, id); + lastToken = firstToken; + } else if (lastToken == null) { + lastToken = firstToken; + firstToken.length = length; + firstToken.id = id; + } else if (lastToken.next == null) { + lastToken.next = new Token(length, id); + lastToken = lastToken.next; + } else { + lastToken = lastToken.next; + lastToken.length = length; + lastToken.id = id; + } + } +} From 694c0b9166dce87b41b701da80e30f7f3a3d0f03 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 4 Dec 2016 16:47:19 -0500 Subject: [PATCH 158/917] better error message when running from the .zip file --- build/windows/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/windows/config.xml b/build/windows/config.xml index 1d7955ca7c..3436d722ef 100755 --- a/build/windows/config.xml +++ b/build/windows/config.xml @@ -53,7 +53,7 @@ An error occurred while starting the application. This application was configured to use a bundled Java Runtime Environment but the runtime is missing or corrupted. If running from a folder with non-ASCII characters, try moving this folder to another location. - Required files could not be found. If running from a folder with non-ASCII characters, try moving this folder to another location. + Required files could not be found. Be sure to first extract the entire Processing folder from the .zip file download. Or if running from a folder with non-ASCII characters, try moving the Processing folder to another location. The registry refers to a nonexistent Java installation or the runtime is corrupted. An application instance is already running. From 261ae12cf8f997b3f1cf170d8da1d1ee3566191a Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 4 Dec 2016 16:47:48 -0500 Subject: [PATCH 159/917] fix exceptions from pasting code into Editor (#4522, #4761) --- todo.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/todo.txt b/todo.txt index 444a7929e4..523f7b7b5f 100755 --- a/todo.txt +++ b/todo.txt @@ -29,6 +29,10 @@ X https://github.com/processing/processing/pull/4744 X 'web colors' next to each other fail to parse in certain situations X https://github.com/processing/processing/issues/4752 X https://github.com/processing/processing/pull/4753 +X Pasting code from editor to empty editor produces Exception +X https://github.com/processing/processing/issues/4522 +X https://github.com/processing/processing/pull/4761 + _ Broken characters in the Welcome Page and the Contribution Manager _ looks like a failure to load the Source Sans font @@ -86,8 +90,6 @@ _ https://github.com/processing/processing/issues/4353#issuecomment-237715947 high -_ Pasting code from editor to empty editor produces Exception -_ https://github.com/processing/processing/issues/4522 _ possible infinite loop on modified externally _ https://github.com/processing/processing/issues/3965 _ PDE and sketches are 2x smaller on high-res Windows machines From 0cb42f9a32ca42a04c13ce3ff5c4c94546eec918 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Mon, 5 Dec 2016 03:46:44 +0100 Subject: [PATCH 160/917] Clean up ChangeDetector Fixes #3965 --- app/src/processing/app/ui/ChangeDetector.java | 327 +++++++----------- 1 file changed, 133 insertions(+), 194 deletions(-) diff --git a/app/src/processing/app/ui/ChangeDetector.java b/app/src/processing/app/ui/ChangeDetector.java index 866d2ffc45..6365740e74 100644 --- a/app/src/processing/app/ui/ChangeDetector.java +++ b/app/src/processing/app/ui/ChangeDetector.java @@ -1,13 +1,18 @@ package processing.app.ui; import java.awt.EventQueue; -import java.awt.Frame; import java.awt.event.WindowEvent; import java.awt.event.WindowFocusListener; -import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ForkJoinPool; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.swing.JOptionPane; @@ -21,6 +26,9 @@ public class ChangeDetector implements WindowFocusListener { private final Sketch sketch; private final Editor editor; + private List ignoredAdditions = new ArrayList<>(); + private List ignoredRemovals = new ArrayList<>(); + // Windows and others seem to have a few hundred ms difference in reported // times, so we're arbitrarily setting a gap in time here. // Mac OS X has an (exactly) one second difference. Not sure if it's a Java @@ -32,9 +40,6 @@ public class ChangeDetector implements WindowFocusListener { static private final boolean DEBUG = Preferences.getBoolean("editor.watcher.debug"); - // Store the known number of files to avoid re-asking about the same change -// private int lastKnownCount = -1; - public ChangeDetector(Editor editor) { this.sketch = editor.sketch; @@ -44,27 +49,19 @@ public ChangeDetector(Editor editor) { @Override public void windowGainedFocus(WindowEvent e) { - // When the window is activated, fire off a Thread to check for changes if (Preferences.getBoolean("editor.watcher")) { - new Thread(new Runnable() { - @Override - public void run() { - if (sketch != null) { - // make sure the sketch folder exists at all. - // if it does not, it will be re-saved, and no changes will be detected - sketch.ensureExistence(); - -// if (lastKnownCount == -1) { -// lastKnownCount = sketch.getCodeCount(); -// } - - boolean alreadyPrompted = checkFileCount(); - if (!alreadyPrompted) { - checkFileTimes(); - } - } - } - }).start(); + if (sketch != null) { + // make sure the sketch folder exists at all. + // if it does not, it will be re-saved, and no changes will be detected + sketch.ensureExistence(); // <- touches UI, stay on EDT + + // TODO: Not sure if we even need to run this async. Usually takes + // just a few ms and we probably want to prevent any changes from + // users until the external changes are sorted out. [jv 2016-12-05] + + // Run task in common pool, starting threads directly is so Java 6 + ForkJoinPool.commonPool().execute(this::checkFiles); + } } } @@ -76,205 +73,147 @@ public void windowLostFocus(WindowEvent e) { } - private boolean checkFileCount() { - // check file count first + // Synchronize, we are running async and touching fields + private synchronized void checkFiles() { List filenames = new ArrayList<>(); - sketch.getSketchCodeFiles(filenames, null); - int fileCount = filenames.size(); + SketchCode[] codes = sketch.getCode(); - // Was considering keeping track of the last "known" number of files - // (instead of using sketch.getCodeCount() here) in case the user - // didn't want to reload after the number of files had changed. - // However, that's a bad situation anyway and there aren't good - // ways to recover or work around it, so just prompt the user again. - if (fileCount == sketch.getCodeCount()) { - return false; - } + // Separate codes with and without files + Map> existsMap = Arrays.stream(codes) + .collect(Collectors.groupingBy(code -> filenames.contains(code.getFileName()))); - if (DEBUG) { - System.out.println(sketch.getName() + " file count now " + fileCount + - " instead of " + sketch.getCodeCount()); - } - if (reloadPrompt()) { - if (sketch.getMainFile().exists()) { - reloadSketch(); - } else { - // If the main file was deleted, and that's why we're here, - // then we need to re-save the sketch instead. - try { - // Mark everything as modified so that it saves properly - for (SketchCode code : sketch.getCode()) { - code.setModified(true); - } - sketch.save(); - } catch (Exception e) { - //if that didn't work, tell them it's un-recoverable - showErrorEDT("Reload Failed", - "The main file for this sketch was deleted\n" + - "and could not be rewritten.", e); - } - } + // ADDED FILES - /* - if (fileCount < 1) { - // if they chose to reload and there aren't any files left - try { - // make a blank file for the main PDE - sketch.getMainFile().createNewFile(); - } catch (Exception e1) { - //if that didn't work, tell them it's un-recoverable - showErrorEDT("Reload failed", "The sketch contains no code files.", e1); - //don't try to reload again after the double fail - //this editor is probably trashed by this point, but a save-as might be possible -// skip = true; - return true; - } - // it's okay to do this without confirmation, because they already - // confirmed to deleting the unsaved changes above - sketch.reload(); - showWarningEDT("Modified Reload", - "You cannot delete the last code file in a sketch.\n" + - "A new blank sketch file has been generated for you."); - } - */ - } else { // !reload (user said no or closed the window) - // Because the number of files changed, they may be working with a file - // that doesn't exist any more. So find the files that are missing, - // and mark them as modified so that the next "Save" will write them. - for (SketchCode code : sketch.getCode()) { - if (!code.getFile().exists()) { - setCodeModified(code); - } - } - rebuildHeaderEDT(); - } - // Yes, we've brought this up with the user (so don't bother them further) - return true; - } + List codeFilenames = Arrays.stream(codes) + .map(SketchCode::getFileName) + .collect(Collectors.toList()); + // Get filenames which are in filesystem but don't have code + List addedFilenames = filenames.stream() + .filter(f -> !codeFilenames.contains(f)) + .collect(Collectors.toList()); - private void checkFileTimes() { - List reloadList = new ArrayList<>(); - for (SketchCode code : sketch.getCode()) { - File sketchFile = code.getFile(); - if (sketchFile.exists()) { - long diff = sketchFile.lastModified() - code.getLastModified(); - if (diff > MODIFICATION_WINDOW_MILLIS) { - if (DEBUG) System.out.println(sketchFile.getName() + " " + diff + "ms"); - reloadList.add(code); - } - } else { - // If a file in the sketch was not found, then it must have been - // deleted externally, so reload the sketch. - if (DEBUG) System.out.println(sketchFile.getName() + " (file disappeared)"); - reloadList.add(code); - } - } + // Show prompt if there are any added files which were not previously ignored + boolean added = addedFilenames.stream() + .anyMatch(f -> !ignoredAdditions.contains(f)); - // If there are any files that need to be reloaded - if (reloadList.size() > 0) { - if (reloadPrompt()) { - reloadSketch(); - - } else { - // User said no, but take bulletproofing actions - for (SketchCode code : reloadList) { - // Set the file as modified in the Editor so the contents will - // save to disk when the user saves from inside Processing. - setCodeModified(code); - // Since this was canceled, update the "last modified" time so we - // don't ask the user about it again. - code.setLastModified(); - } - rebuildHeaderEDT(); - } - } - } + // REMOVED FILES - private void setCodeModified(SketchCode sc) { - sc.setModified(true); - sketch.setModified(true); - } + // Get codes which don't have file + List removedCodes = Optional.ofNullable(existsMap.get(Boolean.FALSE)) + .orElse(Collections.emptyList()); + // Show prompt if there are any removed codes which were not previously ignored + boolean removed = removedCodes.stream() + .anyMatch(code -> !ignoredRemovals.contains(code)); - private void reloadSketch() { - sketch.reload(); - rebuildHeaderEDT(); - } + /// MODIFIED FILES - /** - * Prompt the user whether to reload the sketch. If the user says yes, - * perform the actual reload. - * @return true if user said yes, false if they hit No or closed the window - */ - private boolean reloadPrompt() { - int response = blockingYesNoPrompt(editor, - "File Modified", - "Your sketch has been modified externally.
" + - "Would you like to reload the sketch?", - "If you reload the sketch, any unsaved changes will be lost."); - return response == JOptionPane.YES_OPTION; - } + // Get codes which have file with different modification time + List modifiedCodes = Optional.ofNullable(existsMap.get(Boolean.TRUE)) + .orElse(Collections.emptyList()) + .stream() + .filter(code -> { + long fileLastModified = code.getFile().lastModified(); + long codeLastModified = code.getLastModified(); + long diff = fileLastModified - codeLastModified; + return fileLastModified == 0L || diff > MODIFICATION_WINDOW_MILLIS; + }) + .collect(Collectors.toList()); + // Show prompt if any open codes were modified + boolean modified = !modifiedCodes.isEmpty(); - private void showErrorEDT(final String title, final String message, - final Exception e) { - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - Messages.showError(title, message, e); - } - }); - } + boolean ask = added || removed || modified; - /* - private void showWarningEDT(final String title, final String message) { - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - Messages.showWarning(title, message); - } - }); - } - */ + if (DEBUG) { + System.out.println("ask: " + ask + "\n" + + "added filenames: " + addedFilenames + ",\n" + + "ignored added: " + ignoredAdditions + ",\n" + + "removed codes: " + removedCodes + ",\n" + + "ignored removed: " + ignoredRemovals + ",\n" + + "modified codes: " + modifiedCodes); + } - private int blockingYesNoPrompt(final Frame editor, final String title, - final String message1, - final String message2) { - final int[] result = { -1 }; // yuck + // This has to happen in one go and also touches UI everywhere. It has to + // run on EDT, otherwise windowGainedFocus callback runs again right after + // dismissing the prompt and we get another prompt before we even finished. try { - //have to wait for a response on this one - EventQueue.invokeAndWait(new Runnable() { - @Override - public void run() { - result[0] = Messages.showYesNoQuestion(editor, title, message1, message2); + // Wait for EDT to finish its business + // We need to stay in synchronized scope because of ignore lists + EventQueue.invokeAndWait(() -> { + // Show prompt if something interesting happened + if (ask && showReloadPrompt()) { + // She said yes!!! + if (sketch.getMainFile().exists()) { + sketch.reload(); + editor.rebuildHeader(); + } else { + // If the main file was deleted, and that's why we're here, + // then we need to re-save the sketch instead. + // Mark everything as modified so that it saves properly + for (SketchCode code : codes) { + code.setModified(true); + } + try { + sketch.save(); + } catch (Exception e) { + //if that didn't work, tell them it's un-recoverable + Messages.showError("Reload Failed", "The main file for this sketch was deleted\n" + + "and could not be rewritten.", e); + } + } + + // Sketch was reloaded, clear ignore lists + ignoredAdditions.clear(); + ignoredRemovals.clear(); + + return; + } + + // Update ignore lists to get rid of old stuff + ignoredAdditions = addedFilenames; + ignoredRemovals = removedCodes; + + // If something changed, set modified flags and modification times + if (!removedCodes.isEmpty() || !modifiedCodes.isEmpty()) { + Stream.concat(removedCodes.stream(), modifiedCodes.stream()) + .forEach(code -> { + code.setModified(true); + code.setLastModified(); + }); + + // Not sure if this is needed + editor.rebuildHeader(); } }); + } catch (InterruptedException ignore) { } catch (InvocationTargetException e) { - //occurs if Base.showYesNoQuestion throws an error, so, shouldn't happen - e.getTargetException().printStackTrace(); - } catch (InterruptedException e) { - //occurs if the EDT is interrupted, so, shouldn't happen - e.printStackTrace(); + Messages.loge("exception in ChangeDetector", e); } - return result[0]; + } - private void rebuildHeaderEDT() { - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - editor.header.rebuild(); - } - }); + /** + * Prompt the user whether to reload the sketch. If the user says yes, + * perform the actual reload. + * @return true if user said yes, false if they hit No or closed the window + */ + private boolean showReloadPrompt() { + int response = Messages + .showYesNoQuestion(editor, "File Modified", + "Your sketch has been modified externally.
" + + "Would you like to reload the sketch?", + "If you reload the sketch, any unsaved changes will be lost."); + return response == JOptionPane.YES_OPTION; } } From c580d99800e79a3e01a47d4fbef418e26dd59230 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 6 Dec 2016 17:35:43 -0500 Subject: [PATCH 161/917] notes about #3965 fix --- todo.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/todo.txt b/todo.txt index 523f7b7b5f..48a6ba80e8 100755 --- a/todo.txt +++ b/todo.txt @@ -32,6 +32,9 @@ X https://github.com/processing/processing/pull/4753 X Pasting code from editor to empty editor produces Exception X https://github.com/processing/processing/issues/4522 X https://github.com/processing/processing/pull/4761 +X possible infinite loop on modified externally +X https://github.com/processing/processing/issues/3965 +X https://github.com/processing/processing/pull/4762 _ Broken characters in the Welcome Page and the Contribution Manager @@ -90,8 +93,6 @@ _ https://github.com/processing/processing/issues/4353#issuecomment-237715947 high -_ possible infinite loop on modified externally -_ https://github.com/processing/processing/issues/3965 _ PDE and sketches are 2x smaller on high-res Windows machines _ https://github.com/processing/processing/issues/2411 _ System.setProperty("sun.java2d.dpiaware", "false"); From c607a0df9ca5f9eb26b4504526441234de6d2ee4 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 15 Dec 2016 23:10:29 +0100 Subject: [PATCH 162/917] Clean up ErrorMessageSimplifier Remove weird unused thread-spawning constructor Accept IProblem instead of whole JavaProblem Move fallback process() from JavaProblem to EMSimplifier as a default case Add debug switch and move debug logging into if blocks --- .../java/pdex/ErrorMessageSimplifier.java | 62 ++++++++++++------- .../mode/java/pdex/JavaProblem.java | 31 +--------- 2 files changed, 40 insertions(+), 53 deletions(-) diff --git a/java/src/processing/mode/java/pdex/ErrorMessageSimplifier.java b/java/src/processing/mode/java/pdex/ErrorMessageSimplifier.java index df7909e8ee..efb8d2e702 100644 --- a/java/src/processing/mode/java/pdex/ErrorMessageSimplifier.java +++ b/java/src/processing/mode/java/pdex/ErrorMessageSimplifier.java @@ -23,11 +23,14 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.internal.compiler.problem.DefaultProblem; import processing.app.Language; +import processing.app.Messages; import processing.core.PApplet; import processing.data.StringList; @@ -42,25 +45,20 @@ public class ErrorMessageSimplifier { */ private static TreeMap constantsMap; + private static final boolean DEBUG = false; - public ErrorMessageSimplifier() { - - new Thread() { - public void run() { - prepareConstantsList(); - } - }.start(); - } - + private static final Pattern tokenRegExp = Pattern.compile("\\b token\\b"); private static void prepareConstantsList() { - constantsMap = new TreeMap(); + constantsMap = new TreeMap<>(); Class probClass = DefaultProblem.class; Field f[] = probClass.getFields(); for (Field field : f) { if (Modifier.isStatic(field.getModifiers())) try { - //System.out.println(field.getName() + " :" + field.get(null)); + if (DEBUG) { + Messages.log(field.getName() + " :" + field.get(null)); + } Object val = field.get(null); if (val instanceof Integer) { constantsMap.put((Integer) (val), field.getName()); @@ -70,7 +68,9 @@ private static void prepareConstantsList() { break; } } - //System.out.println("Total items: " + constantsMap.size()); + if (DEBUG) { + Messages.log("Total items: " + constantsMap.size()); + } } @@ -85,17 +85,19 @@ public static String getIDName(int id) { /** * Tones down the jargon in the ecj reported errors. */ - public static String getSimplifiedErrorMessage(JavaProblem problem) { - if (problem == null) return null; + public static String getSimplifiedErrorMessage(IProblem iprob) { + if (iprob == null) return null; - IProblem iprob = problem.getIProblem(); String args[] = iprob.getArguments(); -// Base.log("Simplifying message: " + problem.getMessage() + " ID: " -// + getIDName(iprob.getID())); -// Base.log("Arg count: " + args.length); -// for (int i = 0; i < args.length; i++) { -// Base.log("Arg " + args[i]); -// } + + if (DEBUG) { + Messages.log("Simplifying message: " + iprob.getMessage() + + " ID: " + getIDName(iprob.getID())); + Messages.log("Arg count: " + args.length); + for (String arg : args) { + Messages.log("Arg " + arg); + } + } String result = null; @@ -259,10 +261,24 @@ public static String getSimplifiedErrorMessage(JavaProblem problem) { if (args.length > 0) { result = Language.interpolate("editor.status.hiding_enclosing_type", args[0]); } + break; + + default: + String message = iprob.getMessage(); + if (message != null) { + // Remove all instances of token + // "Syntax error on token 'blah', delete this token" + Matcher matcher = tokenRegExp.matcher(message); + message = matcher.replaceAll(""); + result = message; + } + } + + if (DEBUG) { + Messages.log("Simplified Error Msg: " + result); } - //log("Simplified Error Msg: " + result); - return (result == null) ? problem.getMessage() : result; + return result; } diff --git a/java/src/processing/mode/java/pdex/JavaProblem.java b/java/src/processing/mode/java/pdex/JavaProblem.java index bb4da88987..1aeb38c850 100644 --- a/java/src/processing/mode/java/pdex/JavaProblem.java +++ b/java/src/processing/mode/java/pdex/JavaProblem.java @@ -20,9 +20,6 @@ package processing.mode.java.pdex; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import org.eclipse.jdt.core.compiler.IProblem; import processing.app.Problem; @@ -83,9 +80,7 @@ else if(iProblem.isWarning()) { } this.tabIndex = tabIndex; this.lineNumber = lineNumber; - this.message = process(iProblem); - this.message = ErrorMessageSimplifier.getSimplifiedErrorMessage(this); - //ErrorMessageSimplifier.getSimplifiedErrorMessage(this); + this.message = ErrorMessageSimplifier.getSimplifiedErrorMessage(iProblem); } public void setPDEOffsets(int startOffset, int stopOffset){ @@ -157,30 +152,6 @@ public void setImportSuggestions(String[] a) { importSuggestions = a; } - private static final Pattern tokenRegExp = Pattern.compile("\\b token\\b"); - - public static String process(IProblem problem) { - return process(problem.getMessage()); - } - - /** - * Processes error messages and attempts to make them a bit more english like. - * Currently performs: - *

  • Remove all instances of token. "Syntax error on token 'blah', delete this token" - * becomes "Syntax error on 'blah', delete this" - * @param message - The message to be processed - * @return String - The processed message - */ - public static String process(String message) { - // Remove all instances of token - // "Syntax error on token 'blah', delete this token" - if(message == null) return null; - Matcher matcher = tokenRegExp.matcher(message); - message = matcher.replaceAll(""); - - return message; - } - // Split camel case words into separate words. // "VaraibleDeclaration" becomes "Variable Declaration" // But sadly "PApplet" become "P Applet" and so on. From 84258d9f4ad38e308dd5b35a2e9390e71cc5a6a9 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 15 Dec 2016 23:11:40 +0100 Subject: [PATCH 163/917] Fix ErrorMessageSimplifier indents (no functional changes) --- .../java/pdex/ErrorMessageSimplifier.java | 273 +++++++++--------- 1 file changed, 136 insertions(+), 137 deletions(-) diff --git a/java/src/processing/mode/java/pdex/ErrorMessageSimplifier.java b/java/src/processing/mode/java/pdex/ErrorMessageSimplifier.java index efb8d2e702..c77584e213 100644 --- a/java/src/processing/mode/java/pdex/ErrorMessageSimplifier.java +++ b/java/src/processing/mode/java/pdex/ErrorMessageSimplifier.java @@ -75,7 +75,7 @@ private static void prepareConstantsList() { public static String getIDName(int id) { - if (constantsMap == null){ + if (constantsMap == null) { prepareConstantsList(); } return constantsMap.get(id); @@ -103,175 +103,174 @@ public static String getSimplifiedErrorMessage(IProblem iprob) { switch (iprob.getID()) { - case IProblem.ParsingError: - if (args.length > 0) { - result = Language.interpolate("editor.status.error_on", args[0]); - } - break; - - case IProblem.ParsingErrorDeleteToken: - if (args.length > 0) { - result = Language.interpolate("editor.status.error_on", args[0]); - } - break; - - case IProblem.ParsingErrorInsertToComplete: - if (args.length > 0) { - if (args[0].length() == 1) { - result = getErrorMessageForBracket(args[0].charAt(0)); + case IProblem.ParsingError: + if (args.length > 0) { + result = Language.interpolate("editor.status.error_on", args[0]); + } + break; - } else { - if (args[0].equals("AssignmentOperator Expression")) { - result = Language.interpolate("editor.status.missing.add", "="); + case IProblem.ParsingErrorDeleteToken: + if (args.length > 0) { + result = Language.interpolate("editor.status.error_on", args[0]); + } + break; - } else if (args[0].equalsIgnoreCase(") Statement")) { + case IProblem.ParsingErrorInsertToComplete: + if (args.length > 0) { + if (args[0].length() == 1) { result = getErrorMessageForBracket(args[0].charAt(0)); } else { - result = Language.interpolate("editor.status.error_on", args[0]); + if (args[0].equals("AssignmentOperator Expression")) { + result = Language.interpolate("editor.status.missing.add", "="); + + } else if (args[0].equalsIgnoreCase(") Statement")) { + result = getErrorMessageForBracket(args[0].charAt(0)); + + } else { + result = Language.interpolate("editor.status.error_on", args[0]); + } } } - } - break; - - case IProblem.ParsingErrorInvalidToken: - if (args.length > 0) { - if (args[1].equals("VariableDeclaratorId")) { - if (args[0].equals("int")) { - result = Language.text ("editor.status.reserved_words"); + break; + + case IProblem.ParsingErrorInvalidToken: + if (args.length > 0) { + if (args[1].equals("VariableDeclaratorId")) { + if (args[0].equals("int")) { + result = Language.text("editor.status.reserved_words"); + } else { + result = Language.interpolate("editor.status.error_on", args[0]); + } } else { result = Language.interpolate("editor.status.error_on", args[0]); } - } else { - result = Language.interpolate("editor.status.error_on", args[0]); } - } - break; + break; - case IProblem.ParsingErrorInsertTokenAfter: - if (args.length > 0) { - if (args[1].length() == 1) { - result = getErrorMessageForBracket(args[1].charAt(0)); - } - else { - // https://github.com/processing/processing/issues/3104 - if (args[1].equalsIgnoreCase("Statement")) { - result = Language.interpolate("editor.status.error_on", args[0]); + case IProblem.ParsingErrorInsertTokenAfter: + if (args.length > 0) { + if (args[1].length() == 1) { + result = getErrorMessageForBracket(args[1].charAt(0)); } else { - result = - Language.interpolate("editor.status.error_on", args[0]) + " " + - Language.interpolate("editor.status.missing.add", args[1]); + // https://github.com/processing/processing/issues/3104 + if (args[1].equalsIgnoreCase("Statement")) { + result = Language.interpolate("editor.status.error_on", args[0]); + } else { + result = + Language.interpolate("editor.status.error_on", args[0]) + " " + + Language.interpolate("editor.status.missing.add", args[1]); + } } } - } - break; - - case IProblem.UndefinedConstructor: - if (args.length == 2) { - String constructorName = args[0]; - // For messages such as "contructor sketch_name.ClassXYZ() is undefined", change - // constructor name to "ClassXYZ()". See #3434 - if (constructorName.contains(".")) { - // arg[0] contains sketch name twice: sketch_150705a.sketch_150705a.Thing - constructorName = constructorName.substring(constructorName.indexOf('.') + 1); - constructorName = constructorName.substring(constructorName.indexOf('.') + 1); + break; + + case IProblem.UndefinedConstructor: + if (args.length == 2) { + String constructorName = args[0]; + // For messages such as "contructor sketch_name.ClassXYZ() is undefined", change + // constructor name to "ClassXYZ()". See #3434 + if (constructorName.contains(".")) { + // arg[0] contains sketch name twice: sketch_150705a.sketch_150705a.Thing + constructorName = constructorName.substring(constructorName.indexOf('.') + 1); + constructorName = constructorName.substring(constructorName.indexOf('.') + 1); + } + String constructorArgs = removePackagePrefixes(args[args.length - 1]); + result = Language.interpolate("editor.status.undefined_constructor", constructorName, constructorArgs); } - String constructorArgs = removePackagePrefixes(args[args.length - 1]); - result = Language.interpolate("editor.status.undefined_constructor", constructorName, constructorArgs); - } - break; + break; - case IProblem.UndefinedMethod: - if (args.length > 2) { - String methodName = args[args.length - 2]; - String methodArgs = removePackagePrefixes(args[args.length - 1]); - result = Language.interpolate("editor.status.undefined_method", methodName, methodArgs); - } - break; - - case IProblem.ParameterMismatch: - if (args.length > 3) { - // 2nd arg is method name, 3rd arg is correct param list - if (args[2].trim().length() == 0) { - // the case where no params are needed. - result = Language.interpolate("editor.status.empty_param", args[1]); - - } else { - result = Language.interpolate("editor.status.wrong_param", - args[1], args[1], removePackagePrefixes(args[2])); + case IProblem.UndefinedMethod: + if (args.length > 2) { + String methodName = args[args.length - 2]; + String methodArgs = removePackagePrefixes(args[args.length - 1]); + result = Language.interpolate("editor.status.undefined_method", methodName, methodArgs); + } + break; + + case IProblem.ParameterMismatch: + if (args.length > 3) { + // 2nd arg is method name, 3rd arg is correct param list + if (args[2].trim().length() == 0) { + // the case where no params are needed. + result = Language.interpolate("editor.status.empty_param", args[1]); + + } else { + result = Language.interpolate("editor.status.wrong_param", + args[1], args[1], removePackagePrefixes(args[2])); // String method = q(args[1]); // String methodDef = " \"" + args[1] + "(" + getSimpleName(args[2]) + ")\""; // result = result.replace("method", method); // result += methodDef; + } } - } - break; + break; - case IProblem.UndefinedField: - if (args.length > 0) { - result = Language.interpolate("editor.status.undef_global_var", args[0]); - } - break; + case IProblem.UndefinedField: + if (args.length > 0) { + result = Language.interpolate("editor.status.undef_global_var", args[0]); + } + break; - case IProblem.UndefinedType: - if (args.length > 0) { - result = Language.interpolate("editor.status.undef_class", args[0]); - } - break; + case IProblem.UndefinedType: + if (args.length > 0) { + result = Language.interpolate("editor.status.undef_class", args[0]); + } + break; - case IProblem.UnresolvedVariable: - if (args.length > 0) { - result = Language.interpolate("editor.status.undef_var", args[0]); - } - break; + case IProblem.UnresolvedVariable: + if (args.length > 0) { + result = Language.interpolate("editor.status.undef_var", args[0]); + } + break; - case IProblem.UndefinedName: - if (args.length > 0) { - result = Language.interpolate("editor.status.undef_name", args[0]); - } - break; + case IProblem.UndefinedName: + if (args.length > 0) { + result = Language.interpolate("editor.status.undef_name", args[0]); + } + break; - case IProblem.TypeMismatch: - if (args.length > 1) { - result = Language.interpolate("editor.status.type_mismatch", args[0], args[1]); + case IProblem.TypeMismatch: + if (args.length > 1) { + result = Language.interpolate("editor.status.type_mismatch", args[0], args[1]); // result = result.replace("typeA", q(args[0])); // result = result.replace("typeB", q(args[1])); - } - break; + } + break; - case IProblem.LocalVariableIsNeverUsed: - if (args.length > 0) { - result = Language.interpolate("editor.status.unused_variable", args[0]); - } - break; + case IProblem.LocalVariableIsNeverUsed: + if (args.length > 0) { + result = Language.interpolate("editor.status.unused_variable", args[0]); + } + break; - case IProblem.UninitializedLocalVariable: - if (args.length > 0) { - result = Language.interpolate("editor.status.uninitialized_variable", args[0]); - } - break; + case IProblem.UninitializedLocalVariable: + if (args.length > 0) { + result = Language.interpolate("editor.status.uninitialized_variable", args[0]); + } + break; - case IProblem.AssignmentHasNoEffect: - if (args.length > 0) { - result = Language.interpolate("editor.status.no_effect_assignment", args[0]); - } - break; + case IProblem.AssignmentHasNoEffect: + if (args.length > 0) { + result = Language.interpolate("editor.status.no_effect_assignment", args[0]); + } + break; - case IProblem.HidingEnclosingType: - if (args.length > 0) { - result = Language.interpolate("editor.status.hiding_enclosing_type", args[0]); - } - break; - - default: - String message = iprob.getMessage(); - if (message != null) { - // Remove all instances of token - // "Syntax error on token 'blah', delete this token" - Matcher matcher = tokenRegExp.matcher(message); - message = matcher.replaceAll(""); - result = message; - } + case IProblem.HidingEnclosingType: + if (args.length > 0) { + result = Language.interpolate("editor.status.hiding_enclosing_type", args[0]); + } + break; + + default: + String message = iprob.getMessage(); + if (message != null) { + // Remove all instances of token + // "Syntax error on token 'blah', delete this token" + Matcher matcher = tokenRegExp.matcher(message); + message = matcher.replaceAll(""); + result = message; + } } if (DEBUG) { From a79fe7fdc45992ec6c5989d33939311784496fe1 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 15 Dec 2016 22:47:09 +0100 Subject: [PATCH 164/917] PDEX: simplify import suggestion handling --- java/src/processing/mode/java/pdex/PDEX.java | 51 +++++++++----------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/java/src/processing/mode/java/pdex/PDEX.java b/java/src/processing/mode/java/pdex/PDEX.java index 6182faed36..37b0d9b8e0 100644 --- a/java/src/processing/mode/java/pdex/PDEX.java +++ b/java/src/processing/mode/java/pdex/PDEX.java @@ -36,8 +36,10 @@ import java.util.Collections; import java.util.Comparator; import java.util.Deque; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -1074,6 +1076,9 @@ public void dispose() { private void handleSketchProblems(PreprocessedSketch ps) { + Map suggCache = + JavaMode.importSuggestEnabled ? new HashMap<>() : Collections.emptyMap(); + // Process problems IProblem[] iproblems = ps.compilationUnit.getProblems(); final List problems = Arrays.stream(iproblems) @@ -1095,38 +1100,20 @@ private void handleSketchProblems(PreprocessedSketch ps) { int line = ps.tabOffsetToTabLine(in.tabIndex, in.startTabOffset); JavaProblem p = new JavaProblem(iproblem, in.tabIndex, line); p.setPDEOffsets(in.startTabOffset, in.stopTabOffset); + + // Handle import suggestions + if (JavaMode.importSuggestEnabled && isUndefinedTypeProblem(iproblem)) { + ClassPath cp = ps.searchClassPath; + String[] s = suggCache.computeIfAbsent(iproblem.getArguments()[0], + name -> getImportSuggestions(cp, name)); + p.setImportSuggestions(s); + } + return p; }) - .filter(p -> p != null) + .filter(Objects::nonNull) .collect(Collectors.toList()); - // Handle import suggestions - if (JavaMode.importSuggestEnabled) { - Map> undefinedTypeProblems = problems.stream() - // Get only problems with undefined types/names - .filter(p -> { - int id = ((JavaProblem) p).getIProblem().getID(); - return id == IProblem.UndefinedType || - id == IProblem.UndefinedName || - id == IProblem.UnresolvedVariable; - }) - // Group problems by the missing type/name - .collect(Collectors.groupingBy(p -> ((JavaProblem) p).getIProblem().getArguments()[0])); - - if (!undefinedTypeProblems.isEmpty()) { - final ClassPath cp = ps.searchClassPath; - - // Get suggestions for each missing type, update the problems - undefinedTypeProblems.entrySet().stream() - .forEach(entry -> { - String missingClass = entry.getKey(); - List affectedProblems = entry.getValue(); - String[] suggestions = getImportSuggestions(cp, missingClass); - affectedProblems.forEach(p -> ((JavaProblem) p).setImportSuggestions(suggestions)); - }); - } - } - if (scheduledUiUpdate != null) { scheduledUiUpdate.cancel(true); } @@ -1142,6 +1129,14 @@ private void handleSketchProblems(PreprocessedSketch ps) { } + private boolean isUndefinedTypeProblem(IProblem iproblem) { + int id = iproblem.getID(); + return id == IProblem.UndefinedType || + id == IProblem.UndefinedName || + id == IProblem.UnresolvedVariable; + } + + public static String[] getImportSuggestions(ClassPath cp, String className) { RegExpResourceFilter regf = new RegExpResourceFilter( Pattern.compile(".*"), From 25a2a59621b348e955f4367ce8193d57398075c5 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 16 Dec 2016 00:15:10 +0100 Subject: [PATCH 165/917] Clean up JavaProblem, remove IProblem field --- .../mode/java/pdex/JavaProblem.java | 65 ++++--------------- 1 file changed, 13 insertions(+), 52 deletions(-) diff --git a/java/src/processing/mode/java/pdex/JavaProblem.java b/java/src/processing/mode/java/pdex/JavaProblem.java index 1aeb38c850..bb6a7fb587 100644 --- a/java/src/processing/mode/java/pdex/JavaProblem.java +++ b/java/src/processing/mode/java/pdex/JavaProblem.java @@ -30,10 +30,6 @@ * according to its tab, including the original IProblem object */ public class JavaProblem implements Problem { - /** - * The IProblem which is being wrapped - */ - private IProblem iProblem; /** * The tab number to which the error belongs to */ @@ -71,11 +67,9 @@ public class JavaProblem implements Problem { * @param lineNumber - Line number(pde code) of the error */ public JavaProblem(IProblem iProblem, int tabIndex, int lineNumber) { - this.iProblem = iProblem; if(iProblem.isError()) { type = ERROR; - } - else if(iProblem.isWarning()) { + } else if (iProblem.isWarning()) { type = WARNING; } this.tabIndex = tabIndex; @@ -88,62 +82,41 @@ public void setPDEOffsets(int startOffset, int stopOffset){ this.stopOffset = stopOffset; } + @Override public int getStartOffset() { return startOffset; } + @Override public int getStopOffset() { return stopOffset; } - public String toString() { - return new String("TAB " + tabIndex + ",LN " + lineNumber + "LN START OFF: " - + startOffset + ",LN STOP OFF: " + stopOffset + ",PROB: " - + message); - } - + @Override public boolean isError() { return type == ERROR; } + @Override public boolean isWarning() { return type == WARNING; } + @Override public String getMessage() { return message; } - public IProblem getIProblem() { - return iProblem; - } - + @Override public int getTabIndex() { return tabIndex; } + @Override public int getLineNumber() { return lineNumber; } - /** - * Remember to subtract a -1 to line number because in compile check code an - * extra package statement is added, so all line numbers are increased by 1 - * - * @return - */ - public int getSourceLineNumber() { - return iProblem.getSourceLineNumber(); - } - - public void setType(int ProblemType){ - if(ProblemType == ERROR) - type = ERROR; - else if(ProblemType == WARNING) - type = WARNING; - else throw new IllegalArgumentException("Illegal Problem type passed to Problem.setType(int)"); - } - public String[] getImportSuggestions() { return importSuggestions; } @@ -152,23 +125,11 @@ public void setImportSuggestions(String[] a) { importSuggestions = a; } - // Split camel case words into separate words. - // "VaraibleDeclaration" becomes "Variable Declaration" - // But sadly "PApplet" become "P Applet" and so on. - public static String splitCamelCaseWord(String word) { - String newWord = ""; - for (int i = 1; i < word.length(); i++) { - if (Character.isUpperCase(word.charAt(i))) { - // System.out.println(word.substring(0, i) + " " - // + word.substring(i)); - newWord += word.substring(0, i) + " "; - word = word.substring(i); - i = 1; - } - } - newWord += word; - // System.out.println(newWord); - return newWord.trim(); + @Override + public String toString() { + return "TAB " + tabIndex + ",LN " + lineNumber + "LN START OFF: " + + startOffset + ",LN STOP OFF: " + stopOffset + ",PROB: " + + message; } } From 8902ed1355fb726dbb8300c74011895def95d05f Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 16 Dec 2016 04:36:23 +0100 Subject: [PATCH 166/917] Detect missing braces in tabs, ignore other problems until fixed --- .../mode/java/pdex/JavaProblem.java | 15 ++- java/src/processing/mode/java/pdex/PDEX.java | 110 ++++++++++++------ .../mode/java/pdex/PreprocessedSketch.java | 7 ++ .../mode/java/pdex/PreprocessingService.java | 11 +- .../mode/java/pdex/SourceUtils.java | 41 +++++++ 5 files changed, 146 insertions(+), 38 deletions(-) diff --git a/java/src/processing/mode/java/pdex/JavaProblem.java b/java/src/processing/mode/java/pdex/JavaProblem.java index bb6a7fb587..bfe39b007c 100644 --- a/java/src/processing/mode/java/pdex/JavaProblem.java +++ b/java/src/processing/mode/java/pdex/JavaProblem.java @@ -60,21 +60,28 @@ public class JavaProblem implements Problem { public static final int ERROR = 1, WARNING = 2; + public JavaProblem(String message, int type, int tabIndex, int lineNumber) { + this.message = message; + this.type = type; + this.tabIndex = tabIndex; + this.lineNumber = lineNumber; + } + /** * * @param iProblem - The IProblem which is being wrapped * @param tabIndex - The tab number to which the error belongs to * @param lineNumber - Line number(pde code) of the error */ - public JavaProblem(IProblem iProblem, int tabIndex, int lineNumber) { + public static JavaProblem fromIProblem(IProblem iProblem, int tabIndex, int lineNumber) { + int type = 0; if(iProblem.isError()) { type = ERROR; } else if (iProblem.isWarning()) { type = WARNING; } - this.tabIndex = tabIndex; - this.lineNumber = lineNumber; - this.message = ErrorMessageSimplifier.getSimplifiedErrorMessage(iProblem); + String message = ErrorMessageSimplifier.getSimplifiedErrorMessage(iProblem); + return new JavaProblem(message, type, tabIndex, lineNumber); } public void setPDEOffsets(int startOffset, int stopOffset){ diff --git a/java/src/processing/mode/java/pdex/PDEX.java b/java/src/processing/mode/java/pdex/PDEX.java index 37b0d9b8e0..b6a7e0ffb6 100644 --- a/java/src/processing/mode/java/pdex/PDEX.java +++ b/java/src/processing/mode/java/pdex/PDEX.java @@ -1079,40 +1079,69 @@ private void handleSketchProblems(PreprocessedSketch ps) { Map suggCache = JavaMode.importSuggestEnabled ? new HashMap<>() : Collections.emptyMap(); - // Process problems + final List problems = new ArrayList<>(); + IProblem[] iproblems = ps.compilationUnit.getProblems(); - final List problems = Arrays.stream(iproblems) - // Filter Warnings if they are not enabled - .filter(iproblem -> !(iproblem.isWarning() && !JavaMode.warningsEnabled)) - // Hide a useless error which is produced when a line ends with - // an identifier without a semicolon. "Missing a semicolon" is - // also produced and is preferred over this one. - // (Syntax error, insert ":: IdentifierOrNew" to complete Expression) - // See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=405780 - .filter(iproblem -> !iproblem.getMessage() - .contains("Syntax error, insert \":: IdentifierOrNew\"")) - // Transform into our Problems - .map(iproblem -> { - int start = iproblem.getSourceStart(); - int stop = iproblem.getSourceEnd() + 1; // make it exclusive - SketchInterval in = ps.mapJavaToSketch(start, stop); - if (in == SketchInterval.BEFORE_START) return null; - int line = ps.tabOffsetToTabLine(in.tabIndex, in.startTabOffset); - JavaProblem p = new JavaProblem(iproblem, in.tabIndex, line); - p.setPDEOffsets(in.startTabOffset, in.stopTabOffset); - - // Handle import suggestions - if (JavaMode.importSuggestEnabled && isUndefinedTypeProblem(iproblem)) { - ClassPath cp = ps.searchClassPath; - String[] s = suggCache.computeIfAbsent(iproblem.getArguments()[0], - name -> getImportSuggestions(cp, name)); - p.setImportSuggestions(s); - } - return p; - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + { // Handle missing brace problems + IProblem missingBraceProblem = Arrays.stream(iproblems) + .filter(ErrorChecker::isMissingBraceProblem) + .findFirst() + // Ignore if it is at the end of file + .filter(p -> p.getSourceEnd() + 1 < ps.javaCode.length()) + // Ignore if the tab number does not match our detected tab number + .filter(p -> ps.missingBraceProblems.isEmpty() || + ps.missingBraceProblems.get(0).getTabIndex() == + ps.mapJavaToSketch(p.getSourceStart(), p.getSourceEnd()+1).tabIndex + ) + .orElse(null); + + // If there is missing brace ignore all other problems + if (missingBraceProblem != null) { + // Prefer ECJ problem, shows location more accurately + iproblems = new IProblem[]{missingBraceProblem}; + } else if (!ps.missingBraceProblems.isEmpty()) { + // Fallback to manual detection + problems.addAll(ps.missingBraceProblems); + } + } + + if (problems.isEmpty()) { + List cuProblems = Arrays.stream(iproblems) + // Filter Warnings if they are not enabled + .filter(iproblem -> !(iproblem.isWarning() && !JavaMode.warningsEnabled)) + // Hide a useless error which is produced when a line ends with + // an identifier without a semicolon. "Missing a semicolon" is + // also produced and is preferred over this one. + // (Syntax error, insert ":: IdentifierOrNew" to complete Expression) + // See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=405780 + .filter(iproblem -> !iproblem.getMessage() + .contains("Syntax error, insert \":: IdentifierOrNew\"")) + // Transform into our Problems + .map(iproblem -> { + int start = iproblem.getSourceStart(); + int stop = iproblem.getSourceEnd() + 1; // make it exclusive + SketchInterval in = ps.mapJavaToSketch(start, stop); + if (in == SketchInterval.BEFORE_START) return null; + int line = ps.tabOffsetToTabLine(in.tabIndex, in.startTabOffset); + JavaProblem p = JavaProblem.fromIProblem(iproblem, in.tabIndex, line); + p.setPDEOffsets(in.startTabOffset, in.stopTabOffset); + + // Handle import suggestions + if (JavaMode.importSuggestEnabled && isUndefinedTypeProblem(iproblem)) { + ClassPath cp = ps.searchClassPath; + String[] s = suggCache.computeIfAbsent(iproblem.getArguments()[0], + name -> getImportSuggestions(cp, name)); + p.setImportSuggestions(s); + } + + return p; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + problems.addAll(cuProblems); + } if (scheduledUiUpdate != null) { scheduledUiUpdate.cancel(true); @@ -1129,13 +1158,28 @@ private void handleSketchProblems(PreprocessedSketch ps) { } - private boolean isUndefinedTypeProblem(IProblem iproblem) { + static private boolean isUndefinedTypeProblem(IProblem iproblem) { int id = iproblem.getID(); return id == IProblem.UndefinedType || id == IProblem.UndefinedName || id == IProblem.UnresolvedVariable; } + static private boolean isMissingBraceProblem(IProblem iproblem) { + switch (iproblem.getID()) { + case IProblem.ParsingErrorInsertToComplete: { + char brace = iproblem.getArguments()[0].charAt(0); + return brace == '{' || brace == '}'; + } + case IProblem.ParsingErrorInsertTokenAfter: { + char brace = iproblem.getArguments()[1].charAt(0); + return brace == '{' || brace == '}'; + } + default: + return false; + } + } + public static String[] getImportSuggestions(ClassPath cp, String className) { RegExpResourceFilter regf = new RegExpResourceFilter( diff --git a/java/src/processing/mode/java/pdex/PreprocessedSketch.java b/java/src/processing/mode/java/pdex/PreprocessedSketch.java index 9f4fd2005c..53fa7402ff 100644 --- a/java/src/processing/mode/java/pdex/PreprocessedSketch.java +++ b/java/src/processing/mode/java/pdex/PreprocessedSketch.java @@ -11,6 +11,7 @@ import java.util.Collections; import java.util.List; +import processing.app.Problem; import processing.app.Sketch; import processing.core.PApplet; import processing.mode.java.pdex.TextTransform.OffsetMapper; @@ -34,6 +35,8 @@ public class PreprocessedSketch { public final OffsetMapper offsetMapper; + public final List missingBraceProblems; + public final boolean hasSyntaxErrors; public final boolean hasCompilationErrors; @@ -212,6 +215,8 @@ public static class Builder { public OffsetMapper offsetMapper; + public final List missingBraceProblems = new ArrayList<>(0); + public boolean hasSyntaxErrors; public boolean hasCompilationErrors; @@ -246,6 +251,8 @@ private PreprocessedSketch(Builder b) { offsetMapper = b.offsetMapper != null ? b.offsetMapper : OffsetMapper.EMPTY_MAPPER; + missingBraceProblems = Collections.unmodifiableList(b.missingBraceProblems); + hasSyntaxErrors = b.hasSyntaxErrors; hasCompilationErrors = b.hasCompilationErrors; diff --git a/java/src/processing/mode/java/pdex/PreprocessingService.java b/java/src/processing/mode/java/pdex/PreprocessingService.java index 8a3005256f..6ac0981efa 100644 --- a/java/src/processing/mode/java/pdex/PreprocessingService.java +++ b/java/src/processing/mode/java/pdex/PreprocessingService.java @@ -392,6 +392,15 @@ private PreprocessedSketch preprocessSketch(PreprocessedSketch prevResult) { } } + { // Check for missing braces + List missingBraceProblems = + SourceUtils.checkForMissingBraces(workBuffer, result.tabStartOffsets); + if (!missingBraceProblems.isEmpty()) { + result.missingBraceProblems.addAll(missingBraceProblems); + result.hasSyntaxErrors = true; + } + } + // Transform code to parsable state String parsableStage = toParsable.apply(); OffsetMapper parsableMapper = toParsable.getMapper(); @@ -414,7 +423,7 @@ private PreprocessedSketch preprocessSketch(PreprocessedSketch prevResult) { makeAST(parser, compilableStageChars, COMPILER_OPTIONS); // Get syntax problems from compilable AST - result.hasSyntaxErrors = Arrays.stream(compilableCU.getProblems()) + result.hasSyntaxErrors |= Arrays.stream(compilableCU.getProblems()) .anyMatch(IProblem::isError); // Generate bindings after getting problems - avoids diff --git a/java/src/processing/mode/java/pdex/SourceUtils.java b/java/src/processing/mode/java/pdex/SourceUtils.java index 531c8a3ed9..cddfcff1c4 100644 --- a/java/src/processing/mode/java/pdex/SourceUtils.java +++ b/java/src/processing/mode/java/pdex/SourceUtils.java @@ -323,4 +323,45 @@ static public void scrubCommentsAndStrings(StringBuilder p) { } + static public List checkForMissingBraces(StringBuilder p, int[] tabStartOffsets) { + List problems = new ArrayList<>(0); + tabLoop: for (int tabIndex = 0; tabIndex < tabStartOffsets.length; tabIndex++) { + int tabStartOffset = tabStartOffsets[tabIndex]; + int tabEndOffset = (tabIndex < tabStartOffsets.length - 1) ? + tabStartOffsets[tabIndex + 1] : p.length(); + int depth = 0; + int lineNumber = 0; + for (int i = tabStartOffset; i < tabEndOffset; i++) { + char ch = p.charAt(i); + switch (ch) { + case '{': + depth++; + break; + case '}': + depth--; + break; + case '\n': + lineNumber++; + break; + } + if (depth < 0) { + JavaProblem problem = + new JavaProblem("Found one too many } characters without { to match it.", + JavaProblem.ERROR, tabIndex, lineNumber); + problem.setPDEOffsets(i - tabStartOffset, i - tabStartOffset + 1); + problems.add(problem); + continue tabLoop; + } + } + if (depth > 0) { + JavaProblem problem = + new JavaProblem("Found one too many { characters without } to match it.", + JavaProblem.ERROR, tabIndex, lineNumber - 1); + problem.setPDEOffsets(tabEndOffset - tabStartOffset - 2, tabEndOffset - tabStartOffset - 1); + problems.add(problem); + } + } + return problems; + } + } From b7011c8026418aad8f9b64559d3f4f2f5387177b Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 18 Dec 2016 00:36:22 +0100 Subject: [PATCH 167/917] Don't cache search classpath, only build it when looking for a class Fixes #4748 Libraries imported in opened sketches will be still locked by latest preprocessed CompilationUnit. Otherwise we would have to copy library jars somewhere else so they can be available to CompilationUnit while Contribution Manager updates original unlocked jars. --- java/src/processing/mode/java/pdex/PDEX.java | 7 ++++++- java/src/processing/mode/java/pdex/PreprocessedSketch.java | 6 +++--- .../processing/mode/java/pdex/PreprocessingService.java | 7 +++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/java/src/processing/mode/java/pdex/PDEX.java b/java/src/processing/mode/java/pdex/PDEX.java index b6a7e0ffb6..9c2d0b30d2 100644 --- a/java/src/processing/mode/java/pdex/PDEX.java +++ b/java/src/processing/mode/java/pdex/PDEX.java @@ -1,6 +1,7 @@ package processing.mode.java.pdex; import com.google.classpath.ClassPath; +import com.google.classpath.ClassPathFactory; import com.google.classpath.RegExpResourceFilter; import org.eclipse.jdt.core.compiler.IProblem; @@ -44,6 +45,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.regex.Pattern; @@ -1106,6 +1108,8 @@ private void handleSketchProblems(PreprocessedSketch ps) { } } + AtomicReference searchClassPath = new AtomicReference<>(null); + if (problems.isEmpty()) { List cuProblems = Arrays.stream(iproblems) // Filter Warnings if they are not enabled @@ -1129,7 +1133,8 @@ private void handleSketchProblems(PreprocessedSketch ps) { // Handle import suggestions if (JavaMode.importSuggestEnabled && isUndefinedTypeProblem(iproblem)) { - ClassPath cp = ps.searchClassPath; + ClassPath cp = searchClassPath.updateAndGet(prev -> prev != null ? + prev : new ClassPathFactory().createFromPaths(ps.searchClassPathArray)); String[] s = suggCache.computeIfAbsent(iproblem.getArguments()[0], name -> getImportSuggestions(cp, name)); p.setImportSuggestions(s); diff --git a/java/src/processing/mode/java/pdex/PreprocessedSketch.java b/java/src/processing/mode/java/pdex/PreprocessedSketch.java index 53fa7402ff..50838eff81 100644 --- a/java/src/processing/mode/java/pdex/PreprocessedSketch.java +++ b/java/src/processing/mode/java/pdex/PreprocessedSketch.java @@ -26,7 +26,7 @@ public class PreprocessedSketch { public final ClassPath classPath; public final URLClassLoader classLoader; - public final ClassPath searchClassPath; + public final String[] searchClassPathArray; public final int[] tabStartOffsets; @@ -206,7 +206,7 @@ public static class Builder { public ClassPath classPath; public URLClassLoader classLoader; - public ClassPath searchClassPath; + public String[] searchClassPathArray; public int[] tabStartOffsets = new int[0]; @@ -242,7 +242,7 @@ private PreprocessedSketch(Builder b) { classPath = b.classPath; classLoader = b.classLoader; - searchClassPath = b.searchClassPath; + searchClassPathArray = b.searchClassPathArray; tabStartOffsets = b.tabStartOffsets; diff --git a/java/src/processing/mode/java/pdex/PreprocessingService.java b/java/src/processing/mode/java/pdex/PreprocessingService.java index 6ac0981efa..ce535a92d8 100644 --- a/java/src/processing/mode/java/pdex/PreprocessingService.java +++ b/java/src/processing/mode/java/pdex/PreprocessingService.java @@ -341,7 +341,7 @@ private PreprocessedSketch preprocessSketch(PreprocessedSketch prevResult) { boolean rebuildClassPath = reloadCodeFolder || rebuildLibraryClassPath || prevResult.classLoader == null || prevResult.classPath == null || - prevResult.classPathArray == null || prevResult.searchClassPath == null; + prevResult.classPathArray == null || prevResult.searchClassPathArray == null; if (reloadCodeFolder) { codeFolderClassPath = buildCodeFolderClassPath(sketch); @@ -381,13 +381,12 @@ private PreprocessedSketch preprocessSketch(PreprocessedSketch prevResult) { searchClassPath.addAll(coreLibraryClassPath); searchClassPath.addAll(codeFolderClassPath); - String[] searchClassPathArray = searchClassPath.stream().toArray(String[]::new); - result.searchClassPath = classPathFactory.createFromPaths(searchClassPathArray); + result.searchClassPathArray = searchClassPath.stream().toArray(String[]::new); } } else { result.classLoader = prevResult.classLoader; result.classPath = prevResult.classPath; - result.searchClassPath = prevResult.searchClassPath; + result.searchClassPathArray = prevResult.searchClassPathArray; result.classPathArray = prevResult.classPathArray; } } From 2859d94f13593f295df9f0ee7aa0d4dd6efcc9f3 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 18 Dec 2016 11:17:18 -0500 Subject: [PATCH 168/917] note about recent changes --- todo.txt | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/todo.txt b/todo.txt index 48a6ba80e8..ca1c3b1b8f 100755 --- a/todo.txt +++ b/todo.txt @@ -12,11 +12,15 @@ X will help us with debugging w/ others as well X change to debug.txt; too confusing with the folder thing X replace java.util.logging code with built-in logging X split gui and non-gui portions of console for earlier startup +X split EditorConsole into gui and non-gui code? +X otherwise System.err/out not going to a file unless we have GUI +X also can't debug before the GUI shows up +o gracefully recover from proxy problems +X https://github.com/processing/processing/issues/1601 +_ changed headerType to console (make sure changed back) _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 _ this may be fixed (removed invokeLater() on startup), unconfirmed -_ could not write to temporary directory -_ https://github.com/processing/processing/issues/4757 contrib X Added the remove filter feature @@ -35,7 +39,23 @@ X https://github.com/processing/processing/pull/4761 X possible infinite loop on modified externally X https://github.com/processing/processing/issues/3965 X https://github.com/processing/processing/pull/4762 +X Report missing brace in correct tab, suppress other errors until fixed +X https://github.com/processing/processing/pull/4777 + + +_ did we lose settings.path because it was too buggy? +_ https://github.com/processing/processing/issues/3948 +_ proxy trouble with p5? since adding the system proxy? +_ https://github.com/processing/processing/pull/3251/files +_ larger problem thread https://github.com/processing/processing/issues/3891 +_ ideen2011.blogspot.de/2011/08/java-proxyselector-usesystemproxies-and.html +_ malformed proxy issues http://stackoverflow.com/q/376101 +_ docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html +_ https://github.com/processing/processing/issues/1476#issuecomment-23229990 + +_ could not write to temporary directory +_ https://github.com/processing/processing/issues/4757 _ Broken characters in the Welcome Page and the Contribution Manager _ looks like a failure to load the Source Sans font @@ -111,8 +131,6 @@ _ hidpi scaling via font changes? _ http://stackoverflow.com/a/34152675 _ hi-dpi support on Linux _ https://github.com/processing/processing/issues/4183 -_ did we lose settings.path because it was too buggy? -_ https://github.com/processing/processing/issues/3948 _ Library path mismatch between processing-java and export _ https://github.com/processing/processing/issues/4493 @@ -762,8 +780,6 @@ _ "Update 4 items" as a button name _ new libraries not picked up when changing sketchbook location _ make sure contrib manager can run w/o a network connection _ or if a bad document comes through, it can recover -_ gracefully recover from proxy problems -_ https://github.com/processing/processing/issues/1601 _ alternating blue/white backgrounds aren't updated after changing filter _ just need to call a repaint() after a filter change? _ check with Casey about coloring for error messages From f434d2c2303c8d03e265e14972b652c595e6cdf7 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Tue, 20 Dec 2016 16:21:59 -0500 Subject: [PATCH 169/917] Allow setting vertex of geometry 2D PShape in P3D, fixes #4773 --- core/src/processing/opengl/PShapeOpenGL.java | 24 ++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/core/src/processing/opengl/PShapeOpenGL.java b/core/src/processing/opengl/PShapeOpenGL.java index 8cce642c58..69701acc1d 100644 --- a/core/src/processing/opengl/PShapeOpenGL.java +++ b/core/src/processing/opengl/PShapeOpenGL.java @@ -1664,7 +1664,10 @@ public void setVertex(int index, float x, float y, float z) { } vertices[index][X] = x; vertices[index][Y] = y; - if (is3D) vertices[index][Z] = z; + if (is3D && vertices[index].length > 2) { + // P3D allows to modify 2D shapes, ignoring the Z coordinate. + vertices[index][Z] = z; + } } else { inGeo.vertices[3 * index + 0] = x; inGeo.vertices[3 * index + 1] = y; @@ -1681,9 +1684,22 @@ public void setVertex(int index, PVector vec) { return; } - inGeo.vertices[3 * index + 0] = vec.x; - inGeo.vertices[3 * index + 1] = vec.y; - inGeo.vertices[3 * index + 2] = vec.z; + if (family == PATH) { + if (vertexCodes != null && vertexCodeCount > 0 && + vertexCodes[index] != VERTEX) { + PGraphics.showWarning(NOT_A_SIMPLE_VERTEX, "setVertex()"); + return; + } + vertices[index][X] = vec.x; + vertices[index][Y] = vec.y; + if (is3D && vertices[index].length > 2) { + vertices[index][Z] = vec.z; + } + } else { + inGeo.vertices[3 * index + 0] = vec.x; + inGeo.vertices[3 * index + 1] = vec.y; + inGeo.vertices[3 * index + 2] = vec.z; + } markForTessellation(); } From bad261a98cf46374da2ba44b55f9f48382aaaf3a Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 21 Dec 2016 17:21:58 -0500 Subject: [PATCH 170/917] check for installed Source Sans on Windows (fix for #4747) --- app/src/processing/app/ui/Toolkit.java | 22 ++++++++++++++++++++-- core/todo.txt | 4 ++++ todo.txt | 3 +++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index d8378acd43..29efbb305a 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -69,6 +69,7 @@ import javax.swing.JRootPane; import javax.swing.KeyStroke; +import processing.app.Base; import processing.app.Language; import processing.app.Messages; import processing.app.Platform; @@ -963,8 +964,25 @@ static public String getSansFontName() { static public Font getSansFont(int size, int style) { if (sansFont == null) { try { - sansFont = createFont("SourceSansPro-Regular.ttf", size); - sansBoldFont = createFont("SourceSansPro-Semibold.ttf", size); + // check for an installed version, because they cause nasty conflicts + // https://github.com/processing/processing/issues/4747 + if (Platform.isWindows()) { + sansFont = new Font("Source Sans Pro", Font.PLAIN, size); + // the ps name will be Dialog.plain (or similar) if not installed + if (!sansFont.getPSName().startsWith("Source")) { + sansFont = null; + } + sansBoldFont = new Font("Source Sans Pro Semibold", Font.PLAIN, size); + if (!sansBoldFont.getPSName().startsWith("Source")) { + sansBoldFont = null; + } + } + if (sansFont == null) { + sansFont = createFont("SourceSansPro-Regular.ttf", size); + } + if (sansBoldFont == null) { + sansBoldFont = createFont("SourceSansPro-Semibold.ttf", size); + } // additional language constraints if ("el".equals(Language.getLanguage())) { diff --git a/core/todo.txt b/core/todo.txt index 0816473032..77827eedfb 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -21,6 +21,10 @@ cleaning o probably should also check to make sure PApplet running JVM 8 X or compile against 1.8 and force it? +andres +X PShape array index out of bounds when using P3D +X https://github.com/processing/processing/issues/4773 + _ no prompt shows with selectInput() on 10.11 and 10.12 _ https://github.com/processing/processing/issues/4758 diff --git a/todo.txt b/todo.txt index ca1c3b1b8f..0c74415bea 100755 --- a/todo.txt +++ b/todo.txt @@ -22,6 +22,9 @@ _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 _ this may be fixed (removed invokeLater() on startup), unconfirmed +_ Spaces not handled correctly in when installing "processing-java" on macOS +_ https://github.com/processing/processing/issues/4779 + contrib X Added the remove filter feature X https://github.com/processing/processing/pull/3890 From 121e96cfbd1be9c30764965bd37bddd5f5048900 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 21 Dec 2016 23:48:32 -0500 Subject: [PATCH 171/917] remove unused import --- app/src/processing/app/ui/Toolkit.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 29efbb305a..cbc7f82207 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -69,7 +69,6 @@ import javax.swing.JRootPane; import javax.swing.KeyStroke; -import processing.app.Base; import processing.app.Language; import processing.app.Messages; import processing.app.Platform; From c984762818c5f1569ed5743be08eccb94fdf6692 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 21 Dec 2016 23:56:40 -0500 Subject: [PATCH 172/917] remove redundant use of "if (DEBUG)" --- app/src/processing/app/Util.java | 2 +- .../app/syntax/im/CompositionTextManager.java | 12 ++--- .../app/syntax/im/CompositionTextPainter.java | 49 +++++++++---------- .../app/syntax/im/InputMethodSupport.java | 4 +- 4 files changed, 29 insertions(+), 38 deletions(-) diff --git a/app/src/processing/app/Util.java b/app/src/processing/app/Util.java index 8016ba3113..fd8f8c39d6 100644 --- a/app/src/processing/app/Util.java +++ b/app/src/processing/app/Util.java @@ -74,7 +74,7 @@ static public byte[] loadBytesRaw(File file) throws IOException { */ static public StringDict readSettings(File inputFile) { if (!inputFile.exists()) { - if (Base.DEBUG) System.err.println(inputFile + " does not exist."); + Messages.loge(inputFile + " does not exist inside readSettings()"); return null; } String lines[] = PApplet.loadStrings(inputFile); diff --git a/app/src/processing/app/syntax/im/CompositionTextManager.java b/app/src/processing/app/syntax/im/CompositionTextManager.java index d37441f2cc..a7cc100208 100644 --- a/app/src/processing/app/syntax/im/CompositionTextManager.java +++ b/app/src/processing/app/syntax/im/CompositionTextManager.java @@ -15,12 +15,12 @@ import javax.swing.text.BadLocationException; -import processing.app.Base; import processing.app.Messages; import processing.app.Preferences; import processing.app.syntax.JEditTextArea; import processing.app.syntax.TextAreaPainter; + /** * This class Manage texts from input method * by begin-process-end steps. @@ -156,16 +156,16 @@ private void removeNotCommittedText(AttributedCharacterIterator text){ e.printStackTrace(); } } - + private TextLayout getTextLayout(AttributedCharacterIterator text, int committedCount) { boolean antialias = Preferences.getBoolean("editor.smooth"); TextAreaPainter painter = textArea.getPainter(); - + // create attributed string with font info. AttributedString composed = new AttributedString(text, committedCount, text.getEndIndex()); Font font = painter.getFontMetrics().getFont(); composed.addAttribute(TextAttribute.FONT, font); - + // set hint of antialiasing to render target. Graphics2D g2d = (Graphics2D)painter.getGraphics(); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, @@ -173,9 +173,7 @@ private TextLayout getTextLayout(AttributedCharacterIterator text, int committed RenderingHints.VALUE_TEXT_ANTIALIAS_ON : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); FontRenderContext frc = g2d.getFontRenderContext(); - if (Base.DEBUG) { - Messages.log("debug: FontRenderContext is Antialiased = " + frc.getAntiAliasingHint()); - } + Messages.log("debug: FontRenderContext is Antialiased = " + frc.getAntiAliasingHint()); return new TextLayout(composed.getIterator(), frc); } diff --git a/app/src/processing/app/syntax/im/CompositionTextPainter.java b/app/src/processing/app/syntax/im/CompositionTextPainter.java index 4a53dd5edc..b31ad9271e 100644 --- a/app/src/processing/app/syntax/im/CompositionTextPainter.java +++ b/app/src/processing/app/syntax/im/CompositionTextPainter.java @@ -8,19 +8,18 @@ import java.awt.font.TextHitInfo; import java.awt.font.TextLayout; -import processing.app.Base; -import processing.app.Messages; import processing.app.syntax.JEditTextArea; + /** - * Paint texts from input method. Text via input method are transmitted by - * AttributedCaharacterIterator. This class helps the PDE's TextAreaPainter + * Paint texts from input method. Text via input method are transmitted by + * AttributedCaharacterIterator. This class helps the PDE's TextAreaPainter * to handle AttributedCaharacterIterator. - * + * * For practical purposes, paint to textarea is done by TextLayout class. - * Because TextLayout class is easy to draw composing texts. (For example, + * Because TextLayout class is easy to draw composing texts. (For example, * draw underline composing texts, focus when select from candidates text.) - * + * * @author Takashi Maekawa (takachin@generative.info) */ public class CompositionTextPainter { @@ -39,7 +38,7 @@ public CompositionTextPainter(JEditTextArea textArea) { composedTextLayout = null; } - + /** * Check the painter has TextLayout. * If a user input via InputMethod, this result will return true. @@ -47,19 +46,19 @@ public CompositionTextPainter(JEditTextArea textArea) { public boolean hasComposedTextLayout() { return (composedTextLayout != null); } - - + + /** * Set TextLayout to the painter. * TextLayout will be created and set by CompositionTextManager. - * + * * @see CompositionTextManager */ public void setComposedTextLayout(TextLayout composedTextLayout, int composedStartCaretPosition) { this.composedTextLayout = composedTextLayout; this.composedBeginCaretPosition = composedStartCaretPosition; } - + /** * Invalidate this TextLayout to set null. @@ -70,23 +69,23 @@ public void invalidateComposedTextLayout(int composedEndCaretPosition) { this.composedBeginCaretPosition = composedEndCaretPosition; //this.composedBeginCaretPosition = textArea.getCaretPosition(); } - - + + /** * Draw text via input method with composed text information. - * This method can draw texts with some underlines to illustrate converting characters. - * + * This method can draw texts with some underlines to illustrate converting characters. + * * This method is workaround for TextAreaPainter. * Because, TextAreaPainter can't treat AttributedCharacterIterator directly. * AttributedCharacterIterator has very important information when composing text. * It has a map where are converted characters and committed characters. * Ideally, changing TextAreaPainter method can treat AttributedCharacterIterator is better. But it's very tough!! * So I choose to write some code as a workaround. - * + * * This draw method is proceeded with the following steps. - * 1. Original TextAreaPainter draws characters. + * 1. Original TextAreaPainter draws characters. * 2. CompositionTextPainter.draw method paints composed text. It was actually drawn by TextLayout. - * + * * @param gfx set TextAreaPainter's Graphics object. * @param fillBackGroundColor set textarea's background. */ @@ -102,7 +101,7 @@ public void draw(Graphics gfx, Color fillBackGroundColor) { Point composedLoc = getCaretLocation(); //refillComposedArea(fillBackGroundColor, composedLoc.x, composedLoc.y); composedTextLayout.draw((Graphics2D) gfx, composedLoc.x, composedLoc.y); - + // draw caret. if (this.caret != null) { int caretLocation = Math.round(composedTextLayout.getCaretInfo(caret)[0]); @@ -110,10 +109,6 @@ public void draw(Graphics gfx, Color fillBackGroundColor) { composedLoc.y - (int)composedTextLayout.getAscent(), 1, (int)composedTextLayout.getAscent() + (int)composedTextLayout.getDescent()); - // blink caret. - if (Base.DEBUG) { - Messages.log(rect.toString()); - } Color c = gfx.getColor(); // save if (caretColorFlag) { caretColorFlag = false; @@ -129,8 +124,8 @@ public void draw(Graphics gfx, Color fillBackGroundColor) { } // /** -// * Fill color to erase characters drawn by original TextAreaPainter. -// * +// * Fill color to erase characters drawn by original TextAreaPainter. +// * // * @param fillColor fill color to erase characters drawn by original TextAreaPainter method. // * @param x x-coordinate where to fill. // * @param y y-coordinate where to fill. @@ -144,7 +139,7 @@ public void draw(Graphics gfx, Color fillBackGroundColor) { // int paintWidth = (int) composedTextLayout.getBounds().getWidth(); // gfx.fillRect(x, newY, paintWidth, paintHeight); // } - + private Point getCaretLocation() { int line = textArea.getCaretLine(); diff --git a/app/src/processing/app/syntax/im/InputMethodSupport.java b/app/src/processing/app/syntax/im/InputMethodSupport.java index 2e83768d68..347480552d 100644 --- a/app/src/processing/app/syntax/im/InputMethodSupport.java +++ b/app/src/processing/app/syntax/im/InputMethodSupport.java @@ -195,9 +195,7 @@ public void inputMethodTextChanged(InputMethodEvent event) { } CompositionTextPainter compositionPainter = textArea.getPainter().getCompositionTextpainter(); - if (Base.DEBUG) { - Messages.log(" textArea.getCaretPosition() + committed_count: " + (textArea.getCaretPosition() + committedCount)); - } + Messages.log("textArea.getCaretPosition() + committed_count: " + (textArea.getCaretPosition() + committedCount)); compositionPainter.setComposedTextLayout(getTextLayout(text, committedCount), textArea.getCaretPosition() + committedCount); compositionPainter.setCaret(event.getCaret()); From 5c219a3899561be3d01aa01a55c4380fefe39f46 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 23 Dec 2016 03:40:25 -0500 Subject: [PATCH 173/917] fix direction of slashes --- build/windows/processing.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/windows/processing.bat b/build/windows/processing.bat index c5ec6768af..8f71b553dd 100755 --- a/build/windows/processing.bat +++ b/build/windows/processing.bat @@ -1,3 +1,3 @@ @echo off -.\java\bin\java -cp lib/pde.jar;core/library/core.jar;lib/jna.jar;lib/jna-platform.jar;lib/antlr.jar;lib/ant.jar;lib/ant-launcher.jar processing.app.Base \ No newline at end of file +.\java\bin\java -cp lib\pde.jar;core\library\core.jar;lib\jna.jar;lib\jna-platform.jar;lib\antlr.jar;lib\ant.jar;lib\ant-launcher.jar processing.app.Base From 0ea93206bae557dda6f1cd0eb1239cc6295ea24b Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 29 Dec 2016 14:15:06 +0100 Subject: [PATCH 174/917] FX: Reset transform to identity before drawing background --- core/src/processing/javafx/PGraphicsFX2D.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/core/src/processing/javafx/PGraphicsFX2D.java b/core/src/processing/javafx/PGraphicsFX2D.java index d2f4fdb0a6..f73d22102c 100644 --- a/core/src/processing/javafx/PGraphicsFX2D.java +++ b/core/src/processing/javafx/PGraphicsFX2D.java @@ -2012,15 +2012,20 @@ public void backgroundImpl() { modified = false; loaded = false; + // Save drawing context (transform, fill, blend mode, etc.) + context.save(); + + // Reset transform to identity + context.setTransform(new Affine()); + // This only takes into account cases where this is the primary surface. // Not sure what we do with offscreen anyway. - Paint savedFill = context.getFill(); - BlendMode savedBlend = context.getGlobalBlendMode(); context.setFill(new Color(backgroundR, backgroundG, backgroundB, backgroundA)); context.setGlobalBlendMode(BlendMode.SRC_OVER); context.fillRect(0, 0, width, height); - context.setFill(savedFill); - context.setGlobalBlendMode(savedBlend); + + // Restore drawing context (transform, fill, blend mode, etc.) + context.restore(); } From 205ad43e61e887385bea8b1ac42454f37abf7c8a Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 29 Dec 2016 15:35:30 +0100 Subject: [PATCH 175/917] FX: Implement mouse wheel event --- core/src/processing/javafx/PSurfaceFX.java | 46 ++++++++++++++-------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index 9cd5baa115..84d31794be 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -853,23 +853,37 @@ protected void fxMouseEvent(MouseEvent fxEvent) { x, y, button, count)); } + // https://docs.oracle.com/javase/8/javafx/api/javafx/scene/input/ScrollEvent.html + protected void fxScrollEvent(ScrollEvent fxEvent) { + // the number of steps/clicks on the wheel for a mouse wheel event. + int count = (int) -(fxEvent.getDeltaY() / fxEvent.getMultiplierY()); - // https://docs.oracle.com/javafx/2/api/javafx/scene/input/ScrollEvent.html - protected void fxScrollEvent(ScrollEvent event) { -// //case java.awt.event.MouseWheelEvent.WHEEL_UNIT_SCROLL: -// case java.awt.event.MouseEvent.MOUSE_WHEEL: -// peAction = MouseEvent.WHEEL; -// /* -// if (preciseWheelMethod != null) { -// try { -// peAmount = ((Double) preciseWheelMethod.invoke(nativeEvent, (Object[]) null)).floatValue(); -// } catch (Exception e) { -// preciseWheelMethod = null; -// } -// } -// */ -// peCount = ((MouseWheelEvent) nativeEvent).getWheelRotation(); -// break; + int action = processing.event.MouseEvent.WHEEL; + + int modifiers = 0; + if (fxEvent.isShiftDown()) { + modifiers |= processing.event.Event.SHIFT; + } + if (fxEvent.isControlDown()) { + modifiers |= processing.event.Event.CTRL; + } + if (fxEvent.isMetaDown()) { + modifiers |= processing.event.Event.META; + } + if (fxEvent.isAltDown()) { + modifiers |= processing.event.Event.ALT; + } + + // FX does not supply button info + int button = 0; + + long when = System.currentTimeMillis(); + int x = (int) fxEvent.getX(); // getSceneX()? + int y = (int) fxEvent.getY(); + + sketch.postEvent(new processing.event.MouseEvent(fxEvent, when, + action, modifiers, + x, y, button, count)); } From 683a586d0606cb9e162dc4c39e8bb0065d7b7f2d Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 29 Dec 2016 15:48:15 +0100 Subject: [PATCH 176/917] Unify mouse pressed/released events across renderers OPENGL and FX renderers will now correctly report button which triggered this pressed/released event (same as JAVA2D). Previously: - OPENGL would report currently pressed buttons in order LEFT, CENTER, RIGHT regardless of which button triggered the event. E.g. when holding LEFT and presing RIGHT, LEFT would be reported. When holding CENTER and pressing LEFT, LEFT would be reported - FX would report only first button which is down, so in RELEASE event button would be missing Now: - event contains only button which triggred this event (button just pressed or just released) --- core/src/processing/javafx/PSurfaceFX.java | 21 ++++++++++---------- core/src/processing/opengl/PSurfaceJOGL.java | 16 +++++++++------ 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index 9cd5baa115..d60f1f6e0a 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -806,11 +806,6 @@ protected void fxMouseEvent(MouseEvent fxEvent) { int count = fxEvent.getClickCount(); int action = mouseMap.get(fxEvent.getEventType()); - //EventType et = nativeEvent.getEventType(); -// if (et == MouseEvent.MOUSE_PRESSED) { -// peAction = processing.event.MouseEvent.PRESS; -// } else if (et == MouseEvent.MOUSE_RELEASED) { -// peAction = processing.event.MouseEvent.RELEASE; int modifiers = 0; if (fxEvent.isShiftDown()) { @@ -827,12 +822,16 @@ protected void fxMouseEvent(MouseEvent fxEvent) { } int button = 0; - if (fxEvent.isPrimaryButtonDown()) { - button = PConstants.LEFT; - } else if (fxEvent.isSecondaryButtonDown()) { - button = PConstants.RIGHT; - } else if (fxEvent.isMiddleButtonDown()) { - button = PConstants.CENTER; + switch (fxEvent.getButton()) { + case PRIMARY: + button = PConstants.LEFT; + break; + case SECONDARY: + button = PConstants.RIGHT; + break; + case MIDDLE: + button = PConstants.CENTER; + break; } // If running on Mac OS, allow ctrl-click as right mouse. diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 6a799517e2..bb9c2bc331 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -1060,12 +1060,16 @@ protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent, InputEvent.ALT_MASK); int peButton = 0; - if ((modifiers & InputEvent.BUTTON1_MASK) != 0) { - peButton = PConstants.LEFT; - } else if ((modifiers & InputEvent.BUTTON2_MASK) != 0) { - peButton = PConstants.CENTER; - } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { - peButton = PConstants.RIGHT; + switch (nativeEvent.getButton()) { + case com.jogamp.newt.event.MouseEvent.BUTTON1: + peButton = PConstants.LEFT; + break; + case com.jogamp.newt.event.MouseEvent.BUTTON2: + peButton = PConstants.CENTER; + break; + case com.jogamp.newt.event.MouseEvent.BUTTON3: + peButton = PConstants.RIGHT; + break; } if (PApplet.platform == PConstants.MACOSX) { From 19342f5704290e5b675c88506f60e2bf9fccfd72 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 29 Dec 2016 17:04:16 +0100 Subject: [PATCH 177/917] FX: Add exception handler which reports exceptions form user code Fixes #4339 --- core/src/processing/javafx/PSurfaceFX.java | 44 +++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index 9cd5baa115..f7e08d8a45 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -30,6 +30,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.SynchronousQueue; import javafx.animation.Animation; import javafx.animation.KeyFrame; @@ -71,6 +72,8 @@ public class PSurfaceFX implements PSurface { final Animation animation; float frameRate = 60; + private SynchronousQueue drawExceptionQueue = new SynchronousQueue<>(); + public PSurfaceFX(PGraphicsFX2D graphics) { fx = graphics; canvas = new ResizableCanvas(); @@ -80,7 +83,16 @@ public PSurfaceFX(PGraphicsFX2D graphics) { new EventHandler() { public void handle(ActionEvent event) { long startNanoTime = System.nanoTime(); - sketch.handleDraw(); + try { + sketch.handleDraw(); + } catch (Throwable e) { + // Let exception handler thread crash with our exception + drawExceptionQueue.offer(e); + // Stop animating right now so nothing runs afterwards + // and crash frame can be for example traced by println() + animation.stop(); + return; + } long drawNanos = System.nanoTime() - startNanoTime; if (sketch.exitCalled()) { @@ -366,10 +378,40 @@ public void run() { } catch (InterruptedException e) { } } + startExceptionHandlerThread(); + setProcessingIcon(stage); } + private void startExceptionHandlerThread() { + Thread exceptionHandlerThread = new Thread(() -> { + Throwable drawException; + try { + drawException = drawExceptionQueue.take(); + } catch (InterruptedException e) { + return; + } + // Adapted from PSurfaceJOGL + if (drawException != null) { + if (drawException instanceof ThreadDeath) { +// System.out.println("caught ThreadDeath"); +// throw (ThreadDeath)cause; + } else if (drawException instanceof RuntimeException) { + throw (RuntimeException) drawException; + } else if (drawException instanceof UnsatisfiedLinkError) { + throw new UnsatisfiedLinkError(drawException.getMessage()); + } else { + throw new RuntimeException(drawException); + } + } + }); + exceptionHandlerThread.setDaemon(true); + exceptionHandlerThread.setName("Processing-FX-ExceptionHandler"); + exceptionHandlerThread.start(); + } + + /** Set the window (and dock, or whatever necessary) title. */ public void setTitle(String title) { // PApplicationFX.title = title; // store this in case the stage still null From 122afdfe0b2a6d36d1971c76b7355af579d8ea38 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 29 Dec 2016 19:00:24 +0100 Subject: [PATCH 178/917] FX: Prevent matrix stack overflow Matrix stack could overflow in a very special case when beginShape() was called while strokeWeight=1 and then strokeWeight was changed before endShape(). This PR makes sure matrix is popped correctly even when user changes strokeWeight in the beginShape()/endShape() block. Decided to bug user only when necessary and not show warining when user changes strokeWeight in the beginShape()/endShape() block, same as in JAVA2D. Otherwise we could add checks for all the other things which are mentioned in the docs, but it would be hell to maintain and use. Fixes #4206 --- core/src/processing/javafx/PGraphicsFX2D.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/processing/javafx/PGraphicsFX2D.java b/core/src/processing/javafx/PGraphicsFX2D.java index d2f4fdb0a6..c4b1c38597 100644 --- a/core/src/processing/javafx/PGraphicsFX2D.java +++ b/core/src/processing/javafx/PGraphicsFX2D.java @@ -64,6 +64,7 @@ public class PGraphicsFX2D extends PGraphics { Path2D workPath = new Path2D(); Path2D auxPath = new Path2D(); boolean openContour; + boolean adjustedForThinLines; /// break the shape at the next vertex (next vertex() call is a moveto()) boolean breakShape; @@ -214,7 +215,7 @@ public void beginShape(int kind) { flushPixels(); if (drawingThinLines()) { - pushMatrix(); + adjustedForThinLines = true; translate(0.5f, 0.5f); } } @@ -420,8 +421,9 @@ public void endShape(int mode) { } } shape = 0; - if (drawingThinLines()) { - popMatrix(); + if (adjustedForThinLines) { + adjustedForThinLines = false; + translate(-0.5f, -0.5f); } loaded = false; } From b3431c80240332279e340cdd043c9e527d0937bb Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 29 Dec 2016 21:29:57 +0100 Subject: [PATCH 179/917] FX: Fix curveVertex drawing all curves together as one long curve Fixes #4382 --- core/src/processing/javafx/PGraphicsFX2D.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/processing/javafx/PGraphicsFX2D.java b/core/src/processing/javafx/PGraphicsFX2D.java index d2f4fdb0a6..91e6e391ff 100644 --- a/core/src/processing/javafx/PGraphicsFX2D.java +++ b/core/src/processing/javafx/PGraphicsFX2D.java @@ -207,6 +207,7 @@ public void endDraw() { public void beginShape(int kind) { shape = kind; vertexCount = 0; + curveVertexCount = 0; workPath.reset(); auxPath.reset(); From 7ac8929514dccd099a3b8480ceec339feb898dba Mon Sep 17 00:00:00 2001 From: Joel Moniz Date: Sun, 1 Jan 2017 21:02:51 +0530 Subject: [PATCH 180/917] Replace keyChar with keyCode to prevent new line error when debugging --- java/src/processing/mode/java/JavaInputHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/processing/mode/java/JavaInputHandler.java b/java/src/processing/mode/java/JavaInputHandler.java index 9e3ae59121..0c02a4418c 100644 --- a/java/src/processing/mode/java/JavaInputHandler.java +++ b/java/src/processing/mode/java/JavaInputHandler.java @@ -164,7 +164,7 @@ public boolean handlePressed(KeyEvent event) { event.consume(); } - } else if (c == 10 || c == 13) { // auto-indent + } else if (code == 10 || code == 13) { // auto-indent if (Preferences.getBoolean("editor.indent")) { char contents[] = textarea.getText().toCharArray(); int tabSize = Preferences.getInteger("editor.tabs.size"); From dd5c7abe029b18e878528dca53d432ed2d6d60c3 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 6 Jan 2017 11:18:27 -0500 Subject: [PATCH 181/917] make notes of recent PRs and bug reports --- core/todo.txt | 22 ++++++++++++++++++++-- todo.txt | 18 ++++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index 77827eedfb..64ad94873e 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -25,6 +25,26 @@ andres X PShape array index out of bounds when using P3D X https://github.com/processing/processing/issues/4773 +jakub +X FX: Prevent matrix stack overflow +X https://github.com/processing/processing/pull/4799 +X https://github.com/processing/processing/issues/4206 +X FX: Reset transform to identity before drawing background +X https://github.com/processing/processing/pull/4795 +X FX: Implement mouse wheel event +X https://github.com/processing/processing/issues/4169 +X https://github.com/processing/processing/pull/4796 +X FX: Fix curveVertex drawing all curves together as one long curve +X https://github.com/processing/processing/pull/4800 +X https://github.com/processing/processing/issues/4382 +X FX: Add exception handler which reports exceptions from user code +X https://github.com/processing/processing/pull/4798 +X https://github.com/processing/processing/issues/4339 +X Unify mouse pressed/released events across renderers +X https://github.com/processing/processing/issues/4361 +X https://github.com/processing/processing/pull/4797 + + _ no prompt shows with selectInput() on 10.11 and 10.12 _ https://github.com/processing/processing/issues/4758 @@ -82,8 +102,6 @@ _ https://github.com/processing/processing/issues/3753 javafx -_ mouseWheel() not working with FX2D -_ https://github.com/processing/processing/issues/4169 _ 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 0c74415bea..3f8f4882e2 100755 --- a/todo.txt +++ b/todo.txt @@ -21,6 +21,8 @@ _ changed headerType to console (make sure changed back) _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 _ this may be fixed (removed invokeLater() on startup), unconfirmed +_ "error during export" message, but no error message contents come through +_ e.g. https://github.com/processing/processing/issues/4792 _ Spaces not handled correctly in when installing "processing-java" on macOS _ https://github.com/processing/processing/issues/4779 @@ -28,6 +30,18 @@ _ https://github.com/processing/processing/issues/4779 contrib X Added the remove filter feature X https://github.com/processing/processing/pull/3890 +_ ctrl-J (for debugger) is inserting newline +_ https://github.com/processing/processing/issues/3830 +_ Replace keyChar with keyCode to prevent new line error when debugging +_ https://github.com/processing/processing/pull/4806 +_ https://github.com/processing/processing/issues/4804 +_ "Sketch disappeared" infinite pop up dialogs +_ https://github.com/processing/processing/pull/4808 +_ https://github.com/processing/processing/issues/4805 + +andres +_ update list of optional JRE files for Java 8 +_ https://github.com/processing/processing/issues/3288 jakub X println(int(byte(245))) throwing error @@ -138,8 +152,6 @@ _ Library path mismatch between processing-java and export _ https://github.com/processing/processing/issues/4493 shortcuts -_ ctrl-J (for debugger) is inserting newline -_ https://github.com/processing/processing/issues/3830 _ problems with non-US keyboards and some shortcuts _ https://github.com/processing/processing/issues/2199 _ Determine shortcut for Export vs Use Selection for Find @@ -268,8 +280,6 @@ _ https://github.com/processing/processing/issues/3843 _ clean out the repo _ https://github.com/processing/processing/issues/1898 _ search the source for 'applet' references (i.e. SVG docs) -_ update list of optional JRE files -_ https://github.com/processing/processing/issues/3288 _ PreferencesFrame is a misnomer (not a frame itself) _ change to PreferencesDialog, and make it a dialog? _ move Library to LibraryContribution and into contrib? From 684736c630401687bc9b7e59a684c0eb75d51d64 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 6 Jan 2017 21:45:53 +0100 Subject: [PATCH 182/917] Fix typo in glsl preprocessor Add missing 2D which disappeared in https://github.com/processing/processing/pull/4052/files#diff-88c7dd4e8f37672d20e228a71a433a6dL1889 --- core/src/processing/opengl/PGL.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index e628b59606..72d6c2ef7f 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -1914,7 +1914,7 @@ protected static String[] preprocessFragmentSource(String[] fragSrc0, Pattern[] search = new Pattern[] { Pattern.compile(String.format(GLSL_ID_REGEX, "varying|attribute")), Pattern.compile(String.format(GLSL_ID_REGEX, "texture")), - Pattern.compile(String.format(GLSL_FN_REGEX, "textureRect|texture2D|texture3D|textureCube")), + Pattern.compile(String.format(GLSL_FN_REGEX, "texture2DRect|texture2D|texture3D|textureCube")), Pattern.compile(String.format(GLSL_ID_REGEX, "gl_FragColor")) }; String[] replace = new String[] { @@ -1954,7 +1954,7 @@ protected static String[] preprocessVertexSource(String[] vertSrc0, Pattern.compile(String.format(GLSL_ID_REGEX, "varying")), Pattern.compile(String.format(GLSL_ID_REGEX, "attribute")), Pattern.compile(String.format(GLSL_ID_REGEX, "texture")), - Pattern.compile(String.format(GLSL_FN_REGEX, "textureRect|texture2D|texture3D|textureCube")) + Pattern.compile(String.format(GLSL_FN_REGEX, "texture2DRect|texture2D|texture3D|textureCube")) }; String[] replace = new String[] { "out", "in", "texMap", "texture", From 382b5c0a518cec14e956557b55a2a8927eea90a2 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Mon, 9 Jan 2017 08:49:31 -0500 Subject: [PATCH 183/917] show warning when calling modelX/Y/Z in P2D, fixes #4813 --- core/src/processing/opengl/PGraphics2D.java | 25 +++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/core/src/processing/opengl/PGraphics2D.java b/core/src/processing/opengl/PGraphics2D.java index f3860e20dd..8fbdd5eff9 100644 --- a/core/src/processing/opengl/PGraphics2D.java +++ b/core/src/processing/opengl/PGraphics2D.java @@ -251,6 +251,31 @@ static protected PShape loadShapeImpl(PGraphics pg, } + ////////////////////////////////////////////////////////////// + + // SCREEN TRANSFORMS + + + @Override + public float modelX(float x, float y, float z) { + showDepthWarning("modelX"); + return 0; + } + + + @Override + public float modelY(float x, float y, float z) { + showDepthWarning("modelY"); + return 0; + } + + + @Override + public float modelZ(float x, float y, float z) { + showDepthWarning("modelZ"); + return 0; + } + ////////////////////////////////////////////////////////////// From 01a95dc311c0f0e5e8073c55ffc91a9c2fc88acc Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 9 Jan 2017 15:42:00 -0500 Subject: [PATCH 184/917] notes about recent updates --- core/todo.txt | 5 +++++ todo.txt | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index 64ad94873e..984f130fa9 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -24,6 +24,8 @@ X or compile against 1.8 and force it? andres X PShape array index out of bounds when using P3D X https://github.com/processing/processing/issues/4773 +X modelX/Y/Z() should be disabled in P2D +X https://github.com/processing/processing/issues/4813 jakub X FX: Prevent matrix stack overflow @@ -43,6 +45,9 @@ X https://github.com/processing/processing/issues/4339 X Unify mouse pressed/released events across renderers X https://github.com/processing/processing/issues/4361 X https://github.com/processing/processing/pull/4797 +X Fix typo in GLSL preprocessor +X https://github.com/processing/processing/issues/4810 +X https://github.com/processing/processing/pull/4816 _ no prompt shows with selectInput() on 10.11 and 10.12 diff --git a/todo.txt b/todo.txt index 3f8f4882e2..85d9b6df73 100755 --- a/todo.txt +++ b/todo.txt @@ -24,6 +24,15 @@ _ this may be fixed (removed invokeLater() on startup), unconfirmed _ "error during export" message, but no error message contents come through _ e.g. https://github.com/processing/processing/issues/4792 +_ report of a library or tool (probably includes 2.x? 1.x?) breaking things +_ NoSuchFieldError: useNativeSelect +_ https://github.com/processing/processing/issues/4821 + +_ allow modes to specify their own base file name +_ need to move "is this a sketch?" handling into Mode +_ fix extension check for other modes +_ https://github.com/processing/processing/issues/3980 + _ Spaces not handled correctly in when installing "processing-java" on macOS _ https://github.com/processing/processing/issues/4779 @@ -116,9 +125,6 @@ _ https://github.com/processing/processing/issues/4630 _ editor windows always open on display 1 _ https://github.com/processing/processing/issues/1566 -_ allow modes to specify their own base file name -_ need to move "is this a sketch?" handling into Mode - _ modify line number color when no lines extend that far? _ https://github.com/processing/processing/pull/4560 _ text gutter doesn't seem to be hidpi From 76a89c49b10d121165a07c52bddda6b99a2b3a04 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Tue, 17 Jan 2017 17:21:02 +0000 Subject: [PATCH 185/917] Fix #4826. PShape in Java2D wasn't respecting kind. Reverses commit 66db5817fabfcc01c1c1432e241e8e0fe3c63f93. --- core/src/processing/core/PShape.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/processing/core/PShape.java b/core/src/processing/core/PShape.java index 05bc4e18a4..7d6f1d7a57 100644 --- a/core/src/processing/core/PShape.java +++ b/core/src/processing/core/PShape.java @@ -1604,9 +1604,9 @@ protected void drawImpl(PGraphics g) { } else if (family == PRIMITIVE) { drawPrimitive(g); } else if (family == GEOMETRY) { - // same as path - drawPath(g); -// drawGeometry(g); + // Not same as path: `kind` matters. +// drawPath(g); + drawGeometry(g); } else if (family == PATH) { drawPath(g); } @@ -3442,4 +3442,4 @@ protected void colorCalcARGB(int argb, float alpha) { calcAlpha = (calcAi != 255); } -} \ No newline at end of file +} From ae7907ea587a5e56e6034556e4c116b652698500 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 18 Jan 2017 06:38:25 -0500 Subject: [PATCH 186/917] deal with Oracle download change, double redirect (fixes #4823) --- build/jre/src/Downloader.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/build/jre/src/Downloader.java b/build/jre/src/Downloader.java index 4402321a6f..3be2aba117 100644 --- a/build/jre/src/Downloader.java +++ b/build/jre/src/Downloader.java @@ -11,7 +11,7 @@ */ public class Downloader extends Task { static final String COOKIE = - "gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; " + + //"gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; " + "oraclelicense=accept-securebackup-cookie"; private int version; // Java 8 @@ -133,8 +133,8 @@ void download() throws IOException { //String url = "http://download.oracle.com/otn-pub/java/jdk/" + // https://edelivery.oracle.com/otn-pub/java/jdk/7u45-b18/jre-7u45-linux-i586.tar.gz - String url = "https://edelivery.oracle.com/otn-pub/java/jdk/" + - //String url = "https://download.oracle.com/otn-pub/java/jdk/" + + //String url = "https://edelivery.oracle.com/otn-pub/java/jdk/" + + String url = "http://download.oracle.com/otn-pub/java/jdk/" + (update == 0 ? String.format("%d-b%02d/", version, build) : String.format("%du%d-b%02d/", version, update, build)) + filename; @@ -148,11 +148,12 @@ void download() throws IOException { //printHeaders(conn); //conn.connect(); - if (conn.getResponseCode() == 302) { + while (conn.getResponseCode() == 302) { Map> headers = conn.getHeaderFields(); List location = headers.get("Location"); if (location.size() == 1) { url = location.get(0); + System.out.println("Redirecting to " + url); } else { throw new BuildException("Got " + location.size() + " locations."); } From 73e8173abba39f12ea288d9e1116ac37881529b9 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 18 Jan 2017 06:40:07 -0500 Subject: [PATCH 187/917] update notes --- todo.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/todo.txt b/todo.txt index 85d9b6df73..149bf70a5b 100755 --- a/todo.txt +++ b/todo.txt @@ -17,6 +17,8 @@ X otherwise System.err/out not going to a file unless we have GUI X also can't debug before the GUI shows up o gracefully recover from proxy problems X https://github.com/processing/processing/issues/1601 +X JRE download fails during ant build +X https://github.com/processing/processing/issues/4823 _ changed headerType to console (make sure changed back) _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 @@ -24,10 +26,16 @@ _ this may be fixed (removed invokeLater() on startup), unconfirmed _ "error during export" message, but no error message contents come through _ e.g. https://github.com/processing/processing/issues/4792 +_ Mode, requiring update, appears in Updates tab but not in Modes tab +_ https://github.com/processing/processing/issues/4822 + _ report of a library or tool (probably includes 2.x? 1.x?) breaking things _ NoSuchFieldError: useNativeSelect _ https://github.com/processing/processing/issues/4821 +_ turn off the old code that does unicode escapes in preproc +_ https://github.com/processing/processing/issues/4788 + _ allow modes to specify their own base file name _ need to move "is this a sketch?" handling into Mode _ fix extension check for other modes From 7215447836d8b9b7539e02f294ccdf06218fd1c5 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 18 Jan 2017 06:48:56 -0500 Subject: [PATCH 188/917] add patch note --- core/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index 984f130fa9..76796b9997 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -16,6 +16,9 @@ X add XML.print() method (prints with indent of 2) contribs X Adding missing docs and keywords for TableRow X https://github.com/processing/processing/pull/4333 +X PShape in Java2D wasn't respecting 'kind' +X https://github.com/processing/processing/issues/4826 +X https://github.com/processing/processing/pull/4834 cleaning o probably should also check to make sure PApplet running JVM 8 From e9f8d87d76c513602459b824531077d350bafa10 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 20 Jan 2017 12:49:23 +0100 Subject: [PATCH 189/917] Allow JAVA2D to terminate when animation thread dies When Java2D sketch crashes, closing the window does not stop Event Dispatch Thread. This fix makes PApplet.exit() do the right thing and not wait for surface to finish when the thread is already dead. Fixes #4831 --- core/src/processing/core/PSurfaceNone.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/core/PSurfaceNone.java b/core/src/processing/core/PSurfaceNone.java index 7b5a17f570..cb90384591 100644 --- a/core/src/processing/core/PSurfaceNone.java +++ b/core/src/processing/core/PSurfaceNone.java @@ -207,7 +207,7 @@ public boolean stopThread() { public boolean isStopped() { - return thread == null; + return thread == null || !thread.isAlive(); } From 8395134a4cdc78e8fa6319d0e1ac3a8436504e6a Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 21 Jan 2017 00:52:49 +0100 Subject: [PATCH 190/917] Hide sketchbook window before creating a new one Copy pasted from rebuildExamplesFrame() --- app/src/processing/app/Mode.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/src/processing/app/Mode.java b/app/src/processing/app/Mode.java index c7ceb1e2e2..52ff24192e 100644 --- a/app/src/processing/app/Mode.java +++ b/app/src/processing/app/Mode.java @@ -691,11 +691,18 @@ public DefaultMutableTreeNode buildSketchbookTree() { /** Sketchbook has changed, update it on next viewing. */ public void rebuildSketchbookFrame() { - boolean wasVisible = - (sketchbookFrame == null) ? false : sketchbookFrame.isVisible(); - sketchbookFrame = null; // Force a rebuild - if (wasVisible) { - showSketchbookFrame(); + if (sketchbookFrame != null) { + boolean visible = sketchbookFrame.isVisible(); + Rectangle bounds = null; + if (visible) { + bounds = sketchbookFrame.getBounds(); + sketchbookFrame.setVisible(false); + } + sketchbookFrame = null; + if (visible) { + showSketchbookFrame(); + sketchbookFrame.setBounds(bounds); + } } } From 3d212921b28efb991f7dee4986c698e075fa9de2 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 21 Jan 2017 00:53:27 +0100 Subject: [PATCH 191/917] Make sure old windows are disposed properly --- app/src/processing/app/Mode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/processing/app/Mode.java b/app/src/processing/app/Mode.java index 52ff24192e..2e6087fd56 100644 --- a/app/src/processing/app/Mode.java +++ b/app/src/processing/app/Mode.java @@ -656,6 +656,7 @@ public void rebuildExamplesFrame() { if (visible) { bounds = examplesFrame.getBounds(); examplesFrame.setVisible(false); + examplesFrame.dispose(); } examplesFrame = null; if (visible) { @@ -697,6 +698,7 @@ public void rebuildSketchbookFrame() { if (visible) { bounds = sketchbookFrame.getBounds(); sketchbookFrame.setVisible(false); + sketchbookFrame.dispose(); } sketchbookFrame = null; if (visible) { From 7b8f3078b2ee77868e3a8b2756e3f57e817c2a05 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 21 Jan 2017 00:54:21 +0100 Subject: [PATCH 192/917] Rebuild menus after deleting sketch --- app/src/processing/app/Sketch.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 214080f2bb..9a01d991c6 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -657,9 +657,10 @@ public void handleDeleteCode() { // get the changes into the sketchbook menu //sketchbook.rebuildMenus(); - // make a new sketch, and i think this will rebuild the sketch menu + // make a new sketch and rebuild the sketch menu //editor.handleNewUnchecked(); //editor.handleClose2(); + editor.getBase().rebuildSketchbookMenus(); editor.getBase().handleClose(editor, false); } else { From b1983941e7111cc6dc8f5cc02d63ad2522ca35f7 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 21 Jan 2017 04:11:40 +0100 Subject: [PATCH 193/917] Fire change notifications after all changes has been made --- app/src/processing/app/contrib/ListPanel.java | 2 +- app/src/processing/app/contrib/UpdateListPanel.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index 47ef717bab..2510599987 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -433,7 +433,6 @@ String getAuthorNameWithoutMarkup(String authorList) { void updatePanelOrdering(Set contributionsSet) { model.getDataVector().removeAllElements(); - model.fireTableDataChanged(); int rowCount = 0; synchronized (contributionsSet) { for (Contribution entry : contributionsSet) { @@ -445,6 +444,7 @@ void updatePanelOrdering(Set contributionsSet) { rowCount++; } } + model.fireTableDataChanged(); } diff --git a/app/src/processing/app/contrib/UpdateListPanel.java b/app/src/processing/app/contrib/UpdateListPanel.java index 8d39f02f00..e4287173f2 100644 --- a/app/src/processing/app/contrib/UpdateListPanel.java +++ b/app/src/processing/app/contrib/UpdateListPanel.java @@ -158,7 +158,6 @@ void updatePanelOrdering(Set contributionsSet) { // (UpdateContributionTab) contributionTab model.getDataVector().removeAllElements(); - model.fireTableDataChanged(); ContributionType currentType = null; // Avoid ugly synthesized bold @@ -213,6 +212,7 @@ void updatePanelOrdering(Set contributionsSet) { contributionTab.contribListing.getLatestPrettyVersion(entry) }); } + model.fireTableDataChanged(); UpdateContributionTab tab = (UpdateContributionTab) contributionTab; ((UpdateStatusPanel) tab.statusPanel).update(); } @@ -272,4 +272,4 @@ public void run() { } }); } -} \ No newline at end of file +} From 4171e7c8b9acd2cb973d0dcaa9a2b17d7de5da75 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 21 Jan 2017 04:16:05 +0100 Subject: [PATCH 194/917] Add filter conditions so contribs from other tabs are ignored Wrapped both method bodies with one if condition each. Blame the diff. --- app/src/processing/app/contrib/ListPanel.java | 74 ++++++++++--------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index 2510599987..abca136dcc 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -476,50 +476,54 @@ public void run() { public void contributionRemoved(final Contribution contribution) { - // TODO: this should already be on EDT, check it [jv] - EventQueue.invokeLater(new Runnable() { - public void run() { - synchronized (panelByContribution) { - DetailPanel panel = panelByContribution.get(contribution); - if (panel != null) { - remove(panel); - panelByContribution.remove(contribution); + if (filter.matches(contribution)) { + // TODO: this should already be on EDT, check it [jv] + EventQueue.invokeLater(new Runnable() { + public void run() { + synchronized (panelByContribution) { + DetailPanel panel = panelByContribution.get(contribution); + if (panel != null) { + remove(panel); + panelByContribution.remove(contribution); + } } + synchronized (visibleContributions) { + visibleContributions.remove(contribution); + } + updatePanelOrdering(visibleContributions); + updateColors(); + updateUI(); } - synchronized (visibleContributions) { - visibleContributions.remove(contribution); - } - updatePanelOrdering(visibleContributions); - updateColors(); - updateUI(); - } - }); + }); + } } public void contributionChanged(final Contribution oldContrib, final Contribution newContrib) { - // TODO: this should already be on EDT, check it [jv] - EventQueue.invokeLater(new Runnable() { - public void run() { - synchronized (panelByContribution) { - DetailPanel panel = panelByContribution.get(oldContrib); - if (panel == null) { - contributionAdded(newContrib); - } else { - panelByContribution.remove(oldContrib); - panel.setContribution(newContrib); - panelByContribution.put(newContrib, panel); + if (filter.matches(oldContrib) || filter.matches(newContrib)) { + // TODO: this should already be on EDT, check it [jv] + EventQueue.invokeLater(new Runnable() { + public void run() { + synchronized (panelByContribution) { + DetailPanel panel = panelByContribution.get(oldContrib); + if (panel == null) { + contributionAdded(newContrib); + } else { + panelByContribution.remove(oldContrib); + panel.setContribution(newContrib); + panelByContribution.put(newContrib, panel); + } } - } - synchronized (visibleContributions) { - if (visibleContributions.contains(oldContrib)) { - visibleContributions.remove(oldContrib); - visibleContributions.add(newContrib); + synchronized (visibleContributions) { + if (visibleContributions.contains(oldContrib)) { + visibleContributions.remove(oldContrib); + visibleContributions.add(newContrib); + } + updatePanelOrdering(visibleContributions); } - updatePanelOrdering(visibleContributions); } - } - }); + }); + } } public void filterLibraries(List filteredContributions) { From 0c09afe9602146021d0252093fa4821a6463a460 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 21 Jan 2017 04:26:26 +0100 Subject: [PATCH 195/917] Remove gratuitous invokeLater() Again, just unwrapped bodies from invokeLater, because they run on EDT already. Some were called in loops and spammed EDT with hundreds of Runnables. --- .../app/contrib/ContributionManager.java | 9 +- app/src/processing/app/contrib/ListPanel.java | 105 ++++++++---------- .../app/contrib/UpdateListPanel.java | 78 ++++++------- 3 files changed, 89 insertions(+), 103 deletions(-) diff --git a/app/src/processing/app/contrib/ContributionManager.java b/app/src/processing/app/contrib/ContributionManager.java index 4a6bbf4d96..e2e8297ef6 100644 --- a/app/src/processing/app/contrib/ContributionManager.java +++ b/app/src/processing/app/contrib/ContributionManager.java @@ -39,7 +39,7 @@ public class ContributionManager { - static final ContributionListing listing = ContributionListing.getInstance(); + static ContributionListing listing; /** @@ -543,6 +543,8 @@ static private void cleanup(final Base base) throws Exception { @Override protected Void doInBackground() throws Exception { try { + // TODO: pls explain the sleep and why this runs on a worker thread, + // but a couple of lines above on EDT [jv] Thread.sleep(1000); installPreviouslyFailed(base, Base.getSketchbookToolsFolder()); } catch (InterruptedException e) { @@ -610,7 +612,9 @@ public boolean accept(File folder) { if (file.getName().equals(contrib.getName())) { file.delete(); installOnStartUp(base, contrib); - listing.replaceContribution(contrib, contrib); + EventQueue.invokeAndWait(() -> { + listing.replaceContribution(contrib, contrib); + }); } } } @@ -700,6 +704,7 @@ public boolean accept(File folder) { static public void init(Base base) throws Exception { + listing = ContributionListing.getInstance(); // Moved here to make sure it runs on EDT [jv 170121] managerDialog = new ManagerFrame(base); cleanup(base); } diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index abca136dcc..19d2f16a17 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -448,81 +448,70 @@ void updatePanelOrdering(Set contributionsSet) { } + // Thread: EDT public void contributionAdded(final Contribution contribution) { if (filter.matches(contribution)) { - // TODO: this should already be on EDT, check it [jv] - EventQueue.invokeLater(new Runnable() { - public void run() { - if (!panelByContribution.containsKey(contribution)) { - DetailPanel newPanel = - new DetailPanel(ListPanel.this); - synchronized (panelByContribution) { - panelByContribution.put(contribution, newPanel); - } - synchronized (visibleContributions) { - visibleContributions.add(contribution); - } - if (newPanel != null) { - newPanel.setContribution(contribution); - add(newPanel); - updatePanelOrdering(visibleContributions); - updateColors(); // XXX this is the place - } - } + if (!panelByContribution.containsKey(contribution)) { + DetailPanel newPanel = + new DetailPanel(ListPanel.this); + synchronized (panelByContribution) { + panelByContribution.put(contribution, newPanel); } - }); + synchronized (visibleContributions) { + visibleContributions.add(contribution); + } + if (newPanel != null) { + newPanel.setContribution(contribution); + add(newPanel); + updatePanelOrdering(visibleContributions); + updateColors(); // XXX this is the place + } + } } } + // Thread: EDT public void contributionRemoved(final Contribution contribution) { if (filter.matches(contribution)) { - // TODO: this should already be on EDT, check it [jv] - EventQueue.invokeLater(new Runnable() { - public void run() { - synchronized (panelByContribution) { - DetailPanel panel = panelByContribution.get(contribution); - if (panel != null) { - remove(panel); - panelByContribution.remove(contribution); - } - } - synchronized (visibleContributions) { - visibleContributions.remove(contribution); - } - updatePanelOrdering(visibleContributions); - updateColors(); - updateUI(); + synchronized (panelByContribution) { + DetailPanel panel = panelByContribution.get(contribution); + if (panel != null) { + remove(panel); + panelByContribution.remove(contribution); } - }); + } + synchronized (visibleContributions) { + visibleContributions.remove(contribution); + } + updatePanelOrdering(visibleContributions); + updateColors(); + updateUI(); } } + + // Thread: EDT public void contributionChanged(final Contribution oldContrib, final Contribution newContrib) { if (filter.matches(oldContrib) || filter.matches(newContrib)) { - // TODO: this should already be on EDT, check it [jv] - EventQueue.invokeLater(new Runnable() { - public void run() { - synchronized (panelByContribution) { - DetailPanel panel = panelByContribution.get(oldContrib); - if (panel == null) { - contributionAdded(newContrib); - } else { - panelByContribution.remove(oldContrib); - panel.setContribution(newContrib); - panelByContribution.put(newContrib, panel); - } - } - synchronized (visibleContributions) { - if (visibleContributions.contains(oldContrib)) { - visibleContributions.remove(oldContrib); - visibleContributions.add(newContrib); - } - updatePanelOrdering(visibleContributions); - } + synchronized (panelByContribution) { + DetailPanel panel = panelByContribution.get(oldContrib); + if (panel == null) { + contributionAdded(newContrib); + } else { + panelByContribution.remove(oldContrib); + panel.setContribution(newContrib); + panelByContribution.put(newContrib, panel); } - }); + } + synchronized (visibleContributions) { + if (visibleContributions.contains(oldContrib)) { + visibleContributions.remove(oldContrib); + visibleContributions.add(newContrib); + } + updatePanelOrdering(visibleContributions); + } } } diff --git a/app/src/processing/app/contrib/UpdateListPanel.java b/app/src/processing/app/contrib/UpdateListPanel.java index e4287173f2..44fc7b5ebf 100644 --- a/app/src/processing/app/contrib/UpdateListPanel.java +++ b/app/src/processing/app/contrib/UpdateListPanel.java @@ -218,58 +218,50 @@ void updatePanelOrdering(Set contributionsSet) { } + // Thread: EDT @Override public void contributionAdded(final Contribution contribution) { if (filter.matches(contribution)) { - // TODO: this should already be on EDT, check it [jv] - EventQueue.invokeLater(new Runnable() { - public void run() { - // TODO make this longer and more contorted [fry] - DetailPanel newPanel = - contributionTab.contribDialog.getTab(contribution.getType()).contributionListPanel.panelByContribution.get(contribution); - if (newPanel == null) { - newPanel = new DetailPanel(UpdateListPanel.this); - } - synchronized (panelByContribution) { - if (!panelByContribution.containsKey(contribution)) { - panelByContribution.put(contribution, newPanel); - } - synchronized (visibleContributions) { - visibleContributions.add(contribution); - } - if (newPanel != null) { - newPanel.setContribution(contribution); - add(newPanel); - updatePanelOrdering(panelByContribution.keySet()); - updateColors(); // XXX this is the place - } - } + // TODO make this longer and more contorted [fry] + DetailPanel newPanel = + contributionTab.contribDialog.getTab(contribution.getType()).contributionListPanel.panelByContribution.get(contribution); + if (newPanel == null) { + newPanel = new DetailPanel(UpdateListPanel.this); + } + synchronized (panelByContribution) { + if (!panelByContribution.containsKey(contribution)) { + panelByContribution.put(contribution, newPanel); } - }); + synchronized (visibleContributions) { + visibleContributions.add(contribution); + } + if (newPanel != null) { + newPanel.setContribution(contribution); + add(newPanel); + updatePanelOrdering(panelByContribution.keySet()); + updateColors(); // XXX this is the place + } + } } } - + + // Thread: EDT @Override public void contributionChanged(final Contribution oldContrib, final Contribution newContrib) { - // TODO: this should already be on EDT, check it [jv] - EventQueue.invokeLater(new Runnable() { - public void run() { - synchronized (panelByContribution) { - DetailPanel panel = panelByContribution.get(oldContrib); - if (panel == null) { - contributionAdded(newContrib); - } else { - panelByContribution.remove(oldContrib); - } - } - synchronized (visibleContributions) { - if (visibleContributions.contains(oldContrib)) { - visibleContributions.remove(oldContrib); - } - updatePanelOrdering(visibleContributions); - } + synchronized (panelByContribution) { + DetailPanel panel = panelByContribution.get(oldContrib); + if (panel == null) { + contributionAdded(newContrib); + } else { + panelByContribution.remove(oldContrib); } - }); + } + synchronized (visibleContributions) { + if (visibleContributions.contains(oldContrib)) { + visibleContributions.remove(oldContrib); + } + updatePanelOrdering(visibleContributions); + } } } From ba51eb07fba97a9022d82da54cffb972561228d4 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 21 Jan 2017 04:42:33 +0100 Subject: [PATCH 196/917] Get rid of unnecessary manual synchronization Remove manual synchronization on visibleContributions and panelByContribution. Both are accessed only from EDT. --- app/src/processing/app/contrib/ListPanel.java | 156 ++++++++---------- .../app/contrib/UpdateListPanel.java | 43 ++--- 2 files changed, 89 insertions(+), 110 deletions(-) diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index 19d2f16a17..07b03a34d7 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -430,19 +430,17 @@ String getAuthorNameWithoutMarkup(String authorList) { return name.toString(); } - + // Thread: EDT void updatePanelOrdering(Set contributionsSet) { model.getDataVector().removeAllElements(); int rowCount = 0; - synchronized (contributionsSet) { - for (Contribution entry : contributionsSet) { - model.addRow(new Object[]{entry, entry, entry}); - if (selectedPanel != null && - entry.getName().equals(selectedPanel.getContrib().getName())) { - table.setRowSelectionInterval(rowCount, rowCount); - } - rowCount++; + for (Contribution entry : contributionsSet) { + model.addRow(new Object[]{entry, entry, entry}); + if (selectedPanel != null && + entry.getName().equals(selectedPanel.getContrib().getName())) { + table.setRowSelectionInterval(rowCount, rowCount); } + rowCount++; } model.fireTableDataChanged(); } @@ -454,12 +452,8 @@ public void contributionAdded(final Contribution contribution) { if (!panelByContribution.containsKey(contribution)) { DetailPanel newPanel = new DetailPanel(ListPanel.this); - synchronized (panelByContribution) { - panelByContribution.put(contribution, newPanel); - } - synchronized (visibleContributions) { - visibleContributions.add(contribution); - } + panelByContribution.put(contribution, newPanel); + visibleContributions.add(contribution); if (newPanel != null) { newPanel.setContribution(contribution); add(newPanel); @@ -474,16 +468,12 @@ public void contributionAdded(final Contribution contribution) { // Thread: EDT public void contributionRemoved(final Contribution contribution) { if (filter.matches(contribution)) { - synchronized (panelByContribution) { - DetailPanel panel = panelByContribution.get(contribution); - if (panel != null) { - remove(panel); - panelByContribution.remove(contribution); - } - } - synchronized (visibleContributions) { - visibleContributions.remove(contribution); + DetailPanel panel = panelByContribution.get(contribution); + if (panel != null) { + remove(panel); + panelByContribution.remove(contribution); } + visibleContributions.remove(contribution); updatePanelOrdering(visibleContributions); updateColors(); updateUI(); @@ -495,51 +485,48 @@ public void contributionRemoved(final Contribution contribution) { public void contributionChanged(final Contribution oldContrib, final Contribution newContrib) { if (filter.matches(oldContrib) || filter.matches(newContrib)) { - synchronized (panelByContribution) { - DetailPanel panel = panelByContribution.get(oldContrib); - if (panel == null) { - contributionAdded(newContrib); - } else { - panelByContribution.remove(oldContrib); - panel.setContribution(newContrib); - panelByContribution.put(newContrib, panel); - } + DetailPanel panel = panelByContribution.get(oldContrib); + if (panel == null) { + contributionAdded(newContrib); + } else { + panelByContribution.remove(oldContrib); + panel.setContribution(newContrib); + panelByContribution.put(newContrib, panel); } - synchronized (visibleContributions) { - if (visibleContributions.contains(oldContrib)) { - visibleContributions.remove(oldContrib); - visibleContributions.add(newContrib); - } - updatePanelOrdering(visibleContributions); + if (visibleContributions.contains(oldContrib)) { + visibleContributions.remove(oldContrib); + visibleContributions.add(newContrib); } + updatePanelOrdering(visibleContributions); } } + + // Thread: EDT public void filterLibraries(List filteredContributions) { - synchronized (visibleContributions) { - visibleContributions.clear(); - for (Contribution contribution : panelByContribution.keySet()) { - if (contribution.getType() == contributionTab.contribType) { - if (filteredContributions.contains(contribution)) { - if (panelByContribution.keySet().contains(contribution)) { - visibleContributions.add(contribution); - } + visibleContributions.clear(); + for (Contribution contribution : panelByContribution.keySet()) { + if (contribution.getType() == contributionTab.contribType) { + if (filteredContributions.contains(contribution)) { + if (panelByContribution.keySet().contains(contribution)) { + visibleContributions.add(contribution); } } } - // TODO: Make the following loop work for optimization -// for (Contribution contribution : filteredContributions) { -// if (contribution.getType() == contributionTab.contribType) { -// if(panelByContribution.keySet().contains(contribution)){ -// visibleContributions.add(contribution); -// } -// } -// } - updatePanelOrdering(visibleContributions); } + // TODO: Make the following loop work for optimization +// for (Contribution contribution : filteredContributions) { +// if (contribution.getType() == contributionTab.contribType) { +// if(panelByContribution.keySet().contains(contribution)){ +// visibleContributions.add(contribution); +// } +// } +// } + updatePanelOrdering(visibleContributions); } + // Thread: EDT protected void setSelectedPanel(DetailPanel contributionPanel) { contributionTab.updateStatusPanel(contributionPanel); @@ -566,46 +553,45 @@ protected DetailPanel getSelectedPanel() { } + // Thread: EDT /** * Updates the colors of all library panels that are visible. */ protected void updateColors() { int count = 0; - synchronized (panelByContribution) { - for (Entry entry : panelByContribution.entrySet()) { - DetailPanel panel = entry.getValue(); - - if (panel.isVisible() && panel.isSelected()) { - panel.setBackground(UIManager.getColor("List.selectionBackground")); - panel.setForeground(UIManager.getColor("List.selectionForeground")); - panel.setBorder(UIManager.getBorder("List.focusCellHighlightBorder")); - count++; + for (Entry entry : panelByContribution.entrySet()) { + DetailPanel panel = entry.getValue(); - } else { - Border border = null; - if (panel.isVisible()) { - if (Platform.isMacOS()) { - if (count % 2 == 1) { - border = UIManager.getBorder("List.oddRowBackgroundPainter"); - } else { - border = UIManager.getBorder("List.evenRowBackgroundPainter"); - } + if (panel.isVisible() && panel.isSelected()) { + panel.setBackground(UIManager.getColor("List.selectionBackground")); + panel.setForeground(UIManager.getColor("List.selectionForeground")); + panel.setBorder(UIManager.getBorder("List.focusCellHighlightBorder")); + count++; + + } else { + Border border = null; + if (panel.isVisible()) { + if (Platform.isMacOS()) { + if (count % 2 == 1) { + border = UIManager.getBorder("List.oddRowBackgroundPainter"); } else { - if (count % 2 == 1) { - panel.setBackground(new Color(219, 224, 229)); - } else { - panel.setBackground(new Color(241, 241, 241)); - } + border = UIManager.getBorder("List.evenRowBackgroundPainter"); + } + } else { + if (count % 2 == 1) { + panel.setBackground(new Color(219, 224, 229)); + } else { + panel.setBackground(new Color(241, 241, 241)); } - count++; } + count++; + } - if (border == null) { - border = BorderFactory.createEmptyBorder(1, 1, 1, 1); - } - panel.setBorder(border); - panel.setForeground(UIManager.getColor("List.foreground")); + if (border == null) { + border = BorderFactory.createEmptyBorder(1, 1, 1, 1); } + panel.setBorder(border); + panel.setForeground(UIManager.getColor("List.foreground")); } } } diff --git a/app/src/processing/app/contrib/UpdateListPanel.java b/app/src/processing/app/contrib/UpdateListPanel.java index 44fc7b5ebf..aea0442d99 100644 --- a/app/src/processing/app/contrib/UpdateListPanel.java +++ b/app/src/processing/app/contrib/UpdateListPanel.java @@ -151,6 +151,7 @@ public int compare(Contribution o1, Contribution o2) { }); } + // Thread: EDT @Override void updatePanelOrdering(Set contributionsSet) { // int updateCount = panelByContribution.size(); @@ -228,19 +229,15 @@ public void contributionAdded(final Contribution contribution) { if (newPanel == null) { newPanel = new DetailPanel(UpdateListPanel.this); } - synchronized (panelByContribution) { - if (!panelByContribution.containsKey(contribution)) { - panelByContribution.put(contribution, newPanel); - } - synchronized (visibleContributions) { - visibleContributions.add(contribution); - } - if (newPanel != null) { - newPanel.setContribution(contribution); - add(newPanel); - updatePanelOrdering(panelByContribution.keySet()); - updateColors(); // XXX this is the place - } + if (!panelByContribution.containsKey(contribution)) { + panelByContribution.put(contribution, newPanel); + } + visibleContributions.add(contribution); + if (newPanel != null) { + newPanel.setContribution(contribution); + add(newPanel); + updatePanelOrdering(panelByContribution.keySet()); + updateColors(); // XXX this is the place } } } @@ -249,19 +246,15 @@ public void contributionAdded(final Contribution contribution) { @Override public void contributionChanged(final Contribution oldContrib, final Contribution newContrib) { - synchronized (panelByContribution) { - DetailPanel panel = panelByContribution.get(oldContrib); - if (panel == null) { - contributionAdded(newContrib); - } else { - panelByContribution.remove(oldContrib); - } + DetailPanel panel = panelByContribution.get(oldContrib); + if (panel == null) { + contributionAdded(newContrib); + } else { + panelByContribution.remove(oldContrib); } - synchronized (visibleContributions) { - if (visibleContributions.contains(oldContrib)) { - visibleContributions.remove(oldContrib); - } - updatePanelOrdering(visibleContributions); + if (visibleContributions.contains(oldContrib)) { + visibleContributions.remove(oldContrib); } + updatePanelOrdering(visibleContributions); } } From 3088ded337960c2bd16a0f448f0310ace6c4fb5a Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 21 Jan 2017 05:21:05 +0100 Subject: [PATCH 197/917] Remove some unnecessary code --- app/src/processing/app/contrib/ListPanel.java | 12 +++++------- app/src/processing/app/contrib/UpdateListPanel.java | 10 ++++------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index 07b03a34d7..29b903ffe8 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -378,7 +378,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, } String authorList = contribution.getAuthorList(); String name = getAuthorNameWithoutMarkup(authorList); - label.setText(name.toString()); + label.setText(name); label.setHorizontalAlignment(SwingConstants.LEFT); if(!contribution.isCompatible(Base.getRevision())){ label.setForeground(Color.LIGHT_GRAY); @@ -454,12 +454,10 @@ public void contributionAdded(final Contribution contribution) { new DetailPanel(ListPanel.this); panelByContribution.put(contribution, newPanel); visibleContributions.add(contribution); - if (newPanel != null) { - newPanel.setContribution(contribution); - add(newPanel); - updatePanelOrdering(visibleContributions); - updateColors(); // XXX this is the place - } + newPanel.setContribution(contribution); + add(newPanel); + updatePanelOrdering(visibleContributions); + updateColors(); // XXX this is the place } } } diff --git a/app/src/processing/app/contrib/UpdateListPanel.java b/app/src/processing/app/contrib/UpdateListPanel.java index aea0442d99..47939a3ce9 100644 --- a/app/src/processing/app/contrib/UpdateListPanel.java +++ b/app/src/processing/app/contrib/UpdateListPanel.java @@ -233,12 +233,10 @@ public void contributionAdded(final Contribution contribution) { panelByContribution.put(contribution, newPanel); } visibleContributions.add(contribution); - if (newPanel != null) { - newPanel.setContribution(contribution); - add(newPanel); - updatePanelOrdering(panelByContribution.keySet()); - updateColors(); // XXX this is the place - } + newPanel.setContribution(contribution); + add(newPanel); + updatePanelOrdering(panelByContribution.keySet()); + updateColors(); // XXX this is the place } } From 9ef07444e150feb6a38ade7e9a39950b9ef32390 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 21 Jan 2017 06:56:32 +0100 Subject: [PATCH 198/917] Fix broken Update tab Contribution stays there with spinning wheel until the installation completes --- app/src/processing/app/contrib/UpdateListPanel.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/processing/app/contrib/UpdateListPanel.java b/app/src/processing/app/contrib/UpdateListPanel.java index 47939a3ce9..95b2742521 100644 --- a/app/src/processing/app/contrib/UpdateListPanel.java +++ b/app/src/processing/app/contrib/UpdateListPanel.java @@ -247,10 +247,8 @@ public void contributionChanged(final Contribution oldContrib, DetailPanel panel = panelByContribution.get(oldContrib); if (panel == null) { contributionAdded(newContrib); - } else { + } else if (newContrib.isInstalled()) { panelByContribution.remove(oldContrib); - } - if (visibleContributions.contains(oldContrib)) { visibleContributions.remove(oldContrib); } updatePanelOrdering(visibleContributions); From 4a50ea319bab907f5d87ddfa127f17f78352c216 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 21 Jan 2017 19:03:12 +0100 Subject: [PATCH 199/917] Small threading fixes for run/present/tweak --- java/src/processing/mode/java/JavaEditor.java | 28 ++++++++++++------- java/src/processing/mode/java/JavaMode.java | 7 ----- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 40814d83d5..b08d2bcdd8 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -1057,15 +1057,15 @@ public void handleRun() { debugger.continueDebug(); } else { + prepareRun(); + toolbar.activateRun(); new Thread(new Runnable() { public void run() { - prepareRun(); try { - toolbar.activateRun(); //runtime = jmode.handleRun(sketch, JavaEditor.this); runtime = jmode.handleLaunch(sketch, JavaEditor.this, false); } catch (Exception e) { - statusError(e); + EventQueue.invokeLater(() -> statusError(e)); } } }).start(); @@ -1074,15 +1074,15 @@ public void run() { public void handlePresent() { + prepareRun(); + toolbar.activateRun(); new Thread(new Runnable() { public void run() { - prepareRun(); try { - toolbar.activateRun(); //runtime = jmode.handlePresent(sketch, JavaEditor.this); runtime = jmode.handleLaunch(sketch, JavaEditor.this, true); } catch (Exception e) { - statusError(e); + EventQueue.invokeLater(() -> statusError(e)); } } }).start(); @@ -1090,15 +1090,23 @@ public void run() { public void handleTweak() { + prepareRun(); + //toolbar.activate(JavaToolbar.RUN); + toolbar.activateRun(); + + if (sketch.isModified()) { + toolbar.deactivateRun(); + Messages.showMessage(Language.text("menu.file.save"), + Language.text("tweak_mode.save_before_tweak")); + return; + } + new Thread(new Runnable() { public void run() { - prepareRun(); try { -// toolbar.activate(JavaToolbar.RUN); - toolbar.activateRun(); runtime = jmode.handleTweak(sketch, JavaEditor.this); } catch (Exception e) { - statusError(e); + EventQueue.invokeLater(() -> statusError(e)); } } }).start(); diff --git a/java/src/processing/mode/java/JavaMode.java b/java/src/processing/mode/java/JavaMode.java index 58423decb7..b08a501d66 100644 --- a/java/src/processing/mode/java/JavaMode.java +++ b/java/src/processing/mode/java/JavaMode.java @@ -144,13 +144,6 @@ public Runner handleTweak(Sketch sketch, // final boolean present) throws SketchException { final JavaEditor editor = (JavaEditor) listener; - if (isSketchModified(sketch)) { - editor.deactivateRun(); - Messages.showMessage(Language.text("menu.file.save"), - Language.text("tweak_mode.save_before_tweak")); - return null; - } - // first try to build the unmodified code JavaBuild build = new JavaBuild(sketch); // String appletClassName = build.build(false); From 7886b5d1b4495f51871742280ff70ac7d4a781ad Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 22 Jan 2017 21:44:53 +0100 Subject: [PATCH 200/917] Keep Windows timer resolution high for OpenGL sketches Otherwise java.util.Timer used by FPSAnimator uses 10 or 15 ms resolution, which results in 60 fps sketches running at around 30 fps and 30 fps sketches running at around 21 fps. Fixes #4846 --- core/src/processing/opengl/PSurfaceJOGL.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index bb9c2bc331..daa5079c97 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -431,6 +431,20 @@ protected void initListeners() { protected void initAnimator() { + if (PApplet.platform == PConstants.WINDOWS) { + // Force Windows to keep timer resolution high by + // sleeping for time which is not a multiple of 10 ms. + // See section "Clocks and Timers on Windows": + // https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks + Thread highResTimerThread = new Thread(() -> { + try { + Thread.sleep(Long.MAX_VALUE); + } catch (InterruptedException ignore) { } + }, "HighResTimerThread"); + highResTimerThread.setDaemon(true); + highResTimerThread.start(); + } + animator = new FPSAnimator(window, 60); drawException = null; animator.setUncaughtExceptionHandler(new GLAnimatorControl.UncaughtExceptionHandler() { From e5833e8a7facb53a0c8b8854e9545d6b550e7ef2 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 22 Jan 2017 23:24:32 +0100 Subject: [PATCH 201/917] Make run button behave When clicking run button while a sketch is running, it will be activated again when the sketch is restarted. Previously it got deactivated by the old sketch runner, because it was quitting after the new sketch runner started. --- java/src/processing/mode/java/JavaEditor.java | 7 +++++++ java/src/processing/mode/java/runner/Runner.java | 16 ++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index b08d2bcdd8..70364352a7 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -1170,6 +1170,13 @@ public void handleContinue() { } + public void onRunnerExiting(Runner runner) { + if (this.runtime == runner) { + deactivateRun(); + } + } + + // /** Toggle a breakpoint on the current line. */ // public void toggleBreakpoint() { // toggleBreakpoint(getCurrentLineID().lineIdx()); diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index 9d1dad83d4..9508e2e172 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -24,10 +24,10 @@ import processing.app.*; import processing.app.exec.StreamRedirectThread; -import processing.app.ui.Editor; import processing.core.*; import processing.data.StringList; import processing.mode.java.JavaBuild; +import processing.mode.java.JavaEditor; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; @@ -71,7 +71,7 @@ public class Runner implements MessageConsumer { protected Thread outThread = null; protected SketchException exception; - protected Editor editor; + protected JavaEditor editor; protected JavaBuild build; protected Process process; @@ -86,8 +86,8 @@ public Runner(JavaBuild build, RunnerListener listener) throws SketchException { checkLocalHost(); - if (listener instanceof Editor) { - this.editor = (Editor) listener; + if (listener instanceof JavaEditor) { + this.editor = (JavaEditor) listener; sketchErr = editor.getConsole().getErr(); sketchOut = editor.getConsole().getOut(); } else { @@ -610,7 +610,9 @@ public void run() { // or the user manually closes the sketch window. // TODO this should be handled better, should it not? if (editor != null) { - editor.deactivateRun(); + java.awt.EventQueue.invokeLater(() -> { + editor.onRunnerExiting(Runner.this); + }); } } catch (InterruptedException exc) { // we don't interrupt @@ -679,7 +681,9 @@ public void exceptionEvent(ExceptionEvent event) { handleCommonErrors(exceptionName, message, listener, sketchErr); if (editor != null) { - editor.deactivateRun(); + java.awt.EventQueue.invokeLater(() -> { + editor.onRunnerExiting(Runner.this); + }); } } From aa2db6b505ffc4bd8c4d03f23ecdcdfc27d823ee Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Mon, 23 Jan 2017 03:07:42 +0100 Subject: [PATCH 202/917] Add proper synchronization for sketch launching and closing Pressing Run button twice launched two sketch windows, but only one of them could be closed by Stop button. Pressing Stop had effect only after sketch VM was launched. Both of these issues are now fixed and buttons can handle a frustration-relieving session of aggressive clicking, leaving one sketch window if Run was the last button pressed or no window if Stop was the last button pressed. --- java/src/processing/mode/java/JavaEditor.java | 87 +++++++++-------- .../processing/mode/java/runner/Runner.java | 94 ++++++++++++------- 2 files changed, 100 insertions(+), 81 deletions(-) diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 70364352a7..e340ee7ace 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -47,6 +47,9 @@ public class JavaEditor extends Editor { // Runner associated with this editor window private Runner runtime; + private boolean runtimeLaunchRequested; + private final Object runtimeLock = new Object[0]; + // Need to sort through the rest of these additions [fry] protected final List breakpointedLines = new ArrayList<>(); @@ -1057,57 +1060,48 @@ public void handleRun() { debugger.continueDebug(); } else { - prepareRun(); - toolbar.activateRun(); - new Thread(new Runnable() { - public void run() { - try { - //runtime = jmode.handleRun(sketch, JavaEditor.this); - runtime = jmode.handleLaunch(sketch, JavaEditor.this, false); - } catch (Exception e) { - EventQueue.invokeLater(() -> statusError(e)); - } - } - }).start(); + handleLaunch(false, false); } } public void handlePresent() { - prepareRun(); - toolbar.activateRun(); - new Thread(new Runnable() { - public void run() { - try { - //runtime = jmode.handlePresent(sketch, JavaEditor.this); - runtime = jmode.handleLaunch(sketch, JavaEditor.this, true); - } catch (Exception e) { - EventQueue.invokeLater(() -> statusError(e)); - } - } - }).start(); + handleLaunch(true, false); } public void handleTweak() { - prepareRun(); - //toolbar.activate(JavaToolbar.RUN); - toolbar.activateRun(); + autoSave(); if (sketch.isModified()) { - toolbar.deactivateRun(); Messages.showMessage(Language.text("menu.file.save"), Language.text("tweak_mode.save_before_tweak")); return; } - new Thread(new Runnable() { - public void run() { - try { - runtime = jmode.handleTweak(sketch, JavaEditor.this); - } catch (Exception e) { - EventQueue.invokeLater(() -> statusError(e)); + handleLaunch(false, true); + } + + protected void handleLaunch(boolean present, boolean tweak) { + prepareRun(); + toolbar.activateRun(); + synchronized (runtimeLock) { + runtimeLaunchRequested = true; + } + new Thread(() -> { + try { + synchronized (runtimeLock) { + if (runtimeLaunchRequested) { + runtimeLaunchRequested = false; + if (!tweak) { + runtime = jmode.handleLaunch(sketch, JavaEditor.this, present); + } else { + runtime = jmode.handleTweak(sketch, JavaEditor.this); + } + } } + } catch (Exception e) { + EventQueue.invokeLater(() -> statusError(e)); } }).start(); } @@ -1122,23 +1116,24 @@ public void handleStop() { debugger.stopDebug(); } else { -// toolbar.activate(JavaToolbar.STOP); toolbar.activateStop(); try { - //jmode.handleStop(); - if (runtime != null) { - runtime.close(); // kills the window - runtime = null; - // } else { - // System.out.println("runtime is null"); + synchronized (runtimeLock) { + if (runtimeLaunchRequested) { + // Cancel the launch before the runtime was created + runtimeLaunchRequested = false; + } + if (runtime != null) { + // Cancel the launch after the runtime was created + runtime.close(); // kills the window + runtime = null; + } } } catch (Exception e) { statusError(e); } -// toolbar.deactivate(JavaToolbar.RUN); -// toolbar.deactivate(JavaToolbar.STOP); toolbar.deactivateStop(); toolbar.deactivateRun(); @@ -1171,8 +1166,10 @@ public void handleContinue() { public void onRunnerExiting(Runner runner) { - if (this.runtime == runner) { - deactivateRun(); + synchronized (runtimeLock) { + if (this.runtime == runner) { + deactivateRun(); + } } } diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index 9508e2e172..c383fc2c81 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -61,7 +61,7 @@ public class Runner implements MessageConsumer { protected RunnerListener listener; // Running remote VM - protected VirtualMachine vm; + protected volatile VirtualMachine vm; protected boolean vmReturnedError; // Thread transferring remote error stream to our error stream @@ -78,6 +78,9 @@ public class Runner implements MessageConsumer { protected PrintStream sketchErr; protected PrintStream sketchOut; + protected volatile boolean cancelled; + protected final Object cancelLock = new Object[0]; + public Runner(JavaBuild build, RunnerListener listener) throws SketchException { this.listener = listener; @@ -218,6 +221,13 @@ public boolean launchVirtualMachine(boolean present, String[] args) { commandArgs.append(vmParams); commandArgs.append(sketchParams); + + // Opportunistically quit if the launch was cancelled, + // the next chance to cancel will be after connecting to the VM + if (cancelled) { + return false; + } + launchJava(commandArgs.array()); AttachingConnector connector = (AttachingConnector) @@ -249,7 +259,15 @@ public boolean launchVirtualMachine(boolean present, String[] args) { while (true) { try { Messages.log(getClass().getName() + " attempting to attach to VM"); - vm = connector.attach(arguments); + synchronized (cancelLock) { + vm = connector.attach(arguments); + if (cancelled && vm != null) { + // cancelled and connected to the VM, handle closing now + Messages.log(getClass().getName() + " aborting, launch cancelled"); + close(); + return false; + } + } // vm = connector.attach(arguments); if (vm != null) { Messages.log(getClass().getName() + " attached to the VM"); @@ -523,29 +541,28 @@ protected void generateTrace() { //vm.setDebugTraceMode(debugTraceMode); // vm.setDebugTraceMode(VirtualMachine.TRACE_ALL); // vm.setDebugTraceMode(VirtualMachine.TRACE_NONE); // formerly, seems to have no effect - - // Calling this seems to set something internally to make the - // Eclipse JDI wake up. Without it, an ObjectCollectedException - // is thrown on excReq.enable(). No idea why this works, - // but at least exception handling has returned. (Suspect that it may - // block until all or at least some threads are available, meaning - // that the app has launched and we have legit objects to talk to). - vm.allThreads(); - // The bug may not have been noticed because the test suite waits for - // a thread to be available, and queries it by calling allThreads(). - // See org.eclipse.debug.jdi.tests.AbstractJDITest for the example. - - EventRequestManager mgr = vm.eventRequestManager(); - // get only the uncaught exceptions - ExceptionRequest excReq = mgr.createExceptionRequest(null, false, true); -// System.out.println(excReq); - // this version reports all exceptions, caught or uncaught -// ExceptionRequest excReq = mgr.createExceptionRequest(null, true, true); - // suspend so we can step - excReq.setSuspendPolicy(EventRequest.SUSPEND_ALL); -// excReq.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); -// excReq.setSuspendPolicy(EventRequest.SUSPEND_NONE); // another option? - excReq.enable(); + try { + // Calling this seems to set something internally to make the + // Eclipse JDI wake up. Without it, an ObjectCollectedException + // is thrown on excReq.enable(). No idea why this works, + // but at least exception handling has returned. (Suspect that it may + // block until all or at least some threads are available, meaning + // that the app has launched and we have legit objects to talk to). + vm.allThreads(); + // The bug may not have been noticed because the test suite waits for + // a thread to be available, and queries it by calling allThreads(). + // See org.eclipse.debug.jdi.tests.AbstractJDITest for the example. + + EventRequestManager mgr = vm.eventRequestManager(); + // get only the uncaught exceptions + ExceptionRequest excReq = mgr.createExceptionRequest(null, false, true); + // this version reports all exceptions, caught or uncaught + // suspend so we can step + excReq.setSuspendPolicy(EventRequest.SUSPEND_ALL); + excReq.enable(); + } catch (VMDisconnectedException ignore) { + return; + } Thread eventThread = new Thread() { public void run() { @@ -851,19 +868,22 @@ protected SketchException findException(String message, ObjectReference or, Thre public void close() { - // TODO make sure stop() has already been called to exit the sketch + synchronized (cancelLock) { + cancelled = true; + + // TODO make sure stop() has already been called to exit the sketch - // TODO actually kill off the vm here - if (vm != null) { - try { - vm.exit(0); + // TODO actually kill off the vm here + if (vm != null) { + try { + vm.exit(0); - } catch (com.sun.jdi.VMDisconnectedException vmde) { - // if the vm has disconnected on its own, ignore message - //System.out.println("harmless disconnect " + vmde.getMessage()); - // TODO shouldn't need to do this, need to do more cleanup + } catch (com.sun.jdi.VMDisconnectedException vmde) { + // if the vm has disconnected on its own, ignore message + //System.out.println("harmless disconnect " + vmde.getMessage()); + // TODO shouldn't need to do this, need to do more cleanup + } } - vm = null; } } @@ -884,7 +904,9 @@ synchronized public void message(String s) { if (editor != null) { // editor.internalCloseRunner(); // [091124] // editor.handleStop(); // prior to 0192 - editor.internalCloseRunner(); // 0192 + java.awt.EventQueue.invokeLater(() -> { + editor.internalCloseRunner(); // 0192 + }); } return; } From 7d559371b037ac29fabd99c889931f6bee9494d2 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Mon, 23 Jan 2017 03:09:51 +0100 Subject: [PATCH 203/917] Fix restarting sketch in Debug mode when Run is pressed Disconnect event of the old VM would arrive after the new VM was created, closing it instantly and leaving user without a running sketch. --- java/src/processing/mode/java/Debugger.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/java/src/processing/mode/java/Debugger.java b/java/src/processing/mode/java/Debugger.java index 131fe5faa0..c4be8c3a77 100644 --- a/java/src/processing/mode/java/Debugger.java +++ b/java/src/processing/mode/java/Debugger.java @@ -533,6 +533,12 @@ synchronized List getBreakpoints(String tabFilename) { * @param es Incoming set of events from VM */ public synchronized void vmEvent(EventSet es) { + VirtualMachine vm = vm(); + if (vm != null && vm != es.virtualMachine()) { + // This is no longer VM we are interested in, + // we already cleaned up and run different VM now. + return; + } for (Event e : es) { log("*** VM Event: " + e); if (e instanceof VMStartEvent) { From 2fb23f6e02c1e74f154a5615aa66e170c1c2c100 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 10:36:25 -0500 Subject: [PATCH 204/917] adding fix from #4843 manually --- .../processing/app/contrib/Contribution.java | 21 +++++++++++++++++++ core/todo.txt | 4 ++++ todo.txt | 7 +++++++ 3 files changed, 32 insertions(+) diff --git a/app/src/processing/app/contrib/Contribution.java b/app/src/processing/app/contrib/Contribution.java index 0e26380dee..aa401375e6 100644 --- a/app/src/processing/app/contrib/Contribution.java +++ b/app/src/processing/app/contrib/Contribution.java @@ -367,6 +367,27 @@ static private String translateCategory(String cat) { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o instanceof Contribution) { + Contribution that = (Contribution) o; + return name.toLowerCase().equals(that.name.toLowerCase()); + } + return false; + } + + + @Override + public int hashCode() { + return name.toLowerCase().hashCode(); + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + public interface Filter { boolean matches(Contribution contrib); } diff --git a/core/todo.txt b/core/todo.txt index 76796b9997..5f429c7101 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -51,6 +51,10 @@ X https://github.com/processing/processing/pull/4797 X Fix typo in GLSL preprocessor X https://github.com/processing/processing/issues/4810 X https://github.com/processing/processing/pull/4816 +X Keep Windows timer resolution high for OpenGL sketches +X prevents frame rate in OpenGL hovering around 30 instead of 60 +X https://github.com/processing/processing/pull/4847 +X https://github.com/processing/processing/issues/4846 _ no prompt shows with selectInput() on 10.11 and 10.12 diff --git a/todo.txt b/todo.txt index 149bf70a5b..0ec90691b9 100755 --- a/todo.txt +++ b/todo.txt @@ -25,6 +25,7 @@ _ https://github.com/processing/processing/issues/3933 _ this may be fixed (removed invokeLater() on startup), unconfirmed _ "error during export" message, but no error message contents come through _ e.g. https://github.com/processing/processing/issues/4792 +_ 'run sketches on display' message shows up on clean install _ Mode, requiring update, appears in Updates tab but not in Modes tab _ https://github.com/processing/processing/issues/4822 @@ -75,6 +76,12 @@ X https://github.com/processing/processing/issues/3965 X https://github.com/processing/processing/pull/4762 X Report missing brace in correct tab, suppress other errors until fixed X https://github.com/processing/processing/pull/4777 +X Improvements to sketch launching and stopping +X https://github.com/processing/processing/pull/4848 +X several Contribution Manager fixes +X https://github.com/processing/processing/pull/4844 +X Add missing equals() and hashCode() to Contribution +X _ did we lose settings.path because it was too buggy? From 8960cc6837705f26c22d17758d4dacb867c98976 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 10:47:20 -0500 Subject: [PATCH 205/917] notes from merges, finish adding #4843 --- app/src/processing/app/contrib/ListPanel.java | 2 ++ .../processing/app/contrib/ModeContribution.java | 11 +---------- core/todo.txt | 4 ++++ todo.txt | 13 +++++++++---- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index 29b903ffe8..ad8f34ad5f 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -505,6 +505,8 @@ public void filterLibraries(List filteredContributions) { visibleContributions.clear(); for (Contribution contribution : panelByContribution.keySet()) { if (contribution.getType() == contributionTab.contribType) { + // contains() uses equals() and there can be multiple instances, + // so Contribution.equals() has to be overridden if (filteredContributions.contains(contribution)) { if (panelByContribution.keySet().contains(contribution)) { visibleContributions.add(contribution); diff --git a/app/src/processing/app/contrib/ModeContribution.java b/app/src/processing/app/contrib/ModeContribution.java index d24f70b677..0005de2478 100644 --- a/app/src/processing/app/contrib/ModeContribution.java +++ b/app/src/processing/app/contrib/ModeContribution.java @@ -129,15 +129,6 @@ public ContributionType getType() { } - public boolean equals(Object o) { - if (o == null || !(o instanceof ModeContribution)) { - return false; - } - ModeContribution other = (ModeContribution) o; - return loader.equals(other.loader) && mode.equals(other.getMode()); - } - - public String initLoader(Base base, String className) throws Exception { File modeDirectory = new File(folder, getTypeName()); if (modeDirectory.exists()) { @@ -219,4 +210,4 @@ public String initLoader(Base base, String className) throws Exception { } return className; } -} \ No newline at end of file +} diff --git a/core/todo.txt b/core/todo.txt index 5f429c7101..9dbd88e793 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -55,6 +55,10 @@ X Keep Windows timer resolution high for OpenGL sketches X prevents frame rate in OpenGL hovering around 30 instead of 60 X https://github.com/processing/processing/pull/4847 X https://github.com/processing/processing/issues/4846 +X Sketches still running in the background after closing +X https://github.com/processing/processing/issues/4831 +X (needed to allow JAVA2D to terminate when animation thread dies) +X https://github.com/processing/processing/pull/4839 _ no prompt shows with selectInput() on 10.11 and 10.12 diff --git a/todo.txt b/todo.txt index 0ec90691b9..8cf0bb6b97 100755 --- a/todo.txt +++ b/todo.txt @@ -81,8 +81,15 @@ X https://github.com/processing/processing/pull/4848 X several Contribution Manager fixes X https://github.com/processing/processing/pull/4844 X Add missing equals() and hashCode() to Contribution -X - +X https://github.com/processing/processing/pull/4843 +X Contribution Manager does not show all libraries until filter cleared +X https://github.com/processing/processing/pull/4843 +X https://github.com/processing/processing/issues/4840 +X Syntax highlighting issues (fixed with #4761) +X https://github.com/processing/processing/issues/4286 +X sketchbook window doesn't update when sketches are added, renamed, etc +X https://github.com/processing/processing/issues/2944 +X https://github.com/processing/processing/pull/4842 _ did we lose settings.path because it was too buggy? _ https://github.com/processing/processing/issues/3948 @@ -324,8 +331,6 @@ _ makes saving *really* slow with a lot of libraries _ need to handle the 2.x to 3.x sketchbook transition _ prefs are the same file, but sketchbook location pref is different _ New/Rename/Save As is reloading the whole sketchbook, argh -_ sketchbook window doesn't update when sketches are added, renamed, etc -_ https://github.com/processing/processing/issues/2944 _ possible PR for updating sketchbook stuff _ https://github.com/processing/processing/pull/3081 _ improve start time by populating sketchbook/libraries on threads From 4c09c900f57e984157556658421a7fa7ac4a57fc Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 10:56:15 -0500 Subject: [PATCH 206/917] more notes on fixes --- todo.txt | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/todo.txt b/todo.txt index 8cf0bb6b97..9f4ff21ebb 100755 --- a/todo.txt +++ b/todo.txt @@ -19,7 +19,8 @@ o gracefully recover from proxy problems X https://github.com/processing/processing/issues/1601 X JRE download fails during ant build X https://github.com/processing/processing/issues/4823 -_ changed headerType to console (make sure changed back) +X changed headerType to console (make sure changed back) + _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 _ this may be fixed (removed invokeLater() on startup), unconfirmed @@ -27,16 +28,10 @@ _ "error during export" message, but no error message contents come through _ e.g. https://github.com/processing/processing/issues/4792 _ 'run sketches on display' message shows up on clean install -_ Mode, requiring update, appears in Updates tab but not in Modes tab -_ https://github.com/processing/processing/issues/4822 - _ report of a library or tool (probably includes 2.x? 1.x?) breaking things _ NoSuchFieldError: useNativeSelect _ https://github.com/processing/processing/issues/4821 -_ turn off the old code that does unicode escapes in preproc -_ https://github.com/processing/processing/issues/4788 - _ allow modes to specify their own base file name _ need to move "is this a sketch?" handling into Mode _ fix extension check for other modes @@ -48,11 +43,11 @@ _ https://github.com/processing/processing/issues/4779 contrib X Added the remove filter feature X https://github.com/processing/processing/pull/3890 -_ ctrl-J (for debugger) is inserting newline -_ https://github.com/processing/processing/issues/3830 -_ Replace keyChar with keyCode to prevent new line error when debugging -_ https://github.com/processing/processing/pull/4806 -_ https://github.com/processing/processing/issues/4804 +X ctrl-J (for debugger) is inserting newline +X https://github.com/processing/processing/issues/3830 +X Replace keyChar with keyCode to prevent new line error when debugging +X https://github.com/processing/processing/pull/4806 +X https://github.com/processing/processing/issues/4804 _ "Sketch disappeared" infinite pop up dialogs _ https://github.com/processing/processing/pull/4808 _ https://github.com/processing/processing/issues/4805 @@ -85,6 +80,9 @@ X https://github.com/processing/processing/pull/4843 X Contribution Manager does not show all libraries until filter cleared X https://github.com/processing/processing/pull/4843 X https://github.com/processing/processing/issues/4840 +X Mode, requiring update, appears in Updates tab but not in Modes tab +X https://github.com/processing/processing/issues/4822 +X also fixed w/ https://github.com/processing/processing/pull/4843 X Syntax highlighting issues (fixed with #4761) X https://github.com/processing/processing/issues/4286 X sketchbook window doesn't update when sketches are added, renamed, etc From 90522aa75fc85c4fcec84165c689d279167fa7ce Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 10:57:44 -0500 Subject: [PATCH 207/917] deal with a handful of warnings --- app/src/processing/app/contrib/UpdateListPanel.java | 1 - core/src/processing/javafx/PGraphicsFX2D.java | 1 - core/src/processing/javafx/PSurfaceFX.java | 3 +++ java/src/processing/mode/java/JavaMode.java | 2 ++ 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/contrib/UpdateListPanel.java b/app/src/processing/app/contrib/UpdateListPanel.java index 95b2742521..985889f582 100644 --- a/app/src/processing/app/contrib/UpdateListPanel.java +++ b/app/src/processing/app/contrib/UpdateListPanel.java @@ -2,7 +2,6 @@ import java.awt.Color; import java.awt.Component; -import java.awt.EventQueue; import java.awt.Font; import java.util.Arrays; import java.util.Comparator; diff --git a/core/src/processing/javafx/PGraphicsFX2D.java b/core/src/processing/javafx/PGraphicsFX2D.java index 186c56a01d..52425e3c70 100644 --- a/core/src/processing/javafx/PGraphicsFX2D.java +++ b/core/src/processing/javafx/PGraphicsFX2D.java @@ -41,7 +41,6 @@ import javafx.scene.image.WritableImage; import javafx.scene.image.WritablePixelFormat; import javafx.scene.paint.Color; -import javafx.scene.paint.Paint; import javafx.scene.shape.ArcType; import javafx.scene.shape.StrokeLineCap; import javafx.scene.shape.StrokeLineJoin; diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index 5f9da44438..8239c8f5b5 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -874,6 +874,9 @@ protected void fxMouseEvent(MouseEvent fxEvent) { case MIDDLE: button = PConstants.CENTER; break; + case NONE: + // not currently handled + break; } // If running on Mac OS, allow ctrl-click as right mouse. diff --git a/java/src/processing/mode/java/JavaMode.java b/java/src/processing/mode/java/JavaMode.java index b08a501d66..c201dd7ca7 100644 --- a/java/src/processing/mode/java/JavaMode.java +++ b/java/src/processing/mode/java/JavaMode.java @@ -207,6 +207,7 @@ public void run() { } + /* // TODO Why is this necessary? Why isn't Sketch.isModified() used? static private boolean isSketchModified(Sketch sketch) { for (SketchCode sc : sketch.getCode()) { @@ -216,6 +217,7 @@ static private boolean isSketchModified(Sketch sketch) { } return false; } + */ // public void handleStop() { From a395991e7d9036f979dd77267a641f467cdfd93b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 11:07:41 -0500 Subject: [PATCH 208/917] handle spaces properly for processing-java on macOS (fixes #4779) --- app/src/processing/app/tools/InstallCommander.java | 2 +- todo.txt | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/tools/InstallCommander.java b/app/src/processing/app/tools/InstallCommander.java index b2723f8c6f..518789d4ce 100644 --- a/app/src/processing/app/tools/InstallCommander.java +++ b/app/src/processing/app/tools/InstallCommander.java @@ -105,7 +105,7 @@ public void run() { String classPath = jarList.join(":").replaceAll(javaRoot + "\\/?", ""); writer.println("cd \"" + javaRoot + "\" && " + - Platform.getJavaPath() + + Platform.getJavaPath().replaceAll(" ", "\\\\ ") + " -Djna.nosys=true" + " $OPTION_FOR_HEADLESS_RUN" + " -cp \"" + classPath + "\"" + diff --git a/todo.txt b/todo.txt index 9f4ff21ebb..a004a6d1b5 100755 --- a/todo.txt +++ b/todo.txt @@ -20,6 +20,8 @@ X https://github.com/processing/processing/issues/1601 X JRE download fails during ant build X https://github.com/processing/processing/issues/4823 X changed headerType to console (make sure changed back) +X Spaces not handled correctly in when installing "processing-java" on macOS +X https://github.com/processing/processing/issues/4779 _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 @@ -37,9 +39,6 @@ _ need to move "is this a sketch?" handling into Mode _ fix extension check for other modes _ https://github.com/processing/processing/issues/3980 -_ Spaces not handled correctly in when installing "processing-java" on macOS -_ https://github.com/processing/processing/issues/4779 - contrib X Added the remove filter feature X https://github.com/processing/processing/pull/3890 From 4798a307aa22b58a9e534cf7af446c9c9b519e6c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 11:09:09 -0500 Subject: [PATCH 209/917] more cleanups heading toward release --- todo.txt | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/todo.txt b/todo.txt index a004a6d1b5..81d3d4fa2e 100755 --- a/todo.txt +++ b/todo.txt @@ -23,22 +23,6 @@ X changed headerType to console (make sure changed back) X Spaces not handled correctly in when installing "processing-java" on macOS X https://github.com/processing/processing/issues/4779 -_ blank window on startup where the "welcome" screen should be -_ https://github.com/processing/processing/issues/3933 -_ this may be fixed (removed invokeLater() on startup), unconfirmed -_ "error during export" message, but no error message contents come through -_ e.g. https://github.com/processing/processing/issues/4792 -_ 'run sketches on display' message shows up on clean install - -_ report of a library or tool (probably includes 2.x? 1.x?) breaking things -_ NoSuchFieldError: useNativeSelect -_ https://github.com/processing/processing/issues/4821 - -_ allow modes to specify their own base file name -_ need to move "is this a sketch?" handling into Mode -_ fix extension check for other modes -_ https://github.com/processing/processing/issues/3980 - contrib X Added the remove filter feature X https://github.com/processing/processing/pull/3890 @@ -51,10 +35,6 @@ _ "Sketch disappeared" infinite pop up dialogs _ https://github.com/processing/processing/pull/4808 _ https://github.com/processing/processing/issues/4805 -andres -_ update list of optional JRE files for Java 8 -_ https://github.com/processing/processing/issues/3288 - jakub X println(int(byte(245))) throwing error X https://github.com/processing/processing/issues/4652 @@ -88,9 +68,30 @@ X sketchbook window doesn't update when sketches are added, renamed, etc X https://github.com/processing/processing/issues/2944 X https://github.com/processing/processing/pull/4842 + +_ blank window on startup where the "welcome" screen should be +_ https://github.com/processing/processing/issues/3933 +_ this may be fixed (removed invokeLater() on startup), unconfirmed +_ "error during export" message, but no error message contents come through +_ e.g. https://github.com/processing/processing/issues/4792 +_ 'run sketches on display' message shows up on clean install + +_ report of a library or tool (probably includes 2.x? 1.x?) breaking things +_ NoSuchFieldError: useNativeSelect +_ https://github.com/processing/processing/issues/4821 + +_ allow modes to specify their own base file name +_ need to move "is this a sketch?" handling into Mode +_ fix extension check for other modes +_ https://github.com/processing/processing/issues/3980 + _ did we lose settings.path because it was too buggy? _ https://github.com/processing/processing/issues/3948 +_ update list of optional JRE files for Java 8 +_ Andres provided some updates +_ https://github.com/processing/processing/issues/3288 + _ proxy trouble with p5? since adding the system proxy? _ https://github.com/processing/processing/pull/3251/files _ larger problem thread https://github.com/processing/processing/issues/3891 @@ -153,7 +154,6 @@ _ swap out the fonts? _ Help Menu disabled on OS X _ https://github.com/processing/processing/issues/4353#issuecomment-237715947 - high _ PDE and sketches are 2x smaller on high-res Windows machines _ https://github.com/processing/processing/issues/2411 From d6d848a780188a6534b366cb71e13ef5ac531fe4 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 12:47:37 -0500 Subject: [PATCH 210/917] clearing out some old todo items --- todo.txt | 62 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/todo.txt b/todo.txt index 81d3d4fa2e..775425687d 100755 --- a/todo.txt +++ b/todo.txt @@ -68,6 +68,42 @@ X sketchbook window doesn't update when sketches are added, renamed, etc X https://github.com/processing/processing/issues/2944 X https://github.com/processing/processing/pull/4842 +cleaning +X clean up 'ant doc' target to remove warnings +X https://github.com/processing/processing/issues/1492 +X fixed in 3.1.1 +X Horizontal scrollbar does not scroll textarea all the way +X https://github.com/processing/processing/issues/3591 +X mostly fixed in 3.0b7, opting to wait for RSyntaxArea or whatever +X possible PR for updating sketchbook stuff +o https://github.com/processing/processing/pull/3081 +X should be covered by other fixes +X longer PR about sketchbook stuff, but closed +X https://github.com/processing/processing/pull/3178 +X closed back in April 2015, issue was all over the place +X fix encodings, line endings, and mime types in the repo +X https://github.com/processing/processing/issues/2955 +X fixed 2015-11 https://github.com/processing/processing/pull/2977 +X need to handle the 2.x to 3.x sketchbook transition +X prefs are the same file, but sketchbook location pref is different +o performance +o video stinks.. java2d stinks.. macs stink +o note in the 'drawing in 2d' section of faq +o fastest machine possible +o turn off hyperthreading in the bios +o nice gfx card only helps opengl +o dual processor not particularly useful, unless you make more threads +o but making more threads is often more work than is useful +X too out of date +X why adding .0001 to a float doesn't work +X and how they're imprecise in general (use nf) +X http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Syntax;action=display;num=1130877990 +X long since added to the FAQ +X infinite "file changed" popups +X https://github.com/processing/processing/issues/3965 +o https://github.com/processing/processing/pull/4037 +X https://github.com/processing/processing/pull/4037 + _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 @@ -209,9 +245,6 @@ _ question about PDE_pt-br instead of PDE_pt _ https://github.com/processing/processing/issues/4018 _ Saving sketch with the same name as a class _ https://github.com/processing/processing/pull/4033 -_ infinite "file changed" popups -_ https://github.com/processing/processing/issues/3965 -_ https://github.com/processing/processing/pull/4037 _ Pasting text into PDE results in "Clipboard does not contain a string" _ https://github.com/processing/processing/pull/4040 @@ -325,24 +358,12 @@ sketchbook _ Mode.rebuildLibraryList() called too many times on startup? _ and when sketches saved as well? _ makes saving *really* slow with a lot of libraries -_ need to handle the 2.x to 3.x sketchbook transition -_ prefs are the same file, but sketchbook location pref is different _ New/Rename/Save As is reloading the whole sketchbook, argh -_ possible PR for updating sketchbook stuff -_ https://github.com/processing/processing/pull/3081 _ improve start time by populating sketchbook/libraries on threads _ https://github.com/processing/processing/issues/2945 -_ longer PR about sketchbook stuff, but closed -_ https://github.com/processing/processing/pull/3178 help me -_ Horizontal scrollbar does not scroll textarea all the way -_ https://github.com/processing/processing/issues/3591 -_ clean up 'ant doc' target to remove warnings -_ https://github.com/processing/processing/issues/1492 -_ fix encodings, line endings, and mime types in the repo -_ https://github.com/processing/processing/issues/2955 _ Add support for localizing contributions _ https://github.com/processing/processing/pull/2833 _ https://github.com/processing/processing/issues/3154 @@ -469,9 +490,6 @@ _ fonts by default not working that well? DOC / Other -_ why adding .0001 to a float doesn't work -_ and how they're imprecise in general (use nf) -_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Syntax;action=display;num=1130877990 _ why strong typing? (link also to language thing on main page) _ we cannot commit to any sort of timeframe on releases _ under the hood - basic @@ -488,14 +506,6 @@ _ in doing so, you'll lose access to 'g' _ add main() to your app to make it run on its own _ preproc stuff.. have to make setup() into public void setup() _ (same for key events and all that) -_ performance -_ video stinks.. java2d stinks.. macs stink -_ note in the 'drawing in 2d' section of faq -_ fastest machine possible -_ turn off hyperthreading in the bios -_ nice gfx card only helps opengl -_ dual processor not particularly useful, unless you make more threads -_ but making more threads is often more work than is useful _ is there a way to do xxx? _ advanced users who are outgrowing the basic reference: _ be sure to check the "complete" reference From 99ea09fffd6ed852ea96ad308b6340680301a44b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 14:33:19 -0500 Subject: [PATCH 211/917] write release notes --- build/shared/revisions.txt | 177 +++++++++++++++++++++++++++++++++++++ todo.txt | 7 +- 2 files changed, 181 insertions(+), 3 deletions(-) diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index 67cbbfee2a..ed123519e4 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -1,3 +1,180 @@ +PROCESSING 3.2.4 (REV 0256) - 29 January 2017 + +Just getting in as many bug fixes as we can before the end of days. + +The majority of these are from Jakub Valtar, plus a handful of other +contributors are noted below. Read all the way to the end for fun +new features. + + +[ the pde & the editor ] + ++ Detect changes to 'hosts' file in case users modify/remove localhost. + No sketch window would open after hitting Run if someone had monkeyed + with their /etc/hosts file. + https://github.com/processing/processing/issues/4738 + https://github.com/processing/processing/issues/1868 + https://github.com/processing/processing/issues/3123 + https://github.com/processing/processing/issues/4735 + ++ Ctrl-J (for debugger) is inserting newline + https://github.com/processing/processing/issues/3830 + https://github.com/processing/processing/pull/4806 + https://github.com/processing/processing/issues/4804 + ++ Spaces not handled correctly in when installing "processing-java" on macOS + https://github.com/processing/processing/issues/4779 + ++ println(int(byte(245))) throwing error + https://github.com/processing/processing/issues/4652 + https://github.com/processing/processing/pull/4744 + ++ 'web colors' next to each other fail to parse in certain situations + https://github.com/processing/processing/issues/4752 + https://github.com/processing/processing/pull/4753 + ++ Pasting code from editor to empty editor produces Exception + https://github.com/processing/processing/issues/4522 + https://github.com/processing/processing/pull/4761 + ++ possible infinite loop on modified externally + https://github.com/processing/processing/issues/3965 + https://github.com/processing/processing/pull/4762 + ++ Report missing brace in correct tab, suppress other errors until fixed + https://github.com/processing/processing/pull/4777 + ++ Improvements to sketch launching and stopping + https://github.com/processing/processing/pull/4848 + ++ Syntax highlighting issues (fixed with #4761) + https://github.com/processing/processing/issues/4286 + ++ Sketchbook window wasn't updating when sketches added, renamed, etc + https://github.com/processing/processing/issues/2944 + https://github.com/processing/processing/pull/4842 + + +[ contribution manager ] + ++ Set text style properly for Contribution Manager error message + ++ Added the remove filter feature (Akarshit) + https://github.com/processing/processing/pull/3890 + ++ Several Contribution Manager fixes + https://github.com/processing/processing/pull/4844 + ++ Add missing equals() and hashCode() to Contribution + https://github.com/processing/processing/pull/4843 + ++ Contribution Manager does not show all libraries until filter cleared + https://github.com/processing/processing/pull/4843 + https://github.com/processing/processing/issues/4840 + ++ Mode, requiring update, appears in Updates tab but not in Modes tab + https://github.com/processing/processing/issues/4822 + also fixed w/ https://github.com/processing/processing/pull/4843 + + +[ internal changes ] + ++ Only require reference.zip to be present for build + ++ Move the DEBUG flag into an external file or preferences.txt. + Replace java.util.logging code with built-in logging. + ++ Split GUI and non-GUI portions of console for earlier startup. + (Otherwise System.err/out not going to a file unless we have a GUI, + which means we couldn't debug before the GUI shows up) + ++ Fix JRE download failure during ant build due to Oracle change + https://github.com/processing/processing/issues/4823 + + +[ the core ] + ++ Write exec() documentation + https://github.com/processing/processing/issues/4740 + ++ XML fixes for getChild() producing valid XML. Add xmlns to + elements procured from getChild(), and making sure newline + is added after XML header when formatting. + ++ Adding missing docs and keywords for TableRow + https://github.com/processing/processing/pull/4333 + ++ PShape in Java2D wasn't respecting 'kind' + https://github.com/processing/processing/issues/4826 + https://github.com/processing/processing/pull/4834 + ++ Sketches still running in the background after closing + https://github.com/processing/processing/issues/4831 + (needed to allow JAVA2D to terminate when animation thread dies) + https://github.com/processing/processing/pull/4839 + + +[ closing bugs in opengl ] + ++ PShape array index out of bounds when using P3D + https://github.com/processing/processing/issues/4773 + ++ Disable modelX/Y/Z() in P2D because they don't exist in 2D + https://github.com/processing/processing/issues/4813 + ++ Fix typo in GLSL preprocessor + https://github.com/processing/processing/issues/4810 + https://github.com/processing/processing/pull/4816 + ++ Keep Windows timer resolution high for OpenGL sketches. + Prevents frame rate in OpenGL hovering around 30 instead of 60. + https://github.com/processing/processing/pull/4847 + https://github.com/processing/processing/issues/4846 + + +[ the jakubfx renderer ] + ++ FX: Prevent matrix stack overflow + https://github.com/processing/processing/pull/4799 + https://github.com/processing/processing/issues/4206 + ++ FX: Reset transform to identity before drawing background + https://github.com/processing/processing/pull/4795 + ++ FX: Implement mouse wheel event + https://github.com/processing/processing/issues/4169 + https://github.com/processing/processing/pull/4796 + ++ FX: Fix curveVertex drawing all curves together as one long curve + https://github.com/processing/processing/pull/4800 + https://github.com/processing/processing/issues/4382 + ++ FX: Add exception handler which reports exceptions from user code + https://github.com/processing/processing/pull/4798 + https://github.com/processing/processing/issues/4339 + ++ Unify mouse pressed/released events across renderers + https://github.com/processing/processing/issues/4361 + https://github.com/processing/processing/pull/4797 + + +[ new features ] + ++ Add listPaths(), listFiles() + https://github.com/processing/processing/issues/4622 + ++ Add increment() method that takes IntDict to merge another dictionary. + Calling this increment() since it doesn't make sense in practice for + the other dictionary types, even though it's technically an add(). + ++ Added Entry class for iterating StringDict, IntDict, FloatDict + ++ Added XML.print() method (prints with indent of 2) + + +. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + PROCESSING 3.2.3 (REV 0255) - 7 November 2016 Lots of fixes to the Contribution Manager and a couple OpenGL tweaks. diff --git a/todo.txt b/todo.txt index 775425687d..51148f0cce 100755 --- a/todo.txt +++ b/todo.txt @@ -31,9 +31,6 @@ X https://github.com/processing/processing/issues/3830 X Replace keyChar with keyCode to prevent new line error when debugging X https://github.com/processing/processing/pull/4806 X https://github.com/processing/processing/issues/4804 -_ "Sketch disappeared" infinite pop up dialogs -_ https://github.com/processing/processing/pull/4808 -_ https://github.com/processing/processing/issues/4805 jakub X println(int(byte(245))) throwing error @@ -105,6 +102,10 @@ o https://github.com/processing/processing/pull/4037 X https://github.com/processing/processing/pull/4037 +_ "Sketch disappeared" infinite pop up dialogs +_ https://github.com/processing/processing/pull/4808 +_ https://github.com/processing/processing/issues/4805 + _ blank window on startup where the "welcome" screen should be _ https://github.com/processing/processing/issues/3933 _ this may be fixed (removed invokeLater() on startup), unconfirmed From f11a8665dc54bfdf83bf801bbd0f3e1ff0616886 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 14:38:10 -0500 Subject: [PATCH 212/917] set version number --- core/todo.txt | 2 +- todo.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index 9dbd88e793..f74b2c75c4 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,4 +1,4 @@ -0256 (3.2.4 or 3.3) +0256 (3.2.4) X write exec() documentation X https://github.com/processing/processing/issues/4740 X add xmlns to elements procured from getChild() diff --git a/todo.txt b/todo.txt index 51148f0cce..92ef0ba194 100755 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,4 @@ -0256 (3.2.4 or 3.3) +0256 (3.2.4) X only require reference.zip (and internet connection) when building dist X set text style properly for Contribution Manager error message X Detect changes to 'hosts' file in case users modify/remove localhost From 69bd4ba8c4c2dfb8bd903a395cc6087cdf86fed2 Mon Sep 17 00:00:00 2001 From: Jonathan Feinberg Date: Sun, 29 Jan 2017 17:51:16 -0500 Subject: [PATCH 213/917] Fix a number of memory leaks. --- core/src/processing/core/PApplet.java | 308 +++++------------- core/src/processing/core/ThinkDifferent.java | 6 + .../processing/opengl/PGraphicsOpenGL.java | 184 +++-------- core/src/processing/opengl/PSurfaceJOGL.java | 87 +++-- 4 files changed, 180 insertions(+), 405 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 2f2818fad8..be4a41aa78 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -1194,7 +1194,7 @@ static public int displayDensity(int display) { * */ public void pixelDensity(int density) { - //println(density + " " + this.pixelDensity); + println(density + " " + this.pixelDensity); if (density != this.pixelDensity) { if (insideSettings("pixelDensity", density)) { if (density != 1 && density != 2) { @@ -3482,27 +3482,6 @@ static public Process launch(String... args) { } - /** - * Pass a set of arguments directly to the command line. Uses Java's - * Runtime.exec() - * method. This is different from the launch() - * method, which uses the operating system's launcher to open the files. - * It's always a good idea to use a full path to the executable here. - *
    -   * exec("/usr/bin/say", "-v", "Pipe Organ", "welcome to the command line");
    -   * 
    - * Or if you want to wait until it's completed, something like this: - *
    -   * Process p = exec("/usr/bin/say", "waiting until done");
    -   * try {
    -   *   int result = p.waitFor();
    -   *   println("the process returned " + result);
    -   * } catch (InterruptedException e) { }
    -   * 
    - * You can also get the system output and error streams from the Process - * object, but that's more that we'd like to cover here. - * @return a Process object - */ static public Process exec(String... args) { try { return Runtime.getRuntime().exec(args); @@ -3634,6 +3613,18 @@ public void dispose() { // run dispose() methods registered by libraries handleMethods("dispose"); } + + if (platform == MACOSX) { + try { + final String td = "processing.core.ThinkDifferent"; + final Class thinkDifferent = + Thread.currentThread().getContextClassLoader().loadClass(td); + thinkDifferent.getMethod("cleanup").invoke(null); + } catch (Exception e) { + e.printStackTrace(); + } + } + } @@ -5936,8 +5927,6 @@ static public JSONObject loadJSONObject(File file) { /** * @webref output:files - * @param json the JSONObject to save - * @param filename the name of the file to save to * @see JSONObject * @see JSONArray * @see PApplet#loadJSONObject(String) @@ -5949,7 +5938,7 @@ public boolean saveJSONObject(JSONObject json, String filename) { } /** - * @param options "compact" and "indent=N", replace N with the number of spaces + * @nowebref */ public boolean saveJSONObject(JSONObject json, String filename, String options) { return json.save(saveFile(filename), options); @@ -5987,8 +5976,6 @@ static public JSONArray loadJSONArray(File file) { /** * @webref output:files - * @param json the JSONArray to save - * @param filename the name of the file to save to * @see JSONObject * @see JSONArray * @see PApplet#loadJSONObject(String) @@ -5999,9 +5986,7 @@ public boolean saveJSONArray(JSONArray json, String filename) { return saveJSONArray(json, filename, null); } - /** - * @param options "compact" and "indent=N", replace N with the number of spaces - */ + public boolean saveJSONArray(JSONArray json, String filename, String options) { return json.save(saveFile(filename), options); } @@ -6529,133 +6514,6 @@ static private void selectCallback(File selectedFile, - ////////////////////////////////////////////////////////////// - - // LISTING DIRECTORIES - - - public String[] listPaths(String path, String... options) { - File[] list = listFiles(path, options); - - int offset = 0; - for (String opt : options) { - if (opt.equals("relative")) { - if (!path.endsWith(File.pathSeparator)) { - path += File.pathSeparator; - } - offset = path.length(); - break; - } - } - String[] outgoing = new String[list.length]; - for (int i = 0; i < list.length; i++) { - // as of Java 1.8, substring(0) returns the original object - outgoing[i] = list[i].getAbsolutePath().substring(offset); - } - return outgoing; - } - - - public File[] listFiles(String path, String... options) { - File file = new File(path); - // if not an absolute path, make it relative to the sketch folder - if (!file.isAbsolute()) { - file = sketchFile(path); - } - return listFiles(file, options); - } - - - // "relative" -> no effect with the Files version, but important for listPaths - // "recursive" - // "extension=js" or "extensions=js|csv|txt" (no dot) - // "directories" -> only directories - // "files" -> only files - // "hidden" -> include hidden files (prefixed with .) disabled by default - static public File[] listFiles(File base, String... options) { - boolean recursive = false; - String[] extensions = null; - boolean directories = true; - boolean files = true; - boolean hidden = false; - - for (String opt : options) { - if (opt.equals("recursive")) { - recursive = true; - } else if (opt.startsWith("extension=")) { - extensions = new String[] { opt.substring(10) }; - } else if (opt.startsWith("extensions=")) { - extensions = split(opt.substring(10), ','); - } else if (opt.equals("files")) { - directories = false; - } else if (opt.equals("directories")) { - files = false; - } else if (opt.equals("hidden")) { - hidden = true; - } else if (opt.equals("relative")) { - // ignored - } else { - throw new RuntimeException(opt + " is not a listFiles() option"); - } - } - - if (extensions != null) { - for (int i = 0; i < extensions.length; i++) { - extensions[i] = "." + extensions[i]; - } - } - - if (!files && !directories) { - // just make "only files" and "only directories" mean... both - files = true; - directories = true; - } - - if (!base.canRead()) { - return null; - } - - List outgoing = new ArrayList<>(); - listFilesImpl(base, recursive, extensions, hidden, directories, files, outgoing); - return outgoing.toArray(new File[0]); - } - - - static void listFilesImpl(File folder, boolean recursive, - String[] extensions, boolean hidden, - boolean directories, boolean files, - List list) { - File[] items = folder.listFiles(); - if (items != null) { - for (File item : items) { - String name = item.getName(); - if (!hidden && name.charAt(0) == '.') { - continue; - } - if (item.isDirectory()) { - if (recursive) { - listFilesImpl(item, recursive, extensions, hidden, directories, files, list); - } - if (directories) { - list.add(item); - } - } else if (files) { - if (extensions == null) { - list.add(item); - } else { - for (String ext : extensions) { - if (item.getName().toLowerCase().endsWith(ext)) { - list.add(item); - } - } - } - } - } - } - } - - - ////////////////////////////////////////////////////////////// // EXTENSIONS @@ -9476,6 +9334,7 @@ static final public String[] str(float x[]) { // INT NUMBER FORMATTING + static public String nf(float num) { int inum = (int) num; if (num == inum) { @@ -9484,22 +9343,31 @@ static public String nf(float num) { return str(num); } - static public String[] nf(float[] nums) { - String[] outgoing = new String[nums.length]; - for (int i = 0; i < nums.length; i++) { - outgoing[i] = nf(nums[i]); + + static public String[] nf(float[] num) { + String[] outgoing = new String[num.length]; + for (int i = 0; i < num.length; i++) { + outgoing[i] = nf(num[i]); } return outgoing; } + /** * Integer number formatter. */ - static private NumberFormat int_nf; static private int int_nf_digits; static private boolean int_nf_commas; + static public String[] nf(int num[], int digits) { + String formatted[] = new String[num.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nf(num[i], digits); + } + return formatted; + } + /** * ( begin auto-generated from nf.xml ) * @@ -9515,25 +9383,13 @@ static public String[] nf(float[] nums) { * * ( end auto-generated ) * @webref data:string_functions - * @param nums the numbers to format + * @param num the number(s) to format * @param digits number of digits to pad with zero * @see PApplet#nfs(float, int, int) * @see PApplet#nfp(float, int, int) * @see PApplet#nfc(float, int) * @see int(float) */ - - static public String[] nf(int nums[], int digits) { - String formatted[] = new String[nums.length]; - for (int i = 0; i < formatted.length; i++) { - formatted[i] = nf(nums[i], digits); - } - return formatted; - } - - /** - * @param num the number to format - */ static public String nf(int num, int digits) { if ((int_nf != null) && (int_nf_digits == digits) && @@ -9549,35 +9405,38 @@ static public String nf(int num, int digits) { return int_nf.format(num); } - /** +/** * ( begin auto-generated from nfc.xml ) * * Utility function for formatting numbers into strings and placing * appropriate commas to mark units of 1000. There are two versions, one * for formatting ints and one for formatting an array of ints. The value * for the digits parameter should always be a positive integer. - *

    + *

    * For a non-US locale, this will insert periods instead of commas, or * whatever is apprioriate for that region. * * ( end auto-generated ) - * @webref data:string_functions - * @param nums the numbers to format - * @see PApplet#nf(float, int, int) - * @see PApplet#nfp(float, int, int) - * @see PApplet#nfs(float, int, int) - */ - static public String[] nfc(int nums[]) { - String formatted[] = new String[nums.length]; + * @webref data:string_functions + * @param num the number(s) to format + * @see PApplet#nf(float, int, int) + * @see PApplet#nfp(float, int, int) + * @see PApplet#nfs(float, int, int) + */ + static public String[] nfc(int num[]) { + String formatted[] = new String[num.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfc(nums[i]); + formatted[i] = nfc(num[i]); } return formatted; } /** - * @param num the number to format + * nfc() or "number format with commas". This is an unfortunate misnomer + * because in locales where a comma is not the separator for numbers, it + * won't actually be outputting a comma, it'll use whatever makes sense for + * the locale. */ static public String nfc(int num) { if ((int_nf != null) && @@ -9614,7 +9473,7 @@ static public String nfc(int num) { * * ( end auto-generated ) * @webref data:string_functions - * @param num the number to format + * @param num the number(s) to format * @param digits number of digits to pad with zeroes * @see PApplet#nf(float, int, int) * @see PApplet#nfp(float, int, int) @@ -9624,13 +9483,10 @@ static public String nfs(int num, int digits) { return (num < 0) ? nf(num, digits) : (' ' + nf(num, digits)); } - /** - * @param nums the numbers to format - */ - static public String[] nfs(int nums[], int digits) { - String formatted[] = new String[nums.length]; + static public String[] nfs(int num[], int digits) { + String formatted[] = new String[num.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfs(nums[i], digits); + formatted[i] = nfs(num[i], digits); } return formatted; } @@ -9653,7 +9509,7 @@ static public String[] nfs(int nums[], int digits) { * * ( end auto-generated ) * @webref data:string_functions - * @param num the number to format + * @param num the number(s) to format * @param digits number of digits to pad with zeroes * @see PApplet#nf(float, int, int) * @see PApplet#nfs(float, int, int) @@ -9662,13 +9518,11 @@ static public String[] nfs(int nums[], int digits) { static public String nfp(int num, int digits) { return (num < 0) ? nf(num, digits) : ('+' + nf(num, digits)); } - /** - * @param nums the numbers to format - */ - static public String[] nfp(int nums[], int digits) { - String formatted[] = new String[nums.length]; + + static public String[] nfp(int num[], int digits) { + String formatted[] = new String[num.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfp(nums[i], digits); + formatted[i] = nfp(num[i], digits); } return formatted; } @@ -9679,22 +9533,23 @@ static public String[] nfp(int nums[], int digits) { // FLOAT NUMBER FORMATTING + static private NumberFormat float_nf; static private int float_nf_left, float_nf_right; static private boolean float_nf_commas; - /** - * @param left number of digits to the left of the decimal point - * @param right number of digits to the right of the decimal point - */ - static public String[] nf(float nums[], int left, int right) { - String formatted[] = new String[nums.length]; + static public String[] nf(float num[], int left, int right) { + String formatted[] = new String[num.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nf(nums[i], left, right); + formatted[i] = nf(num[i], left, right); } return formatted; } - +/** + * @param num[] the number(s) to format + * @param left number of digits to the left of the decimal point + * @param right number of digits to the right of the decimal point + */ static public String nf(float num, int left, int right) { if ((float_nf != null) && (float_nf_left == left) && @@ -9717,17 +9572,19 @@ static public String nf(float num, int left, int right) { return float_nf.format(num); } - /** - * @param right number of digits to the right of the decimal point - */ - static public String[] nfc(float nums[], int right) { - String formatted[] = new String[nums.length]; +/** + * @param num[] the number(s) to format + * @param right number of digits to the right of the decimal point + */ + static public String[] nfc(float num[], int right) { + String formatted[] = new String[num.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfc(nums[i], right); + formatted[i] = nfc(num[i], right); } return formatted; } + static public String nfc(float num, int right) { if ((float_nf != null) && (float_nf_left == 0) && @@ -9751,13 +9608,14 @@ static public String nfc(float num, int right) { /** + * @param num[] the number(s) to format * @param left the number of digits to the left of the decimal point * @param right the number of digits to the right of the decimal point */ - static public String[] nfs(float nums[], int left, int right) { - String formatted[] = new String[nums.length]; + static public String[] nfs(float num[], int left, int right) { + String formatted[] = new String[num.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfs(nums[i], left, right); + formatted[i] = nfs(num[i], left, right); } return formatted; } @@ -9770,10 +9628,10 @@ static public String nfs(float num, int left, int right) { * @param left the number of digits to the left of the decimal point * @param right the number of digits to the right of the decimal point */ - static public String[] nfp(float nums[], int left, int right) { - String formatted[] = new String[nums.length]; + static public String[] nfp(float num[], int left, int right) { + String formatted[] = new String[num.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfp(nums[i], left, right); + formatted[i] = nfp(num[i], left, right); } return formatted; } @@ -12322,8 +12180,8 @@ public void imageMode(int mode) { * * @webref image:loading_displaying * @param img the image to display - * @param a x-coordinate of the image by default - * @param b y-coordinate of the image by default + * @param a x-coordinate of the image + * @param b y-coordinate of the image * @see PApplet#loadImage(String, String) * @see PImage * @see PGraphics#imageMode(int) @@ -12338,8 +12196,8 @@ public void image(PImage img, float a, float b) { /** - * @param c width to display the image by default - * @param d height to display the image by default + * @param c width to display the image + * @param d height to display the image */ public void image(PImage img, float a, float b, float c, float d) { if (recorder != null) recorder.image(img, a, b, c, d); diff --git a/core/src/processing/core/ThinkDifferent.java b/core/src/processing/core/ThinkDifferent.java index 38637c559d..8596696198 100644 --- a/core/src/processing/core/ThinkDifferent.java +++ b/core/src/processing/core/ThinkDifferent.java @@ -71,6 +71,12 @@ public void handleQuitRequestWith(QuitEvent event, QuitResponse response) { }); } + static public void cleanup() { + if (application == null) { + application = Application.getApplication(); + } + application.setQuitHandler(null); + } // Called via reflection from PSurfaceAWT and others static public void setIconImage(Image image) { diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 892ac69903..19f1e271e4 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -49,6 +49,40 @@ public class PGraphicsOpenGL extends PGraphics { // ........................................................ + // Disposal of native resources + // Using the technique alternative to finalization described in: + // http://www.oracle.com/technetwork/articles/java/finalization-137655.html + static private ReferenceQueue refQueue = new ReferenceQueue<>(); + + static final private int MAX_DRAIN_GLRES_ITERATIONS = 10; + + static void drainRefQueueBounded() { + int iterations = 0; + while (iterations < MAX_DRAIN_GLRES_ITERATIONS) { + Disposable res = + (Disposable) refQueue.poll(); + if (res == null) { + break; + } + res.dispose(); + ++iterations; + } + } + + private static abstract class Disposable extends WeakReference { + protected Disposable(T obj) { + super(obj, refQueue); + drainRefQueueBounded(); + } + + public void dispose() { + System.err.println("disposing " + this); + disposeNative(); + } + + abstract public void disposeNative(); + } + // Basic rendering parameters: /** Whether the PGraphics object is ready to render or not. */ @@ -820,42 +854,16 @@ protected void removeFontTexture(PFont font) { ////////////////////////////////////////////////////////////// - // RESOURCE HANDLING - // Using the technique alternative to finalization described in: - // http://www.oracle.com/technetwork/articles/java/finalization-137655.html - - static final private int MAX_DRAIN_GLRES_ITERATIONS = 10; - protected static class GLResourceTexture extends WeakReference { + protected static class GLResourceTexture extends Disposable { int glName; private PGL pgl; private int context; - static private ReferenceQueue refQueue = new ReferenceQueue(); - static private List refList = new ArrayList(); - - static void drainRefQueueBounded() { - ReferenceQueue refQueue = GLResourceTexture.referenceQueue(); - int iterations = 0; - while (iterations < MAX_DRAIN_GLRES_ITERATIONS) { - GLResourceTexture res = (GLResourceTexture)refQueue.poll(); - if (res == null) { - break; - } - res.dispose(); - ++iterations; - } - } - - static ReferenceQueue referenceQueue() { - return refQueue; - } - public GLResourceTexture(Texture tex) { - super(tex, refQueue); + super(tex); - drainRefQueueBounded(); pgl = tex.pg.getPrimaryPGL(); pgl.genTextures(1, intBuffer); @@ -863,11 +871,10 @@ public GLResourceTexture(Texture tex) { this.glName = tex.glName; this.context = tex.context; - - refList.add(this); } - private void disposeNative() { + @Override + public void disposeNative() { if (pgl != null) { if (glName != 0) { intBuffer.put(0, glName); @@ -878,11 +885,6 @@ private void disposeNative() { } } - void dispose() { - refList.remove(this); - disposeNative(); - } - @Override public boolean equals(Object obj) { GLResourceTexture other = (GLResourceTexture)obj; @@ -900,36 +902,14 @@ public int hashCode() { } - protected static class GLResourceVertexBuffer extends WeakReference { + protected static class GLResourceVertexBuffer extends Disposable { int glId; private PGL pgl; private int context; - static private ReferenceQueue refQueue = new ReferenceQueue(); - static private List refList = new ArrayList(); - - static void drainRefQueueBounded() { - ReferenceQueue refQueue = GLResourceVertexBuffer.referenceQueue(); - int iterations = 0; - while (iterations < MAX_DRAIN_GLRES_ITERATIONS) { - GLResourceVertexBuffer res = (GLResourceVertexBuffer)refQueue.poll(); - if (res == null) { - break; - } - res.dispose(); - ++iterations; - } - } - - static ReferenceQueue referenceQueue() { - return refQueue; - } - public GLResourceVertexBuffer(VertexBuffer vbo) { - super(vbo, refQueue); - - drainRefQueueBounded(); + super(vbo); pgl = vbo.pgl.graphics.getPrimaryPGL(); pgl.genBuffers(1, intBuffer); @@ -937,11 +917,10 @@ public GLResourceVertexBuffer(VertexBuffer vbo) { this.glId = vbo.glId; this.context = vbo.context; - - refList.add(this); } - private void disposeNative() { + @Override + public void disposeNative() { if (pgl != null) { if (glId != 0) { intBuffer.put(0, glId); @@ -952,11 +931,6 @@ private void disposeNative() { } } - void dispose() { - refList.remove(this); - disposeNative(); - } - @Override public boolean equals(Object obj) { GLResourceVertexBuffer other = (GLResourceVertexBuffer)obj; @@ -974,7 +948,7 @@ public int hashCode() { } - protected static class GLResourceShader extends WeakReference { + protected static class GLResourceShader extends Disposable { int glProgram; int glVertex; int glFragment; @@ -982,30 +956,8 @@ protected static class GLResourceShader extends WeakReference { private PGL pgl; private int context; - static private ReferenceQueue refQueue = new ReferenceQueue(); - static private List refList = new ArrayList(); - - static void drainRefQueueBounded() { - ReferenceQueue refQueue = GLResourceShader.referenceQueue(); - int iterations = 0; - while (iterations < MAX_DRAIN_GLRES_ITERATIONS) { - GLResourceShader res = (GLResourceShader)refQueue.poll(); - if (res == null) { - break; - } - res.dispose(); - ++iterations; - } - } - - static ReferenceQueue referenceQueue() { - return refQueue; - } - public GLResourceShader(PShader sh) { - super(sh, refQueue); - - drainRefQueueBounded(); + super(sh); this.pgl = sh.pgl.graphics.getPrimaryPGL(); sh.glProgram = pgl.createProgram(); @@ -1017,11 +969,10 @@ public GLResourceShader(PShader sh) { this.glFragment = sh.glFragment; this.context = sh.context; - - refList.add(this); } - private void disposeNative() { + @Override + public void disposeNative() { if (pgl != null) { if (glFragment != 0) { pgl.deleteShader(glFragment); @@ -1039,11 +990,6 @@ private void disposeNative() { } } - void dispose() { - refList.remove(this); - disposeNative(); - } - @Override public boolean equals(Object obj) { GLResourceShader other = (GLResourceShader)obj; @@ -1065,7 +1011,7 @@ public int hashCode() { } - protected static class GLResourceFrameBuffer extends WeakReference { + protected static class GLResourceFrameBuffer extends Disposable { int glFbo; int glDepth; int glStencil; @@ -1075,30 +1021,8 @@ protected static class GLResourceFrameBuffer extends WeakReference private PGL pgl; private int context; - static private ReferenceQueue refQueue = new ReferenceQueue(); - static private List refList = new ArrayList(); - - static void drainRefQueueBounded() { - ReferenceQueue refQueue = GLResourceFrameBuffer.referenceQueue(); - int iterations = 0; - while (iterations < MAX_DRAIN_GLRES_ITERATIONS) { - GLResourceFrameBuffer res = (GLResourceFrameBuffer)refQueue.poll(); - if (res == null) { - break; - } - res.dispose(); - ++iterations; - } - } - - static ReferenceQueue referenceQueue() { - return refQueue; - } - public GLResourceFrameBuffer(FrameBuffer fb) { - super(fb, refQueue); - - drainRefQueueBounded(); + super(fb); pgl = fb.pg.getPrimaryPGL(); if (!fb.screenFb) { @@ -1132,11 +1056,10 @@ public GLResourceFrameBuffer(FrameBuffer fb) { } this.context = fb.context; - - refList.add(this); } - private void disposeNative() { + @Override + public void disposeNative() { if (pgl != null) { if (glFbo != 0) { intBuffer.put(0, glFbo); @@ -1167,11 +1090,6 @@ private void disposeNative() { } } - void dispose() { - refList.remove(this); - disposeNative(); - } - @Override public boolean equals(Object obj) { GLResourceFrameBuffer other = (GLResourceFrameBuffer)obj; @@ -6586,6 +6504,8 @@ protected void deleteSurfaceTextures() { if (filterTexture != null) { filterTexture.dispose(); } + + } diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index daa5079c97..14d5059e12 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -89,6 +89,8 @@ public class PSurfaceJOGL implements PSurface { protected FPSAnimator animator; protected Rectangle screenRect; + private Thread drawExceptionHandler; + protected PApplet sketch; protected PGraphics graphics; @@ -104,7 +106,7 @@ public class PSurfaceJOGL implements PSurface { protected List monitors; protected MonitorDevice displayDevice; protected Throwable drawException; - protected Object waitObject = new Object(); + private final Object drawExceptionMutex = new Object(); protected NewtCanvasAWT canvas; @@ -431,20 +433,6 @@ protected void initListeners() { protected void initAnimator() { - if (PApplet.platform == PConstants.WINDOWS) { - // Force Windows to keep timer resolution high by - // sleeping for time which is not a multiple of 10 ms. - // See section "Clocks and Timers on Windows": - // https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks - Thread highResTimerThread = new Thread(() -> { - try { - Thread.sleep(Long.MAX_VALUE); - } catch (InterruptedException ignore) { } - }, "HighResTimerThread"); - highResTimerThread.setDaemon(true); - highResTimerThread.start(); - } - animator = new FPSAnimator(window, 60); drawException = null; animator.setUncaughtExceptionHandler(new GLAnimatorControl.UncaughtExceptionHandler() { @@ -452,40 +440,43 @@ protected void initAnimator() { public void uncaughtException(final GLAnimatorControl animator, final GLAutoDrawable drawable, final Throwable cause) { - synchronized (waitObject) { + synchronized (drawExceptionMutex) { drawException = cause; - waitObject.notify(); + drawExceptionMutex.notify(); } } }); - new Thread(new Runnable() { + drawExceptionHandler = new Thread(new Runnable() { public void run() { - synchronized (waitObject) { + synchronized (drawExceptionMutex) { try { - if (drawException == null) waitObject.wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - } -// System.err.println("Caught exception: " + drawException.getMessage()); - if (drawException != null) { - Throwable cause = drawException.getCause(); - if (cause instanceof ThreadDeath) { -// System.out.println("caught ThreadDeath"); -// throw (ThreadDeath)cause; - } else if (cause instanceof RuntimeException) { - throw (RuntimeException)cause; - } else if (cause instanceof UnsatisfiedLinkError) { - throw new UnsatisfiedLinkError(cause.getMessage()); - } else if (cause == null) { - throw new RuntimeException(drawException.getMessage()); - } else { - throw new RuntimeException(cause); + while (drawException == null) { + drawExceptionMutex.wait(); } + // System.err.println("Caught exception: " + drawException.getMessage()); + if (drawException != null) { + Throwable cause = drawException.getCause(); + if (cause instanceof ThreadDeath) { + // System.out.println("caught ThreadDeath"); + // throw (ThreadDeath)cause; + } else if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else if (cause instanceof UnsatisfiedLinkError) { + throw new UnsatisfiedLinkError(cause.getMessage()); + } else if (cause == null) { + throw new RuntimeException(drawException.getMessage()); + } else { + throw new RuntimeException(cause); + } + } + } catch (InterruptedException e) { + return; } } } - }).start(); + }); + drawExceptionHandler.start(); } @@ -777,6 +768,10 @@ public void resumeThread() { public boolean stopThread() { + if (drawExceptionHandler != null) { + drawExceptionHandler.interrupt(); + drawExceptionHandler = null; + } if (animator != null) { return animator.stop(); } else { @@ -1074,16 +1069,12 @@ protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent, InputEvent.ALT_MASK); int peButton = 0; - switch (nativeEvent.getButton()) { - case com.jogamp.newt.event.MouseEvent.BUTTON1: - peButton = PConstants.LEFT; - break; - case com.jogamp.newt.event.MouseEvent.BUTTON2: - peButton = PConstants.CENTER; - break; - case com.jogamp.newt.event.MouseEvent.BUTTON3: - peButton = PConstants.RIGHT; - break; + if ((modifiers & InputEvent.BUTTON1_MASK) != 0) { + peButton = PConstants.LEFT; + } else if ((modifiers & InputEvent.BUTTON2_MASK) != 0) { + peButton = PConstants.CENTER; + } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { + peButton = PConstants.RIGHT; } if (PApplet.platform == PConstants.MACOSX) { From 281b9300bad3b89365211f5205f03d8baa5da554 Mon Sep 17 00:00:00 2001 From: Jonathan Feinberg Date: Sun, 29 Jan 2017 17:51:42 -0500 Subject: [PATCH 214/917] Sshhhh. --- core/src/processing/opengl/PGraphicsOpenGL.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 19f1e271e4..54d8f25d42 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -76,7 +76,6 @@ protected Disposable(T obj) { } public void dispose() { - System.err.println("disposing " + this); disposeNative(); } From 78394fc1449252fbe9633be60944d42f1c599744 Mon Sep 17 00:00:00 2001 From: Jonathan Feinberg Date: Sun, 29 Jan 2017 18:00:32 -0500 Subject: [PATCH 215/917] Unscrewup merge. --- core/src/processing/core/PApplet.java | 296 ++++++++++++++----- core/src/processing/opengl/PSurfaceJOGL.java | 30 +- 2 files changed, 249 insertions(+), 77 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index be4a41aa78..fad10e5808 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -1194,7 +1194,7 @@ static public int displayDensity(int display) { * */ public void pixelDensity(int density) { - println(density + " " + this.pixelDensity); + //println(density + " " + this.pixelDensity); if (density != this.pixelDensity) { if (insideSettings("pixelDensity", density)) { if (density != 1 && density != 2) { @@ -3482,6 +3482,27 @@ static public Process launch(String... args) { } + /** + * Pass a set of arguments directly to the command line. Uses Java's + * Runtime.exec() + * method. This is different from the launch() + * method, which uses the operating system's launcher to open the files. + * It's always a good idea to use a full path to the executable here. + *
    +   * exec("/usr/bin/say", "-v", "Pipe Organ", "welcome to the command line");
    +   * 
    + * Or if you want to wait until it's completed, something like this: + *
    +   * Process p = exec("/usr/bin/say", "waiting until done");
    +   * try {
    +   *   int result = p.waitFor();
    +   *   println("the process returned " + result);
    +   * } catch (InterruptedException e) { }
    +   * 
    + * You can also get the system output and error streams from the Process + * object, but that's more that we'd like to cover here. + * @return a Process object + */ static public Process exec(String... args) { try { return Runtime.getRuntime().exec(args); @@ -5927,6 +5948,8 @@ static public JSONObject loadJSONObject(File file) { /** * @webref output:files + * @param json the JSONObject to save + * @param filename the name of the file to save to * @see JSONObject * @see JSONArray * @see PApplet#loadJSONObject(String) @@ -5938,7 +5961,7 @@ public boolean saveJSONObject(JSONObject json, String filename) { } /** - * @nowebref + * @param options "compact" and "indent=N", replace N with the number of spaces */ public boolean saveJSONObject(JSONObject json, String filename, String options) { return json.save(saveFile(filename), options); @@ -5976,6 +5999,8 @@ static public JSONArray loadJSONArray(File file) { /** * @webref output:files + * @param json the JSONArray to save + * @param filename the name of the file to save to * @see JSONObject * @see JSONArray * @see PApplet#loadJSONObject(String) @@ -5986,7 +6011,9 @@ public boolean saveJSONArray(JSONArray json, String filename) { return saveJSONArray(json, filename, null); } - + /** + * @param options "compact" and "indent=N", replace N with the number of spaces + */ public boolean saveJSONArray(JSONArray json, String filename, String options) { return json.save(saveFile(filename), options); } @@ -6514,6 +6541,133 @@ static private void selectCallback(File selectedFile, + ////////////////////////////////////////////////////////////// + + // LISTING DIRECTORIES + + + public String[] listPaths(String path, String... options) { + File[] list = listFiles(path, options); + + int offset = 0; + for (String opt : options) { + if (opt.equals("relative")) { + if (!path.endsWith(File.pathSeparator)) { + path += File.pathSeparator; + } + offset = path.length(); + break; + } + } + String[] outgoing = new String[list.length]; + for (int i = 0; i < list.length; i++) { + // as of Java 1.8, substring(0) returns the original object + outgoing[i] = list[i].getAbsolutePath().substring(offset); + } + return outgoing; + } + + + public File[] listFiles(String path, String... options) { + File file = new File(path); + // if not an absolute path, make it relative to the sketch folder + if (!file.isAbsolute()) { + file = sketchFile(path); + } + return listFiles(file, options); + } + + + // "relative" -> no effect with the Files version, but important for listPaths + // "recursive" + // "extension=js" or "extensions=js|csv|txt" (no dot) + // "directories" -> only directories + // "files" -> only files + // "hidden" -> include hidden files (prefixed with .) disabled by default + static public File[] listFiles(File base, String... options) { + boolean recursive = false; + String[] extensions = null; + boolean directories = true; + boolean files = true; + boolean hidden = false; + + for (String opt : options) { + if (opt.equals("recursive")) { + recursive = true; + } else if (opt.startsWith("extension=")) { + extensions = new String[] { opt.substring(10) }; + } else if (opt.startsWith("extensions=")) { + extensions = split(opt.substring(10), ','); + } else if (opt.equals("files")) { + directories = false; + } else if (opt.equals("directories")) { + files = false; + } else if (opt.equals("hidden")) { + hidden = true; + } else if (opt.equals("relative")) { + // ignored + } else { + throw new RuntimeException(opt + " is not a listFiles() option"); + } + } + + if (extensions != null) { + for (int i = 0; i < extensions.length; i++) { + extensions[i] = "." + extensions[i]; + } + } + + if (!files && !directories) { + // just make "only files" and "only directories" mean... both + files = true; + directories = true; + } + + if (!base.canRead()) { + return null; + } + + List outgoing = new ArrayList<>(); + listFilesImpl(base, recursive, extensions, hidden, directories, files, outgoing); + return outgoing.toArray(new File[0]); + } + + + static void listFilesImpl(File folder, boolean recursive, + String[] extensions, boolean hidden, + boolean directories, boolean files, + List list) { + File[] items = folder.listFiles(); + if (items != null) { + for (File item : items) { + String name = item.getName(); + if (!hidden && name.charAt(0) == '.') { + continue; + } + if (item.isDirectory()) { + if (recursive) { + listFilesImpl(item, recursive, extensions, hidden, directories, files, list); + } + if (directories) { + list.add(item); + } + } else if (files) { + if (extensions == null) { + list.add(item); + } else { + for (String ext : extensions) { + if (item.getName().toLowerCase().endsWith(ext)) { + list.add(item); + } + } + } + } + } + } + } + + + ////////////////////////////////////////////////////////////// // EXTENSIONS @@ -9334,7 +9488,6 @@ static final public String[] str(float x[]) { // INT NUMBER FORMATTING - static public String nf(float num) { int inum = (int) num; if (num == inum) { @@ -9343,31 +9496,22 @@ static public String nf(float num) { return str(num); } - - static public String[] nf(float[] num) { - String[] outgoing = new String[num.length]; - for (int i = 0; i < num.length; i++) { - outgoing[i] = nf(num[i]); + static public String[] nf(float[] nums) { + String[] outgoing = new String[nums.length]; + for (int i = 0; i < nums.length; i++) { + outgoing[i] = nf(nums[i]); } return outgoing; } - /** * Integer number formatter. */ + static private NumberFormat int_nf; static private int int_nf_digits; static private boolean int_nf_commas; - static public String[] nf(int num[], int digits) { - String formatted[] = new String[num.length]; - for (int i = 0; i < formatted.length; i++) { - formatted[i] = nf(num[i], digits); - } - return formatted; - } - /** * ( begin auto-generated from nf.xml ) * @@ -9383,13 +9527,25 @@ static public String[] nf(int num[], int digits) { * * ( end auto-generated ) * @webref data:string_functions - * @param num the number(s) to format + * @param nums the numbers to format * @param digits number of digits to pad with zero * @see PApplet#nfs(float, int, int) * @see PApplet#nfp(float, int, int) * @see PApplet#nfc(float, int) * @see int(float) */ + + static public String[] nf(int nums[], int digits) { + String formatted[] = new String[nums.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nf(nums[i], digits); + } + return formatted; + } + + /** + * @param num the number to format + */ static public String nf(int num, int digits) { if ((int_nf != null) && (int_nf_digits == digits) && @@ -9405,38 +9561,35 @@ static public String nf(int num, int digits) { return int_nf.format(num); } -/** + /** * ( begin auto-generated from nfc.xml ) * * Utility function for formatting numbers into strings and placing * appropriate commas to mark units of 1000. There are two versions, one * for formatting ints and one for formatting an array of ints. The value * for the digits parameter should always be a positive integer. - *

    + *

    * For a non-US locale, this will insert periods instead of commas, or * whatever is apprioriate for that region. * * ( end auto-generated ) - * @webref data:string_functions - * @param num the number(s) to format - * @see PApplet#nf(float, int, int) - * @see PApplet#nfp(float, int, int) - * @see PApplet#nfs(float, int, int) - */ - static public String[] nfc(int num[]) { - String formatted[] = new String[num.length]; + * @webref data:string_functions + * @param nums the numbers to format + * @see PApplet#nf(float, int, int) + * @see PApplet#nfp(float, int, int) + * @see PApplet#nfs(float, int, int) + */ + static public String[] nfc(int nums[]) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfc(num[i]); + formatted[i] = nfc(nums[i]); } return formatted; } /** - * nfc() or "number format with commas". This is an unfortunate misnomer - * because in locales where a comma is not the separator for numbers, it - * won't actually be outputting a comma, it'll use whatever makes sense for - * the locale. + * @param num the number to format */ static public String nfc(int num) { if ((int_nf != null) && @@ -9473,7 +9626,7 @@ static public String nfc(int num) { * * ( end auto-generated ) * @webref data:string_functions - * @param num the number(s) to format + * @param num the number to format * @param digits number of digits to pad with zeroes * @see PApplet#nf(float, int, int) * @see PApplet#nfp(float, int, int) @@ -9483,10 +9636,13 @@ static public String nfs(int num, int digits) { return (num < 0) ? nf(num, digits) : (' ' + nf(num, digits)); } - static public String[] nfs(int num[], int digits) { - String formatted[] = new String[num.length]; + /** + * @param nums the numbers to format + */ + static public String[] nfs(int nums[], int digits) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfs(num[i], digits); + formatted[i] = nfs(nums[i], digits); } return formatted; } @@ -9509,7 +9665,7 @@ static public String[] nfs(int num[], int digits) { * * ( end auto-generated ) * @webref data:string_functions - * @param num the number(s) to format + * @param num the number to format * @param digits number of digits to pad with zeroes * @see PApplet#nf(float, int, int) * @see PApplet#nfs(float, int, int) @@ -9518,11 +9674,13 @@ static public String[] nfs(int num[], int digits) { static public String nfp(int num, int digits) { return (num < 0) ? nf(num, digits) : ('+' + nf(num, digits)); } - - static public String[] nfp(int num[], int digits) { - String formatted[] = new String[num.length]; + /** + * @param nums the numbers to format + */ + static public String[] nfp(int nums[], int digits) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfp(num[i], digits); + formatted[i] = nfp(nums[i], digits); } return formatted; } @@ -9533,23 +9691,22 @@ static public String[] nfp(int num[], int digits) { // FLOAT NUMBER FORMATTING - static private NumberFormat float_nf; static private int float_nf_left, float_nf_right; static private boolean float_nf_commas; - static public String[] nf(float num[], int left, int right) { - String formatted[] = new String[num.length]; + /** + * @param left number of digits to the left of the decimal point + * @param right number of digits to the right of the decimal point + */ + static public String[] nf(float nums[], int left, int right) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nf(num[i], left, right); + formatted[i] = nf(nums[i], left, right); } return formatted; } -/** - * @param num[] the number(s) to format - * @param left number of digits to the left of the decimal point - * @param right number of digits to the right of the decimal point - */ + static public String nf(float num, int left, int right) { if ((float_nf != null) && (float_nf_left == left) && @@ -9572,19 +9729,17 @@ static public String nf(float num, int left, int right) { return float_nf.format(num); } -/** - * @param num[] the number(s) to format - * @param right number of digits to the right of the decimal point - */ - static public String[] nfc(float num[], int right) { - String formatted[] = new String[num.length]; + /** + * @param right number of digits to the right of the decimal point + */ + static public String[] nfc(float nums[], int right) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfc(num[i], right); + formatted[i] = nfc(nums[i], right); } return formatted; } - static public String nfc(float num, int right) { if ((float_nf != null) && (float_nf_left == 0) && @@ -9608,14 +9763,13 @@ static public String nfc(float num, int right) { /** - * @param num[] the number(s) to format * @param left the number of digits to the left of the decimal point * @param right the number of digits to the right of the decimal point */ - static public String[] nfs(float num[], int left, int right) { - String formatted[] = new String[num.length]; + static public String[] nfs(float nums[], int left, int right) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfs(num[i], left, right); + formatted[i] = nfs(nums[i], left, right); } return formatted; } @@ -9628,10 +9782,10 @@ static public String nfs(float num, int left, int right) { * @param left the number of digits to the left of the decimal point * @param right the number of digits to the right of the decimal point */ - static public String[] nfp(float num[], int left, int right) { - String formatted[] = new String[num.length]; + static public String[] nfp(float nums[], int left, int right) { + String formatted[] = new String[nums.length]; for (int i = 0; i < formatted.length; i++) { - formatted[i] = nfp(num[i], left, right); + formatted[i] = nfp(nums[i], left, right); } return formatted; } @@ -12180,8 +12334,8 @@ public void imageMode(int mode) { * * @webref image:loading_displaying * @param img the image to display - * @param a x-coordinate of the image - * @param b y-coordinate of the image + * @param a x-coordinate of the image by default + * @param b y-coordinate of the image by default * @see PApplet#loadImage(String, String) * @see PImage * @see PGraphics#imageMode(int) @@ -12196,8 +12350,8 @@ public void image(PImage img, float a, float b) { /** - * @param c width to display the image - * @param d height to display the image + * @param c width to display the image by default + * @param d height to display the image by default */ public void image(PImage img, float a, float b, float c, float d) { if (recorder != null) recorder.image(img, a, b, c, d); diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 14d5059e12..b314ad4511 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -433,6 +433,20 @@ protected void initListeners() { protected void initAnimator() { + if (PApplet.platform == PConstants.WINDOWS) { + // Force Windows to keep timer resolution high by + // sleeping for time which is not a multiple of 10 ms. + // See section "Clocks and Timers on Windows": + // https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks + Thread highResTimerThread = new Thread(() -> { + try { + Thread.sleep(Long.MAX_VALUE); + } catch (InterruptedException ignore) { } + }, "HighResTimerThread"); + highResTimerThread.setDaemon(true); + highResTimerThread.start(); + } + animator = new FPSAnimator(window, 60); drawException = null; animator.setUncaughtExceptionHandler(new GLAnimatorControl.UncaughtExceptionHandler() { @@ -1069,12 +1083,16 @@ protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent, InputEvent.ALT_MASK); int peButton = 0; - if ((modifiers & InputEvent.BUTTON1_MASK) != 0) { - peButton = PConstants.LEFT; - } else if ((modifiers & InputEvent.BUTTON2_MASK) != 0) { - peButton = PConstants.CENTER; - } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { - peButton = PConstants.RIGHT; + switch (nativeEvent.getButton()) { + case com.jogamp.newt.event.MouseEvent.BUTTON1: + peButton = PConstants.LEFT; + break; + case com.jogamp.newt.event.MouseEvent.BUTTON2: + peButton = PConstants.CENTER; + break; + case com.jogamp.newt.event.MouseEvent.BUTTON3: + peButton = PConstants.RIGHT; + break; } if (PApplet.platform == PConstants.MACOSX) { From 870fd6bdda5bdba370f26bf82dfcf5de271e181f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 20:20:46 -0500 Subject: [PATCH 216/917] starting the next release --- app/src/processing/app/Base.java | 6 +- core/done.txt | 63 +++++++++++++++++++ core/todo.txt | 62 +----------------- done.txt | 104 +++++++++++++++++++++++++++++++ todo.txt | 103 +----------------------------- 5 files changed, 172 insertions(+), 166 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 5df968ed4b..fb36f77643 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2012-16 The Processing Foundation + Copyright (c) 2012-17 The Processing Foundation Copyright (c) 2004-12 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology @@ -55,9 +55,9 @@ public class Base { // Added accessors for 0218 because the UpdateCheck class was not properly // updating the values, due to javac inlining the static final values. - static private final int REVISION = 256; + static private final int REVISION = 257; /** This might be replaced by main() if there's a lib/version.txt file. */ - static private String VERSION_NAME = "0256"; //$NON-NLS-1$ + static private String VERSION_NAME = "0257"; //$NON-NLS-1$ /** Set true if this a proper release rather than a numbered revision. */ /** diff --git a/core/done.txt b/core/done.txt index d87755923c..1d3c46b079 100644 --- a/core/done.txt +++ b/core/done.txt @@ -1,3 +1,66 @@ +0256 (3.2.4) +X write exec() documentation +X https://github.com/processing/processing/issues/4740 +X add xmlns to elements procured from getChild() +X make sure newline is added after XML header when formatting + +api additions +X add listPaths(), listFiles() +X https://github.com/processing/processing/issues/4622 +X add increment() method that takes IntDict to merge another dictionary +X Calling this increment() since it doesn't make sense in practice for +X the other dictionary types, even though it's technically an add() +X add Entry class for iterating StringDict, IntDict, FloatDict +X add XML.print() method (prints with indent of 2) + +contribs +X Adding missing docs and keywords for TableRow +X https://github.com/processing/processing/pull/4333 +X PShape in Java2D wasn't respecting 'kind' +X https://github.com/processing/processing/issues/4826 +X https://github.com/processing/processing/pull/4834 + +cleaning +o probably should also check to make sure PApplet running JVM 8 +X or compile against 1.8 and force it? + +andres +X PShape array index out of bounds when using P3D +X https://github.com/processing/processing/issues/4773 +X modelX/Y/Z() should be disabled in P2D +X https://github.com/processing/processing/issues/4813 + +jakub +X FX: Prevent matrix stack overflow +X https://github.com/processing/processing/pull/4799 +X https://github.com/processing/processing/issues/4206 +X FX: Reset transform to identity before drawing background +X https://github.com/processing/processing/pull/4795 +X FX: Implement mouse wheel event +X https://github.com/processing/processing/issues/4169 +X https://github.com/processing/processing/pull/4796 +X FX: Fix curveVertex drawing all curves together as one long curve +X https://github.com/processing/processing/pull/4800 +X https://github.com/processing/processing/issues/4382 +X FX: Add exception handler which reports exceptions from user code +X https://github.com/processing/processing/pull/4798 +X https://github.com/processing/processing/issues/4339 +X Unify mouse pressed/released events across renderers +X https://github.com/processing/processing/issues/4361 +X https://github.com/processing/processing/pull/4797 +X Fix typo in GLSL preprocessor +X https://github.com/processing/processing/issues/4810 +X https://github.com/processing/processing/pull/4816 +X Keep Windows timer resolution high for OpenGL sketches +X prevents frame rate in OpenGL hovering around 30 instead of 60 +X https://github.com/processing/processing/pull/4847 +X https://github.com/processing/processing/issues/4846 +X Sketches still running in the background after closing +X https://github.com/processing/processing/issues/4831 +X (needed to allow JAVA2D to terminate when animation thread dies) +X https://github.com/processing/processing/pull/4839 + + 0255 (3.2.3) andres diff --git a/core/todo.txt b/core/todo.txt index f74b2c75c4..ebd169cd15 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,64 +1,4 @@ -0256 (3.2.4) -X write exec() documentation -X https://github.com/processing/processing/issues/4740 -X add xmlns to elements procured from getChild() -X make sure newline is added after XML header when formatting - -api additions -X add listPaths(), listFiles() -X https://github.com/processing/processing/issues/4622 -X add increment() method that takes IntDict to merge another dictionary -X Calling this increment() since it doesn't make sense in practice for -X the other dictionary types, even though it's technically an add() -X add Entry class for iterating StringDict, IntDict, FloatDict -X add XML.print() method (prints with indent of 2) - -contribs -X Adding missing docs and keywords for TableRow -X https://github.com/processing/processing/pull/4333 -X PShape in Java2D wasn't respecting 'kind' -X https://github.com/processing/processing/issues/4826 -X https://github.com/processing/processing/pull/4834 - -cleaning -o probably should also check to make sure PApplet running JVM 8 -X or compile against 1.8 and force it? - -andres -X PShape array index out of bounds when using P3D -X https://github.com/processing/processing/issues/4773 -X modelX/Y/Z() should be disabled in P2D -X https://github.com/processing/processing/issues/4813 - -jakub -X FX: Prevent matrix stack overflow -X https://github.com/processing/processing/pull/4799 -X https://github.com/processing/processing/issues/4206 -X FX: Reset transform to identity before drawing background -X https://github.com/processing/processing/pull/4795 -X FX: Implement mouse wheel event -X https://github.com/processing/processing/issues/4169 -X https://github.com/processing/processing/pull/4796 -X FX: Fix curveVertex drawing all curves together as one long curve -X https://github.com/processing/processing/pull/4800 -X https://github.com/processing/processing/issues/4382 -X FX: Add exception handler which reports exceptions from user code -X https://github.com/processing/processing/pull/4798 -X https://github.com/processing/processing/issues/4339 -X Unify mouse pressed/released events across renderers -X https://github.com/processing/processing/issues/4361 -X https://github.com/processing/processing/pull/4797 -X Fix typo in GLSL preprocessor -X https://github.com/processing/processing/issues/4810 -X https://github.com/processing/processing/pull/4816 -X Keep Windows timer resolution high for OpenGL sketches -X prevents frame rate in OpenGL hovering around 30 instead of 60 -X https://github.com/processing/processing/pull/4847 -X https://github.com/processing/processing/issues/4846 -X Sketches still running in the background after closing -X https://github.com/processing/processing/issues/4831 -X (needed to allow JAVA2D to terminate when animation thread dies) -X https://github.com/processing/processing/pull/4839 +0257 (3.2.5) _ no prompt shows with selectInput() on 10.11 and 10.12 diff --git a/done.txt b/done.txt index 1ac0c6a7eb..f6f80ec4bc 100644 --- a/done.txt +++ b/done.txt @@ -1,3 +1,107 @@ +0256 (3.2.4) +X only require reference.zip (and internet connection) when building dist +X set text style properly for Contribution Manager error message +X Detect changes to 'hosts' file in case users modify/remove localhost +X https://github.com/processing/processing/issues/4738 +X No sketch window opens after hitting Run if hosts file changed +X https://github.com/processing/processing/issues/1868 +X https://github.com/processing/processing/issues/3123 +X https://github.com/processing/processing/issues/4735 +X move the DEBUG flag into an external file or preferences.txt +X will help us with debugging w/ others as well +X change to debug.txt; too confusing with the folder thing +X replace java.util.logging code with built-in logging +X split gui and non-gui portions of console for earlier startup +X split EditorConsole into gui and non-gui code? +X otherwise System.err/out not going to a file unless we have GUI +X also can't debug before the GUI shows up +o gracefully recover from proxy problems +X https://github.com/processing/processing/issues/1601 +X JRE download fails during ant build +X https://github.com/processing/processing/issues/4823 +X changed headerType to console (make sure changed back) +X Spaces not handled correctly in when installing "processing-java" on macOS +X https://github.com/processing/processing/issues/4779 + +contrib +X Added the remove filter feature +X https://github.com/processing/processing/pull/3890 +X ctrl-J (for debugger) is inserting newline +X https://github.com/processing/processing/issues/3830 +X Replace keyChar with keyCode to prevent new line error when debugging +X https://github.com/processing/processing/pull/4806 +X https://github.com/processing/processing/issues/4804 + +jakub +X println(int(byte(245))) throwing error +X https://github.com/processing/processing/issues/4652 +X https://github.com/processing/processing/pull/4744 +X 'web colors' next to each other fail to parse in certain situations +X https://github.com/processing/processing/issues/4752 +X https://github.com/processing/processing/pull/4753 +X Pasting code from editor to empty editor produces Exception +X https://github.com/processing/processing/issues/4522 +X https://github.com/processing/processing/pull/4761 +X possible infinite loop on modified externally +X https://github.com/processing/processing/issues/3965 +X https://github.com/processing/processing/pull/4762 +X Report missing brace in correct tab, suppress other errors until fixed +X https://github.com/processing/processing/pull/4777 +X Improvements to sketch launching and stopping +X https://github.com/processing/processing/pull/4848 +X several Contribution Manager fixes +X https://github.com/processing/processing/pull/4844 +X Add missing equals() and hashCode() to Contribution +X https://github.com/processing/processing/pull/4843 +X Contribution Manager does not show all libraries until filter cleared +X https://github.com/processing/processing/pull/4843 +X https://github.com/processing/processing/issues/4840 +X Mode, requiring update, appears in Updates tab but not in Modes tab +X https://github.com/processing/processing/issues/4822 +X also fixed w/ https://github.com/processing/processing/pull/4843 +X Syntax highlighting issues (fixed with #4761) +X https://github.com/processing/processing/issues/4286 +X sketchbook window doesn't update when sketches are added, renamed, etc +X https://github.com/processing/processing/issues/2944 +X https://github.com/processing/processing/pull/4842 + +cleaning +X clean up 'ant doc' target to remove warnings +X https://github.com/processing/processing/issues/1492 +X fixed in 3.1.1 +X Horizontal scrollbar does not scroll textarea all the way +X https://github.com/processing/processing/issues/3591 +X mostly fixed in 3.0b7, opting to wait for RSyntaxArea or whatever +X possible PR for updating sketchbook stuff +o https://github.com/processing/processing/pull/3081 +X should be covered by other fixes +X longer PR about sketchbook stuff, but closed +X https://github.com/processing/processing/pull/3178 +X closed back in April 2015, issue was all over the place +X fix encodings, line endings, and mime types in the repo +X https://github.com/processing/processing/issues/2955 +X fixed 2015-11 https://github.com/processing/processing/pull/2977 +X need to handle the 2.x to 3.x sketchbook transition +X prefs are the same file, but sketchbook location pref is different +o performance +o video stinks.. java2d stinks.. macs stink +o note in the 'drawing in 2d' section of faq +o fastest machine possible +o turn off hyperthreading in the bios +o nice gfx card only helps opengl +o dual processor not particularly useful, unless you make more threads +o but making more threads is often more work than is useful +X too out of date +X why adding .0001 to a float doesn't work +X and how they're imprecise in general (use nf) +X http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Syntax;action=display;num=1130877990 +X long since added to the FAQ +X infinite "file changed" popups +X https://github.com/processing/processing/issues/3965 +o https://github.com/processing/processing/pull/4037 +X https://github.com/processing/processing/pull/4037 + + 0255 (3.2.3) X ensure that update.id is set before checking for contrib updates X if prettyVersion is blank (or null?), just use version (Firmata) diff --git a/todo.txt b/todo.txt index 92ef0ba194..e5bef7c2e4 100755 --- a/todo.txt +++ b/todo.txt @@ -1,105 +1,4 @@ -0256 (3.2.4) -X only require reference.zip (and internet connection) when building dist -X set text style properly for Contribution Manager error message -X Detect changes to 'hosts' file in case users modify/remove localhost -X https://github.com/processing/processing/issues/4738 -X No sketch window opens after hitting Run if hosts file changed -X https://github.com/processing/processing/issues/1868 -X https://github.com/processing/processing/issues/3123 -X https://github.com/processing/processing/issues/4735 -X move the DEBUG flag into an external file or preferences.txt -X will help us with debugging w/ others as well -X change to debug.txt; too confusing with the folder thing -X replace java.util.logging code with built-in logging -X split gui and non-gui portions of console for earlier startup -X split EditorConsole into gui and non-gui code? -X otherwise System.err/out not going to a file unless we have GUI -X also can't debug before the GUI shows up -o gracefully recover from proxy problems -X https://github.com/processing/processing/issues/1601 -X JRE download fails during ant build -X https://github.com/processing/processing/issues/4823 -X changed headerType to console (make sure changed back) -X Spaces not handled correctly in when installing "processing-java" on macOS -X https://github.com/processing/processing/issues/4779 - -contrib -X Added the remove filter feature -X https://github.com/processing/processing/pull/3890 -X ctrl-J (for debugger) is inserting newline -X https://github.com/processing/processing/issues/3830 -X Replace keyChar with keyCode to prevent new line error when debugging -X https://github.com/processing/processing/pull/4806 -X https://github.com/processing/processing/issues/4804 - -jakub -X println(int(byte(245))) throwing error -X https://github.com/processing/processing/issues/4652 -X https://github.com/processing/processing/pull/4744 -X 'web colors' next to each other fail to parse in certain situations -X https://github.com/processing/processing/issues/4752 -X https://github.com/processing/processing/pull/4753 -X Pasting code from editor to empty editor produces Exception -X https://github.com/processing/processing/issues/4522 -X https://github.com/processing/processing/pull/4761 -X possible infinite loop on modified externally -X https://github.com/processing/processing/issues/3965 -X https://github.com/processing/processing/pull/4762 -X Report missing brace in correct tab, suppress other errors until fixed -X https://github.com/processing/processing/pull/4777 -X Improvements to sketch launching and stopping -X https://github.com/processing/processing/pull/4848 -X several Contribution Manager fixes -X https://github.com/processing/processing/pull/4844 -X Add missing equals() and hashCode() to Contribution -X https://github.com/processing/processing/pull/4843 -X Contribution Manager does not show all libraries until filter cleared -X https://github.com/processing/processing/pull/4843 -X https://github.com/processing/processing/issues/4840 -X Mode, requiring update, appears in Updates tab but not in Modes tab -X https://github.com/processing/processing/issues/4822 -X also fixed w/ https://github.com/processing/processing/pull/4843 -X Syntax highlighting issues (fixed with #4761) -X https://github.com/processing/processing/issues/4286 -X sketchbook window doesn't update when sketches are added, renamed, etc -X https://github.com/processing/processing/issues/2944 -X https://github.com/processing/processing/pull/4842 - -cleaning -X clean up 'ant doc' target to remove warnings -X https://github.com/processing/processing/issues/1492 -X fixed in 3.1.1 -X Horizontal scrollbar does not scroll textarea all the way -X https://github.com/processing/processing/issues/3591 -X mostly fixed in 3.0b7, opting to wait for RSyntaxArea or whatever -X possible PR for updating sketchbook stuff -o https://github.com/processing/processing/pull/3081 -X should be covered by other fixes -X longer PR about sketchbook stuff, but closed -X https://github.com/processing/processing/pull/3178 -X closed back in April 2015, issue was all over the place -X fix encodings, line endings, and mime types in the repo -X https://github.com/processing/processing/issues/2955 -X fixed 2015-11 https://github.com/processing/processing/pull/2977 -X need to handle the 2.x to 3.x sketchbook transition -X prefs are the same file, but sketchbook location pref is different -o performance -o video stinks.. java2d stinks.. macs stink -o note in the 'drawing in 2d' section of faq -o fastest machine possible -o turn off hyperthreading in the bios -o nice gfx card only helps opengl -o dual processor not particularly useful, unless you make more threads -o but making more threads is often more work than is useful -X too out of date -X why adding .0001 to a float doesn't work -X and how they're imprecise in general (use nf) -X http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Syntax;action=display;num=1130877990 -X long since added to the FAQ -X infinite "file changed" popups -X https://github.com/processing/processing/issues/3965 -o https://github.com/processing/processing/pull/4037 -X https://github.com/processing/processing/pull/4037 +0257 (3.2.5) _ "Sketch disappeared" infinite pop up dialogs From f393c6b0c6ebd4783ec2ae155781734b4f9702b7 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Jan 2017 20:26:01 -0500 Subject: [PATCH 217/917] note about previous release --- todo.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/todo.txt b/todo.txt index e5bef7c2e4..24b37130d3 100755 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,12 @@ 0257 (3.2.5) +cleaning +X Contribution Manager does not show all libraries until filter cleared +X https://github.com/processing/processing/issues/4840 +X fixed in 3.2.4 + + _ "Sketch disappeared" infinite pop up dialogs _ https://github.com/processing/processing/pull/4808 _ https://github.com/processing/processing/issues/4805 From d5b7aa41f0463b3c877d206cac4560c5910d2d6d Mon Sep 17 00:00:00 2001 From: Jonathan Feinberg Date: Mon, 30 Jan 2017 13:38:31 -0500 Subject: [PATCH 218/917] Restore reachability for weakrefs. --- core/src/processing/opengl/PGraphicsOpenGL.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 54d8f25d42..3835811407 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -53,6 +53,7 @@ public class PGraphicsOpenGL extends PGraphics { // Using the technique alternative to finalization described in: // http://www.oracle.com/technetwork/articles/java/finalization-137655.html static private ReferenceQueue refQueue = new ReferenceQueue<>(); + static private List> reachableWeakReferences = new LinkedList<>(); static final private int MAX_DRAIN_GLRES_ITERATIONS = 10; @@ -73,9 +74,11 @@ private static abstract class Disposable extends WeakReference { protected Disposable(T obj) { super(obj, refQueue); drainRefQueueBounded(); + reachableWeakReferences.add(this); } public void dispose() { + reachableWeakReferences.remove(this); disposeNative(); } From 018b0006d3cdf118eaf22afbafc85573a97384ad Mon Sep 17 00:00:00 2001 From: Jonathan Feinberg Date: Mon, 30 Jan 2017 13:40:08 -0500 Subject: [PATCH 219/917] Reformat long line. --- core/src/processing/opengl/PGraphicsOpenGL.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 3835811407..368be4a501 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -53,7 +53,8 @@ public class PGraphicsOpenGL extends PGraphics { // Using the technique alternative to finalization described in: // http://www.oracle.com/technetwork/articles/java/finalization-137655.html static private ReferenceQueue refQueue = new ReferenceQueue<>(); - static private List> reachableWeakReferences = new LinkedList<>(); + private static List> reachableWeakReferences = + new LinkedList<>(); static final private int MAX_DRAIN_GLRES_ITERATIONS = 10; From 0c987d9da2978366df536b6cc44f2a3d329936e5 Mon Sep 17 00:00:00 2001 From: Jonathan Feinberg Date: Mon, 30 Jan 2017 13:47:03 -0500 Subject: [PATCH 220/917] Protect disposables from ClassCastException. --- core/src/processing/opengl/PGraphicsOpenGL.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 368be4a501..061c0377ae 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -890,6 +890,9 @@ public void disposeNative() { @Override public boolean equals(Object obj) { + if (!(obj instanceof GLResourceTexture)) { + return false; + } GLResourceTexture other = (GLResourceTexture)obj; return other.glName == glName && other.context == context; @@ -936,6 +939,9 @@ public void disposeNative() { @Override public boolean equals(Object obj) { + if (!(obj instanceof GLResourceVertexBuffer)) { + return false; + } GLResourceVertexBuffer other = (GLResourceVertexBuffer)obj; return other.glId == glId && other.context == context; @@ -995,6 +1001,9 @@ public void disposeNative() { @Override public boolean equals(Object obj) { + if (!(obj instanceof GLResourceShader)) { + return false; + } GLResourceShader other = (GLResourceShader)obj; return other.glProgram == glProgram && other.glVertex == glVertex && @@ -1095,6 +1104,9 @@ public void disposeNative() { @Override public boolean equals(Object obj) { + if (!(obj instanceof GLResourceFrameBuffer)) { + return false; + } GLResourceFrameBuffer other = (GLResourceFrameBuffer)obj; return other.glFbo == glFbo && other.glDepth == glDepth && From c01d88b4d582f5f4924c4c527ca70fd814ea3082 Mon Sep 17 00:00:00 2001 From: Jonathan Feinberg Date: Mon, 30 Jan 2017 15:58:35 -0500 Subject: [PATCH 221/917] Use Java standard modifier order. --- core/src/processing/opengl/PGraphicsOpenGL.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 061c0377ae..bccf51a562 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -52,7 +52,7 @@ public class PGraphicsOpenGL extends PGraphics { // Disposal of native resources // Using the technique alternative to finalization described in: // http://www.oracle.com/technetwork/articles/java/finalization-137655.html - static private ReferenceQueue refQueue = new ReferenceQueue<>(); + private static ReferenceQueue refQueue = new ReferenceQueue<>(); private static List> reachableWeakReferences = new LinkedList<>(); @@ -79,6 +79,7 @@ protected Disposable(T obj) { } public void dispose() { + System.err.println("disposing " + this ); reachableWeakReferences.remove(this); disposeNative(); } From ff23364fe41c9d7821db7132da23c3a063d77c3b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 30 Jan 2017 18:50:16 -0500 Subject: [PATCH 222/917] add StringDict constructor, another double quote case --- core/src/processing/data/StringDict.java | 15 +++++++++++++++ core/src/processing/data/Table.java | 6 ++++++ core/todo.txt | 3 +++ todo.txt | 2 ++ 4 files changed, 26 insertions(+) diff --git a/core/src/processing/data/StringDict.java b/core/src/processing/data/StringDict.java index 3768f69537..1ea488359d 100644 --- a/core/src/processing/data/StringDict.java +++ b/core/src/processing/data/StringDict.java @@ -108,6 +108,21 @@ public StringDict(String[][] pairs) { } + /** + * Create a dictionary that maps between column titles and cell entries + * in a TableRow. + */ + public StringDict(TableRow row) { + String[] titles = row.getColumnTitles(); + if (titles == null) { + titles = new StringList(IntList.fromRange(row.getColumnCount())).array(); + } + for (int col = 0; col < row.getColumnCount(); col++) { + set(titles[col], row.getString(col)); + } + } + + /** * @webref stringdict:method * @brief Returns the number of key/value pairs diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index 307b9df67a..be8defeec4 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -671,6 +671,12 @@ protected boolean ingest() { addPiece(start, i, hasEscapedQuotes); start = i+2; return true; + + } else { + // This is a lone-wolf quote, occasionally seen in exports. + // It's a single quote in the middle of some other text, + // and not escaped properly. Pray for the best! + i++; } } else { // not a quoted line diff --git a/core/todo.txt b/core/todo.txt index ebd169cd15..c1608243ee 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,4 +1,7 @@ 0257 (3.2.5) +X StringDict(TableRow) constructor +X allow lone double quotes in the midst of csv strings +_ make trim() work on column titles as well _ no prompt shows with selectInput() on 10.11 and 10.12 diff --git a/todo.txt b/todo.txt index 24b37130d3..ed123f37b8 100755 --- a/todo.txt +++ b/todo.txt @@ -6,6 +6,8 @@ X Contribution Manager does not show all libraries until filter cleared X https://github.com/processing/processing/issues/4840 X fixed in 3.2.4 +_ NVIDIA driver problems (and means to check) +_ https://github.com/processing/processing/issues/4853 _ "Sketch disappeared" infinite pop up dialogs _ https://github.com/processing/processing/pull/4808 From 94c557e23d067974d64cbe060ce0f4e80cb88d71 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 30 Jan 2017 18:53:08 -0500 Subject: [PATCH 223/917] return null for PApplet.trim(null) --- core/src/processing/core/PApplet.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 2f2818fad8..440bfa8382 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -8662,6 +8662,9 @@ static public Object reverse(Object list) { * @see PApplet#join(String[], char) */ static public String trim(String str) { + if (str == null) { + return null; + } return str.replace('\u00A0', ' ').trim(); } @@ -8673,7 +8676,7 @@ static public String[] trim(String[] array) { String[] outgoing = new String[array.length]; for (int i = 0; i < array.length; i++) { if (array[i] != null) { - outgoing[i] = array[i].replace('\u00A0', ' ').trim(); + outgoing[i] = trim(array[i]); } } return outgoing; From 0f2a671c9dce2c1349cf0cebf9daf3c2bd0188b8 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 30 Jan 2017 18:54:38 -0500 Subject: [PATCH 224/917] make trim(String[]) handle arrays, Table.trim() handles columns --- core/src/processing/core/PApplet.java | 3 +++ core/src/processing/data/Table.java | 1 + core/todo.txt | 1 + 3 files changed, 5 insertions(+) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 440bfa8382..0ba12d8aa8 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -8673,6 +8673,9 @@ static public String trim(String str) { * @param array a String array */ static public String[] trim(String[] array) { + if (array == null) { + return null; + } String[] outgoing = new String[array.length]; for (int i = 0; i < array.length; i++) { if (array[i] != null) { diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index be8defeec4..4622d64130 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -4045,6 +4045,7 @@ public void removeTokens(String tokens, String columnName) { * @see Table#removeTokens(String) */ public void trim() { + columnTitles = PApplet.trim(columnTitles); for (int col = 0; col < getColumnCount(); col++) { trim(col); } diff --git a/core/todo.txt b/core/todo.txt index c1608243ee..eee476aaf1 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,4 +1,5 @@ 0257 (3.2.5) +X return null for PApplet.trim(null) X StringDict(TableRow) constructor X allow lone double quotes in the midst of csv strings _ make trim() work on column titles as well From 48bbf23bc10be79d00ad80ed81480020cfc2fa12 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 30 Jan 2017 19:23:02 -0500 Subject: [PATCH 225/917] consume Unicode BOM (0xFEFF) in createReader() and Table parser --- core/src/processing/core/PApplet.java | 15 ++++++++++++++- core/src/processing/data/Table.java | 10 ++++++++++ core/todo.txt | 6 +++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 0ba12d8aa8..b6128c7866 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -6744,7 +6744,20 @@ static public BufferedReader createReader(File file) { static public BufferedReader createReader(InputStream input) { InputStreamReader isr = new InputStreamReader(input, StandardCharsets.UTF_8); - return new BufferedReader(isr); + + BufferedReader reader = new BufferedReader(isr); + // consume the Unicode BOM (byte order marker) if present + try { + reader.mark(1); + int c = reader.read(); + // if not the BOM, back up to the beginning again + if (c != '\uFEFF') { + reader.reset(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return reader; } diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index 4622d64130..8f6ce05d08 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -378,6 +378,15 @@ protected void parse(InputStream input, String options) throws IOException { } else { InputStreamReader isr = new InputStreamReader(input, encoding); BufferedReader reader = new BufferedReader(isr); + + // strip out the Unicode BOM, if present + reader.mark(1); + int c = reader.read(); + // if not the BOM, back up to the beginning again + if (c != '\uFEFF') { + reader.reset(); + } + /* if (awfulCSV) { parseAwfulCSV(reader, header); @@ -4039,6 +4048,7 @@ public void removeTokens(String tokens, String columnName) { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + /** * @webref table:method * @brief Trims whitespace from values diff --git a/core/todo.txt b/core/todo.txt index eee476aaf1..e7552fe0ea 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -2,7 +2,11 @@ X return null for PApplet.trim(null) X StringDict(TableRow) constructor X allow lone double quotes in the midst of csv strings -_ make trim() work on column titles as well +X make trim() work on column titles as well +_ add trimRows() and trimColumns() +_ would you ever use one w/o the other? +_ should trim() just handle it? +X consume Unicode BOM (0xFEFF) in createReader() and Table parser _ no prompt shows with selectInput() on 10.11 and 10.12 From 5a23b02d97fa70f30bc1b287ddcfe2700dda12eb Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 31 Jan 2017 04:55:03 -0500 Subject: [PATCH 226/917] fixing up StringDict(TableRow) and Table.trim() now removes extra rows and columns --- core/src/processing/data/StringDict.java | 7 +++- core/src/processing/data/Table.java | 50 ++++++++++++++++++++++++ core/todo.txt | 13 +++--- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/core/src/processing/data/StringDict.java b/core/src/processing/data/StringDict.java index 1ea488359d..a5d83fd095 100644 --- a/core/src/processing/data/StringDict.java +++ b/core/src/processing/data/StringDict.java @@ -110,9 +110,12 @@ public StringDict(String[][] pairs) { /** * Create a dictionary that maps between column titles and cell entries - * in a TableRow. + * in a TableRow. If two columns have the same name, the later column's + * values will override the earlier values. */ public StringDict(TableRow row) { + this(row.getColumnCount()); + String[] titles = row.getColumnTitles(); if (titles == null) { titles = new StringList(IntList.fromRange(row.getColumnCount())).array(); @@ -120,6 +123,8 @@ public StringDict(TableRow row) { for (int col = 0; col < row.getColumnCount(); col++) { set(titles[col], row.getString(col)); } + // remove unused and overwritten entries + crop(); } diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index 8f6ce05d08..61817d5166 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -4059,8 +4059,58 @@ public void trim() { for (int col = 0; col < getColumnCount(); col++) { trim(col); } + // remove empty columns + int lastColumn = getColumnCount() - 1; + //while (isEmptyColumn(lastColumn) && lastColumn >= 0) { + while (isEmptyArray(getStringColumn(lastColumn)) && lastColumn >= 0) { + lastColumn--; + } + setColumnCount(lastColumn + 1); + + // remove empty rows (starting from the end) + int lastRow = lastRowIndex(); + //while (isEmptyRow(lastRow) && lastRow >= 0) { + while (isEmptyArray(getStringRow(lastRow)) && lastRow >= 0) { + lastRow--; + } + setRowCount(lastRow + 1); + } + + + protected boolean isEmptyArray(String[] contents) { + for (String entry : contents) { + if (entry != null && entry.length() > 0) { + return false; + } + } + return true; } + + /* + protected boolean isEmptyColumn(int column) { + String[] contents = getStringColumn(column); + for (String entry : contents) { + if (entry != null && entry.length() > 0) { + return false; + } + } + return true; + } + + + protected boolean isEmptyRow(int row) { + String[] contents = getStringRow(row); + for (String entry : contents) { + if (entry != null && entry.length() > 0) { + return false; + } + } + return true; + } + */ + + /** * @param column ID number of the column to trim */ diff --git a/core/todo.txt b/core/todo.txt index e7552fe0ea..fb384dbc28 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -3,14 +3,13 @@ X return null for PApplet.trim(null) X StringDict(TableRow) constructor X allow lone double quotes in the midst of csv strings X make trim() work on column titles as well -_ add trimRows() and trimColumns() -_ would you ever use one w/o the other? -_ should trim() just handle it? +o add trimRows() and trimColumns() +o would you ever use one w/o the other? +X just make this part of trim() X consume Unicode BOM (0xFEFF) in createReader() and Table parser - - -_ no prompt shows with selectInput() on 10.11 and 10.12 -_ https://github.com/processing/processing/issues/4758 +o no prompt shows with selectInput() on 10.11 and 10.12 +X https://github.com/processing/processing/issues/4758 +X can't fix, seems embedded in the Java implementation _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 From 87c21e36701342cc3cdf6b5f725079f683b6e263 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 31 Jan 2017 04:58:33 -0500 Subject: [PATCH 227/917] remove rows/cols from beginning in trim() --- core/src/processing/data/Table.java | 9 +++++++++ core/todo.txt | 2 ++ 2 files changed, 11 insertions(+) diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index 61817d5166..657fd6e5dd 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -4067,6 +4067,11 @@ public void trim() { } setColumnCount(lastColumn + 1); + // trim() works from both sides + while (getColumnCount() > 0 && isEmptyArray(getStringColumn(0))) { + removeColumn(0); + } + // remove empty rows (starting from the end) int lastRow = lastRowIndex(); //while (isEmptyRow(lastRow) && lastRow >= 0) { @@ -4074,6 +4079,10 @@ public void trim() { lastRow--; } setRowCount(lastRow + 1); + + while (getRowCount() > 0 && isEmptyArray(getStringRow(0))) { + removeRow(0); + } } diff --git a/core/todo.txt b/core/todo.txt index fb384dbc28..e0f598d8bd 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -6,6 +6,8 @@ X make trim() work on column titles as well o add trimRows() and trimColumns() o would you ever use one w/o the other? X just make this part of trim() +X also remove rows/columns from beginning +X since that's what trim() on strings does X consume Unicode BOM (0xFEFF) in createReader() and Table parser o no prompt shows with selectInput() on 10.11 and 10.12 X https://github.com/processing/processing/issues/4758 From 4de17ed378890e3f55371b535aba2b39d4e21f14 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 31 Jan 2017 17:11:29 -0500 Subject: [PATCH 228/917] don't delete export folders if they don't exist --- app/src/processing/app/Mode.java | 11 +++++++---- todo.txt | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/Mode.java b/app/src/processing/app/Mode.java index 2e6087fd56..54c5c1392a 100644 --- a/app/src/processing/app/Mode.java +++ b/app/src/processing/app/Mode.java @@ -1017,10 +1017,13 @@ public void prepareExportFolder(File targetFolder) { if (targetFolder != null) { // Nuke the old applet/application folder because it can cause trouble if (Preferences.getBoolean("export.delete_target_folder")) { - try { - Platform.deleteFile(targetFolder); - } catch (IOException e) { - e.printStackTrace(); + if (targetFolder.exists()) { + try { + Platform.deleteFile(targetFolder); + } catch (IOException e) { + // ignore errors/continue; likely to be ok + e.printStackTrace(); + } } } // Create a fresh output folder (needed before preproc is run next) diff --git a/todo.txt b/todo.txt index ed123f37b8..2b46ba1e81 100755 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,6 @@ 0257 (3.2.5) +X check for already-exported folders before trying to remove them +X was spewing 'file not found' errors into the console cleaning @@ -6,6 +8,7 @@ X Contribution Manager does not show all libraries until filter cleared X https://github.com/processing/processing/issues/4840 X fixed in 3.2.4 + _ NVIDIA driver problems (and means to check) _ https://github.com/processing/processing/issues/4853 From b1bb1f15772b719862b2f507f0ddf2d646f68d5d Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 31 Jan 2017 20:46:52 -0500 Subject: [PATCH 229/917] change some null handling with JSON --- core/src/processing/data/JSONObject.java | 38 +++++++++++++++++------- core/todo.txt | 7 +++++ todo.txt | 1 - 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/core/src/processing/data/JSONObject.java b/core/src/processing/data/JSONObject.java index 1c15b3aa12..768fdd7f8e 100644 --- a/core/src/processing/data/JSONObject.java +++ b/core/src/processing/data/JSONObject.java @@ -539,11 +539,15 @@ static protected String doubleToString(double d) { */ public Object get(String key) { if (key == null) { - throw new RuntimeException("Null key."); + throw new RuntimeException("JSONObject.get(null) called"); } Object object = this.opt(key); if (object == null) { - throw new RuntimeException("JSONObject[" + quote(key) + "] not found."); + // Adding for rev 0257 in line with other p5 api + return null; + } + if (object == null) { + throw new RuntimeException("JSONObject[" + quote(key) + "] not found"); } return object; } @@ -563,10 +567,14 @@ public Object get(String key) { */ public String getString(String key) { Object object = this.get(key); + if (object == null) { + // Adding for rev 0257 in line with other p5 api + return null; + } if (object instanceof String) { return (String)object; } - throw new RuntimeException("JSONObject[" + quote(key) + "] not a string."); + throw new RuntimeException("JSONObject[" + quote(key) + "] is not a string"); } @@ -599,10 +607,12 @@ public String getString(String key, String defaultValue) { */ public int getInt(String key) { Object object = this.get(key); + if (object == null) { + throw new RuntimeException("JSONObject[" + quote(key) + "] not found"); + } try { - return object instanceof Number - ? ((Number)object).intValue() - : Integer.parseInt((String)object); + return object instanceof Number ? + ((Number)object).intValue() : Integer.parseInt((String)object); } catch (Exception e) { throw new RuntimeException("JSONObject[" + quote(key) + "] is not an int."); } @@ -778,14 +788,17 @@ public boolean getBoolean(String key, boolean defaultValue) { * @webref jsonobject:method * @brief Gets the JSONArray value associated with a key * @param key a key string - * @return A JSONArray which is the value. - * @throws RuntimeException if the key is not found or if the value is not a JSONArray. + * @return A JSONArray which is the value, or null if not present + * @throws RuntimeException if the value is not a JSONArray. * @see JSONObject#getJSONObject(String) * @see JSONObject#setJSONObject(String, JSONObject) * @see JSONObject#setJSONArray(String, JSONArray) */ public JSONArray getJSONArray(String key) { Object object = this.get(key); + if (object == null) { + return null; + } if (object instanceof JSONArray) { return (JSONArray)object; } @@ -799,14 +812,17 @@ public JSONArray getJSONArray(String key) { * @webref jsonobject:method * @brief Gets the JSONObject value associated with a key * @param key a key string - * @return A JSONObject which is the value. - * @throws RuntimeException if the key is not found or if the value is not a JSONObject. + * @return A JSONObject which is the value or null if not available. + * @throws RuntimeException if the value is not a JSONObject. * @see JSONObject#getJSONArray(String) * @see JSONObject#setJSONObject(String, JSONObject) * @see JSONObject#setJSONArray(String, JSONArray) */ public JSONObject getJSONObject(String key) { Object object = this.get(key); + if (object == null) { + return null; + } if (object instanceof JSONObject) { return (JSONObject)object; } @@ -864,7 +880,7 @@ public JSONObject getJSONObject(String key) { * @return true if the key exists in the JSONObject. */ public boolean hasKey(String key) { - return this.map.containsKey(key); + return map.containsKey(key); } diff --git a/core/todo.txt b/core/todo.txt index e0f598d8bd..4b370f4e42 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -12,6 +12,13 @@ X consume Unicode BOM (0xFEFF) in createReader() and Table parser o no prompt shows with selectInput() on 10.11 and 10.12 X https://github.com/processing/processing/issues/4758 X can't fix, seems embedded in the Java implementation +X return null for getString(), getJSONObject(), and getJSONArray() +X when key is not present, more in line w/ other p5 api + +contrib +X Fix a number of memory leaks (jdf) +X https://github.com/processing/processing/pull/4862 + _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 diff --git a/todo.txt b/todo.txt index 2b46ba1e81..a5c57e307f 100755 --- a/todo.txt +++ b/todo.txt @@ -2,7 +2,6 @@ X check for already-exported folders before trying to remove them X was spewing 'file not found' errors into the console - cleaning X Contribution Manager does not show all libraries until filter cleared X https://github.com/processing/processing/issues/4840 From ea529448b3a54ed60056aaaa350cbd0d5534ac6a Mon Sep 17 00:00:00 2001 From: Jonathan Feinberg Date: Wed, 1 Feb 2017 12:55:41 -0500 Subject: [PATCH 230/917] Delete stray println. --- core/src/processing/opengl/PGraphicsOpenGL.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index bccf51a562..eeebcc9cc1 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -79,7 +79,6 @@ protected Disposable(T obj) { } public void dispose() { - System.err.println("disposing " + this ); reachableWeakReferences.remove(this); disposeNative(); } From 0b5fc1a4fecacb91829563a4e0b4afd421a1068e Mon Sep 17 00:00:00 2001 From: codeanticode Date: Wed, 1 Feb 2017 16:30:53 -0500 Subject: [PATCH 231/917] removed printout to system.err --- core/src/processing/opengl/PGraphicsOpenGL.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index bccf51a562..eeebcc9cc1 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -79,7 +79,6 @@ protected Disposable(T obj) { } public void dispose() { - System.err.println("disposing " + this ); reachableWeakReferences.remove(this); disposeNative(); } From 98d6740ba7531ac10c4de201e4ff28420db89f39 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 3 Feb 2017 10:03:54 -0500 Subject: [PATCH 232/917] notes about the patch from jdf --- core/todo.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index 4b370f4e42..3100cabeb5 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -18,6 +18,8 @@ X when key is not present, more in line w/ other p5 api contrib X Fix a number of memory leaks (jdf) X https://github.com/processing/processing/pull/4862 +X https://github.com/jdf/processing.py/issues/233 +X https://github.com/processing/processing/pull/4873 _ TRIANGLE_STRIP not working correctly with createShape() and default renderer From e683d04d69c67d19ea784e75bb8cb52741d5d10c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 3 Feb 2017 11:58:22 -0500 Subject: [PATCH 233/917] deal with a handful of warnings --- java/src/processing/mode/java/Debugger.java | 2 +- .../mode/java/pdex/PreprocessingService.java | 11 +++++------ java/src/processing/mode/java/runner/Runner.java | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/java/src/processing/mode/java/Debugger.java b/java/src/processing/mode/java/Debugger.java index c4be8c3a77..5d7eecb573 100644 --- a/java/src/processing/mode/java/Debugger.java +++ b/java/src/processing/mode/java/Debugger.java @@ -1407,7 +1407,7 @@ private void loge(String msg, Throwable t) { } - private void logitse(Throwable t) { + static private void logitse(Throwable t) { Messages.loge("incompatible thread state?", t); } diff --git a/java/src/processing/mode/java/pdex/PreprocessingService.java b/java/src/processing/mode/java/pdex/PreprocessingService.java index ce535a92d8..0827e3ffe9 100644 --- a/java/src/processing/mode/java/pdex/PreprocessingService.java +++ b/java/src/processing/mode/java/pdex/PreprocessingService.java @@ -72,7 +72,6 @@ /** * The main error checking service */ -@SuppressWarnings("unchecked") public class PreprocessingService { protected final JavaEditor editor; @@ -93,7 +92,7 @@ public class PreprocessingService { private CompletableFuture preprocessingTask = new CompletableFuture<>(); private CompletableFuture lastCallback = - new CompletableFuture() {{ + new CompletableFuture() {{ complete(null); // initialization block }}; @@ -568,8 +567,8 @@ private static List buildSearchLibraryClassPath(JavaMode mode) { } - private List buildSketchLibraryClassPath(JavaMode mode, - List programImports) { + static private List buildSketchLibraryClassPath(JavaMode mode, + List programImports) { StringBuilder classPath = new StringBuilder(); programImports.stream() @@ -590,7 +589,7 @@ private List buildSketchLibraryClassPath(JavaMode mode, } - private List buildJavaRuntimeClassPath() { + static private List buildJavaRuntimeClassPath() { StringBuilder classPath = new StringBuilder(); // Java runtime @@ -654,7 +653,7 @@ private static CompilationUnit makeASTWithBindings(ASTParser parser, /** * Ignore processing packages, java.*.*. etc. */ - private boolean ignorableImport(String packageName) { + static private boolean ignorableImport(String packageName) { return (packageName.startsWith("java.") || packageName.startsWith("javax.")); } diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index c383fc2c81..1223ee7521 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -127,7 +127,7 @@ public Runner(JavaBuild build, RunnerListener listener) throws SketchException { * Has the user screwed up their hosts file? * https://github.com/processing/processing/issues/4738 */ - private void checkLocalHost() throws SketchException { + static private void checkLocalHost() throws SketchException { try { InetAddress address = InetAddress.getByName("localhost"); if (!address.getHostAddress().equals("127.0.0.1")) { From 79e890296743f27f6cbbb7d6d2e98bed0a13beb7 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 3 Feb 2017 12:06:03 -0500 Subject: [PATCH 234/917] minor cleaning --- .../gui/datatransfer/FileTextFieldTransferHandler.java | 2 +- .../tools/MovieMaker/src/processing/app/tools/MovieMaker.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/shared/tools/MovieMaker/src/ch/randelshofer/gui/datatransfer/FileTextFieldTransferHandler.java b/build/shared/tools/MovieMaker/src/ch/randelshofer/gui/datatransfer/FileTextFieldTransferHandler.java index 5288fe7a79..9e5ce36b06 100644 --- a/build/shared/tools/MovieMaker/src/ch/randelshofer/gui/datatransfer/FileTextFieldTransferHandler.java +++ b/build/shared/tools/MovieMaker/src/ch/randelshofer/gui/datatransfer/FileTextFieldTransferHandler.java @@ -84,7 +84,7 @@ public boolean importData(JComponent comp, Transferable t) { } try { - java.util.List list = (List) t.getTransferData(DataFlavor.javaFileListFlavor); + List list = (List) t.getTransferData(DataFlavor.javaFileListFlavor); if (list.size() > 0) { File file = (File) list.get(0); diff --git a/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java b/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java index 1823ea00cf..e3f559f3fd 100644 --- a/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java +++ b/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java @@ -694,7 +694,7 @@ private BufferedImage readImage(File file) { } - private void cannotRead(File file) { + static private void cannotRead(File file) { String path = file.getAbsolutePath(); String msg = Language.interpolate("movie_maker.error.cannot_read", path); System.err.println(msg); From 5656a2752d4be831864fea77773193c004735f4a Mon Sep 17 00:00:00 2001 From: Guillermo Perez Date: Tue, 7 Feb 2017 18:45:24 -0300 Subject: [PATCH 235/917] Update jna.txt comment The txt comment was out of date, so I changed the version number and pointed to maven folder/pom. --- app/lib/jna.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/lib/jna.txt b/app/lib/jna.txt index acc3f19fb3..4dbac83c25 100644 --- a/app/lib/jna.txt +++ b/app/lib/jna.txt @@ -1,2 +1,4 @@ -The JAR file is JNA 3.5.2 (presumably) downloaded from -https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna/3.5.2/ +The JAR file is JNA 4.2.0 + +You can find the corresponding file for Maven here: +https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna/4.2.0/ From 2a02adeb3ba2ce9c3a295f215212e802e2b91379 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 10 Feb 2017 15:59:27 -0500 Subject: [PATCH 236/917] working on ui zoom support for high-res Windows/Linux displays --- app/src/processing/app/BaseSplash.java | 2 +- app/src/processing/app/Mode.java | 2 +- app/src/processing/app/Settings.java | 1 + .../processing/app/contrib/ManagerTabs.java | 6 +- app/src/processing/app/ui/Editor.java | 10 +-- app/src/processing/app/ui/EditorButton.java | 9 ++- app/src/processing/app/ui/EditorFooter.java | 6 +- app/src/processing/app/ui/EditorHeader.java | 31 ++++---- app/src/processing/app/ui/EditorStatus.java | 14 ++-- app/src/processing/app/ui/EditorToolbar.java | 26 +++---- app/src/processing/app/ui/Toolkit.java | 71 +++++++++++++++++-- 11 files changed, 113 insertions(+), 65 deletions(-) diff --git a/app/src/processing/app/BaseSplash.java b/app/src/processing/app/BaseSplash.java index 39848de5ea..5dc125f6a1 100644 --- a/app/src/processing/app/BaseSplash.java +++ b/app/src/processing/app/BaseSplash.java @@ -9,7 +9,7 @@ public class BaseSplash { static public void main(String[] args) { try { - final boolean hidpi = Toolkit.highResDisplay(); + final boolean hidpi = Toolkit.highResImages(); final String filename = "lib/about-" + (hidpi ? 2 : 1) + "x.png"; File splashFile = Platform.getContentFile(filename); SplashWindow.splash(splashFile.toURI().toURL(), hidpi); diff --git a/app/src/processing/app/Mode.java b/app/src/processing/app/Mode.java index 54c5c1392a..c548844db1 100644 --- a/app/src/processing/app/Mode.java +++ b/app/src/processing/app/Mode.java @@ -753,7 +753,7 @@ public Image loadImage(String filename) { public Image loadImageX(String filename) { - final int res = Toolkit.highResDisplay() ? 2 : 1; + final int res = Toolkit.highResImages() ? 2 : 1; return loadImage(filename + "-" + res + "x.png"); } diff --git a/app/src/processing/app/Settings.java b/app/src/processing/app/Settings.java index 4b155a5edb..5dbfa99eeb 100644 --- a/app/src/processing/app/Settings.java +++ b/app/src/processing/app/Settings.java @@ -205,6 +205,7 @@ public Font getFont(String attr) { style |= Font.ITALIC; } int size = PApplet.parseInt(pieces[2], 12); + size = Toolkit.dpi(size); // replace bad font with the default from lib/preferences.txt if (replace) { diff --git a/app/src/processing/app/contrib/ManagerTabs.java b/app/src/processing/app/contrib/ManagerTabs.java index ad986a24a8..594be25053 100644 --- a/app/src/processing/app/contrib/ManagerTabs.java +++ b/app/src/processing/app/contrib/ManagerTabs.java @@ -217,11 +217,7 @@ public void paintComponent(Graphics screen) { sizeH = size.height; imageW = sizeW; imageH = sizeH; - if (Toolkit.highResDisplay()) { - offscreen = createImage(imageW*2, imageH*2); - } else { - offscreen = createImage(imageW, imageH); - } + offscreen = Toolkit.offscreenGraphics(this, imageW, imageH); } Graphics g = offscreen.getGraphics(); diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index fee7ae1813..f0ff783d97 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -43,7 +43,6 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; -import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Font; import java.awt.Frame; @@ -79,9 +78,9 @@ public abstract class Editor extends JFrame implements RunnerListener { protected EditorState state; protected Mode mode; - static public final int LEFT_GUTTER = 44; - static public final int RIGHT_GUTTER = 12; - static public final int GUTTER_MARGIN = 3; + static public final int LEFT_GUTTER = Toolkit.dpi(44); + static public final int RIGHT_GUTTER = Toolkit.dpi(12); + static public final int GUTTER_MARGIN = Toolkit.dpi(3); protected MarkerColumn errorColumn; @@ -350,7 +349,8 @@ public void caretUpdate(CaretEvent e) { // Set the minimum size for the editor window int minWidth = Preferences.getInteger("editor.window.width.min"); int minHeight = Preferences.getInteger("editor.window.height.min"); - setMinimumSize(new Dimension(minWidth, minHeight)); + //setMinimumSize(new Dimension(minWidth, minHeight)); + setMinimumSize(Toolkit.zoom(minWidth, minHeight)); // Bring back the general options for the editor applyPreferences(); diff --git a/app/src/processing/app/ui/EditorButton.java b/app/src/processing/app/ui/EditorButton.java index 8a115c5715..3b197acfa2 100644 --- a/app/src/processing/app/ui/EditorButton.java +++ b/app/src/processing/app/ui/EditorButton.java @@ -30,7 +30,7 @@ abstract public class EditorButton extends JComponent implements MouseListener, MouseMotionListener, ActionListener { - static public final int DIM = 30; + static public final int DIM = Toolkit.dpi(30); /** Button's description. */ protected String title; @@ -112,10 +112,13 @@ public void paintComponent(Graphics g) { } else if (rollover) { image = rolloverImage; } + int dim = getSize().width; // width == height if (gradient != null) { - g.drawImage(gradient, 0, 0, DIM, DIM, this); + //g.drawImage(gradient, 0, 0, DIM, DIM, this); + g.drawImage(gradient, 0, 0, dim, dim, this); } - g.drawImage(image, 0, 0, DIM, DIM, this); + //g.drawImage(image, 0, 0, DIM, DIM, this); + g.drawImage(image, 0, 0, dim, dim, this); } diff --git a/app/src/processing/app/ui/EditorFooter.java b/app/src/processing/app/ui/EditorFooter.java index 80c5c50dc0..f8a17aa2b5 100644 --- a/app/src/processing/app/ui/EditorFooter.java +++ b/app/src/processing/app/ui/EditorFooter.java @@ -229,11 +229,7 @@ public void paintComponent(Graphics screen) { sizeH = size.height; imageW = sizeW; imageH = sizeH; - if (Toolkit.highResDisplay()) { - offscreen = createImage(imageW*2, imageH*2); - } else { - offscreen = createImage(imageW, imageH); - } + offscreen = Toolkit.offscreenGraphics(this, imageW, imageH); } Graphics g = offscreen.getGraphics(); diff --git a/app/src/processing/app/ui/EditorHeader.java b/app/src/processing/app/ui/EditorHeader.java index e669314196..a688bfc4a2 100644 --- a/app/src/processing/app/ui/EditorHeader.java +++ b/app/src/processing/app/ui/EditorHeader.java @@ -44,26 +44,25 @@ */ public class EditorHeader extends JComponent { // height of this tab bar - static final int HIGH = 29; + static final int HIGH = Toolkit.dpi(29); - static final int ARROW_TAB_WIDTH = 18; - static final int ARROW_TOP = 11; - static final int ARROW_BOTTOM = 18; - static final int ARROW_WIDTH = 6; + static final int ARROW_TAB_WIDTH = Toolkit.dpi(18); + static final int ARROW_TOP = Toolkit.dpi(11); + static final int ARROW_BOTTOM = Toolkit.dpi(18); + static final int ARROW_WIDTH = Toolkit.dpi(6); - static final int CURVE_RADIUS = 6; + static final int CURVE_RADIUS = Toolkit.dpi(6); static final int TAB_TOP = 0; - static final int TAB_BOTTOM = 27; + static final int TAB_BOTTOM = Toolkit.dpi(27); // amount of extra space between individual tabs - static final int TAB_BETWEEN = 3; + static final int TAB_BETWEEN = Toolkit.dpi(3); // amount of margin on the left/right for the text on the tab - static final int TEXT_MARGIN = 16; + static final int TEXT_MARGIN = Toolkit.dpi(16); // width of the tab when no text visible // (total tab width will be this plus TEXT_MARGIN*2) - static final int NO_TEXT_WIDTH = 16; + static final int NO_TEXT_WIDTH = Toolkit.dpi(16); -// Color bgColor; Color textColor[] = new Color[2]; Color tabColor[] = new Color[2]; Color modifiedColor; @@ -185,11 +184,7 @@ public void paintComponent(Graphics screen) { sizeH = size.height; imageW = sizeW; imageH = sizeH; - if (Toolkit.highResDisplay()) { - offscreen = createImage(imageW*2, imageH*2); - } else { - offscreen = createImage(imageW, imageH); - } + offscreen = Toolkit.offscreenGraphics(this, imageW, imageH); } Graphics g = offscreen.getGraphics(); @@ -199,6 +194,7 @@ public void paintComponent(Graphics screen) { } Graphics2D g2 = Toolkit.prepareGraphics(g); + Toolkit.dpiStroke(g2); g.drawImage(gradient, 0, 0, imageW, imageH, this); @@ -265,7 +261,8 @@ public void paintComponent(Graphics screen) { g.setColor(tabColor[SELECTED]); // can't be done with lines, b/c retina leaves tiny hairlines g.fillRect(Editor.LEFT_GUTTER, TAB_BOTTOM, - editor.getTextArea().getWidth() - Editor.LEFT_GUTTER, 2); + editor.getTextArea().getWidth() - Editor.LEFT_GUTTER, + Toolkit.dpi(2)); // draw the tab for the menu g.setColor(tabColor[UNSELECTED]); diff --git a/app/src/processing/app/ui/EditorStatus.java b/app/src/processing/app/ui/EditorStatus.java index e59c726dd6..c71923e0da 100644 --- a/app/src/processing/app/ui/EditorStatus.java +++ b/app/src/processing/app/ui/EditorStatus.java @@ -47,9 +47,9 @@ * Panel just below the editing area that contains status messages. */ public class EditorStatus extends BasicSplitPaneDivider { //JPanel { - static final int HIGH = 28; + static final int HIGH = Toolkit.dpi(28); static final int LEFT_MARGIN = Editor.LEFT_GUTTER; - static final int RIGHT_MARGIN = 20; + static final int RIGHT_MARGIN = Toolkit.dpi(20); Color urlColor; Color[] fgColor; @@ -271,11 +271,7 @@ public void paint(Graphics screen) { sizeW = size.width; sizeH = size.height; - if (Toolkit.highResDisplay()) { - offscreen = createImage(sizeW*2, sizeH*2); - } else { - offscreen = createImage(sizeW, sizeH); - } + offscreen = Toolkit.offscreenGraphics(this, sizeW, sizeH); } Graphics g = offscreen.getGraphics(); @@ -332,11 +328,11 @@ public Dimension getPreferredSize() { public Dimension getMinimumSize() { - return new Dimension(300, HIGH); + return Toolkit.zoom(300, HIGH); } public Dimension getMaximumSize() { - return new Dimension(super.getMaximumSize().width, HIGH); + return Toolkit.zoom(super.getMaximumSize().width, HIGH); } } diff --git a/app/src/processing/app/ui/EditorToolbar.java b/app/src/processing/app/ui/EditorToolbar.java index 0af6c8a4c1..2d373ce34e 100644 --- a/app/src/processing/app/ui/EditorToolbar.java +++ b/app/src/processing/app/ui/EditorToolbar.java @@ -52,11 +52,11 @@ abstract public class EditorToolbar extends JPanel implements KeyListener { // haven't decided how to handle this/how to make public/consistency // for components/does it live in theme.txt - static final int HIGH = 53; + static final int HIGH = Toolkit.dpi(53); // horizontal gap between buttons - static final int GAP = 9; + static final int GAP = Toolkit.dpi(9); // corner radius on the mode selector - static final int RADIUS = 3; + static final int RADIUS = Toolkit.dpi(3); protected Editor editor; protected Base base; @@ -78,8 +78,7 @@ public EditorToolbar(Editor editor) { base = editor.getBase(); mode = editor.getMode(); - gradient = mode.makeGradient("toolbar", 400, HIGH); -// reverseGradient = mode.getGradient("reversed", 100, EditorButton.DIM); + gradient = mode.makeGradient("toolbar", Toolkit.dpi(400), HIGH); rebuild(); } @@ -286,11 +285,11 @@ class ModeSelector extends JPanel { int titleAscent; int titleWidth; - final int MODE_GAP_WIDTH = 13; - final int ARROW_GAP_WIDTH = 6; - final int ARROW_WIDTH = 6; - final int ARROW_TOP = 12; - final int ARROW_BOTTOM = 18; + final int MODE_GAP_WIDTH = Toolkit.dpi(13); + final int ARROW_GAP_WIDTH = Toolkit.dpi(6); + final int ARROW_WIDTH = Toolkit.dpi(6); + final int ARROW_TOP = Toolkit.dpi(12); + final int ARROW_BOTTOM = Toolkit.dpi(18); int[] triangleX = new int[3]; int[] triangleY = new int[] { ARROW_TOP, ARROW_TOP, ARROW_BOTTOM }; @@ -328,11 +327,7 @@ public void paintComponent(Graphics screen) { Dimension size = getSize(); width = 0; if (width != size.width || height != size.height) { - if (Toolkit.highResDisplay()) { - offscreen = createImage(size.width*2, size.height*2); - } else { - offscreen = createImage(size.width, size.height); - } + offscreen = Toolkit.offscreenGraphics(this, size.width, size.height); width = size.width; height = size.height; } @@ -357,6 +352,7 @@ public void paintComponent(Graphics screen) { // draw the outline for this feller g.setColor(outlineColor); + Toolkit.dpiStroke(g2); g2.draw(Toolkit.createRoundRect(1, 1, width-1, height-1, RADIUS, RADIUS, RADIUS, RADIUS)); diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index cbc7f82207..7f4b0c3e56 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -21,6 +21,7 @@ package processing.app.ui; +import java.awt.BasicStroke; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; @@ -494,7 +495,7 @@ static public ImageIcon getIconX(File dir, String base) { * a hidpi display, get the NN*2 version automatically, sized at NN */ static public ImageIcon getIconX(File dir, String base, int size) { - final int scale = Toolkit.highResDisplay() ? 2 : 1; + final int scale = Toolkit.highResImages() ? 2 : 1; String filename = (size == 0) ? (base + "-" + scale + "x.png") : (base + "-" + (size*scale) + ".png"); @@ -734,6 +735,13 @@ static public Clipboard getSystemClipboard() { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + static public Image offscreenGraphics(Component comp, int width, int height) { + int m = Toolkit.isRetina() ? 2 : 1; + //return comp.createImage(m * dpi(width), m * dpi(height)); + return comp.createImage(m * width, m * height); + } + + /** * Handles scaling for high-res displays, also sets text anti-aliasing * options to be far less ugly than the defaults. @@ -743,15 +751,17 @@ static public Clipboard getSystemClipboard() { static public Graphics2D prepareGraphics(Graphics g) { Graphics2D g2 = (Graphics2D) g; - if (Toolkit.highResDisplay()) { + //float z = zoom * (Toolkit.isRetina() ? 2 : 1); + if (Toolkit.isRetina()) { // scale everything 2x, will be scaled down when drawn to the screen g2.scale(2, 2); } + //g2.scale(z, z); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - if (Toolkit.highResDisplay()) { + if (Toolkit.isRetina()) { // Looks great on retina, not so great (with our font) on 1x g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); @@ -794,10 +804,63 @@ static public Graphics2D prepareGraphics(Graphics g) { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + static float zoom = 3; + + + /* + // http://stackoverflow.com/a/35029265 + static public void zoomSwingFonts() { + Set keySet = UIManager.getLookAndFeelDefaults().keySet(); + Object[] keys = keySet.toArray(new Object[keySet.size()]); + + for (Object key : keys) { + if (key != null && key.toString().toLowerCase().contains("font")) { + System.out.println(key); + Font font = UIManager.getDefaults().getFont(key); + if (font != null) { + font = font.deriveFont(font.getSize() * zoom); + UIManager.put(key, font); + } + } + } + } + */ + + + static public int dpi(int pixels) { + return (int) (zoom * pixels); + } + + + static BasicStroke dpiStroke; + + static public void dpiStroke(Graphics2D g2) { + if (zoom != 1) { + if (dpiStroke == null || dpiStroke.getLineWidth() != zoom) { + dpiStroke = new BasicStroke(zoom); + } + g2.setStroke(dpiStroke); + } + } + + + static Dimension zoom(int w, int h) { + return new Dimension(dpi(w), dpi(h)); + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + static Boolean highResProp; - static public boolean highResDisplay() { + static public boolean highResImages() { + return isRetina() || (zoom > 1); + } + + + static public boolean isRetina() { if (highResProp == null) { highResProp = checkRetina(); } From bc2826cb41163a9c789593aa564cdf82bc36d981 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 10 Feb 2017 16:02:55 -0500 Subject: [PATCH 237/917] let's call this 'zoom' instead, since it's not really dpi at all --- app/src/processing/app/Settings.java | 2 +- .../app/syntax/TextAreaPainter.java | 2 +- app/src/processing/app/ui/Editor.java | 6 ++--- app/src/processing/app/ui/EditorButton.java | 2 +- app/src/processing/app/ui/EditorHeader.java | 22 +++++++++---------- app/src/processing/app/ui/EditorStatus.java | 4 ++-- app/src/processing/app/ui/EditorToolbar.java | 18 +++++++-------- app/src/processing/app/ui/Toolkit.java | 4 ++-- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/app/src/processing/app/Settings.java b/app/src/processing/app/Settings.java index 5dbfa99eeb..efd016f231 100644 --- a/app/src/processing/app/Settings.java +++ b/app/src/processing/app/Settings.java @@ -205,7 +205,7 @@ public Font getFont(String attr) { style |= Font.ITALIC; } int size = PApplet.parseInt(pieces[2], 12); - size = Toolkit.dpi(size); + size = Toolkit.zoom(size); // replace bad font with the default from lib/preferences.txt if (replace) { diff --git a/app/src/processing/app/syntax/TextAreaPainter.java b/app/src/processing/app/syntax/TextAreaPainter.java index fd7c23da2f..7919c0ecf3 100644 --- a/app/src/processing/app/syntax/TextAreaPainter.java +++ b/app/src/processing/app/syntax/TextAreaPainter.java @@ -123,7 +123,7 @@ public void updateAppearance() { Toolkit.getMonoFontName(); String fontFamily = Preferences.get("editor.font.family"); - int fontSize = Preferences.getInteger("editor.font.size"); + final int fontSize = Toolkit.zoom(Preferences.getInteger("editor.font.size")); plainFont = new Font(fontFamily, Font.PLAIN, fontSize); if (!fontFamily.equals(plainFont.getFamily())) { System.err.println(fontFamily + " not available, resetting to monospaced"); diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index f0ff783d97..2abf0d4b0e 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -78,9 +78,9 @@ public abstract class Editor extends JFrame implements RunnerListener { protected EditorState state; protected Mode mode; - static public final int LEFT_GUTTER = Toolkit.dpi(44); - static public final int RIGHT_GUTTER = Toolkit.dpi(12); - static public final int GUTTER_MARGIN = Toolkit.dpi(3); + static public final int LEFT_GUTTER = Toolkit.zoom(44); + static public final int RIGHT_GUTTER = Toolkit.zoom(12); + static public final int GUTTER_MARGIN = Toolkit.zoom(3); protected MarkerColumn errorColumn; diff --git a/app/src/processing/app/ui/EditorButton.java b/app/src/processing/app/ui/EditorButton.java index 3b197acfa2..0e848efb67 100644 --- a/app/src/processing/app/ui/EditorButton.java +++ b/app/src/processing/app/ui/EditorButton.java @@ -30,7 +30,7 @@ abstract public class EditorButton extends JComponent implements MouseListener, MouseMotionListener, ActionListener { - static public final int DIM = Toolkit.dpi(30); + static public final int DIM = Toolkit.zoom(30); /** Button's description. */ protected String title; diff --git a/app/src/processing/app/ui/EditorHeader.java b/app/src/processing/app/ui/EditorHeader.java index a688bfc4a2..3c1c410db6 100644 --- a/app/src/processing/app/ui/EditorHeader.java +++ b/app/src/processing/app/ui/EditorHeader.java @@ -44,24 +44,24 @@ */ public class EditorHeader extends JComponent { // height of this tab bar - static final int HIGH = Toolkit.dpi(29); + static final int HIGH = Toolkit.zoom(29); - static final int ARROW_TAB_WIDTH = Toolkit.dpi(18); - static final int ARROW_TOP = Toolkit.dpi(11); - static final int ARROW_BOTTOM = Toolkit.dpi(18); - static final int ARROW_WIDTH = Toolkit.dpi(6); + static final int ARROW_TAB_WIDTH = Toolkit.zoom(18); + static final int ARROW_TOP = Toolkit.zoom(11); + static final int ARROW_BOTTOM = Toolkit.zoom(18); + static final int ARROW_WIDTH = Toolkit.zoom(6); - static final int CURVE_RADIUS = Toolkit.dpi(6); + static final int CURVE_RADIUS = Toolkit.zoom(6); static final int TAB_TOP = 0; - static final int TAB_BOTTOM = Toolkit.dpi(27); + static final int TAB_BOTTOM = Toolkit.zoom(27); // amount of extra space between individual tabs - static final int TAB_BETWEEN = Toolkit.dpi(3); + static final int TAB_BETWEEN = Toolkit.zoom(3); // amount of margin on the left/right for the text on the tab - static final int TEXT_MARGIN = Toolkit.dpi(16); + static final int TEXT_MARGIN = Toolkit.zoom(16); // width of the tab when no text visible // (total tab width will be this plus TEXT_MARGIN*2) - static final int NO_TEXT_WIDTH = Toolkit.dpi(16); + static final int NO_TEXT_WIDTH = Toolkit.zoom(16); Color textColor[] = new Color[2]; Color tabColor[] = new Color[2]; @@ -262,7 +262,7 @@ public void paintComponent(Graphics screen) { // can't be done with lines, b/c retina leaves tiny hairlines g.fillRect(Editor.LEFT_GUTTER, TAB_BOTTOM, editor.getTextArea().getWidth() - Editor.LEFT_GUTTER, - Toolkit.dpi(2)); + Toolkit.zoom(2)); // draw the tab for the menu g.setColor(tabColor[UNSELECTED]); diff --git a/app/src/processing/app/ui/EditorStatus.java b/app/src/processing/app/ui/EditorStatus.java index c71923e0da..fd97751acf 100644 --- a/app/src/processing/app/ui/EditorStatus.java +++ b/app/src/processing/app/ui/EditorStatus.java @@ -47,9 +47,9 @@ * Panel just below the editing area that contains status messages. */ public class EditorStatus extends BasicSplitPaneDivider { //JPanel { - static final int HIGH = Toolkit.dpi(28); + static final int HIGH = Toolkit.zoom(28); static final int LEFT_MARGIN = Editor.LEFT_GUTTER; - static final int RIGHT_MARGIN = Toolkit.dpi(20); + static final int RIGHT_MARGIN = Toolkit.zoom(20); Color urlColor; Color[] fgColor; diff --git a/app/src/processing/app/ui/EditorToolbar.java b/app/src/processing/app/ui/EditorToolbar.java index 2d373ce34e..8507c0de2e 100644 --- a/app/src/processing/app/ui/EditorToolbar.java +++ b/app/src/processing/app/ui/EditorToolbar.java @@ -52,11 +52,11 @@ abstract public class EditorToolbar extends JPanel implements KeyListener { // haven't decided how to handle this/how to make public/consistency // for components/does it live in theme.txt - static final int HIGH = Toolkit.dpi(53); + static final int HIGH = Toolkit.zoom(53); // horizontal gap between buttons - static final int GAP = Toolkit.dpi(9); + static final int GAP = Toolkit.zoom(9); // corner radius on the mode selector - static final int RADIUS = Toolkit.dpi(3); + static final int RADIUS = Toolkit.zoom(3); protected Editor editor; protected Base base; @@ -78,7 +78,7 @@ public EditorToolbar(Editor editor) { base = editor.getBase(); mode = editor.getMode(); - gradient = mode.makeGradient("toolbar", Toolkit.dpi(400), HIGH); + gradient = mode.makeGradient("toolbar", Toolkit.zoom(400), HIGH); rebuild(); } @@ -285,11 +285,11 @@ class ModeSelector extends JPanel { int titleAscent; int titleWidth; - final int MODE_GAP_WIDTH = Toolkit.dpi(13); - final int ARROW_GAP_WIDTH = Toolkit.dpi(6); - final int ARROW_WIDTH = Toolkit.dpi(6); - final int ARROW_TOP = Toolkit.dpi(12); - final int ARROW_BOTTOM = Toolkit.dpi(18); + final int MODE_GAP_WIDTH = Toolkit.zoom(13); + final int ARROW_GAP_WIDTH = Toolkit.zoom(6); + final int ARROW_WIDTH = Toolkit.zoom(6); + final int ARROW_TOP = Toolkit.zoom(12); + final int ARROW_BOTTOM = Toolkit.zoom(18); int[] triangleX = new int[3]; int[] triangleY = new int[] { ARROW_TOP, ARROW_TOP, ARROW_BOTTOM }; diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 7f4b0c3e56..53e6a9f449 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -827,7 +827,7 @@ static public void zoomSwingFonts() { */ - static public int dpi(int pixels) { + static public int zoom(int pixels) { return (int) (zoom * pixels); } @@ -845,7 +845,7 @@ static public void dpiStroke(Graphics2D g2) { static Dimension zoom(int w, int h) { - return new Dimension(dpi(w), dpi(h)); + return new Dimension(zoom(w), zoom(h)); } From 90fbe14ac8df1e3ba4ed82aa1b46b6ca29f16ff0 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 10 Feb 2017 16:16:58 -0500 Subject: [PATCH 238/917] fix the twice-doubled status bar --- app/src/processing/app/ui/Editor.java | 10 ++++++---- app/src/processing/app/ui/EditorStatus.java | 4 ++-- app/src/processing/app/ui/Toolkit.java | 2 ++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 2abf0d4b0e..bb654d5f27 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -43,6 +43,7 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; +import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Font; import java.awt.Frame; @@ -347,10 +348,11 @@ public void caretUpdate(CaretEvent e) { state.apply(this); // Set the minimum size for the editor window - int minWidth = Preferences.getInteger("editor.window.width.min"); - int minHeight = Preferences.getInteger("editor.window.height.min"); - //setMinimumSize(new Dimension(minWidth, minHeight)); - setMinimumSize(Toolkit.zoom(minWidth, minHeight)); + int minWidth = + Toolkit.zoom(Preferences.getInteger("editor.window.width.min")); + int minHeight = + Toolkit.zoom(Preferences.getInteger("editor.window.height.min")); + setMinimumSize(new Dimension(minWidth, minHeight)); // Bring back the general options for the editor applyPreferences(); diff --git a/app/src/processing/app/ui/EditorStatus.java b/app/src/processing/app/ui/EditorStatus.java index fd97751acf..3a24432961 100644 --- a/app/src/processing/app/ui/EditorStatus.java +++ b/app/src/processing/app/ui/EditorStatus.java @@ -328,11 +328,11 @@ public Dimension getPreferredSize() { public Dimension getMinimumSize() { - return Toolkit.zoom(300, HIGH); + return new Dimension(Toolkit.zoom(300), HIGH); } public Dimension getMaximumSize() { - return Toolkit.zoom(super.getMaximumSize().width, HIGH); + return new Dimension(super.getMaximumSize().width, HIGH); } } diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 53e6a9f449..40f7d7437b 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -844,9 +844,11 @@ static public void dpiStroke(Graphics2D g2) { } + /* static Dimension zoom(int w, int h) { return new Dimension(zoom(w), zoom(h)); } + */ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . From 66fce8f45bd85922e712307275858c1ef0557451 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 10 Feb 2017 16:20:22 -0500 Subject: [PATCH 239/917] move stroke into centralized location --- app/src/processing/app/ui/EditorHeader.java | 2 +- app/src/processing/app/ui/EditorToolbar.java | 2 +- app/src/processing/app/ui/Toolkit.java | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/processing/app/ui/EditorHeader.java b/app/src/processing/app/ui/EditorHeader.java index 3c1c410db6..7fba02d21a 100644 --- a/app/src/processing/app/ui/EditorHeader.java +++ b/app/src/processing/app/ui/EditorHeader.java @@ -194,7 +194,7 @@ public void paintComponent(Graphics screen) { } Graphics2D g2 = Toolkit.prepareGraphics(g); - Toolkit.dpiStroke(g2); +// Toolkit.dpiStroke(g2); g.drawImage(gradient, 0, 0, imageW, imageH, this); diff --git a/app/src/processing/app/ui/EditorToolbar.java b/app/src/processing/app/ui/EditorToolbar.java index 8507c0de2e..6d192d7370 100644 --- a/app/src/processing/app/ui/EditorToolbar.java +++ b/app/src/processing/app/ui/EditorToolbar.java @@ -352,7 +352,7 @@ public void paintComponent(Graphics screen) { // draw the outline for this feller g.setColor(outlineColor); - Toolkit.dpiStroke(g2); + //Toolkit.dpiStroke(g2); g2.draw(Toolkit.createRoundRect(1, 1, width-1, height-1, RADIUS, RADIUS, RADIUS, RADIUS)); diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 40f7d7437b..137b94eca4 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -766,6 +766,7 @@ static public Graphics2D prepareGraphics(Graphics g) { g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); } + zoomStroke(g2); return g2; } @@ -832,14 +833,14 @@ static public int zoom(int pixels) { } - static BasicStroke dpiStroke; + static BasicStroke zoomStroke; - static public void dpiStroke(Graphics2D g2) { + static private void zoomStroke(Graphics2D g2) { if (zoom != 1) { - if (dpiStroke == null || dpiStroke.getLineWidth() != zoom) { - dpiStroke = new BasicStroke(zoom); + if (zoomStroke == null || zoomStroke.getLineWidth() != zoom) { + zoomStroke = new BasicStroke(zoom); } - g2.setStroke(dpiStroke); + g2.setStroke(zoomStroke); } } From c0b24c69fc073d154cdcc9da625840fd5ec06728 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 10 Feb 2017 16:30:02 -0500 Subject: [PATCH 240/917] rename retina prop based on actual use --- app/src/processing/app/ui/Toolkit.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 137b94eca4..31370b3d1d 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -735,6 +735,10 @@ static public Clipboard getSystemClipboard() { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + /** + * Create an Image to be used as an offscreen drawing context, + * automatically doubling the size if running on a retina display. + */ static public Image offscreenGraphics(Component comp, int width, int height) { int m = Toolkit.isRetina() ? 2 : 1; //return comp.createImage(m * dpi(width), m * dpi(height)); @@ -855,7 +859,9 @@ static Dimension zoom(int w, int h) { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - static Boolean highResProp; + // Changed to retinaProp instead of highResProp because only Mac + // "retina" displays use this mechanism for high-resolution scaling. + static Boolean retinaProp; static public boolean highResImages() { @@ -864,10 +870,10 @@ static public boolean highResImages() { static public boolean isRetina() { - if (highResProp == null) { - highResProp = checkRetina(); + if (retinaProp == null) { + retinaProp = checkRetina(); } - return highResProp; + return retinaProp; } From ae3cd5ff539e39cbd4d1b17c76871e8144e9159e Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 10 Feb 2017 16:30:14 -0500 Subject: [PATCH 241/917] fix the bottom bar and its tabs --- app/src/processing/app/ui/EditorFooter.java | 36 +++++++++------------ 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/app/src/processing/app/ui/EditorFooter.java b/app/src/processing/app/ui/EditorFooter.java index f8a17aa2b5..4abd04c51c 100644 --- a/app/src/processing/app/ui/EditorFooter.java +++ b/app/src/processing/app/ui/EditorFooter.java @@ -50,21 +50,21 @@ */ public class EditorFooter extends Box { // height of this tab bar - static final int HIGH = 32; + static final int HIGH = Toolkit.zoom(32); - static final int CURVE_RADIUS = 6; + static final int CURVE_RADIUS = Toolkit.zoom(6); - static final int TAB_TOP = 2; - static final int TAB_BOTTOM = 29; + static final int TAB_TOP = Toolkit.zoom(2); + static final int TAB_BOTTOM = Toolkit.zoom(29); // amount of extra space between individual tabs - static final int TAB_BETWEEN = 2; + static final int TAB_BETWEEN = Toolkit.zoom(2); // amount of margin on the left/right for the text on the tab - static final int MARGIN = 14; + static final int MARGIN = Toolkit.zoom(14); - static final int ICON_WIDTH = 16; - static final int ICON_HEIGHT = 16; - static final int ICON_TOP = 7; - static final int ICON_MARGIN = 7; + static final int ICON_WIDTH = Toolkit.zoom(16); + static final int ICON_HEIGHT = Toolkit.zoom(16); + static final int ICON_TOP = Toolkit.zoom(7); + static final int ICON_MARGIN = Toolkit.zoom(7); static final int UNSELECTED = 0; static final int SELECTED = 1; @@ -241,9 +241,10 @@ public void paintComponent(Graphics screen) { Graphics2D g2 = Toolkit.prepareGraphics(g); g.setColor(tabColor[SELECTED]); - g.fillRect(0, 0, imageW, 2); + // can't be done with lines, b/c retina leaves tiny hairlines + g.fillRect(0, 0, imageW, Toolkit.zoom(2)); - g.drawImage(gradient, 0, 2, imageW, imageH, this); + g.drawImage(gradient, 0, Toolkit.zoom(2), imageW, imageH, this); // reset all tab positions for (Tab tab : tabs) { @@ -254,14 +255,9 @@ public void paintComponent(Graphics screen) { // now actually draw the tabs drawTabs(Editor.LEFT_GUTTER, g2); + // the number of updates available in the Manager drawUpdates(g2); -// // draw the two pixel line that extends left/right below the tabs -// g.setColor(tabColor[SELECTED]); -// // can't be done with lines, b/c retina leaves tiny hairlines -// g.fillRect(Editor.LEFT_GUTTER, TAB_BOTTOM, -// editor.getTextArea().getWidth() - Editor.LEFT_GUTTER, 2); - screen.drawImage(offscreen, 0, 0, imageW, imageH, null); } @@ -291,7 +287,7 @@ private void drawTabs(int left, Graphics2D g) { private void drawUpdates(Graphics2D g2) { if (updateCount != 0) { FontRenderContext frc = g2.getFontRenderContext(); - final int GAP = 5; + final int GAP = Toolkit.zoom(5); final String updateLabel = "Updates"; String updatesStr = "" + updateCount; double countWidth = font.getStringBounds(updatesStr, frc).getWidth(); @@ -315,7 +311,7 @@ private void drawUpdates(Graphics2D g2) { public Dimension getPreferredSize() { - return new Dimension(300, HIGH); + return new Dimension(Toolkit.zoom(300), HIGH); } From d55baaf27ee9e0f4b076e9309137e81a5757b8bf Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 10 Feb 2017 16:52:26 -0500 Subject: [PATCH 242/917] border in pixels --- app/src/processing/app/ui/PreferencesFrame.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/ui/PreferencesFrame.java b/app/src/processing/app/ui/PreferencesFrame.java index f475f6bf3e..5e5393a0ed 100644 --- a/app/src/processing/app/ui/PreferencesFrame.java +++ b/app/src/processing/app/ui/PreferencesFrame.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2012-15 The Processing Foundation + Copyright (c) 2012-17 The Processing Foundation Copyright (c) 2004-12 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology @@ -96,7 +96,7 @@ public PreferencesFrame(Base base) { pain.setLayout(layout); - final int BORDER = Platform.isMacOS() ? 20 : 13; + final int BORDER = Toolkit.zoom(Platform.isMacOS() ? 20 : 13); JLabel sketchbookLocationLabel, restartProcessingLabel; JButton browseButton; //, button2; From 58704051065fb2312cda97d18ec0f814bfe96131 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 10 Feb 2017 17:27:05 -0500 Subject: [PATCH 243/917] add preference to set the zoom factor --- .../processing/app/ui/PreferencesFrame.java | 31 ++++++++++++++++--- app/src/processing/app/ui/Toolkit.java | 2 +- build/shared/lib/languages/PDE.properties | 1 + 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/app/src/processing/app/ui/PreferencesFrame.java b/app/src/processing/app/ui/PreferencesFrame.java index 5e5393a0ed..f0e5d9a348 100644 --- a/app/src/processing/app/ui/PreferencesFrame.java +++ b/app/src/processing/app/ui/PreferencesFrame.java @@ -49,6 +49,7 @@ public class PreferencesFrame { GroupLayout layout; static final Integer[] FONT_SIZES = { 10, 12, 14, 18, 24, 36, 48 }; + static final String[] ZOOM_OPTIONS = { "100%", "150%", "200%", "300%" }; JTextField sketchbookLocationField; JTextField presentColor; @@ -71,6 +72,7 @@ public class PreferencesFrame { JCheckBox importSuggestionsBox; //JCheckBox codeCompletionTriggerBox; + JComboBox zoomSelectionBox; JComboBox displaySelectionBox; JComboBox languageSelectionBox; @@ -98,7 +100,9 @@ public PreferencesFrame(Base base) { final int BORDER = Toolkit.zoom(Platform.isMacOS() ? 20 : 13); - JLabel sketchbookLocationLabel, restartProcessingLabel; + JLabel sketchbookLocationLabel; + JLabel languageRestartLabel; + JLabel zoomRestartLabel; JButton browseButton; //, button2; @@ -135,7 +139,7 @@ public void actionPerformed(ActionEvent e) { } } languageSelectionBox.setModel(new DefaultComboBoxModel(languageSelection)); - restartProcessingLabel = new JLabel(" (" + Language.text("preferences.requires_restart") + ")"); + languageRestartLabel = new JLabel(" (" + Language.text("preferences.requires_restart") + ")"); // Editor and console font [ Source Code Pro ] @@ -158,6 +162,17 @@ public void actionPerformed(ActionEvent e) { consoleFontSizeField = new JComboBox(FONT_SIZES); fontSizeField.setSelectedItem(Preferences.getFont("editor.font.size")); + + // Interface scale: [ 100% ] (requires restart of Processing) + + JLabel zoomLabel = new JLabel(Language.text("preferences.zoom") + ": "); + zoomSelectionBox = new JComboBox(); + zoomSelectionBox.setModel(new DefaultComboBoxModel(ZOOM_OPTIONS)); + zoomRestartLabel = new JLabel(" (" + Language.text("preferences.requires_restart") + ")"); + + + // + JLabel backgroundColorLabel = new JLabel(Language.text("preferences.background_color")+": "); final String colorTip = "" + Language.text("preferences.background_color.tip"); @@ -392,7 +407,7 @@ public void actionPerformed(ActionEvent e) { .addGroup(layout.createSequentialGroup() .addComponent(languageLabel) .addComponent(languageSelectionBox,GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) // This makes the component non-resizable in the X direction - .addComponent(restartProcessingLabel)) + .addComponent(languageRestartLabel)) .addGroup(layout.createSequentialGroup() .addComponent(fontLabel) .addComponent(fontSelectionBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) @@ -402,6 +417,10 @@ public void actionPerformed(ActionEvent e) { .addComponent(fontSizeField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(consoleFontSizeLabel) .addComponent(consoleFontSizeField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(zoomLabel) + .addComponent(zoomSelectionBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(zoomRestartLabel)) .addGroup(layout.createSequentialGroup() .addComponent(backgroundColorLabel) .addComponent(hashLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) @@ -452,7 +471,7 @@ public void actionPerformed(ActionEvent e) { .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER) .addComponent(languageLabel) .addComponent(languageSelectionBox) - .addComponent(restartProcessingLabel)) + .addComponent(languageRestartLabel)) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER). addComponent(fontLabel) .addComponent(fontSelectionBox)) @@ -461,6 +480,10 @@ public void actionPerformed(ActionEvent e) { .addComponent(fontSizeField) .addComponent(consoleFontSizeLabel) .addComponent(consoleFontSizeField)) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER) + .addComponent(zoomLabel) + .addComponent(zoomSelectionBox) + .addComponent(zoomRestartLabel)) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER) .addComponent(backgroundColorLabel) .addComponent(hashLabel) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 31370b3d1d..73cf3fbfe6 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -111,7 +111,7 @@ public class Toolkit { static public int getButtonWidth() { // Made into a method so that calling Toolkit methods doesn't require // the languages to be loaded, and with that, Base initialized completely - return Integer.parseInt(Language.text("preferences.button.width")); + return zoom(Integer.parseInt(Language.text("preferences.button.width"))); } diff --git a/build/shared/lib/languages/PDE.properties b/build/shared/lib/languages/PDE.properties index f1c3eedb14..d69ec6be17 100644 --- a/build/shared/lib/languages/PDE.properties +++ b/build/shared/lib/languages/PDE.properties @@ -166,6 +166,7 @@ preferences.editor_and_console_font = Editor and Console font preferences.editor_and_console_font.tip = Select the font used in the Editor and the Console.
    Only monospaced (fixed-width) fonts may be used,
    though the list may be imperfect. preferences.editor_font_size = Editor font size preferences.console_font_size = Console font size +preferences.zoom = Interface scale preferences.background_color = Background color when Presenting preferences.background_color.tip = Select the background color used when using Present.
    Present is used to present a sketch in full-screen,
    accessible from the Sketch menu. preferences.use_smooth_text = Use smooth text in editor window From e976cb542a54c76b84767d23f70d00b8bed05c7d Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 10 Feb 2017 17:43:21 -0500 Subject: [PATCH 244/917] add gui for setting the zoom level --- .../processing/app/ui/PreferencesFrame.java | 14 +++++++++-- app/src/processing/app/ui/Toolkit.java | 23 ++++++++++++++++++- build/shared/lib/defaults.txt | 3 +++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/app/src/processing/app/ui/PreferencesFrame.java b/app/src/processing/app/ui/PreferencesFrame.java index f0e5d9a348..d0ad96de65 100644 --- a/app/src/processing/app/ui/PreferencesFrame.java +++ b/app/src/processing/app/ui/PreferencesFrame.java @@ -49,7 +49,6 @@ public class PreferencesFrame { GroupLayout layout; static final Integer[] FONT_SIZES = { 10, 12, 14, 18, 24, 36, 48 }; - static final String[] ZOOM_OPTIONS = { "100%", "150%", "200%", "300%" }; JTextField sketchbookLocationField; JTextField presentColor; @@ -167,7 +166,7 @@ public void actionPerformed(ActionEvent e) { JLabel zoomLabel = new JLabel(Language.text("preferences.zoom") + ": "); zoomSelectionBox = new JComboBox(); - zoomSelectionBox.setModel(new DefaultComboBoxModel(ZOOM_OPTIONS)); + zoomSelectionBox.setModel(new DefaultComboBoxModel(Toolkit.zoomOptions.array())); zoomRestartLabel = new JLabel(" (" + Language.text("preferences.requires_restart") + ")"); @@ -658,6 +657,9 @@ protected void applyFrame() { fontSizeField.setSelectedItem(Preferences.getInteger("editor.font.size")); } + Preferences.set("editor.zoom", + String.valueOf(zoomSelectionBox.getSelectedItem())); + try { Object selection = consoleFontSizeField.getSelectedItem(); if (selection instanceof String) { @@ -727,6 +729,14 @@ public void run() { fontSizeField.setSelectedItem(Preferences.getInteger("editor.font.size")); consoleFontSizeField.setSelectedItem(Preferences.getInteger("console.font.size")); + String zoomSel = Preferences.get("editor.zoom"); + int zoomIndex = Toolkit.zoomOptions.index(zoomSel); + if (zoomIndex != -1) { + zoomSelectionBox.setSelectedIndex(zoomIndex); + } else { + zoomSelectionBox.setSelectedIndex(0); + } + presentColor.setBackground(Preferences.getColor("run.present.bgcolor")); presentColorHex.setText(Preferences.get("run.present.bgcolor").substring(1)); diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 73cf3fbfe6..75270f058a 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -75,6 +75,7 @@ import processing.app.Platform; import processing.app.Preferences; import processing.app.Util; +import processing.core.PApplet; import processing.data.StringList; @@ -809,7 +810,7 @@ static public Graphics2D prepareGraphics(Graphics g) { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - static float zoom = 3; + static float zoom = 0; /* @@ -832,11 +833,31 @@ static public void zoomSwingFonts() { */ + static final StringList zoomOptions = + new StringList("100%", "150%", "200%", "300%"); + static public int zoom(int pixels) { + if (zoom == 0) { + zoom = parseZoom(); + } return (int) (zoom * pixels); } + static private float parseZoom() { + String zoomSel = Preferences.get("editor.zoom"); + if (zoomOptions.hasValue(zoomSel)) { + // shave off the % symbol at the end + zoomSel = zoomSel.substring(0, zoomSel.length() - 1); + return PApplet.parseInt(zoomSel, 100) / 100f; + + } else { + Preferences.set("editor.zoom", "100%"); + return 1; + } + } + + static BasicStroke zoomStroke; static private void zoomStroke(Graphics2D g2) { diff --git a/build/shared/lib/defaults.txt b/build/shared/lib/defaults.txt index f5380d3598..1c25c57b2b 100644 --- a/build/shared/lib/defaults.txt +++ b/build/shared/lib/defaults.txt @@ -105,6 +105,9 @@ editor.window.height.min.windows = 530 # tested with Raspberry Pi display editor.window.height.min.linux = 480 +# scaling for the interface (to handle Windows and Linux HiDPI displays) +editor.zoom = 100% + # font size for editor #editor.font = Monospaced,plain,12 # Monaco is nicer on Mac OS X, so use that explicitly From 95d396fd8b86857b9bd3ebd9a61855ed40a1c6c4 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 12:29:49 -0500 Subject: [PATCH 245/917] add system dpi method from Arduino --- .../app/platform/DefaultPlatform.java | 8 ++ .../app/platform/WindowsPlatform.java | 106 +++++++++--------- 2 files changed, 63 insertions(+), 51 deletions(-) diff --git a/app/src/processing/app/platform/DefaultPlatform.java b/app/src/processing/app/platform/DefaultPlatform.java index f3b47425b3..58529b516f 100644 --- a/app/src/processing/app/platform/DefaultPlatform.java +++ b/app/src/processing/app/platform/DefaultPlatform.java @@ -153,4 +153,12 @@ public int unsetenv(String variable) { CLibrary clib = CLibrary.INSTANCE; return clib.unsetenv(variable); } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + public int getSystemDPI() { + return 96; + } } diff --git a/app/src/processing/app/platform/WindowsPlatform.java b/app/src/processing/app/platform/WindowsPlatform.java index c19d14a1a1..4ff87e44c8 100644 --- a/app/src/processing/app/platform/WindowsPlatform.java +++ b/app/src/processing/app/platform/WindowsPlatform.java @@ -28,8 +28,11 @@ import com.sun.jna.Library; import com.sun.jna.Native; +import com.sun.jna.Pointer; import com.sun.jna.platform.win32.Shell32Util; import com.sun.jna.platform.win32.ShlObj; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; import processing.app.Base; import processing.app.Messages; @@ -602,56 +605,57 @@ public int unsetenv(String variable) { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - // JNA code for using SHGetFolderPath to fix Issue 410 - // https://code.google.com/p/processing/issues/detail?id=410 - // Based on answer provided by McDowell at - // http://stackoverflow.com/questions/585534/what-is-the-best-way-to-find-the-users-home-directory-in-java/586917#586917 -// private static Map OPTIONS = new HashMap(); -// -// static { -// OPTIONS.put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE); -// OPTIONS.put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE); -// } -// -// -// static class HANDLE extends PointerType implements NativeMapped { -// public HANDLE() { } -// } -// -// static class HWND extends HANDLE { } -// -// -// public interface Shell32 extends Library { -// -// public static final int MAX_PATH = 260; -// public static final int SHGFP_TYPE_CURRENT = 0; -// public static final int SHGFP_TYPE_DEFAULT = 1; -// public static final int S_OK = 0; -// -// // KNOWNFOLDERIDs are preferred to CSDIL values -// // but Windows XP only supports CSDIL so thats what we have to use -// public static final int CSIDL_APPDATA = 0x001a; // "Application Data" -// public static final int CSIDL_PERSONAL = 0x0005; // "My Documents" -// -// static Shell32 INSTANCE = (Shell32) Native.loadLibrary("shell32", Shell32.class, OPTIONS); -// -// /** -// * see http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx -// * -// * HRESULT SHGetFolderPath( HWND hwndOwner, int nFolder, HANDLE hToken, -// * DWORD dwFlags, LPTSTR pszPath); -// */ -// public int SHGetFolderPath(HWND hwndOwner, int nFolder, HANDLE hToken, -// int dwFlags, char[] pszPath); -// -// /** -// * This function can be used to copy, move, rename, -// * or delete a file system object. -// * @param fileop Address of an SHFILEOPSTRUCT structure that contains -// * information this function needs to carry out the specified operation. -// * @return Returns zero if successful, or nonzero otherwise. -// */ -// public int SHFileOperation(SHFILEOPSTRUCT fileop); -// } + // Need to extend com.sun.jna.platform.win32.User32 to access + // Win32 function GetDpiForSystem() + interface ExtUser32 extends StdCallLibrary, com.sun.jna.platform.win32.User32 { + ExtUser32 INSTANCE = (ExtUser32) Native.loadLibrary("user32", ExtUser32.class, W32APIOptions.DEFAULT_OPTIONS); + + public int GetDpiForSystem(); + + public int SetProcessDpiAwareness(int value); + + public final int DPI_AWARENESS_INVALID = -1; + public final int DPI_AWARENESS_UNAWARE = 0; + public final int DPI_AWARENESS_SYSTEM_AWARE = 1; + public final int DPI_AWARENESS_PER_MONITOR_AWARE = 2; + + public Pointer SetThreadDpiAwarenessContext(Pointer dpiContext); + + public final Pointer DPI_AWARENESS_CONTEXT_UNAWARE = new Pointer(-1); + public final Pointer DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = new Pointer(-2); + public final Pointer DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = new Pointer(-3); + } + + + static private int detected = detectSystemDPI(); + + + public int getSystemDPI() { + if (detected == -1) { + return super.getSystemDPI(); + } + return detected; + } + + + public static int detectSystemDPI() { + try { + ExtUser32.INSTANCE.SetProcessDpiAwareness(ExtUser32.DPI_AWARENESS_SYSTEM_AWARE); + } catch (Throwable e) { + // Ignore error + } + try { + ExtUser32.INSTANCE.SetThreadDpiAwarenessContext(ExtUser32.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); + } catch (Throwable e) { + // Ignore error (call valid only on Windows 10) + } + try { + return ExtUser32.INSTANCE.GetDpiForSystem(); + } catch (Throwable e) { + // DPI detection failed, fall back with default + System.out.println("DPI detection failed, fallback to 96 dpi"); + return -1; + } + } } From df64ad2245cf37c7a8e43ad6d74936ea59ec4175 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 15:30:29 -0500 Subject: [PATCH 246/917] add check for NVIDIA driver bug #4853 --- app/src/processing/app/Base.java | 41 +++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index fb36f77643..5fb1a54164 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -221,19 +221,16 @@ static private void createAndShowGUI(String[] args) { // Needs to be shown after the first editor window opens, so that it // shows up on top, and doesn't prevent an editor window from opening. if (Preferences.getBoolean("welcome.show")) { - final boolean prompt = sketchbookPrompt; -// EventQueue.invokeLater(new Runnable() { -// public void run() { try { - new Welcome(base, prompt); + new Welcome(base, sketchbookPrompt); } catch (IOException e) { Messages.showTrace("Unwelcoming", "Please report this error to\n" + "https://github.com/processing/processing/issues", e, false); } } -// }); -// } + + checkDriverBug(); } catch (Throwable t) { // Catch-all to pick up badness during startup. @@ -250,6 +247,38 @@ static private void createAndShowGUI(String[] args) { } + // Remove this code in a couple months [fry 170211] + // https://github.com/processing/processing/issues/4853 + static private void checkDriverBug() { + if (Platform.isWindows()) { + new Thread(new Runnable() { + public void run() { + try { + Process p = Runtime.getRuntime().exec("powershell Get-WmiObject Win32_PnPSignedDriver| select devicename, driverversion | where {$_.devicename -like \\\"*nvidia*\\\"}"); + String[] lines = PApplet.loadStrings(PApplet.createReader(p.getInputStream())); + for (String line : lines) { + if (line.contains("3.7849")) { + EventQueue.invokeLater(new Runnable() { + public void run() { + Messages.showWarning("NVIDIA screwed up", + "Due to an NVIDIA bug, you need to update your graphics drivers,\n" + + "otherwise you won't be able to run any sketches. Update here:\n" + + "http://nvidia.custhelp.com/app/answers/detail/a_id/4378\n" + + "or read background about the issue at this link:\n" + + "https://github.com/processing/processing/issues/4853"); + } + }); + } + } + } catch (Exception e) { + Messages.loge("Problem checking NVIDIA driver", e); + } + } + }).start(); + } + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . From 6922bdf1e24727ffee96d37f61343f46e61237aa Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 15:58:57 -0500 Subject: [PATCH 247/917] prevent enormous console with dpi scaling --- app/src/processing/app/ui/Editor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index bb654d5f27..19a9d825b8 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -262,6 +262,9 @@ public void paintComponent(Graphics g) { textarea = createTextArea(); textarea.setRightClickPopup(new TextAreaPopup()); textarea.setHorizontalOffset(JEditTextArea.leftHandGutter); + //System.out.println(textarea.getPreferredSize()); + textarea.setPreferredSize(new Dimension(textarea.getPreferredSize().width, + Toolkit.zoom(90))); { // Hack: add Numpad Slash as an alternative shortcut for Comment/Uncomment int modifiers = Toolkit.awtToolkit.getMenuShortcutKeyMask(); From 96b7a4a09f7aaa04bc3abd53404eb04a9e973b73 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 15:59:10 -0500 Subject: [PATCH 248/917] notes about NVIDIA change --- todo.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/todo.txt b/todo.txt index a5c57e307f..6785680ff4 100755 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,8 @@ 0257 (3.2.5) X check for already-exported folders before trying to remove them X was spewing 'file not found' errors into the console +X NVIDIA driver problems (and means to check) +_ https://github.com/processing/processing/issues/4853 cleaning X Contribution Manager does not show all libraries until filter cleared @@ -8,9 +10,6 @@ X https://github.com/processing/processing/issues/4840 X fixed in 3.2.4 -_ NVIDIA driver problems (and means to check) -_ https://github.com/processing/processing/issues/4853 - _ "Sketch disappeared" infinite pop up dialogs _ https://github.com/processing/processing/pull/4808 _ https://github.com/processing/processing/issues/4805 From ee05a4c7f561492acfb1957b4c51929c762da0ae Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 15:59:49 -0500 Subject: [PATCH 249/917] fix zoom on the tabs for the contrib manager --- .../processing/app/contrib/ManagerTabs.java | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/app/src/processing/app/contrib/ManagerTabs.java b/app/src/processing/app/contrib/ManagerTabs.java index 594be25053..8cc1e5d331 100644 --- a/app/src/processing/app/contrib/ManagerTabs.java +++ b/app/src/processing/app/contrib/ManagerTabs.java @@ -48,26 +48,24 @@ */ public class ManagerTabs extends Box { // height of this tab bar - static final int HIGH = 34; -// static final int HIGH = 29; + static final int HIGH = Toolkit.zoom(34); // amount of space around the entire window - static final int BORDER = 8; -// static final int BORDER = 12; + static final int BORDER = Toolkit.zoom(8); - static final int CURVE_RADIUS = 6; + static final int CURVE_RADIUS = Toolkit.zoom(6); - static final int TAB_TOP = 0; - static final int TAB_BOTTOM = HIGH - 2; + static final int TAB_TOP = Toolkit.zoom(0); + static final int TAB_BOTTOM = HIGH - Toolkit.zoom(2); // amount of extra space between individual tabs - static final int TAB_BETWEEN = 2; //4; + static final int TAB_BETWEEN = Toolkit.zoom(2); // amount of margin on the left/right for the text on the tab - static final int MARGIN = 14; + static final int MARGIN = Toolkit.zoom(14); - static final int ICON_WIDTH = 16; - static final int ICON_HEIGHT = 16; - static final int ICON_TOP = 7; - static final int ICON_MARGIN = 7; + static final int ICON_WIDTH = Toolkit.zoom(16); + static final int ICON_HEIGHT = Toolkit.zoom(16); + static final int ICON_TOP = Toolkit.zoom(7); + static final int ICON_MARGIN = Toolkit.zoom(7); static final int UNSELECTED = 0; static final int SELECTED = 1; @@ -109,7 +107,7 @@ public ManagerTabs(Base base) { tabColor[SELECTED] = mode.getColor("manager.tab.selected.color"); tabColor[UNSELECTED] = mode.getColor("manager.tab.unselected.color"); - gradient = mode.makeGradient("manager.tab", 400, HIGH); + gradient = mode.makeGradient("manager.tab", Toolkit.zoom(400), HIGH); setBorder(new EmptyBorder(BORDER, BORDER, BORDER, BORDER)); @@ -231,7 +229,9 @@ public void paintComponent(Graphics screen) { g.drawImage(gradient, 0, 0, imageW, imageH, this); g.setColor(tabColor[SELECTED]); - g.fillRect(0, TAB_BOTTOM, imageW, 2); + // draw the two pixel line that extends left/right below the tabs + // can't be done with lines, b/c retina leaves tiny hairlines + g.fillRect(0, TAB_BOTTOM, imageW, Toolkit.zoom(2)); // reset all tab positions for (Tab tab : tabList) { @@ -239,16 +239,10 @@ public void paintComponent(Graphics screen) { font.getStringBounds(tab.name, g2.getFontRenderContext()).getWidth(); } - placeTabs(0); //Editor.LEFT_GUTTER); + placeTabs(0); // now actually draw the tabs drawTabs(g2); -// // draw the two pixel line that extends left/right below the tabs -// g.setColor(tabColor[SELECTED]); -// // can't be done with lines, b/c retina leaves tiny hairlines -// g.fillRect(Editor.LEFT_GUTTER, TAB_BOTTOM, -// editor.getTextArea().getWidth() - Editor.LEFT_GUTTER, 2); - screen.drawImage(offscreen, 0, 0, imageW, imageH, null); } From 25341519930e677a99997afc96b3680c729c0392 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 16:06:44 -0500 Subject: [PATCH 250/917] perhaps a better setting here --- app/src/processing/app/ui/Editor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 19a9d825b8..bc820c7695 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -264,7 +264,7 @@ public void paintComponent(Graphics g) { textarea.setHorizontalOffset(JEditTextArea.leftHandGutter); //System.out.println(textarea.getPreferredSize()); textarea.setPreferredSize(new Dimension(textarea.getPreferredSize().width, - Toolkit.zoom(90))); + Toolkit.zoom(360))); { // Hack: add Numpad Slash as an alternative shortcut for Comment/Uncomment int modifiers = Toolkit.awtToolkit.getMenuShortcutKeyMask(); From f28d7483138ca18806d1d4ed7daa2d1eacf44e25 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 16:12:48 -0500 Subject: [PATCH 251/917] perhaps this is the correct place --- app/src/processing/app/ui/Editor.java | 4 ++-- app/src/processing/app/ui/EditorState.java | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index bc820c7695..28e906c009 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -263,8 +263,8 @@ public void paintComponent(Graphics g) { textarea.setRightClickPopup(new TextAreaPopup()); textarea.setHorizontalOffset(JEditTextArea.leftHandGutter); //System.out.println(textarea.getPreferredSize()); - textarea.setPreferredSize(new Dimension(textarea.getPreferredSize().width, - Toolkit.zoom(360))); +// textarea.setPreferredSize(new Dimension(textarea.getPreferredSize().width, +// Toolkit.zoom(360))); { // Hack: add Numpad Slash as an alternative shortcut for Comment/Uncomment int modifiers = Toolkit.awtToolkit.getMenuShortcutKeyMask(); diff --git a/app/src/processing/app/ui/EditorState.java b/app/src/processing/app/ui/EditorState.java index d44dd3b07f..0237ea1d1e 100644 --- a/app/src/processing/app/ui/EditorState.java +++ b/app/src/processing/app/ui/EditorState.java @@ -158,8 +158,10 @@ GraphicsConfiguration defaultConfig() { * @param editors List of editors currently opened */ void defaultLocation(List editors) { - int defaultWidth = Preferences.getInteger("editor.window.width.default"); - int defaultHeight = Preferences.getInteger("editor.window.height.default"); + int defaultWidth = + Toolkit.zoom(Preferences.getInteger("editor.window.width.default")); + int defaultHeight = + Toolkit.zoom(Preferences.getInteger("editor.window.height.default")); defaultWidth = Math.min(defaultWidth, deviceBounds.width); defaultHeight = Math.min(defaultHeight, deviceBounds.height); From f32bee7b8beb0fdae8eb2e2126f8836e89951462 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 16:22:09 -0500 Subject: [PATCH 252/917] yet another attempt for the editor sizing --- app/src/processing/app/ui/Editor.java | 7 ++++++- app/src/processing/app/ui/Toolkit.java | 12 +++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 28e906c009..01bddf99a4 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -263,8 +263,13 @@ public void paintComponent(Graphics g) { textarea.setRightClickPopup(new TextAreaPopup()); textarea.setHorizontalOffset(JEditTextArea.leftHandGutter); //System.out.println(textarea.getPreferredSize()); + final int editorHeight = + Preferences.getInteger("editor.window.height.default") - 240; + final int editorWidth = + Preferences.getInteger("editor.window.width.default") - 70; // textarea.setPreferredSize(new Dimension(textarea.getPreferredSize().width, -// Toolkit.zoom(360))); +// Toolkit.zoom(textareaHeight))); + textarea.setPreferredSize(Toolkit.zoom(editorWidth, editorHeight)); { // Hack: add Numpad Slash as an alternative shortcut for Comment/Uncomment int modifiers = Toolkit.awtToolkit.getMenuShortcutKeyMask(); diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 75270f058a..98b31085fc 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -844,6 +844,11 @@ static public int zoom(int pixels) { } + static public Dimension zoom(int w, int h) { + return new Dimension(zoom(w), zoom(h)); + } + + static private float parseZoom() { String zoomSel = Preferences.get("editor.zoom"); if (zoomOptions.hasValue(zoomSel)) { @@ -870,13 +875,6 @@ static private void zoomStroke(Graphics2D g2) { } - /* - static Dimension zoom(int w, int h) { - return new Dimension(zoom(w), zoom(h)); - } - */ - - // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . From fbfa1cf090a66f98dd0950082054663d7c3a7979 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 22:24:46 +0000 Subject: [PATCH 253/917] fix console location and divider placement --- app/src/processing/app/ui/Editor.java | 8 +++++--- app/src/processing/app/ui/EditorConsole.java | 3 ++- app/src/processing/app/ui/EditorState.java | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 01bddf99a4..b7bfcec9c5 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -262,14 +262,16 @@ public void paintComponent(Graphics g) { textarea = createTextArea(); textarea.setRightClickPopup(new TextAreaPopup()); textarea.setHorizontalOffset(JEditTextArea.leftHandGutter); + /* //System.out.println(textarea.getPreferredSize()); - final int editorHeight = - Preferences.getInteger("editor.window.height.default") - 240; + final int editorHeight = 200; + //Preferences.getInteger("editor.window.height.default") - 340; //240; final int editorWidth = Preferences.getInteger("editor.window.width.default") - 70; // textarea.setPreferredSize(new Dimension(textarea.getPreferredSize().width, // Toolkit.zoom(textareaHeight))); textarea.setPreferredSize(Toolkit.zoom(editorWidth, editorHeight)); + */ { // Hack: add Numpad Slash as an alternative shortcut for Comment/Uncomment int modifiers = Toolkit.awtToolkit.getMenuShortcutKeyMask(); @@ -349,7 +351,7 @@ public void caretUpdate(CaretEvent e) { contentPain.setTransferHandler(new FileDropHandler()); - // Finish preparing Editor (formerly found in Base) + // Finish preparing Editor pack(); // Set the window bounds and the divider location before setting it visible diff --git a/app/src/processing/app/ui/EditorConsole.java b/app/src/processing/app/ui/EditorConsole.java index 2699758917..48da521a03 100644 --- a/app/src/processing/app/ui/EditorConsole.java +++ b/app/src/processing/app/ui/EditorConsole.java @@ -223,7 +223,8 @@ public PrintStream getErr() { */ protected void updateAppearance() { String fontFamily = Preferences.get("editor.font.family"); - int fontSize = Preferences.getInteger("console.font.size"); + int fontSize = + Toolkit.zoom(Preferences.getInteger("console.font.size")); StyleConstants.setFontFamily(stdStyle, fontFamily); StyleConstants.setFontSize(stdStyle, fontSize); StyleConstants.setFontFamily(errStyle, fontFamily); diff --git a/app/src/processing/app/ui/EditorState.java b/app/src/processing/app/ui/EditorState.java index 0237ea1d1e..5de166cf3f 100644 --- a/app/src/processing/app/ui/EditorState.java +++ b/app/src/processing/app/ui/EditorState.java @@ -221,6 +221,8 @@ void apply(Editor editor) { editor.setBounds(editorBounds); if (dividerLocation != 0) { editor.setDividerLocation(dividerLocation); + } else { + editor.setDividerLocation(2 * editor.getSize().height / 3); } if (isMaximized) { editor.setExtendedState(Frame.MAXIMIZED_BOTH); From 46be857333ff1c08dc31e4dcf5cb213adc1628ce Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 22:25:12 +0000 Subject: [PATCH 254/917] remove the unused debugging stuff --- app/src/processing/app/ui/Editor.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index b7bfcec9c5..b4b1356fda 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -262,18 +262,8 @@ public void paintComponent(Graphics g) { textarea = createTextArea(); textarea.setRightClickPopup(new TextAreaPopup()); textarea.setHorizontalOffset(JEditTextArea.leftHandGutter); - /* - //System.out.println(textarea.getPreferredSize()); - final int editorHeight = 200; - //Preferences.getInteger("editor.window.height.default") - 340; //240; - final int editorWidth = - Preferences.getInteger("editor.window.width.default") - 70; -// textarea.setPreferredSize(new Dimension(textarea.getPreferredSize().width, -// Toolkit.zoom(textareaHeight))); - textarea.setPreferredSize(Toolkit.zoom(editorWidth, editorHeight)); - */ - { // Hack: add Numpad Slash as an alternative shortcut for Comment/Uncomment + { // Hack: add Numpad Slash as alternative shortcut for Comment/Uncomment int modifiers = Toolkit.awtToolkit.getMenuShortcutKeyMask(); KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DIVIDE, modifiers); final String ACTION_KEY = "COMMENT_UNCOMMENT_ALT"; From 96b24195a6e921af086096c2a6112a00f4e5dae4 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 22:25:38 +0000 Subject: [PATCH 255/917] line lengths, people --- app/src/processing/app/ui/Editor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index b4b1356fda..0039ab18e7 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -265,7 +265,8 @@ public void paintComponent(Graphics g) { { // Hack: add Numpad Slash as alternative shortcut for Comment/Uncomment int modifiers = Toolkit.awtToolkit.getMenuShortcutKeyMask(); - KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DIVIDE, modifiers); + KeyStroke keyStroke = + KeyStroke.getKeyStroke(KeyEvent.VK_DIVIDE, modifiers); final String ACTION_KEY = "COMMENT_UNCOMMENT_ALT"; textarea.getInputMap().put(keyStroke, ACTION_KEY); textarea.getActionMap().put(ACTION_KEY, new AbstractAction() { From 54231178fb8e9bce1332d43a28f465446920e57b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 22:26:35 +0000 Subject: [PATCH 256/917] simplify the divider location setup --- app/src/processing/app/ui/EditorState.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/ui/EditorState.java b/app/src/processing/app/ui/EditorState.java index 5de166cf3f..8116042473 100644 --- a/app/src/processing/app/ui/EditorState.java +++ b/app/src/processing/app/ui/EditorState.java @@ -219,11 +219,12 @@ void update(Editor editor) { void apply(Editor editor) { editor.setBounds(editorBounds); - if (dividerLocation != 0) { - editor.setDividerLocation(dividerLocation); - } else { - editor.setDividerLocation(2 * editor.getSize().height / 3); + + if (dividerLocation == 0) { + dividerLocation = 2 * editor.getSize().height / 3; } + editor.setDividerLocation(dividerLocation); + if (isMaximized) { editor.setExtendedState(Frame.MAXIMIZED_BOTH); } From cead05738669d4f67e56fd613175aff489d76d4c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 17:54:05 -0500 Subject: [PATCH 257/917] more cleanups --- .../processing/app/contrib/ManagerFrame.java | 224 +----------------- 1 file changed, 3 insertions(+), 221 deletions(-) diff --git a/app/src/processing/app/contrib/ManagerFrame.java b/app/src/processing/app/contrib/ManagerFrame.java index e65a864db7..ae31e54f7b 100644 --- a/app/src/processing/app/contrib/ManagerFrame.java +++ b/app/src/processing/app/contrib/ManagerFrame.java @@ -38,37 +38,25 @@ public class ManagerFrame { static final String ANY_CATEGORY = Language.text("contrib.all"); -// static final int TAB_WIDTH = 100; -// static final int TAB_HEIGHT = 34; - static final int AUTHOR_WIDTH = 240; - static final int STATUS_WIDTH = 66; + static final int AUTHOR_WIDTH = Toolkit.zoom(240); + static final int STATUS_WIDTH = Toolkit.zoom(66); static final String title = "Contribution Manager"; Base base; JFrame frame; -// JTabbedPane tabbedPane; ManagerTabs tabs; - // the calling editor, so updates can be applied -// Editor editor; - ContributionTab librariesTab; ContributionTab modesTab; ContributionTab toolsTab; ContributionTab examplesTab; UpdateContributionTab updatesTab; -// JLabel numberLabel; - -// private JLabel[] tabLabels; -// private JPanel updateTabPanel; -// private JLabel updateTabLabel; public ManagerFrame(Base base) { this.base = base; -// numberLabel = new JLabel(Toolkit.getLibIconX("manager/notification")); librariesTab = new ContributionTab(this, ContributionType.LIBRARY); modesTab = new ContributionTab(this, ContributionType.MODE); toolsTab = new ContributionTab(this, ContributionType.TOOL); @@ -77,11 +65,7 @@ public ManagerFrame(Base base) { } - // TODO remove this Editor... need to use Base.getActiveEditor() - // The editor may be closed while still running the contrib manager public void showFrame(ContributionType contributionType) { -// this.editor = editor; - ContributionTab showTab = getTab(contributionType); if (frame == null) { makeFrame(); @@ -100,7 +84,7 @@ public void showFrame(ContributionType contributionType) { private void makeFrame() { frame = new JFrame(title); - frame.setMinimumSize(new Dimension(750, 500)); + frame.setMinimumSize(Toolkit.zoom(750, 500)); tabs = new ManagerTabs(base); makeAndShowTab(false, true); @@ -111,129 +95,7 @@ private void makeFrame() { tabs.addPanel(examplesTab, "Examples"); tabs.addPanel(updatesTab, "Updates"); - /* - tabbedPane.addTab("Libraries", null, librariesTab, "Libraries"); - tabbedPane.setMnemonicAt(0, KeyEvent.VK_1); - - tabbedPane.addTab("Modes", null, modesTab, "Modes"); - tabbedPane.setMnemonicAt(1, KeyEvent.VK_2); - - tabbedPane.addTab("Tools", null, toolsTab, "Tools"); - tabbedPane.setMnemonicAt(2, KeyEvent.VK_3); - - tabbedPane.addTab("Examples", null, examplesTab, "Examples"); - tabbedPane.setMnemonicAt(3, KeyEvent.VK_4); - - tabbedPane.addTab("Updates", null, updatesTab, "Updates"); - tabbedPane.setMnemonicAt(4, KeyEvent.VK_5); - - tabbedPane.setUI(new SpacedTabbedPaneUI()); - tabbedPane.setBackground(new Color(0x132638)); - tabbedPane.setOpaque(true); - - for (int i = 0; i < 5; i++) { - tabbedPane.setToolTipTextAt(i, null); - } - */ - - /* - final String[] tabTitles = { - "Libraries", "Modes", "Tools", "Examples", "Updates" - }; - tabLabels = new JLabel[4]; - - for (int i = 0 ; i < 4; i++) { - final int temp = i; - tabLabels[i] = new JLabel(tabTitles[i]) { - @Override - protected void paintComponent(Graphics g) { - g.setClip(Toolkit.createRoundRect(0, 0, - getWidth(), getHeight(), - temp == 0 ? 6 : 0, - temp == 3 ? 6 : 0, - 0, 0)); - super.paintComponent(g); - } - }; - tabLabels[i].setForeground(Color.WHITE); - tabLabels[i].setBackground(new Color(0x2d4251)); - tabLabels[i].setOpaque(true); - tabLabels[i].setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6)); - tabLabels[i].setPreferredSize(new Dimension(TAB_WIDTH, TAB_HEIGHT)); - tabLabels[i].setHorizontalAlignment(SwingConstants.CENTER); - tabLabels[i].setFont(Toolkit.getSansFont(14, Font.BOLD)); - tabbedPane.setTabComponentAt(i, tabLabels[i]); - } - */ - - /* - updateTabPanel = new JPanel() { - @Override - protected void paintComponent(Graphics g) { - g.setClip(Toolkit.createRoundRect(0, 0, getWidth(), getHeight(), - 6, 6, 0, 0)); - super.paintComponent(g); - } - };; - updateTabLabel = new JLabel("Updates"); - updateTabLabel.setFont(Toolkit.getSansFont(14, Font.BOLD)); - numberLabel.setVerticalTextPosition(SwingConstants.CENTER); - numberLabel.setHorizontalTextPosition(SwingConstants.CENTER); - numberLabel.setFont(Toolkit.getSansFont(14, Font.BOLD)); - numberLabel.setForeground(Color.WHITE); - updateTabPanel.setOpaque(true); - updateTabPanel.setBackground(new Color(0x2d4251)); - updateTabLabel.setForeground(Color.WHITE); - updateTabPanel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6)); - updateTabPanel.setPreferredSize(new Dimension(TAB_WIDTH, TAB_HEIGHT)); - tabbedPane.setTabComponentAt(4, updateTabPanel); - */ - - /* - GroupLayout tabLayout = new GroupLayout(updateTabPanel); - tabLayout.setAutoCreateGaps(true); - updateTabPanel.setLayout(tabLayout); - tabLayout.setHorizontalGroup(tabLayout - .createSequentialGroup() - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, - GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) - .addComponent(updateTabLabel) - .addComponent(numberLabel) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, - GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)); - tabLayout.setVerticalGroup(tabLayout - .createParallelGroup(GroupLayout.Alignment.CENTER) - .addComponent(numberLabel).addComponent(updateTabLabel)); - - numberLabel.setVisible(false); - */ - - /* - tabbedPane.addChangeListener(new ChangeListener() { - - @Override - public void stateChanged(ChangeEvent e) { - for(int i = 0 ; i < 4; i++){ - tabLabels[i].setBackground(new Color(0x2d4251)); - tabLabels[i].setForeground(Color.WHITE); - } - updateTabPanel.setBackground(new Color(0x2d4251)); - updateTabLabel.setForeground(Color.WHITE); - int currentIndex = tabbedPane.getSelectedIndex(); - if(currentIndex != 4){ - tabbedPane.getTabComponentAt(tabbedPane.getSelectedIndex()).setBackground(new Color(0xe0fffd)); - tabbedPane.getTabComponentAt(tabbedPane.getSelectedIndex()).setForeground(Color.BLACK); - }else{ - updateTabPanel.setBackground(new Color(0xe0fffd)); - updateTabLabel.setForeground(Color.BLACK); - } - getActiveTab().contributionListPanel.scrollPane.requestFocusInWindow(); - } - }); - */ - frame.setResizable(true); -// tabbedPane.setBorder(new EmptyBorder(BORDER, BORDER, BORDER, BORDER)); Container c = frame.getContentPane(); c.add(tabs); @@ -255,73 +117,7 @@ public void stateChanged(ChangeEvent e) { */ protected void disposeFrame() { frame.dispose(); -// editor = null; - } - - - // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - - /* - private class SpacedTabbedPaneUI extends BasicTabbedPaneUI { - - @Override - protected void installDefaults() { - UIManager.put("TabbedPane.selected", Color.BLACK); - UIManager.put("TabbedPane.tabsOverlapBorder" , true); - super.installDefaults(); - tabInsets = new Insets(0, 0, 0, 0); - contentBorderInsets = new Insets(0, 0, 0, 0); - tabAreaInsets = new Insets(0, 0, 0, 0); - selectedTabPadInsets = new Insets(0, 0, 0, 0); - } - - - @Override - protected int getTabLabelShiftY(int tabPlacement, int tabIndex, - boolean isSelected) { - return 1; - } - - - @Override - protected void paintTabBackground(Graphics g, int tabPlacement, - int tabIndex, int x, int y, int w, int h, - boolean isSelected) { - } - - - @Override - protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, - int x, int y, int w, int h, boolean isSelected) { - } - - - @Override - protected void paintFocusIndicator(Graphics g, int tabPlacement, - Rectangle[] rects, int tabIndex, - Rectangle iconRect, Rectangle textRect, - boolean isSelected) { - } - - - @Override - protected LayoutManager createLayoutManager() { - return new BasicTabbedPaneUI.TabbedPaneLayout() { - - @Override - protected void calculateTabRects(int tabPlacement, int tabCount) { - super.calculateTabRects(tabPlacement, tabCount); - rects[0].x -= 2; - rects[1].x -= 1; - rects[2].x -= 1; - rects[3].x -= 1; - rects[4].x = tabbedPane.getWidth() - rects[4].width + 1; - } - }; - } } - */ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -420,19 +216,5 @@ protected ContributionTab getTab(ContributionType contributionType) { ContributionTab getActiveTab() { return (ContributionTab) tabs.getPanel(); - /* - switch (tabbedPane.getSelectedIndex()) { - case 0: - return librariesTab; - case 1: - return modesTab; - case 2: - return toolsTab; - case 3: - return examplesTab; - default: - return updatesTab; - } - */ } } From a50f5b1c0a9b6fba7ef4038be0333d6e51c13f3e Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 18:19:43 -0500 Subject: [PATCH 258/917] centralize font setup and fix the dpi setting --- .../app/contrib/ContributionTab.java | 9 ++++----- .../processing/app/contrib/DetailPanel.java | 4 ++-- app/src/processing/app/contrib/ListPanel.java | 19 ++++++------------- .../processing/app/contrib/ManagerFrame.java | 12 ++++++++++++ .../processing/app/contrib/StatusPanel.java | 2 +- .../app/contrib/UpdateListPanel.java | 12 ++---------- .../app/contrib/UpdateStatusPanel.java | 3 +-- 7 files changed, 28 insertions(+), 33 deletions(-) diff --git a/app/src/processing/app/contrib/ContributionTab.java b/app/src/processing/app/contrib/ContributionTab.java index 447f0eb08d..6165e7a0d3 100644 --- a/app/src/processing/app/contrib/ContributionTab.java +++ b/app/src/processing/app/contrib/ContributionTab.java @@ -25,7 +25,6 @@ import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; -import java.awt.Font; import java.awt.event.*; import java.util.*; @@ -172,7 +171,7 @@ private void createComponents() { categoryChooser = new JComboBox(); categoryChooser.setMaximumRowCount(20); - categoryChooser.setFont(Toolkit.getSansFont(14, Font.PLAIN)); + categoryChooser.setFont(ManagerFrame.NORMAL_PLAIN); updateCategoryChooser(); @@ -227,7 +226,7 @@ public void actionPerformed(ActionEvent e) { } }); tryAgainButton = new JButton("Try Again"); - tryAgainButton.setFont(Toolkit.getSansFont(14, Font.PLAIN)); + tryAgainButton.setFont(ManagerFrame.NORMAL_PLAIN); tryAgainButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { contribDialog.makeAndShowTab(false, true); @@ -350,10 +349,10 @@ public FilterField () { super(""); JLabel filterLabel = new JLabel("Filter"); - filterLabel.setFont(Toolkit.getSansFont(14, Font.PLAIN)); + filterLabel.setFont(ManagerFrame.NORMAL_PLAIN); filterLabel.setOpaque(false); - setFont(Toolkit.getSansFont(14, Font.PLAIN)); + setFont(ManagerFrame.NORMAL_PLAIN); filterLabel.setIcon(Toolkit.getLibIconX("manager/search")); JButton removeFilter = Toolkit.createIconButton("manager/remove"); removeFilter.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2)); diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index f62f953cdf..8e2882a632 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -198,7 +198,7 @@ public void hyperlinkUpdate(HyperlinkEvent e) { notificationLabel.setInheritsPopupMenu(true); notificationLabel.setVisible(false); notificationLabel.setOpaque(false); - notificationLabel.setFont(Toolkit.getSansFont(12, Font.PLAIN)); + notificationLabel.setFont(ManagerFrame.SMALL_PLAIN); { updateButton = new JButton("Update"); @@ -406,7 +406,7 @@ public void setContribution(Contribution contrib) { } // Avoid ugly synthesized bold - Font boldFont = Toolkit.getSansFont(12, Font.BOLD); + Font boldFont = ManagerFrame.SMALL_BOLD; String fontFace = ""; StringBuilder desc = new StringBuilder(); diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index ad8f34ad5f..ef45020194 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -61,10 +61,6 @@ public class ListPanel extends JPanel static Icon foundationIcon; static Icon downloadingIcon; - static Font plainFont; - static Font boldFont; - static Font headerFont; - // Should this be in theme.txt? Of course! Is it? No. static final Color HEADER_BGCOLOR = new Color(0xffEBEBEB); @@ -76,10 +72,6 @@ public ListPanel() { incompatibleIcon = Toolkit.getLibIconX("manager/incompatible"); foundationIcon = Toolkit.getLibIconX("icons/foundation", 16); downloadingIcon = Toolkit.getLibIconX("manager/downloading"); - - plainFont = Toolkit.getSansFont(14, Font.PLAIN); - boldFont = Toolkit.getSansFont(14, Font.BOLD); - headerFont = Toolkit.getSansFont(12, Font.PLAIN); } } @@ -114,7 +106,7 @@ public Component prepareRenderer(TableCellRenderer renderer, int row, int column scrollPane.setBorder(BorderFactory.createEmptyBorder()); table.setFillsViewportHeight(true); table.setDefaultRenderer(Contribution.class, new ContribStatusRenderer()); - table.setFont(plainFont); + table.setFont(ManagerFrame.NORMAL_PLAIN); table.setRowHeight(28); table.setRowMargin(6); table.getColumnModel().setColumnMargin(0); @@ -231,7 +223,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, if (tableHeader != null) { setForeground(tableHeader.getForeground()); } - setFont(headerFont); + setFont(ManagerFrame.SMALL_PLAIN); setIcon(getSortIcon(table, column)); setBackground(HEADER_BGCOLOR); // if (column % 2 == 0) { @@ -308,7 +300,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, } if (column == 0) { Icon icon = null; - label.setFont(plainFont); + label.setFont(ManagerFrame.NORMAL_PLAIN); if (contribution.isInstalled()) { icon = upToDateIcon; if (contribListing.hasUpdates(contribution)) { @@ -334,6 +326,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, } else if (column == 1) { // Generating ellipses based on fontMetrics + final Font boldFont = ManagerFrame.NORMAL_BOLD; String fontFace = ""; FontMetrics fontMetrics = table.getFontMetrics(boldFont); //table.getFont()); int colSize = table.getColumnModel().getColumn(1).getWidth(); @@ -368,7 +361,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, if (table.isRowSelected(row)) { label.setBackground(new Color(0xe0fffd)); } - label.setFont(plainFont); + label.setFont(ManagerFrame.NORMAL_PLAIN); label.setOpaque(true); } else { if (contribution.isSpecial()) { @@ -388,7 +381,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, if (table.isRowSelected(row)) { label.setBackground(new Color(0xe0fffd)); } - label.setFont(Toolkit.getSansFont(14, Font.BOLD)); + label.setFont(ManagerFrame.NORMAL_BOLD); label.setOpaque(true); } return label; diff --git a/app/src/processing/app/contrib/ManagerFrame.java b/app/src/processing/app/contrib/ManagerFrame.java index ae31e54f7b..85c36353ee 100644 --- a/app/src/processing/app/contrib/ManagerFrame.java +++ b/app/src/processing/app/contrib/ManagerFrame.java @@ -53,10 +53,22 @@ public class ManagerFrame { ContributionTab examplesTab; UpdateContributionTab updatesTab; + static Font SMALL_PLAIN; + static Font SMALL_BOLD; + static Font NORMAL_PLAIN; + static Font NORMAL_BOLD; + public ManagerFrame(Base base) { this.base = base; + final int smallSize = Toolkit.zoom(12); + final int normalSize = Toolkit.zoom(14); + SMALL_PLAIN = Toolkit.getSansFont(smallSize, Font.PLAIN); + SMALL_BOLD = Toolkit.getSansFont(smallSize, Font.BOLD); + NORMAL_PLAIN = Toolkit.getSansFont(normalSize, Font.PLAIN); + NORMAL_BOLD = Toolkit.getSansFont(normalSize, Font.BOLD); + librariesTab = new ContributionTab(this, ContributionType.LIBRARY); modesTab = new ContributionTab(this, ContributionType.MODE); toolsTab = new ContributionTab(this, ContributionType.TOOL); diff --git a/app/src/processing/app/contrib/StatusPanel.java b/app/src/processing/app/contrib/StatusPanel.java index 9505b1df7d..02f7228ce8 100644 --- a/app/src/processing/app/contrib/StatusPanel.java +++ b/app/src/processing/app/contrib/StatusPanel.java @@ -79,7 +79,7 @@ public StatusPanel(final ContributionTab contributionTab, int width) { installIcon = Toolkit.getLibIconX("manager/install"); updateIcon = Toolkit.getLibIconX("manager/update"); removeIcon = Toolkit.getLibIconX("manager/remove"); - buttonFont = Toolkit.getSansFont(14, Font.PLAIN); + buttonFont = ManagerFrame.NORMAL_PLAIN; } setBackground(new Color(0xebebeb)); diff --git a/app/src/processing/app/contrib/UpdateListPanel.java b/app/src/processing/app/contrib/UpdateListPanel.java index 985889f582..11b23bfd67 100644 --- a/app/src/processing/app/contrib/UpdateListPanel.java +++ b/app/src/processing/app/contrib/UpdateListPanel.java @@ -2,7 +2,6 @@ import java.awt.Color; import java.awt.Component; -import java.awt.Font; import java.util.Arrays; import java.util.Comparator; import java.util.HashSet; @@ -20,7 +19,6 @@ import javax.swing.table.TableCellRenderer; import processing.app.Base; -import processing.app.ui.Toolkit; public class UpdateListPanel extends ListPanel { @@ -87,7 +85,7 @@ public void changeSelection(int rowIndex, int columnIndex, table.setFillsViewportHeight(true); table.setSelectionBackground(new Color(0xe0fffd)); table.setSelectionForeground(table.getForeground()); - table.setFont(Toolkit.getSansFont(14, Font.PLAIN)); + table.setFont(ManagerFrame.NORMAL_PLAIN); table.setRowHeight(30); table.setRowMargin(6); table.getColumnModel().setColumnMargin(-1); @@ -153,16 +151,10 @@ public int compare(Contribution o1, Contribution o2) { // Thread: EDT @Override void updatePanelOrdering(Set contributionsSet) { -// int updateCount = panelByContribution.size(); -// new Exception("update count is " + updateCount).printStackTrace(System.out); -// (UpdateContributionTab) contributionTab - model.getDataVector().removeAllElements(); ContributionType currentType = null; - // Avoid ugly synthesized bold - Font boldFont = Toolkit.getSansFont(table.getFont().getSize(), Font.BOLD); - String fontFace = ""; + String fontFace = ""; for (Contribution entry : contributionsSet) { if (entry.getType() != currentType) { diff --git a/app/src/processing/app/contrib/UpdateStatusPanel.java b/app/src/processing/app/contrib/UpdateStatusPanel.java index b47b584cb7..f91db9fbd5 100644 --- a/app/src/processing/app/contrib/UpdateStatusPanel.java +++ b/app/src/processing/app/contrib/UpdateStatusPanel.java @@ -21,7 +21,6 @@ package processing.app.contrib; import java.awt.Color; -import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -39,7 +38,7 @@ public UpdateStatusPanel(UpdateContributionTab tab, int width) { this.contributionTab = tab; updateButton = Toolkit.createIconButton("Update All", "manager/update"); - updateButton.setFont(Toolkit.getSansFont(14, Font.PLAIN)); + updateButton.setFont(ManagerFrame.NORMAL_PLAIN); updateButton.setHorizontalAlignment(SwingConstants.LEFT); updateButton.setVisible(true); updateButton.setEnabled(false); From 4526a830b210170913418e80787ec673936e30f0 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 18:22:44 -0500 Subject: [PATCH 259/917] fix the table view sizing --- app/src/processing/app/contrib/ListPanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/contrib/ListPanel.java b/app/src/processing/app/contrib/ListPanel.java index ef45020194..d9b36ce122 100644 --- a/app/src/processing/app/contrib/ListPanel.java +++ b/app/src/processing/app/contrib/ListPanel.java @@ -107,8 +107,8 @@ public Component prepareRenderer(TableCellRenderer renderer, int row, int column table.setFillsViewportHeight(true); table.setDefaultRenderer(Contribution.class, new ContribStatusRenderer()); table.setFont(ManagerFrame.NORMAL_PLAIN); - table.setRowHeight(28); - table.setRowMargin(6); + table.setRowHeight(Toolkit.zoom(28)); + table.setRowMargin(Toolkit.zoom(6)); table.getColumnModel().setColumnMargin(0); table.getColumnModel().getColumn(0).setMaxWidth(ManagerFrame.STATUS_WIDTH); table.getColumnModel().getColumn(2).setMinWidth(ManagerFrame.AUTHOR_WIDTH); From e6488d0c293faaeb6d8b467d5d4a8e6a9c4a7c74 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 18:26:11 -0500 Subject: [PATCH 260/917] fix button sizing in contribs --- app/src/processing/app/contrib/DetailPanel.java | 16 ++++++++-------- app/src/processing/app/contrib/StatusPanel.java | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/processing/app/contrib/DetailPanel.java b/app/src/processing/app/contrib/DetailPanel.java index 8e2882a632..e36978e114 100644 --- a/app/src/processing/app/contrib/DetailPanel.java +++ b/app/src/processing/app/contrib/DetailPanel.java @@ -71,7 +71,7 @@ class DetailPanel extends JPanel { private final ListPanel listPanel; private final ContributionListing contribListing = ContributionListing.getInstance(); - static final int BUTTON_WIDTH = 100; + static final int BUTTON_WIDTH = Toolkit.zoom(100); static Icon foundationIcon; /** @@ -227,14 +227,14 @@ public void actionPerformed(ActionEvent e) { rightPane.setInheritsPopupMenu(true); rightPane.setOpaque(false); rightPane.setLayout(new BoxLayout(rightPane, BoxLayout.Y_AXIS)); - rightPane.setMinimumSize(new Dimension(DetailPanel.BUTTON_WIDTH, 1)); + rightPane.setMinimumSize(new Dimension(BUTTON_WIDTH, 1)); add(rightPane, BorderLayout.EAST); barButtonCardLayout = new CardLayout(); barButtonCardPane.setLayout(barButtonCardLayout); barButtonCardPane.setInheritsPopupMenu(true); barButtonCardPane.setOpaque(false); - barButtonCardPane.setMinimumSize(new Dimension(DetailPanel.BUTTON_WIDTH, 1)); + barButtonCardPane.setMinimumSize(new Dimension(BUTTON_WIDTH, 1)); { installProgressBar = new JProgressBar(); @@ -242,7 +242,7 @@ public void actionPerformed(ActionEvent e) { installProgressBar.setStringPainted(true); resetInstallProgressBarState(); Dimension dim = - new Dimension(DetailPanel.BUTTON_WIDTH, + new Dimension(BUTTON_WIDTH, installProgressBar.getPreferredSize().height); installProgressBar.setPreferredSize(dim); installProgressBar.setMaximumSize(dim); @@ -267,7 +267,7 @@ public void actionPerformed(ActionEvent e) { }); Dimension installButtonDimensions = installRemoveButton.getPreferredSize(); - installButtonDimensions.width = DetailPanel.BUTTON_WIDTH; + installButtonDimensions.width = BUTTON_WIDTH; installRemoveButton.setPreferredSize(installButtonDimensions); installRemoveButton.setMaximumSize(installButtonDimensions); installRemoveButton.setMinimumSize(installButtonDimensions); @@ -290,7 +290,7 @@ public void actionPerformed(ActionEvent e) { // Set the minimum size of this pane to be the sum of the height of the // progress bar and install button Dimension dim = - new Dimension(DetailPanel.BUTTON_WIDTH, + new Dimension(BUTTON_WIDTH, installRemoveButton.getPreferredSize().height); rightPane.setMinimumSize(dim); rightPane.setPreferredSize(dim); @@ -314,7 +314,7 @@ private void reorganizePaneComponents() { rightPane.setInheritsPopupMenu(true); rightPane.setOpaque(false); rightPane.setLayout(new BoxLayout(rightPane, BoxLayout.Y_AXIS)); - rightPane.setMinimumSize(new Dimension(DetailPanel.BUTTON_WIDTH, 1)); + rightPane.setMinimumSize(new Dimension(BUTTON_WIDTH, 1)); add(rightPane, BorderLayout.EAST); if (updateButton.isVisible() && !removeInProgress && !contrib.isDeletionFlagged()) { @@ -359,7 +359,7 @@ private void reorganizePaneComponents() { Dimension progressDim = installProgressBar.getPreferredSize(); Dimension installDim = installRemoveButton.getPreferredSize(); - progressDim.width = DetailPanel.BUTTON_WIDTH; + progressDim.width = BUTTON_WIDTH; progressDim.height = Math.max(progressDim.height, installDim.height); rightPane.setMinimumSize(progressDim); rightPane.setPreferredSize(progressDim); diff --git a/app/src/processing/app/contrib/StatusPanel.java b/app/src/processing/app/contrib/StatusPanel.java index 02f7228ce8..4c25c5ec1e 100644 --- a/app/src/processing/app/contrib/StatusPanel.java +++ b/app/src/processing/app/contrib/StatusPanel.java @@ -45,7 +45,7 @@ class StatusPanel extends JPanel { - static final int BUTTON_WIDTH = 150; + static final int BUTTON_WIDTH = Toolkit.zoom(150); static Icon foundationIcon; static Icon installIcon; From d74d196b6e3411d72c3d94e9f25cc88af3e6f14b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 18:33:34 -0500 Subject: [PATCH 261/917] fix the icon sizing --- app/src/processing/app/ui/Toolkit.java | 55 ++------------------------ 1 file changed, 3 insertions(+), 52 deletions(-) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 98b31085fc..c447c16a92 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -500,71 +500,22 @@ static public ImageIcon getIconX(File dir, String base, int size) { String filename = (size == 0) ? (base + "-" + scale + "x.png") : (base + "-" + (size*scale) + ".png"); -// File file = Platform.getContentFile("lib/" + filename); File file = new File(dir, filename); if (!file.exists()) { -// System.err.println("does not exist: " + file); return null; } ImageIcon outgoing = new ImageIcon(file.getAbsolutePath()) { + @Override public int getIconWidth() { - return super.getIconWidth() / scale; + return Toolkit.zoom(super.getIconWidth()) / scale; } @Override public int getIconHeight() { - return super.getIconHeight() / scale; - } - - /* - @Override - public Image getImage() { - //javax.swing.LookAndFeel -> creates a synthetic disabled icon - //com.apple.laf.AquaButtonUI - new Exception().printStackTrace(); - return super.getImage(); - } - - private Image getImageImpl() { - return super.getImage(); - } - */ - - /* - @Override - public Image getImage() { - Image actual = super.getImage(); - - return new Image() { - @Override - public int getWidth(ImageObserver observer) { - return actual.getWidth(observer) / scale; - } - - @Override - public int getHeight(ImageObserver observer) { - return actual.getHeight(observer) / scale; - } - - @Override - public ImageProducer getSource() { - return actual.getSource(); - } - - @Override - public Graphics getGraphics() { - return actual.getGraphics(); - } - - @Override - public Object getProperty(String name, ImageObserver observer) { - return actual.getProperty(filename, observer); - } - }; + return Toolkit.zoom(super.getIconHeight()) / scale; } - */ @Override public synchronized void paintIcon(Component c, Graphics g, int x, int y) { From e9459e5d6134220f395eba01140a03324aadee11 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 11 Feb 2017 18:35:54 -0500 Subject: [PATCH 262/917] fix filter width --- app/src/processing/app/contrib/ContributionTab.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/processing/app/contrib/ContributionTab.java b/app/src/processing/app/contrib/ContributionTab.java index 6165e7a0d3..532d7f9ed9 100644 --- a/app/src/processing/app/contrib/ContributionTab.java +++ b/app/src/processing/app/contrib/ContributionTab.java @@ -38,7 +38,7 @@ public class ContributionTab extends JPanel { static final String ANY_CATEGORY = Language.text("contrib.all"); - static final int FILTER_WIDTH = 180; + static final int FILTER_WIDTH = Toolkit.zoom(180); ContributionType contribType; ManagerFrame contribDialog; From 93749da60c3a515d5e945f710947c1fdffa681f1 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 12 Feb 2017 09:31:23 -0500 Subject: [PATCH 263/917] switch to em spacing (for hidpi), use renamed font to fix #4747 --- app/src/processing/app/ui/Toolkit.java | 4 + .../lib/fonts/ProcessingSansPro-LICENSE.txt | 98 ++++++++++++++++++ .../lib/fonts/ProcessingSansPro-Regular.ttf | Bin 0 -> 288348 bytes .../lib/fonts/ProcessingSansPro-Semibold.ttf | Bin 0 -> 286908 bytes build/shared/lib/welcome/generic.html | 19 ++-- build/shared/lib/welcome/sketchbook.html | 26 +++-- todo.txt | 2 + 7 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 build/shared/lib/fonts/ProcessingSansPro-LICENSE.txt create mode 100644 build/shared/lib/fonts/ProcessingSansPro-Regular.ttf create mode 100644 build/shared/lib/fonts/ProcessingSansPro-Semibold.ttf diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index c447c16a92..7e22da357a 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -1005,6 +1005,7 @@ static public String getSansFontName() { static public Font getSansFont(int size, int style) { if (sansFont == null) { try { + /* // check for an installed version, because they cause nasty conflicts // https://github.com/processing/processing/issues/4747 if (Platform.isWindows()) { @@ -1024,6 +1025,9 @@ static public Font getSansFont(int size, int style) { if (sansBoldFont == null) { sansBoldFont = createFont("SourceSansPro-Semibold.ttf", size); } + */ + sansFont = createFont("ProcessingSansPro-Regular.ttf", size); + sansBoldFont = createFont("SourceSansPro-Semibold.ttf", size); // additional language constraints if ("el".equals(Language.getLanguage())) { diff --git a/build/shared/lib/fonts/ProcessingSansPro-LICENSE.txt b/build/shared/lib/fonts/ProcessingSansPro-LICENSE.txt new file mode 100644 index 0000000000..caaf349732 --- /dev/null +++ b/build/shared/lib/fonts/ProcessingSansPro-LICENSE.txt @@ -0,0 +1,98 @@ +"Processing Sans" fonts are just "Source Sans", but renamed to +prevent conflicts on Windows with other versions of Source Sans. +https://github.com/processing/processing/issues/4747 + + +Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/build/shared/lib/fonts/ProcessingSansPro-Regular.ttf b/build/shared/lib/fonts/ProcessingSansPro-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c7862f39aff8f584b64fa792933030e9488fc59e GIT binary patch literal 288348 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⩔B9p=_05p{95t3B5h$MQx9i@(3wONSiX?L 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�$&jK>gY@(&NKLPXv~&)n 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
    nwo)`U+sn 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 z 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

    W5>NaS_=Wh1X%%pMP{qA6 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 Date: Sun, 12 Feb 2017 09:38:53 -0500 Subject: [PATCH 264/917] digging into system dpi settings --- app/src/processing/app/Platform.java | 8 ++++++++ app/src/processing/app/ui/PreferencesFrame.java | 1 + todo.txt | 2 ++ 3 files changed, 11 insertions(+) diff --git a/app/src/processing/app/Platform.java b/app/src/processing/app/Platform.java index 02b24c1421..93b62d4c82 100644 --- a/app/src/processing/app/Platform.java +++ b/app/src/processing/app/Platform.java @@ -399,4 +399,12 @@ static public String getenv(String variable) { static public int unsetenv(String variable) { return inst.unsetenv(variable); } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + static public int getSystemDPI() { + return inst.getSystemDPI(); + } } \ No newline at end of file diff --git a/app/src/processing/app/ui/PreferencesFrame.java b/app/src/processing/app/ui/PreferencesFrame.java index d0ad96de65..a113093ad3 100644 --- a/app/src/processing/app/ui/PreferencesFrame.java +++ b/app/src/processing/app/ui/PreferencesFrame.java @@ -730,6 +730,7 @@ public void run() { consoleFontSizeField.setSelectedItem(Preferences.getInteger("console.font.size")); String zoomSel = Preferences.get("editor.zoom"); + System.out.println(Platform.getSystemDPI()); int zoomIndex = Toolkit.zoomOptions.index(zoomSel); if (zoomIndex != -1) { zoomSelectionBox.setSelectedIndex(zoomIndex); diff --git a/todo.txt b/todo.txt index 05c9be75bf..8d81446845 100755 --- a/todo.txt +++ b/todo.txt @@ -11,6 +11,8 @@ X Contribution Manager does not show all libraries until filter cleared X https://github.com/processing/processing/issues/4840 X fixed in 3.2.4 +_ EventQueue problems with "could not find sketch size" message? +_ https://github.com/processing/processing/issues/4893 _ "Sketch disappeared" infinite pop up dialogs _ https://github.com/processing/processing/pull/4808 From 9a6bf029b02dc59edfe9d8d5a95004c62221bfd5 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 12 Feb 2017 10:02:10 -0500 Subject: [PATCH 265/917] possible fix for visual artifacts seen in #4700 --- build/windows/config.xml | 5 +++++ todo.txt | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/build/windows/config.xml b/build/windows/config.xml index 3436d722ef..1184cb4066 100755 --- a/build/windows/config.xml +++ b/build/windows/config.xml @@ -39,6 +39,11 @@ directory of processing.exe (the current working directory). --> -Djna.boot.library.path=lib -Djna.nounpack=true + + -Dsun.java2d.d3d=false + -Dsun.java2d.ddoffscreen=false + -Dsun.java2d.noddraw=true 1.8.0_60 diff --git a/todo.txt b/todo.txt index 8d81446845..fd59ae7dd2 100755 --- a/todo.txt +++ b/todo.txt @@ -11,6 +11,10 @@ X Contribution Manager does not show all libraries until filter cleared X https://github.com/processing/processing/issues/4840 X fixed in 3.2.4 +possible +X visual artifacts on Windows 10 when using menus +X https://github.com/processing/processing/issues/4700 + _ EventQueue problems with "could not find sketch size" message? _ https://github.com/processing/processing/issues/4893 From 0a3b082d6b5b3f4635309dd3e98d0d752e3f3ed6 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 12 Feb 2017 10:21:55 -0500 Subject: [PATCH 266/917] add "auto" option for interface scaling --- .../processing/app/ui/PreferencesFrame.java | 22 +++++++++++++++--- app/src/processing/app/ui/Toolkit.java | 23 +++++++++++++------ build/shared/lib/defaults.txt | 2 ++ build/shared/lib/languages/PDE.properties | 1 + todo.txt | 3 ++- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/app/src/processing/app/ui/PreferencesFrame.java b/app/src/processing/app/ui/PreferencesFrame.java index a113093ad3..8d8ef8c6ca 100644 --- a/app/src/processing/app/ui/PreferencesFrame.java +++ b/app/src/processing/app/ui/PreferencesFrame.java @@ -69,9 +69,10 @@ public class PreferencesFrame { JCheckBox warningsCheckerBox; JCheckBox codeCompletionBox; JCheckBox importSuggestionsBox; - //JCheckBox codeCompletionTriggerBox; JComboBox zoomSelectionBox; + JCheckBox zoomAutoBox; + JComboBox displaySelectionBox; JComboBox languageSelectionBox; @@ -165,11 +166,19 @@ public void actionPerformed(ActionEvent e) { // Interface scale: [ 100% ] (requires restart of Processing) JLabel zoomLabel = new JLabel(Language.text("preferences.zoom") + ": "); + + zoomAutoBox = new JCheckBox(Language.text("preferences.zoom.auto")); + zoomAutoBox.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + zoomSelectionBox.setEnabled(!zoomAutoBox.isSelected()); + } + }); + zoomSelectionBox = new JComboBox(); zoomSelectionBox.setModel(new DefaultComboBoxModel(Toolkit.zoomOptions.array())); zoomRestartLabel = new JLabel(" (" + Language.text("preferences.requires_restart") + ")"); - // JLabel backgroundColorLabel = new JLabel(Language.text("preferences.background_color")+": "); @@ -418,6 +427,7 @@ public void actionPerformed(ActionEvent e) { .addComponent(consoleFontSizeField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addComponent(zoomLabel) + .addComponent(zoomAutoBox) .addComponent(zoomSelectionBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(zoomRestartLabel)) .addGroup(layout.createSequentialGroup() @@ -481,6 +491,7 @@ public void actionPerformed(ActionEvent e) { .addComponent(consoleFontSizeField)) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER) .addComponent(zoomLabel) + .addComponent(zoomAutoBox) .addComponent(zoomSelectionBox) .addComponent(zoomRestartLabel)) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER) @@ -657,6 +668,7 @@ protected void applyFrame() { fontSizeField.setSelectedItem(Preferences.getInteger("editor.font.size")); } + Preferences.setBoolean("editor.zoom.auto", zoomAutoBox.isSelected()); Preferences.set("editor.zoom", String.valueOf(zoomSelectionBox.getSelectedItem())); @@ -729,8 +741,12 @@ public void run() { fontSizeField.setSelectedItem(Preferences.getInteger("editor.font.size")); consoleFontSizeField.setSelectedItem(Preferences.getInteger("console.font.size")); + boolean zoomAuto = Preferences.getBoolean("editor.zoom.auto"); + if (zoomAuto) { + zoomAutoBox.setSelected(zoomAuto); + zoomSelectionBox.setEnabled(!zoomAuto); + } String zoomSel = Preferences.get("editor.zoom"); - System.out.println(Platform.getSystemDPI()); int zoomIndex = Toolkit.zoomOptions.index(zoomSel); if (zoomIndex != -1) { zoomSelectionBox.setSelectedIndex(zoomIndex); diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 7e22da357a..5ceaacac89 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -787,6 +787,7 @@ static public void zoomSwingFonts() { static final StringList zoomOptions = new StringList("100%", "150%", "200%", "300%"); + static public int zoom(int pixels) { if (zoom == 0) { zoom = parseZoom(); @@ -801,15 +802,23 @@ static public Dimension zoom(int w, int h) { static private float parseZoom() { - String zoomSel = Preferences.get("editor.zoom"); - if (zoomOptions.hasValue(zoomSel)) { - // shave off the % symbol at the end - zoomSel = zoomSel.substring(0, zoomSel.length() - 1); - return PApplet.parseInt(zoomSel, 100) / 100f; + if (Preferences.getBoolean("editor.zoom.auto")) { + float newZoom = Platform.getSystemDPI() / 96f; + String percentSel = ((int) (newZoom*100)) + "%"; + Preferences.set("editor.zoom", percentSel); + return newZoom; } else { - Preferences.set("editor.zoom", "100%"); - return 1; + String zoomSel = Preferences.get("editor.zoom"); + if (zoomOptions.hasValue(zoomSel)) { + // shave off the % symbol at the end + zoomSel = zoomSel.substring(0, zoomSel.length() - 1); + return PApplet.parseInt(zoomSel, 100) / 100f; + + } else { + Preferences.set("editor.zoom", "100%"); + return 1; + } } } diff --git a/build/shared/lib/defaults.txt b/build/shared/lib/defaults.txt index 1c25c57b2b..3beaf068b2 100644 --- a/build/shared/lib/defaults.txt +++ b/build/shared/lib/defaults.txt @@ -107,6 +107,8 @@ editor.window.height.min.linux = 480 # scaling for the interface (to handle Windows and Linux HiDPI displays) editor.zoom = 100% +# automatically set based on system dpi (only helps on Windows) +editor.zoom.auto = true # font size for editor #editor.font = Monospaced,plain,12 diff --git a/build/shared/lib/languages/PDE.properties b/build/shared/lib/languages/PDE.properties index d69ec6be17..c195725736 100644 --- a/build/shared/lib/languages/PDE.properties +++ b/build/shared/lib/languages/PDE.properties @@ -167,6 +167,7 @@ preferences.editor_and_console_font.tip = Select the font used in the Editor and preferences.editor_font_size = Editor font size preferences.console_font_size = Console font size preferences.zoom = Interface scale +preferences.zoom.auto = Automatic preferences.background_color = Background color when Presenting preferences.background_color.tip = Select the background color used when using Present.
    Present is used to present a sketch in full-screen,
    accessible from the Sketch menu. preferences.use_smooth_text = Use smooth text in editor window diff --git a/todo.txt b/todo.txt index fd59ae7dd2..806bf8b168 100755 --- a/todo.txt +++ b/todo.txt @@ -13,7 +13,8 @@ X fixed in 3.2.4 possible X visual artifacts on Windows 10 when using menus -X https://github.com/processing/processing/issues/4700 +_ https://github.com/processing/processing/issues/4700 + _ EventQueue problems with "could not find sketch size" message? _ https://github.com/processing/processing/issues/4893 From 0482a902c8ad12f7b4f09cc37cf138cf0fb35999 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 12 Feb 2017 10:24:42 -0500 Subject: [PATCH 267/917] remove the old Source Sans --- .../lib/fonts/SourceSansPro-LICENSE.txt | 93 ------------------ .../lib/fonts/SourceSansPro-Regular.ttf | Bin 293956 -> 0 bytes .../lib/fonts/SourceSansPro-Semibold.ttf | Bin 292404 -> 0 bytes 3 files changed, 93 deletions(-) delete mode 100644 build/shared/lib/fonts/SourceSansPro-LICENSE.txt delete mode 100644 build/shared/lib/fonts/SourceSansPro-Regular.ttf delete mode 100644 build/shared/lib/fonts/SourceSansPro-Semibold.ttf diff --git a/build/shared/lib/fonts/SourceSansPro-LICENSE.txt b/build/shared/lib/fonts/SourceSansPro-LICENSE.txt deleted file mode 100644 index df187637e1..0000000000 --- a/build/shared/lib/fonts/SourceSansPro-LICENSE.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. - -This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/build/shared/lib/fonts/SourceSansPro-Regular.ttf b/build/shared/lib/fonts/SourceSansPro-Regular.ttf deleted file mode 100644 index 44486cdc6702b42d1ed03b02779d6f47520a0e4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 293956 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
    =7tP=r#}8@P$womCCP)&kpi{;} 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

    -PP`9ceiuw9(GT= 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%0A4Z?eHaw!!7d?uQ zU(=%YZ(3vys&%0B0WEjX^%w7%ShNncd_lIMHQbK*9gC>G8|M!6J&Udh%=S3T(DyC6 zMlc`5xf9iT0$nc{&5v>yd}5Ik&^>XI(0vxsI{z$A0s4hS*IeeyI9gAKETZj8%Ua2U z!xp(2{V~pH^oT`t4EQBZeU{Lv7T%8#r>TY04RM-TbZzA{x0r=!7Ypy*h||v^C!(bm z^E^7-!aH)}jDT|Dqdz*N!>Pc$2|X3GUu{OI4@Jw^p&uz)#twONredaCooS$L`Xh7} zT#T7Ab7+swrI;xvhq`y>VLpJ)2W@}_lm+yiYB>!!6Egi+?%#xWy-K=Lw6iW%abhzX4rq@oz%cSwbQ7S)eRK3Fz}cIfd$= zS|8w(Zb!?JathT$Y1e#nBmOO@mJx(fQB5m^w63(gAk-B7&=P8a?y!U!p_(5EX+3M1 zg1;2qW$|xAcU%0cP};5HUx(6e6`%5TY2r#Kf*MOG19dE+Y!nAds3q!ILaotSmQY*N zw}jfEl#3GTfKo0>h`!*~wuCyNl#vpmJ-T%*p{{76CDa|IeJgtU?KZH4iqVFaP+v6J zq9@rd<>*FnKLE{y9L%(B-q#7xb8xqnB{T}vJhZ`0Iht$HGj*4K=#uu(7_`t5It|tI z^~8Q0s&PYTBHG^)Iujjl2~9$);5<$RS(JSLjL8&vvIT^h=&Kc-@ zSb)8zd7(x7q`S!Cj76`vIGX0g7DvOr0q((XZ}dL+3ugMg`;f)a{61{a{_U=UM{zS7 zrN1bSrt2|y5wn)VOBU_Z?#u8h_A}7eEY2MCb&GQax*7g~o4M#47VY!y7TAjYh3GpL z9V1-ElmLzE{W#;%593Tg=?4L)qr2l&vX2#@9cn(j1W3gEBzhdsu3Y-9mjsP5Q?6bU zpg(CjdCj3c=3CKx=#2Rjv+>*0%U9200yHg)En425rcX%&`mmy9?=dz7v_NmMxEoQ;gA#_N7WePy zZE@1k+b!-U^o}?g=yHqJp`IlLWTW?5v<|)d;oGZuFn`fQv$RLhsL)Hda5*(ubkr|DBV zf~Eg-D z;uN9#E$+wY=W)8CUs>E;=+|+&q2E}v?R($G=`PZupT)lz9cb}qqk~{D<3Hn2i{mZ+ zT=YbX&sfo-)Z$-_j~6kCKlbNhNBjliKbh0uNls=$oVMk zSke7un6{|M1t{%L(fwt(qeUo(Fl|E7y;@kq0-29e_loY>!qm4S*P$9N=sql5WD&|L ztl@(0$->m1BG;qTnWFo%a4(D8fcCcN{w!Q5|9HEz&z#IVK(hBg@Sa-zOICCv6v$CR*TW_?y~4vYIwOt&(_2D zSoEwee6K}{(fcfVZWmr*kv{1C7CplYKVXr*=z|tL&kJk*LHePZXV9~~@Iw|UK{d~y z=X_yp6CnN3zgqOnFZ_r_w5>gA(euBsmJ0}NF8r89&jQ1bTVxRWgvHcB*H~mQ`lLnA z2*XcVMEj$bDd>4&Sj!P)0=mwk=VW1Riy)_?+WtV#%);8{Kq}GaEP8$xe%>Mz(HAUw zmKNS%ku%U2EqbOFe#s(dqAy$Yj4iy;B9qX+S@gUu{E9`+LjP{jv$yaji_Aq|wdna% z_%(}Mj=pX&T1T5L`dlLX4~w2{gx|2}Gm7w=7Cq+(Z?WjJittv8o_U1dvgmV*@Y@zW z{|Ilh=rfG)I~F|)3BPO6=NaMmEP5^y-fq$78{zjYdPWldz@pD8!XH}n%p<(RqR%eE zJ1u(t5&p=c&oROuTl6d>yvw4`Hp06tW)}L1MW1zq_gKt@=w6GS_lG~Vn7h$^7SVKl zW--gr{T9)*d~V^nt%Sd@=<|T^mlmGoO89_9pACfnY2o>-# zI$~I3lh=p?AOxd<-CoQckcOE4Fpb6_s!p6KO3UAdG+WIkL^nEyZ*!wuL|7Lgm_R?L(|WGPVI z&b#PxxCi@_(0k!Q%vv5R;ZfXtjIM^qF#ijE+~W2|wGDyW1Er5CuGYy@7Ux^^X^T4$ zT?^|7hcrdBte?ev4Z7ZE{kuVcOw)ieRWS3n|Krl9-y2xF<@YQ4Q_ zakbvIz*g)Vpl`w3m{U+KYtZwF$a@yIF}fYzCw$5}@&SB^nL3ED9zau}Ddst7GmAG5O@kKL({G|-i+3d& zg>>xc2hj|R?w_MM7LPKIwzq_CL@86n-+*?60?vOtw38)78;f>@ZiIOiNNncc zqWj@!FX)Z^&1i|mUyly7c=W|6?O4&hbd>(Acz;2sTYOEUmKXR}pjAM6{Wj<&a4BX@ z?`0N$J~{`k!M+f^4i;h7v@Egs%g}o){$J4*7XK0S0U#ef?KZ0E0RJ&m^8^0l=qih^ zX;weruS3-x_x&f(HSi>6h_1Ex&!FlK^`Azcv-q^tbn0F4X{YJbv*J;f=}jzp29O@L z=ovsd^{9A+mrfZeK5aie&*FcDmRkJH=x`W;o2_UWoPv2HItEU~{122eQ~bBl#c&g5 z`bvgl@%N#=#s3_wZ}I7884WBxeJ`V-#eWBFWbw&sMpKKw9c^au_oHEpzZY$5@jpXp z7mEK0I?m$nLMve+_B(iuC=D1JJnAHSxyAn$r5>`MzzzL1`zfIO{2x);Up8s+>8sfr z;6=>8ps!f`L+Gm(|2yWl2ds9p z2aG7s935Q{T`;(EL3BWL()h~NUUs0|n7Ckc`{-&ZD?f{WN0z6rE*{`VRAeKG_Y#_3yx~#4vnsMb4tsHm#>~v(tLGs$>`?k>CyhHHf5`1M-Z z@NX7I{@tQDZb3;91|`vdt(j9wU`S?qbG67!&rBzsqf3apcJ9!!^8TbWeRMmP_icIk z(Q(?E$9W^Jt$Etb&xtgyCkbtz_HyGU-U{xKpOu!RmQGP_Ml&_ZTDe(JoolTO+efzTs0ewpBi_7;U%vn(d8nI(8ePHw@oU5-jvF9Q^IY!SESi2k>=w>(h7l| z*n)I~Nw4l4BcwN)0K^%LT-;CJ1_$Wv9;5;OGKN7V%!Vbf3h8D6>eMMw$&_H3@c#+Y=^@ltueR8-1?yK>tY}ZMNkTpU=A!5X*(a5!&=xPl1o^* zgq4f`T>R(aza9SD;lCaJ+u^?*{@dX{&x16etn!9ICCmoODsL5RgdIRxwNHUuSPh$C z7aSJJPl8rZ4COE#=EHJW3tM16zfM6Q74l&ajDuOQ7*@gt*bWCpIwn9XD28&80@77T z{DlXEk3fMmcPa$Z+=+Xg(ax%*z4H=S1sh>691-b)-!8dO0u@jN3t@#w5ostQ4Mn7( zh%^+Dh9c6?bvn$4<**jEz<&F}XSY-|9|plVAdGH{fiSueMmNIfc2J}{<{s05aC#6< z55noO1qi370O9n^2g2z&4hW~`Vj!HJ`0YtJJrDBoXaYo`2ufiR%n|8Lo_enqDV{FU zrw43;U2s^WZxXbEVkigP^qmjOVJ&Qd{lS5j^h-tap%f;;99Rmg0e2-wLe+z!F*5Zn&I?GW4!nGefh zEo_1PB102Ih6$uXJ`93!FbfvLO4tC~;h@OzxIaD$ML?QQpx#fQj8355PpAOu{e*=; zy`QiiwuziLPoxxorT8l)>{7xmCG1kdE+y>Y_#KYl;rJbn-{JTjj^E)s;E>1&{Et`$ zYhW|%g(D(mDL~w1_%Evf{FmXs4F6^8VH+F}8R4Nt0f$6RN`YJ` z;a97d@<3pcNO>0YfRQi-=D{+N(S$LYFh&!`Xu=px7^4Z}6v8-#Fis(iQ!1be7QzZx z58HSFnerS%c~(#^6_iT_|6~s3dzhm(`7QbWhI~KoV@jDj3WAQuo052wckOqY? z3@TwZEP++Lu#BH^Vt-KuY~%&&azJOV=f&zdu!9$>F<<7vevvtZ zH+PrF<;z8`sDvZDM7UPuO3LM``65@7-mAGcpR~{C-ZfK17T|ZmGG5$UA+oRs4^ggwGW;$h{$=xE8LWZLuov)qC)am!eb++Z{#{((rPtiQi~Dz{KrWO( z1yliU?_L4xVH+F}S?)m=^nj5t1?Bqy9amodXNT%FbpbTHY@?$+>4w0aC0AS z?!(P}xVdi%%!5O`pq>caTagR+Td^0gzaKyMr@&^|0S9V)+K_t$LV#qO#Qni|b(<91wZQgET0FVNeN#_0kd`j+ZvV4mc$8aw23w4;Tqk zU>+=kHLw}>!Vz9&mcSmQK_Lu-N|+5xU=?hH9dJnG z)fB+pt0SQbmcSa=28Vc|G7)lta9*1N3t<&(h6B7zp9on{0>tzBJXir6VJ|Q8dyoY^ zU?fa|d9VzKXEWh!R(D54{*eN?Py!WD1q)#XtcPuIfDZ#aNP|Kc29+=ymcT052s_{q z9}gr#7W9CTFa_qpGFStfVJ{rvGip#&J8=csCJpVHiw-g|G@X!vQ{`NQ5jPE$>yrJXir6VJ|OA zdXNPrPzm$+z+$?{2aLBLY~e$TTv!35`$N6nE3zXAN}wF(!!lScvNHk5&(3_{{!Z@i zoC0%zbnjdVgtL=yb`s9c!+fMc`aUAAj|zdXKH4GjG2wrV-N*RZMVPy0!$H1V-^>GF z!uVt@-@cE8N~q$4jx50cr^9#%vxbj1@cS9=_Y?2_rF_+o{TGD!MJXJBBYez}2x*WD zJpeafR=^=X?jZaFn?(Lu1cdihD?q;{PhXSngOhkLoC3K0W*Knro6REME`${#hspsr zhi1WIk?)A(JL34BbbXKiAF%%c`@@xh-^2JljQx)z;h@M*gz<9;EaxK-;{IhErzAW0 z*kg$psS;yK;IJ46vzx_-94RngOs!Pd1lz^O98Ge*O>4dlb*)o06*-hP3j;hhfQLda=+uu*+lUl-5@4?v6u|*XOsYbGqYei5LV`LF-b}3-a zA*5s!R@wC~<2Njh-9&+)^e$=!(C?>Cp4=19qN=*JpF&(mCEo_2aVhU!9 zDa?f)!2LqPC{(+JumaY@X4nfy#B}y}nT7NfVb^sWY~iB_uDcI|17dpMrzh7vcZlhQ z``)-KULvMXrI^0>?Tep&0!a{sd?#UJtCNJgVh5cft5cZTUV$PW&W@RW9KFJno;L04wpK)GE(9+_8mX5+DjiPzsY^ z4lIS$unBg-VKKKRK`SVRa+nVDVL7Z7vy?Jjx?jv~l;`b~+3l3&9fWbm2G}BI8RgHu z(kxp7D`1V7JI4Xx+&Kphz!5$!q5SXS`mV)5cy|%^-BVyTEEKbR7*xPPG4~MmJ=+2E zy-UU17Zt;v&#WM>6@LLt@wi znineJh?ottU_LB|wXg~Bv*Dna7m4r1D3I0{2f;WoFX858^ksBoshGcU|8JOInJ(t< z#Q%57X%pA4E(XG9zhhocg4M7Aw!?lnEM_zIn_EE<5a#Cju!RqvQlS*MeuH~&;QkH5 zdK35TL(H4ly-B{`#Lt^mfIIdg=FQcx5w-(mvPB>TT0svW%q`@5%Pd$3%V7;{f*o*B z%vKLlfiSmj5%bm{Anvzki`hn4><`R4NpOgdrIrG5y@&hvNXvWNdylZ*Bdqrbi}k(P z&b{rqPz)ns5)jt*#jpa_!e+qFcGA54h?w`M@BvT);O>KMVm{0Q{C!B6JBom~cB~S! zlXUDPT-NmFqaHx~9~0ll8^r7?gk55GbG;kCyVr~PgmCu=Q~>_>4ud0NKCKe7kFfTw z7Q_18?8kmT_xE$}bMAeg zPl>Qs%+D*u94Qv_%OE%;rh2KE*j{nuusBYMIBtqKUZFU(62$Q_`-j9yNQCX;)Ltr1 zopIvS#h!JxlQ<0K!4g;jo5ZQt18`Fh`+6&3GaMABK7Q&KK?UHqKJM$|zWxDml9Heh z%3(Gv7pK8uSObT}X&423-rfm9%z*|1BTND`C+ zaYhb_6CDP7#Yr!Q&EjO>He)&ve#UCp09ydR8Mx0Ryv#Jn2i#_s!yF(!o{>43YhWX6 zhXdkd38X+P=mDir3FISZ6C4qzC1JHBoR*}iCGoY~FHWl>m@iIi4+y_CVYepC*4%4- zSe!QFV7)kP3A^odSP8_JI}$dD(=H3}*KU_MdBso#8^vj#1Qjq3aF?G3+{@o0P6xv3 zKsq`sgH=F$9X;p)gw=7gI0XWQFbi;3uo?)r0Jnuvm;&p?>68eB)roLAZ4;+6{yGzW z=T<;?olBt-2&eM~I3P|J?sXxYqEx_KR0NA*hd5m;05{#Hz6Zoz#VJXE+2Zu)x%?Q6ct#SqGz}VdeMZo^~a?n668fXsUF6ya8 zJ+*j7^w;0kB{Tf8>Gqm&&0r{Qm){{dRM0Zdw9Kq$+~k7f%$Av<_nSP}B&kI`uU^`h z@63PaqJkX-rlPd8aBAl+=TuL37X32wF;);l$(F^_mMm$K&G#Vxefd5kStLM$#ALPC z(#?`aT&YbV2w)4Q8eifakmi6yhTzt}mK_?6wGQnBYAiGz)_NDc`#N+#R7?j_{%<0%Bzg2Zk zr!Ix zEv`pzS=n~@xr6%@RGvNM^a5wmz4s2EUDoE*b1$5wf7zINHJ=e@T{-?w#As{HBQEVX zHMN^SQ}cs5)tcllDF-!~-YC6ML8DCmEi((MzxeV?6Ll6%cyPjt6SN*Q-j9N|-tT`M zZ_xW}Yz@lHwbh@0^%XI#o1lNhxu(wb?>A-sn#ccPoj)UCYQ?tYFu9GA+x!lH+zvWr zb}DE1iF4X75cu=V)Unhz?Cnw~e8Gz3Wb^ z-j&`iNVoR6lAvw||A{hsh7{J+NFCCsqnp+jZ!~SuKE^vqTY?_ONLA1vlYh&qOzoK~j%)jyihFEdR>^+)l#k-rnKOHcpr`?(FXtV%}(&SR%ieD9govFaJ7@Vpn|<;QO=T!g=)`Tvi-*sbZi4d^RXCW(^VHX)wB zTL>pz#{Oacel15$Grt8rp8De?1(U7+y7Bt2x8)g0)s_{wX&%pOkgw#hX;RS3bV=5h z!O+$vGsG{MYnd5#8#O4qqN;96U9WC(-5K-Fc0J$mI-T8rN}=b}s>NSqtKJal6OHzX zm|_}G+a{g6bZWA+`U8`*v`MEfotsp@6VFFa@{ufK{xBc$TKK(*I$pJjT2G0#o@!yR zwNw8$xoA?5XSDSMNjD_@g3bLrukJJ}BzEz&1?P1!X(V;}wS_agRDYu5uFeTF86T1v zA&!o_|6zpC8BFIbof~upJ9Z?{*{hz@vSTl1h@8v}zflT*U1E6gX;Kw7?YaYE3y6POG{6@WK>?>s7p>Py>xW@i5a~|cbR(0B~!bM?wvtx z*?A#M`PGxgd^ayPDNX~8U8kJkYkF|P*mYuOu}$Cl*e z^c&OZ)RPtu9X#Awl#+jZ*UqJ#njSRAU(l<4P);NGErGYQ#>$tWHR))f)zada4wkGI z$y!g(N*jD7iPv_mBvV%8g>zlHj1?9!r1G_J~{JP4q{RR%~HAtZij?ZFjl?*= zE-LDptK&-!?MBv2P2au_dXSM%roZvJ>Fmi(BYMft%Dm)R-3QD%epo-Klg77?e)FVn@hV8fiFAifi)q zUs~9Im?)poMOM7J3fzKUhirG#=8G$mnl|tnG_618g4Y@5o-V5F+O@LC3}#B^Z|Sgr z*T1ioF6aOGcpGWyH2U4riPuT0x=6JHa!tx~2hvDVg9)Yum8p9XCYWPWdrZ1BUAr3z zxl1m;pld=>f>*au-O`DrbsN|966z;(op#CM;R*G9FH}F_L~`|1r%8o{XBC}?8Mwo*1D_04h5JTiAsViR^Cjq3Kl_>pJkmLAu%zIR-c#1qVL)ANQV z`7K)HH@Ttu`RX;dH!BE-3!2>?w0UhC=10<9|JSzhKS{Sv{x+GEcBkJYuF-~#vj^5o zOY)M!^#)$}w{OiI4`%nz$?2c{VD-drgEDJH+}{&-ZN3?f*R7`o;2l$Dzpj$(c*2mz zs=~DArFwdw6YqWWnD&|glTH^j>5W>M9@V?eqt!2)-UH0O2?MH|O~7q?#;=#n56l{^ zWm-*)DH>yn)IK`2{yKu`UW1)BCC?g`7*mK*cju&){@IjtG-beL)QGQnbQcm1?%R=0 zT_)f%V@I&c)TyOQp3CGMYT1kNw{fEeY=!HYmTcfU)nkNfyrEBN`oMFBncDn4g{=PR zZCanvy<*I1310fpP`E={$C5S;TP2>@r)AIFa6)os^ZIEi$2ZG4=gjJzozrqoNozLM zPiY!$m>woQ{M~oPo!Wep*jO^;qME!Or+Gc@n7oG6A|%Pbn|Y6bbXjK?^0k7wg=QYu zXjYp9Sv?L@i@>DIl1O0Es)=H4Nm7+W9%naRZn=TpsBW|5B=em)> zIeCLRHp}cbtWSr&9g7N!niV9bM+%*no*L0SBePFM*WRa>WSw@>$RQ)TeAR;!ZH9rF7(FG^|Iq{ooK-C7hh zYM)t_n9+A!&z|G@W=5L~ZIC>A=>JFDn+HaARQJMNw_9p0t(IEdtyb^*E~(XObxRuU z(u}qlX?D%Ncx>Ypyl8CW6~}BI8;E%!d3gztkOe|Q0ytpou^|Kq;juX2kcBM}mav%c zfSC1pTHo(f)!o#ZfqdT|U)~$K{kx^xRi~=XId!&LIp%lmi4f^Q`y%@FJZSF$5j5Jj z5UFu%kVa}b8Qaso9ZdzLyRgi!NzTwzDpwt+ zg*_&&>0s6hS8Q3Za&#`8nLbb)+EWQwmHH=IRwrU3!EAE<@h_GueRGcF+?h%0eqw69 z;)=A+ExKJxV48ztvs2W62J*mJuRMzdysq|MDvx^a<#6=b@zMPGgbGGVr5FG)BN~Ja zpEL+kdFf!2td6L(w_~M;87va6Q*(3Oxyimj$<-4KPMtl=9$Rm!WM)f&Hv78cVD&`( zR_dSClH1I(UxL0P(7N{{|KBY4^gc=o+sOczp%WHg9vM)$^yQ~4E9lBa@Ya%LMd0Y( zD95_+nc-M3x*kH;L(ta6ChkS6DYO!^w383V$L&sFQaI!c%MW3N!lPTK$a>P9?>X-13J>kfb|qZx9m)P9 z$4;boUR6sDl~bvqp}~pe{=$4Nn3?}VS8OmAt$J;aTqIoTw7KW|3UmEFd(&ZOF_51s z^fcSsJT7nV*i33>Ajm#g862n#l?E&IHYzBaR0TZ z>z`)n$)RYZ{!ZFk6IcPCR6d4P(5asZWoPu>>79Wr#2nJ{vti!bq@~50$Y7>O#CV#Q zH^!p5TonJ<^L4K>n+k{1>2MgH3;f>ZbDKk!PviGonE!E=8d4c-_&uyN5*M^O+VQL1 z_|k=1VVT=gL8A zr`9z-M~Z?uGT2z8Nk#9~73N588C`q02#N|N)@);8{5(%v7XNRAY%E#3clkE!6A%2^ zQ};ixs(hrr`1McJzw%Eh7^GXrBA>FmH5dwxDXFi^-0sq1{Q{!Uu%_>lCZy@>I8biMh%JznBfPg-az zIxsqYJJJZW?I=fJ+>WGKt!n#`JwF#4P`fF%qm*?oqJM6vHd}2p`byOIqv~ZKiUv6K z%o2@kG(!6!UdXx!4$WpVvxf!-4$ow>GlvIiQ&Y9twOS>QrE@Bc~7CRRVx@JM-6rzF1DfBy1 zgvHYExhjINLbFRk4EVf)-wXYYuZ%tUfkm#_(xTN3l4om`OD!zCOJo{-Fzw( zIPiPStLt~9M@``lKUy0x%S+X9Ht4XDEpRuK0^6ssM0P>XZQ?`ez);;7Drp`~=(tdw z6nqm3Y!|+XwNLv&s7_7Q5ht`Ha4;$7Mk+4rkghthm)n918L2-_lm7ZeRd@Qx+YSVh zQh$n+F5zAtgYqO~&s`XkOShr?zgX`b(3xmDRCPm6g76A8i~Sf_$tJy?j-IaYjE_Bk zWU$h9jm_3STK_!fV`M9TBl=O&`yn-)?N>E%ePPS-ajN?8>%=EW^YC$DXp#Z2<#1yf z$spM)vPk-bA?LZu)u~#1Hj~SAM>6i-p{)Px!ODS1HBb$wlde$O;~&cV{ew%6YqIX*aq@-q<+dSya)F@Xy8f3))5yijp^ek6*4S>xwWrx|{Y#TW zu@u`^_bz1yNZvT`Kh&>A+mPO`%c%o=%c&L^h)~n<{{w$<$6A}W%?1Twsgs0 zIMMAUzxUAj@s@TwOg*hLH_W!e6l8bU$8Wy>!dQzF-<>U^=z4M?m0Cz{s-Jc5x01WE z*@fgc#kzB%YyXI``1QRcZ74bobqRs!0rZ%p70qB5dQSe6F5Yu5xI4`^dhX5|EIoFg z-ec#R|HpkJ?Y?$ftEaVe*Bjq_--N^8K?ba0W_kXUr|7}|KlStfx~iwo>n-}OqB-8I z@i`7z7S**UO;HW~(=Le~0tz-QST5nS_L~)DV z9%ERS+u%tPzEf+TG2v?(o-^U&8a`~oQyN|{;j0>6GU0b=_^1irr{NPSzL}#~4h=6e z?~C8o#&wH^*VOi$4)AJFi7Rh;@`Rq2+sbGm`v=6?Ne?eFea z|Bm-d$6sN>KdQC=4HN!B4S%JI^WRtLnzeJfs=rUMFPj-<1vbbq${L(ecZZB@(G9gm zA0P=ED?CfI7h17<=?-Wo-yQAHFi3`w$%YIvq%2*8FIzn4#xQOJ1b4P45eUO=ew88a zVA3LF*bn+9JAENX7%?$-A~wby^*I7ApDW}Vu76&On)%{De@`~uBjuehKFtZ`JZF`^08PS!2Isv`!$Jg9U5NN@B-mbX+u~)yD)Yi zbjNE9GAH>Y;)DTs<&3xubS)oOqVy;O45_^HxrqJgdC;3*hBVAH^JjB4o<7 z+YhtjygiRa;=E7bNw(jB(_R&L#)K2E5%`1&U(oO&iBtT@jFs9q@!y?bW3rz)1#w0i zUPihScoXlx5zhms{==M#I}+c3+Ai=HP&>$nZ}WbWHb6WZj=OE}qzR|-i1ry1PW==3 zgb62}E%0FzPCQ%S1rtuZMc^e9PIM9Ykcw~SDCSAS%PcF#&&Nf)S+uXI?Kw`eMc_Fd zS30f4vju*K#7B609ly)azR5~FTeQDh$3aix*#f^;#i^g1XA@35n;fLXv(aBLfrFbF z?lVg2@gWUS3%Z;peN1pnIuldm7-bt8|FvXN1vuM4)_>FOVA7@ z`5e&Mr^x4OP_x|+Vy=cbkJD`$Jw9pX(@uF?V-p)<(mcs7>#m7F!s%^sw)Td*otKYL zvspWw)g^8x4EelK&+cyj)_66s|COD5y|(iC%1~`?!Xf(+#|HWcyv$Z4zv(sM{lLEh zJ&lUU&;*V5+9CU!hWLX2A6!_*3fcJ5_iS`+Ze-8MvmDZKO za}xhH@QRiAqritH4qcjs`1%xhLEx4J^y2eYTK@tclI_Ls(mEITgltdlnQvK%4+^{{ z@#W2&<#T)<1zxtip7WvNX2$YEF5|aa=5+1G$cM;i0dfu!9|_fBod*t$%&)-_b=H6ZZG-aGK%7PBdfZ4LGe+ zfe)!T_y^)3HN4F3ROPiY$=^e?L9_3X2NN`i}n*Hd`-i1Dh|C3af=#$fbBE9 zpZY1@Go-c8ncA1xKFQ}+O?V!-&L`yVstb4J{#7v9d-vS@GA3vcIqLf|>m zdx%d6eAtAO920oKgl}m04iipv6YX`qGe>cg8eV4m`FMFeCFdWaea-Y9(u)Ls$7S%l zO!#A3`@2mz=}Y20_i8x$qtS=-CFs+9PZ;|}JVN|kN&7pR2hu+T{#yQbR!jfpmvMvl z|3sD{y zdEL^?)KWN#nA7jJx7Uj^YbV}G5tQy1^N!JdgU5;+JS1{#|KN$jEjuatl&xpxf^5Ec zfBkI~hq`mP{^2~fD;3eR=D;^R&>|13l(>R6BXk%Fc_bb$G)-wi)ih1gZD46b3zE8V zHLF5bGSfJ&@(>BOv2@p=Qfd9}751m~Uw-+^U@S*dscScGFC4sY|Ngu8=ec5enmzZ@ zyYIOjbFNq_;QOz%7C=`+tm?1qZ=P#fe#nqKpF=;WFD!&2V$v9=0v{ZrXDDQy@>Rra zY>E3lsK)*7o=7HJn~$`2jnxK*E*AhCZAm6vaYxEk3Jgy=`(AmpAsQIGQ;du3W$%_e z4{LlIT;(OAJ;`#>UfqiVC!Qzp9NQ(|lOwumIN#GW|FF+cjC96QvuIJLGE7e22{NRT z8>D0CA4z$#;*-a-8MB?`vrV2J#1rF;-o%~L2*wi2T88`b00yZ9SWU6P?B>47jDPyt z#f%#C8>;RpXOrqlW5^I53}qoT;jvbZ-n&N&`@M1hc#mt?Cp8CF*%E3kWz!DMliiZO zMUCh0;Ad%pPcS1+vOwTNDh}C!cw!Adz*HMS&V-lQxRepVxjd)$K%UckIPX%QubTcY zkG~@s!efDXe<>G@WS}@Z37pPI0?(Lm;^hLL&~P8c6l?flhUfhKX8eGLBLxk>vkFUo1Dd^lIN|8KKLyV!$M@5Vw@lKq0`A&>t&4{Rbvev6He@V0; zi#=aSYW4_^Uk0lr)!+!jxoa9WF^ea3_n4-$CJgp=MP@L>~9dW*mdCYI3I9h8-!S2N`p7c(>?J zjoM=__kkBvEc<}&M{2N?%LTzXaSne)oS0@`$Xh37J&4)oQL&hP&WCwaEO%crzslL~uVtf{4!t!|Bl-+6kz-`!nNS+E?> z3(7OrDN7EKc2dXswPW+2v?RH9gp5p_KlJ$gDTowJI8!#+mSFu#chu)>Z9dxGxiGSQ z+&*h{g?pqt9-nNle@KM!V;|GJJj2)jm-+fPu5%-9+!xPqeOR>T^QgUt*1y2@^`9ep zXt=r_U@fzD@ZTlh2kpDZ_`chUCrvo*JJCL4!fAgAd|2Qj2A#j3VyVe)@k@Gt1D-VD z^nTGkW5VhE0v|TvBr63zq~bWsBKBRw%a#{u{mb8_^)K4j)b`i}zu@N`f#(E{^@BKe z-hV`vqW?*{lMZwiIPGhJPndA(kHCji9Q{E&yoQ&VpYO*U&eTRc&jR4bifSLnsWoUh zrmonnO$f{}%+4<{hC+2t(+4W~0TUt7!yy1FpX?1L5-?0DT zZ{0OHh-tw)YS=$FLKg_)T(w`NS2t+`-P>vd6g`VI&h>y+(5o9XY3J0T6NJbiC#!YL zU=yv4#OYKdBK(D3N%8#%V`h71uUpC}jD67Y_QBoZTIS}Znd?__`Q10pEF5jCKh<>D z(SPK=eJ$>`=hA__$-chBuQ+hv73=+H&Rli&Ec#D&_ZO7o=zmt%Wg^u3$hN%~x(rTw z=pnh`F7nkD;iCxxquHgWs#asrWhjYoK%x9{3h}FW_0WCxzr1B!t_7iJbYyWZs{!wdH!|%~>^hcvx*3Rh$dYk)oT>HEGw7;X@*YO8T__bR5 z2Tk~}hCig?^!qAZvvy8b_4lzROPho2Ul9{Gh$!rPRsImC9TsoQ+u;0^&Pt@=kXMsOcp6-Ba_^;G#qR;mAdDGF}mTD-oU0zXV zEzslXs5!e>#FSoyT{{e3L~*+%&}!cD2P(BBH`U{HbdFAGgeo^}*0?Frf=*TiP|b_y z10Ywe;6a zMC75&#GvhZiV20UihQgAR$`pUBO>eMtx};-N=_ZABs?<< zUe~HGQcm{ejz@#8z8+u4P$nMv+{FAG_z$Ns@g*kg(h2taoG)=)0pE~#o^Y&R1#?0< zUlE*kU$4%H4Bp!=I$hAG4Ro^OpBFYm^6yg&otP65M@1Gj5f4d0!=0c!Rk{&Uk!D1M z1bgu<&F6rmWR`!UG_V}L3CTifV3ZakA}D`FI@sdk#(Um#*_5#1TGPRU^9|ZlKGWZE z{x9%^v?&n&an7#vFKv_SK%HUI87N0f@GcQ6L;hl#b&5d6Nl2PJvgGpR^9=PtWH^e@X#uy9q2HMr2h1E_oR(e5!veDcUh^~hub326Jq4<4*FUHbG;FnNaN z*ORJ5ckV{_=O~ZPfVc7ar*-$wR+7)6eN}4@ocs0!p4D-soy%u|pO?6mzlY?x!0*)C zv;X39Ti`D@;Q!3!w!rVvaP(878_8|ZndByGg^i8!0S9?L;2_S?T7{;Dj5?zyR>;kZ z(39LU4kQHrPLfb?lMvSJ5O@-WkX2Of7%)43V-jqNqg6Y&u!Rren8Bcq6 z>tzxKbDYyr;As<1>qg-HCY;udz{@852O56Rgwr|}?Z-_xtyh8PO*rYR0?!J3 z^BXv9e4n3Zlf3^K%R}%<5ns(w-W=Ksyv!1Oy@KDG@H}v`5if7{n(%)3g1^FTf+GJe zq-SBvxV-JT82PPi;82v|Mp1ccWCcZnQ)C6nBnNn$Dw8OBi1?bC*FoN5k=MbkjYbJX z>3KXCnUW^B&@rXxNkJp>^nU&eo~8$5By0p<0%bnLWi#2vaAvT)lF#uHXje4g34w2Z z5qKZXJ-4OV?P-aB2KX55X^Ceg{#D>v1-wV%6^Z{0cqf5e_wnnz}u(4O$_6A+RTKF0|lA&{jq;Wsd7=2sD|2~7h zHP*AzDXAZ5xpf0MqBLCbUgT!7e!ga&0YGc!ReX&t!=A73eVF0+0S0+3_NNIiv!J>^ zO?VzS+4IpqMM3`@dQQrJBNs`n?nN=s$PSWqkU|39i%(Afh+0RJ7krSxuKH`K6cnyD2zqT5&iJgP$hR_ zqmnRGszli5}Q|uy|t}WLP0t^Os`Wg!BC^@Un_;<|w~ZYhPyX z5o-hs_WS%jdHJ3`^*ts$$_%(dvPQHYH{m2x1fErK%n#0s8h$|P#^^s}1o0u!zO1!} ztTD7NvxvHuO?aM#xvZJTTK=|j5vwTAuL*6o{RZzp=~6H9aTWNuqEhy4#Z?*2aW11p zdsRjYoW><^DJ%Ke;YH%p60aEFPkdV9s>~I?Yt`^EQ+uMPc)u#U^H`_IKh<#P0Gtlu zJ)|Rw_Er5oN;lU91%6)QZJZ9I3kv*By*=ndHXMP!+=P=2N8tBpIQpZ}hjc;W|D+2V z`o(Q5;_p;lM)a3-C4s+&|D6@|`wre`gH?cC=jL;-qrCEeMJ`UJDg8M`)c!d*LFHT5OMVMjHV`I>oqDD(l?fx ziXEY^31%P8el2|bC&!km*{|XtNwj#u8h}kD2dO=-=PWeHGo2Pf+ENY~#g2&4`lY2L z&qqbo9q442#3!BBN*ty5k{V=m37=!!52q^CBE@@)YE4!sVHgp*5|~t4R^wugGLIx~D>I%_`@HB>wVlc1-lZiWTIJm0QsSeH< zIs@Cb8auOHK6a%)m2YicZ|`!)3O&iYfb9teC~!+n&ut>K3(-;(b! z;|H|%$n)mo6YnW&c+T`5;5=St8S8RZ`7|oT+@S8XBw4_d+ZKrunbTzNPD-xZCBK2= zVEu@^dg4D}@SiY>4G`6moCnj%guY3?6GdOc>tv(#C0CFdL?hg2$RD@yDu8b)EF=n* zp?E5kAIyjRVShR`RJ}b^+h6P7Rq_R5fl$7j5Bd6L9sZuZ*-W4}7U+%lC!+oNVkFVG zw5uLsKN;LR77Y|fqv=XM)8h&C`qQ;+e5}yRY3YHiJg!^?k@T*my@x3g{u{NX+j-{u?c$9i zUv9+{Mx5^p(LQa$Ne>fv)`XKDCh&?0Cp}Eyd65??ewXVh0`E7q|E1P`#DM?EN_v}U zKW4zc!TE~7$BnqPsI|Y+NsW@Ek+lzSh3X@_cOxdXio!`ctL$ zSVKEuqx(6|dReR?c}|vzEc)s(Mhd9XKt$Zr4p+;HQjCD88bkIv5j#LREfi}>aXq4* zlpfooda)=>My*d^um!NU7Dk=kKt~%&6!2OsykbEq7j*S>!5AQp-Tv0a3~I9&>lbJi z0Su3i?*(O1`7>CfwMdAD`U+Q2DkVvzvk&`+v?fu70lp86Dk`lRhEYuEp+4MEP6O3y zE+o1l6z2m4!WBxn8w)Tft=?qNpglC#$9Y8txhIrGt~2}*-zy37^N77-!lNdfbOzDB zYQ(wDAn>e)=ZIEX`!f6^l!poKr+l98(INi3QFa&q-K}`Si1R%v+NVu8?L~oCB+ly) z@b?q%C!5(OfB#lIVZ{0SMfy&`e;Coldd#w&i8_KLu( zT6@$>;C6O_XC;n3!TyN%zbfX%@}Io_9Opbh;NvEo`XlhNibJZ7mZ6VpEDVB!tYdwfHoN@^kY zo6-Bm_r%5zl}9ER3ywubX58^UxOR??3?CYg`olwe<4e^kSEO^%T?{POrYGLMF>&p3 z?(~U+9ezimcV#wSO?yCRS?`G3ToRU7sN73hs`T+U6hM+E1eCPEV98Zx%-o|AZswv# zYCRym;1T&Rg+Ibn@W@!ok`6{&3Lb4J;a!>1N+pO&migplSkdbpSzq7Jn+3-nA-SE9@fX3F12Pf62fZf?6Fn6caStlR zG@-+oP*S$kvUD(gYQ?cAU~!)oHpA=GQEf7dw{PCwRj$F5K0daC7}qVFjX?vCGeT!fyyWWWw2XQxp0+`yvxRdcY4je*KAw* z&RmJ_#UJqu*KI4|(fXgm{-=7IL0CPtI#|EbDj+;2WPudET(W(;U+yC)ELM?*7mk0W*gW2Bm9cc^pO zQ0q%S^b4Dhh-Fmc6i8RGW4fpUUaOYpJ)w((se>lx78R+Yt&cJ~{22|IY#(?#z6nDRu>(=cf`;5@8nT+IK(?(; zrbqjkN1xz@dc6Y+L&1{E7Yq~&R%N@Qy|KuU(p*@sMX9W5wRRlUd#8_&OkFjXJab_G z;@*)jQ1xEY+34*1roP)dmhtr_(b>FjsqAeqV7Sz57^q_ikS-F?V)~Y&X;|@_{|YK7@X?A^S|z zmK&<0^;1{-sUYlAG#U`Q8IcwwQEBz1E&cqI+leM=J}Fc&jSA^q#MG!yOY$k*MIfzE z_8uCAmT`w{dYTnj+xS&P1TYv7TTqjQJ@yN7xhYtWCkIr5(Imq zz$Cqzvk0r93o68}rQ$(?GGv6KU@FZ~N%i!y#{CKhwlTzpR*GKOnYq$qId8<_?dXX3 z!MC=n@qANiyssBGQZyBEm;P-_v1i4S#vXl+%btYp@oKOm8h2^4+yU6+V#2}cLeN7g zE=+J*9;(Zaf^jvmRG4_IxJCtw{hOuZ$?WLV|_0v zaYw|rlvj922@|qYpW0thej9~lx1FUFG{h{*M{=36&D=x>>t5rG;LJky%CF<>&}@b6 z3Hw!@A5$&vhS(c@euy_A(@&cjim(xN1xaX#LZ7XmL7bm==`?`gbv`Rb=1L*$NtALP zS{)8q6*g+08;k7-X49yYzJDT-oZLS+Fwyd*njP}E$?qf64 zlVsON-<6A)r#@I4wNty)&bHrH%{T#B!B~1BGsw0@+Dj|eo3L%UvC69Gdm5iKntr)) zP>V8c7(x$DGh72EJ%;RASZJi4_X7a)o1T%I*(vg6LW3FXOzz)twYt)s%vgy z?s&~^nTg100RAw}yvYPUr7Fj)g*`ixll}R8ba+>$Z+EgUP>v)A`Ua*}ubvzXjYbCg z_BlM6(NtweyUjTsOAg1odVRaQT=8%ywlLy&}Ia9er) zG)Zx+JvzV8Y$1jK^GH#Kw7cjQKg9H4d79x>2hjwk>Ka~#-lp>?S z^5ivpCQHR)GBO+}E+0$J4uy01zRCF5io+M)?di@WX4hh&aNO0kyVMmQPR7Qaw)P#B z)My5|o-`*)6UGt1src8M6^Jb9fNI63s0c=5qNpRP_+qYZZz!QI_@1g~5%X3jhqd&r zjq_QFRCi@7Cl~U$ou?|(3ky?8GGzCk8r?c4vDvF;X3oyWjvYLF_>ej`SYw-C$5|jZCa)*kw2riF!cpE%QRw1F{)YWH#k*c8IE@@(4t=QPs#^oZg1CL(jf_=lASE z@`ZYWtJj)7^OJy zc@0budqURb1N}v;J*_UPV1(#$eA6Ne(C;7e_vT~WnAG<>G8$g z0q?+ke9Y&i+(+E51|HeL*JQs%yY==826ob*V8!MmLF|S6hFh>Cx1>0X7QW`l+D`GC zq=^ME$`B3&qQ(}Dl8z42w@{;4455|C!u0&C#D#gYV5vALVYtkB^s0$c|4_)CaG^xd zfn@SPK3H`n+@VU}z~s53nQUJ?)|YV{KU}`Lzv?{H-ciWs3mxr;oYnrT%ZHDj9!w<{ zqtV4=ihL^MOPON-f%)|4H@3<1kIu35s^s$gAcZ&>EEQ{Ml`0sOjU>YzIpb7w9jRa4 z6qKPJe+)hc7u#so{3Mm|#z+3>nk4R!5RQ>(n(e!UL`&);>51RRIWA^-iOMmgw@^R9 zTtQ6~Wiv=IB(qVo>@A&OC{=)zMqxA}1&mCj6z*p{l?W?>>GBJc;lOIV2*Y43xQ^e5 z@vqF!?Thc1VgvW0c_Rrt#!v^o@eOub zkLpGJLiA~dk6nvEmfK11k**WdEnu{PXe$XnH}!@3#&1L6Bd2@$D&F$i8tYtJJIRJm zoTz{LBo>!-^Mk0ScO%B{K#{Km# z1;b5=kk99TqYRg>|7_<_DC$X-g2OXT_PILDtOz>0IpPa=yIg+d37x{2_syR}S6_io zB?Ns{yTeIxF@0AVui7Kciq2d#+oUt3@UI!;Ax(-5kT^5rNeGNf?Yj@O=dlCw+7mcS zCRw&3a*IjV{f(vBNj+I3~-ug7g| zJ?@U~j!q5rt^5&9eJ6d=1-y9nnTw=piDJnr6^)vf zOiaikIGvVn+-t9i^8!1+bXB|-nCUOiPS!j=SN<=4xUs?ReP{n-Igp&#`)nz;L2-+$*-}{&_cd;XpAgRQa-#6d#v%UV11A2GED3&5usl3E^mAm4vgEd zftY0hF^e|5C$4+u8vO3Yy-KHb(rRGH#!i7>9TY$!H&zchTd3w0i9hmLlCTLu{`W%f z3Guc>BZ^N!J3J#Df%1fU@Y!R&0|Bwr+)zlL+&U)W7yoT-gdEFO0xUdePvI1#8;DDJs8ndwpc`;DqTT&q9Jlhu=Hx<=4-Yr;7{>jP zw_Tmiiz|7A+Mo}bD-V2M@jHkH^t;DmBwk|%@hSx{mk6-LCI*^Z@ zT#9Y59O7;VnNv&3l8Bcfrwu7k(zYSSr+ZqJBWq0*GE>(6ukLZz{N6O|EJJp5x6sKsiVhBqi<*5t1 zC~+%dt@461eNMc(p!fg4b#~hJ%o2~ign;z>3(--#q zk9^}j11B@@tb2d#o$w8w$h;FIf}X+S*+E-3tVD6$uJS9qvf_3q;(w|qHj1i*y6sNh zK14L-%BD1nqn-#lOV$VUlXaI4&15n&s7rX5J`b15(``R#n<)>^*?(c5b;M_`nuZxD z9>$>b#SNqmF%a4qlA1X+F#&Ut^6aw;ZbO}zI5m?}xaSdfSiHdcut!|F27iUwq?lc* z2IJIbkj~yzO;_w1lEDrxPo-H*lcF_*fjYf(pA_9F6j*Wa8>PlrvF<%ONTE`&HS)f2 zolHAT$iC>LHtGXvU(|f_|Bro9luJ{FzAUoGK$ob#KO1iQm7U}K54;&;5RS_>d8aQ$ zMTm+>ab%b4WAAwnWBF7X(E_B% zS=dus`_*6#(wWQCBtt

    Q@Us>4qht^OD9yd`8~s#$`Zl1h+uZ;T@+Y5e4ufb*q|v z#e>%^ZT#g9>RDHs_v)kXes|rw{yT+K8o}xmTd~ORcbm3o8Tnb#;j#uDPM;s4yAZXA zMnVr0w#O{*Ultfe2wp@L)~uAGzC;#BIO#(YVc{|!>Q`L;)|d0g+r4c)&TKFT&EVI% z2+q-5EHzmVHMIoGbJ^N*Z||>nDIAYSLmufrU{7iJ!SZb1z>oOZUU;EMQzKne>St=a zoXL-74pVbwr%S#>M^8&B#u5OP|u>1UB9RjPMn{< zX?8>(5#TeYlrHjQy_)VA@p)s!Z)MZu1MxK^XrI74jCOarV(s)+HjAJ97SFC z-%xJC0_8YhSB|QDKwtgBl_ZV^6mmtO0s3O6bOb5^Do*EGx`9hgHE6tC?;_(dsre*syei;6=1Vael0I)q+KGoUBG_h6Ek6NS+gY z$@3-XOLbwb(r8E~P@%Wco)t6~_cw^jCpfap!1qapbU~z3V6(LC-*{?c&mJBPj#&4< z!QFgMrC4jN=^gmL@%qmY0ewf(Va)qck^c1}jTDs8C z_5Ccw28A<5=^s{02SygB!=%(VDd&Tn9duJ;Mbtk=$PJP|gwn#?BkSW)XHTf}_$Ls8 z6fTDG|DD;y-yiD?^*E#B>yGr~T0XvGFzd9QSVV(T$HEqW5|z~WtX~c8X~N8{v;xrZRj`EfS^4fy#5qZCHN%_wyK4PqQS7pjqwW1 zar|W)Lpgsg=$vhCw|6?jp5%C;H@sur@zUFvzyAEfRH(94ykJ$1G+F(XeYN>p_fw{l z@qWaL+RrOU9rO=p4)l%RT>$BVTfX$0`yB6hwc%1kiUHkB?M|n6rw|6uc{T)!xD!$1 z*;o86s*puzPGL)8m`z%**51n_!$%pPkBo%@8ho5|=7;dsO^i1z#?|m0`v~;xC zS~^-sUj5Md2|Mma#5FCm*U!OLW@~A0fgDtCKSckx+>9v30fhwd^Uvaht4V6zE{Ex( zut($El4eC#FcD?btVwD&M$wBAs(qhA@Tq#6XeTpt-|=*3x-^-in+IFmt(j6sw|4Vj z+p-cY%niW3dWedV=2DPFnLGNR7!74B}N^Q0oxE#e(?i%6wv za<+N@K)-n_t9l`gQs=T(Kz$#`RKu za^j4$p2&?PJL{MD9f;r3G|@nDJl-pBM7&W~ z?J&N?=DWGB6^6Y=i_6iux|~6ybx?2|p^}OaKOv*YPM1MX=}vmGeXF++1gXCi<_PBi zzoHSxaSA(?RYsj`gw!zF#LPZnYiYWOz90FvC*uh&_74nu@>9iPQ|pmrGU?8__dB{1 zIArmg9Z_9#=W1mrIGFNw=N^l=6WKo6i;%UrffT$(vmrE`1LS(tbO5T9h3o^q7D=j# z6E1Pr2E9NSKVYRr4Qtgx`|MT&?N`|K+nZ-k7)`T`ugAAy?*w(d`f~aTKdPz`P^8ID zQ9{xd&S!UBC{AX($144E{vGjamimy3+lw4rHWM5u4TdUXxzI|o>K|Gu7k2I#4%B}D zdZn;`|K8k(Ur|L)(1-eoTCzdm6rl}O6{&o}Hju(oRlDAhZjxO%B?ZAZeL7zkc?_qW!YYNyHuQblUz z0q+SU-jXJ7VIM(1Bl_C9LI5|_vQ=xM({W8$vq}3Pdna)e@}E#Sbl7{e@Dr}HL4EL5 zeCX!izWd?ol8KhP)(-4>!?#Wp&y5>MSw2;3T1OZ0d(E58Y(V(|EO{dq(E~3i^)#J; zAU%m@s{TWkJ>o26cqUmwc1+@N&}`t!;m#aT3f>4_w7q#Xy?O)wZ}s-oG~1243a_vK z?)d%V^$qs=TGRc+>#S6B7kA!0i;+?$`n<|xuV53PxE{n{^L~+}7e;Y9hm#3h*H+Xz zz~b%;QLdI&+lV1agE`Ac^o@?~EtmJv=e}}JKGNMC$@lc+=rh;ji^Y7tc-+x<;?dK` zA3o7PaQxxpryo7hcRDn4!|KvYX2apxmn^N`FcbPx%-0)@_WEKpE{6SSQC@>_^;;fN z$J7vEDlJI*f|Z^TzHu!eFP+n|aIsXWtQDC)gz;R2J`e)+9#5$FB~6XWN-3eI0Gt+f z5z|8#h4DEtFBz!$8UVh)wSE_S06W(ERnE$jB?e4$v$%$5Qa&wsFbqJAslP%(b%Fvg!zAP*rGQ_77z7cK~Y z&{+eXC7kF5J$3_lpXDCPVeZj#m>axBS6CY4Bzg)jBZ>*b41FWV5jle>GJz;Ul%b0n zEcl+nX9@;N3T!3zL}6;`QAm(vM0lyyLx(uXCS9lI=DKr}eSwmzCm5W1r}NAM4=jiq zz9R*sI{z_I$UqeRx^I5}cl}m5X6qkf%yX81RM$v|&futer-dmrj8@)Gp|@x_$TZmS z)AZ7`;b5O9Aa4L_1k@;30sd!@aDtO?62zIozghgF1*qU3kyQjkkUvJ)e2Fg=@vIO3 zYCx%m$W~&i=gMD?y0lzD;mfW<(EI-TP4wQlc%?PjKz>@peBJR_0@Rsqw@j*YAQczA zsI;z&(sj1#cBFU$p~cuZPo~9Vh$C2CJ;y$I?p(cgj<0*fX|WlqnWs>`71gkZZ5I24 ze*d5WPf8pf8g`WKjFRm$0;hX!*&S44Ug9~~9x>bO4Bfpa@nMMBNt=i{bY z0umpRxcFVvq?h=FsXc1mOT4Dy$W`Tcvr4>dxyb88;9efWVU^HsWs>Ypr>j&MvFe1+ zn@-$h1`sqRb|-w_bYC*nn04cmyuWn!C+rurl%Q1UbQi&E(&F?t{SzJD-u4?Qrek&W zSSV_^2EvQ0kz3X2=@~*1V{z#x<^zRx*de;FPmZTV;{;1VJ#qziu3^O=RM&~r5%uxt z76fDNrHG6b`l7f3S-5S<$`InkXh>#h$%08MIh*K$n2MWRQ2f-2tjj+^%q)tPJL10P zPtV(I?YG<|J`hSOs+RXB*{zQb-#$`D+4TBjk5=v&VIitwj>Joh3$=Rs*^ALr|i z|2M4*`fseqC=)d-w&DpRPPx{yecFVh-h#xlCLB4~60ewW)LW2v-h@+)Jkg(i6OMWd z5+5<)sDC2yaScb!T&jN}@iI&E+-Wf`%7GW}uWIdIP?A&+OXBAx4td0$H{f>~+P70Z zEZP3$I*#_Jhb8fQG@NSqs&u1zSfDfLZSL1`?eFf>{*HcM#~(1^sA(>L=Rp&Wn&uLJ zNWH;6x{*lO&Xf8hIu|2N+^ z_;1W(g27&;w&U|G@HER9aH7A!`%U=AG#nvchW4o4D%&44;k4exd&W&T?I(ffO*rjK zfoBN^AA_I7@(lcMjWs75Gz#!#lHwKAoK!w?X$pUcan9i-VXDWdh?)gS)UxFD7=e#a zJw}O7vS!|%{4&3X-;+4%F@BuaW5k_PmM>8KMA`lT^kjPfH0qB2y#eQSM^XFcr;syF zs>jINQ(dKpWIaaICFRdonbYuhcrNNO;`gZ@qajXGDopx#jXpkX2DGI!4{0?`Shwx? zq&P{pT7nU*IV>tKZm=%3;9~uES&8~jdVf3Vw~%~TA4-+&rEzW6fe+&D7WgyyIO)C< z@!wWHFZgfvZ;&rd`ng`(_H_B8TU1DqC66%gM zsZU|N)Ni`8yxAh=8`UKFT{O)^3GtlYrA(=wbl&54aN>>kKYXwv~^2Fg!#V1?>u*ddg0;BjjM$%_Z+gswb$04D;;}apL!kN zcJ~`%oLHAMPQ*3HanXIe6m^dwlU+s$f!-b9qtXD@Fn_upxz!GwBs;K`;!K>(Znb^t z!l&;&+2wcHT>j1zbT0{89=&F4?3&T~2h`uDduN+r>r?-m?t^WHm6B*&5p#fV6y2ho zsinH5&%WFU*yqB(hgziktWQTMaubs-M)%p!T8Mj@{8wQgt-lJ9VZX`VeeN7f;$Q1I zq2tQAML)WTCj3sHanQtWx%>?-dLJa!WZnZmiqIl&5*^@|UDGoE&iPFXkwodc^m#cC z5k7Vo|IIvp_(l9?yMBw1TuS=5jj?#NqA12dwU&y}y0aK;93}g_`G0zjy|4an?|+ib zF0iIc3+Mjr`*fE!Vq+})4!mZ_Jp8w~6N>kPVympk5&NFPz0I4t$bMPlxgVnJF+TL|l<2 z3sPr_qOU|S3>zLlHIuk)*Up#DFWjD(JvIIvYhwEB?Aw0-*#0KAQh%ap|FPeH+w9rt zgcZg17;G*UDp+XlZ=Q-Ytcw69rRs0V*-ntcMNshOf@Na`~+uhy%L)c}W|C|*)co!^>^ zE#^!F$BO6#J%wIaDkz#b%V(2TrO-sl$VU37cBUjJ5;RRGBC!y@Ad-MH*(6eirj%($ zh76wG_q`)GrY6=3eS3Vi?%NS|?g)9D?oLNKFu0@HR-N@^BOb-xJreWgW1gDhRWF}9 zH=n9ZUE6={x%H^uXJ2n_Eesw%<4Kl+N2dlnh3UfDKG0)nb4`gse+a`Ia~p9Di)IOH z@R3P}DBo`>a2g-qZz(=T@|JbNQcv+27cobWw)`o1L`A4D`HIL=gT04u!-4`LNr%D; zwVYXsjfVTh%>!R}LY3-9X!b_fQlPqjG_y3CC>3Y-Cq@=heMd5iO?hZwZfvaA+Ziu~ zI%>(GDiWcWA6Fi$9Gy*h`{w(H_Xch4=T?T-h6CaJ#Q6!_aGq9;+^7@9-3|35TsP+H!kas5m=dw>{n!3@3cGM;^OS4TKI{_0o~UkDr~o z<+giP`mZTq?gnsX{2}J92-%}qJuVlu!Dnqq^C1m^yAb~;UlQE_brF^Z(NQb`VDMA% zbCHPr)NUr$%6~)@pYXyP65Dw7t^HH!;J{?kSB!hSg_*v}O=H20l~@EtBEqqeTu*ez z!AfncnweR4$BK^V*uiRH=SZ%jD_tB6`wCIF$9**K>*|WeQ(oWT=v-lVeKK)+X}+=? z>DoUNEhpgj;<2tzVvYtZ*Q&bD6?4?d-<*WhBTsme*JTzt&?34!3`(d*?Iga(L6x}l z>eG%@E&PToX^jdz+{g>VE#JDl5D~ML_U%ZF6f>Fl$WpHVP_j5OnX42_ow05dA(|Kq zPsIjGheWRQSi7xblIO1n{kt=iBCRNgt;k?^`&W{^d_DFdp5?tbPZTYS=JnW+ai&|h zM427o%TZ6oq+4agXyE7M%TNY^ViA%Zk=PGSDxxi#*`3FIy{*1nG&NU=78XyGyGN&{ zeC$-y;K}8_u6Q}IJR7_ikET5BT^;Rqd!%|`a_Ht8&Sn@x{r(dtqGxWrxi3{oc$=NW z)!zMl95dKg-^82+u~JQ3rXk8gKl@XZg~-CB=mDQR>r%#X>yc6rjTYue2!v3#6D6Zs9`;UiHX?|;AQ3sUa$RgcWh9;x~+ece|(zH{gC z8ioC#UfT<-1%BmjtQPz_g*7yIGxRxRY zdy3tq>PVn1f9HHlS4()$a1b-Umg<>G+%s@^exT*%_Q67G-|7xDvdh*pnd;3snPRm*uDqrGrSaidiS3dr%4)@uI$9`ncw?1PNy=a>u&;qvxb<66 z<*`kdz70WVS6J!9_i?_!XrW1C?HJ|nGybcm?m+&0q}7%mhTx6#jb|_X>{K9i)%Dl+ z9sBUf*}Lw#dmgmv0Uv$>e0UyOqlwm%w7PXi=fh8vo(DaXB##H5MNaP+=uHw=k9#Bc zDaFAhAa#oPK7j87_)apqgzqJMC;m-dGH|*r{F_%)sf|cBPNlghTCO(YRW(QA>R|58 z?7kC%t7mss!oF-J+&2s-1*(qpu-`r3Kj{i*yq>VfoAiW+vp#pa8qZWB9U7l^G`9r$ z=LQoKoUCk}-U?#{}ztFka&-i>AqFx*H zDI;gnee6UjRRUAEtH?kx7ARp|rGqo5qIR$}aELw+4UCSBjpCmpfvW9OsG^2XUQO-v z(cQa`9oxP8C}ssUtQFk-0*zIRC~8PQH%cOMk6SPgBz**TZv{dpN|B!+JVlgeLfVrW z8Nhu;)g+W#nlw0jNzf`DgSPPV#W4uY-*mN|cXhvPiT$55idBJn(cR&6W*uugJ1185 zrOrNgjr}Fho;cEUGJR-uq9fq3Dku>~d|0vU0uQi(wjM~Iz2=oE<(0l?q|u9Of>iy0 zBHL6KKS?c-D?@ozBI(>GQ|ReXyhSTV$Zmw~N=_aaym2Ejwwz5aM4*Mgq<^+DIyf61 zd7S;}{JELvtL~h>dOj6QPTdHN`|zQa1N+x*izA9jtO+Fr`uiYZwJ4}7tO?->j`4k? zMv|(OCyMu)*GU|!Ka1l6b)7F3IwezzFLRU*Or^3jhx(a2KbI@?#mDyzl*gT+oWDFZ ziDaeIlQUQrDyqI;k++*>W}T_3(>r+?~!=~rBUZk5M+ zeGB5Vg`MgYtytKp5P=cY&YcapQF^w*|G!yJZ-1wr^>qLJde+lBF%PYqbI^T%208N( zjfs_d@xN`_m>T3)gSax*Um-y(7|ung3`p<7MioU^=n_nk;!lYhB-k9>d`{a#EU$J- zmCCxI48f*gb=$4USKRrb58nPt+l?>(i%;D42HS@mY@Lk-{`24K&(xm?!fV2Cuj?9a z?6?gP8rM=RjGy;iw*w?dc}N(dHyXBSoLa;UEp*LDjY_9;2n~x$*EVsxo4T}`Jwjx0 z6P&)j>|QoBcX~(A+Ke^ESZ91Vb;H7Pm**Cb_tg(P{&tp`JyN+-F0?{E-4Pki^eFL5 zUsaA?UA}7CzvGsP3%{kjo$ptila;q)Zc04w$__5hm9qx^sP9=d5`gs4X7rkFt08+` z9udI(Si3@(;4uMQ57IYBMcv5qq)%IgcqcaaH}+psO5K!2XXC|Y+r3Rq`By zkm^5mxUk1<^Xzgwc>ltMk>bRyyJnV$P{S^t-w~S}SY1nuR;!WR=so)%c&Jb=BglgI zP=0fny$$2a;v{U+N%Yh3)6n`DOrvx#A;vD*Bv&Ca*=>U(g|4uAvNsq=C+2H$NYv8c zLSWRB@r}%NNBaWtzMv!gfmpQ9(;IDfBt{QTj-Q;4$9%h8?nArMLy4Z&c3&hH3V>T$ zEsLPNANO~Jp$kpu_R%ZEZ<4O08c&AhwUN4rrlqKoEeRTr zQ?WLC?CQag8Y4zLkv}f{$$SYmjAX{Qyo_5KCC_?h`_$DG%$g3^% zA~yyC+l)QY%xhdoW(_%lgJrXtw9A8-|I~%L=vG`FCVt)(}N(i+E#Js-9UYj1Qd27xwH5^iQSwmn)$n@>rp1wXm7J15imGf2Wd| zJu|)dn%aE%^u*GkroW#!JQ9dcpBS4uw=<&@4j0%zR?Y@7GiWF7MZ* z-(^4J?O!I}g9u-|pUZuYZ^-u`QcK0@{x?P76^p<*59IA}hXU{ajr@221@A9eJ!mg} z_a?e4Qhg7{#d~fN@7eq%CjDmRx5+OsL00$&YNE*cm0--sLgf13Yp>(>5TPfC1C|E)(PzNP=x z!xA_4AMf%XrxrCB9|6>|Z6mWxVXS1-^B>TW~SnA7i{ZzMk7a9js>>HRyo#jC)UMJqx@b z@t=b4eGk6PjHT=4ay9ez{{{Su0te&J_xtyNe+2zO`+bCK^Z~w|Uk~rMKFIsu#SmSf zuV>&7NSq=bnyqp@1HVP!#F2o@^$h%_5+_%mx}J$I{RN+2mz-ZQkA%OU;{nSvyuCKR zirLTjARjNSXETl&2Ho%;P?P&5866MReiFVQ@l`{Ah|dVV6kveSUd+pjp#LxUywI+u zc>(9d`vp$(BJhI5i4Q15e`Vb~FL?it1#X@f;Qx&Np#2{D)d%Uv@&4z5H~2|`)BE2< z{a4l*tq233vHlN)~89hdD1`JDJyhW01@zV%(&@4r_*ck}0xF4lKw zfB$azocNhW7wez$=NPx`X7QZ!HH|XXbC-E8DI=cae)t!x9~ApQ^h^0`tzT7b-{@2+ zqLn(|X>I>#>%~fzX?4E;p86&Cg-(|bYJdNC@;U7foi0ynfB#|moc2kE_!pbQA4gcNzS`W$;HYgFh^BaUP-m zzeMz(VZ~$K1y21J_`C_H{tG;M89ZUassEz=>n?*|xD5X2W$=ehIL*6w|LZSo*y^AjrT;YBij3K5$)x9mgxU7xemKk z{)2Na(O=;6Oq_GY`IqP~aKpXCXs_eO`_hf)<=2_sL-QiubKx@hqnE)SmN@sf@bz=6 z?0=T`U*Ob#fzPun-(TXKPUGE>>+KS6FK}uv@OgPo7dVYe;L*$A2@_7^6764i8T`U! z@JBC$KWxHjy@~g~{xbL@Mx3u7(LQU!i4P0B--OdT6nNf<8|)7+y9_Sv64D+*>rK4p z7TI3dJ&69o?onkoa{3FL=r8bj;KUCFPV^Ue^fGwDgcJQm``29tzi=7+(aYcun{cAP zc>n7!gFj-#IsHZZtir&et>HSv$vxFGB7Ky?~w*oy^a5 z{eYemz0A*bJz@Ljy1qcqiGJq4*Y$?&pX>U=_Rn=aV*BU1K0(ikzUJT8^@{DE>-q(r zb9$TqUez0BaL+B`p74Glx2}`-e{-DEop8{da8CCkr@MGgbT>cO27|m%jxZ( z>++hO6Wz^!ugmT2pX>5_`{%kG-~PES&*?eQ-TeEyT;Kk=F5mH-)7|{{s+=FddWX*k z?-%>vI)-+9e*@=qC!E$h{XMOBl`qh9l`rVeb^bulRsNtq*ZIWu&vkx5&sBb*|GmyP zwtuekkL{o9d}RCQIzOT3DnHSGU*{{^KiBySo@@L?|9j47EEE^Ei^qi(;Y&1m10v+_ zh!}i?x>uL7Q&15DCVz^~ccX})9kF+myGl8JZhq?y#ixpIB6oqD16hjugDVS{(_Jwh z%xPs0zc#ZJjISgv9~I_GCgV@H=8qH#=jW~*9Tun#6|iQw?}Nv+v|Cb$3&Lm}n!oo7 zQH?ym7qI{o+bE&}D2jyYUTJskaR-O$oYQ?AtV>3=STnPOK{etfSei~FXk_*H8U?qk z9p8LcYkubNup0PMIW$vf?cXq{J!R{m_N5XmdNfrRefuGZ)SFFX=l0|c0>?9nsK!vzOcD1 zJ$`76$6P3T_RlW5T7BWPzxNROi}*J7di1y5vczF%KV%*$=JB&YoI5>|Q-=_~+EUW4;t*UIAYUATW1de$< z>}$8RwKR|2HeF)Pojr38ER|Sm=7zbI^;aJsc%O6dWdC3(FdDz=jd!^RYzGbUaW#9L$lkTLK^u9nhYXjY(5ol>}8C*aSL;(?(QE@>=QE}`BMZi&! zad3AOml?;OC_1jVja~VF&%JM{N~IfgoX_V^lT_u@tM~3b_uRAJb0j$NszITk`MP)y zhl%8c6Es_dcjFx6N01a?(45BKaHFB1e4~)96Si27TM}q^Wjgv!fbm%met%X#MaVj#y1Tcp+*csu0l?#KKG*!+VEtPCf(-yyMCcq_Y(Sr}}N`vALx!I*Wy zV07I-G8nTg80=!e-oaqZs$j4ikjV+YjIrFRJXeLiPJ!*lk&rKl-@$b;1$G$t{xrk) z(G6giDzFpcsPLe+6W_gp!?3o$7arBz3qK*{I!iPnorb~M@`4j|6qSWmdFGEv^c!rx zSkkySV-015N875LE}I+03bJW$!h>2JYrn-k?>YB9t6B1sr6intr7IJ%&MelZVt%Xe zsLt$3c+*+j(`|D(tB3}F1{x%PpjM^jlGCN2WgM7w1UoPE3Qux6l<8LFr<6p@^>HD| z?qN|gq)YBX+tcgD=V+THjjjvf4e` zezBv~8TFt#FL3d=5dW*5S*tu#UxK3VVQNoXB0kI5NNp(SsN+wpuy~@*)(){>>#f~PD(XV0TO-J(J|Bj*btgOAUlSRWl;+NDn2C_d6N4i zIG|`~c^hIWMUTqzP~Ntq6kX1WaHs+0Jq(6AF;@}6dmDS7s;;+sqcxL5NU{|dQ=yvL z8l$;Ndi}?^)=+J%72CCbpV{3&(JpaKo?9I}@XFjIIjv4bO5{@kQcn;zw<^qyx8R|Y z2b9vu(^q*XS3i^vS&1s$ia&{fKgTqM_iBv|ZnMv?Z5L~e z)duY=*G-klg3`0;(4&?x;W%O#^*9TueHLs;imC(69MK$Oe zaOw`?jn1mu}|K3I6_(vF=Y(eThp?ur9b6H`nw zr2Mi5{LtBd8(w+sRyJ~52(?aerUCy4QRqw`$_bTv6xK3nUwy>jGdLVhV|8t9ZIy7* zyx~aU7mX>Q=AO!$>Y7KsIi+*wmj{~XW*6Geetqhjj|g42O$bkgdb@h0@hj)&K_EIP z5W|RfpzeXp|5e6NrZk*^4lW?mhcem)yl;VyPUma+v1xk8OJ7-8rZjIdLNM<$)IgYK z+=9PS$fAp5*YbRL%B!P{_arpntOd;vl=Bci(T{!z_y;7=AxYK=4-LWTlmt%sgtWTH z2W%00MJ1|GlR?!_w>?-q8wKI0O!msDsC zjm_cvgqp(d?+Z6K8nhLcXa!g1^@aBe(ZYA=2lD1mh#$=XFAJJi%Xo>C1%uviO0BGJ z0(2Jv)C58ab5bH6R{V@63yf7VRzn$ubk2ej@=*B~Sc&6ZkiE-F*a+fv2-naVry0tb z1jA{;aTom4o3wJFcRC>YQZNRMoNebyEgBaz1sk?+zij)qhF~aSkJMYLYAX!pdb44^ z+v;~PWV+4vcqnKdUb$>#xV|YIbC}&6nE^}p9J{u{q_@@^t0A=?Ba}TB%DAelfX2$Y zM*9P|Cq3svvnTnc58E5-D)BkQI>U%YJBa;bLx$iPuqzQvnAkDZT_UTHSg?grh8D$Z zi5M)%YLy9~@^g>A;;kdABX4=-r$2YYqEohE!pn**{RL_Q-cGo$%#O3?9#p?S7$Q0iRkD~W2$`tCkS&Lt=n5O znUvQ(A4%@o+&UOp26Sf%p|wD*kIjrEjB zj5!j=r0$veY$uS7!&T_;q1P@Quc^?D{pPq>htUgluF~KuOJ12~Ge%;g#SB z=MHFr{H#BX-$m3xgi*{TOrpdlmR9%dutXwB;s=b`gIj zi-yCNi}$Xs?q0Ek!!dbt(vUYDFj^ZL4A^%TW#1_?kaylK50&gKl3klYA4bq9uL4m6 ztV-CDx6#t-^uw?E{*Q0`#8%vnHjcDuzytpWIB3K78&OX}+An1?O~nDY7q{qpsp&QLG6K zcOH1`Fje4KymM~haIZs_%j;{BjIsI=(19W6N@{~havZfmAh$QM&j~k59S`aHC~R$T zX!bd>ZPa=jSX(V{;Q}t~IEO3Y;yiLv<{kCe2fU*K=_FL!gv&^3r>S5hKPYIkkaT2< zn}j>uO(uJl)!Z017=Lj6p$=W!&a0nk+-9t-yilvN*c*kP|LToz{MFe%j#E~Vmc=VR z4LYUs6n^zAlcZ{>`%69h!zqDRT&)AYl`GwFnM9RW4Ol&@s73xB;=fd@wyYiqa&2)U z8VzJ9!(DHC+m6kfcL)#D@4|0i@#Z(b;sW|5%xv0HA&l!5=I0l5g)*CrUOVFua&ghoaF)=6_)p@v^tWgnXqbf>Ngj4D^NxXq; zP)n;XtU_BtIhU_fITz?gz@eZS!t*V79@V3j*0zj475CL5tmzc~MA9jUGGV+@Csh+6 zQHw_k?{Kt-yH^H-S4~U?S{habySBoa-!^dHeKS2eo!~xujQ9)|F@k3sRJtmgrCL9R z*I?o&DQK3oT6(-vja;fOTrKlLK4*VH_rA_r|%{b$o_HD~!K<_wQKQZy1^A84nnHu1x3EKZfv zmW@Nz{mJ1+T~0_xAVW=Hqbk<;sVe3=jXx#)=!-)CO2?kDcw}T}e&5!~sXG_M^ue?C zmg#KQLc3#6u8+b1*bBrLpdaIOoCADMIhj_rChPZ;osEd9MDgxCR4P|404qtT^`nB4 zAOKTKt4p1`Mk0}s-JM&eCuXN-CWQx9fhc?Pj6AknTj6Oyj$!6BzNj?5ZkbyD%F!_i zu)%1SRu9V~xo|g)Was)}5RQ25+*WGzR;J^lo`K+{g98`MrPA{k8{3+veUXC~9bDP& zch3gfQ(JG`y7km@g75`B{z{D14N0z4i;z6M>S!fBT?I&|v6!*B?xZ^Jn1f?kpg@xF zjf?_Gmk+U-kft6ZMIGCK>=yaN>Hyk6&{=Ofd?N1bJusQ7xN&v$75dD?-tNI8Q}OuJ zk-V#o_$ej~)pa<$hv@FwuM4ak$ zieoKoI?@hfh6!AD_(vuk6)oot5s8qw2@OfD4OvhZ6sK!?1+!Le{3G0U;OvU^kKOvVc3aQ8RTIEV|9;qq7b3Dup&{w3WoAoz>ms3R-E zI|zvlcK9jELfeDN@Hh;o}gdKYr=UIX@{~VLbV>PY^5B;rO+sgos!{8 zLR}nLFtMv29W~bMtTecjzJZb$?-Cgr-c4@xfXLWYTPoUR_gb14#=_SxJuy+(sN13cq=T)rr+9@-e z*&%l9A0Ck*`g1E(M@yvI$$G>;eDLJ(sw6uGFI&hoFCHBn*zX^3_eZA>82|V`Rr?mx zW1fNd5o2Qc)K+YoRC{pN?ccs~@Ztjz-*j^uhK#wuZW7Ki-N-7hndb9M*TRU9qxusp zSXnJ6@KT(95{%kjw)2a0Na=j1x{hicFREOEUG*$Z-QkB@C;S8+X-sk-UmR$v%obHu z*J7)UIeb2c)91U+;rBc6bI+>yWYFzyYI3`S^6S|?#zfg1oR|~xW})vHFiFUB@Chge znkc**%8BsvXuD^y^F-ze;aot^Xp2VdeFi_0?(1VvvKHfPl@y&%(t;HxoD$&KA$2$+ zyQn5@{yNf&Ywe^LhZ=-UQxbE|KXRkVZK?~U^1`D7le053eWi-BEI6Pqzh!RW!d}P4 zxxQQ*@j?i=>o7+sqZvVnM89o(43a>Y+1vSbq{u)67#k^BiBkK-I4e7 zk!%fUUos!0iJFy3F0HPuPUX4u%b!^jj`vSO>|mJ+e-iYH1QePI--m?89KaW_Sg*t! zTxy@5GHpSf0k6wKRu9(}M7AEJInhd)nYL8C@ljAj<_J%){od}*Z|e(OH8^f>w#b{j zV{`YXKRwh<`=0L)lF2LDYhd>x_nPhXd8VZ>8&Z1>Bu}%d+x%Z!ktlEBc*&Mz;Wyd0 z56Etu^O%$3<2^Uy*Z`*?aWm#bU1ZN=RZ=WQwJcBIDW%q>_%Pj&^GR`%;g0(Z0^~CQ zoY`Ack6il>hSOGoY$>wK$3&{}Xy7#t)f3ibbX=@8b8o9mxm00Q&(q9>z2+y z{uS-tGHpdgFKh~+kb8iN{a2)(*ceC6!YxR>bE$(AbF;}!CAD9WYMPqtb?vtC0jt|& zuQXLT+|~a8Qv781p>F*D&s%0IDlQRq;XuL3#z#C-cuw1c43r$5h1Z?i_AFKrOA3eL z*gX{v4Ky68p%S?d6n?{s{XFgoxgEaKueGu;n z7Q-v~6`JwAcFZxzv>IwE-oe(iA}9NILoX>FfJ_g)_*{fJ`EPh>A%WK~!Wxy`{Vx_6 z_!F6`pxw2#A??M$+cHj)L4r`QI7R;BRFVISLC9x5Xu1k@8bi6$UmEmI%~}K_XrUP z$=b(0sjUIEgdYraHAS=c;n96#~zd83+v(zXW6i^x>3k0ia9i+j#x>~m6Q*s zYQgGsc&}I<2cf}LvEAg8hItw`QJvI3mLysR6yU(>Q+9@|Jm&ZtC6Y!OGioBhRY#8T z|H|)8o+tXy*g6`odE{f2sl>S>5Q&ktfc|03kL2+x<`;xUSu#J#WuwkdD!0Mt9w{J_ z2aRH3#7F4BzaFooO_Dc<7UVP{FW4Olckq`i63pxM9)HFNw2?ErS2y(fzkNpy-}H*6 z!$N<|_5VM7k7GVV;#HVW3p93VkE>jfFAU$X#O6HGfQq-DJgjmDKT(lrH0f+f$BX&+ zg?RDCQHHzT&(AgotpSbs4X{YodxTW3qwb9}up{NIK-6Vgk5!5cu(7s%V(Ti44!m!l zMCpnWr_eX)N8ba!e40%%zRF};nHi;e&UyYGH{4Zs9t-%9MP9zdEcExSM}@X?hIP^h z&llGrzrqhN-n8aodA#aqqy;Z?W}VmbfTR&fVzMwO4i4OccT=?+(yDN(v?ThYPN|$c zD#iE9@gGd@B}Rah$*w027GA~3Xnno`+Ax*ThPpG=21IIpW<~( zQ;Vl|G&6rouzyGAm8alv2{l(e3@rmEi-kWi-vm~V>&)~wY!IauWm%1RH9kSrGj*&( z3N$ltQ;LL8|J7<>&&GHu2|%iwN*m73v`X@>bfTwTN#{_qQD6@5^8C}uNt35uSMM`T zUi(ki+`9T>Xp~3qkBmp7!@?g-`#CgaP70m=Cgo@Z5E^ zcgr}2N;ljuB=ZBF)k9p?$vHtTv{9sp2KuYbrO_fr$?GFVoSwRe+B9F(?syu?p3B;?!H~aw}&D^%ZM<1Q(g|p-H8~Oe~X~-X9 zcKRDY0~GUrH(o`aKcgK({>%Z*8)Z)Wzs#Un!I~^$9{)edr4h){kLq~jVnzMjziVnu z;YbEuQpH1}Hx%;X1sxG(H;wSOW!s2fv_;xHfmABsX^T)*T@kwpxi?rN8{||B83ITV z1V14B{rk;lT8_7DKI=4QB~wRyv}B;*hp5CLwi1nD%$&v$Ndg@8KeTm>Pr^4P z`P_fPuH!L=Rw>4ihs?i(`LAD)uY=Di3EvX;IVB~Z6U!N3y#&bDgkA!G(|wg(0_|h$ zZ|<84E550ufC#qYvpTN8dn9-Ze9cc#PbVmhg!fkb{TJkLH$lss!QQ9>mtGfSBEwp4 zeCT?X7d#^;luMIfES!{!5M$k>hss6Jc#Aq@3{oLvlUC2SI4S)~!Bo^fvkTs1*QYlh z8@KyiHiN_39q5|RdMdq(>BMA*x2bPSYimze)<5hWGQQ_6C+^r5tI<|gR#hA})m2p0 z$0i0sVPEgo&hEV<;l10ZrY8K!;Qm9HmzH`x3IB=n8WzkmqQ*BQ-lW!}lw6?95+DzA z7&J#7gs>!^h+pzrq?Aj;Pn$rkW|1_-j0sUj8%yTIC;ZLy=M&>uZz7TI@#m+L`)6B| z@s>?H+B2=$W#Rc+Ut1{LY1A3=*+?!_FN6agZ=mqeXuuaHUQc7c1!FJohop{M)uFjg zK>l!Y>EW=6d0H5KMtB~*NU^?kYs;b!_iDg$t;-3OG!FHiQWIg|f-)FbOcaut%u;e5 zl9VPr#L1r|<%A9j(8nkv6zL**coc8Az~HGi*PHZCVe_o<(0}M1=Fh(Jfk$U6tjUS4 zFBh(wee?lA*R#bVbYPi4r*x+Jn~WX<00Vj`O zdDYAgCCq(X_35ZnmA0jt z#VG+)0+s+{9=mYl7DQN zd^$Yelg*Xqdy;x7WqUIGu)3>K>fhL;lY9WKqzLn)>*2n z%{~iKul$xO;LYNQH~H(Ddk^Zqy0QCDH)-0{^n6jF;>LQ+jw?sg^LXHjd9;#IJoMNct zO);_)hQ&DuxsLJ#PV$H=+~?WsuI84&Xdu&n!SrBDb4xthp8r5}Pm811 z{@a30eg_K%u!x77+FZ5suz&u^5g zi6={2Wcv8t-%w?$GRzojE)vB=%lupC3pU}l{_Fdr` zBaakpPdz2e>%TC0om8ItGdx$1GX>J(o#(mm0Dw!7PDOQO2|FzL78=XDj-L^pr!}J9 z)U@Z<2E=Oi99|oU^n{1m--uiRyYNP^y5~jDm3)0FovG``{R`k3kaiVpZ?j0d`Q!Hp z@4rX5Z5Qv`Zd}U?KSIaYO2mFhhfHA%Pod936muKWd`X_4q$a6d7RvfRNDtO4r!!P- zjTg+WWmG~@Yw9=2Yxh%z9%V8%fq&Y-2b$P5VQA(~b`AC1jq@m+Thr_0&%u$y7 z1~ok>b-=3Bn-O~*(OKKv+Yb9X#v==*`Gu?q&J78?C;q&C<@T07l3QRhExCef;6$P*_2PR|#)q zdMbNf9?yRY&$E{0LJgCD;ax=lb`p|Uy?#W*32hUY#JPPpDnmY6KlPcA%}&P>;nt<_!9W4vY-# z9}aLF!KQi|<8*_Iug|$vaikWhmtX)1!Qbmb3&epl!B?sSM{u_G*?x=%B0kY z$+(fG>A+6}J}Tr9L#c0qdS_>oZ33zBMn06VK#3p@y!x>bE99ecloQPlQnL(PI!{7T z2PPI-*?J-AXfoQWEj5m~&s^IWb9vgl$0sL`f8-+-zUkJTdwkuSzg$(ZO091-^o|`7$)0&TPFh5@6s*wen=~)5^^tU(;yraNXCN>&zFU3&u$+K$3|D$TP7Q`wv4A^qUOoZS55W$I<2YDk})v6 ze`xr?P$1x#G+TQIH%*MX%~L)fttI8FzKQ8#&1`M^FpH{+T?aMHMuAc zm%pBURN|!=^H20ds?j?xBtgbxg~;tPFXAB5K01#^LD{N2GJgi%6S-}NtU=Md zc#f?iL1?>3=L_Jk2-&2uPapp%lW2Uv9~HthSTZP-VLtT~leM5Lc+`cTqhfcZ(8Fy2 z3|wIQC?V#`{#r+Gw-Y;3+$0x#XN)*_4arC8Vh z)_up~`7CU4ru#vJ2;?=v{2)&@$X``0ZOUI&t?m7|KV$>!wTpLI=CAm^?^pP}5<*!1zoj^AZG zq?5Ed+XG~tV$DdWi=wZO9n|z9xvNBO2DU_`SXN>Cl;*B-lG`|UmA1?KZn@?7Lk|th zYSeJgp+h~wM|NL$;qJ?ev^(I2_${+#h5uqWF=C7+=nCcepc`R>dz1wXPe7G0){mZv znv#4_#r7x1vFxwWYd`s+t2foyYjjohh9=ukugzt$Rn%77-8Bb<=hwnB(dbP0=)$Io zibJ9<5-5Cv)(eYvm-tp_PA%u$y~RpPv5ig5mk<^BLBrl^m{JcE{zNu5?uk0m!aG3& zwW?lQre&+q@iSOO#MPyRkvqZA($Er7-7vB=5V@xgu1s`>a*ZPhMci=1@h{~oe!S~- zy7r^pT|$$jc{5dyipMu$k?0X~bmMo2ahKI ze3%VZ&;-D%DaO#U{*0_tF+$}|l0avK0Lx0+t;7p>#x}1NL3$!d@@DK;2TFD**_tmB zXs8n&)P=@E=ZiHsVtHTf1OHgzcAqES;BASxD&NP~0dhzTVQyYklB<)D$XoTEQPQIb z&4kDs{im>ZNs`n2B%PNdoO{TNBTN`^)yQZCUETzaN-qGLnrg3Lo2P z#L}XuZ^uVKXMT&%UWR~8`IHfD5oAAe1MnPvdNv$i)^Q#`z1VGd;9a^%%Z846B4c@c z&;QN2mPI7WFqYM`G$oEF^6pmHHI_f=Y>3_RpKd? zM0+IGjnCi*d3A_+z)-W{Iv3-@q*HMJ2=m#ntlEQ39kJ7Bqv7{NvQift+2Cz%g@Tt}WzK(ZI z>$FU1WTY`l2x$OnRdrj=WCfw>r0HNZMDJcX_TQ(FSrYRV|cq zEiH1$=Qvztk_sx^#`x(B_A$j%>eqLEm6Q?{xoVyz&+XyfQaSfp_8pQmhDAkoY>pxk z%$)+yDeatR7APuloScVG!8eQG1UU|=rsy)o2w=0V%aJR~bSP#qJhzhbM4sKixg$9T zz#X-vHgs`n<@a^5;TCs%Y^AMrys^s~bM(zj_jt3m7DwJ&`@sFx$-(6g_-;b19U=K{ zT;@4zqaK_OG2pcUiZwt}S(N3xB-hQpJQ-xO?*7mvk`u6Yu{ON*qAMcNW-NJDi4lT)3H zdW6W>cxWlfu|&ZPO1K~u(aOe!_Oj(^ou7TveDgbsMtIMO*FXMvzC!qjGRnnX3==pr zVSRrGoSiGDQys0Uwc_y@f(b)#Vvtm?fuboC?_Hne$#XiX(k~5}azteQNGcD-tf38N z6@^}6mN&Qd8C|tHgU!(KvU_ho*=cYXbk)}CmTTU0fW-L$d)j78ISvS#=l57sR{X!` zk8fpS9rMX!&)6^@$=(3pV5?llpHx(n{VL~iP%Sg6(?(-OWLw%P<*^3ZG4J185^tEr z$Vy`l%=1pZ9kMf+4Gwunf3tiXvLCh2VGStuelcE=uSdBm$Qv6+ocH}Q)hrO3T+pE6 zpEQ*+M*7#KugFO&Y9b3ifGrm+dnxHF|EyU6f+jeE+W2X0{IoXbPN{?v z16)xWHUbnx>}5$Y7IJQ@d8Re0_A2Gbe6MUivNp@JX2iad!E!&(+V3>KC%+HIOEkxF z6q(P0aukW?cuphwrHDT#zoUStpk%*)lU)~(uH(Mu2<-Z=vg^LU?+==OL3|fznEOT& z0=#e1_y59t(iF?q>$6meR)(|h!!Llpxeo<>AtWCP9Nj9M>a$DmZsuDN5jXyw@GI<% zRzzF3%J`RTTh*(r?v2xkEg}Jjah^`>Y9ep4V!cd*=)^l7_a$8d=gw)TOTJz7TP5)X zElEnVq=Fu-vVIb8UJOPzdSSq+SO`2*c(T2t|S9} zZ(MVWjAnBa6P@4~p6 zyG|N_@=l-@x5T?1hWvi%Q*v^1BuarL_`xU(m>T7x_!=r{(>v^OP^uO+(&fgv7HGo^ z2#xC(ZS#3A3Ou8ru_N6V9i4Z^vyHy_WMk5FNkdmO(C79>7Zb6AJ59z!m(%Nyr5kgu z^g_TB8Zvs@Mq^F+OvD_WLXa)(o*NA0GjU5|J`moX9XOV?HdgGd4!HwSQRirJyYo?Z zxVg|`Yltjm9BsblF7VSh_Vc$v#|H4voQzpXL)wUjKLw92A)^w=;LH?3CS<;`nODZp z5Sd4s=%5aoKWi>nUA=&Q95GLQy(i|7UX34m_q*TwzIVO*LpxnPyT?X%bvYbeyGF-$ z_qebxX28?FD4xWVl(Y6~E#Wfh`zg$VMns9+lzAh2a!EC-fojI{eP}tLV9&ha>eg}J zwwLb}-aS?AYB>9!d-1#=p7(X&z>mEw-Chd7s~C_(3`mK17d?;cBJLsOCnR@Sda1rIBZvWk>h_OZIvYn?biaEjy=SC(ro$T`5?-Uj%f2=r-a-+qZh)WH_zk$Mt=PWEXGpHn?w zB4If`%~meQmaudJN;>ARHeJ-z>78lq7;Z>Sl&l>cqZ658BW_%gYo>7Radt-m>z3!VQwO_DK)}Ru+}w@5=tye zGTv0|t2_G)@F8cJl9otTsg{1Qnd$FJyeDI!8X9pu=z$~;MSp`is%i@7Z6qt@Y3hYk z;U|B2?c!qL7x!yLozZQ2&nDq@g_~C1bM`jRoX6ElX;=*RU%~jA)Eroe?`$+W9=<*K$#w(y!+)4&}U4t@-hxoImO9v>|nKywS+d z(6|tDB5y`%#FdUes8U(+^n=Th-+!I#0KXF~Ez5(E*#a*IjHk24| zYYgP4Q}ND@*2ccZ>Oo^Xm+`*sZUc6SBiTjwyU zG#27pSOb%qrzBb48_fi98;KL}q9D~MDozESK?63ER{wsTJu%c=_?qycuJO28xAoQ= zuN^utG5+#bzIhMH8j70`Ka7DJj^a#}w7sNE^o^c(8k&$rTI~Tm8Cm<-eKmL;U_!-* z&w1`XowDG0Y$QtZC3x+GXRTNo;}p4;I0wq1%efUk5ov3*N15JZ7lf9D?w}=*a741+ z>|_E-R_;0{iW$Xy4gRjhN_S&hCem&VHP<%xIul(1Uu?|iZXSyH+TsDD&OMcl4Wyl} z%wWu!iuesWqd(prhzz#4h2!qLFWH$%I>U{Q!Z+G8?uge}YwwG+c4NPi{`ocFhkAu5 zbQK}}8>i(J+eo!h(Tx);*vRNAf>|R+1H6;s#i(!%y5gdc=Z>K66nED`>*KawF-Csp z>33BRH^;hiw(e!`K!Z$JbD_i-BdkO-=q@q7OPC17mgfd~y1NSxs+1LzD9am}yBb8d zHI9K{y^G~vO05m~S4coQVENm8xDKDk%%fM z8+-N)5AW)7xw>`@5AW$|d@vdeM(Jn$JnWEX3f-P(9$bc#G$&cXXFxm?y@MI&A{r&z zn|ucxcABDU?9poLSQc7>V#7APx>XtAnks=q2aX0=R@DEuc6@gexXwF|5-}oE=NOf$J{1=(+$5 z23Oo$U+;~(TnW-r62{EdlMDBK-~;z9oZOn(>+0S$GP06)I`b=WF?|Z(CAy~^WTun6`vfT@qK2s>uVVLxcS86w=Kg=JkEDk$o{qJ5 zL8vN*zoi-a$ZbXXNNankJ_4JOa%7;7h?Tk#W-HQo{|H=E>PF3EQ_|;< znfQE+ecp?|e}?%~>c**59pmSu-~C^dW6^c|9AnAh+5g3!J!zz| zQQyb^V1G}+(AE~wnIB5MQgiqvQX1E#0*WoB?td~1RN7;kBhlGLvBsdDR7Mx zYo`5AenQIl=P=@Q{GF^1$TMUdfFxBj$*4}8mt)$0$?Uu>=4Vh@Ihc0SJDs*6m?_z3 z;*dX7_^CbXRoH>u*5;M@0q4_m7-^B6BIz@=iri84L|Nk^U8a~HP%VLVIt!iD)U+;k z`~BUEt!)eRy3p2<&vzha(HNV(a%TFf*;s7$s_B_4XJb3BI&k1B`T-qtJ7s7CJ7wb$ z{Y`eth0|5;hJsJEQ)V~d3+nU!K6c8*GqG%26n09A_(F##(6iX;?s2?nG`DlpM6jhN z=^bq8@U%~)qEpkG(yE>Ee(;4k_;Ds=y-6Al#&?DiV?jQ21og#Clllz~iXnaRT&4+A zlwQ;{@wA4mFiv(b$QjDT6yYa&Kb|uO-86{=5$Q=G(oI7eh9PRILI)I!mC_I}L`o^rdze>d zV^vf-O+uWb^5=o!#;Vb5vZuq91>rcefnZm{rS)u%tQ-t>&Llfm27<47p(%M_%V^)w zP~l^Zo<*z8k>4>Kid}xVb+OBzUOF-Jq0<~!bVmJ$7;~j=J6N!+R}2;F6_O5z8Awwq z)+@*la~{1yc!Jo+*~joOI{%H_YVrS`e>9I=I38|ok9L87>>SQa!JpMRPkxS9oQHp4 zJ)KxT@DHr#PDV#=(9JK!A>d|L71t{m{p0i9>~mGNk5|id_C;L(*V5TNI!9uNs}SSy z2Ho7Y+Zmlrp1S$&ee_(^CBPby{xZqN5ym)wz}9R()=c)H-BYToO0sDq@1*RF*+@1~ z1+g++RU=EKgC|ZLT<=LsZM$*n@(s($`#vp-i_l-~N?;|EA%PHzl zp;&AZ32i(&(ooC&Y2;NgoZFxFF-B<5sB-Ea_{kK1T3KZpDZPjJ(|G1EtKtqOKs`t( z&k*8*^kits=k%w&{!Z>qgOnm~T4-RIq}1J`Cm-9?(Vt*4DmR^J-n(~Siz=f?ccr>x z%DGxeMs17>8byh~!pPS9(&AY8^ZC+PUrX6p^3r{2U2}>rE!XNwdh3_#J#j~}Sr7u` zO@qKnbk4z>wlticfU`>WrM-d4DkU}}9hKN^8umqE)rg>hYq(1-T(=poHII)|GwOh_J8L?8z1N&sV5)W!Mh>I zvYYbxt-U13L`jZOJ*y&L$9eYk-_eI=-Oz_N*Tj5iozqG3p?LIOXkL7-`p`0rKaqWsV?08M z7@o_ArUbS&cA@!`B`!2yz3f8Em3q+pQSL$W=h8uV(B?W~gXBRQin%he06b{HWUh&M z&`#zCQ=QF8SJdk)Jl&r0#QkoQV>AW_8lx-jL%RohN?PT}lAfZj#>PH0SzURlKC~jm z#U%dLJK(AsZjE(yxO%sG2P|DaPe;rpHqM2%9D!$6a-gjUlcD(DEkrzp4=WC|rr6<& z+7`Qg(M{Jb?Ynt<0yH&<*!I^ow_zR|_PwoyBMfeC*$%FJ9Ti0iB$LK;Q&XCLNH(!P zy|_ocdJjpvW^NM$-2;J?7(37_MVY2tZ8@RZo5=(cnavLmT85&Lra)|WgchL;uSPWT<##y;9Q3 z*eH!uL?0vV)W))Ut-ff^*VJoQb@fqc=HC*w9y?a}(2o=Z(7oq1&mpg?4qO(q|zv1c_z^TU76U`If|$D_KG@hBxp}X{q6Rl;I8i2NJ}H?7x*o@b}VuL z!}?aZuRWEBJHly?vp3piOAaIg+2&+(M?l2@=d;7YoxlNkE|f7gk>1`!eav}rd9oaN zF1H6`tdVJJKo`r}QR`Ew3RsMxA1+(~0`xa%4_DN)vBrGu_Ti?T88*OV@-xd@qya^G zG17!Rl<_(+Qqf(6L`3X`*Jz#uEmVNg>5Myg9J+g1TBsTHMRwf@twVUtC$GBdlSF&C zR=5M#Ms+vfIz4{>8(tCX7jDozBYqTgPSxDep$bsy5ypBgP=bR^BJO{P#!q^Z32kL# zEF#>{lY8ZG*4dL5g5CfQZwZ=F;bzUVIA_N1L#H*V1|IH%O_HlD+9mtgP291tH<}P` zR_=itvb})u2=BmnqPiO~5@S9}#+69_tHE%_aY{1Wck6*iX zf$$;CTd`v}j6VA}`bNa>70-#r_hEiNHZL|l%Vrj~}+7fE8ih1EV_<^n{PlFTFKBD@@d>w5p zc7(Ke#E!6=PX72vp!L$rFVAK#zx>kHz>yz6H#nI0#9amhg3|fHK{n2L^u2e9-^ZP3 z&WM1pIXfs2$C|l-sW`qeI6gi&)t$?AKXl~TSHJq%BY^|ozT%2+AE0@r);4MWpnM;u zApbt?#10n8f-QHPeRm3Xc}V(ZfZd0_zjN&(!6!ZmOUHq^P&PTug`Y*D?0+zQ3R&Z4 z=aZLTewTLl;Mt}@ToqlrNb@u0d-A&T62H>-SdEjcIePi!Pu?{set+;U@4@#1((^ju z={`fc6XL1#ya3(>**jP^uw}?amoBntc#2C=b^r$;qk%h1s0b48PX~+v`dpydSEto# ztE@qnD`>64+d5x!AnypfDgvQUpu!b)+*KRM#Tzrpl+)B`GfkLmZj&pO%rwSxf!e`P zCbhXW-(Ib&&gNP-r!pbFUYNHK#=QCX)p=9xBVJE2hIer`ej{FE&>exp9FotmAhf7V zL8L#}X%OxQCQo(N#(eV}5Q-KLH1BUIpG=GYE4=$&WIkxWDRU*k_V{q&vM!+*JlXk=xrQu99XzwsTSQKAsqm!J#t z%KV?T&;11v2#pQ*oqv)0qRjf*&o=!`y02JtU%hl^9lNsyccwl+EA#X7LbLE#Vd(6) zg)bFyG?rH3M&TdCFTjSd%KKH)f-rs(LBy;(vkqeM`q&$@J%=rq8wL$WEk}B?v%-y$ zgPA_pRad$CG6y5u>3(f%9}ynH{S2zNPSX8wKVE7A4TIS63ObC5AGii6t%nZdIV}2| z1L{_%EoOOKf7f05y_I*}Rk>tvw1|==850Fw;EXsE@g@IiU(;esQePA7D3XF{_BY>Jrtewu7!t+}*#FbritT@eI&7=$B|*4;@gZa!3R$ zwGPWpeh8{;L{v}zR_1qd+9&#le1m>2{1*CoRCgWjr`KI4@LXBMjI;shzERyt20uyX zIr#PBI~bf_e^NkL5^!8EzO3l_>)81Zk<|ma7w`bMqT+cEl71TG$7Yb+10h0`8pKdz zOo!&jMn&WoR!~rlv7%0>j3~NLo*-7LS%0XudS9i%X|2s?!aa>c(L-ISshrmxO@(c` zw5(fyW&g+p=0H=-nS|r3w>9HP_C;cS?Md)ZRlA0a!6xvD4`C1_FA;$PmWd`=GL#u| zMSN)B>@7eKK8fP@&y;Jao(k7HC{~>{-*Neq;_ATJP5j!OYfs_6C#Czs0}Zewu}EHR zzdSEKboN%6Z$E|m%Gb(#8|z7DULd2k=Lf~(?8YLKiN~01Gr$@+13x&wvpRP2OcFit zvsRSh=U|mVv$hxpx>Il-KK!+o7D-w{_R)Anl9|Fl(S7AnaJkFR>2QA+uc5^5%cN+~ zO!ti*J}fv_abGS?rTYTEf}P3m_4u_g$qoGC^9KhDZ({fr>`ZR+YgPPOWc=dVD+UW& z=vt;5;Cg=T2Kc>8c(Cv$8Nbj6lxyXg72)@;LE#FzE!Mte?f1wEr(V`ENX%R`ICx|_9-lrkIC#-aV!1Ip-JG6mYix41H(16x zddBSLE{C5ewFD1&Ohnn&#h9RDn7qU&sa=#DcLqt@0^C}~*m-db#H6CSCNU-0By|K$ zNndR4Q*Q|Nrd;k+Pq3>wnMx;`Uwq2@h09F7mS8B`WIpn~rf2}kfI5u_$*1>;Pq8)6 zAscNw_;?PYG>M-a7S)PH1z##;m}I#?S!9q>67*^0{da1z3`XB< ze}=xpYp{_m%N4_O5dtc)QGRr#-a%*36+C<|K9TeJauad+)t`^q?XkQ+kfYaJW+~WW zX-MaSO%AiwY;g*`-rRILJ(Kf#b2I7mbk3V{B)UVPo}|N(>x;(&_0-3tw10`mv84U1dDWF6_scKa8E)tGOOy?!|Z$`02%1 zG#HBpqvZK?2|#!U&eN31!4lkgrs-*TtavUeoy6#s%362gn`t&;`eqC6MfarDY{6W} ztBNP#9c^`5SDuy!y}1QCA$REU#u~`=Lj7Q_sh}4#@2*`m;ai4tNpsQ>wOZ4z$UxSc zvqtK}W^04ZlJ*7beW}~m<6?hno7w8CGgaFSiAX$eH@6!a8jQyJDr;>bYzZ~i8`mQW z^*4a0yMQMPsB^chqeyWN=075i7Gb+rk9S;B(_u_nd>y7qhcVFz3V)@5-a5S2;g!lh z&{@9}t{^T5L~JlamHVydZk6u!ll#{|SJLT9b@>C?y12n@4zx4}tc|94Qn;*iRz`Lv zVj%5sHnbQ`9odeKdQ+yA__rH$`~lE0)&34^F4}0eNKeOy#H)~?kI*;qDi7vDBtvD7 zY1Z^gWK9PM=`)JHtE8>sgyUf2nWH#1+s?e`989XR`3_w)x3p#2=UPm}o$IG4bj{Cg z+T43VTZYkk``T`8k9a#I(iY7j$bDkC+!`LoJIWuWgK`3Dg3&u-%sDnO+PhZlU8=ei z0$-v!!y!#0<51)Hj24wn&EUKZmY6b7r`b}f%O)9p@E_nHBy*rqj*x?j!B&zxf!V#1 zdB~(zB~qLQ1te{=bS~kYGq1j&cjCl-J2stKX^jocMN)lw(J>O}ob+}~r90eW?R3gD z>u3(!gQFKsj-1@z+q`&Le{xH(amR^z>p-*swk^un>G zXw(;-A5U!^OSL7wc41@tWTyLq*>wKU>$f2fDe7n#Y8OII&mAFObEhi--=L^zU;B~x zg7`_u^<~YaB{-Dvb%qWLO4yvoJ5C%NhrlDw8f}Ef2?>w1IS7}8L5|Cr|1B;}0xISY zf~m;ZJTY|j&fMT-w{4y{z9k*ZPe$YIm7;AV*gA-IS&4R+Xqryhdo0m_)!Vmcu=k2> z9m$E^+2B~CH@?_m4%=M@dxJgfGBtXm3)e2~y7Q9m)WXq`fqg^4WXKzv?n^8T#@Z66 z4>-~z>9%bH;g)UJ&yMXM@YdD!*&5cI?voAmo@Bc{7z92kuklCX>wqu6=305DsrmtS z6t$)+E>I%tbX;%cb@WJEHGm4~l~@ZM9j1EoRHKfL5R-(Vv##{&!Yjc&c%|!n&~CF- zHjw>f^+c5L2(h0Kgo*_p>~PL+t>3)MK5o0(F=ks_so%QSG2yt{88}gY;)%JN<{rd< zczNQ9Cxp72n4Qyyou$+?LzTJ$=J`|60B@RE?QJccD>o=vCuPT5rP8p7B9K$uAa%4B zK}6(Ip#Ii!2}FxN8{-F!(ea8ZP3xa9-)J`4(IvqC%tJRnbZz9Js9@~wPHasimkVDK z4QF3Cbqa$7zgr^31Y_g;jx-mBbjbo$N2ivGr)n00RP#OrIcLKS$fIdv{DJT+*DCuf zx*nv2rB9`1JN@aF?tx(MLi6%SzNIZYI@8&Ad`2|X`r0F*Va%p47w?HQ2py3?&{KFv zBtC^Xke}ms!jDAFgd9Z%4f+V`B?m7e&R+UbAVPD}>_<(^Q)*XUXX3E-@gzZ0i{PACihMm`L zeJu=NS_69S1B}L%H7I*-aT`PERd^zaPI&~y&sY*xe*ENPss z*~fhga+U3+)vvCuepNI)_0-uHzDJ=U{%rI$H(*`Ydz92iNrhMND0V;d(kgKU{(Z_N zIf3uj!;dZTgY)28PVYk`kTs*Hv$1A4);`z2?Aa8^hN7#s^r*45rMokp7j|IRj^4unIAFt*L8HZ)} zk(OIs6m^40XjikisHdF3j?7YQvRb2ObEAaIYW9x&qI95^jYTmN=zMnw#V1fxhz=z$ zUBA0Y7hbszmEtQzUF){=_7bLjmbTyY8 zduOk%q6Ucl-HGJI&7VE{f?zz6I@0_&(U8b`8YRIOHp*L92c&X;+2OKLZXnlGl@>!V zy@ckjJ)@Dx=$@`l{@U3;HPt^jIcbbe9v&XLa3UNTzi?>y@MLuV{^h0JyO);tbKZ|L z{HW&-1L54fJVWDzI25Ksv-@3L}>;XGm9Mu%8!L26Rme7_c@Pg3fyX+;bC%D!i`2E1h)or$Jo|#|QDOrKX@c0e zz~Mq)7O|4Y1W4wwtEDH>o4SMDtv6kN)xtzqXHR}yG}K21o4aQ%U;WHyg!)uGNjgvz zeDZUm6R~n7=T0g=t72Ilot$%rV=+=ye)4Phfoo&~V20d<&A2E-CHDrf8V$;!P{|#@ z67v5vczLWRw2)398Kl3lHDbp(qE!FRKu_avD4d9g`n+vno2O&Wm<(?6HZ?W+ytU36 zcPQh71IHeB&)7UZkJDqa8=OroO`)DNMu0iF@#}NId3kSyjpjr?V)=Y{ac_i&?-f4u zHsOJN`wGjr=OX<6;4z?UrO$&D*V^cwp90+y{Z)eM>OghOk|dErK21rs2&wGmZr|~) zwzjULzRpFXyJz=^5Gj0XabRFkNEE(1vbzTp!Bkie%74eRYvG-d=%b8(6)W1Lm&jxy z<>QuAM0(!`ubnd5Yjq~8adP#8qT!F3g$(}xqbxh&3lafF1$YugiN~;iHdm+{J;r zf5tPb;U$m|A$iJFRH(3u}UI zOt@&@Sm7?po#(ctRuH4Q&td?2eL(Z;wc9p;hl=6i*Olv|CGhVn@OTOQOA5TB1paXa zo-BcXPl2}-!?k(^-c<}2f2hFwWcXT~Y-R=Crup?>ej?9HTvOnA`Fh~}r&^-|zxo{T zYf9h&<@#$&;FAjcdKu2fBjYWmXLtj?OU9*LQNH(b`Fm_!D*RLld`Y?frV{wP0)M3p zXU~`M8q+hp%Fibs!&;Q_STDTU`((bpqaxDh#F1GdKY^FX_gYf?(Zw1&X^~V(7gFRIVed@S8 zH^~lA=cZQrCwEB|E8b6;ar_-WZ$WVv?wsZEh$_jCL0S)wI*`wTM;)j(8rQ_ooG=I9 zWi>V-FHW3AqF6{T=wipUmT=)Gf=PJeH$VRI9~K_CZ$R*E`hT%ah0jRF@yU~*SvG#Q zM}N)sXh`@X+oOD5w1+r6NpOr9+3_M2UPuLsh#!$>TxJTXo-wLL%**e%u>Q2FDXbrH z6^c0Va|aZE!KZA6sUHxnD%bL${gJ*2gBKwNrgJKXDAsqUM0^eYv5RMC&*`l>dh}H( zov>rQ%ceaM3I_@|CzA`^Ej&kHp8QUjJ1O#deL{%*Q;UOVIIFx)pv@bb4S^_7&!r^@-@NX*cb_q_prk?SkC)soRgeG?XrL{Quad16{ zw+TVwLzGus0#5)=Q5#c;--`SsBfIL(K{ z`%2)%pE@evMhDS;DSIJ{kkgYUqfq`=z*BcDHwpYdUSeO|gA=?lWY zh$KfiJTBh{@IN#D%;8r{@Fs=_;@cd4P0{tgLUxG^zqSbeaV_y@e*N__oQ;#{fZ*WI z1SkGTjKm2z!C%gDU~9Dcc)>EDPF!7^73UEcT?k0c87FiLXEJh@2JJrdcR+-%ODPP zIsGPkWlfdUS!Xzh7f=*yDl^0SiY=nnVySO5j@Ma=e1gO?z#D4WdVGPcQ&ebGcno}n zz!!(N39S;3agq;FfoA~!9%P#b_qiCfY=MMOq=V$pQ{|y_{0sUw&*Tx2VnSLaRZynT zB-vLKai@eo3qGR`Qxr#Oz~3gkQbe9I7w9w|0+guDk1iebgN#{TRTm{5L!MbUAg897 z7xJsZD{>VJ_^+pM!;gL>ykc?^(}eu{EndFN=<|zg-T}?6Y~GY)9V>!|IDGBD0Z%hL z@#~`!{40P@Gy381xCH+R;8|1@jp{hOLxNM>#lz^3!;>727@bD*b&=?t!`r3n`E!ZK za(JI~{Q$22G2?X{o|oX$YjMq2*!pmIo90%=Yf@`b4f%f@s^`Cqo{M>n8TTidO*$7@ z9S&K)g4IhFzvNeWbGpCQ<}&zJCp`5AtHduH(SWO(l&5%)%qbYoe}lQlMcU(hY%S85 z$+!CrhTEsuT117sM1u|yzF1sOeHQfkEkXyEUyy&r@HU}Ck$=VT1mGn9HsiVPV{7^} zyH7}SJHJ1{QDrcyF5_3@JH+k{Fs z9xeF)``B93{bTwhJ(ux+{yF4z$@dcY-k)G2Li1vAi&|AKl~jdaRY4LrIm$ z;Adx2p%$x0;eL9hDwC8!NAVNVIq75ubSoP&cd>thId|fs)z`*9`h&uUUq0L;SiV0! zvhT#ccS$@RJ>AKk`&W)XVP3|cILT<1!`o#z)(3uO<@z>ZUY5_4lmqyerTb)+`xL_i zLJ^$ta(;bZ37q6PhsS03nuGkp3Ve%z^a+W_Y1laV_3g^_@sjIR9yebCPk_g9J@9v8 zl8v7NK(K3tW;TA36~*vSF`Usgzdl+5r}1-myafIw1>R8tC)vfXPZqOzdo;APxB%@h{LZw2mG26IO#|H`fE$zq#tqk^$MKE zL;4ZHNk0NU+5W(|U~{yrJtwBcFf4>1rMVSZAJcO$L9J^8yj@*ZJ7 zP#`LHZ}trx7#q7_ z*w5mwyM%39SGH}Tv0_h5iw`nuQStYmXRN2O${I}#<616oE9$2}V+*pekxqqk9^hH3 z&crLLQkI&UIKOe6q#psl>dNhgx`Ebc0t-+UFmY6co6L>1F>}V<(Ps)>G+r7#As)i! zLwmo1a%%PZ;ypfH1TW?Z)3m3g>x=gk(-$OoT<}OdBu@BJu4j9b;W0{k7I|N-8pWe8 zRVr0?fO;_XG+BF0a+5Aa^%baENQ7Zg?yf6Y1gJ+VdGaa9RH>%|PO@BQRR@WdY2l~S z{ZVJJnS&2r;_)Icg zfb#?-85Z$UvL`tFW(m&XE{yknRl`CbCwBU!=XFl@YElg6uObdM$8(b$O3+lEEELKrOx7v z5|ws6$TS64C89&eN`#47h>5dS;m!F4SGPT5^N0Fot1dLPL_2#|y}jFeH(zW$G``86 z8Zt&4Bi6bQ&a)VLFS7eaMhagLrZRJ#{w+8&G2R#GOgaf~JeEXw{yJNiKFu%Ly13!v zL5xX(Z`J&q;d4EFi{_USobah$-=_H`!>1cMT`@cXICMHChE=a}?lNzoiciwzsw7NO zju`1}ROJx)Fu){PNR%m7i&y%Tnq)9f8U2zu_rurj@=?U=WiR_~r|vEL_PwR|yEK0m z_hNMU4L1LPkYMv)4-XZ?nT+PwM@!(O!*F=K1Wq~(hj)~~X&-TTvII^x0f)B~!*-k;ERI#?=kk%dhOErH*|>ivo)S^%RE=A` zI&1bx1tDYyV>tFF_~=*HoMBhsX}#w*H-T}KxDgoserZe zj}%^&==&6t$FGq1u1ep<@M5|@#pE=fV>nK-RuKZ3_s<=F(xF}EApdOKOUL+0~J6OsFk4pGvmGsDWud@8eqep+; zsr!MPBl+vMB1!Vqy+8@Zx&$1NkA~`^oI6LSxKBKJ9Zg6jIYT4CxRp#iHA@F0<5@bZ zinIagJ?85J?FE|dm@p^3x|d-oQ&=o9~~hl8t{O#p`r(K zXj1DCNj$7zl6&zDWj{-W^!2!btp#Q8M3cl6_`yWCOdpPj8#?J^>vAf&Q@e0MM8x)iH4p) z)Hifw`qtMFJ*@2${uA_|g@tzROc6C}l4^`_D&TqnWvU>Z$PC||tYeY1Fo{d6H@IUa zTaC>SbgtG%`p8%JuBwV1+KNm{_(P#OHqwUrZ1jBcgJA8Hypb|WP(8Z576F~#;Qrbg zSe&)M9&fxsp4&!1{y)~<1TeCy${VluYRgioq_)(S+ACE_E!iqbW#6|>Z=sW>n_lPz zx|_8TXoSWV1yRHqWKDZ2A3H{oN-Wx(ZL-ZXZ)N|92FHEy7K@1?tQPS zI_XB|`+sQltGapbzH`q#_iXo^bD3+v9g7O)`up_gIv}nbaYu1*%pY%XI~@VHQH0xF zss-OQ#`@lCHLaLi<66{RB@XY8iIH4@`k5Zzj`|mfK>$DJ+Tz}xMeOZiZ20|AjLi(+ zye5a&#l&cvo5EYYCL-9etnB&^wSIqTJLV~hzE(wF^%d{xx~PsyZ@RWzhqp8CgxVXn ztZ_^MVj`{42XA?>^zNTc_85C+l&_QqXZAgE-+kpVaNoq1VeS7s%)ymD?N`6A=WIR7zE ztM(}d~l}=NsZZ?ReQ|G1hv+*<*()zGxYlk2mpc;FP2x8Luh# z`#Dn71A>j>wZ=T{pLj?)@%&rgsaR&d^2PD<9(Z_{#6MQBu%Rrp(aO38VWLi9L@ep^ z$dL@8=LUF%=8^S8zLyem5Y?;U?^!6XU`p_pW zhcCV9RkI^zMJcVCM`mAj)1`+kpG5yTz%&Tnk*(~1zKq}Xvv`6spZH`22Wm_7;xVVG z1$02qYEs-mdo_dBjEEyEXjs;@C+ZC;l=|$ z$o04qg~<4PcW$@Qp6(io_3vg#^zQ!HP*>V++noRHFby_sN_A<)4&PhlS`e|un2tMt>nYEgvEhpVBGv@M~+?JtObYOFC`@+$|e#onR*V*HP z+3aY_xqWLYD&J9R-!YSplSh0^_H{Nt%eTy^gvfAqFt;*EK`U^^r z9`Gc;{z|j8#`@srH`grfjSmfsq)OX2e;%b|FBwrb`Px!#8ti4=2RK8uIQ3c3Tc)xv z^k?-Nr>56{!m%>Vz%jKiu1Cr(o^H&Q>Bd;x;8~10pwESEq)YCE$8cqALK~iMh5jW^ z=;L}x3y#a!Lxcw>;?{IOyqCy%f%qsCX$>Hei~jURg}IO(Wnk>Y_3!Vthut=t%Mr-W z1xJgQ6-R?}d7HP!WwW`%_U`vze`4&p=M>MOP_yx{wXJyK>t8=nY%>`T8=FIiO8@oT zb6{PDH1^K_LExcGc`XcbZZTB2Q)S(sM7*7zRl(gA=}&CIH|_y3i_&(6GW_e0Q5O{* zMENfi7#%#EFUB`yazn3}FZLrNBQhEsNbD_~e_=YA8;T8WwI$MK17@7&I zk>(h7Hws0UYPh7%WE#Hj>Pzd)rr~?3_xxSQk?bo=FR1lj?6^4dO2ww@K!D}%;Ny|; zbzMsL>J7jfVGIJ-enZ)l@G?7EvY3@m&>VFTT_@sR7EXN!w%y>ZmXRU zE=**NT$YbbFE&NvDX-V%GS^#OLFf2qj^8z{)<6B~VA4}-J))}a(1oS{BWPmve?Sxe zg>@ZRSBv{hG(inbp6o4ilpUab-OC~3J~aClRE*^etq~_2+KokL*ygFX)j6HcI!DB= zj2ycX!SD7+y4z+nUu3EY6fzs%z6pxug9DfKO`cou$TckD0;=_D#u5p81%E$H$JOq) z3V!vFJ}(vBRNgP*GA)d!#P8GeM$DHHc=$H(;DU~*N$zzzdSz`;H|DI=fEUQ!V(4jF zbRE||t!dOcEn z?<-w2GL4R)w|2lUaTxSNy){zNtF$2D%G^}EQBuS6AmT~ppHQDAKWfzKwMfm@gBI@e zF(-=NVMVI2tx}#Mn+~z_wwJ@9)0zzj~?VdO3h%=_#ejNpuChG z-fTXA|I7;u^14~zc&+Zb3>h*39NR!^kRbJC3Gy=9hb}?%oef5R)kx}xtmYbk$XGu1 z*s+ba3t-!Cr*Q&#Ao#=tnBMpCzABH%x;5w_1N6u;UF3JN(i7L9*yDzhpMVW3bz{ac zq2!Ztk*h6)Q#o6%>>CKg?Z>`tG`VvNeXn^sUT|C;q38Rrv^Ci1)3o7@P6FCV1k2TSFPQ>!N`)Fra_x zS<Y}arJ|z9u!b)v^|KVX^C}-d9r4#EpW6J`ecpu#E66NXJA%!k z>!M|!BFj{0?%e)w_wJfXwa=a3H?S)-?(I(uZL0a|SL$YqiDL7}g6c(Sg2@dR&qQ;f zxn}?5mhEGce)l|`w)AzrU~~djAMC_KXXVyfW>f|IY8Qvdysq$bdD4Nb$3gh1o03P$ z7$512h9*Y!0LrS4#$#0x0-yaI03`l6&ux>k z_3SwS!XB2f>>_rb>t^+LYA?pqij}9qx{mi%uQg2(4!fO|?Wt~5ClT!Trp zB;g5Q!QVvLX>M0hl1KMg%X4)xO#$VTpK`SZ+BOWt{Mn&+Q@Gw~wp*Ip`+K}m`!ObV z9>)P=?c@2(NXlt6?@*2LbS7g`|3i6D8}CQeUqPp%?Zfz;CZW?o=MZ%|A{EPRojj?~ zl#HliF3w|E8G1BTGuDZWp{lHtN}Q5j!GQ%_L=tV$Yf-vU9V$R zTC;IXmhgyAAD*2)GM5k~JSN7sFU-pt9vFv~-wU1T8C@r;_M4vB&jIpj#1z<24~|}@ zAnI;wbEqXmRu+`DQ6fAUhzeQC+`a;!rBY5YGH;kI4;qdj|NW_cJ z-N)4BSRfFO2LdtudJ0CU5UCiCR@VXJVeGF;-4(lmq_d8Smc7ohtIWtrNJjC?`@KkrEh!g_$fW@FL@IIe>sC@_e2XjctTIt&5-m$UJa#dHMdWmOdx^KM| zdKp)?z6M~Iacw`Tt?iE08|0dY9mjTQ$3QbsYAZTDgUy0SJf-I|H z#HKDbQsJ5*X|q6-8P027sYFtBX8pEi5VubVX1G`24#Olf#YY#?X?>D!y6B=~Cr|e3 z)LY1sW;4p)Y}vJI%aWsYB!e@79p@%9?W}yS*ue zaB^kx#3w0rt55hf;v8A*2J-|-ZvU>UZ80!kr!>{g6$j^QO3&A9u(i$|nVLE@n@G$a znwmN?*Q$JVdTMIA^p?#F3ouY*Zv86sh${Mg8SWviDQTJ0kD#wK@(d5GL9Css>~_tK zBb6PamUVBgbJ-HE(Ls;T)@-e`l?oIs&{Qr3k?2@mxK&cI?+_<`uhy`(mgp zE<9h{v9AGH>AneS>e2^EJD~yVld%nYNLivUycye`x88c}`$h9__rGoA``^cUgMEc{ z^9SI()A07w?G!f+F?W?Gs-kV4BxPtC0xdHOh?$uRjBw)K9nY6xtsMB`02A`_K}Bx- zjXMhgKu!J;!gsdCaHZ{=#&cPWjWuWJrz_`K_0i=f)TKY`o%6!@RBz3m7`yDxJLoRi zS^waJ&*8tb_~<^p`SSul>D3kCqst;5;WRsLT|}kEXoMXH&WY7zr|c5rv12vCngt#h zQ%Sv?{<_BU?gIB!Alq1-05Q>G;lG^Y4xY#_n=+ddXLsGLOxYfMzaA=Yk&DO~rCdAR zTgK^AzLvRb`q+Ap*>(HGbgglkJ<3Uva_ttuH%{mrdEFXX#{k!P$*bjpFh{Cg5o9l3 z!Og1-Vh$U_F^H4AykAYNvslKyflV-HMsvz9QEYvrNSdK#35> z6DxWH>px#&)i3yL9(?czw2S_MP8$JBH|U?W@FMWTod(M~4{wG3xqquiT9E@vIYO~V z4;QF>eGwXvJXGsO<#|)vOn1u}YU35pu|4>qy6n_>#kKYEhVAcPx6dqP31Z(shvjUG zb&+G031(iuNmNIXVw$^uwZN7~&@TNktN_VtGdM2wXzNe z@dVb=$+~q`p%ZB)^E@Q(KOr+fSs0p00dzcT$&ZvP5!RrwsX zX|LE#mHjd4$>E7A(8mE0tIE4H+x9dK_baZp7PuTkn#&P;5GIowCokV|#{is;zs3ut z4qI*CY5QJJL3jN-tSzgxOF6oFb9qk^?TmL~J8E>WUDk7;j~!WsvOnchA}&#K8s4MpjClTe@x0Wr`MkU@LmeCU$@X8D z+lPeiZNxdgFQ~2H5$({8CJk@Xd9dbEsNlK6VIM;lHKJ<;rH)|Cj5A}!ki20;quvoi zUVMv|?+Y2C+7oF!5fy)pBZfq34D?MDgoLFf*)JsQAmp!hri>Q%qJHw7V0N0e7I+=F1erL6otzg@*#co>cQxzrQ^Zv4@J@fsOmN zwbbsm=YkRCZb#DPY!A5uiPC*`TgzC~k!Vg}h$5a-`7ZK1So^qaA5OVO6Q=+{}VQn>+QZI}vDX3?$sz)s|W~JTY;2wzU<0vWdeBsa>A@ zTu)&(<8ozY3q5mrTDUo^G1eEUsl<1!i!ZOl#mh`_BX&U;cR~x7Q6t5Izs&{qw%scF$S{<}%9Yd9UPkLzY zWMX@w=pAd{J&>913`C0yX>Y&pl~diz8^%N1VxG}VyEi+MOw7;CCsgBp@@_BuP9FhW z`HFqDP8+Puiu7_wo-Zm3(R!2_cf-*ySGhb zQqh6nVC#-TcCM$Tx1%r}8{CLOZS&q(D(Vb->X$OHa6I6hjV4{K{qf9@)7UW4n;cAg zNN24W6iR+#{kbb1!gbQJqW^QB&7{T2)Ib3u#w!^vHvFO$fKzqEJ&a~b=trohE2q%L zUi#r1=jZ=$o2nS?PWx-OD5Ir+*#6pY?e|akykRf#+_L&Rg>gLb3Z7qvr|6NHmBZ8< z0Gqx$Amf;{7>BhU%Crk+5(q-Ky?;1!ezXvn%;g7**-&esuSpsDUacePW~tHm;KurF zc)^qC%4E8lnqo@LzN0lYuJ+Lkxdb?qY8cXd_pG+_mssHP9NM&yI^1E_eUy4mC8?%5 z23yOnqAd$1CM;XBv$Fded<``PHxDOLlPmfDt-;ZzLNL&g@T&g##KQUE!b~dG-I?+C zyK4t+;qimB8!wxSC;hWc&CYfxU(uzNc4(^S=G)uzfzTw<_Bj_Z{BsZH!d_Y9>$K4d z&2!I6-^~*HWe6vsa%?wR-(Yeki|wn*iJs9!qiOmThYl3>%@q$`bloPr$B3HfFDPHa z+G<6{?6{%4SHCWHx$-WYDG2z6fIUi(lwn9nh9Fu}_(nOdpPfKF_6UyP)#ZWMUlsTi z0znHGH0n}-L2Pujb*NGj{3*MkKkNvl-0_ZJ*Fy$*{lHSm%#r0#O{Bp%h)Y=4e|inrMG9 znQ#TYuDZrtB$*X-ggs}(xA|aCcU0)8m3Db+m0e!Z4^N7jLJkD97go-f-T=n-u%--S z<86jk;DkFtlx|=x7-0E)E4WncVt2LL$Md|e2r@}WyE>f3rND@zC*nE918v z;Gys^u`K(#nCoiWrhH&4&+t^M+}3N(YkhXlo@f89d|In`7jW`_Ku>&ExBjkmI%#F= zMrxw^A+CjS1;GNwsu!Mqi0htbpWUOps&e=!Yx=){GuN`vJkD}{D}(nOVv7FP=eOE} z@vtYE2=xSdV=MiwV|l+PnhZINn z)>XC-C1kxS*|omYAhOuUbag`18tnqCZ#Pbhi7{{pI^M zuf7)NSDrv`YtQ4u`I#_`S^xG72U))M+{ca{eeB%m(!;xVKfDAeva7GfIhLpOqp4T2 zpR{0KGCi;AK+D%^Jw!!+=x5jJ-8c*DAT*M{Qm#V9vR1Tsnxp;|5<)c$IIEy zvphVmE{>lXz;jXUeckZ%orK2`m70LhliZyKE%F=u6Tl8Rc?wsVWsDskG9(dJtc4c? zO=myMa(qNP%CaYkFC*ip9bnVRVSN z=PBT= z+y}g9Z4o@XAliTztu2N7_KRnMm#X^~MH}#C(F!F?OV zeZY&>){3@8(MEVB%oC+Q7@k#HC0_LV(DsCAV~m%)FS9yrxO4Ski5IOcTKb0Jy`l|x zVH@Od7_#bI<*j00ISJWlfxf&Z5Ch^64ll8JEF^$d>I^}dWo;7#{n+e|9kcvI+uNh~ z*e<`|f=e&G;DXDirxzC|kwL^DIt3>M;nm6;U_C_fHnHzX$zM_Bs5Zi!z?;fO;fKy` z&3R{)RKLaLC|!>Z&`%8i%mZ#8^lR(_=}=d;E~T4JHw5V>v$9XYJt_v3^Z^t+T`T7& zBF!mBPhcT4wh^Z!2X5INHrpWs|%+}#=+3&wgZEp`9bMP>#k2;s%=yKB+<|GZ1MFci!JG5Z?-!cbhkG4 zgvN7$&ZH+6isrp-eYQ+8(-&?DMGDatZ;Q{Bi^dy+ZT?ukvA(l4n2YcnwG?o*A2_dr zJ+=sJnb$*2=EXfrsrt}W%wP{AZlqI=n>%vHk{cRk;esJ9QQT8*Si+=3sP11cL36c&gDB{QTmg*$m|)67EjA zN&7fERN0KV^n-5`vNO>BV<1zffQR^T-m>r zDmdbeQFpG_oa!5z@Fcq<{&+Of7By#Vm+d`#MYDaN-aavwnjU0r_33ytoJ{s~2paFf zylnyA?1)r1rrm6k*{U^8}Y+qfaUp)mAcV9M@`II;lkGL9 zdj}`o$?gy){~w!Ng$_>XzshMIZI#o^iI;qAV)a4r^Y4N&oc%oWcV;^}vg65kJh?J{ z;sIFThF* z1j@x?DY)XTirEv7dBd@xS9RE0TLOMxD4QuPQa*Oe_Fnr4Jtojovv&;8=%J76}qb{TMrx>8iyh6%stqpZ8 zq06w1x{SOprW{xL)TdR8toQ>d@xK+qgH0+%YUb zvi=q-Kz=m2(3eY}Qyky7ZyfLbc)h<3hm+Q; z&J}R`rcyN2SNg{6IB)^^4cuI59E6`ZsA0kY*cid!&{&z5@78=n74{BZC2U>Gzh@Tu zBGG}xO#7s}!;$j!PLK76vd)g8ay&G!t-o(&I1=*~nw;m%Eu7v13jPoH9Y^xg0N9DAHQGJ70LMDK4(&sK0?4Z#rt23XQ&oDDC<|bO#@Lz!gfq} zI~}RW!0gn7Gg`a#UA{%2dywcJio`s9O)j8&TV2i0nZI+BAxYfaB5=d85H~{WA=Uv8 zBWTDcL1X3Y$i9`oU0L~Cj^-mDDJ?zmL>VWBThR|9ZnS=kjCVz(WZw$!EiK9W>=?Hn z_cdWf$rZ-2TLdlXsvaJKi}o!Y6P`g|HWXQIiWQXOsn$$KvQr6{z8mgqgUefk{SNeH zlin)y!#E!~2JTXWO$bqpT?FmaBSdV8C=+c&`gv4+E5a`t!u1LDWBWEz#%Ve|JZ0(!?E*qZ0x$K$?rB9N6ipd5)KCx*|<=Y~1+ zI9(vwHP-ma2Ojv@Tmslp3_h&sbAg+zzzk2G=3A|hT6VzX169d5wg_4(r!AFz=_CM@ zMO+`~A`f4-JepsQc6-MniFj*h#2NM5o7;-9)Iu=p=?sOV?ZM$}Zdo}VjShJI2+8&~ z1gxH5(i_OfT%ka(!yWMW{Ph86S8i|%U~R$>&If+1pi&7ZjW^ck<{3&Z?5~1rJKlVQ zvgHKsyku^!^bU*x$D(75luZsn*(Pm_wRn!9s*E7Sc*?0(;)~^n+jcH@wxzn3b}GmB zUiPcs&-VAv{{B~&?L~j9FQNCN=#K`ST$lQq#7>01602e|3&xw@c-}~zqaLSW)eUcd z183r2k}L+0{1=_K)+sltjp#Eb;@%~%s*d*LI-tqw!H4D<<6)W*?ZFx1S=t5>Es2p- zzqcyzrBYesz>XaWOP$$RW2-4F^wl)fsOCCza%tN|z2;i8YOb|(6TWXHW)Qy`|JJu+ zbK+WB`kuer=j--=53j-~$+!*!Udbyd>8WjTWpVZL+#;QSqq41lk>?i4Z-`peu~e*% z&f)p%dfZOUiDP^7)}}gRjoq3(@7SyM^wc=&)LKVPmvZBezPYhVMycYo`92OV*@ zJMK8hdHEl}v;#0TLKaKygRoe&w@Dp@^#WXLPA7Wp>v!ero%L#+t1iFeb;^zRDUM70 z9e(`(lG3jb#l-RY(f2v%yH@aG(h%hp&3N7YLR!*m#q$IrSD%XniGV5p*B@6BU;n0Z zV~;X0*Hik+EFjYKTljWjGUfrjH33=+U?<;WoFOTcbM5|yy!x>QnThO|yk6|q$n7n; z;g852o)ry`RS^+I9{1}z`gb2zePM66HyoNzzk0gHkCLT@6J? z;I=O$oc@U>$6QU++s5&#hEA-R^Nri!!H*a=X{)X5$%_9r-5D60@umv7P-Z$FcSM!r z9(PRn=C%D!?|Bym;PlsuU&a8F_iHI z^25>A9($@G;7E3Lw0a}9xT9Y=?#)iLw~gn#&9?sf`k{`_L3>@F-A6nLyF}nAT-F+> z`*Jl<_YGjqXm`puVa_H`2jbO(zfgZ*?4961ayzowi^2pBZ6b?(bO?Fe9~j@@OLqqX z8K-G^#%grt%#lbW7J_4V&-T=4#_MY8zp~UBbNHqcZw>Z#93@V8{`_%e6gUaO_rpCw zi514tL6;Jf<075_3#0uQ2NuGW(mpP9I@Cd=Y0jAg z{_S5H_kk-@zaey9dxD&lX#Mmry&%NNjS#x`G#ONoCr2q9rf)K z6IiR}Q6pjj;_mtp)ifBHDE$uzHDLG+ZAR>kk71vAr$*JnAEd>~35uSByOpB00QH_% zGk(tjUGyKKO(2e`D=Z|#>mYz-$Ttx=4#X9?Ftsfad69t(fK(QWg?B)1vkxocp!(`U z#=>y~s|dHycl5sD%^eL*o<>KoIoTDo2kVawT5H{jjzFEqX07pthDJvBZPC0H(Nt$k zFk9!X_ho<6o@);v!QJhQ;IKD%4s+o~qj{{R#U9Lr>_)S>q0Zir%63mH?bs!XM6k8; z+mPE~Q;bfxN5rIb0*6}!U2{Eg<+I)dwGr}qy00~BPFu!RQG=b!W>T*9PX%l-chQBuM#M)>S(wve*c({Q~&7y#xO?sf1vvr=grN!GE z3Qa7lF9qE006(SIE3+k`E32zNG5pT(X7twxYL93$OK3SMxw57z^p5?IZtHBo0uOaJ*0jt{vl0BTy6o3ZV@e^ z(;VNc!zsNe%%`9(R7Hgnnld18$#zcF7~PT#BThkvd~p>OszPRvAN=3iJdZ{Pa(;hq zAQ~Cubuf}>ZB5`K7++i4M9%BYO|(&NOb>K+4Gwm74q%*+t%g4-=Zp7-4I;M+Ga)o5 z?hNf?2 zL=ASNO%s|_{gd)FWUWepnw&iNcU3Z#bxHq3pBwNK60(glO?nu3hJjhr=6G^}S%5?l z&-ig>tP?c;7NGTsfEz3_GD0s%-jT+6K~l8+$>iwpPAvM;JqR5&)=a!58V<)>vVXdK zz~R|-4w2U$EA{?;h0=b{RoD1gfWpEuPFycHjrp+RI>v_xdNogvnlw?JN^Wh;<8 zYt&TH?y@#oowe>vBgt}b(qvpvjV;N)m$K=&(u8+p#U2>f+Zs8cvla%UBf3x^fYP7^ zVm%2s%VJ$;H7IyNJE;l|My7gMxXp5VeA?gY&3k?RY_KU7Xqp&kEqc<27qn>Mag$*pnIXHWeBgo%Y&>`dYK4u{qkDN0~NMTLr&(-WUd0BN`_Z zuvb%-NuwO9n4};sCn~TuT*)#8bEi?1=tF3bNZ51BlL|jL+||)jH@9tD-r3k>Pb$Z! zi*Fq>?%X-~)Svt=z?I0Czq#cjjlfB`25hEPupY>@2`c$is9&Urv>B- z8Bdld=gdlWRxXut{L1C-kTKM~^a_&1`!BfQ{X)P<+w(}Pox{(?S1{5mGVP^k?w z^p&a?x{_nl-zl9%M!IVnmBZ(*BpoJKb}sKm{NUzo2a_(+xPzW<5N2MmR-Bv z0u;${jsqr#VW}D>EyApfXX2Oc*BU@#25XnDE2OIl4A5AEgG@ljqb#|Ufe{#H5-><7 z0a?u@2Y1CoCSPdh!6WA-W2O+ID?a@0AviuBc+W^*--v+6fc=OkVH2K4cUlHb86FE( zNF4+}@z2?o-#~+aQ3w}`XL_Pp!lufEwJVEucYUM1&L63<+_cgU1J-1=TXRcSH;-ap z*EnGgdmYO7UEX}a*WtUX^vOZG!vU8U_-hgLKt1y>v)x!R!h>{p?_F9cuEm7bBe$p7zG}KqAvUq}=$h zBc93!V?8KYj1Hg*~ zuQ6S)c5H9hesKF|w%>ohGI;;}=n2{9iW~i5yBnm)7#~c&gcrBJ4!0_9-l(j;1LsA3 zPI*Z9O60hBA2Y6W4+FI)YhN*J6nh1B<(l|F(={Ko*qfYnHdjr+p7?2|ziVZ#y*FH6 zV;-z+#DjQS4RmkPh7U@$Zcnb^O4P5B79yx30;NRKhXt(>v{AHh{Y12+AaW2PT%;L% z8l{NiRz%=NIzcV^Z?oNQ*X7Fvi`{C(r)TTME>BOkzQJp3Zum`io3|sTc;4YjHa90d z?0Q7`1j5M(cR)@Zj1D;3zrsk0i>riD%0P{hmP8U&VU zZHI+UEVto7&T!R%ggR1dp_@eIOccGu?)ronUUD#nx1x z&e`f=tnS{Lp2+zoQkhsMPzKnveMmqOI-Tokk%>aOFhxX47fJ!DO{CUp`BrfUP*Ec2 zq-9}Pe#I)5^X@`5qLMvPv=}76(sSV#x++eqL=X2fU zVX$EgH^B~)`&6_;^?j<&Ww7LLmb5t%@p9@HAy~YaC;HSRwL395u_IPx@1?80>)ZZ5 z&7j8Kg|`3yto{W(A)Y{OGyJ1^p@4&$u(ru@%n$YvAqEc(YQAby<=vF6`F+^{x;N_M8qo}!lydw7EI851otVyV!}^MItQhqkZ> z!{iyz+&_}{J%-&H`7BH}Jdwj)%m>cPfDo*MvJKE-6467b*Q}HePYs*sUh{mnV{g1S zvC!V#)iyde+O{;a)HT~O+|rwD?~n}}k6vg_N4K=Z^X;)*GL|3joZD+Ve4!;9nnwIr zI-HKhI;MLT4%m+Xt^yG8ef5o4`MY%-Xt^a798>}lPeR-(z<{n!WH3J6{3NH9m9?ab z7Q^UhGQ^=cYoUf|2FdBWW7T>OTwdJlw|Y>(rfW!5FPyg3G=%yVbH%OU30Ef6*;{A5 z`&MHhsMzOyJBszL`dM?J;Lk7g1T)F;W`D8Z@ANIYoAVZ3B3|eBwna5xxkAarKTKp1jTG)+%k8rZCE#YL{z%#@6oAI zGB{qBpIYh3ZwpPj^P&DZ+kgJIqCE9Q`%EF)ADd>0U*8b(*Yr~Iq>W>8KXkv%f6k*c<=mMSZTaes!CLtT%K zV4Y$(!Wd0TX#EbmA`4q0;|RimOForGm2P>p)$Bc{^VRA1wUK*Y@D09x{`-lzOfy&Eov zZb0fo3zKeW9_aFcmDo|80`o+F4C|4Q>P3YDVP}mg%#06Ve07R>);2m zQkE5%Mh%vZPA=fyuF+8xf+m^F6H92fqdtYL* z#!=fJ%(*Ay+X^~jL%;=q1@)bvShfxXubS3iMw7gbH#Fh-9-nDhpzN? zjMq7=r2%s!Fp}vsUVxd@`FfAx^*SCkZLWf)9wMbj))r-LD@nVI5|JF9G-?4I&~wIE z2VF_^0$*XsEZLgC9W=>Xape>3xRTnrZhLTNw=_AK(=6HlS)_nmv;3D-4?)l|XuN1X zXsj_U4_l0;)1-m<19u{q;;-JI`U8*%-g62A7Q5d*Xm0Q~RLKOlf2<*3A8Q*7QYe^d zDk?8RCeV|efC|!K__B^02T=j1X_-DWk`i^lQosnSGDvNTd8xGM9NHESz03;6N*=~t z_XMsHNDtJ{&mGJMqb<$)V}j<#$RI{*6+F_p@3zpXYkym0XhT z#4hj4lZSWPYf{$&BAzy0Rsv~6~o_n78R%nzi37fXE9vG z*?@@N0F%UCqo5QcqI?`66(u3u42i{=nYU#(4y7$4BbM~=#!TuRwWEwT8moDS^5z-y z1J3kVela_d@%&Wn+0~UPo$96o1y!GZ1%}=vXrmV6Nh1ze8KC#)6B^9Q@0ID@Oh=E&f_+h}bVR)mqwXOMh&g9ZO!++#TK%>1o~{ z9~@7-GSMC_m~6Fai>f^EKxx};i;K@GnY>Afm7aU?MI~B#uBY^EB~$wLGX6sR7!6aH z@879!#cZ`hUlmp&cOf!FMuy0se;ZB^h>r|_&cRwWU;qvHUW2PH2Kk!`6zyDY5|Lpf zrIlFO)}{_c>c#O>GBDVKwx_F~6J*Ic-^$qlLNb8S=a@5PlC0>5_w2@xQG2|n7|#r^~4 zvYC1e6&ibm#=Y1Zz>@Cog@7rN)cQ!5Yh#V2-rN)Ki8X=vdjh^2YZ|S+=K2$2FCYWi`$Ndyl;Lt63z|Q+ zLirV2NOF9pfRK(kURF4QZ9{7S--7tY>UpU2E!H-x=fMgRf0dGgW2bw-Tzxi8#nz!) zm*^-sU=%3EuBAb2o-K86ZJ!HHdb^_wn>NjPTI*LHA3o>kA#2aJs}^RjT@=j@;WMF;fTP9E*KnT=hB? zlBAQ`Unu){=USarX4i`oE`{*ZWT2i-FT-(!<->{QbjPYrE;cIu{TJ8G%!lnU#{&x= zbNkzp(Sm<4x^;N@!n&HRuXdzePnCXSv*+`zGtq8mzPn)CdrmSqV0MHW@K4$oZEFck zB=S49cv~H#ju!i9W859j#X}pNA-9N!VQmKLTtCHHNLDICY06P$<}1}o^s1e#BZ18k z%qU~jDfdX_bp9A|CC}q(NSvnOis(OG!-Zz#5Xrq(&qD)!{l&|BmWN}};pM_~+d^Qn zG1=UaoD47Im5Bq_JCtXf*PeReLQB{3u?=&a=>2<5?a^_U-&|^~?;dIGuws@K?6|N_ zF>SshIt^>pqbeiO4wMjzAS)xv^ZmHR#MB|iWpSoyop3%GQN@+amCJfzv{qP43bCSs z8&eV?bXQolh)_pZA(VGHmDsGGn;Ds_d3xdI`kBEQ<>p%hNz3fCbz$J)*WLG%z4@*| zb1J%L)X^Iqn_YJP<|lyPx%wOBCxAb0xIl;hWjGNxX-tCQ67%Fggp?H!DKGh*>ym#X z58`^GRH7xtQvi{G(g*Ln_!K-vk5zoeFhx}MnY(p(1^*p;7yb*6bc7V+erx{)x7l9G zP3OjQ)A=Xgylr~hI6hxhQPm-4b=Z6n-_!+@td$(YJp2&j@K$W^b-bi{t(`Uw&IDi; z;{dF(W*apn(i2C*zj7oT87(W0Oq@4S9*>CcERX5Q>+s(L$`kkV`re7@iSdc)$uDf* z{-((pew}z0`~h)x8q77Ih;of{t;9=(dMZ%MSR-zkk^56iR%ut0i!->CwD9Bu3(7V3 zmwu)^p?qb)JX#u5$45u`F6vH?13v+1p=C;a*_rleo`@4zYOJ(L5lU;4v(DWE!ayGs zITf$e8Yy-utH^hy#V_QGmPuk)<)NM){AO@&RuSUlEuGs&6Uni2I+9=cN@#d;ayWGN zfVnteR=Pde*{*KXH|ig|TiG-+I7+u9_JMYQud1*sjj$;}U2F4KnY(I5*?|u$hvrJ} zwy7UDwF{4-mY4P%@^&6S({JYD;tZy{4QY|PU4tvmki(YL9A%weo6br@^>hl*tGR<{sMw9w<~<#HvP?6})5x;&Ja~p)O{f5v zfFU5i4c7@=J8+!?ad?3TW0f1ZI%61dT;UJSI7zzOISath934HEalV_~Fu(sje zH4S10l$y)e<|CIry{>6`T?=#01~4yHF)!1r|Dniv+0WUq%qbt_v}pI(*W9y3+=D|P zwR$A89t<`umk*b!+aC?^-P1!*}__J!{9cc-q+I zJ!|1P{T?~44XeM@#typyV_#H6_?<=@Yhjk~Y?R}IR4Za#&jB7r#d*M)^M>>FHT~z8 zaHaP2NeDXqNMRnO*d|O*u2>!%Nye!&N3k-&x}l!o_!Rw%_bh8t^0EtLBK~#a@`p1n zGq;|mUwTphw!RVoaKg19X_!`4HC@e0`~!IC1j>(8=C_65zhhVm{58-|DFv-yGL(X> zEG3j?VLc^0-+K7r9S=Wz!4oS_;Q#DHi7G!*jsdUh_nP96Qqh$a%oeMVT&sLT#i?8P zpWM;sZWuOeuuW6+a&zXg;XCdazT@q~Z^!?y9eKx{BX`|3a_2in?j&Iv0qY829mhBF z!Ha?&S{w|5|G(luU*~ zt;$9EH?h_}ZTKVdp5KnDHrE(lshCAu-0%tD;iqcK@-4$F3>N$=<7DE7YXElwvetuf zGhm(GbStky+si9R&~8*b5k>h?XZwKx;SbBy%R{A78HW~(WI4im2 zXD3lA*q;RfQYon>R*pjwZ0YyP6Su#6`Qe9`-+en?rx=Qg7kd4@n3pm}DzaVA%ML0y z78l;FMy2@9{dXTIc9}Z)+%2W!ciwUf36pcv3*7DpTPWAS)neUh%Q}LlsG>m*L7uZm z8;80Utz5}GsPR!Nt?1ZY-Sm$aU=76J`-KreYtA~bxc~NTKUSI+H;XT&|6c4pvGUg| zC&WL1DQb98c}{sZC@u?{V+}A`oz!s|OUrV~%sAt3Mkmva;)F`oid_%{Y$Ao6o-i43 zr|bxKwzYaP(Xr@!Li;)zoqN$A_78XTqT-l;xU-O_e2yA!Ri0CAp#L8W`u}m6{=s9w z9}uxw#bfZcz8FqeQr=j)TX_Q9r1UGSjg;Xg^+mM-k(J$s5mZS$iFK|5%k+|x*$#+r zti+oW-{?c-?gH0BiE!H9BO{J@$QkSyjpygO0*;o1vwO0od$zp`Rc$ZJ#Zz6`M6yR2YU>)@ z*M*&X;&H?37PWxW=`8A{Vol_r3%>-p6^2KwT<1{px}QnulzZ~60xQI%%sr=fofQu; z^Z3RcWELIJk$`i3MdY-YdSRzQEiBir`*~`nHxe1#+MQZx85JQ*?nNSYxw!+kFj#H&o-Y; z{Jht!Za2+u9Ju!Q@!`UbiKNN6-L$Y+{)zX*S3jgq8GFHDNRKrdeZgmBw5E$LTG|lU z@O&!XcWh|B`%*IwL^N8=AKd!vPUZf{;AH6w&Q>S>um00Z(3}L_8`L?}EwHGNv-q6{ zBYP9-6Ij%9#h87oZ&Vf7WerdjG|sEVqQU}XkeeiM3SC)DkVdr22*wrjxQzJ6_rqtD zFO|OfxhIwLuA5VOmEO4nrqX|vexdD2ub}_^=-;}IkD-4u7Gai)rPQ@3kFO z_?|#fTFQ)YNFf$P3*0k$bbpnCHPsol)cYH9{=CPJS_4z(TzIHE9?mXbd<0W^~6uV0p{=@7Wq2F0?ew1#+tSgM~{*+mpi>PY2Fn`mOqQ@T2a^ zsfI73;n5E+UCeYJGh+&;MQE$04lNn_6U!?ltcH|WJfvWQHOwOfiUn*1$9hJUUL+49 z;K*vh-;}p3-nf5YVE>Ja8*n}KMU&as{))-jYcjpvZ!P_k@>z3j=IHq3(M)Z9-|p+@ z=C0q}$7`+WGsukW=o=~E4DDU!N9*fzg}!{f?Nh`z_gep3ol<%BBI%ZE$0}BgS?Pm^ z6V&2WvZY@tu7Qs!Z!TT+u_mR?q|}Yyx92|G*|z#Kby97@vvGZfPpdqOL9^H_*(L_- zu%=;DTGI~2a_@vvFS_w7w|#6tag}~K@Uha>0-iMBIj0N{cYL9IVFjDhMKJbsQSm5a z0}qw1R&IL;4>l2!@zU?9v;0NyU~5c=2Rog}RVjKErBM3a#Jzjjk6#S*w$jxf8z}u! z^qF7%l5vCj95_AoOL7+KmtGKl-qI>R^TztIGT&pT4OXn-^ zQ{K14e|UDZ5w-L_Z9G@~6(mX;ISA_`pLq1l>C_?X6P;fFxmZO#{JU~;`#Y|foV?;4 z+x6@8@m+m=yN*v!Uq@27Zn}HNR4O&Kqg%Uf9J=hC=kLAi^5Nmj@7jC*J1-kr=sfR+ zty^!{+10g^*Yi5}CZ~26`*%;ZwodKtAJ{#aG4rQ$T-G>XECDfuLrbl# zF-I)FQT^uRslDo7pE@?8esA(r=frAEVm6Efr`*GrY`%G_ zd+?Pbmwa{Csb`f_JOA}HHv*;&Lldrc@2L;Zh&eH>{zAP@eF*%3^ob;6F(;%WCLv>J zWe|*r&M;c+XH@V$pXH zp07Wtk6^s)oApLG-+YIx6;!RQISOH;%-x}YrFWfmPu}23g`NJ~NWvYnOqyyNeXe+C z&=zRS)R;#GTY9Dgb?z|aYr<_ctM*!ZqqD)+(bXGjU-Ub?nPA5@XX&;1nNBb8-@p2M z*fjTIUK=Yl@wLp3GwGaiYUOSQ&*23oknrUayT-zL@_zUJ`w!fIf59|VEDo85`uppY z6=kLLVClgFH(YbNFSM%_o;%!v6xvzG$gEQNe%ikmPEZnPn z2=}I}5EMAi!DOIE4K=FK#}~_e@NZnFwBm|i+}Q5AT6y1lE?1zZY41`kd>+3Clp9dz z_7kGcEq_ldx1i4LW1`M2f49JfzgPWlylKB-hp}Be(}1?yMcblbMQghR=jLt(?OLr7 z1@VI7zJEpAW1=lyZo63RRZgn^f%{sk+9uHUYqSl^HjKxK+SFGHxkkBvdhUeJvd^OW zo_dP#S=1HOnSBqQZ8yACdv6i%4dA^NYy2wQv-%I}sNtjHcZ9zUuF?yJD_0-K-*-;& z_a1dzc}o2*`bd{yI;u|LOs>b#Rw%c<0q?q3zN_4Jg*vQ!TKzHZ%a_~Usdl0U@}JOF zEVsQ^?N@$bM6`@`u-x{vI*B@DUqV}Vx$U7M)it%FSqZ4v^9+u-i>=Ipz2;AEZPwE=a2%`!{WQYZnRBTPstYm4A1@R5X zS)hm=+Zci?>q|1~fDs1NZ$itP&~meA;ifxV!?=cFT91GuO^LrG(Yk_G z_Oc6C-nAds{kW?i-w)&aVSMM`FT?lC@ZEy%SK&K146nnLPJ$cgf~)deRfmmNw^yeU zS9`bq|Fl>4U;W-o>|U?k;cf2V)#+`n)qamQdA&_d-e!k(-PzdO+=%;}+I456*W1|S z^*FVwet(^#x!KX^YtCuU?f1Cc9*^7Qxg7tv@qf?JW?b>Dx%5o4+lBw!&B|*$NE!FI zou1NR{Wj%O&G-{;Xf7Qo-**Fg_c=(7q__if=bnqb-^IiQs;JN$d;o&p(!aZZ^ z$A@ka&-@GExm>`*I$W%6!)-RmF>5Y$^+t908TZoyKReW3!-vVYVCezus;psw9|aC2 zD`?h)03%_f2*GGXIFS{hVjsTZ*cJKfP1mdYZn-6UH zIB}roQq!gCx30J%wsR-@TZE7J5%92PQIWEG?@++UG<GL3bM?+Gius*k&U?qJw5J%#I#Wtz3>R*$JG zhQ9_+miZ~nI~CLfKf+%tK6M3U)RomM)n^U2pOKa{Tw}uV!0iwu&x*S1kQrLPkds2@ z>3!gLM$p4vb=dHJ@O_Vg^@i8so493Jt0v&r0sJBv0YP<$Nrrxu8A-d<8DoPl*4!NP zH5g}9cX~t}_Gbqo_0E{TsmUL6)<*`ievWUCI%2pV^XfSBdl+mXs*CFHDd_gOF*}-e zE4$TjdwW>jt+>;p>WDux6wCDXW@1AboK~`WNPWWaF5_mb#I<7(c%hS&Imq&}9(#Og;jNM5oV{XPKNUJtYA_hn$tkEWgK1!^df z2;qXW-PI?UKNHPnqs*ZJ%#W*+h8f6Axu1gFf1&39yz-WBIF$lum|B{zp8j$BJKdzm% ztbR#9Zdt$LoyzJb)FH!p##(5;YiXgv-|$uzz%XjccTrYWN!58msjPKnvnSD^4t1NI zPIt4qK^^S&#eH_I??((fjaQtZZ*Bcahx}RlZdh9MU=2OeZAM(TOC447X{~Q{^%k|$ za2&dpo_EG{R$34is58`nt0%R3(|>4ue25=UDCEIM?HtPHhK6$4p^mUW5Do|YbcbOs z-l0BbxWstv|GNLq;o;7Xk&zBpFz9jzgX&|2Y_3qqWebR;^acW6FIG4Eza4pA--TYt zIO=LI0|ZqBDNHcyc5EHRN9}LUl;(8KdO5M$iaz z?J3U2;V!%Oz{abN;iG>0p6r`j@F5I{J5eVf+n|4AC*lmeOog9}=`dOv4ErNs=yOO& zwfq(8#4VY_hcmaJuLJ5AAlH`8(3gPh?0t<1iPnSXUlHB8Gx`ej^-~oY7V4=rb`i|0 zM#XF1thm(VcgF7qK2pHpl^PCNIY&wXxkMPvqXG>U3AVuLRTpjDaReW=|HH{owBUn2 zLcr;@8cxr+<`~Y#HFu^Cue@sGfn)fnkG(m2PYXU0uX_R4`{B!wHSh>kBRZ)pUa^!Q z7O)wESsn zJb0SxwNi-VJh1GAG6Ppnf@@3uE&Kiw^oSm#1#6YmDD81{5oZdW*P<08x2QvzF83gI z2%MpyI=(42=}!6E6>qaYKzjNhWaC!MhwOvCTVaceN*oj)%+62Ys2|Vf6>ByX@~DWD z_r`sled@H@>~=cgRbBlWB;GfzHmNnpYxzf0V8}^mX@Y z(r{RenSJSFmWnMS@_;81On&%la}#slAHMiv@r)7Ad=Ph^{)}8I8ouz{VLbA+J1)L> zxctmhpfJW?z;hyCt}HLcL36zdT`JXoC+O_uaB;H5_04XS5a3_N>6g zU8`Qhj@7TiAodDLPi#sFPu1K2F(`dd)QUie=huzqXM7t5&i{Fj$?b|+I^L1JsA>gl-)dk*^Br@cWSWq9njOuS^CxR#5dqu(>;68q+J!xE$RNQxDEmpz*xTfe zCeFeX+hAk>&6xqa$5%f;8gw)_1suKK$mKk(QGZQmq1oNgkNOYF>L*uIhU?ImNA%UW zwy&zlZY7u-wKoTB8$^$p&8soPiPet-!}^{R6 zu%I2R>6d;i=xOh&&+z`$&w-xuX#0WI)`+%Gqiq6h-w|z#t5L%vt0&QxEw!P?X3KSN>}zHysIXia!CE=8$~r=2nW4#W zEBCMQLb{VhiCkpimiLdl3)$_e+itSf*y?@X80u}a1!|pkMV&Omor``;18M}m%xBOq z<+lmYa}6qG6#y|HcD1xKdgR|vocQ-6(XLA`zr0Ym{PIiHNO62@Y`oag=C4PYd-P>o zy-=Mtyc@M5W$YR2_^`HX9eO1%B!{O`#HcyO*VN(4*l`Dx!|H&uY73}iY2vHiaM+7t z51(Pd2Ygq*96pi#wfM?rHsLDXzaMtcdyJd|#=iBg(M_RGa-*QJ42-T=5g3|c1g6>) zqXsOPkro4dsRl{wz75wL(V_X001i;x@%qkJ9@Bpiw?>>o-Dh~v=&r(tu?inlw#kRr z;)BX}wF~hye6(+0c%7%E#p4czeu5A3lv>ouXPp1!hlM~Zq5N4t9|@tKaV{PMbljI) z|L&KYi-QwOZ(lbTS7cATN1p@zdfHq_S}4y&MbDv)AW!-s0(ktuT12=IX;M8O)rjaU zT(el_4K)rv_aamVJ>uwoNi=0Kp>5tjU2q7(`q;GtF(F8 zH@iKxS)Yq7`W*QG$@xr!{-eA$ir`|5sV!nIkb5cSpat)2`-Xf!GcR2D&hrxL*oMC` zzo!{j)^b2Tb0z4E(OK}rRg-8nir#JPNcoeYKvT4~7heMj@l{znh2QMzZ*(+fE%Ne4 zeG>I+g^se?x=I6f9dBGVbj|4p5}gfqX}HU(*Z2_)ictk6^|W<8t-tc2p`nNL?^U$) zZteX%L8sb(ChSDv)B3*vL|@axN;s(lQeM*c4h`K~p(35Xod;>g5?6h|gI-;M^CZ{_ zOkZl2Jog^6h?!&N3^SQ{M}RXZ4Bw!Dw_|*$e#G0$*M7maLB95Ss(hp7sd~xc)o&%{PrvHz< zH-V3;$o9wYty}kAvIhtdktHf1AcpQvClL2+jVJ;VK*hC5LWqPUlLZtV_iYsSWgPcy z+_!Puhf&;@abeVP7)1pnh!7E(7!lF_eb1@7eLEpR^yzzV{_o%U)T#Z{sZ*y;t+&!p zeqfatzt=Ix>{UAAl)dO2RK%LFC%(y|J6$QbmDP<@(3II*htvKBbuaoCBwhj3rH{`& zy7K7UW93D|XO9+-?soj~yG6`VvqHfC!xr4OxHN(06keIqOuA>9_k_~&Xs+FR{(+k2 zJx4T;VVbi+^TnFxZY8-Z&7_iO2Q(#tZYsp1d-m|-J-SEiS&qjsnAgTSYdGknSDU+| zSFwW7(hdVXBy1Ry%iH+oU@}=zlcPk-b_kd9^(wrFZ|K!&4?4u)l7r6*0>&17TbFc z>$lsk*=gDCINu5O%$&K`0Y?YIX_;vw9c3|Z=ArGcww_?RN_R$H|0_g#9J^AC9^Ida z9PI4lJHfr9j@s>@;{y4l{9R>H`|&vi-c7V{)0Acm_+RndKj|xax(!WDM{a5|eh89h zZ=DY;MEK~kI^L8zz{=QVj{yVr*d@a{fKM&{H2j?K20ppyJ8aj?%w31|)h8EJwmM&U z4Q2QC`?Eh|P>n=GBTbuV(NF!E9wxw)iS$*%iNo0AC)Oup*J?j^?5I&=VNJ3QIeqMc zYHVE%+k5X}boB7k>q^_0ZkNLuQCoI&sE4|?gwMJDzf@PMC)GExt~4v^+qtfV^%DbK z>N)~5q4tEzvizyGtwNg)=Ns?4>KmQA>b9lgNc|97DUALl0KJpbWdonC*nrjX^Qoap zeemz{QVuTZGh}3P_pEqiFPVX7>TtVq?5F`lvr-pz!xpdoU%(_iVfL=SBIZ$^2qGa& zB$SqPeGr!2l~CN~NR)^{am|s@nOA!#4Pxa%kBu5WuM^WmY##O|uf{#--u#UtjawLT zF<#LZ%JkJTtv2cXNP0_hINU@ceTkie_&q_AKFs4wusF->PMwS>zyq@T+M~vd8D;M) z`VK32+TLq~)+_t_PO)#_p(Fbx4;VgtKyts4L;GIcMZt*JiFi-%8tbp%AKmZ(tFZE= z_Ed**^z5cY+yP^g zvxg7QP9A%}@4KiL^tVM~oN*p_=|Z>c)x)?%Dv#uk=%ZOB>6rM~qy*37<*}oVJm$zz zM@x~DJEV`5>kb<^a+sTI^%;^Y#toi1bMXGtGY0P7H@)AGA^p<(?mm$AghZ?kI`|6k zh{mV*w=;>m;a$gHk02T-X{yTyc6x$>{fWOg+ zGmY_dM!kab$4}rAbtMUBS46vvyeNn-e1=#DZ|^03 zS554-c~)wlfxU+ewL&5-H7UjVZI^Bf8V?6gE>GY|w{1W=kCqrDpYb*TP5EIpMM@X+ zec*Y?y$7HP4(U5|&r`V(0(PI?d&m+I+$(#J0qIH92rPe8=D7)FcH0h#Wyaf~bD3y} zgfbuFhUi>oe`*LW(`$=<7=NfO=pEhxs17|wL+wCfMk2QT3K-4b-O86q(Nn~9aaFes zFg~ew-@zkNCLBmJ*X5mGHr%8UO7Xid@X z-bOF$IORrUs-TqGCV2#3gP27~Ra8gSon9@kHu7J)lC5?kCt?RWLR|4fJ z+AWN9d7pM$#$?H_mLR=MNMjq#c!pl#af~sxm)A9x+IQ*jUPjod*6t)D+wsauF+$Ft zb$FVUL@ic2!RK$xY2w^P6%e)>YIuHqK?#v=Z!aC< zrWBXWtZHnksjtgX$)}c+BM{hkZhdn_ecghbU~V9He8Il+qw}ijo9E=#*31s&=I0jV zg#!iMW7SmEH04Bdnj52)Rr8~b^K$Cv?1%?7bvey*t8!-4)euL@o52`lud5te-)Dqm5NL2&k>8 zsH$s1*)4UID2<3IpExOJN<&qhN<2v=7?b0%E0`P1&0%CZFQJJph}P6bXV+G##*5}e ziVn|-Ht&<8$!V%+tZ8U&%5AEt&8=^&9y=v6Nh8^gqRN^k)OU6ZF$Ap>t;>0@s61z4 z`9E@si^?aKkI6Y=;`D>3%$S~YMA5WqMU$sbEGy5MGA*ZM%H-0C((EXlkgcsF_n!ky9J3 zt8R%_SB=SOsA`;F(?r6b?q2pD&`+M?QKln1%ViTcj!@~Xy~IY>JZ|0t&(iuPoq5zpXN zSvSttR*<8g)hmVjF>%V3gx3 z5i^qUHzRx>3}0h$ahm>ek;224%Q@#GZWNce5L7iISB^0a_?uuFjRk;&EduOyOz&i1 zn2*q$oNQ22Z?qs)g;ABW3veg+k*6Ff>zK-^NK?-tM0XA9Qg74(FO^db47Etv2u|dJ z55$jsQRhf?gBr8}VVw(%IryBt4rP)2P^*^1r6fj`UWd@JD6J83R9DJFZj!JT zZhw+ol8xM-C6!ZA8nt!~S~nN)V2zb}!p=!*GvvPk6if$gif6uL5=Z9%&qC%K)mEjT z)`EnxEUJ1_U5LX}H;*&r=u4B}pThWwXFldhoiI>O?J8X)FJy8ODC=CVM@!&FXDbP(I`i6&p|IEKYXk`j(}@AT679zY&v3(K4+=iyi*WD|1fL{LQ6TvM0QhuB+5z3CmTn>J`}N(hPYh?s(fjz!qtfeP)c%0a;xOE z2K}W0oFMtE{k0nSPevH&)*L|6#hw-*ihfM;bAOi1bk<0ouFb&{ zo}|6I>e_PVKod$*eQFWYPwA8f^GCQ^v}r9uRsEE{A(`qfw3^EyDV(G6;?^}^;KI7* zF(~nFelES5WZ|~paIAy&#K1QSUoq^32H6{8FcykAhTkVUlhW3Ye zl|kqxKx`)(hd|^e;WdWI5X7nIfYU(AbO`fIi1LvT$ys>!{utv};{oF};}zpUW40-< z+Ndz4X`7Den!WH%X|kDOrkZK^pe@79GMDlyHzY)VbBiZII=0I~- z<8P?otL7l%b^J%|A?8ps$K1`_-Q2?*W)3$;n0uNd%~9rPb1%I5F~;26%r(cF0eoZ| z!soVOGaui@yf!$Jcu^%$ep9=8@)6<}CAQ^BD73 zy!Y|2d7OE?d4d@=XPXsfrCDXpF{{nFW{r8GInS)c_grhtI&)x%2Fi&Lka_4zwfG+v zHyL&2&E_rUt@w8EcJmJNkLI1`UFO|*NbX+qKJ$L#7V`n~LGvN=VF>XL=AUqx=n?bJ z=A-6grim9mp-9ZfjVAL6^GWk5^J()h<`TSb^o;qexzv2leBOM)d=alreQUmKzGA*= zzGl8|{>^;DeA9dj?=6vX~r3%zj3A*AhNM%Fi`9&28qF9h!`qz#BO4Dv4Cr) zrMOC5Ev^y27uSkE;8l<7#SP*{ag(@N+#+rjw~5=u9paDTPH~sGTihe=759nz#RK9& z@sM~J-;zEe{wy99kBP^{6XHqn6uu_?i&!H5DxML~ilyQ?@w|9JyeM80FN;^itKv2B zy7-%TL%b>85^sxT;_u=e@veAJ{6oAi{wbE@OY0BBhhl~JNPH|l!RO+u#A@-WSR-1+ zTJf1!CqBnZyVr{iqD_1uHi|FBCh?WnjJGh_#n+-ke1n&Dz7<==cVe6PUi=_%t=BRw zVOf^6Y|F7+tCy8zC0i+0s+DG?TNzfS)!XW0^|i9BepY{LfR%0SVhyx*wFX&(ts&M> zE63W++TGg28fFc*M&Ntxk=7_{w6&Kt#@ZWunq#ei6|_QDo)xz8tpaPDHQp+;_ObT0 z_Otf44zLci4zh}@Vyna|waToBHNiUAnrIzj9coRo4zng(Q>>}h;np;(+?sC9ux46E zSVvk%S+lI8tz)cXt>diYtrM)MHQTDNDy=GOj#X{VwQ8&rt$9|hHQ%bU>a7OrH&&z7 zWHnnY)&gsxb&_?mwa7ZfI@S8Eb((d$b%u4Ob(VFub&hqeb)I#;b%FIe>q6@yYq52) zb%}MUb(wX!b%k}Mb(M9sb&d6V>ssp%)^*nP)(zH;)=k#U)-Bep)@|19)*aR#tvju| zth=pytb48dtoyA8tOu=!tcR^XS&vwMwjQ+}vmUpeu%5J@vYxj7VlA=$YCU5;Yb~{& zv!1tJuwJxYvR<}cv0k-avtGCUX1!s(X}x8=Z7s9@ZoOl@YrSXv!+PKPr?uSrm-T`5 zp|!&L$okm C>svQ}H4T5GIUYpwN}wa)t7T5oNz+N>|Ejn@EAqzA{Vp zll|oYnJssb1LdxAkQ^+B$e}Vv?k0Dad&psOxEvw(lq2ORIa=-|$H={9t{f`^GKgEd zc`_{XWq}+g$IC*wkK9-8C-;{J$OGj;vPc%o5?LzCWJFGo2g`}_5P7JaBoC95Kz=A!$dBa5@)NmIu9B9h;4(085`QK_8@z(J;WYr=h(a1yW4x%!|dVq2zyU^q&>32iOPN2iZk-v0Y-9+GTdco?strPqYuQ549)RhuM?u zDfU$RaC@3vZcn#o*fZ@T>?7@?>{<5F_A&Oc_Hp*{_6c^>o^4mym3Eaq$F8>L+BNox z_B^}Ro^RLL^>%~(8@thNvYYJ|dx5>sKFL1WUSywQpKAZsKFvPeKEpoKKFdDaKF2=S zKF>bizQF#SeW87kz1Y6kzQn%NzRbSdzQVrJzRJGZzQ+E&eXacm`#Sr2`v&_)`zHHl z`xg6F`!@S_`wsh$_MP@!_TBb9_PzFf_Wkw)_Jj6A_QUp{>__ZB+mG6h*^k>#*iYI| z*-zVlv6t9?wV$z{wU^q@+0WZA*e}{I*)Q9#*st2J*{|Dwv){1awBNGdwwKv|x8Jef zwcoS%l^Rr&|YDGWPfabVz0DU*{khO?KO6*z1IHBUT1%9ueUeYZT1)T zM*B;9ll_&w+5WfPZhvie*x%S&>~HO@_ILI+`+NHbJLVXU=?KSiq+>e{UQ6obBss}W z3jT*lnv?EiIGIjwr;pRu$#VKR{ha|$wzG>f(Am`)B z?CFejMmeLMy__-5-cGJF)(JR4C*bZ3S$(>cO9(mBeR7awKLbLaZYsRIknDwr_QN&8l2xajZTx(?6f!woQ2Lw&dJUq z=M?8u=eN#j&gsq>&Y8|x&e_g6&biKc&iT#-&hMNHor|2s&c)6p&ZW*}&gIS(&Xvwp z&ehH}&hMRToj*9&IoCTkI5#>s88a2A>bJjVZJL{bdPMhQvD zubmE@^}LM#mELZ2INvy1oNt}2&Uel>=X>V|C*~Ti=?d3!rE9wm&TYTMY0;Cei{ja}<7(qdECesba_}zW4&w^97hYw)!T6(_oIBnvboX)h#Z8?3 z-2>bM-GkgBx7aOlOWiUz;!bc6b|<=rxQDuv+{4_-?i6>bd$>EzEqAB8Gu)Z(5$=)h zQSL1FX!jWRSob*hc=rT1>dtm6+)B5~o#R%!bKM&EM0cKB>&|!U+@IRoaZh!B>z?MG?w;YE>7M1D?VjVF>z?PH?_S{k&b`pR$X)DS>|Wwt z>R#qv?q10aet?Ox;l-o4iSgL|EOy?cXuqkEHkvwMqst9zS!yRp=G&MlfBt!S*T zbBbm+RxPMrm$7{Pt+a=mAQ+Bb=U##;N>-@z9Zc%-8 zeO=W&N{83MIbR@H#_0l~aGuH^C`c)(sA;TdnLnqt>ZIh7%KGML1r9};ozjXZh}Nle zsev*CH`Yg+oiY_$rmI%QRZA|5XV=te>Wek?#TrksroKc|U!tim(bSg|xMe=|!LlH8 z1GNaJOh}-1LZ{+z>=tq+Bv2g+q)^=h;ckTaQ4De5BQoyiF(!}$tZSXV5p2?>vPr>IJ$O_|$L zR~>C^nO_@i;j#n4(x9%QZln@jW~nZ-R9B-^V=dKKOPSU{Fs#$(hwLeH>l?M`lDy-Q;S?Fw+8q- zPBm6(p|*<^zsoc~%L?2XN~G)=KL5%z`DL0e{F@3^9A%o1k$`hVbz^ivm2-q*#1TFt zl8&gXslvfuO_OsJr%5@=k5p*JduTKf5zS~w)GWrAJgZYD3zijn{No&f;CSvCXnrOT z@*HxbnnTe%<4|XLEYpz)d}Q=f=bgBu%=6y>*rL| zg>-3!x^+XvaxQ7Q8YR&+s&14PVyYQcqH9!A?A9m>leC>%sZxeYQ%>w$5?Wt3W1g;O zUViGl>c*<7I-DO@)>JsPs*l$)@v;`xQn>Q8SjY40((^Pw^E4mBnvdZ;r;bsn?2$sJ zF3u0gqONCL5o)T!g(-E>hI$;a*Eh_qa_d#S)9SnFyjse=aoW@Wo{}up^;4ZYSf)BR zY^EC&XnOPW?0Ua5m+IP-YUwD|smgS%JYg*>b{Z3Emp{&FjMpw$maln}ud(H8Z21wV ziF2hib#0b>E(qF9XD!eL7UVh2am-MHTq`8gmbQw2i#ELO0+aK)BTzRDj`;~e4@qeFW93*~cr1ww^Nyh2I@kWMMxkP-#>nT@d3 zs1@?sT@8MLkZO0>nhvkQ@o&qh^W&{j@fN6N3l->c3%LQ1&Wrc_y8J>d zcS?W)p>diI<8*z-X*%$MIhQ|9(}90}r2LwWak|`by8h#I`QtRd$LVs%>2j5}4}`|+ za>na&#_Mv%>vG0xyyG?A@fz=Vjd#4R*LaOz4VS>H>s6@hQ|PsiE~ilA*K!e3qh26X zq~e2W!i)ACZ_PP=jtz5s4Z~Xao7vTDP0Wq=NXxcY;gS=vuCot~HZ(-B2AMy*GAa&h5tCcQku_Kn)X>aEOs%n| z&8@e~YpUl*t?AJgcZNb`O`Tg~mB37Gs!_!h6()1}&GmKlO{uy>_VhxD?0`6FS1P$Y zfk@Sbshqk1_GD;}mojdTWix6Q^BrdF>sx?&A zd0f?6uBsxsxJ1;oh?8nC>T`XqMpU+mE8C39w&=<>prREp@Y?l6g37HsY@V7O1@hE9 z0Cs*dQ>QAVDPm7A(83N(n><#K%d23jrbFe_#j__vd%Tp%Ob18xPQ<_=SzQuyAkiF* z1X#JjR-R$||BK6%oBQ zj_8?VL@%WxdNvUWYWzWsKcw-6G<{f8Gu@bRvK`X?kmuL=LtcJOUr5uJr}5=!e0u2_ z(X+0IUQ9>yoHC;4oRK_@PcO0~dafB!bCh62&FQfDpz((_{)qNRv|p`&kWSMZ*7Sxo ze!X;y==objFX;Q^J_Zv zY%Zdfw21fGRmZErFc?vTA#9CT4TkW0>2!Vc+A*T1O_35EU#R(_CM&^6p~h3F=~0sj zgljy7x*gSIAsA76Rl!J+#-o>nks^&pFAXC_x;(u^j1*}+MY>)AwUUY8Ef1C_HTeie z)Z_#5&4V#)o)p05K^rztK47a=L?oc5ff2pe7ST)42=>?*Z%~&L^vcnA)ubjE32J{( zmlM?G1a&zfoj>H|*YRo+6pVy){*cbE_p2g$RTl|qIzpOG?4B`Qc^Yq?hgXM>)9LiS zR79`UB6+&pJWZG0jEd+rSwyc4BYF)K(HlS!y)hKgYodr=3q|y1RYb4ZB5D!`{(JpJ z*Gun3M)Y=7M6cQ+dSfI~rs+|W=wL)mhJi=RgPH^)T;o%dYxs42)Z`j|U4J#XM!(X2 zy%iPFtFVaLl0v-ZH?2iTpXwc?h+aHJ#%cLelTXC!^3|joeqFwrRKu^!Q{R zTR{=E{K6Q^<-lgSfz5gZHtUZ-o@%#1-ng=)XkC4CRc%#GG%fDRt%x>I`yrmogPm{l zD4E2N;?umLHa>bHm6k5OR~^wiIuX626NzYTqt~7hwc!M=XsxE#_z}I08qph{5xtWT z(QE&R-UE;5wQNLh>_tj=PX|&^N)*!m4kV_`cb7$ccO)TANrJmH!HtP_98YP28w&zI zoZZZ=u+nOQu+nO%mss3@a@Le*rHrVCzXOxn^rzss+Pp#(=b{CBwlYore}6 z)J6!2=TWU3RGFy4A_ z>DE)@InwCXDvY-lTslorK+#qd@LCcsFHX0J8ovW!HBJY@YCMIl#AzVRa}G2*Iy6()EF`noGgfd{R0p5LRO)Y~6}#Y=mF8 zq8c0F*R7bR`IQ&v7hJl&dh;i&=A+1?+cQt|FE7qNxV${YN(R)N6nV6?sW~b9TH4i^ z8VIW~6}IM`8bjgN(yqo(__ef!wX~}_EW$NSde=UzH?G2J&WdB^@dhBUrT#_T-x>4R#lu$r+z%5^KNF)9#_Mar*K2f|quAe;xZ5RS!Fyix`5^KuLE z-1S3wYT$+K`4zrAHSmVUDU}La;VDxCZ>UTSys%jn!B+GH)zMZc7z#KoSQHf$DXZ9x zHly-QRd!8obK^W&l-pDxiwTqvC?!xvAVOdQfrAN5Byb3ULkUbGa2SEf1f~#}O5kt; z(+HFkm`-2@ftdu3AaEpsqX^6bNGekMoa9m)olO<#MF~5d6rr{{n<`R^ys0B{ChMCX zj6`i3HdXX0;_XhvQUl`R2PK3P8=e8*8S0$NNs=kj6kP(oW)$au)k|i+#Ms zKHg%+tM7*(n_c8(ri&sP58V~hChjCc5KnhZ$W<0^in4eiWu2Qs-9$m+)Uw2;&^J>UiPscq{{0k$ zYi9Y3E%q5(?2}aN@di8QK4YPqJq#s2V@sH^`szwN0p`IfEnQ%NGd?D1}K(08C6Au|E zA};R!F$1dPoim_;6Al`@x?*7wXOYk35@xb@*x;qbX#>bkxIv?{;sniO9=67Pp65|z zlGJS)c6pLUjfza9KU}(2qwyef0v?|lOuz__+FJLh>D4?6-KB8$#W>(OA)*geqyW zS9;Q9k5P(_aDKe}u+RRmPfD2cPl-$Ulz0nF=`7__JjAI}5~W;U=Rql%oo@8R2`t4( zuO+?2muaj8z0gv>hNV7#OMPlfeQHY;wH~+ZDTJmMU-t3w`JJfLFAxh(ufQ_DKwrT? z8R`T$L-o_>B=q$pM&c=!UVKRjL7AQIDIq{rx71VbIEeQ|7S3^g zfcOw#;oQ3zM;DD+wx z_W}r;Q`S5eRGL z_1POGqXR$KD3nw4u^)v`#F-Q9UVQim2ec-g|G{M+)xn;#@WdBRZ&nAVCsT07n;N@RaSS*h_K@-5u4;jk}5_+*pzx#9`1vE`K(ADFT1_eqbB#t8L^^aoOGbj2~0 zB_!}Eix4@f(fN4Br3qsfJZdqHK1@qiShQkApH~Z3MDu!;Y+9}&o>r@fSBq6R)LIn@ zc&Q2vQ*}}WPTr9wO}Q%T7n1%<`Athz6TK4ycZTQIap}Kl!OndXE{4=n8Au8*23ELJ z*7*MUV@~#C*z_Y6_`|2M@wXO&DXBf2D}4Q=V4}#moa@d zF5u0pYSxh%+UrH9k{<^RiYE4WQEL073CHrheZmgrC_?lu1BIzw2IXSDQU>NMrPI76 zr{*qYQT&A~J%Mm|GZIOMKLu@DQ;(*FI~mVP&5yFvqinWE861kT**;~n>$d>p(!J$qD;AnGEPU7aXLjA zI~8S|kSQZq0%hb)q>TI?W#rbBku$Bnv2qTc{$eyy2U-ZN?LcFag^`IYXiBos`N@KY zBnw+8WMLD9tcl9PMhf|`l|mLaQ^>-03R#ntg)J5GO;y(6%9^IEa%D|d)(mCMRMrv7 zI#O9jDGM7dgiHyhGh6v8l%)jMfgYeFbCgxBEOcNB#3X~P6O}bjSx^=f2*pDdIz3rX zWn?ud>o>}3R92I+pjRkKi?S9dYoW5B=_u}GWi4Whcj7`NYA-gVPar~iZ#JaP`2wM` zKuVRK!~;W0m7bNtok{}$u5c=x%z~)H^@}=OhbWpEcepq{#nWJnMC&kiYb^%1b23z1 z$z)m9(pb;L1q(xIjAA}idULe#WLaC&$fr!9Kv99yfY;@4e+p#4TPQ2*>#CJU?NNsU z>O=;%+QJK{OZM>dell!6p+RQ7#i(uuAzW=0hJyLYYLPexYLYq*UI1&XOhU(DM-!J8 zRA&T8tTrZt>RcXvwGkOqCj;=S(t`PcB%tCRG&hw;C*^KRAw8wtsodGLN0-Ab1w4FK zf(4zbg}w|O@M;%QCv(`K)bs@Nl4!h|Pw(|9OgJ@*Ha6BTY~kHlAP6O~p9V2bk+06c zaSvDF$X9ovLgP?2-gS#s>zw)O6ae>jbvm2|aD1i4qdA#h!gn};Pt~D7oyy`Kukw#m zr?H^|b>|10x2lc-b#4W}IE;#aaOBItB58)1jw5rka z)WtjaRio*heE7M0!d8v0ck&@KEM&0N@mZceGSAaT=6NB_SS&#_^&!natVH5G4Qc*i zN#ciTiu9p+UPz0LK19#chv<3w_%%--zvk)V);xW5nx~FCAl14?`j|9NACu;VwJ2ee zE?%}i0?jM%gm63wWQGz^c2ious+$*3{%YMO4_}m3Mb@ZaZN~9 zk`Tu-q2tg?<8-l`=t_w5D4{r}Bq6R)f%^2qO%$L@rDL|Z`uE$E){`r(>HyzcDw<8V-fI7KtNwW?va=6MjM#?z47OG9oY z%>k{F1A%eLO%0f}=hC2*S~uJGu<8ydS&WoLB6!`(#GAhKU&!zREbu#fL#AART;#+4E-)MIjCcRDtm~Cbo0xwIAfjeY| z;LgXZQUWhVl>(NT_%DR!1iTz&;;pF32x&B%;a+4e0=&??5Fxjkx553ixdiYTb1C5S z=JS9rntum;*L)9fxw#zhBeNCoGjly)o7o1q5icH@c;)Cj!^A5_c+7}iF#^P=;t1&@ z`T+LBt3@VWCfW^fF9AC70#OiY@&#&*w}uWhBwiXS0W1?`fD^<7z{A90fK$X2z-eL{ z;7lT01TC)5^#=~12|XA1*{WwfDHm~A>)mqCcuSaA>bL}4CFdn zoDFzB{$rTH8#PhG#49xwfOS@#A@MFv1KDbhhgHC zjtsz&_DH~K_B6mF?IQsjY;c3#w*b7sz5x*LRRG>@{}B*xRRH3x3cv^K2LKmFhqkzxa&jR9w3cwfb7Xe?kUj}^Je%mndWq&$gwwnzo@S)ZNdp@YOwDKE_w_ z7vp6&VeE#`p@_rx{ebwsA8=3n?>Q4+_KyPG%SEl+z1>{EApRewiEsJy0Q2#`QB8c$ zKMt_aMV;|YKmJE2upa<;kb4kdv0DaM?v?}M`+UF}7ytW{zRm}%b5Vb{(QO25cAEhg zxC;PJa!&$W|D}B5^jqmhN13be$1Mn;t{KD7z=K!APo(FgVYC`>&OtP`Yf@GFP zCQUa6R-D{eYmC81iSvwUwb5pJn3Dh59eO<3$#`342%uR$tvCno%h2oI5?E63;>=L( z6VM9%jhuvh^gkd6;C+SN4ZCPoS&k7XnKnJgIAC)5VL8U6@XcOg}DmmGML3M z7r>kYL;v%ho;wcUWygc?lH*jo)_4LWTO!WH)0J$?G0JvlX}ek5E0vuxTid5<`(h9Qz>|6{+6QftcG9p5hc6y}=ZKjH=FVMy!FkU(=&#<-e0}=sPom6J<1J8Qn6Ljw zo3rtXWfsgpGshf(nL-G!Odf!c5atMn;PuEu@K)q8coTB2S%)_t7nx_^HOIwBe+ANC zi@&MnO)yjOBICWtb%^;e(mjsX6`#jDif0nGlm(Kc)hp~DF?9oTY}~Sc5h-BW4MvSZ(#S??EVwOOq1qxSsZ>2hm2;p3x{lD_Z|!l zN@;w_;omb{&Ee_nzKY$$+5Hr|vl-sbAuln!kwbFX{UO5_@#dt77f-(i9Kj)HGiQdf z`v-#ND2AB~M{@Xg?4HZ+tqi~BkQ#==7!F~mI6t4<#xf4MhTUJ`B}&uWm0=1&<9l`o z*nKg(M=(5$VTfTa!{G#tO$=9XNFVV&u=NqI7-;TSixHcO7tS!cnp6MB%v`)%^s%u9 z?`&?utbH5an(YOd&EnoDxId22JyP|?cwaO&Atm=myvth3eew$Q#+$ew-pg1wp)XQT z9HIN7*AqveryYY(>XBQ_A9Vlgk9R_M$D5$>UKa0Tm3W(zdzU!NY(vkINI41p@Hm=V zLl100Uz2!ilY1DrYKS|)=Y9-_Gn~q>kl|2X2Qxg1VKu{jSOPC#$#K~I z6o=o!@NjW2@Epo8jYCQqj$wEwLxM0wsD|HI2PcW3-8+h!`e_hFbQ;RPJR za&BC~?jEGw+?!+fVCWK5@^6l2_ZJ*~JiGtRko$%1Q?GGsCa=R(y@KRMzXrrBuz)YE zd}%G*shAC-m1(xhM)lt1#G{v9f9V}g(Vxdr%os6iOv8+GB;IHa<2~ks@DB4Nytzz& z5scu32c6HH#W0IuZ-$u!jWrBEKIhun)(c5*vZo`w1FrIAkTqj$-$>3^y@+KZbR-@dd}8!0;x9 zBNz@NXne!&K@4|g%!M5O6o)**?(yvI%kJ+Ou3-2yho>@J!t|WY?lBDK5;VSI_i%=L zGt6O_#&92o0fNQ{><%+LjNw>@dooO7IGUi*#_r?Uy_Mnj9I^+&7e+kyGSY0PA9z1% z4}vcwzmS=bqCeI^{jsw2^#dfx+yEZ05a&Q!4-nVF-M}G#jP5f_1_WtYSxFW?lfepHYmp0{v?OPt)ANn&Wo_jXT+0#*qI1xYk3)R*wCK zLueghnyhJ_Kj--i6Uy4Xi)K^0Ef<>YNW8h~mG>{se?DV8iQR`YoWLQ98d~FEG+~&_ za5O{Kcz<2{e27cs)rNu9#(%J}umh2WKX8Y~R6}6b3+@*U^SSA~7P}N$b{}Ze#MQ^R?6~}^(pPCPHH%HR%%1)d8zlOzLUBs zb!(bTOHK=<%}hHr?Y6X6(>A7OrSFqIDgC(ghV--2uS&l&{r>dF)0d<_pZ;q4Tj|Tw zKTcnhzA=4E`VSd0BRL~8qkl$D#)ynD8KI2v8M8CyX4GXgXPlOCLB=&1H)K4R@o2`! z8QU`ZXNEJUWuB3FP3GO1&t$%lxw&^{@7&%~d!N|*+TM@!ezi~kK9zk=?9(Q*&vzBG8&)SsL(XUs(A^nE++o#{uezW?W z(eI{y5BGb#-y8it?%%8bkpAQQ7x!=O|9JoR@bL5gMt}1FV|VjFn1j%NlFfaMEOS4j z7h(d4DMm~&VghE7F~lrJco|FtJwnI@Myfmsy~UId#oB)a?rrpotu+S3HW=Blt;RsO z^I=|sc^T#vm{(z5gLxfhHPUni>-8%VjJ9K z(0UiBZUfbunBqaP4(J1kS-v!A=WKWQN5iIlf*?!?hUQ5xA6N`1228;3T6&WH4OG*%o>;zVdlZq z!pw)kzPVWsgPn8pH!#?%F`HnpH)FQIU@zTV2y+q)cGPk9AkDjB?t!@%25(^F#6g-b zz`O{9Jsa~an73h;!K{I4g;|UJfA9!ngB0MA0FMNCB)}s99trSBfJXv665x>lk1(s1 z0z4AnkpPbbcqG6h0UinPNPtHIJQCm$&L$-OQ-Z{QN|0hKOaKNlBp^eWJ4+EZB&4+! z(%K4XZH2V9LRwoPt*!Ek*e1Loo@UH9QXo}XFn-_afTXT62BAOh7Td-WIu_EK2R}|~ zjB}CpuQ1QRJPWfF<~f+>VP1ggxj%NGKX#x$cA!6YK$2IXKdwT5T!sF)3jJ{v`r|6} z$5rT$t02kkkmPnqayuls9g^G*Np6QEw?mTKA<6BK0RqYbUmhSq39YqX&?+Rz$pXpJ_sMjKkA4Xx3J z)@U;iMt|;33ok+Vn=q?jzJ%EX<7wuW*fO~Q=46<2V9tfPFxC#4Z->mcL+0Bd^X-uN zc6np04P5;Waz70JZZmkBlR)brs!L8Nc)@pETHMq4J7{4$~XE69M z8?CYwEzyCNXytx09Bl;+2F;!d&E5+w(}9**3J!OG!yVvo2RPgT4tIdVt>ADgINS;j zw}Qj1;BYHA+zJl2g2S!ga4R_63J$k|!>!&Q=4!45Ct>ADgINS;jw}Qj1;BYHA z+zJl2g2SypD(?r!wwY&vyO2}!9GG)q&VxB0<^q_zF>c=jb1%$&FpnbaF__0;o`880 zW(jb-39||Y^+bzpLyK)gi*;Zu?T{_8C(vR~pv9h$XBdOgFWTi$dhQJiVl)}`-*2#xrD-etS z3v6Y?wpy7mz0orTL8}j3h(lOB4tg(TyE6Uq+L3Y_ux!)$vyG(fQYRTBK~*NG%0#MR zC}o&oGrbx355t)-L~9?MB~fTP(h7w76zv?wolAx1@MAxKUq7HEP!;DuHqXEXLHPjm zf8wnCf!Mm8tkurZ@P8qdWSs_m=IJEJKWVvNBg7OfI42j7>^JNf+R8)=5_~AOChn$? z#1twn4O-F<^<5r@L_9vWuCn2!P6rjHycT0zvOEp{1Lky?GmLC`ChW6dpKWA9OJ}=D zu#;iv^whN0QZ5CVZXpN9Hp&9@JKtqde8M`B=#p|0Mv}uYhn_ZVg z2|fKVj1ZIIo)TLwr@}rQ{%Nrla(b-Ixer>v)fhUEY7?iJ277v}1F@S72eECyL9rc( z{Tg}O5W9)AsRxsMDO-SBU+KJdta?2Gq|6H+@W-2oqwzvw zmq3(I{uM|;yx9Pr`uP)MJB$?MU5nT@VBY|mH-Ngwk$Vd5xbkeCJg7}&=eS>kxu7b5OzBU4<1@Ec*@1p6-7 zcfX^CiqCm=2Wj4Gczfi4k35M7Mjx^nvLMlLgZcra#O8m~5C`U`EHT zvWs9B!<4|3!j!>8U?#vE3^Nht5ST+@pbPB7U?#&%fkAJx4~LlsQw}p7W(Lemm?L10 zggFXk7R>C}8oL6f5~d1f4oo%7T$mb|t77YIoCVm|z+mUzzBaZVvz_-0X}=#^VSfy> z4(4l`b8Htv8hSY-7UM1AwjlL3q~3OK2(b;i zf18{VdlfmiVT9O-+-(>kHUmQkH0D>pvKkul3*`O`8uBaBkkH}Ys5Kq>*wgk(OMYc! z$Vo7V8AIe`m?^+F753psskC>8tiV`ZiSeS!$dYqlS0k&ihECG4&3{|gIJ^3;J_yEpba$?_hPpZ zym|NmjNF*j7%}V{!-gEh+GDE$S7U@q_#vkkzp1Zct)AF2-Jnv&qf2V#ZokrdFp$XPQKdzoh!>CjW&8-n-osq*S^T|++;FLs z-NIhr5{;H>)udN4-KOjmNM-i$>xJ?YW;s2iiU(u&0jpN!_19AIXal<;KkL^s4dBRT zl!zXP6;-dFfS+=7`(vJO2KBlg-6l#1oj>4qrW$0^x<8??9Xorj^9PXC z%{xEeX5M7$c|Oiqy7DRpd_U(08g_ErjXnKy@c(D$`9E3b|Diemf3~D_p*}%F@O&@9 z-z8;&*W3M5L7jaR=7*@g3WAuMt-}nZgVssp;=Gx$hjHf=kj7$#ZF`8bj4nTwn@7=Z z<~nKys>VX>W@8VsOZK1b?Rk9txhSzKi@Ctg|9Ywm)zkYiUw*kd|0Mc68g^v&ROcPc zuXcoPr{mO$!k34i#(A$8FIRUhK{DJmT(9|m`1=V&LZgT6(~xY&+@`3FzboPSQ6W$kPt^X{Si-@!Owh?#hLDJvcSm zWee$Yv_DZo6lzKAnyw{X!S~-|@Ev$I?u>Wyi_zCt`j_BR+=G<)JVSo^qWl2k5S<)f&rscz zPs`S5BPmATaPHI(TH-F`OV|aX-8lSkXLv`u3qP3$-BROW@oEUoenaQhi#_Po4t!Xl z#wyf!9nbq)(F16wc>`+U%}CN{A1HPbQqW#9^)}{h?4KS17=hY-E_?$nd@=SU`sRB*<@{yB75`9sEdf6VYtQ>@J!8YYjbGr`xut&^LTYz# zc@wp3_q%Md?>vltyQ&b<;_Ql#qwvw&P4S=4Pj;b4A!U#5mOH$75TkkpDd%d_S>cVm!|Goa(=)9eOT*2Qk<=#~;m# z`*fQsQD!Lt&Xe(`+Ar|yZY8&4w8TY^lipcj*S_XqfX?n_HsHnXgiZCNa}&jzZsfQd z9F*!uWTl&2I~C;bfT`rMl{=N~*GVK}9|JM*M*StOro0ln@`3za!n)SU%erG5r!YLq zVP1}JYt`u2DFZI{4qy|I6QC;0Lb^NDuccwCOsvwg0sz7u=X z&#K4sb)cagG}HWs<~FUA0{Pbf>RGI^k?Nm14>bOd@n+{|gOFukJz<{g!V)K@^8)ZOUcyl==5Fveun=3c;~bh=F%6$ z9>Ki%A>2f|Ep{A_IR@Rx#F}`MI>nD&=g~nnwK~ttJ7S;2-lZEM@W0FOw%Em}$91tw z*!LO2w_=ay?e15wlxF)M?U*1R^{KX>l5cxVUWl)6ypW$^JBlwqHD|)On2A?SvhZd{ zw?CaOtJ}z(4%GT1$DqGo^7mh)YbQyeQ}%9tJ`a1=anQss;~RP-_9l;0-RPx6{ps(R zsQnLGGw}Wh&tk9(MPnVt4OOx(UyrAWcoeZdeccf6tx!qpllexCf7Ca5q}k}{{H}Sq zmu>7Cid>*8@z=%Q?cARF6n0yA+@(InYcqN`*#*b9%fU75)DoZtwFi&9ky~>Ar<*|Q zyQc-?VmED&nAUS+lB?Cd%~9&wF5%&np55i5R`+yL5S#u{UnNC%8<`*H8pYG{sbNC@Jy@I90j=7!0hlG z)aMmZvHkDI;=LRweVZXwyCP32hZC1*UYt%o9~1Rx1a#sddJ6fmUr1^3qZT$Gsd$?N zf3(}m`%E-DqnI82FgB@istvQ&jlaq%OQ#;VBU-wPLv8p5rXQy{;>n61k>J|lZt!+` zA|YcZCpe=d9$W-(Hshp6aXb~Rq}RQ%uRCQiFgAAnQE8o854ilDFm5@7eA_wGkNdp- z`{OBlN+PQ3*C$zNe7c5Un>#=j=^DQ2vcZbkfrHjB6u zJBLq#mc*XIHy3YE?%31b>Lm7vqE6#{G@;#miKPD_@FPFwENNWtm#q1vxJK{9<{PD6 zWH)wyyzSH7Z>MKoy4}JkDcl{R9}gpq*^Pt*el+Kg(3l|4zGQcv#RM=jj#C|%+fD`V zNXM#PrL{MY=bf_ts-Et2W?~rnn=|Z$-Ob3=AB#l zmIw7Mx-9@3S}Q)@LD!*0=`ICyAl>}<27lPoVeWc8AZ&~W7QB3h@C~sqV_)dgtIuPf ztMX$XB8K$0o(*=A+qH~~cfz(Ct&u(PG#uq?3_a9~g0l^bL)1r^@_2e)cd3?&pXuxX z3rC^e7#9*#v38*SxA?hcck}=5!a8B;gflUwM>o$?c#kv-t(1;GNJ_#e;*HmM!LJhz zny>m{Is89rUZpfdBlxK}g1tqRtEZiJq+N>4Ht2u@#_^H1UFUO(&kcpM4J@}w$06ICIMC1GyY1HJ@Iot-SP>pO>a?}OC)HOE;x zS|CJ3 z4z$`bKeJDHLYUU#@sMGVch-K4mvA%BArpGPxQ88+1e!ctsOjBQU*#v8?+Vbj7k;0L zbJNR(RNaJmvBVqJ#9it362xuH<#Zaw9q{!A^eVjc$VoDxN%JtF2n3^DdB?Vc!zNsu~*<*4x>jIj{;7`Si0*?Dlc-y zN3X=b$$azVUfZ05Zd~XeYwexc0q`<+c8dk+S8td zl5Vd&*kbNM)HhF^b=nU`A>Y*8iguB)ue~-+Nc%tQ#Je)!!)l&k&?(g$;KNGj*8heZ znqI|~PN3cr4_T_D5>#mok9OF`I*Sryu+!;Szwm8Q?P9qHy`Adc*|*cke>7o&7S=ODw2$gpe1oqu0<;)XF`b}} zZGB$~Elz)0M|95hQ+$wIx|QY22($%Cg5K;-&mgp;(+mh>HQJfK8c}Tvx!+7Jk9y+2 zJ-|&GoOHO-_CJ9%+7$qHZWYv&@-v@&6vU68^JBcAe8)eg9CvduM^HPE^pcO#$nE~j z0u*k6`2gv7cA?vnZuceVTcyJjH5cTYbmdAIHNOaVtzBp8kczlLZwdYEAGpXgC5~!8 z8(Bg|v@^~974D@85pn0Q)tkHmsBCcDm*VGD4AxaEy)-&x4S(N`nYH%6tmY10s_uBh z*!4_8=X$|QzrBsIkZ!)~aeVvuoe4pHCHIgmk`S()3ZdSlCClfkmwv~%{r<#Q86Plf zTjlj|?-$z>9Wf&Ws%OqmN+=DsS z!K*kA!FG0M4sf2ItgW^~`jZ17G0Q=%_XS=&e|**(59!$v@8RA|nbtPE_U@#6ezctu zOGudUkp{vmft_N#@hG80n)B_f8>1!d=6~)Ky9RGh$XOu&sYASBe8U8PKSx7rw<9-aZ=GT!!cTXe z4J3XD)ZuX#nUAK#hZJ}N80QpjhFu$=DZ<_g9HnU{a3v5zH^EyZ@8awu+e!M{W zzlqZ4v`$s$Q#DS+qYXW`@ zzr^q=30yB(C31si|NHojztz$Swx6u~=`zcC6n~Le9fgERUtM^7i;hD>L zIf~w;*N$SXDNzYW=l-I;3)KpW+7P%Q){5hR-5caUIP-IGPac!9c7R_W3*-Ua>;g4l zG_^=;3)F|OSkH!}pC($wjfGN6O3jkzr>W>HFP+MR6xvsTs!py(i-MYoCzXoMajh8j zgC-AS2c|uegET7M1;_-(k9s_bPn(ANJ=AT^{(h!^7T<($Y(&L%5?C#CKipt@qMD0WgZM}V5~+#Ytw8!3j3C~n~`BE9&5 zrw=?|ILg5P9q9Rhj}N^hBN)^vikCgRGykjsV))sWI8Cl9y!J=x@=Bhj>VMCrz?&&n zdx^IoG9P{K=e5Ohp2Lav-imZrzc%BSzvoaJHBB@@^*>>W>K? z-seB@&)*7^_AuexC`)p~+BqC*EhFX2(pUwW!Z!=>|IsfkMJwU#Erdn$w{}v4*@85g z!*v)XLiW`V8y*z69_jKN&x4{q!>HeO#_?4I*_BP?JD#tRf8@L9$&m|3w9M^7uG8=q zxqfzsv;uX3n*Q7YUL((gaj-vLPoV5yNo#1)5lCXT4eeXY))gE3l@vdwo&vv5{X}?+ z!8rt8F5J)S(GU+f-s&Fk%ftBZVJ_KEfg``TbCDemI+6MS_xNFmCkSg;HsZ=&KZb7w z4(<2$Xatm+pU2g890Bg^^85hP;19r%fB1yqC0nx$O*+e{U6far5_vXoA zi3cQdQ42yUjP-Q(kd$E5>p7HX4+fKqMNW6ESjJK(Uayo&E|K7Aashr4dNFk5N79R= zV`#3D@zC}HH)OA|J;6Mbn!&Tuks7cP58%JP#HC2w-Qxu%E|hs1`lfc{O9uYgXT-|D zjApTfT6(2}{dBrF<=1Khnnzju!%tJtg3j##jvp=J_NOWf&MLFpG1?X~KgaTN7wI>& z8&80Cjv=SFM@$HRD&p|OTA6F)pV5f1`p=-ve1#PJaWoJBz3!*7o>b}1FNifTeBJ16 z=*20>DKl*33jqHWyDCZB|2>Ca4sJ&6;m|Z?x2EHOGWz)?`c&ov$jpfU;rRf6-Lncm z=FUz29iX5?M^e|78UIB`SO_nW-JkZrCsYMFD}l=&kr;ZVip0pQnF{`i>)@a3q@od{L^9{3lyq#`}WHMy|FtDrx zxz~E>=n0PXh=xMEm9_a#hDhYHiX-jhvw`{B$S*h`TAGZ3Nqu|pJA}Wi>t!FGqLQ;r zMy=kC^5?YvN+|FzJp7XM6gB?kI84uj{|Wf~e(VYG1&`)V(VBl(atUwKx!(qOCwt?0 z-pjyRF{uXMYeQ<_8H4jJ!5)x_WWrjMq~V|qG3O*_2>>#bZzlB7wC7X=}bpxUiRodtfoGMw!H0? zgmjacgZ=|Dw4~h^xOB=87$?%B4C*Ler05ygqrrPJSAg$%GQfkyi=XDKsQr?uG}Ra1 zNz;?Tr>X8NE|DUB3E&L4%^9CQSSfs{MLiKrJ*P2EaaSVYMsOWy%{C5&xlfr%`&;ifx-eu(iPSL-In*6we@xKzDud>Sh*|d|Z zLTdHV5EST74g+T?y^Ga5&O%!Qf69}vQkURN5PgL?>Tbv?UL8a zs-vtlw#~15!@Ip3GtFK?&CBucF8P5y695C)tdM7eU^Hf)-3CwiR!FlO5fe>GOc*655;C}1ky`~ z@CV6QF7=C3X)40&Lg){8McxuyvNrmpynVe;;%pB*Q%LUOc+2-F{-&Vpr!6k+36zOs zTh8)kUOgxGpuBv!j|bkNAMg2$XOs$o+-G^qQrXHbALw87M(|ln6+LZ&tehhi9|7e@ zk*@}x1v{+CGs_WztMVRq1X~m4t=2}rVD%jS;@>;yl{p=RPE#hIk$TAkc%AQYkH^{A z3XX4w)Ej7NNK)x2S|l@p#U4Gy4$EGdq827^y1 zUem4YWCh-n@+Q*L?vBUl@}T2|>(rvaA&Ejh)=N0~Lt9@fR)MX5Uof0TdiQdhi$ z_!7F0)K&#lAuOsVkTKA=f%88fQajp%Ckb-2)7L3&q8+YjY2it0X|S$P?tN))&|NIg}4)Sl%l>RWsxe2a{bT7iux=d zC(r%1XuzvA)`ni+VH9L4b!eJkUVm4sKp`ye}ONFHdp=q0S!^l)6#&U_R-gXAr) zFYygy+>^CHg_l)QR2=i+z4Jwo18 zX#6Z{;F~U;j~pa0*TS1o5Xj^LKg;aHzDitfO|wECZg6$R`6Y>yz7 z2IVkYw?oPkYfIdtbiF4xiDto-Y%-2~T8~cY(tj)k+Qf5GlHLWr1+m)D67n3pnNw)z zf9!6!5ARmIG};jI{)=Dp&Whf6SyxY$1`0a}f6Qh)#U{xkZ#{q`Vmp^jf9Q9~Egn_B zCLp2L0=$*2WtR$V1A1?*ckVC6^4{IipR&f>`!dQd$yE~fLTfs6oH*vktfDc2Gnf0T za|Gs3{nhpUZ>aAaIqTU!lE+OWQQ#EZxXh}=wjy6G^Xh*z5mYA}J7j)!iRP4;o$amR zL2N2`ipkBhrk_}pl<~k*@Kvv6fgLWTT}UyRdIs)P;u%6t;UPZ=pW9y0Jmi3U zqn$po`}~|GWY5l!LjI^cS3v72ef4Zoz^(Qd&&Q|XexH(lDv4RVjCba7(7+Yxr2y7L ztJ{mQ#LY-q3ms=My~5ZB6z8u5^UF@4()W*pH@<=1*n)lR*Ml$1UZ66!d@uYt=%KSc zWcB#TJzj43*!Q597b3;;hYE&Z7t!E#*;ndmf8OnQW_adLbp-gfTxVaQu2UYE6Ikq; zNDR?T(t@egyjVbX1k+C&3G^#6dGz15?Cf5xxK_Lse}MJ_8Wo;6iT5HD4FtZWczLSe zy?FW0g0rtJn6q{;cFs2ky+b3Dw+CpAu*JX&9FeLs!&1P{3j*&^xV?ACyvxv|_!+L?4ot%ndUJIB)^TW||KH-^6zk-f zsG$=t@ve@8hk&~vRc5eJbCt7GAHjEX>MZ^%-rb641J{B^ce>;3>kq93ZxPx!IM-3X zPG0OuPUYi)^|CIs7BBAQMvYrbUn`k{-g~ZOTG4rtja?Kgx_YiL>6tUpPw_Sfa(jGH zApgZ=a)7$erZun%=zj{lLtsyk%X{xF^zGs5FKqK4_gRTOCF8)y0gqwMCvgYw`Pi9T zOBp0GD&n3pT9fW2IeG^o-4=dfbAqJU`-Mnc7%i6XgoIwuE z>cIUr;3p&7`!HYi71jcM4!tArG_u*>wxDK9yY8?j{cwNTS8_4x$4XJuvmG(4Q9`PW zib(s4-tm{v%8=*uhnItOeR%quC9ekY3S7D9n*Xhz1@;$}kzNTs`}fAZ))r}u#Cq%r zC*NcCM*7j7kS8kHn!lp0MRzY*`=2>S`(+$iW@X4M*6Qi8P{_w%5GOgTY##`+}JnU0`*6k0ss)n@aN3+o$5YF*Oj-3)}I@md#8#}*C9o;Q(1A-3$=&IpRvl>P!ziq5V=bk zJGlV!t;I4CdAkSSN%Vgy@xSXWpoKCsOmrA|R<3InI+j$fM1J0DFU}8obN~HcquP(_ z;C*;L@*-TLhJl`Ay1!KLj5;fK{rC7r*}XumNHiIl{VZM);cB8k?xB?<*3CiWk@M4h zd7xfU1j=V)@ zjEUyxmBfs}z;!QID8x0-$Lb%2A})I=@?8-gUJleJ^XdfCFgp*S{5`l$VxhJExwvQP zfD3H*p24$7V41ALIsV=u^g}A)zU#n!?Ci($4S^gI`qKmb!(2=kyU;5s&vS~_qYYwr z;3}R_sLbn`kXZ`+R)^4>csTw2Rdj#k=WHO}@gQ2rf6?{-O|jBX_utrh^!H}yXu^>n z#UJ*aKejWVli}QtAsz)mOA5Xtz9-pN)2ksQ9VsDa{wIf}h{J>aq~d{xSH#MF-W5N+ zAMw_YOB%6@T!3f$0dw(F{yAKd$b(NJPa`|%$yaS^17cr2uVsR1nCm6_u3Qz*&{53( zUJDG~inF=?N@R|Cpnp~eJi#Yd!)v*Xy%HJ7Ct=`?2WF7_uSJqBf$PQ7i=TzobEbG` z|9E*pk()zH`FkyBlNVhpveQG-HbI}*f!=tbC@l~}kI2=ZpmppxIYs)%{|1hsFVXkp zDo;votWL1JQnF3~y>?%qjzAdfAHUrcOvkxg3)oZsT1w;!KmkVM?qQ0U7?{;0_ zO!9d70x4$>p}Pr%1nVeX!b=A(EkqvS!Fz(&4drta-DEe#t?kxvQ{8m8zMJ7@y4h|+ zx3SyQZRWOcTf1%D_HLfr!OeI3x+C3D?l|`ncY-^~EpR8hQ`~9p;9c_yi3c++cPj%*!OSEWKXO;`0)ee6n+f$v~u zfkv|Nm9>VLd)e41Z$udljC`Y$F~yi_OfzN~cN_N@FBmTxFBz{GuNv!(H;j$Oo5m*N zE#qzD9b>ccuCc{<&v@VXz}RVgW_)h!F}^UqG`=$S8ebdV82gQHjRVFZ<45Bs;^w-|-Ii_}x1BrM9q&$bFLkH7m$}p3neG+t zmF`vUJa>V6wR;U}7^^hC(qt(c7Oe|jRSy1$2#f=ihYni-vwtgMMp$KVf~uIo8iP4u z)iJL$PIXh=)p)#z$JFEM3H6NnMD12TtE0wN<5T0Hc6B9lvAN7FG*_4_%^S_z%)88c z%zMoT&49!}`eDX?<+%vJP86+7;|HyN`W=J=vaT&$n0EYwcI<*X;H7279CZ9-hf? zI}=I|X}6zyKEm>NMtO<^!3*3K^`iV!_FD9#R<_&G?WC03)$M~47q}Oz2zRJELRE6d zxMT3-8u+Bq7YcpR7`^fYehu-=yMb9hqh&z^!R27r1qgY6kpzK{W?{ zty3+G4aO$b8o0Gt*;#B8i5|(sz#z0cd2RU zu|DcbJo98V2fa35T_yOX<^sd+SMvqK)YXDx>Kb6#V`>R7?FqG1uuUyP53f~)=;PPa z3O4~gb}jpN2w@jM7kyFdW*D{epf`zocK*ujp6xI{lg%Zbq1qW_dHptYi)a z)-ETu-fuo(zHGi`t~Xydx0oN8d(1D)ede#A)RR_}6=%g;308`gMoMj9Wmw&;?$&u$ z538ru%j#|QvHDv5tYOx0YlJn@8fA^P##m#man^Wik+s-PKhHv2>SbNdJTu>GU`Py48S%sy`a>XdWBod_q=Depu%6`W|NqEpGK z={(>(=&W%bmYxO{9W*a7=a^TSbIp0?d~<=h(7YN~467xeZQf+wZ2n*#wol-!2Kvn3 zTe<+$xSh|@2W`BmugOoQ{AcI)Wo|=!ao62kOZDvQ`I$MRk9Ip zG&iaU<{J%-E=CWdk-ADfV5cumR;}LMz&BmkTu8-jj?l7JN zhyB7>OYZudu@7(b1-#Smz?;7Zk9`GP_D5qKxa<+*HFDVX8i%n#+q#kQhHk2x8b1Sj zHW^2)x9xc2ce|dQse9W#`&QlGzTLi4uXAs5Z_*nC-*g*239hlp=5XaRN17vzTIM8k zl2IG<@S;)2`PMmLv`4;J@URt1nb(^)D%bp*`F9mzK4U(w(#)644JyNY)7+$*nD3bH zs9a#kd#aha&HO;MFh4YRs8;63=6==2{LVb2dYV645vs2hZBmSbF2ndmYQodv|6Zz_Dl9xpti5=U(_@5?$svyH^)_PqfHUkW!5Y>r)FET zm1E7Z3YBYJXI-yifKz`{)qz*Hsv5wp+f|(Pp!KMV2ZlYaQh;Sos#Dx93f z0JdDB$^m2M06VTSuTmPAGgpNJd*-PyV9`^ zz!zl;jwk~-;sCn3vI++WZKO=yTDJyWd~AKJ%Gt~98&o;>M)xMPSp&DVvh;90TxmT) zPe9%&dJ0l5)0gqO1uD8(8K9&elxZF|v4ews0yL%Zs{^_IrHV4YGQUEOeJ0ugDgO<6 z?nm=S^x_fo2;#q(zW^RHkD+(}W&R62ecU{bl;6zXl$LJAJGCuaga43gRW2mSL3WWWfPxVD;@ac2t6Yu!-CubRy9&lR%5F%(sQk5 zfX#ttVfGe#i;A>Aus=`{_6~ao;-A^r$I0Gr?+5(e{$7>0f3|-{{8wOM1fH-uxW>;a z2AU35p+MXD1u4fMpDbOV3qT)R&8@(q?dEp$Zau4>stP@(zN!X(*hf_YcNwcHg2P;a z7F=mvsUpE?R^mDDu^e zl^E3udQGfq1Kp;&8Up>MhH3{LCr%B8^ooa`BUn9wSbYhxx+y52wwel^vktyNCKx_} z7(M~|rcYf?3~xycZw)P>p}LrO-WHleV>MGXf%Y_5^~A3UF@K^Oh+h-p|3ozdzg%@S ze$z+`6V=P=b+q{n(0_CFj`{*^{!)F7*6vf^qn(G;PiW^q@oPd&4h*slCK@&(p zO^p^tM>W;xY;=Y`BGfd&xZZeBT~2ChO=@Zj&ikC232yrm^1N)kjQp<{uON?5*#uJA z1n9%>;;PWv1kzetaPAL~2f8uf7seO3D%3Z@_`x`gIJh;^p%1H>q{K@|iIFXx zsF7y2*#fYo*$FBA%pr&mGlv5%HW#bz&@Ps%D$t8psNRq)*Q>gaEa2SGk#AFD%{$CH z0Pi&KR5{Q>?otWnYIC)!X5MYy4LNeJd9SKyK43n8s}GqEq3k2(BdV79xcN9zo;06C z*{95>)OnCo&!|hyXU%6(^K<5NxcajBGHQF(d{y;={=E)4Uo&5W{M!Io)*G_yP1Gi` zEXRBgvTQ75**4tq14y)r<_<`--jHY?qy3+mpW`aDA=D<^ZZx@Fl)2aZTGb%Wt3;kR z2G-4fl?n;?ovJN%4z3Cpj4^*Q|B1Np!ZGI0=Ff-=M;t?r7*CGakQ{Lgw5?xN4`^H` zkVm*<1@m|FB;=d$$avUG8gbJy!DVnDE?hI2Tyu<7&MJo#;hkfwNUOY>Y*nx-sBCi3 z7^|XH5mzfiBG-UKt_CPPwV@Sj#Ud`8HIbZk3^{8Sw7qzwCqQ2Krt(kx# z+ruH-uTtf$xz=3B{CUub&Yk6N{3dt81W_662zB6 zFPKifV7j%&T7%jiwjKdoXRT9Hp(VWr?)$9n$7Q>qAJA9o7zT?T@UFAf0wvuvaKO!(fr^Qkm8#)?w6n)H<%TUD2)%SkJDf zGVFHtAjF5;8X`)SpM7D*@jIr}-ppSPb!o|o*GR6S_Yuc|m`((6=Z z+ADFe3)ibOXx6W*I$|N>>YMhPD%Rd)zlHeQ_S>p~{f@mE@ptWa5f`ag(|!+@WJi0e zy;aqRPX4~igI>N3c|=-9+uQ9A5f_`zpRz1#j2agnGs zq0fJg_#S%?>i@$2LbbQQgpL;n9q((EZ|}4Bp*`Q&-ylU~Z%zAK`vBtK+25fJ2knE1 zi!@HM57~!M!w>ckssrqU!$|+h{s~X_Py3&^`w{yHQbc0cgxzoy@n4`rHh>O!9PJkw z9t~aPH>Ce=|Bg~8?USmWV>pJ2b4aPCa2#lx9iaz*tNKG{41+CP&J9}~D6L+_Uw$TjLXsBbu#F$I5B$P$=Bo0P#FgPyC9DaY!hcf`s)~T~TXIc!Cn}vmv*W z&;rp%BPh8m!fugYUHsyZD;3wpXH*L^ygtrEPi+QUKLcSVexk8vL4u21Zx$lg+fc5z zr(DmcT<=V|uHhHyfv4=LdZ9l=uXR;_NcVI#NL_+-(QzxQ%hYr{iAee?&<7UcNkrb) zP>a-Jw0#MFDQYQxiE0_f>{HbB>UQK`1#e3_{4I~8o+s2=Ji#;grK@MvOK7QR3E64` ze$mtw8beq31iHd*Xbid37}`-|=tPa7D>a66bp*d0@!X)EU+{~C9|Pa5H7XjFR4R0c z80g%wMyyJJm6w5Z(a0+rO^oKM7JVJfVDWWVamIPZc`6CEUk~Jj^@sTR#!%!LW=ugn zQ;n%8JI$D>YQyU`3n^C^^Hc+4zOh(k8B2^MDvJ7jL+B-ULvOeT+DQ{?CvB*mTl_?`jV44$d2$Rid)KDCx+ z#&+XF)U(6bfvcjyG!y?GQob_2LVT~W7iITBn@NQ&`VCTGjiSxp8{Z>-$T)E~iPu`J9-l54m5~=T-*;l@0+En;@Gs*@`q-lhkO?N=P6bCX)_plMb7Z0$b5m$fd2&fz+4) zYJ3&7iN%mjI?RSQ{Y|8Z-H=PWA)6Ffn-rKp+G|DcXGi#>K1EKU!vxUb9>l)@HRg)H z9dWTLvO$3d5Erj#D^g%h+8Mc|LxXgfK>M@}?b8ON$tI-98l=e@q{)_~#%$UjHOx`w zD3wqBtCBU{ngRP%w6IFnEcjWP2mLHpff7U)OQkO6TB3`kQWtZni&dg7){webQ|e+3 zsf#tGE|x=GEQi)^W$PB}7S+tU&AJV6m9+{`?B5o&f77kIt-E2{KWIIOyNmATSPxkb zAubx6V?Aa)hWt-hPXIn;Jq7rj^&IH`dFy#qpZZ+~@|SY(tglyjB2|i$Vc+XN8-pw^2kRb$VVc{N6M3rM3IkFARnnkJ`znnQipt`oF#mu zo%J*LNFMn}9Qep@hzlRdBOi$)AIT#h2?rl(gmmE@dDIr;$SLy3DI&-tBB?EwCwHho z?hsAxP{+Q_z73^TfiL7aRh_D;3jG7(t*ox9(mzm*{(;6$qLZi^Imu44YE6wMl^Tsp zjV6^EO%3pq$+SkbZmZkEchpX|Q zU!X6*eFy3bQNv(8Sk)3ww#v~%H2f5Lm>vfIl-Rk^dW0UK%5elB5}xi+stLydD(EqK zjLO33(^yqmkJIB+6ePcAxOg6!FX@e)5oz1?uDmHjBJo`gocMmg%AwJw3uF}Qx z3(FLqUswuacNiFLTMgUfZu@Rk(Z0vNM}=c-)+8?0ApTV$=A{$! zYJ^~0II%5G3%11&+v*V8Vu@|lh;1F{J&Dsp^-xt$3vSi-`#}Y_8W6WKh+8d*TbabI zY~q$l+{z?wr4qN=5w|SjRtw^mk3Pa$S}?3OG0aB{vx#9j#4sN*%piv4&?DmmZb3Q` zt9Fe>CiNLwq#JL>eoR5B=dc?d; zVxEtfmq{Ox&m3WnQ0<6$ttff2h<_&KPkG9pNXnn`ls}Cqe-h{mNTU2nr2L7Z{7Izz ziK6@|Px;fB@}~*qPh-lTCX_!7DSsML{#2m+X-oOjmhz`9#U-^=CAEZ+TH26Wnvq%}=ml`>7wi{M!;7GtHk1j`lnIq7 z6Dm?B$hcWe)s)h}vvTW_x~fq!BvLX&Q8FZg-X5dhPMb^2r5NE^W-bG#5g(opquYh> zu8AivnV!6680)@4)x&uAjY#>Mc`M@L)vImZZr+agDsz=8PY+)-J$xDT@HL@_FM=Mv zY8WNI2Q}Yo-iQ46oA)Cw-o8|foP*z(Ys@u>V+ zjHVZ`ocT1ytm@Ghm;hhkKTuYDfep>)F^ZLpQ7rgN=of5azGA+DxOfL!&^uV0-obbo z{Y0JOBTS}`u$j3Dqh87M6eeTTYYSQ^{=#Vb3#-vz=)(xuhp0`whRO6AYIB$Q3EH{a z+>MrhYJQ5V;zz7aKVlPl5KVXx_o}9t7x6Vbjxu(VNk3u?{fLS5BQ}K}@q3KF9fCJ8 z5#GdqA})T!6#5a<%%djOR??doMQ>t#dJ`Mbo0vjxVikH5GvQ5yZDXEWk8$Bmtcd)TtV-}KiZ?Nl-o!L| z6C2T+m_~169eNW}=uNBvZ(>d8nc_`Mq&KlCy@`qRCMMFGm`QJ96#a-*=ts=7@WWli zo0w=dvKnK|uZh(J?G$ff8oh}r^d>f7KYd`oY_AC^vkSS|R&-a&k`y%}Ra;uWhvuUG?m#TwHq7EZ5NReHs;;1%1B z{2$sM;x6J9s|&B#M@ZQT-&kGv#&)S%^opg^D;7(ym`$%(C3?jw&?^>3uUI<0Vm09v z`vzsjAC?1u*tclm0eHpI=@n~CuUI<0V$JClt3|I^oQ#^|dBrQ1M6Xybykb8iF8;7A z`ok*FA6AwAuq^vG_`}la4@;sy%z*RCP_d47w5mm~SUSC8wdfU-@kp63qA_nq5GRY4 zXBI8b@w7a%XnAJQ=FFkZ*@!l0Q(BvsK!(?VS4Kvcyb+}g+Ln`PG0MnjHta$f6>Uz- za4c=YEZT%wv3Ybl9$b}?i`wQb;B*D#bm`!9s}Pq_ zjCArilRU0Fd0Yy4TvzhA0*+&Eep+U7sN=?ci{Omeyca=HR?y6)t31>|(~$?4L`=?rkX^(ZBr zt|vKN4|2K!aypZou7I2_onxH6$?v+7-_^u;=Z7dO{H`bYT^#t`E;Y&g1YECx{H}of zE}i_YJI76Gkn45fxXBRmy9DyPf#i32=C|gzssp)R1CE{y;pj;%j-Cu5*BeN#H-ud8 zVsgEKD<=^1&hGgBJPVK=Q#clt*Bu+)UaAn!*Zx$Ri=j3ml{?tYFK@#VfCVh)rT5Z zA8J@tsbTe}hSi@MR)1<(gQ#J(p@!vB!x~Nv%ch1koEnx*4XZyjtp3!n`cuPdOAEgp zE&R!}@JCqUJIth2pNTnBZ>dXZ)sLh-pGiwTGsG7-iZ*;h+VD+i!{^e5Z$|6AC9U@n zwAeFgrDxg+cDlNhR{BU<=9zx)os8g&qD|hAHhC_s@s^Z2VURkns-cuO;gmN+DR0iF zyy?vGm!TYgDbMkjp_Dgi9Df-~Ns~rN6HQ6eiIOIglBO;t%}|cNl;ilzP)eF;j=v1$ z_)BMwzYL|Mxqy;pC?!oaCCyMunlwt92uhlvlr$AM{!*UfFGDGBqB;IDl#-?sCCyMu znu?S(X_Pck9Df-~Npn6WO=ph34CVMsH08}u%9}LKX{bV}QQtF&fsS_qc zCTb$bVun)c45idbqtxj{O;+Y%#VGhT;N6I!CL2plb^yH_gQ?Gsp$^-MI;=w-wiUe_ zGJ7$WG@wZX25CT(1}xHmOBx6#4TO;f%8>@bNCV|a1DZ5olLj2pfK3{3NCPHmz$9i{ z!0d;V3!Hu!debBDUAb&o7+Y43EenGz&8I9~K=~O#Z|$HmBxfxAwaqC%2UC7lr2M>y z-rD)}*1`*o-$Ht8ucn_ioPOFB^wVa-OIu&9pr1CAe%clE(=MXal{vy9b!A3UE2&Z7j5pg(p{F$pX)GMZBkSEL-ii2m65^v6ciADc;k?A7$gM$;3! zf}YrLdSX}56T5<**i3q2SI`r?h?3k#A8an=c?+o1WUl7< zsxG|}{ppps96qo?YBarHBjNqJNL@ugMFsl6M$lVPi{6SE^i~X|Cu}CY6<5$(F_&J6 zVf04~rzawno`{L`M9iTlB9)$qbowAt>4WG???Wp64yp7z)S}0d~tPvLU< z6sE&>bu-#|yS@|fe!T|pDZLgmN5q3Q8Xl~d&~lkMQUQLfH`EAvAEwj$aJk;0KSCby zLG;(3>pi$Co`_oXL|j2%Ln?g@bLeGArI(=={R^q|ETmFvn?`-jq^4Gmnp!XFXi?O~ z5~+*1)Wu?`i*=(GR*m{sA~mmG)VX?4+e)N{)tS1LL)|KhT2&%7DVI7_3bm&i)SJpt zZ|X&jDUn*zCDf9-QA?^u{iq!EqiNKS7SkSFLY>H^PBfL;P$9J;gW6CWwV~eBgL+aA zDx@A%o_bIr^`JQFL50+S;-~@Dqz05k4JeKpP*-X|h17tmPy;HY22_(8P$4y-F4TYu zsR5lw4JeKpP$V^=LTW&9)POFd?qgH;DNo&}kh)JKb)Q1&K84hMlBoL>Quhg??t__n zn5!2{-KUVc&ob&hy{Y^3r0!El-KQpXpF-+BanyZcsrz)L?o)-jPjBizQ>pvJQR^wB z))PmqCkbF%Nk>y!0~bMse@ zU%FF&v8caHqUKVSI!gkzk_74_@zh6#P!lPj_K`rnqdPT@WNIAo)HteB*XTq2B7vGk zJT;36)GQ`Zv#3g)q7QY7%G4m@sX=t-jLHs}Jzie5#r*LKsuTUn=hO4$&GPWHhSnik z!$M^!?Ej?)S9nfY9XfXJr)rFtIc0+CHD=1FOVs)a!=_DA$HjeuH9#j}>&jkXRUnVk zAW2(d9>fJ|I4sx8)m+SFxKZ7y)~Kg3S7D>ts&*l#(YH_gB-NT_V{oSkNd82X4hh^! zb;JycfocTiZBAG7Fbm=)b(eZb{T-6`P4zzJHOT#9pgTn3u1S#bjZjY~%()n(Myg4e zS215LS2wHG>S4^2ctvee+b|Cz(9RfTV%A9v^o9D6@NHCQ*w`1UQK|rQF&3yo^*435 zdIaOHud27y2kKMk6n48o`AMo@UY~wRYH^Rg=Ow9^`gZG^qz?D%(=ExU?SFa;^H^e$ zy8$$YwyF>2c#c++)huWwE7UFO9`z_@YOGUltL^GDfBS7!0a{HhXe3QBlN0kDG0$_1 zx>Q{OJ>yz+tGX96KK`LzgO&fG`rKc}ftR5MdVUCXJhurb?P>C zALfTVr`D^@YKPk6FXLiPO&qkMEX-la!|c=ZG0SzFnyRi;*Klsh{g_YkJjR&cRUcut zh}XAa@MFYdj)@O?O$TT{{V~gQJZ7)V!5o#9@IgGFo>VVjw#gQ?6Qj{ynR1xhB6DxD z;o-Ou9CdJ%fld+KBLmD)RO*o0~JAj08<;|Zq_&LW&o zxRh`u;cbNXjL4Zf!hV==E#WJKn+UfN?k3zvc$o0GK*t&}Z0aZ{im(b{4Z2NpV8jG>7vUbl{e*`Ij}RUg7^VoFNtaEW5*A5Vi7=Khfv`4VJwhL06T+5+ z?F$fubtddV*pF}!;ZVZSgcAs-5Y8Z+Q!r)Zq_BmAO9`(dyqRzn;XQbOax z!xf=J7)e-(FqSZZur^^mLLXt1sS`&`4sS`=mGA<>(S*|o=M!E>cqiebgfC2;>dOw_ zM7WJ`H{m|Q!-U5LMp%SVgt3GvfH@Hj2pbW$BP zggprR5e_08N;rDzWy7aNP9U5@ID>Ew;X=Ztgx3+?Ot^~ho~f5jo*KD^a4q3F!p(#` z3HK5nCOjdqd>CPsS)-;Dlush8OW1%ghcK70HDL$Bu7te^`$G$n*XYXhQFiwYc&={#`Kx`hv9Yk3kz{ zHD=(#t%W*7_cHw0=;5Tv6c2hSqCXncBF`NrvFsm%HCXnK!9|kt4Fg7+AyEqu@7mRfc#@YsB zO@c95Gs&F|;(CB~fGKeu{b6f=*u)=Z`op^ZP{t@FzpPxBFv=e~{;(}V?356f>kobY zFwGw(`NLR$80`DqV{?<2f_;Vyz}T9URZgoKOF531!K^HsvZ2{E`NB$3#&!(4raB; zY6;bR{Fs6S@4 zKYZFBuJwnTyYc~d_4+Bcwil+{%P>URtE)QA?=4W(pX4oi&>#->V5Oj{64 zdnOqBBoH&OSBF>DfK+f>NC~3>(|{o=(!kspH`T}i?8j>zcujIadinFqyWsr|d19}Q zy8~%D8!?nkmbDr=Mh9b&UaWsI8=0-m#nw`+8hO;2?K*B}caXa`Y;D-la=GPZmD?Vk zi8tOF9>X5+QC(aH-+Np=3m@PHc;2?cC$<~js{I(FJED#Q^&KNpL+Y55+&uj*!+gDs z;bM&)1(3c(Z)dnvzt3=)evjdDjTMr(UMS_UOAN~+WO;-vkC5dNvOGeTN67LB3-xBK zn4hGH8CrTJMP@>~>H2!W3@uoar>_Cbmz?exy#jEt7K~V;uLE4F1s9fS!HebkTEN26 zc&l$hdLl-sr2ZQL^YjgX`Iv7lwcP@^MBfUyO#cmVIiy{4`WO4ar#c+iG6kN@`S9be zgpcta_*I{V_ir71xtrlz-3f`ZR~>* z%QWOa@-5f985T-;^h=&bd4w#FkmV7wJVKU7$npqT9$}&Wko|cFo+1%raq_&Y0Q2i{$K#efa<3xIk06~M*%WxypGD?7o9{x}Bg;hW6UpEJzYdl@d)(D_JF`xq|O zUol*!zhJmrf6cHE(zG0=!&r zz!N26)Kz)_>z?tv$OAlh3vjW<8fet|4&YL~5pcPF8xXU5@#b67``r)T{E?i6Hyi%^ z<)DIFpi|ukI(QP?xeG)K5V;2>)`vhRV z33~^%bp{+`nt+Q~A!neh}szlO*`*ns)=?DHd6jEgZ zIN%KE(+kaV$eCz{1E!dj0MpHifEil!hK6PsV4mp$=9`rPN10Ut$C*_CCt&4(b_>iX zz{O@H;1V+$aH%P>b(t9fxZJD&SjM|Ct0O(ptO1x}iUiIxF#?9WBmgcp;{lhLH365I zae$ByB9+Y~#PdwdWQV?YHcwXzITOv=fGK7MV7l1=FaxW0Cylfn{@$~Kzo;`O9fnJLWjiDr2`h8Gu{l~drmYjV3=a|XP9T6&oCb= zd_24v%y6+eh~W|wHaGBTsd*v8W#&MJ%gu`z7Mcywnnbe^V2YUom}h1K=3@sBdA5Fl zW6WH@#by)0C1!KLrDjvWWoBc*6*Py@6H)Bs%qH9(U< z4bUUXuHhr3ixiX^J^>U7C^dWvDAG@A*a;|-uk0H3AYHhy)UX#&IH=UH4^X(L)bItM za89Wq!qc7ux^931z|*9c+5!qclU`~CD7;L1sRN+!G3lRky1C9qGK|Z>`}HFE7b16`Wo36@&Q>-gLw_IH{_$3(}49e znA3ng`!J7TEmq1ri?h3sS9Xy62d+Pj*$mGj_MFny4y&0mQ{oiAdu0Vr$PcUE%J^X& z+$nxo$HqHi=Z=scR>R3Wi&Olt>W%HgO1M%#?D0|N59@u({9y%9SwB3tHr8O?%DL}6 z`H8jL`qcW&`rO)MePMlReP!*nzP9#R-&p&tZ>tEJ!tb;va{bv1+m9W@|z}B{j1tzxb*sdLBm$Sp|2s_d)Z%1Kw%V^Adsbp8S ztJqcTYIckrYgfmb**H7iu8CQ>iFT5mY^T_@?Amr6yRMyz-7wQJN2b2rz|O#m{4A`; z&$e^yhIS*nF;><#wR7!ec5}Oh-O_Glx3=5ZZ84Xoy`5)wu=DMXb|<^D-No)|ceA_O z=h;2%p7ua{klhPw`1{y>?SA(8c7J;SR`FkGUt|xqFSdu+L+xRhhcm(+X^*l;+hgpp zu+1*9C)gA1Np=BtGrZKEVo$ZF*_YXu+tckC_Dp-0eT6;SzS5p!UuDnbuAK|)h4$6< zBKsQ5AzorHwU=QAPocfSzSh3ZzTRGG-+;M1H`zDaf3t7FEYst+@;9Rl4H17Wy zd_NVghhn(IOXGNHe15hJY%Yz-rE&NrS=Yn8B45MYqt|5x57zIzDYL0D3kmz!U>4FA z%s$$RSx4JsT@F^|?2tLqvI++?qp>RuW*>cyxkq2f9BBJ%S!aWJN7!)&^NtQ;*3lu% zHj=$3f5NP0tewG3=3g++=wFy+^sCHU#tfsAvPK3gWK5Z1#Q8-=rQeOWm9DI@20P5D z>{M~8T32Geax7*m*Kp#Tc+6Bzz&zz7%u-HqYB{wXXakjws!#vdQDRwi7@)$EbeIiF z{CCjd#iYdl3>^v;-VS~Q4YA^E)g5!;{ErZu`Z?!2 z{ha~M12gco72PT>2!C_Q%3Xwoh(v6 z`T+j22YXO{Gv#a&w;)gy+&EiYUgg}9_L=1B_V$!r?Jz-Y3k%U&79^=3#X;i%4zGg zb6Pvl<)Rm2x5cyEuNJxSJr`?$b%8a|8f0B)4Yn?_F1ChPL(AITmXB^kcYr2oM7M@N zSx2|Uj&ftHHdb4!oz>pTvpQJ$R!6Io)w#?Tyb`jXbykVJtj~7`oO&;7+}Xh0nyU!x zh};A_?d0lay18zlTk2NMT^hT6M(1Kq0O0R1_zYNn(T!Af%v!IeV|1*pu50Kx9j|NZ z1f8gpbh1v-wRCM=N7vPVLpVY-|S*AW=sD6gY*1s$y`>Pi~+VTBV|y^ftpb$Mk}IF5cR z+vlXsOEhdsa}MEEgmVeK^!bc0AY4dzHQ^${YXFT37zqG;91tto@yDLa7-3|Th5O&2?fn0*)!cD9UGa>1;@L{0zfueQPfMTbrL@4)TR^3BK-p13 zUvUb%M{*bcovq#TKd1$oWB%iEw@f_{t@=;ure$cR_RCI~)wPU$*!!2>uN^Y9EX~!g zuUfCzwM7CrcRF{u-WL~2er*9`s_to}l*pmTcy+B&+o*>z_a;V5qdiuE_29VsaAT}7 z2_x^bjJd`ljJ>ZkZZYn}==;Oi8~s^~zpuxa1GZuX*KUlM?>7!(kE`FYT|qeHNGzmQ zZAd5|BwtIcyXvfaU^UesJyegzs;4Q~qh}7*D=pR6>6`T`eUDzFAJ=QKB59r8h*e12 z^iHfi+N%%f!}=(8J<(xSktiDa4uF5F2^d_ zTdX^+`>;CjNo%e33ihPhg7qQ0U`zi5TN%Dw>osQ>;Cg2`;Oou^zzxnwz&D&xfE%6B zfNwfu05>_9VPn1Jj1x&`z3q$#e8;&2aI-T3@Lgvj;1*{R;CoI1;8tfc;QP*{fZLoY zfFC$h0k=ET06%mt1Ki;3(Z1P$uRB))ZgA!R zzTsR2xY3!5TyHw_G<>IM;e4E}LmL<1>}_Wu;5*LMNZafz((odpjn@EfaTWu<=PUu- z>MR9(-&qE@%~=lkfl~;$-B|(np>r+Z4(B?+kDTiPcRDKpKXz^a+~wS;w4I>giMA6p zyw!G+h9+hw>j=OU9SK+q`i8b^>nOlFx&mNb9SxYOD*~qJN`UF2pXe&~D%AOjt_HYU z#{hn+V*x+Y)d4@(@JCyFbR6IpIv(&#T@&ytodCF3Cjx%0;e)pJL6g?jH#!Ayzpe%N zt*#AtK*JKWzSHm*TL*P2;P)CHWb2TIr`Y;I*8@DP>jR#2ZbPe-b30%~odH-$X98B% z&{^y%+6P!w#*po5ItMUDHw28;jQ}%s6TmF&zo_kOoeSvG%>Z+BbHIkW1z;oH60osu z1t|KrwjUIn0z^LmqQ|V3Vp-U~;jNX!7a4lNdZ_C(f+jlvJf@3svC5`5?1@yTF>w9@ zoJYX==m5>V3BC<65a*GwMe?D?H^rAC2I0IsER&AV>T~hkhzoHZ1v{k^bo^%cio{@? zSAf;h85)0cd{g2goJYfk=>q+~1=e(3jPr`HXu850Xo>Gl48eIN*f-r^8??gLCx!yU zhFSeB_&pIq?*|uz4;NpgXa_jbY7aQd$^#s2bpRY=m?K?FQ>& zFl?e6r!8U^!8U5>paxj|E%a=VXh$ftd@y0L)py zTgSJ6vY>&^pcX1~18`5w2+-~dd^zYkBi~$WMcI4Hw8~(SiDmXjEd=*^(SI?%BT#1J zSeS{Cf-e!tEFg?5q3;H=`O$=6dB5efXhMU2Z zA;^_%$jl(Q@Uk}BK){w6Vfp34PKf^lE&N4~?YeQp(n!>o%>zHfu z26l2?gBpgYPq0FDpE`lnp(~8RSP^=oF#;<>|89)Is?O()h4Li}V+q!6ZZcNNx=rIo z>~yiixCyH?zcB8!UbDv<55lu|hwce&={Y?g^8G8l%KqAMF`{ayc=n+8ou`Zv-+1ch z_Q!XfCY1d}Czefe179vWH%kva&9`Bge@8urEpJRi)?bGvw443(8~f=Z_R~oA(^&S?)$FIG?57*pPdBljZe~B- zC3VBX?aaDutF;BcK4jejq%O6VV$bg7Rw4Fu{hPH4bAj*;54`in$a~DdF5pHpqoW!G z9iW>Ui(PbwVDJ24#tLs^dW?Iwe9YZ!cVQj(7WD~tfY^;%%3;MUd<|F`dkEi= z_z^u4fmNxMu@jJdVI%{qNmEo4t|QIGI#R6svU04JSY@Wc71&m;{tQQ}Zo#}M>C-#p zIl$8fqHX9=;4@?mXuG}B6Q4VN$$5pXmmC-INex`-=H+#-19hQh@5!)Na7{d!?7<6( zz`6uCK|k1gU@3b8_4->e0DKD4DR|z^>W6cAqiw)>40sPlpRM=7dihV_V+8j3Jr9~# zPwZdZ+vtNY*z|K2x$;dALt}gg{R5c-4iJx@ygTp%=VIq#?8I<|a|JvCl5ZIMAO+N{ zxZ2-<$7dd9WXQEK@{D-0aFmukpOFU3zmtAKW{v+ z=o*-eRe{)56SVz{T8n*}l)V%~hbsxb` z-4`pFTj~pidh{qfeHT3%GW2{s22yLhz7&`svs#XPxGeI4fIVNMmkk(Q-bf>&kh8^Dnp>KifFud%)f z-==G-Z^rlOn(4n`?p_Oh3%*m=THgx!&|cq$Z`F0sx8qA<{q!pEwf_1J@V0UKPVl!0 z`Y!Oe$$B-uTsKAEjjz{D)A!&Dc9-jW@fEun`aXQgZkE0uU$dL7AHWyw=I96URlB)* zjXU3+uOD(3x(oHg{5H`ec+=3b$QuMh8bL}O#oP+PwRWVb0mQ0-z|($e80l*qFsPFn zPb|8GI|@w%o#)^?Lqg*P&`i3inV_FxY8L7JYI3A&NQ3ens$0}j&`hFQ4oR4z3L&L3 zFmpq8E{5b1NoIdlrVkbVQ}LtzQF;Ss5q{u(8&lTJ>Tx4S6-+6ZIH}k=;~HFNT!ZV3 z@s%6omr@$C6CCTL%p>#;p%aPYUtPi~UUKZeeDh;}cFNUT)Opb_yNdsm!X%gqZT#IoUZm z**+eFV#??EvU3{xavC;n*0|Xq-^C$~J-=_@cHxz)^qo0z*raKrMkM7GOqpCT#k-x) zm+9RuHF#NWnAA6L$G)ScTt05ZsHwPhQbtmz9N&B+CA5PKTbc8X3JU4rdcI+(ryl)# zmww&;7GEiRXPueXrwpi9u=}~X8}g=Jvi{Y~UW0zEvi|ZFc}AVQwReA+e`NnZu6TXg z=9G`t!ch9;@ack?pb8Et*Q{w8LcWL5N*`NN} zdzkL~z{5XxX<*ODzdviqmTzwT=J(}a4rtSA*YC`D zeCdG)_C1_h?aE=l+;VBfm%i+Ecek%EI{tOkgAML_cvR8{J8#~#OZc37q?kMb*Ymn>M+5R#w4?sgpCO z5p^<06ig(J)vRn7C#^7_gFu5vw81N^nP}zun)n*6&ROkSl<6-#V#cMf$=6Eil7;QBrFKxswGtaeQfVUeQYSCEf=d&aUo@@h~S^DkQ#Snpw+c(ZzJOXPV^Z_R!nY;e6-rHnE7Pe7tDFq zH{ZG!6u-<*@lo#`$=&q(tBogFJICJ=SEE;n7XRC6$fIFjc5X2m&S@5);o;{*!;OGQ zWEu6(M8kc@jhQrRiqLVRGt%)rBO;o0c<#ko4|eGCV${jI4-X6Pd&85reDYX>3SHlr zbaGM4zUNn{y2WZ!|F?&3zWL)gm=4r@#%;UW0vGx_~ga64q9_ZTCb>>LpOgi ztVMqBn(tNWAF;C2iANqkI=WS-M<-ADX5}|S-i>~K!-A1FR)4w9+%NWTOSymR3wqYw z({H$N)a!?0roGf|QN7(^-IuRietpKB(>o-N-LYoc^iQHL%vsidS;Ln<9x&fRC)vTh;j1QRb%ZodLo)7M-_!s(fxyT3M)~Rm&OzV_ej1%NHG?!h zeQM@ZKZhovHx1_1i|QBU9X4)QW{Ip>)22?%7%?nkOit#AQB!;^rE!T?V_!pG_Uf$F z8KI?xA)KZ(Si#v+c}@s(>$q{;y-{7OBz)L?SDz6vZ7y!|Qu%$pL}^AXE7n(SZrR+g zxRiwufj6SX+Ux77?uV}(?rS>Z-i4`dLG06?)!Dsz`;F$qi+a?#>$bLL{HI&Kn)y!h zSZCL>Icq1rdZaaAB>r;HuZ_qLbEO?&i>nk}zdx##tl;&)n?`R3c>!K(WB+0=xAKRon> z`XcHp=Y?zcq}Lf(l1rY2!ad|L_kqgFbjx=fCPN6IUDIz>LltquGQ3(-j8X=U);2>*&18*$` zZ_QsqaA1(wY=SYtGlI;ZQwW|cdI*Wd`Bdo;?B{HSb9g*5ozpcif|-3}q7m#8`Aj@; zn!#^|@m@RW+=5ZqPTZX``anvi!zw6ns|j z?d1VM<(~!fE+<#WCm59KL~_*?GChwFt`)U3%vgHKws ze|>dArR1igijQ(!=I|E$2nc(|IMt&k)O7sFAnES5OKzuik}ICrn#GHP$}-2()1%i5 zVoi&-U7q6OGYR4|4w&#^20^$IK&`{?LlDX@RyvW;aoO-J|E<=c!HcF$!1{x2z)uhh zn*zWKtl*nNqhuB4%|%5;%>osA8PAv@C5#Q>HZQo)XrQFOHuo^(^0(4hI z5iElP@J3q7zmeQM-CXsJ^oHuwT1rAlV;kpuak1YgwB6rC`@XK@ zRn==CGUj0M8@kXKG5!lWW@)=~Ou0J1y%Y1^)m8bjO{7wKrJ}?0@g(%>h&^|3b^Y1( zChNuXU#=~!u}?@I98WG?_f*o=YN|^nwKCz|HRqwNG|#czwYw!{W0ZO(T83|UZVG*O zrX+vEk4{%^f7?BfiIcIdS{Z}n3XB;XPIg(E5;rOm;EGE<+c24)8&v5;&#@AOn$6nNO7l(5q$+-b(3q>K8FA4)Zipno-z2Z_tQRirJzYG7%DFgp80P!@W zDKLeu!OsH`GhhnL7I-<1;DMB&*nB>1jYeVcXqXW4bo-(~w6w4zjX{bcu@+KO3A{8U zb|fjBMp(}ZA~EUFbGf4AtOH}0;DwCLOw17@i%)^f`!wjj!Z=X}h|R!I7L!gwq<{o( zPzWdNO=1$(hO%i0ba&p6C{Dqi8cK#x<-jC5gw2ao^NA^qiYx_^yh&m>5g$$%4aOd3 zIDa8V`X3hltE?S*`C`MUMG_7-(?pf;4$a0m_GBLSPwM3Kq$}4Pz)v}-y9lYhJ#;3~ zUvTpq;ey(6tbP(hR1upuINVaN|EgK&-mkZcO~j5R)JpuW5LVrzvLgSML`-uBru-1u zcCS`YV3ygzv)i9GXUt?~is$t+j#rkprjFSL-Z6h6Z8SxEZ`@Y>w)JRpSFOiSN@G#+ zDLQLK1Rft)x^wsYCy6~xB~Q-W7v(tZQFqyYdoJEBe9zFIzu>UC0*Qsk z@-%QDuSviLfbC$bpxBNi7gW-_H7FrDL9h-i*n&KkuA2{tHZ@)}CeWY_5%rJ@x8J*CQCd5f*G%*H0fYBSZpS-gZ^7Fv$jl9F-iU zBtHGwltuf39bP`{%ikIdS8l)+(sdr^FkIp11Ht?{>TIN12tWY+4~D}(!Sok7{smDi ztdnxqT+VHn_&w`Rifn*XZ^p2^--Uy|>}c`e!xH<>OifO=B&wBuYr=Uy;l`k;=B-hA zWHmwlEvS9pKz+!0kvARkX-vH*wZoP-dcSV|@pjAlX~AP64`!Oz7-83yg6apvUVoz> z#JZ&}(CC&MtM6Qrn@s-Ipxi@M_Spcn)lWP3e|uC<`R>?|eicG|nixLDmhwD=9koIt!z6tc77cD0eOCO+%J{VO{R|X8ZjE znOD^SO1pQ&=L!(gO0QWzJVYK9DVdG;tGv`1j4C(x`rw9hYEh=VWfzqO$7$OdH%#X!S z8F&vZEW{$Pf)s6MQ}rP;LNk-B>zQbnQU1r(0B5jo(GnaI2ADaF*qs92ur3+_e>d*4{vKZ`_*)s>(c?u%|{=W zY<6OQjM%j|w&UR`s#22ciDh5|p_{f^H$B)4oPx*-nEpI zyUV}e4l>yXN$%OFcE__5CAxDXV;=u<)PiGu-=DNo+@LY0NBif8(KRk!(VY{9GO-@2 z+&^xJ*65LB)eSVQ8>(ZjfX7J~BXfQ!$+~ zRV?*ByI{rH+DL)#HrPp<$ITpiu=mLKm+1w`_X7jlz{@V*qd`}&9)baNLn&Q$S9@=I zS*b*q1Q$u-6%<$@1u%QPYzg&q%0-PbD! NZ!^EJg9yI>`4dh{B2EAR From 59602ad23d6d4db12fd92689fd332d46aeaab26a Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 12 Feb 2017 12:10:39 -0500 Subject: [PATCH 268/917] fix up the todo list based on hidpi changes --- core/todo.txt | 7 ++++++ todo.txt | 67 ++++++++++++++++++++++++++------------------------- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index 3100cabeb5..30a9e0a80c 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -22,6 +22,13 @@ X https://github.com/jdf/processing.py/issues/233 X https://github.com/processing/processing/pull/4873 +high +_ Sketches on Windows don't take UI sizing into account +_ https://github.com/processing/processing/issues/4894 +_ Sketches on Linux don't take UI scaling into account +_ https://github.com/processing/processing/issues/4895 + + _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 diff --git a/todo.txt b/todo.txt index 806bf8b168..283208dec0 100755 --- a/todo.txt +++ b/todo.txt @@ -1,21 +1,47 @@ 0257 (3.2.5) X check for already-exported folders before trying to remove them X was spewing 'file not found' errors into the console -X NVIDIA driver problems (and means to check) -_ https://github.com/processing/processing/issues/4853 -_ put the reference (and examples?) into .zip files -_ unzipping the app takes forever +X PDE and sketches are 2x smaller on high-res Windows machines +X https://github.com/processing/processing/issues/2411 +o System.setProperty("sun.java2d.dpiaware", "false"); +X though that seems broken in Java 8: http://superuser.com/a/1007783 +X until we fix it.. +o call this from JNA? https://msdn.microsoft.com/en-us/library/windows/desktop/dn302122(v=vs.85).aspx +o or modify the manifest/app? https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx +o hidpi scaling via font changes? +o http://stackoverflow.com/a/34152675 +X hi-dpi support on Linux +X https://github.com/processing/processing/issues/4183 cleaning X Contribution Manager does not show all libraries until filter cleared X https://github.com/processing/processing/issues/4840 X fixed in 3.2.4 -possible +unconfirmed X visual artifacts on Windows 10 when using menus _ https://github.com/processing/processing/issues/4700 +X Broken characters in the Welcome Page and the Contribution Manager +_ https://github.com/processing/processing/issues/4747 +X looks like a failure to load the Source Sans font +X what happens if font loading fails? +X are there conflicts between version in lib and OS? +o are we still installing fonts into ext? +o fixed by rolling back to 8u92, broken since 8u102 in 3.1.2 +X NVIDIA driver problems (and means to check) +_ https://github.com/processing/processing/issues/4853 +_ blank window on startup where the "Welcome" screen should be +_ this may be fixed (removed invokeLater() on startup), unconfirmed +_ https://github.com/processing/processing/issues/3933 +_ Welcome screen doesn't size properly for HiDPI screens +_ https://github.com/processing/processing/issues/4896 + +_ put the reference (and examples?) into .zip files +_ unzipping the app takes forever +_ see the 'examples' section below + _ EventQueue problems with "could not find sketch size" message? _ https://github.com/processing/processing/issues/4893 @@ -23,9 +49,6 @@ _ "Sketch disappeared" infinite pop up dialogs _ https://github.com/processing/processing/pull/4808 _ https://github.com/processing/processing/issues/4805 -_ blank window on startup where the "welcome" screen should be -_ https://github.com/processing/processing/issues/3933 -_ this may be fixed (removed invokeLater() on startup), unconfirmed _ "error during export" message, but no error message contents come through _ e.g. https://github.com/processing/processing/issues/4792 _ 'run sketches on display' message shows up on clean install @@ -57,14 +80,6 @@ _ https://github.com/processing/processing/issues/1476#issuecomment-23229990 _ could not write to temporary directory _ https://github.com/processing/processing/issues/4757 -_ Broken characters in the Welcome Page and the Contribution Manager -_ looks like a failure to load the Source Sans font -_ https://github.com/processing/processing/issues/4747 -_ what happens if font loading fails? -_ are there conflicts between version in lib and OS? -_ are we still installing fonts into ext? -_ fixed by rolling back to 8u92, broken since 8u102 in 3.1.2 - _ 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 @@ -108,25 +123,11 @@ _ swap out the fonts? _ Help Menu disabled on OS X _ https://github.com/processing/processing/issues/4353#issuecomment-237715947 -high -_ PDE and sketches are 2x smaller on high-res Windows machines -_ https://github.com/processing/processing/issues/2411 -_ System.setProperty("sun.java2d.dpiaware", "false"); -_ though that seems broken in Java 8: http://superuser.com/a/1007783 -_ modi -_ until we fix it.. -_ call this from JNA? https://msdn.microsoft.com/en-us/library/windows/desktop/dn302122(v=vs.85).aspx -_ or modify the manifest/app? https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx - medium _ detect changes in case with libraries _ https://github.com/processing/processing/issues/4507 _ make when opening new editor window, open on the same display as current _ https://github.com/processing/processing/issues/4526 -_ hidpi scaling via font changes? -_ http://stackoverflow.com/a/34152675 -_ hi-dpi support on Linux -_ https://github.com/processing/processing/issues/4183 _ Library path mismatch between processing-java and export _ https://github.com/processing/processing/issues/4493 @@ -634,9 +635,9 @@ _ .java files are copied to the root folder as well as the source folder PDE / Examples -_ keep examples.zip in a zip file? (5000 files @ 30 MB instead of 15 MB zip) -_ mark examples as untitled (rather than read-only) -_ maybe even pull these directly from the zip file? +o keep examples.zip in a zip file? (5000 files @ 30 MB instead of 15 MB zip) +o mark examples as untitled (rather than read-only) +o maybe even pull these directly from the zip file? _ load examples from zip files _ https://github.com/processing/processing/issues/182 _ don't make examples read-only From 06495c3d49bcde00f0f6824d1a2e21298ffe9129 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 12 Feb 2017 12:23:17 -0500 Subject: [PATCH 269/917] write release notes for 3.3 --- build/shared/revisions.txt | 80 ++++++++++++++++++++++++++++++++++++++ core/todo.txt | 2 +- todo.txt | 6 +-- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index ed123519e4..323754939f 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -1,3 +1,83 @@ +PROCESSING 3.3 (REV 0257) - 12 February 2017 + +This release adds the ability to the scale the UI or high-resolution +(known as HiDPI) screens on Windows and Linux. Sketches don't scale yet, +but this will at least make the Editor and Contribution Manager usable +again on more recent Windows and Linux laptops. This release also attempts +to fix several other Windows bugs, detailed below. + +The "unconfirmed" fixes section is a handful of issues that I've never +been able to reproduce, but that should now be fixed. Please confirm at +the links listed to let me know if it's working. + +This is release 3.3 instead of 3.2.5 due to the huge change to the PDE +for scaling, as well as minor API modifications (see below). + + +[ big fixes ] + ++ PDE was too small on high-res Windows and Linux machines. If you're + having trouble with this, change the "Interface scaling" option in + the Preferences window. On Windows, it will attempt to auto-detect. + https://github.com/processing/processing/issues/2411 + https://github.com/processing/processing/issues/4183 + + +[ unconfirmed fixes ] + ++ Visual artifacts on Windows 10 when using menus + https://github.com/processing/processing/issues/4700 + ++ Broken characters in the Welcome Page and the Contribution Manager + https://github.com/processing/processing/issues/4747 + ++ Add a dialog box to warn Windows users about NVIDIA driver problems + https://github.com/processing/processing/issues/4853 + ++ Blank window on startup where the "Welcome" screen should be + https://github.com/processing/processing/issues/3933 + + +[ minor fixes ] + ++ Prevent unnecessary 'file not found' errors in the console during Export + + +[ fixed earlier ] + ++ Contribution Manager does not show all libraries until filter cleared + https://github.com/processing/processing/issues/4840 + + +[ changes to core ] + ++ StringDict(TableRow) constructor to create a dictionary from a table row + ++ Allow lone double quotes in the midst of CSV strings. This improves + compatibility with spreadsheets exported from Google Sheets. + ++ Return null (rather than NullPointerException) for PApplet.trim(null) + ++ Make trim() work on column titles as well + ++ Make Table.trim() also remove unused rows and columns. This will remove + extra rows or columns at the beginning as well, since that's what trim() + does to whitespace on strings. + ++ Consume Unicode BOM (0xFEFF) in createReader() and Table parser + ++ Return null for getString(), getJSONObject(), and getJSONArray() + when key is not present, more in line w/ other API + ++ Several fixes for memory leaks from jdf + https://github.com/processing/processing/pull/4862 + https://github.com/jdf/processing.py/issues/233 + https://github.com/processing/processing/pull/4873 + + +. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + PROCESSING 3.2.4 (REV 0256) - 29 January 2017 Just getting in as many bug fixes as we can before the end of days. diff --git a/core/todo.txt b/core/todo.txt index 30a9e0a80c..85175755ae 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,4 +1,4 @@ -0257 (3.2.5) +0257 (3.3) X return null for PApplet.trim(null) X StringDict(TableRow) constructor X allow lone double quotes in the midst of csv strings diff --git a/todo.txt b/todo.txt index 283208dec0..28ab7f4977 100755 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,4 @@ -0257 (3.2.5) +0257 (3.3) X check for already-exported folders before trying to remove them X was spewing 'file not found' errors into the console X PDE and sketches are 2x smaller on high-res Windows machines @@ -30,8 +30,8 @@ o are we still installing fonts into ext? o fixed by rolling back to 8u92, broken since 8u102 in 3.1.2 X NVIDIA driver problems (and means to check) _ https://github.com/processing/processing/issues/4853 -_ blank window on startup where the "Welcome" screen should be -_ this may be fixed (removed invokeLater() on startup), unconfirmed +X blank window on startup where the "Welcome" screen should be +X this may be fixed (removed invokeLater() on startup), unconfirmed _ https://github.com/processing/processing/issues/3933 From 3eb6fdaec0610abe82e2cc6959618a832fcc2ff5 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 12 Feb 2017 12:28:44 -0500 Subject: [PATCH 270/917] fix font typo and add scaling caveat --- app/src/processing/app/ui/Toolkit.java | 2 +- build/shared/revisions.txt | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index 5ceaacac89..f82e2f81bb 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -1036,7 +1036,7 @@ static public Font getSansFont(int size, int style) { } */ sansFont = createFont("ProcessingSansPro-Regular.ttf", size); - sansBoldFont = createFont("SourceSansPro-Semibold.ttf", size); + sansBoldFont = createFont("ProcessingSansPro-Semibold.ttf", size); // additional language constraints if ("el".equals(Language.getLanguage())) { diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index 323754939f..9008cf89ec 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -3,12 +3,16 @@ PROCESSING 3.3 (REV 0257) - 12 February 2017 This release adds the ability to the scale the UI or high-resolution (known as HiDPI) screens on Windows and Linux. Sketches don't scale yet, but this will at least make the Editor and Contribution Manager usable -again on more recent Windows and Linux laptops. This release also attempts -to fix several other Windows bugs, detailed below. +again on more recent Windows and Linux laptops. -The "unconfirmed" fixes section is a handful of issues that I've never -been able to reproduce, but that should now be fixed. Please confirm at -the links listed to let me know if it's working. +Note: the scaling feature is only meant to patch up problems on HiDPI +devices, it does not provide an all-purpose means for scaling UI elements +independent of the OS. + +This release also attempts to fix several other Windows bugs, detailed +below. The "unconfirmed" fixes section is a handful of issues that I've +never been able to reproduce, but that should now be fixed. Please +confirm at the links listed to let me know if it's working. This is release 3.3 instead of 3.2.5 due to the huge change to the PDE for scaling, as well as minor API modifications (see below). From 801a94adc5675b356cf1a7a0ecea0264abe3cafb Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 12 Feb 2017 13:02:19 -0500 Subject: [PATCH 271/917] starting the next release (3.3.1) --- app/src/processing/app/Base.java | 4 ++-- core/done.txt | 24 +++++++++++++++++++++ core/todo.txt | 23 +------------------- done.txt | 37 ++++++++++++++++++++++++++++++++ todo.txt | 25 ++++----------------- 5 files changed, 68 insertions(+), 45 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 5fb1a54164..05ea1a0f96 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -55,9 +55,9 @@ public class Base { // Added accessors for 0218 because the UpdateCheck class was not properly // updating the values, due to javac inlining the static final values. - static private final int REVISION = 257; + static private final int REVISION = 258; /** This might be replaced by main() if there's a lib/version.txt file. */ - static private String VERSION_NAME = "0257"; //$NON-NLS-1$ + static private String VERSION_NAME = "0258"; //$NON-NLS-1$ /** Set true if this a proper release rather than a numbered revision. */ /** diff --git a/core/done.txt b/core/done.txt index 1d3c46b079..2842d1cdb5 100644 --- a/core/done.txt +++ b/core/done.txt @@ -1,3 +1,27 @@ +0257 (3.3) +X return null for PApplet.trim(null) +X StringDict(TableRow) constructor +X allow lone double quotes in the midst of csv strings +X make trim() work on column titles as well +o add trimRows() and trimColumns() +o would you ever use one w/o the other? +X just make this part of trim() +X also remove rows/columns from beginning +X since that's what trim() on strings does +X consume Unicode BOM (0xFEFF) in createReader() and Table parser +o no prompt shows with selectInput() on 10.11 and 10.12 +X https://github.com/processing/processing/issues/4758 +X can't fix, seems embedded in the Java implementation +X return null for getString(), getJSONObject(), and getJSONArray() +X when key is not present, more in line w/ other p5 api + +contrib +X Fix a number of memory leaks (jdf) +X https://github.com/processing/processing/pull/4862 +X https://github.com/jdf/processing.py/issues/233 +X https://github.com/processing/processing/pull/4873 + + 0256 (3.2.4) X write exec() documentation X https://github.com/processing/processing/issues/4740 diff --git a/core/todo.txt b/core/todo.txt index 85175755ae..af6470bd17 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,25 +1,4 @@ -0257 (3.3) -X return null for PApplet.trim(null) -X StringDict(TableRow) constructor -X allow lone double quotes in the midst of csv strings -X make trim() work on column titles as well -o add trimRows() and trimColumns() -o would you ever use one w/o the other? -X just make this part of trim() -X also remove rows/columns from beginning -X since that's what trim() on strings does -X consume Unicode BOM (0xFEFF) in createReader() and Table parser -o no prompt shows with selectInput() on 10.11 and 10.12 -X https://github.com/processing/processing/issues/4758 -X can't fix, seems embedded in the Java implementation -X return null for getString(), getJSONObject(), and getJSONArray() -X when key is not present, more in line w/ other p5 api - -contrib -X Fix a number of memory leaks (jdf) -X https://github.com/processing/processing/pull/4862 -X https://github.com/jdf/processing.py/issues/233 -X https://github.com/processing/processing/pull/4873 +0258 (3.3.1) high diff --git a/done.txt b/done.txt index f6f80ec4bc..46de0d8666 100644 --- a/done.txt +++ b/done.txt @@ -1,3 +1,40 @@ +0257 (3.3) +X check for already-exported folders before trying to remove them +X was spewing 'file not found' errors into the console +X PDE and sketches are 2x smaller on high-res Windows machines +X https://github.com/processing/processing/issues/2411 +o System.setProperty("sun.java2d.dpiaware", "false"); +X though that seems broken in Java 8: http://superuser.com/a/1007783 +X until we fix it.. +o call this from JNA? https://msdn.microsoft.com/en-us/library/windows/desktop/dn302122(v=vs.85).aspx +o or modify the manifest/app? https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx +o hidpi scaling via font changes? +o http://stackoverflow.com/a/34152675 +X hi-dpi support on Linux +X https://github.com/processing/processing/issues/4183 + +cleaning +X Contribution Manager does not show all libraries until filter cleared +X https://github.com/processing/processing/issues/4840 +X fixed in 3.2.4 + +unconfirmed +X visual artifacts on Windows 10 when using menus +_ https://github.com/processing/processing/issues/4700 +X Broken characters in the Welcome Page and the Contribution Manager +_ https://github.com/processing/processing/issues/4747 +X looks like a failure to load the Source Sans font +X what happens if font loading fails? +X are there conflicts between version in lib and OS? +o are we still installing fonts into ext? +o fixed by rolling back to 8u92, broken since 8u102 in 3.1.2 +X NVIDIA driver problems (and means to check) +_ https://github.com/processing/processing/issues/4853 +X blank window on startup where the "Welcome" screen should be +X this may be fixed (removed invokeLater() on startup), unconfirmed +_ https://github.com/processing/processing/issues/3933 + + 0256 (3.2.4) X only require reference.zip (and internet connection) when building dist X set text style properly for Contribution Manager error message diff --git a/todo.txt b/todo.txt index 28ab7f4977..0c84b65fd1 100755 --- a/todo.txt +++ b/todo.txt @@ -1,24 +1,7 @@ -0257 (3.3) -X check for already-exported folders before trying to remove them -X was spewing 'file not found' errors into the console -X PDE and sketches are 2x smaller on high-res Windows machines -X https://github.com/processing/processing/issues/2411 -o System.setProperty("sun.java2d.dpiaware", "false"); -X though that seems broken in Java 8: http://superuser.com/a/1007783 -X until we fix it.. -o call this from JNA? https://msdn.microsoft.com/en-us/library/windows/desktop/dn302122(v=vs.85).aspx -o or modify the manifest/app? https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx -o hidpi scaling via font changes? -o http://stackoverflow.com/a/34152675 -X hi-dpi support on Linux -X https://github.com/processing/processing/issues/4183 - -cleaning -X Contribution Manager does not show all libraries until filter cleared -X https://github.com/processing/processing/issues/4840 -X fixed in 3.2.4 - -unconfirmed +0258 (3.3.1) + + +awaiting confirmation (fixed in 3.3) X visual artifacts on Windows 10 when using menus _ https://github.com/processing/processing/issues/4700 X Broken characters in the Welcome Page and the Contribution Manager From 792fbe9c5025159c771b588de28a25279a86729b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 12 Feb 2017 14:44:12 -0500 Subject: [PATCH 272/917] add separate issue for cross-platform scaling --- core/todo.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index af6470bd17..e0d25ca5a5 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -2,6 +2,8 @@ high +_ implement sketch scaling into PApplet +_ https://github.com/processing/processing/issues/4897 _ Sketches on Windows don't take UI sizing into account _ https://github.com/processing/processing/issues/4894 _ Sketches on Linux don't take UI scaling into account From 3faaa37c6993cb6603e201cd126a56b9a981a592 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 13 Feb 2017 14:24:17 -0500 Subject: [PATCH 273/917] notes about confirmed fixes --- todo.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/todo.txt b/todo.txt index 0c84b65fd1..0f1a715154 100755 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,13 @@ 0258 (3.3.1) - +X add Jump to Declaration +X https://github.com/processing/processing/pull/4707 +X https://github.com/processing/processing/issues/4668 awaiting confirmation (fixed in 3.3) X visual artifacts on Windows 10 when using menus _ https://github.com/processing/processing/issues/4700 X Broken characters in the Welcome Page and the Contribution Manager -_ https://github.com/processing/processing/issues/4747 +X https://github.com/processing/processing/issues/4747 X looks like a failure to load the Source Sans font X what happens if font loading fails? X are there conflicts between version in lib and OS? @@ -16,6 +18,8 @@ _ https://github.com/processing/processing/issues/4853 X blank window on startup where the "Welcome" screen should be X this may be fixed (removed invokeLater() on startup), unconfirmed _ https://github.com/processing/processing/issues/3933 +X amazing blurry editor window +X https://github.com/processing/processing/issues/4892 _ Welcome screen doesn't size properly for HiDPI screens From bb58930e4ad62ff69b023b2fb42d728a40ec7654 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Wed, 15 Feb 2017 13:56:28 +0100 Subject: [PATCH 274/917] Make editor buttons nice when scaling UI --- app/src/processing/app/ui/EditorButton.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/processing/app/ui/EditorButton.java b/app/src/processing/app/ui/EditorButton.java index 0e848efb67..04dea5f011 100644 --- a/app/src/processing/app/ui/EditorButton.java +++ b/app/src/processing/app/ui/EditorButton.java @@ -112,6 +112,11 @@ public void paintComponent(Graphics g) { } else if (rollover) { image = rolloverImage; } + + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BICUBIC); + int dim = getSize().width; // width == height if (gradient != null) { //g.drawImage(gradient, 0, 0, DIM, DIM, this); From b5f58864158a089e7255ab8b3125bd090d4b7140 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Wed, 15 Feb 2017 14:01:16 +0100 Subject: [PATCH 275/917] Enable bicubic interpolation for possibly scaled components --- app/src/processing/app/ui/Toolkit.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index f82e2f81bb..771cde4031 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -717,6 +717,8 @@ static public Graphics2D prepareGraphics(Graphics g) { RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BICUBIC); if (Toolkit.isRetina()) { // Looks great on retina, not so great (with our font) on 1x g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, From b9920bebfd51f20006a83e50ae90d6e8ca40d705 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Wed, 15 Feb 2017 15:03:03 +0100 Subject: [PATCH 276/917] Fix preprocessing of code with double backslash in string or char literal Fixes #4903 --- java/src/processing/mode/java/pdex/SourceUtils.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/java/src/processing/mode/java/pdex/SourceUtils.java b/java/src/processing/mode/java/pdex/SourceUtils.java index cddfcff1c4..fecde5c940 100644 --- a/java/src/processing/mode/java/pdex/SourceUtils.java +++ b/java/src/processing/mode/java/pdex/SourceUtils.java @@ -266,6 +266,14 @@ static public void scrubCommentsAndStrings(StringBuilder p) { for (int i = 0; i <= length; i++) { char ch = (i < length) ? p.charAt(i) : 0; char pch = (i == 0) ? 0 : p.charAt(i-1); + // Get rid of double backslash immediately, otherwise + // the second backslash incorrectly triggers a new escape sequence + if (pch == '\\' && ch == '\\') { + p.setCharAt(i-1, ' '); + p.setCharAt(i, ' '); + pch = ' '; + ch = ' '; + } switch (state) { case OUT: switch (ch) { From e2c701f9c8287aebc3645eb2aa1989bf8a9cd143 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 15 Feb 2017 14:56:09 -0500 Subject: [PATCH 277/917] notes on fixes from Jakub --- todo.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/todo.txt b/todo.txt index 0f1a715154..91a0f161d6 100755 --- a/todo.txt +++ b/todo.txt @@ -3,6 +3,14 @@ X add Jump to Declaration X https://github.com/processing/processing/pull/4707 X https://github.com/processing/processing/issues/4668 +jakub +X Fix preprocessing of code with double backslash in string or char literal +X https://github.com/processing/processing/issues/4903 +X https://github.com/processing/processing/pull/4907 +X Ugly button images at 125% and 150% scaling on Windows +X https://github.com/processing/processing/issues/4901 +X https://github.com/processing/processing/pull/4906 + awaiting confirmation (fixed in 3.3) X visual artifacts on Windows 10 when using menus _ https://github.com/processing/processing/issues/4700 @@ -21,6 +29,11 @@ _ https://github.com/processing/processing/issues/3933 X amazing blurry editor window X https://github.com/processing/processing/issues/4892 +_ Ugly button images at 125% and 150% scaling on Windows +_ https://github.com/processing/processing/issues/4901 +_ Gap between tab headers and text area at 125% and 150% scaling on Windows +_ Math.ceil() helps +_ https://github.com/processing/processing/issues/4902 _ Welcome screen doesn't size properly for HiDPI screens _ https://github.com/processing/processing/issues/4896 From 34e503207204b3d71a76916b882d422ea4497d3f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 15 Feb 2017 14:57:39 -0500 Subject: [PATCH 278/917] these were the things just closed --- todo.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/todo.txt b/todo.txt index 91a0f161d6..33d7b9db1b 100755 --- a/todo.txt +++ b/todo.txt @@ -29,11 +29,9 @@ _ https://github.com/processing/processing/issues/3933 X amazing blurry editor window X https://github.com/processing/processing/issues/4892 -_ Ugly button images at 125% and 150% scaling on Windows -_ https://github.com/processing/processing/issues/4901 _ Gap between tab headers and text area at 125% and 150% scaling on Windows -_ Math.ceil() helps _ https://github.com/processing/processing/issues/4902 +_ Math.ceil() helps _ Welcome screen doesn't size properly for HiDPI screens _ https://github.com/processing/processing/issues/4896 From e2e500d6cc34d6bfb0158a7624a792a7071eefce Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 15 Feb 2017 17:50:39 -0500 Subject: [PATCH 279/917] clean up type warnings --- .../FileTextFieldTransferHandler.java | 3 ++- .../src/processing/app/tools/MovieMaker.java | 24 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/build/shared/tools/MovieMaker/src/ch/randelshofer/gui/datatransfer/FileTextFieldTransferHandler.java b/build/shared/tools/MovieMaker/src/ch/randelshofer/gui/datatransfer/FileTextFieldTransferHandler.java index 9e5ce36b06..adb7f01cbf 100644 --- a/build/shared/tools/MovieMaker/src/ch/randelshofer/gui/datatransfer/FileTextFieldTransferHandler.java +++ b/build/shared/tools/MovieMaker/src/ch/randelshofer/gui/datatransfer/FileTextFieldTransferHandler.java @@ -84,7 +84,8 @@ public boolean importData(JComponent comp, Transferable t) { } try { - List list = (List) t.getTransferData(DataFlavor.javaFileListFlavor); + List list = (List) + t.getTransferData(DataFlavor.javaFileListFlavor); if (list.size() > 0) { File file = (File) list.get(0); diff --git a/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java b/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java index e3f559f3fd..a482e1fbf2 100644 --- a/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java +++ b/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java @@ -533,10 +533,10 @@ private void createMovie(final File movieFile) { // --------------------------------- // Create the QuickTime movie // --------------------------------- - SwingWorker w = new SwingWorker() { + SwingWorker w = new SwingWorker() { @Override - protected Object doInBackground() { + protected Throwable doInBackground() { try { // Read image files File[] imgFiles = null; @@ -600,20 +600,18 @@ Dimension findSize(File[] imgFiles) { @Override protected void done() { - Object o; + Throwable t; try { - o = get(); + t = get(); } catch (Exception ex) { - o = ex; - } - if (o instanceof Throwable) { - Throwable t = (Throwable) o; - t.printStackTrace(); - JOptionPane.showMessageDialog(MovieMaker.this, - Language.text("movie_maker.error.movie_failed") + "\n" + (t.getMessage() == null ? t.toString() : t.getMessage()), - Language.text("movie_maker.error.sorry"), - JOptionPane.ERROR_MESSAGE); + t = ex; } + t.printStackTrace(); + JOptionPane.showMessageDialog(MovieMaker.this, + Language.text("movie_maker.error.movie_failed") + "\n" + + (t.getMessage() == null ? t.toString() : t.getMessage()), + Language.text("movie_maker.error.sorry"), + JOptionPane.ERROR_MESSAGE); createMovieButton.setEnabled(true); } }; From f98392136678e32dbc24d040af35582b3a50c5d3 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 15 Feb 2017 17:52:09 -0500 Subject: [PATCH 280/917] variable only used for execute(), remove declaration --- .../MovieMaker/src/processing/app/tools/MovieMaker.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java b/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java index a482e1fbf2..44abc680b6 100644 --- a/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java +++ b/build/shared/tools/MovieMaker/src/processing/app/tools/MovieMaker.java @@ -533,7 +533,7 @@ private void createMovie(final File movieFile) { // --------------------------------- // Create the QuickTime movie // --------------------------------- - SwingWorker w = new SwingWorker() { + new SwingWorker() { @Override protected Throwable doInBackground() { @@ -614,9 +614,7 @@ protected void done() { JOptionPane.ERROR_MESSAGE); createMovieButton.setEnabled(true); } - }; - w.execute(); - + }.execute(); }//GEN-LAST:event_createMovie From 1c218e2f2d4e31614411b3aef5ef5b79a00a923f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 15 Feb 2017 17:55:57 -0500 Subject: [PATCH 281/917] stumbled across spacing issues --- java/src/processing/mode/java/pdex/PDEX.java | 31 ++++++-------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/java/src/processing/mode/java/pdex/PDEX.java b/java/src/processing/mode/java/pdex/PDEX.java index 9dda7101e8..e155b381e3 100644 --- a/java/src/processing/mode/java/pdex/PDEX.java +++ b/java/src/processing/mode/java/pdex/PDEX.java @@ -23,7 +23,6 @@ import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; -import java.awt.event.ActionEvent; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.InputEvent; @@ -89,6 +88,7 @@ import static processing.mode.java.pdex.ASTUtils.*; + public class PDEX { private static final boolean SHOW_DEBUG_TREE = false; @@ -188,7 +188,6 @@ public void documentChanged(Document newDoc) { private class InspectMode { - boolean inspectModeEnabled; boolean isMouse1Down; @@ -279,9 +278,9 @@ public void keyReleased(KeyEvent e) { inspectModeEnabled = inspectModeEnabled && isHotkeyDown; } }); - } + void handleInspect() { int off = editor.getSelectionStart(); int tabIndex = editor.getSketch().getCurrentCodeIndex(); @@ -289,6 +288,7 @@ void handleInspect() { pps.whenDoneBlocking(ps -> handleInspect(ps, tabIndex, off)); } + // Thread: EDT void handleInspect(MouseEvent evt) { int off = editor.getJavaTextArea().xyToOffset(evt.getX(), evt.getY()); @@ -352,13 +352,10 @@ private void handleInspect(PreprocessedSketch ps, int tabIndex, int offset) { void dispose() { // Nothing to do } - } - - private static class ShowUsage { - + static private class ShowUsage { final JDialog window; final JTree tree; @@ -595,12 +592,10 @@ void dispose() { window.dispose(); } } - } - private static class ShowUsageTreeNode { - + static private class ShowUsageTreeNode { final int tabIndex; final int startTabOffset; final int stopTabOffset; @@ -902,7 +897,6 @@ void rename(PreprocessedSketch ps, IBinding binding, String newName) { int offsetDiff = precedingIntervals * intervalLengthDiff; editor.getTextArea().setCaretPosition(currentOffset + offsetDiff); - } @@ -911,16 +905,12 @@ void dispose() { window.dispose(); } } - } - - private static class DebugTree { - + static private class DebugTree { final JDialog window; final JTree tree; - final Consumer updateListener; @@ -1030,13 +1020,10 @@ public void postVisit(ASTNode node) { } }); } - } - - private static class ErrorChecker { - + static private class ErrorChecker { // Delay delivering error check result after last sketch change #2677 private final static long DELAY_BEFORE_UPDATE = 650; @@ -1181,6 +1168,7 @@ static private boolean isUndefinedTypeProblem(IProblem iproblem) { id == IProblem.UnresolvedVariable; } + static private boolean isMissingBraceProblem(IProblem iproblem) { switch (iproblem.getID()) { case IProblem.ParsingErrorInsertToComplete: { @@ -1197,7 +1185,7 @@ static private boolean isMissingBraceProblem(IProblem iproblem) { } - public static String[] getImportSuggestions(ClassPath cp, String className) { + static public String[] getImportSuggestions(ClassPath cp, String className) { RegExpResourceFilter regf = new RegExpResourceFilter( Pattern.compile(".*"), Pattern.compile("(.*\\$)?" + className + "\\.class", @@ -1224,6 +1212,5 @@ public static String[] getImportSuggestions(ClassPath cp, String className) { }) .toArray(String[]::new); } - } } From 635614965a213189d0261cbf5f7809d6e41bc740 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 13:07:30 +0100 Subject: [PATCH 282/917] Add --density sketch arg --- core/src/processing/core/PApplet.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 473e032e8b..46137db944 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -787,6 +787,8 @@ public class PApplet implements PConstants { */ static public final String ARGS_SKETCH_FOLDER = "--sketch-path"; + static public final String ARGS_DENSITY = "--density"; + /** * When run externally to a PdeEditor, * this is sent by the sketch when it quits. @@ -906,6 +908,7 @@ public PSurface getSurface() { // Unlike the others above, needs to be public to support // the pixelWidth and pixelHeight fields. public int pixelDensity = 1; + int suggestedDensity = -1; String outputPath; OutputStream outputStream; @@ -10367,6 +10370,7 @@ public void uncaughtException(Thread t, Throwable e) { // boolean fullScreen = false; boolean present = false; // boolean spanDisplays = false; + int density = -1; String param = null, value = null; String folder = calcSketchPath(); @@ -10409,6 +10413,15 @@ public void uncaughtException(Thread t, Throwable e) { } else if (param.equals(ARGS_LOCATION)) { location = parseInt(split(value, ',')); + + } else if (param.equals(ARGS_DENSITY)) { + density = parseInt(value, -1); + if (density == -1) { + System.err.println("Could not parse " + value + " for " + ARGS_DENSITY); + } else if (density != 1 && density != 2) { + density = -1; + System.err.println(ARGS_DENSITY + " should be 1 or 2"); + } } } else { @@ -10477,6 +10490,10 @@ public void uncaughtException(Thread t, Throwable e) { // (and most likely, from the PDE's preference setting). sketch.display = displayNum; + // Set the suggested density that is coming from command line + // (most likely set from the PDE based on a system DPI scaling) + sketch.suggestedDensity = density; + // For 3.0.1, moved this above handleSettings() so that loadImage() can be // used inside settings(). Sets a terrible precedent, but the alternative // of not being able to size a sketch to an image is driving people loopy. From c30503f0a07512cbd7b395ce238cc1a5e8914165 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 13:13:09 +0100 Subject: [PATCH 283/917] Return command line density arg value from displayDensity() --- core/src/processing/core/PApplet.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 46137db944..3c4849ee47 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -1143,7 +1143,7 @@ public int displayDensity() { /** * @param display the display number to check */ - static public int displayDensity(int display) { + public int displayDensity(int display) { if (PApplet.platform == PConstants.MACOSX) { // This should probably be reset each time there's a display change. // A 5-minute search didn't turn up any such event in the Java 7 API. @@ -1186,6 +1186,15 @@ static public int displayDensity(int display) { } } catch (Exception ignore) { } } + } else if (PApplet.platform == PConstants.WINDOWS || + PApplet.platform == PConstants.LINUX) { + if (suggestedDensity == -1) { + // TODO: detect and return DPI scaling using JNA; Windows has + // a system-wide value, not sure how it works on Linux + return 1; + } else if (suggestedDensity == 1 || suggestedDensity == 2) { + return suggestedDensity; + } } return 1; } From 15941f449e8721ff5e67fb2a3df76b547e83d462 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 13:24:09 +0100 Subject: [PATCH 284/917] Pass display density from PDE to sketches as a command line arg --- java/src/processing/mode/java/runner/Runner.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index 1223ee7521..65058b881e 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -24,6 +24,7 @@ import processing.app.*; import processing.app.exec.StreamRedirectThread; +import processing.app.ui.Toolkit; import processing.core.*; import processing.data.StringList; import processing.mode.java.JavaBuild; @@ -466,6 +467,10 @@ protected StringList getSketchParams(boolean present, String[] args) { // removed for 3.0a6 because it would break the args passed to sketches. params.append(PApplet.ARGS_SKETCH_FOLDER + "=" + build.getSketchPath()); + if (Toolkit.zoom(100) >= 200) { // Use 100 to bypass possible rounding in zoom() + params.append(PApplet.ARGS_DENSITY + "=2"); + } + params.append(build.getSketchClassName()); } // Add command-line arguments to be given to the sketch itself From 01f63221f1f164b689bb43860c5954d7b3ae62fb Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 16:13:23 +0100 Subject: [PATCH 285/917] pixelDensity (Java2D): scale window up --- core/src/processing/awt/PSurfaceAWT.java | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/core/src/processing/awt/PSurfaceAWT.java b/core/src/processing/awt/PSurfaceAWT.java index cd4649436a..6d642f9011 100644 --- a/core/src/processing/awt/PSurfaceAWT.java +++ b/core/src/processing/awt/PSurfaceAWT.java @@ -90,6 +90,8 @@ public class PSurfaceAWT extends PSurfaceNone { int sketchWidth; int sketchHeight; + int windowScaleFactor; + public PSurfaceAWT(PGraphics graphics) { //this.graphics = graphics; @@ -224,7 +226,7 @@ public void validate() { if (!oldSize.equals(newSize)) { // System.out.println("validate() render old=" + oldSize + " -> new=" + newSize); oldSize = newSize; - sketch.setSize(newSize.width, newSize.height); + sketch.setSize(newSize.width / windowScaleFactor, newSize.height / windowScaleFactor); // try { render(); // } catch (IllegalStateException ise) { @@ -423,8 +425,11 @@ public void initFrame(final PApplet sketch) {/*, int backgroundColor, sketch.displayWidth = screenRect.width; sketch.displayHeight = screenRect.height; - sketchWidth = sketch.sketchWidth(); - sketchHeight = sketch.sketchHeight(); + windowScaleFactor = PApplet.platform == PConstants.MACOSX ? + 1 : sketch.pixelDensity; + + sketchWidth = sketch.sketchWidth() * windowScaleFactor; + sketchHeight = sketch.sketchHeight() * windowScaleFactor; boolean fullScreen = sketch.sketchFullScreen(); // Removing the section below because sometimes people want to do the @@ -481,7 +486,7 @@ public void initFrame(final PApplet sketch) {/*, int backgroundColor, // http://dev.processing.org/bugs/show_bug.cgi?id=908 frame.add(canvas); - setSize(sketchWidth, sketchHeight); + setSize(sketchWidth / windowScaleFactor, sketchHeight / windowScaleFactor); /* if (fullScreen) { @@ -954,8 +959,8 @@ public void setSize(int wide, int high) { return; // unchanged, don't rebuild everything } - sketchWidth = wide; - sketchHeight = high; + sketchWidth = wide * windowScaleFactor; + sketchHeight = high * windowScaleFactor; // canvas.setSize(wide, high); // frame.setSize(wide, high); @@ -1142,8 +1147,9 @@ public void componentResized(ComponentEvent e) { // overall size of the window. Perhaps JFrame sets its coord // system so that (0, 0) is always the upper-left of the content // area. Which seems nice, but breaks any f*ing AWT-based code. - setSize(windowSize.width - currentInsets.left - currentInsets.right, - windowSize.height - currentInsets.top - currentInsets.bottom); + int w = windowSize.width - currentInsets.left - currentInsets.right; + int h = windowSize.height - currentInsets.top - currentInsets.bottom; + setSize(w / windowScaleFactor, h / windowScaleFactor); // correct the location when inset size changes setLocation(x - currentInsets.left, y - currentInsets.top); From ce9c2e2c54bc8abc48e769b4ec1d652411439053 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 16:13:53 +0100 Subject: [PATCH 286/917] pixelDensity (Java2D): set default transform --- core/src/processing/awt/PGraphicsJava2D.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/processing/awt/PGraphicsJava2D.java b/core/src/processing/awt/PGraphicsJava2D.java index 325563526e..5a1c8aca35 100644 --- a/core/src/processing/awt/PGraphicsJava2D.java +++ b/core/src/processing/awt/PGraphicsJava2D.java @@ -409,8 +409,6 @@ public void beginDraw() { checkSettings(); resetMatrix(); // reset model matrix vertexCount = 0; - - g2.scale(pixelDensity, pixelDensity); } @@ -2236,6 +2234,7 @@ public void shearY(float angle) { @Override public void resetMatrix() { g2.setTransform(new AffineTransform()); + g2.scale(pixelDensity, pixelDensity); } From c3f942852a2e401a27b09a655728dde1b517a4eb Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 16:15:36 +0100 Subject: [PATCH 287/917] pixelDensity (Java2D): scale mouse input --- core/src/processing/awt/PSurfaceAWT.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/processing/awt/PSurfaceAWT.java b/core/src/processing/awt/PSurfaceAWT.java index 6d642f9011..27c7b8e6be 100644 --- a/core/src/processing/awt/PSurfaceAWT.java +++ b/core/src/processing/awt/PSurfaceAWT.java @@ -1318,7 +1318,8 @@ protected void nativeMouseEvent(java.awt.event.MouseEvent nativeEvent) { sketch.postEvent(new MouseEvent(nativeEvent, nativeEvent.getWhen(), peAction, peModifiers, - nativeEvent.getX(), nativeEvent.getY(), + nativeEvent.getX() / windowScaleFactor, + nativeEvent.getY() / windowScaleFactor, peButton, peCount)); } From d336591f670a2a0536221f5ae4b1dbfcb9900576 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 17 Feb 2017 01:07:32 +0100 Subject: [PATCH 288/917] pixelDensity (FX): fix window size --- core/src/processing/javafx/PSurfaceFX.java | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index 8239c8f5b5..508040016f 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -22,6 +22,8 @@ package processing.javafx; +import com.sun.glass.ui.Screen; + import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; @@ -244,6 +246,13 @@ public void start(final Stage stage) { PApplet sketch = surface.sketch; + float renderScale = Screen.getMainScreen().getRenderScale(); + float uiScale = Screen.getMainScreen().getUIScale(); + if (sketch.pixelDensity == 2 && renderScale < 2) { + sketch.pixelDensity = 1; + System.err.println("pixelDensity(2) is not available for this display"); + } + // Use AWT display code, because FX orders screens in different way GraphicsDevice displayDevice = null; @@ -308,14 +317,14 @@ public void start(final Stage stage) { int sketchHeight = sketch.sketchHeight(); if (fullScreen || spanDisplays) { - sketchWidth = (int) screenRect.getWidth(); - sketchHeight = (int) screenRect.getHeight(); + sketchWidth = (int) (screenRect.getWidth() / uiScale); + sketchHeight = (int) (screenRect.getHeight() / uiScale); stage.initStyle(StageStyle.UNDECORATED); - stage.setX(screenRect.getMinX()); - stage.setY(screenRect.getMinY()); - stage.setWidth(screenRect.getWidth()); - stage.setHeight(screenRect.getHeight()); + stage.setX(screenRect.getMinX() / uiScale); + stage.setY(screenRect.getMinY() / uiScale); + stage.setWidth(screenRect.getWidth() / uiScale); + stage.setHeight(screenRect.getHeight() / uiScale); } Canvas canvas = surface.canvas; From 431596977abf82e148ba73f4f9ad12c2580dff7f Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 17 Feb 2017 01:08:54 +0100 Subject: [PATCH 289/917] pixelDensity (FX): fix updatePixels being low res --- core/src/processing/javafx/PGraphicsFX2D.java | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/core/src/processing/javafx/PGraphicsFX2D.java b/core/src/processing/javafx/PGraphicsFX2D.java index 52425e3c70..4e6e11da43 100644 --- a/core/src/processing/javafx/PGraphicsFX2D.java +++ b/core/src/processing/javafx/PGraphicsFX2D.java @@ -645,9 +645,27 @@ protected void flushPixels() { int mw = mx2 - mx1; int mh = my2 - my1; - PixelWriter pw = context.getPixelWriter(); - pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels, - mx1 + my1 * pixelWidth, pixelWidth); + if (pixelDensity == 1) { + PixelWriter pw = context.getPixelWriter(); + pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels, + mx1 + my1 * pixelWidth, pixelWidth); + } else { + // The only way to push all the pixels is to draw a scaled-down image + if (snapshotImage == null || + snapshotImage.getWidth() != pixelWidth || + snapshotImage.getHeight() != pixelHeight) { + snapshotImage = new WritableImage(pixelWidth, pixelHeight); + } + + PixelWriter pw = snapshotImage.getPixelWriter(); + pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels, + mx1 + my1 * pixelWidth, pixelWidth); + context.save(); + resetMatrix(); + context.scale(1d / pixelDensity, 1d / pixelDensity); + context.drawImage(snapshotImage, mx1, my1, mw, mh, mx1, my1, mw, mh); + context.restore(); + } } modified = false; @@ -2133,8 +2151,9 @@ public void loadPixels() { snapshotImage = new WritableImage(pixelWidth, pixelHeight); } - SnapshotParameters sp = new SnapshotParameters(); + SnapshotParameters sp = null; if (pixelDensity != 1) { + sp = new SnapshotParameters(); sp.setTransform(Transform.scale(pixelDensity, pixelDensity)); } snapshotImage = ((PSurfaceFX) surface).canvas.snapshot(sp, snapshotImage); From b5ec5f9eb3ce25d5c736ec349edf90e8b95d63f1 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 17 Feb 2017 13:37:20 +0100 Subject: [PATCH 290/917] pixelDensity (Java2D): fix set() clamping on wrong boundary --- core/src/processing/awt/PGraphicsJava2D.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/awt/PGraphicsJava2D.java b/core/src/processing/awt/PGraphicsJava2D.java index 5a1c8aca35..67d3d75e7d 100644 --- a/core/src/processing/awt/PGraphicsJava2D.java +++ b/core/src/processing/awt/PGraphicsJava2D.java @@ -2889,7 +2889,7 @@ protected void getImpl(int sourceX, int sourceY, @Override public void set(int x, int y, int argb) { - if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return; + if ((x < 0) || (y < 0) || (x >= pixelWidth) || (y >= pixelHeight)) return; // ((BufferedImage) image).setRGB(x, y, argb); getset[0] = argb; // WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster(); From 51dff7689968c5da7344b61d53e90359eaf8329f Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 17 Feb 2017 13:38:09 +0100 Subject: [PATCH 291/917] pixelDensity (Java2D): set modified to false after updatePixels() --- core/src/processing/awt/PGraphicsJava2D.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/awt/PGraphicsJava2D.java b/core/src/processing/awt/PGraphicsJava2D.java index 67d3d75e7d..22145cfaa8 100644 --- a/core/src/processing/awt/PGraphicsJava2D.java +++ b/core/src/processing/awt/PGraphicsJava2D.java @@ -2796,7 +2796,7 @@ public void updatePixels(int x, int y, int c, int d) { if (pixels != null) { getRaster().setDataElements(0, 0, pixelWidth, pixelHeight, pixels); } - modified = true; + modified = false; } From 38d671672d5e4a62eb7b751e9e80cdf2adad6fd0 Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 17 Feb 2017 18:47:44 +0100 Subject: [PATCH 292/917] ARM: Allow Raspberry Pi's Mesa GL driver to use up to 8 lights This caused register allocation issues before, but now this seem to be only still necessary for the binary GLES2 driver, where even enabling one more light (from 2 to 3) will make the shader compiler unhappy. Tested with 11.1.0-1+rpi1 on all P2D & P3D examples. --- core/src/processing/opengl/PGraphicsOpenGL.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index eeebcc9cc1..802114c9f5 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -6885,8 +6885,7 @@ protected void getGLParameters() { // overwrite the default shaders with vendor specific versions // if needed - if (OPENGL_RENDERER.equals("VideoCore IV HW") || // Broadcom's binary driver for Raspberry Pi - OPENGL_RENDERER.equals("Gallium 0.4 on VC4")) { // Mesa driver for same hardware + if (OPENGL_RENDERER.equals("VideoCore IV HW")) { // Mesa driver for same hardware defLightShaderVertURL = PGraphicsOpenGL.class.getResource("/processing/opengl/shaders/LightVert-vc4.glsl"); defTexlightShaderVertURL = From eb47dea9fc5139e651481d7f59e4a1c5b37d58c0 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 17 Feb 2017 17:31:04 -0500 Subject: [PATCH 293/917] notes from github updates --- core/todo.txt | 8 ++++++++ todo.txt | 2 ++ 2 files changed, 10 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index e0d25ca5a5..423cccbe48 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,6 +1,14 @@ 0258 (3.3.1) +gohai +X Fix MeshTweening vertex shader +X https://github.com/processing/processing-docs/issues/523 +X https://github.com/processing/processing-docs/pull/524 +X ARM: Allow Raspberry Pi's Mesa GL driver to use up to 8 lights +X https://github.com/processing/processing/pull/4915 + + high _ implement sketch scaling into PApplet _ https://github.com/processing/processing/issues/4897 diff --git a/todo.txt b/todo.txt index 33d7b9db1b..15bbe67d03 100755 --- a/todo.txt +++ b/todo.txt @@ -2,6 +2,8 @@ X add Jump to Declaration X https://github.com/processing/processing/pull/4707 X https://github.com/processing/processing/issues/4668 +_ Small tooltip text on high-dpi screens +_ https://github.com/processing/processing/issues/4914 jakub X Fix preprocessing of code with double backslash in string or char literal From 8d69455511a590a6dfdd3df651a81ace6791b04f Mon Sep 17 00:00:00 2001 From: gohai Date: Sat, 18 Feb 2017 18:48:05 +0100 Subject: [PATCH 294/917] Report more error conditions in validateFramebuffer --- core/src/processing/opengl/PGL.java | 12 +++++++++++- core/src/processing/opengl/PJOGL.java | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index 72d6c2ef7f..3dd37191f0 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -2064,12 +2064,21 @@ protected boolean validateFramebuffer() { } else if (status == FRAMEBUFFER_INCOMPLETE_FORMATS) { System.err.println(String.format(FRAMEBUFFER_ERROR, "incomplete formats")); + } else if (status == FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER) { + System.err.println(String.format(FRAMEBUFFER_ERROR, + "incomplete draw buffer")); + } else if (status == FRAMEBUFFER_INCOMPLETE_READ_BUFFER) { + System.err.println(String.format(FRAMEBUFFER_ERROR, + "incomplete read buffer")); + } else if (status == FRAMEBUFFER_INCOMPLETE_MULTISAMPLE) { + System.err.println(String.format(FRAMEBUFFER_ERROR, + "incomplete multisample buffer")); } else if (status == FRAMEBUFFER_UNSUPPORTED) { System.err.println(String.format(FRAMEBUFFER_ERROR, "framebuffer unsupported")); } else { System.err.println(String.format(FRAMEBUFFER_ERROR, - "unknown error")); + "unknown error " + status)); } return false; } @@ -2991,6 +3000,7 @@ protected interface FontOutline { public static int FRAMEBUFFER_INCOMPLETE_FORMATS; public static int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER; public static int FRAMEBUFFER_INCOMPLETE_READ_BUFFER; + public static int FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; public static int FRAMEBUFFER_UNSUPPORTED; public static int FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE; diff --git a/core/src/processing/opengl/PJOGL.java b/core/src/processing/opengl/PJOGL.java index 9c579032e9..3f4b394b5b 100644 --- a/core/src/processing/opengl/PJOGL.java +++ b/core/src/processing/opengl/PJOGL.java @@ -982,6 +982,7 @@ public void next() { FRAMEBUFFER_INCOMPLETE_FORMATS = GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS; FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER; FRAMEBUFFER_INCOMPLETE_READ_BUFFER = GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER; + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = GL.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; FRAMEBUFFER_UNSUPPORTED = GL.GL_FRAMEBUFFER_UNSUPPORTED; FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE; From 739cf0edbfb96739e2c436edbd1bd92dd320a0c1 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 18 Feb 2017 13:24:23 -0500 Subject: [PATCH 295/917] improve sum() functions in processing.data --- core/src/processing/data/FloatDict.java | 26 +++++++++++++++++++++---- core/src/processing/data/FloatList.java | 18 ++++++++++++++--- core/src/processing/data/IntDict.java | 26 +++++++++++++++++++++---- core/src/processing/data/IntList.java | 18 ++++++++++++++--- core/todo.txt | 5 +++++ 5 files changed, 79 insertions(+), 14 deletions(-) diff --git a/core/src/processing/data/FloatDict.java b/core/src/processing/data/FloatDict.java index 81bbd99a60..dbb89eceef 100644 --- a/core/src/processing/data/FloatDict.java +++ b/core/src/processing/data/FloatDict.java @@ -522,6 +522,27 @@ public float maxValue() { } + public float sum() { + double amount = sumDouble(); + if (amount > Float.MAX_VALUE) { + throw new RuntimeException("sum() exceeds " + Float.MAX_VALUE + ", use sumDouble()"); + } + if (amount < -Float.MAX_VALUE) { + throw new RuntimeException("sum() lower than " + -Float.MAX_VALUE + ", use sumDouble()"); + } + return (float) amount; + } + + + public double sumDouble() { + double sum = 0; + for (int i = 0; i < count; i++) { + sum += values[i]; + } + return sum; + } + + public int index(String what) { Integer found = indices.get(what); return (found == null) ? -1 : found.intValue(); @@ -708,10 +729,7 @@ public void swap(int a, int b) { * @return a FloatDict with the original keys, mapped to their pct of the total */ public FloatDict getPercent() { - double sum = 0; - for (int i = 0; i < count; i++) { - sum += values[i]; - } + double sum = sum(); FloatDict outgoing = new FloatDict(); for (int i = 0; i < size(); i++) { double percent = value(i) / sum; diff --git a/core/src/processing/data/FloatList.java b/core/src/processing/data/FloatList.java index c3ee4c2870..a8d190ec49 100644 --- a/core/src/processing/data/FloatList.java +++ b/core/src/processing/data/FloatList.java @@ -627,11 +627,23 @@ public int maxIndex() { public float sum() { - double outgoing = 0; + double amount = sumDouble(); + if (amount > Float.MAX_VALUE) { + throw new RuntimeException("sum() exceeds " + Float.MAX_VALUE + ", use sumDouble()"); + } + if (amount < -Float.MAX_VALUE) { + throw new RuntimeException("sum() lower than " + -Float.MAX_VALUE + ", use sumDouble()"); + } + return (float) amount; + } + + + public double sumDouble() { + double sum = 0; for (int i = 0; i < count; i++) { - outgoing += data[i]; + sum += data[i]; } - return (float) outgoing; + return sum; } diff --git a/core/src/processing/data/IntDict.java b/core/src/processing/data/IntDict.java index 57d045d4cd..e3f5805b93 100644 --- a/core/src/processing/data/IntDict.java +++ b/core/src/processing/data/IntDict.java @@ -508,6 +508,27 @@ public int maxValue() { } + public int sum() { + long amount = sumLong(); + if (amount > Integer.MAX_VALUE) { + throw new RuntimeException("sum() exceeds " + Integer.MAX_VALUE + ", use sumLong()"); + } + if (amount < Integer.MIN_VALUE) { + throw new RuntimeException("sum() less than " + Integer.MIN_VALUE + ", use sumLong()"); + } + return (int) amount; + } + + + public long sumLong() { + long sum = 0; + for (int i = 0; i < count; i++) { + sum += values[i]; + } + return sum; + } + + public int index(String what) { Integer found = indices.get(what); return (found == null) ? -1 : found.intValue(); @@ -676,10 +697,7 @@ public void swap(int a, int b) { * @return an IntDict with the original keys, mapped to their pct of the total */ public FloatDict getPercent() { - double sum = 0; - for (int i = 0; i < count; i++) { - sum += values[i]; - } + double sum = sum(); // a little more accuracy FloatDict outgoing = new FloatDict(); for (int i = 0; i < size(); i++) { double percent = value(i) / sum; diff --git a/core/src/processing/data/IntList.java b/core/src/processing/data/IntList.java index 2d833dcf01..fda738c546 100644 --- a/core/src/processing/data/IntList.java +++ b/core/src/processing/data/IntList.java @@ -596,11 +596,23 @@ public int maxIndex() { public int sum() { - int outgoing = 0; + long amount = sumLong(); + if (amount > Integer.MAX_VALUE) { + throw new RuntimeException("sum() exceeds " + Integer.MAX_VALUE + ", use sumLong()"); + } + if (amount < Integer.MIN_VALUE) { + throw new RuntimeException("sum() less than " + Integer.MIN_VALUE + ", use sumLong()"); + } + return (int) amount; + } + + + public long sumLong() { + long sum = 0; for (int i = 0; i < count; i++) { - outgoing += data[i]; + sum += data[i]; } - return outgoing; + return sum; } diff --git a/core/todo.txt b/core/todo.txt index 423cccbe48..5441472807 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,4 +1,9 @@ 0258 (3.3.1) +X improve sum() functions in processing.data +X add sum() to IntDict and FloatDict +X add sumLong() to IntList, IntDict (to handle cases outside integer range) +X add sumDouble() to FloatList, FloatDict (to handle outside float range) +X throw exception when using sum() with numbers that are too large or small gohai From d5d4fa603d69a349cc46325e360f0f532cbd4b7f Mon Sep 17 00:00:00 2001 From: gohai Date: Sat, 18 Feb 2017 19:43:00 +0100 Subject: [PATCH 296/917] Make validateFramebuffer match latest Khronos doc for GL4 Suggested by @JakubValtar --- core/src/processing/opengl/PGL.java | 14 +++++++++++--- core/src/processing/opengl/PJOGL.java | 5 ++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index 3dd37191f0..3a1490a343 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -2052,6 +2052,9 @@ protected boolean validateFramebuffer() { int status = checkFramebufferStatus(FRAMEBUFFER); if (status == FRAMEBUFFER_COMPLETE) { return true; + } else if (status == FRAMEBUFFER_UNDEFINED) { + System.err.println(String.format(FRAMEBUFFER_ERROR, + "framebuffer undefined")); } else if (status == FRAMEBUFFER_INCOMPLETE_ATTACHMENT) { System.err.println(String.format(FRAMEBUFFER_ERROR, "incomplete attachment")); @@ -2070,12 +2073,15 @@ protected boolean validateFramebuffer() { } else if (status == FRAMEBUFFER_INCOMPLETE_READ_BUFFER) { System.err.println(String.format(FRAMEBUFFER_ERROR, "incomplete read buffer")); + } else if (status == FRAMEBUFFER_UNSUPPORTED) { + System.err.println(String.format(FRAMEBUFFER_ERROR, + "framebuffer unsupported")); } else if (status == FRAMEBUFFER_INCOMPLETE_MULTISAMPLE) { System.err.println(String.format(FRAMEBUFFER_ERROR, "incomplete multisample buffer")); - } else if (status == FRAMEBUFFER_UNSUPPORTED) { + } else if (status == FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS) { System.err.println(String.format(FRAMEBUFFER_ERROR, - "framebuffer unsupported")); + "incomplete layer targets")); } else { System.err.println(String.format(FRAMEBUFFER_ERROR, "unknown error " + status)); @@ -2994,14 +3000,16 @@ protected interface FontOutline { public static int DEPTH_STENCIL; public static int FRAMEBUFFER_COMPLETE; + public static int FRAMEBUFFER_UNDEFINED; public static int FRAMEBUFFER_INCOMPLETE_ATTACHMENT; public static int FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; public static int FRAMEBUFFER_INCOMPLETE_DIMENSIONS; public static int FRAMEBUFFER_INCOMPLETE_FORMATS; public static int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER; public static int FRAMEBUFFER_INCOMPLETE_READ_BUFFER; - public static int FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; public static int FRAMEBUFFER_UNSUPPORTED; + public static int FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; + public static int FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; public static int FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE; public static int FRAMEBUFFER_ATTACHMENT_OBJECT_NAME; diff --git a/core/src/processing/opengl/PJOGL.java b/core/src/processing/opengl/PJOGL.java index 3f4b394b5b..b02d1b30cf 100644 --- a/core/src/processing/opengl/PJOGL.java +++ b/core/src/processing/opengl/PJOGL.java @@ -45,6 +45,7 @@ import com.jogamp.opengl.GL2ES3; import com.jogamp.opengl.GL2GL3; import com.jogamp.opengl.GL3ES3; +import com.jogamp.opengl.GL3; import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLCapabilitiesImmutable; @@ -976,14 +977,16 @@ public void next() { DEPTH_STENCIL = GL.GL_DEPTH_STENCIL; FRAMEBUFFER_COMPLETE = GL.GL_FRAMEBUFFER_COMPLETE; + FRAMEBUFFER_UNDEFINED = GL3.GL_FRAMEBUFFER_UNDEFINED; FRAMEBUFFER_INCOMPLETE_ATTACHMENT = GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; FRAMEBUFFER_INCOMPLETE_DIMENSIONS = GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; FRAMEBUFFER_INCOMPLETE_FORMATS = GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS; FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER; FRAMEBUFFER_INCOMPLETE_READ_BUFFER = GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER; - FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = GL.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; FRAMEBUFFER_UNSUPPORTED = GL.GL_FRAMEBUFFER_UNSUPPORTED; + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = GL.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; + FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE; FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME; From f2d00e5dba249c2b6c2facc506ecc20ed9f7031f Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 18 Feb 2017 19:11:17 +0100 Subject: [PATCH 297/917] pixelDensity (OpenGL): fix pixel operations --- .../processing/opengl/PGraphicsOpenGL.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index eeebcc9cc1..6ab34bf161 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -637,6 +637,9 @@ public void setSize(int iwidth, int iheight) { height = iheight; updatePixelSize(); + texture = null; + ptexture = null; + // init perspective projection based on new dimensions defCameraFOV = 60 * DEG_TO_RAD; // at least for now defCameraX = width / 2.0f; @@ -5417,30 +5420,29 @@ protected void readPixels() { protected void drawPixels(int x, int y, int w, int h) { - int f = (int)pgl.getPixelScale(); - int len = f * w * f * h; + int len = w * h; if (nativePixels == null || nativePixels.length < len) { nativePixels = new int[len]; nativePixelBuffer = PGL.allocateIntBuffer(nativePixels); } try { - if (0 < x || 0 < y || w < width || h < height) { + if (0 < x || 0 < y || w < pixelWidth || h < pixelHeight) { // The pixels to be copied to the texture need to be consecutive, and // they are not in the pixels array, so putting each row one after // another in nativePixels. - int offset0 = f * (y * width + x); + int offset0 = y * pixelWidth + x; int offset1 = 0; - for (int yc = f * y; yc < f * (y + h); yc++) { - System.arraycopy(pixels, offset0, nativePixels, offset1, f * w); - offset0 += f * width; - offset1 += f * w; + for (int yc = y; yc < y + h; yc++) { + System.arraycopy(pixels, offset0, nativePixels, offset1, w); + offset0 += pixelWidth; + offset1 += w; } } else { PApplet.arrayCopy(pixels, 0, nativePixels, 0, len); } - PGL.javaToNativeARGB(nativePixels, f * w, f * h); + PGL.javaToNativeARGB(nativePixels, w, h); } catch (ArrayIndexOutOfBoundsException e) { } PGL.putIntArray(nativePixelBuffer, nativePixels); @@ -5464,10 +5466,10 @@ protected void drawPixels(int x, int y, int w, int h) { // (off)screen buffer. // First, copy the pixels to the texture. We don't need to invert the // pixel copy because the texture will be drawn inverted. - int tw = PApplet.min(texture.glWidth - f * x, f * w); - int th = PApplet.min(texture.glHeight - f * y, f * h); + int tw = PApplet.min(texture.glWidth - x, w); + int th = PApplet.min(texture.glHeight - y, h); pgl.copyToTexture(texture.glTarget, texture.glFormat, texture.glName, - f * x, f * y, tw, th, nativePixelBuffer); + x, y, tw, th, nativePixelBuffer); beginPixelsOp(OP_WRITE); drawTexture(x, y, w, h); endPixelsOp(); @@ -5476,7 +5478,7 @@ protected void drawPixels(int x, int y, int w, int h) { // currently drawing to. Because the texture is invertex along Y, we // need to reflect that in the vertical arguments. pgl.copyToTexture(texture.glTarget, texture.glFormat, texture.glName, - f * x, f * (height - (y + h)), f * w, f * h, nativePixelBuffer); + x, pixelHeight - (y + h), w, h, nativePixelBuffer); } } @@ -5960,9 +5962,9 @@ protected void drawTexture(int x, int y, int w, int h) { pgl.disable(PGL.BLEND); pgl.drawTexture(texture.glTarget, texture.glName, texture.glWidth, texture.glHeight, - 0, 0, width, height, + 0, 0, pixelWidth, pixelHeight, 1, x, y, x + w, y + h, - x, height - (y + h), x + w, height - y); + x, pixelHeight - (y + h), x + w, pixelHeight - y); pgl.enable(PGL.BLEND); } } From 8faf547aed047fb8ba0875660b32924d3f283631 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 18 Feb 2017 20:28:06 +0100 Subject: [PATCH 298/917] pixelDensity (OpenGL): update sketch pixel size when display density changes --- core/src/processing/opengl/PGraphicsOpenGL.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 6ab34bf161..2a03b88bc3 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -695,6 +695,10 @@ protected void updatePixelSize() { float f = pgl.getPixelScale(); pixelWidth = (int)(width * f); pixelHeight = (int)(height * f); + if (primaryGraphics) { + parent.pixelWidth = pixelWidth; + parent.pixelHeight = pixelHeight; + } } From 1ea9ff1fb07d9ef8f91c95f71f44b38a0814d68a Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 18 Feb 2017 20:28:38 +0100 Subject: [PATCH 299/917] pixelDensity (OpenGL): make sure sketch pixel size is initialized --- core/src/processing/opengl/PSurfaceJOGL.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index b314ad4511..0649e389e9 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -390,6 +390,8 @@ protected void initWindow() { sketchHeight = screenRect.height; } + sketch.setSize(sketchWidth, sketchHeight); + float[] reqSurfacePixelScale; if (graphics.is2X()) { // Retina From 70579e1df32b90409a151e889b8b553b7004304f Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 18 Feb 2017 20:29:59 +0100 Subject: [PATCH 300/917] pixelDensity (OpenGL): size sketch and graphics when density changes --- core/src/processing/opengl/PSurfaceJOGL.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 0649e389e9..90b3526dc9 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -816,15 +816,15 @@ public void run() { public void setSize(final int width, final int height) { - if (width == sketch.width && height == sketch.height) { - return; - } + if (pgl.presentMode()) return; + + sketchWidth = width; + sketchHeight = height; + + sketch.setSize(width, height); + graphics.setSize(width, height); - if (!pgl.presentMode()) { - sketch.setSize(width, height); - sketchWidth = width; - sketchHeight = height; - graphics.setSize(width, height); + if (window.getWidth() != width || window.getHeight() != height) { window.setSize(width, height); } } From 5d3d9aaedff63087f4d6b74f42ad84d231accd13 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 18 Feb 2017 21:28:09 +0100 Subject: [PATCH 301/917] pixelDensity (OpenGL): scale window and mouse input --- core/src/processing/opengl/PSurfaceJOGL.java | 54 +++++++------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 90b3526dc9..7811cd733d 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -110,6 +110,8 @@ public class PSurfaceJOGL implements PSurface { protected NewtCanvasAWT canvas; + protected int windowScaleFactor; + protected float[] currentPixelScale = {0, 0}; protected boolean external = false; @@ -331,6 +333,8 @@ protected void initWindow() { // window = GLWindow.create(displayDevice.getScreen(), pgl.getCaps()); // } + windowScaleFactor = PApplet.platform == PConstants.MACOSX ? + 1 : sketch.pixelDensity; boolean spanDisplays = sketch.sketchDisplay() == PConstants.SPAN; screenRect = spanDisplays ? @@ -386,14 +390,14 @@ protected void initWindow() { */ if (fullScreen || spanDisplays) { - sketchWidth = screenRect.width; - sketchHeight = screenRect.height; + sketchWidth = screenRect.width / windowScaleFactor; + sketchHeight = screenRect.height / windowScaleFactor; } sketch.setSize(sketchWidth, sketchHeight); float[] reqSurfacePixelScale; - if (graphics.is2X()) { + if (graphics.is2X() && PApplet.platform == PConstants.MACOSX) { // Retina reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; @@ -403,7 +407,7 @@ protected void initWindow() { ScalableSurface.IDENTITY_PIXELSCALE }; } window.setSurfaceScale(reqSurfacePixelScale); - window.setSize(sketchWidth, sketchHeight); + window.setSize(sketchWidth * windowScaleFactor, sketchHeight * windowScaleFactor); window.setResizable(false); setSize(sketchWidth, sketchHeight); sketchX = displayDevice.getViewportInWindowUnits().getX(); @@ -825,20 +829,20 @@ public void setSize(final int width, final int height) { graphics.setSize(width, height); if (window.getWidth() != width || window.getHeight() != height) { - window.setSize(width, height); + window.setSize(width * windowScaleFactor, height * windowScaleFactor); } } public float getPixelScale() { - if (graphics.is2X()) { + float result = graphics.pixelDensity; + if (graphics.pixelDensity == 2 && PApplet.platform == PConstants.MACOSX) { // Even if the graphics are retina, the user might have moved the window // into a non-retina monitor, so we need to check window.getCurrentSurfaceScale(currentPixelScale); - return currentPixelScale[0]; - } else { - return 1; + result = currentPixelScale[0]; } + return result; } @@ -941,32 +945,10 @@ public void init(GLAutoDrawable drawable) { } public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { -// int c = graphics.backgroundColor; -// pgl.clearColor(((c >> 16) & 0xff) / 255f, -// ((c >> 8) & 0xff) / 255f, -// ((c >> 0) & 0xff) / 255f, -// ((c >> 24) & 0xff) / 255f); -// pgl.clear(PGL.COLOR_BUFFER_BIT); pgl.resetFBOLayer(); -// final float[] valReqSurfacePixelScale = window.getRequestedSurfaceScale(new float[2]); - window.getCurrentSurfaceScale(currentPixelScale); -// final float[] nativeSurfacePixelScale = window.getMaximumSurfaceScale(new float[2]); -// System.err.println("[set PixelScale post]: "+ -// valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+ -// hasSurfacePixelScale[0]+"x"+hasSurfacePixelScale[1]+" (has), "+ -// nativeSurfacePixelScale[0]+"x"+nativeSurfacePixelScale[1]+" (native)"); - - - - -// System.out.println("reshape: " + w + ", " + h); pgl.getGL(drawable); -// if (!graphics.is2X() && 1 < hasSurfacePixelScale[0]) { -// setSize(w/2, h/2); -// } else { -// setSize(w, h); -// } - setSize((int)(w/currentPixelScale[0]), (int)(h/currentPixelScale[1])); + int pixelScale = (int) getPixelScale(); + setSize(w / pixelScale, h / pixelScale); } } @@ -1114,9 +1096,9 @@ protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent, peCount = nativeEvent.getClickCount(); } - window.getCurrentSurfaceScale(currentPixelScale); - int sx = (int)(nativeEvent.getX()/currentPixelScale[0]); - int sy = (int)(nativeEvent.getY()/currentPixelScale[1]); + int pixelScale = (int) getPixelScale(); + int sx = nativeEvent.getX() / pixelScale; + int sy = nativeEvent.getY() / pixelScale; int mx = sx; int my = sy; From e94d290f41aa1f1b4ae0be62bbfbbba9061681a6 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 00:18:01 +0100 Subject: [PATCH 302/917] pixelDensity (FX): draw 2x images properly --- core/src/processing/javafx/PGraphicsFX2D.java | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/core/src/processing/javafx/PGraphicsFX2D.java b/core/src/processing/javafx/PGraphicsFX2D.java index 4e6e11da43..157540fed5 100644 --- a/core/src/processing/javafx/PGraphicsFX2D.java +++ b/core/src/processing/javafx/PGraphicsFX2D.java @@ -1031,8 +1031,8 @@ protected void imageImpl(PImage who, // Nuke the cache if the image was resized if (cash != null) { - if (who.width != cash.image.getWidth() || - who.height != cash.image.getHeight()) { + if (who.pixelWidth != cash.image.getWidth() || + who.pixelHeight != cash.image.getHeight()) { cash = null; } } @@ -1059,12 +1059,17 @@ protected void imageImpl(PImage who, // This might be a PGraphics that hasn't been drawn to yet. // Can't just bail because the cache has been created above. // https://github.com/processing/processing/issues/2208 - who.pixels = new int[who.width * who.height]; + who.pixels = new int[who.pixelWidth * who.pixelHeight]; } cash.update(who, tint, tintColor); who.setModified(false); } + u1 *= who.pixelDensity; + v1 *= who.pixelDensity; + u2 *= who.pixelDensity; + v2 *= who.pixelDensity; + context.drawImage(((ImageCache) getCache(who)).image, u1, v1, u2-u1, v2-v1, x1, y1, x2-x1, y2-y1); @@ -1105,14 +1110,14 @@ public void update(PImage source, boolean tint, int tintColor) { // BufferedImage.TYPE_INT_ARGB); // } if (image == null) { - image = new WritableImage(source.width, source.height); + image = new WritableImage(source.pixelWidth, source.pixelHeight); } //WritableRaster wr = image.getRaster(); PixelWriter pw = image.getPixelWriter(); if (tint) { - if (tintedTemp == null || tintedTemp.length != source.width) { - tintedTemp = new int[source.width]; + if (tintedTemp == null || tintedTemp.length != source.pixelWidth) { + tintedTemp = new int[source.pixelWidth]; } int a2 = (tintColor >> 24) & 0xff; // System.out.println("tint color is " + a2); @@ -1126,8 +1131,8 @@ public void update(PImage source, boolean tint, int tintColor) { // The target image is opaque, meaning that the source image has no // alpha (is not ARGB), and the tint has no alpha. int index = 0; - for (int y = 0; y < source.height; y++) { - for (int x = 0; x < source.width; x++) { + for (int y = 0; y < source.pixelHeight; y++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int r1 = (argb1 >> 16) & 0xff; int g1 = (argb1 >> 8) & 0xff; @@ -1142,7 +1147,7 @@ public void update(PImage source, boolean tint, int tintColor) { (((b2 * b1) & 0xff00) >> 8); } //wr.setDataElements(0, y, source.width, 1, tintedTemp); - pw.setPixels(0, y, source.width, 1, argbFormat, tintedTemp, 0, source.width); + pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelWidth); } // could this be any slower? // float[] scales = { tintR, tintG, tintB }; @@ -1156,19 +1161,19 @@ public void update(PImage source, boolean tint, int tintColor) { (tintColor & 0xffffff) == 0xffffff) { int hi = tintColor & 0xff000000; int index = 0; - for (int y = 0; y < source.height; y++) { - for (int x = 0; x < source.width; x++) { + for (int y = 0; y < source.pixelHeight; y++) { + for (int x = 0; x < source.pixelWidth; x++) { tintedTemp[x] = hi | (source.pixels[index++] & 0xFFFFFF); } //wr.setDataElements(0, y, source.width, 1, tintedTemp); - pw.setPixels(0, y, source.width, 1, argbFormat, tintedTemp, 0, source.width); + pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelHeight); } } else { int index = 0; - for (int y = 0; y < source.height; y++) { + for (int y = 0; y < source.pixelHeight; y++) { if (source.format == RGB) { int alpha = tintColor & 0xFF000000; - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int r1 = (argb1 >> 16) & 0xff; int g1 = (argb1 >> 8) & 0xff; @@ -1179,7 +1184,7 @@ public void update(PImage source, boolean tint, int tintColor) { (((b2 * b1) & 0xff00) >> 8); } } else if (source.format == ARGB) { - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int a1 = (argb1 >> 24) & 0xff; int r1 = (argb1 >> 16) & 0xff; @@ -1193,14 +1198,14 @@ public void update(PImage source, boolean tint, int tintColor) { } } else if (source.format == ALPHA) { int lower = tintColor & 0xFFFFFF; - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int a1 = source.pixels[index++]; tintedTemp[x] = (((a2 * a1) & 0xff00) << 16) | lower; } } //wr.setDataElements(0, y, source.width, 1, tintedTemp); - pw.setPixels(0, y, source.width, 1, argbFormat, tintedTemp, 0, source.width); + pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelWidth); } } // Not sure why ARGB images take the scales in this order... @@ -1222,8 +1227,8 @@ public void update(PImage source, boolean tint, int tintColor) { // If no tint, just shove the pixels on in there verbatim //wr.setDataElements(0, 0, source.width, source.height, source.pixels); //System.out.println("moving the big one"); - pw.setPixels(0, 0, source.width, source.height, - argbFormat, source.pixels, 0, source.width); + pw.setPixels(0, 0, source.pixelWidth, source.pixelHeight, + argbFormat, source.pixels, 0, source.pixelWidth); } this.tinted = tint; this.tintedColor = tintColor; From 03005aa5bd86151a890c6a4ca96cffb69dd4ae07 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 01:41:23 +0100 Subject: [PATCH 303/917] pixelDensity (Java2D): fix pixel operations --- core/src/processing/awt/PGraphicsJava2D.java | 61 ++++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/core/src/processing/awt/PGraphicsJava2D.java b/core/src/processing/awt/PGraphicsJava2D.java index 22145cfaa8..0143772b7c 100644 --- a/core/src/processing/awt/PGraphicsJava2D.java +++ b/core/src/processing/awt/PGraphicsJava2D.java @@ -1571,8 +1571,8 @@ protected void imageImpl(PImage who, // Nuke the cache if the image was resized if (cash != null) { - if (who.width != cash.image.getWidth() || - who.height != cash.image.getHeight()) { + if (who.pixelWidth != cash.image.getWidth() || + who.pixelHeight != cash.image.getHeight()) { cash = null; } } @@ -1599,12 +1599,17 @@ protected void imageImpl(PImage who, // This might be a PGraphics that hasn't been drawn to yet. // Can't just bail because the cache has been created above. // https://github.com/processing/processing/issues/2208 - who.pixels = new int[who.width * who.height]; + who.pixels = new int[who.pixelWidth * who.pixelHeight]; } cash.update(who, tint, tintColor); who.setModified(false); } + u1 *= who.pixelDensity; + v1 *= who.pixelDensity; + u2 *= who.pixelDensity; + v2 *= who.pixelDensity; + g2.drawImage(((ImageCache) getCache(who)).image, (int) x1, (int) y1, (int) x2, (int) y2, u1, v1, u2, v2, null); @@ -1672,14 +1677,14 @@ public void update(PImage source, boolean tint, int tintColor) { // in the alpha channel when drawn to the screen. // https://github.com/processing/processing/issues/2030 if (image == null) { - image = new BufferedImage(source.width, source.height, + image = new BufferedImage(source.pixelWidth, source.pixelHeight, BufferedImage.TYPE_INT_ARGB); } WritableRaster wr = image.getRaster(); if (tint) { - if (tintedTemp == null || tintedTemp.length != source.width) { - tintedTemp = new int[source.width]; + if (tintedTemp == null || tintedTemp.length != source.pixelWidth) { + tintedTemp = new int[source.pixelHeight]; } int a2 = (tintColor >> 24) & 0xff; // System.out.println("tint color is " + a2); @@ -1693,8 +1698,8 @@ public void update(PImage source, boolean tint, int tintColor) { // The target image is opaque, meaning that the source image has no // alpha (is not ARGB), and the tint has no alpha. int index = 0; - for (int y = 0; y < source.height; y++) { - for (int x = 0; x < source.width; x++) { + for (int y = 0; y < source.pixelHeight; y++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int r1 = (argb1 >> 16) & 0xff; int g1 = (argb1 >> 8) & 0xff; @@ -1708,7 +1713,7 @@ public void update(PImage source, boolean tint, int tintColor) { ((g2 * g1) & 0xff00) | (((b2 * b1) & 0xff00) >> 8); } - wr.setDataElements(0, y, source.width, 1, tintedTemp); + wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp); } // could this be any slower? // float[] scales = { tintR, tintG, tintB }; @@ -1722,18 +1727,18 @@ public void update(PImage source, boolean tint, int tintColor) { (tintColor & 0xffffff) == 0xffffff) { int hi = tintColor & 0xff000000; int index = 0; - for (int y = 0; y < source.height; y++) { - for (int x = 0; x < source.width; x++) { + for (int y = 0; y < source.pixelHeight; y++) { + for (int x = 0; x < source.pixelWidth; x++) { tintedTemp[x] = hi | (source.pixels[index++] & 0xFFFFFF); } - wr.setDataElements(0, y, source.width, 1, tintedTemp); + wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp); } } else { int index = 0; - for (int y = 0; y < source.height; y++) { + for (int y = 0; y < source.pixelHeight; y++) { if (source.format == RGB) { int alpha = tintColor & 0xFF000000; - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int r1 = (argb1 >> 16) & 0xff; int g1 = (argb1 >> 8) & 0xff; @@ -1744,7 +1749,7 @@ public void update(PImage source, boolean tint, int tintColor) { (((b2 * b1) & 0xff00) >> 8); } } else if (source.format == ARGB) { - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int a1 = (argb1 >> 24) & 0xff; int r1 = (argb1 >> 16) & 0xff; @@ -1758,13 +1763,13 @@ public void update(PImage source, boolean tint, int tintColor) { } } else if (source.format == ALPHA) { int lower = tintColor & 0xFFFFFF; - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int a1 = source.pixels[index++]; tintedTemp[x] = (((a2 * a1) & 0xff00) << 16) | lower; } } - wr.setDataElements(0, y, source.width, 1, tintedTemp); + wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp); } } // Not sure why ARGB images take the scales in this order... @@ -1784,7 +1789,7 @@ public void update(PImage source, boolean tint, int tintColor) { // in a PImage and how the high bits will be set. } // If no tint, just shove the pixels on in there verbatim - wr.setDataElements(0, 0, source.width, source.height, source.pixels); + wr.setDataElements(0, 0, source.pixelWidth, source.pixelHeight, source.pixels); } this.tinted = tint; this.tintedColor = tintColor; @@ -2839,12 +2844,6 @@ public int get(int x, int y) { //public PImage get(int x, int y, int w, int h) - @Override - public PImage get() { - return get(0, 0, width, height); - } - - @Override protected void getImpl(int sourceX, int sourceY, int sourceWidth, int sourceHeight, @@ -2855,7 +2854,7 @@ protected void getImpl(int sourceX, int sourceY, // ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster(); WritableRaster raster = getRaster(); - if (sourceWidth == target.width && sourceHeight == target.height) { + if (sourceWidth == target.pixelWidth && sourceHeight == target.pixelHeight) { raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, target.pixels); // https://github.com/processing/processing/issues/2030 if (raster.getNumBands() == 3) { @@ -2869,7 +2868,7 @@ protected void getImpl(int sourceX, int sourceY, // Copy the temporary output pixels over to the outgoing image int sourceOffset = 0; - int targetOffset = targetY*target.width + targetX; + int targetOffset = targetY*target.pixelWidth + targetX; for (int y = 0; y < sourceHeight; y++) { if (raster.getNumBands() == 3) { for (int i = 0; i < sourceWidth; i++) { @@ -2881,7 +2880,7 @@ protected void getImpl(int sourceX, int sourceY, System.arraycopy(temp, sourceOffset, target.pixels, targetOffset, sourceWidth); } sourceOffset += sourceWidth; - targetOffset += target.width; + targetOffset += target.pixelWidth; } } } @@ -2910,18 +2909,18 @@ protected void setImpl(PImage sourceImage, // ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster(); if ((sourceX == 0) && (sourceY == 0) && - (sourceWidth == sourceImage.width) && - (sourceHeight == sourceImage.height)) { + (sourceWidth == sourceImage.pixelWidth) && + (sourceHeight == sourceImage.pixelHeight)) { // System.out.format("%d %d %dx%d %d%n", targetX, targetY, // sourceImage.width, sourceImage.height, // sourceImage.pixels.length); raster.setDataElements(targetX, targetY, - sourceImage.width, sourceImage.height, + sourceImage.pixelWidth, sourceImage.pixelHeight, sourceImage.pixels); } else { // TODO optimize, incredibly inefficient to reallocate this much memory PImage temp = sourceImage.get(sourceX, sourceY, sourceWidth, sourceHeight); - raster.setDataElements(targetX, targetY, temp.width, temp.height, temp.pixels); + raster.setDataElements(targetX, targetY, temp.pixelWidth, temp.pixelHeight, temp.pixels); } } From b2240f95f93e0da6ce0818c1ed38a65821e3e5c9 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 01:42:34 +0100 Subject: [PATCH 304/917] pixelDensity (OpenGL): fix textures --- core/src/processing/core/PGraphics.java | 7 ++++++- .../src/processing/opengl/PGraphicsOpenGL.java | 18 +++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 02b9919c7b..9c8195d7c1 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -3879,6 +3879,11 @@ protected void imageImpl(PImage img, // fillA = 1; // } + u1 *= img.pixelDensity; + u2 *= img.pixelDensity; + v1 *= img.pixelDensity; + v2 *= img.pixelDensity; + beginShape(QUADS); texture(img); vertex(x1, y1, u1, v1); @@ -7347,7 +7352,7 @@ protected void backgroundFromCalc() { * @param image PImage to set as background (must be same size as the sketch window) */ public void background(PImage image) { - if ((image.width != width) || (image.height != height)) { + if ((image.pixelWidth != width) || (image.pixelHeight != height)) { throw new RuntimeException(ERROR_BACKGROUND_IMAGE_SIZE); } if ((image.format != RGB) && (image.format != ARGB)) { diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 2a03b88bc3..9ecf2fadc4 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -2147,8 +2147,8 @@ protected void vertexImpl(float x, float y, float z, float u, float v) { } if (textured && textureMode == IMAGE) { - u /= textureImage.width; - v /= textureImage.height; + u /= textureImage.pixelWidth; + v /= textureImage.pixelHeight; } inGeo.addVertex(x, y, z, @@ -5555,10 +5555,10 @@ public boolean save(String filename) { @Override protected void processImageBeforeAsyncSave(PImage image) { if (image.format == AsyncPixelReader.OPENGL_NATIVE) { - PGL.nativeToJavaARGB(image.pixels, image.width, image.height); + PGL.nativeToJavaARGB(image.pixels, image.pixelWidth, image.pixelHeight); image.format = ARGB; } else if (image.format == AsyncPixelReader.OPENGL_NATIVE_OPAQUE) { - PGL.nativeToJavaRGB(image.pixels, image.width, image.height); + PGL.nativeToJavaRGB(image.pixels, image.pixelWidth, image.pixelHeight); image.format = RGB; } } @@ -6003,7 +6003,7 @@ protected void drawPTexture() { @Override public void mask(PImage alpha) { updatePixelSize(); - if (alpha.width != pixelWidth || alpha.height != pixelHeight) { + if (alpha.pixelWidth != pixelWidth || alpha.pixelHeight != pixelHeight) { throw new RuntimeException("The PImage used with mask() must be " + "the same size as the applet."); } @@ -6364,8 +6364,8 @@ public Texture getTexture(PImage img) { if (tex == null) return null; if (img.isModified()) { - if (img.width != tex.width || img.height != tex.height) { - tex.init(img.width, img.height); + if (img.pixelWidth != tex.width || img.pixelHeight != tex.height) { + tex.init(img.pixelWidth, img.pixelHeight); } updateTexture(img, tex); } @@ -6491,8 +6491,8 @@ protected PImage wrapTexture(Texture tex) { // avoid initializing the pixels array. PImage img = new PImage(); img.parent = parent; - img.width = tex.width; - img.height = tex.height; + img.width = img.pixelWidth = tex.width; + img.height = img.pixelHeight = tex.height; img.format = ARGB; setCache(img, tex); return img; From 98f52e7e0a6a2f837e2cc644daeb76291bef64ab Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 02:49:46 +0100 Subject: [PATCH 305/917] pixelDensity (FX): run with highest density --- core/src/processing/javafx/PSurfaceFX.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index 508040016f..b64750a336 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -247,9 +247,15 @@ public void start(final Stage stage) { PApplet sketch = surface.sketch; float renderScale = Screen.getMainScreen().getRenderScale(); + if (PApplet.platform == PConstants.MACOSX) { + for (Screen s : Screen.getScreens()) { + renderScale = Math.max(renderScale, s.getRenderScale()); + } + } float uiScale = Screen.getMainScreen().getUIScale(); if (sketch.pixelDensity == 2 && renderScale < 2) { sketch.pixelDensity = 1; + sketch.g.pixelDensity = 1; System.err.println("pixelDensity(2) is not available for this display"); } From 5155c361a5d21ed3c89f864a0c7c128b5c8a695f Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 03:01:16 +0100 Subject: [PATCH 306/917] pixelDensity (FX): leave the density check up to PSurfaceFX --- core/src/processing/core/PApplet.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 3c4849ee47..406949911b 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -1212,9 +1212,11 @@ public void pixelDensity(int density) { if (density != 1 && density != 2) { throw new RuntimeException("pixelDensity() can only be 1 or 2"); } - if (density == 2 && displayDensity() == 1) { + if (!FX2D.equals(renderer) && density == 2 && displayDensity() == 1) { + // FX has its own check in PSurfaceFX // Don't throw exception because the sketch should still work - throw new RuntimeException("pixelDensity(2) is not available for this display"); + System.err.println("pixelDensity(2) is not available for this display"); + this.pixelDensity = 1; } else { this.pixelDensity = density; } From e568a07a819aa818e9a0697999e0454bc22d31a6 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 05:47:01 +0100 Subject: [PATCH 307/917] pixelDensity (OpenGL): fix 1x on macOS --- core/src/processing/opengl/PSurfaceJOGL.java | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 7811cd733d..ef080ab5d1 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -822,27 +822,33 @@ public void run() { public void setSize(final int width, final int height) { if (pgl.presentMode()) return; + boolean changed = sketch.width != width || sketch.height != height; + sketchWidth = width; sketchHeight = height; sketch.setSize(width, height); graphics.setSize(width, height); - if (window.getWidth() != width || window.getHeight() != height) { + if (changed) { window.setSize(width * windowScaleFactor, height * windowScaleFactor); } } public float getPixelScale() { - float result = graphics.pixelDensity; - if (graphics.pixelDensity == 2 && PApplet.platform == PConstants.MACOSX) { + if (graphics.pixelDensity == 1) { + return 1; + } + + if (PApplet.platform == PConstants.MACOSX) { // Even if the graphics are retina, the user might have moved the window // into a non-retina monitor, so we need to check window.getCurrentSurfaceScale(currentPixelScale); - result = currentPixelScale[0]; + return currentPixelScale[0]; } - return result; + + return 2; } @@ -947,8 +953,8 @@ public void init(GLAutoDrawable drawable) { public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { pgl.resetFBOLayer(); pgl.getGL(drawable); - int pixelScale = (int) getPixelScale(); - setSize(w / pixelScale, h / pixelScale); + window.getCurrentSurfaceScale(currentPixelScale); + setSize((int) (w / currentPixelScale[0]), (int) (h / currentPixelScale[1])); } } From 6698a13d2e70d4d70ba0d0bf48225365cac1df2a Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 06:00:41 +0100 Subject: [PATCH 308/917] pixelDensity (OpenGL): fix 1x mouse input on macOS --- core/src/processing/opengl/PSurfaceJOGL.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index ef080ab5d1..d67c9632f9 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -1102,9 +1102,15 @@ protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent, peCount = nativeEvent.getClickCount(); } - int pixelScale = (int) getPixelScale(); - int sx = nativeEvent.getX() / pixelScale; - int sy = nativeEvent.getY() / pixelScale; + int scale; + if (PApplet.platform == PConstants.MACOSX) { + window.getCurrentSurfaceScale(currentPixelScale); + scale = (int) currentPixelScale[0]; + } else { + scale = (int) getPixelScale(); + } + int sx = nativeEvent.getX() / scale; + int sy = nativeEvent.getY() / scale; int mx = sx; int my = sy; From 369822982b51f9a8c70ff1cbc86a57e3f594eada Mon Sep 17 00:00:00 2001 From: gohai Date: Sat, 18 Feb 2017 19:17:17 +0100 Subject: [PATCH 309/917] Retry with multisampling disabled if creating a framebuffer fails because of INCOMPLETE_MULTISAMPLE --- core/src/processing/opengl/PGL.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index 3a1490a343..372c9b74df 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -961,7 +961,16 @@ private void createFBOLayer() { createDepthAndStencilBuffer(true, depthBits, stencilBits, packed); } - validateFramebuffer(); + int status = validateFramebuffer(); + + if (status == FRAMEBUFFER_INCOMPLETE_MULTISAMPLE && 1 < numSamples) { + System.err.println("Continuing with multisampling disabled"); + reqNumSamples = 1; + destroyFBOLayer(); + // try again + createFBOLayer(); + return; + } // Clear all buffers. clearDepth(1); @@ -2048,10 +2057,10 @@ protected boolean linked(int program) { } - protected boolean validateFramebuffer() { + protected int validateFramebuffer() { int status = checkFramebufferStatus(FRAMEBUFFER); if (status == FRAMEBUFFER_COMPLETE) { - return true; + return 0; } else if (status == FRAMEBUFFER_UNDEFINED) { System.err.println(String.format(FRAMEBUFFER_ERROR, "framebuffer undefined")); @@ -2086,7 +2095,7 @@ protected boolean validateFramebuffer() { System.err.println(String.format(FRAMEBUFFER_ERROR, "unknown error " + status)); } - return false; + return status; } protected boolean isES() { From d60a63041e594e139a1d7b7df65324cebb547802 Mon Sep 17 00:00:00 2001 From: Gottfried Haider Date: Sun, 19 Feb 2017 10:03:06 +0100 Subject: [PATCH 310/917] Revert "ARM: Allow Raspberry Pi's Mesa GL driver to use up to 8 lights" --- core/src/processing/opengl/PGraphicsOpenGL.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 802114c9f5..eeebcc9cc1 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -6885,7 +6885,8 @@ protected void getGLParameters() { // overwrite the default shaders with vendor specific versions // if needed - if (OPENGL_RENDERER.equals("VideoCore IV HW")) { // Mesa driver for same hardware + if (OPENGL_RENDERER.equals("VideoCore IV HW") || // Broadcom's binary driver for Raspberry Pi + OPENGL_RENDERER.equals("Gallium 0.4 on VC4")) { // Mesa driver for same hardware defLightShaderVertURL = PGraphicsOpenGL.class.getResource("/processing/opengl/shaders/LightVert-vc4.glsl"); defTexlightShaderVertURL = From dc126ebf962f27ee96d9878a0152f2c58f39956f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 19 Feb 2017 10:35:02 -0500 Subject: [PATCH 311/917] createInput() and createOutput() now both use buffered streams by default --- core/src/processing/core/PApplet.java | 9 +++++---- core/todo.txt | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 473e032e8b..095f9816cd 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -6920,7 +6920,7 @@ static public PrintWriter createWriter(OutputStream output) { * */ public InputStream createInput(String filename) { - InputStream input = createInputRaw(filename); + InputStream input = new BufferedInputStream(createInputRaw(filename)); final String lower = filename.toLowerCase(); if ((input != null) && (lower.endsWith(".gz") || lower.endsWith(".svgz"))) { @@ -7360,11 +7360,12 @@ public OutputStream createOutput(String filename) { static public OutputStream createOutput(File file) { try { createPath(file); // make sure the path exists - FileOutputStream fos = new FileOutputStream(file); + OutputStream output = + new BufferedOutputStream(new FileOutputStream(file)); if (file.getName().toLowerCase().endsWith(".gz")) { - return new GZIPOutputStream(fos); + return new GZIPOutputStream(output); } - return fos; + return output; } catch (IOException e) { e.printStackTrace(); diff --git a/core/todo.txt b/core/todo.txt index 5441472807..5a407980b0 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -4,6 +4,8 @@ X add sum() to IntDict and FloatDict X add sumLong() to IntList, IntDict (to handle cases outside integer range) X add sumDouble() to FloatList, FloatDict (to handle outside float range) X throw exception when using sum() with numbers that are too large or small +X createInput() and createOutput() now both use buffered streams by default +X createInputRaw() does not, however gohai From 83739c692754ec9d65d3730b4574a66619892575 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 19 Feb 2017 13:58:26 -0500 Subject: [PATCH 312/917] deal with static access warning --- core/src/processing/opengl/PJOGL.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/processing/opengl/PJOGL.java b/core/src/processing/opengl/PJOGL.java index b02d1b30cf..7b67fe0d9d 100644 --- a/core/src/processing/opengl/PJOGL.java +++ b/core/src/processing/opengl/PJOGL.java @@ -45,7 +45,6 @@ import com.jogamp.opengl.GL2ES3; import com.jogamp.opengl.GL2GL3; import com.jogamp.opengl.GL3ES3; -import com.jogamp.opengl.GL3; import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLCapabilitiesImmutable; @@ -977,7 +976,7 @@ public void next() { DEPTH_STENCIL = GL.GL_DEPTH_STENCIL; FRAMEBUFFER_COMPLETE = GL.GL_FRAMEBUFFER_COMPLETE; - FRAMEBUFFER_UNDEFINED = GL3.GL_FRAMEBUFFER_UNDEFINED; + FRAMEBUFFER_UNDEFINED = GL2ES3.GL_FRAMEBUFFER_UNDEFINED; FRAMEBUFFER_INCOMPLETE_ATTACHMENT = GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; FRAMEBUFFER_INCOMPLETE_DIMENSIONS = GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; @@ -986,7 +985,7 @@ public void next() { FRAMEBUFFER_INCOMPLETE_READ_BUFFER = GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER; FRAMEBUFFER_UNSUPPORTED = GL.GL_FRAMEBUFFER_UNSUPPORTED; FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = GL.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; - FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; + FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = GL3ES3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE; FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME; From 130c5c5fbb212591d4da7dd20054bc508c7042b8 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 19 Feb 2017 15:37:14 -0500 Subject: [PATCH 313/917] missed wrapping this guy in a buffer --- core/src/processing/core/PApplet.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 095f9816cd..7606f28396 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -7094,6 +7094,7 @@ public InputStream createInputRaw(String filename) { return null; } + /** * @nowebref */ @@ -7102,7 +7103,7 @@ static public InputStream createInput(File file) { throw new IllegalArgumentException("File passed to createInput() was null"); } try { - InputStream input = new FileInputStream(file); + InputStream input = new BufferedInputStream(new FileInputStream(file)); if (file.getName().toLowerCase().endsWith(".gz")) { return new GZIPInputStream(input); } From 59e5fde94de3348295d4ab4a43312076bbce9348 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 19 Feb 2017 15:47:00 -0500 Subject: [PATCH 314/917] fix wrong ordering of buffered wrapping --- core/src/processing/core/PApplet.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 7606f28396..49ab538709 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -6920,18 +6920,19 @@ static public PrintWriter createWriter(OutputStream output) { * */ public InputStream createInput(String filename) { - InputStream input = new BufferedInputStream(createInputRaw(filename)); + InputStream input = createInputRaw(filename); final String lower = filename.toLowerCase(); if ((input != null) && (lower.endsWith(".gz") || lower.endsWith(".svgz"))) { try { - return new GZIPInputStream(input); + // buffered has to go *around* the GZ, otherwise 25x slower + return new BufferedInputStream(new GZIPInputStream(input)); } catch (IOException e) { printStackTrace(e); return null; } } - return input; + return new BufferedInputStream(input); } @@ -7103,11 +7104,11 @@ static public InputStream createInput(File file) { throw new IllegalArgumentException("File passed to createInput() was null"); } try { - InputStream input = new BufferedInputStream(new FileInputStream(file)); + InputStream input = new FileInputStream(file); if (file.getName().toLowerCase().endsWith(".gz")) { - return new GZIPInputStream(input); + return new BufferedInputStream(new GZIPInputStream(input)); } - return input; + return new BufferedInputStream(input); } catch (IOException e) { System.err.println("Could not createInput() for " + file); From 0a23259967447daf15a70c67924ab7a82fba4d0c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 20 Feb 2017 15:08:57 -0500 Subject: [PATCH 315/917] set the look and feel on Windows for 2x and native-like support --- core/src/processing/core/PApplet.java | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 49ab538709..f29ab52022 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -44,6 +44,7 @@ import javax.swing.ImageIcon; // used by selectInput(), selectOutput(), selectFolder() import javax.swing.JFileChooser; +import javax.swing.UIManager; // used to present the fullScreen() warning about Spaces on OS X import javax.swing.JOptionPane; // used by desktopFile() method @@ -994,6 +995,7 @@ void handleSettings() { if ("0".equals(result)) { EventQueue.invokeLater(new Runnable() { public void run() { + checkLookAndFeel(); final String msg = "To use fullScreen(SPAN), first turn off “Displays have separate spaces”\n" + "in System Preferences \u2192 Mission Control. Then log out and log back in."; @@ -6287,6 +6289,25 @@ private Frame selectFrame() { */ + static private boolean lookAndFeelCheck; + + /** + * Initialize the Look & Feel if it hasn't been already. + * Call this before using any Swing-related code in PApplet methods. + */ + static private void checkLookAndFeel() { + if (!lookAndFeelCheck) { + if (platform == WINDOWS) { + // Windows is defaulting to Metal or something else awful. + // Which also is not scaled properly with HiDPI interfaces. + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { } + } + lookAndFeelCheck = true; + } + } + /** * Open a platform-specific file chooser dialog to select a file for input. * After the selection is made, the selected File will be passed to the @@ -6499,6 +6520,8 @@ public void run() { selectedFile = new File(fileDialog.getDirectory(), fileDialog.getFile()); } } else { + checkLookAndFeel(); + JFileChooser fileChooser = new JFileChooser(); fileChooser.setDialogTitle(prompt); fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); From a04035354df4851897bbdcd626445881c57af73f Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 20 Feb 2017 15:17:01 -0500 Subject: [PATCH 316/917] maybe no space there after all --- core/src/processing/core/PApplet.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index f29ab52022..2638bc67a4 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -6521,7 +6521,6 @@ public void run() { } } else { checkLookAndFeel(); - JFileChooser fileChooser = new JFileChooser(); fileChooser.setDialogTitle(prompt); fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); From 2b3dac0568fb79acf1ab0185920d0db3c2d0b4bc Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 20 Feb 2017 15:30:49 -0500 Subject: [PATCH 317/917] fix ordering of BufferedOutputStream; huge speed fix --- core/src/processing/core/PApplet.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 2638bc67a4..91d12d2f22 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -7384,12 +7384,11 @@ public OutputStream createOutput(String filename) { static public OutputStream createOutput(File file) { try { createPath(file); // make sure the path exists - OutputStream output = - new BufferedOutputStream(new FileOutputStream(file)); + OutputStream output = new FileOutputStream(file); if (file.getName().toLowerCase().endsWith(".gz")) { - return new GZIPOutputStream(output); + return new BufferedOutputStream(new GZIPOutputStream(output)); } - return output; + return new BufferedOutputStream(output); } catch (IOException e) { e.printStackTrace(); From e4d30fe7a79c51e51de942ed705235d505cc1e3f Mon Sep 17 00:00:00 2001 From: gohai Date: Wed, 22 Feb 2017 16:46:56 +0100 Subject: [PATCH 318/917] IO: Rename the (publicly listed) waitForInterrupt function to waitFor This function is used like this: GPIO.waitFor(pin number, rising/falling/change, timeout or -1) While it's using an interrupt internally, in the way it is used it doesn't relate to the interrupt functions (attachInterrupt, etc) at all. To prevent confusion, rename it to waitFor. (Another possible name would be waitForPin.) --- java/libraries/io/src/processing/io/GPIO.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/java/libraries/io/src/processing/io/GPIO.java b/java/libraries/io/src/processing/io/GPIO.java index a0b9709553..fc86d23436 100644 --- a/java/libraries/io/src/processing/io/GPIO.java +++ b/java/libraries/io/src/processing/io/GPIO.java @@ -451,12 +451,17 @@ public static void releasePin(int pin) { * @return true if the interrupt occured, false if the timeout occured * @webref */ - public static boolean waitForInterrupt(int pin, int mode, int timeout) { + public static boolean waitFor(int pin, int mode, int timeout) { enableInterrupt(pin, mode); return waitForInterrupt(pin, timeout); } + public static boolean waitForInterrupt(int pin, int mode, int timeout) { + throw new RuntimeException("The waitForInterrupt function has been renamed to waitFor. Please update your sketch accordingly."); + } + + /** * Waits for the value of an input pin to change * From 5177d48afe19da3d6f71c6b7c2604de69f24fa9a Mon Sep 17 00:00:00 2001 From: gohai Date: Wed, 22 Feb 2017 16:54:03 +0100 Subject: [PATCH 319/917] IO: Remove the RPI (Raspberry Pi) class This provided constants that translated from the physical header pin numbers to GPIO lines. Instead, we (and the majority of other Pi related documentation out there) now just use GPIO numbers exclusively. The class hasn't been used in examples since a few versions, and also wasn't ever properly documented in the reference, so unlikely that many people will notice. --- java/libraries/io/src/processing/io/RPI.java | 88 -------------------- 1 file changed, 88 deletions(-) delete mode 100644 java/libraries/io/src/processing/io/RPI.java diff --git a/java/libraries/io/src/processing/io/RPI.java b/java/libraries/io/src/processing/io/RPI.java deleted file mode 100644 index 523ffeb123..0000000000 --- a/java/libraries/io/src/processing/io/RPI.java +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Copyright (c) The Processing Foundation 2015 - Hardware I/O library developed by Gottfried Haider as part of GSoC 2015 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -package processing.io; - - -/** - * @webref - */ -public class RPI { - - /* - * The Raspberry Pi has a 2x20 pin header for connecting various peripherals. - * The following constants describe how the pins of this header correspond - * to the pin numbering used by the CPU and by software ("GPIO pin number"). - * - * You can use this class to refer to a pin by its location on the header: - * e.g. GPIO.digitalWrite(RPI.PIN7, GPIO.HIGH) - * - * Alternatively, if you know a pins "true" pin number (GPIO number), you - * can use it directly. The following is equivalent to the example above: - * GPIO.digitalWrite(4, GPIO.HIGH) - * - * PIN1 is located on the "top left" of the column of pins, close to the two - * LEDs. PIN2 is next to it. PIN3 is below PIN1, and it goes on like this. - * See also: http://pi.gadgetoid.com/pinout - */ - - public static final int PIN1 = -1; /* 3v3 Power, can source up to 50 mA */ - public static final int PIN2 = -1; /* 5v Power, connected to input power */ - public static final int PIN3 = 2; /* GPIO 2, also: I2C data */ - public static final int PIN4 = -1; /* 5v Power, connected to input power */ - public static final int PIN5 = 3; /* GPIO 3, also: I2C clock */ - public static final int PIN6 = -1; /* Ground */ - public static final int PIN7 = 4; /* GPIO 4 */ - public static final int PIN8 = 14; /* GPIO 14, also: Serial TX */ - public static final int PIN9 = -1; /* Ground */ - public static final int PIN10 = 15; /* GPIO 15, also: Serial RX */ - public static final int PIN11 = 17; /* GPIO 17 */ - public static final int PIN12 = 18; /* GPIO 18 */ - public static final int PIN13 = 27; /* GPIO 27 */ - public static final int PIN14 = -1; /* Ground */ - public static final int PIN15 = 22; /* GPIO 22 */ - public static final int PIN16 = 23; /* GPIO 23 */ - public static final int PIN17 = -1; /* 3v3 Power, can source up to 50 mA */ - public static final int PIN18 = 24; /* GPIO 24 */ - public static final int PIN19 = 10; /* GPIO 10, also: SPI MOSI */ - public static final int PIN20 = -1; /* Ground */ - public static final int PIN21 = 9; /* GPIO 9, also: SPI MISO */ - public static final int PIN22 = 25; /* GPIO 25 */ - public static final int PIN23 = 11; /* GPIO 11, also: SPI SCLK */ - public static final int PIN24 = 8; /* GPIO 8, also: SPI Chip Select 0 */ - public static final int PIN25 = -1; /* Ground */ - public static final int PIN26 = 7; /* GPIO 7, also: SPI Chip Select 1 */ - public static final int PIN27 = 0; /* GPIO 0, also: HAT I2C data, reserved [currenly not accessible] */ - public static final int PIN28 = 1; /* GPIO 1, also HAT I2C data, reserved [currenly not accessible] */ - public static final int PIN29 = 5; /* GPIO 5 */ - public static final int PIN30 = -1; /* Ground */ - public static final int PIN31 = 6; /* GPIO 6 */ - public static final int PIN32 = 12; /* GPIO 12 */ - public static final int PIN33 = 13; /* GPIO 13 */ - public static final int PIN34 = -1; /* Ground */ - public static final int PIN35 = 19; /* GPIO 19, also: SPI MISO [currenly not accessible] */ - public static final int PIN36 = 16; /* GPIO 16 */ - public static final int PIN37 = 26; /* GPIO 26 */ - public static final int PIN38 = 20; /* GPIO 20, also: SPI MISO [currenly not accessible] */ - public static final int PIN39 = -1; /* Ground */ - public static final int PIN40 = 21; /* GPIO 21, also: SPI CLK [currenly not accessible] */ -} From b661ca7e7f1b4171c4cceffc81ed8f2bce8f51c2 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 24 Feb 2017 15:12:50 -0500 Subject: [PATCH 320/917] recent notes from github issues --- core/todo.txt | 7 +++++++ todo.txt | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index 5a407980b0..0fcf902e56 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -14,6 +14,13 @@ X https://github.com/processing/processing-docs/issues/523 X https://github.com/processing/processing-docs/pull/524 X ARM: Allow Raspberry Pi's Mesa GL driver to use up to 8 lights X https://github.com/processing/processing/pull/4915 +X ...and revert it back again +X https://github.com/processing/processing/pull/4922 +X Retry with multisampling disabled if creating a framebuffer fails +X because of INCOMPLETE_MULTISAMPLE +X https://github.com/processing/processing/pull/4921 +X Report more error conditions in validateFramebuffer +X https://github.com/processing/processing/pull/4920 high diff --git a/todo.txt b/todo.txt index 15bbe67d03..1dcbb7c6c5 100755 --- a/todo.txt +++ b/todo.txt @@ -4,6 +4,10 @@ X https://github.com/processing/processing/pull/4707 X https://github.com/processing/processing/issues/4668 _ Small tooltip text on high-dpi screens _ https://github.com/processing/processing/issues/4914 +_ mode list does not update after changing sketchbook folder +_ already reported? +_ swap font smoothing for tab size? +_ implement simple table for prefs? jakub X Fix preprocessing of code with double backslash in string or char literal From 1d1232cb5f80d97a5cdde8b744eaf2b644062f03 Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 24 Feb 2017 11:12:50 +0100 Subject: [PATCH 321/917] IO: Introduce a variant of waitFor that doesn't take a timeout This simplifies the semantic of the variant with three arguments, since we now don't have the "-1 means wait forever" case any longer. --- java/libraries/io/src/processing/io/GPIO.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/java/libraries/io/src/processing/io/GPIO.java b/java/libraries/io/src/processing/io/GPIO.java index fc86d23436..856bdb228f 100644 --- a/java/libraries/io/src/processing/io/GPIO.java +++ b/java/libraries/io/src/processing/io/GPIO.java @@ -447,7 +447,18 @@ public static void releasePin(int pin) { * Waits for the value of an input pin to change * @param pin GPIO pin * @param mode what to wait for: GPIO.CHANGE, GPIO.FALLING or GPIO.RISING - * @param timeout don't wait more than timeout milliseconds (-1 waits indefinitely) + * @webref + */ + public static void waitFor(int pin, int mode) { + waitForInterrupt(pin, mode, -1); + } + + + /** + * Waits for the value of an input pin to change + * @param pin GPIO pin + * @param mode what to wait for: GPIO.CHANGE, GPIO.FALLING or GPIO.RISING + * @param timeout don't wait more than timeout milliseconds * @return true if the interrupt occured, false if the timeout occured * @webref */ From 1f76c4110b15083beb7e47b8bd67a99f9bb4b34d Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 24 Feb 2017 11:21:02 +0100 Subject: [PATCH 322/917] IO: Make waitFor throw an exception in case of a timeout Previously, it returned a boolean indicating success. But the code on the caller-side will be nicer to read with exceptions. --- java/libraries/io/src/processing/io/GPIO.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/java/libraries/io/src/processing/io/GPIO.java b/java/libraries/io/src/processing/io/GPIO.java index 856bdb228f..a4042122d5 100644 --- a/java/libraries/io/src/processing/io/GPIO.java +++ b/java/libraries/io/src/processing/io/GPIO.java @@ -456,15 +456,18 @@ public static void waitFor(int pin, int mode) { /** * Waits for the value of an input pin to change + * + * This function will throw a RuntimeException in case of a timeout. * @param pin GPIO pin * @param mode what to wait for: GPIO.CHANGE, GPIO.FALLING or GPIO.RISING * @param timeout don't wait more than timeout milliseconds - * @return true if the interrupt occured, false if the timeout occured * @webref */ - public static boolean waitFor(int pin, int mode, int timeout) { + public static void waitFor(int pin, int mode, int timeout) { enableInterrupt(pin, mode); - return waitForInterrupt(pin, timeout); + if (waitForInterrupt(pin, timeout) == false) { + throw new RuntimeException("Timeout occurred"); + } } From bf0e64907763bc9810d20c5999066bd6d22cfdd9 Mon Sep 17 00:00:00 2001 From: gohai Date: Sat, 25 Feb 2017 15:42:59 +0100 Subject: [PATCH 323/917] IO: Remove superfluous super in examples --- java/libraries/io/examples/SPIAnalogDigitalOOP/MCP3001.pde | 4 ++-- java/libraries/io/examples/SPIAnalogDigitalOOP8/MCP3008.pde | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/libraries/io/examples/SPIAnalogDigitalOOP/MCP3001.pde b/java/libraries/io/examples/SPIAnalogDigitalOOP/MCP3001.pde index e25869633e..944e097e5d 100644 --- a/java/libraries/io/examples/SPIAnalogDigitalOOP/MCP3001.pde +++ b/java/libraries/io/examples/SPIAnalogDigitalOOP/MCP3001.pde @@ -7,13 +7,13 @@ class MCP3001 extends SPI { MCP3001(String dev) { super(dev); - super.settings(500000, SPI.MSBFIRST, SPI.MODE0); + settings(500000, SPI.MSBFIRST, SPI.MODE0); } float getAnalog() { // dummy write, actual values don't matter byte[] out = { 0, 0 }; - byte[] in = super.transfer(out); + byte[] in = transfer(out); // some input bit shifting according to the datasheet p. 16 int val = ((in[0] & 0x1f) << 5) | ((in[1] & 0xf8) >> 3); // val is between 0 and 1023 diff --git a/java/libraries/io/examples/SPIAnalogDigitalOOP8/MCP3008.pde b/java/libraries/io/examples/SPIAnalogDigitalOOP8/MCP3008.pde index 5ae8d9ef06..ee3affd0f3 100644 --- a/java/libraries/io/examples/SPIAnalogDigitalOOP8/MCP3008.pde +++ b/java/libraries/io/examples/SPIAnalogDigitalOOP8/MCP3008.pde @@ -8,7 +8,7 @@ class MCP3008 extends SPI { MCP3008(String dev) { super(dev); - super.settings(500000, SPI.MSBFIRST, SPI.MODE0); + settings(500000, SPI.MSBFIRST, SPI.MODE0); } float getAnalog(int channel) { @@ -19,7 +19,7 @@ class MCP3008 extends SPI { byte[] out = { 0, 0, 0 }; // encode the channel number in the first byte out[0] = (byte)(0x18 | channel); - byte[] in = super.transfer(out); + byte[] in = transfer(out); int val = ((in[1] & 0x03) << 8) | (in[2] & 0xff); // val is between 0 and 1023 return val/1023.0; From b77cbfe1ad7bc548ece2e9bbc8edcd4e22e50713 Mon Sep 17 00:00:00 2001 From: gohai Date: Sun, 26 Feb 2017 16:39:33 +0100 Subject: [PATCH 324/917] IO: Fix SPI.close() --- java/libraries/io/src/processing/io/PWM.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/libraries/io/src/processing/io/PWM.java b/java/libraries/io/src/processing/io/PWM.java index 455a659e41..2a8fe19f22 100644 --- a/java/libraries/io/src/processing/io/PWM.java +++ b/java/libraries/io/src/processing/io/PWM.java @@ -117,7 +117,7 @@ public void close() { // XXX: implicit clear()? // XXX: also check GPIO - String fn = "/sys/class/pwm/" + chip + "/export"; + String fn = "/sys/class/pwm/" + chip + "/unexport"; int ret = NativeInterface.writeFile(fn, Integer.toString(channel)); if (ret < 0) { if (ret == -2) { // ENOENT From 1b01cfdf1099cdc413f11b32c615e3da2afdd169 Mon Sep 17 00:00:00 2001 From: Omar Hommos <11maxed11@gmail.com> Date: Fri, 3 Mar 2017 20:39:09 +0100 Subject: [PATCH 325/917] Marhaba! - Register Arabic Language in Languages.java - Update languages.txt file - PDE_ar.properties --- app/src/processing/app/Language.java | 1 + build/shared/lib/languages/PDE_ar.properties | 590 +++++++++++++++++++ build/shared/lib/languages/languages.txt | 1 + 3 files changed, 592 insertions(+) create mode 100644 build/shared/lib/languages/PDE_ar.properties diff --git a/app/src/processing/app/Language.java b/app/src/processing/app/Language.java index 93543d10d3..43e01f8f63 100644 --- a/app/src/processing/app/Language.java +++ b/app/src/processing/app/Language.java @@ -89,6 +89,7 @@ static private String[] listSupported() { // List of languages in alphabetical order. (Add yours here.) // Also remember to add it to build/shared/lib/languages/languages.txt. final String[] SUPPORTED = { + "ar", // Arabic "de", // German, Deutsch "en", // English "el", // Greek diff --git a/build/shared/lib/languages/PDE_ar.properties b/build/shared/lib/languages/PDE_ar.properties new file mode 100644 index 0000000000..1565be130c --- /dev/null +++ b/build/shared/lib/languages/PDE_ar.properties @@ -0,0 +1,590 @@ + + +# --------------------------------------- +# Language: Arabic (ar) | العربية +# --------------------------------------- + + +# --------------------------------------- +# Menu + +# | File | Edit | Sketch | Debug | Tools | Help | +# | File | +menu.file = ملف +menu.file.new = جديد +menu.file.open = افتح... +menu.file.recent = Open Recent +menu.file.sketchbook = Sketchbook... +menu.file.sketchbook.empty = Empty Sketchbook +menu.file.examples = Examples... +menu.file.close = Close +menu.file.save = Save +menu.file.save_as = Save As... +menu.file.export_application = Export Application... +menu.file.page_setup = Page Setup +menu.file.print = Print... +menu.file.preferences = Preferences... +menu.file.quit = Quit + +# | File | Edit | Sketch | Debug | Tools | Help | +# | Edit | +menu.edit = Edit +menu.edit.undo = تراجع +menu.edit.redo = Redo +menu.edit.action.addition = addition +menu.edit.action.deletion = deletion +menu.edit.cut = Cut +menu.edit.copy = Copy +menu.edit.copy_as_html = Copy as HTML +menu.edit.paste = Paste +menu.edit.select_all = Select All +menu.edit.auto_format = Auto Format +menu.edit.comment_uncomment = Comment/Uncomment +menu.edit.increase_indent = Increase Indent +menu.edit.decrease_indent = Decrease Indent +menu.edit.find = Find... +menu.edit.find_next = Find Next +menu.edit.find_previous = Find Previous +menu.edit.use_selection_for_find = Use Selection for Find + +# | File | Edit | Sketch | Debug | Tools | Help | +# | Sketch | +menu.sketch.run = تشغيل +menu.sketch.present = Present +menu.sketch.tweak = Tweak +menu.sketch.stop = إيقاف +# --- +menu.library = Import Library... +menu.library.add_library = Add Library... +menu.library.contributed = Contributed +menu.library.no_core_libraries = mode has no core libraries +# --- +menu.sketch = Sketch +menu.sketch.show_sketch_folder = Show Sketch Folder +menu.sketch.add_file = إضافة ملف.. + +# | File | Edit | Sketch | Debug | Tools | Help | +# | Debug | +menu.debug = Debug +menu.debug.enable = Enable Debugger +menu.debug.disable = Disable Debugger +#menu.debug.show_debug_toolbar = Show Debug Toolbar +#menu.debug.debug = Debug +#menu.debug.stop = Stop +# --- +menu.debug.toggle_breakpoint = Toggle Breakpoint +#menu.debug.list_breakpoints = List breakpoints +# --- +# used for both menus and toolbars +menu.debug.step = Step +menu.debug.step_into = Step Into +menu.debug.step_out = Step Out +menu.debug.continue = Continue +# --- +#menu.debug.print_stack_trace = Print Stack Trace +#menu.debug.print_locals = Print Locals +#menu.debug.print_fields = Print Fields +#menu.debug.print_source_location = Print Source Location +#menu.debug.print_threads = Print Threads +# --- +#menu.debug.variable_inspector = Variable Inspector +menu.debug.show_variables = Show Variables +menu.debug.hide_variables = Hide Variables +#menu.debug.show_sketch_outline = Show Sketch Outline +#menu.debug.show_tabs_list = Show Tabs List + +# | File | Edit | Sketch | Debug | Tools | Help | +# | Tools | +menu.tools = Tools +menu.tools.color_selector = Color Selector... +menu.tools.create_font = Create Font... +menu.tools.archive_sketch = Archive Sketch +menu.tools.fix_the_serial_lbrary = Fix the Serial Library +menu.tools.install_processing_java = Install "processing-java" +menu.tools.add_tool = Add Tool... + +# | File | Edit | Sketch | Debug | Tools | Help | +# | Help | +menu.help = Help +menu.help.welcome = Welcome to Processing 3 +menu.help.about = About Processing +menu.help.environment = Environment +menu.help.reference = Reference +menu.help.find_in_reference = Find in Reference +menu.help.libraries_reference = Libraries Reference +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.troubleshooting = Troubleshooting +menu.help.troubleshooting.url = http://wiki.processing.org/w/Troubleshooting +menu.help.faq = Frequently Asked Questions +menu.help.faq.url = http://wiki.processing.org/w/FAQ +menu.help.foundation = The Processing Foundation +menu.help.foundation.url = http://processing.org/foundation/ +menu.help.visit = Visit Processing.org +menu.help.visit.url = http://processing.org/ + + +# --------------------------------------- +# Basics + +# Buttons +prompt.yes = Yes +prompt.no = No +prompt.cancel = Cancel +prompt.ok = OK +prompt.browse = Browse +prompt.export = Export + + +# --------------------------------------- +# Frames + +# Open (Frame) +open = Open a Processing sketch... + +# Save (Frame) +save = Save sketch folder as... +save.title = Do you want to save changes to %s
    before closing? +save.hint = If you don't save, your changes will be lost. +save.btn.save = Save +save.btn.dont_save = Don't Save + +# Close (Frame) also used to prompt on non-OS X machines +close.unsaved_changes = Save changes to %s? + +# Preferences (Frame) +preferences = Preferences +preferences.button.width = 80 +preferences.requires_restart = requires restart of Processing +preferences.sketchbook_location = Sketchbook location +preferences.sketchbook_location.popup = Sketchbook location +preferences.language = Language +preferences.editor_and_console_font = Editor and Console font +preferences.editor_and_console_font.tip = Select the font used in the Editor and the Console.
    Only monospaced (fixed-width) fonts may be used,
    though the list may be imperfect. +preferences.editor_font_size = Editor font size +preferences.console_font_size = Console font size +preferences.zoom = Interface scale +preferences.zoom.auto = Automatic +preferences.background_color = Background color when Presenting +preferences.background_color.tip = Select the background color used when using Present.
    Present is used to present a sketch in full-screen,
    accessible from the Sketch menu. +preferences.use_smooth_text = Use smooth text in editor window +preferences.enable_complex_text_input = Enable complex text input +preferences.enable_complex_text_input_example = i.e. Japanese +preferences.continuously_check = Continuously check for errors +preferences.show_warnings = Show warnings +preferences.code_completion = Code completion with +preferences.trigger_with = Trigger with +preferences.cmd_space = space +preferences.suggest_imports = Suggest import statements +preferences.increase_max_memory = Increase maximum available memory to +preferences.delete_previous_folder_on_export = Delete previous folder on export +preferences.check_for_updates_on_startup = Allow update checking (see FAQ for information shared) +preferences.run_sketches_on_display = Run sketches on display +preferences.run_sketches_on_display.tip = Sets the display where sketches are initially placed.
    As usual, if the sketch window is moved, it will re-open
    at the same location, however when running in present
    (full screen) mode, this display will always be used. +preferences.automatically_associate_pde_files = Automatically associate .pde files with Processing +preferences.launch_programs_in = Launch programs in +preferences.launch_programs_in.mode = mode +preferences.file = More preferences can be edited directly in the file +preferences.file.hint = edit only when Processing is not running + +# Sketchbook Location (Frame) +sketchbook_location = Select new sketchbook location + +# Sketchbook (Frame) +sketchbook = Sketchbook +sketchbook.tree = Sketchbook + +# Examples (Frame) +examples.title = %s Examples +examples.add_examples = Add Examples... +examples.libraries = Contributed Libraries +examples.core_libraries = Libraries +examples.contributed = Contributed Examples + +# Export (Frame) +export = Export Options +export.platforms = Platforms +export.options = Options +export.options.present = Presentation Mode +export.options.show_stop_button = Show a Stop button +export.description.line1 = Export to Application creates double-clickable, +export.description.line2 = standalone applications for the selected platforms. +export.unsaved_changes = Save changes before export? +export.notice.cancel.unsaved_changes = Export canceled, changes must first be saved. +export.notice.exporting = Exporting application... +export.notice.exporting.done = Done exporting. +export.notice.exporting.error = Error during export. +export.notice.exporting.cancel = Export to Application canceled. +export.tooltip.macosx = Mac OS X export is only available on Mac OS X +export.full_screen = Full Screen +export.embed_java = Embed Java +export.embed_java.for = Embed Java for +export.code_signing = Code Signing +export.messages.is_read_only = Sketch is Read-Only +export.messages.is_read_only.description = Some files are marked "read-only", so you will\nneed to re-save the sketch in another location,\nand try again. +export.messages.cannot_export = Cannot Export +export.messages.cannot_export.description = You cannot export a sketch that has not been saved. + +# Find (Frame) +find = Find +find.find = Find: +find.replace_with = Replace with: +find.ignore_case = Ignore Case +find.all_tabs = All Tabs +find.wrap_around = Wrap Around +find.btn.replace_all = Replace All +find.btn.replace = Replace +find.btn.replace_and_find = Replace & Find +find.btn.previous = Previous +find.btn.find = Find + +# Find in reference (Frame) +find_in_reference = Find in Reference + +# File (Frame) +file = Select an image or other data file to copy to your sketch + +# Create Font (Frame) +create_font = Create Font +create_font.label = Use this tool to create bitmap fonts for your program.\nSelect a font and size, and click 'OK' to generate the font.\nIt will be added to the data folder of the current sketch. +create_font.size = Size +create_font.smooth = Smooth +create_font.characters = Characters... +create_font.character_selector = Character Selector +create_font.character_selector.label = Default characters will include most bitmaps for Mac OS\nand Windows Latin scripts. Including all characters may\nrequire large amounts of memory for all of the bitmaps.\nFor greater control, you can select specific Unicode blocks. +create_font.default_characters = Default Characters +create_font.all_characters = All Characters +create_font.specific_unicode = Specific Unicode Blocks +create_font.filename = Filename + +# Color Selector (Frame) +color_selector = Color Selector + +# Archive Sketch (Frame) +archive_sketch = Archive sketch as... + +# Tweak Mode +tweak_mode = Tweak Mode +tweak_mode.save_before_tweak = Please save the sketch before running in Tweak Mode. +tweak_mode.keep_changes.line1 = Keep the changes? +tweak_mode.keep_changes.line2 = You changed some values in your sketch. Would you like to keep the changes? + +# DebugTray +debugger.name = Name +debugger.value = Value +debugger.type = Type + +# --------------------------------------- +# Toolbars + +# [Run/Present] [Stop] [New] [Open] [Save] +toolbar.run = Run +toolbar.present = Present +toolbar.stop = Stop +toolbar.debug = Debug +# --- +toolbar.new = New +toolbar.open = Open +toolbar.save = Save +# toolbar.export_application = Export Application +toolbar.add_mode = Add Mode... + +# [Debug] [Continue] [Step] [Stop] [Toggle Breakpoints] [Variable Inspector] +#toolbar.debug.continue = Continue +#toolbar.debug.step = Step +#toolbar.debug.step_into = Step Into +#toolbar.debug.stop = Stop +#toolbar.debug.toggle_breakpoints = Toggle Breakpoint +#toolbar.debug.variable_inspector = Variable Inspector + + +# --------------------------------------- +# Editor + +# [Tab1] [Tab2] [v] +editor.header.new_tab = New Tab +editor.header.rename = Rename +editor.header.delete = Delete +editor.header.previous_tab = Previous Tab +editor.header.next_tab = Next Tab +editor.header.delete.warning.title = Yeah, no. +editor.header.delete.warning.text = You cannot delete the main tab of the only open sketch. + +# PopUp menu +editor.popup.jump_to_declaration = Jump to Declaration +editor.popup.show_usage = Show Usage... +editor.popup.rename = Rename... + +# Tabs +editor.tab.new = New Name +editor.tab.new.description = Name for new file +editor.tab.rename = New Name +editor.tab.rename.description = New name for file + +# Sketch +editor.sketch.rename.description = New name for sketch + +editor.status.autoformat.no_changes = No changes necessary for Auto Format. +editor.status.autoformat.finished = Auto Format finished. +editor.status.find_reference.select_word_first = First select a word to find in the reference. +editor.status.find_reference.not_available = No reference available for "%s". +editor.status.drag_and_drop.files_added.0 = No files were added to the sketch. +editor.status.drag_and_drop.files_added.1 = One file added to the sketch. +editor.status.drag_and_drop.files_added.n = %d files added to the sketch. +editor.status.saving = Saving... +editor.status.saving.done = Done saving. +editor.status.saving.canceled = Save canceled. +editor.status.printing = Printing... +editor.status.printing.done = Done printing. +editor.status.printing.error = Error while printing. +editor.status.printing.canceled = Printing canceled. +editor.status.copy_as_html = Code formatted as HTML has been copied to the clipboard. +editor.status.debug.busy = Debugger busy... +editor.status.debug.halt = Debugger halted. +editor.status.archiver.create = Created archive "%s". +editor.status.archiver.cancel = Archive sketch canceled. + +# Errors +editor.status.warning = Warning +editor.status.error = Error +editor.status.error_on = Error on "%s" +editor.status.missing.default = Missing "%c" +editor.status.missing.semicolon = Missing a semicolon ";" +editor.status.missing.left_sq_bracket = Missing left square bracket "[" +editor.status.missing.right_sq_bracket = Missing right square bracket "]" +editor.status.missing.left_paren = Missing left parenthesis "(" +editor.status.missing.right_paren = Missing right parenthesis ")" +editor.status.missing.left_curly_bracket = Missing left curly bracket "{" +editor.status.missing.right_curly_bracket = Missing right curly bracket "}" +editor.status.missing.add = Consider adding "%s" +editor.status.reserved_words = "color" and "int" are reserved words & cannot be used as variable names +editor.status.undefined_method = The function "%s(%s)" does not exist +editor.status.undefined_constructor = The constructor "%s(%s)" does not exist +editor.status.empty_param = The function "%s()" does not expect any parameters +editor.status.wrong_param = The function "%s()" expects parameters like: "%s(%s)" +editor.status.undef_global_var = The global variable "%s" does not exist +editor.status.undef_class = The class "%s" does not exist +editor.status.undef_var = The variable "%s" does not exist +editor.status.undef_name = The name "%s" cannot be recognized +editor.status.type_mismatch = Type mismatch, "%s" does not match with "%s" +editor.status.unused_variable = The value of the local variable "%s" is not used +editor.status.uninitialized_variable = The local variable "%s" may not have been initialized +editor.status.no_effect_assignment = The assignment to variable "%s" has no effect +editor.status.hiding_enclosing_type = The class "%s" cannot have the same name as your sketch or its' enclosing class + +# Footer buttons +editor.footer.errors = Errors +editor.footer.errors.problem = Problem +editor.footer.errors.tab = Tab +editor.footer.errors.line = Line +editor.footer.console = Console + +# New handler +new.messages.is_read_only = Sketch is Read-Only +new.messages.is_read_only.description = Some files are marked "read-only", so you will\nneed to re-save the sketch in another location,\nand try again. + +# Rename handler +rename.messages.is_untitled = Sketch is Untitled +rename.messages.is_untitled.description = How about saving the sketch first\nbefore trying to rename it? +rename.messages.is_modified = Please save the sketch before renaming. +rename.messages.is_read_only = Sketch is Read-Only +rename.messages.is_read_only.description = Some files are marked "read-only", so you will\nneed to re-save the sketch in another location,\nand try again. + +# Naming handler +name.messages.problem_renaming = Problem with rename +name.messages.starts_with_dot.description = The name cannot start with a period. +name.messages.invalid_extension.description = ".%s" is not a valid extension. +name.messages.main_java_extension.description = The first tab cannot be a .%s file.\n(It may be time for you to graduate to a\n"real" programming environment, hotshot.) +name.messages.new_sketch_exists = Nope +name.messages.new_sketch_exists.description = A file named "%s" already exists at\n"%s" +name.messages.new_folder_exists = Cannot Rename +name.messages.new_folder_exists.description = Sorry, a sketch (or folder) named "%s" already exists. +name.messages.error = Error +name.messages.no_rename_folder.description = Could not rename the sketch folder. +name.messages.no_rename_file.description = Could not rename "%s" to "%s" +name.messages.no_create_file.description = Could not create the file "%s"\nin "%s" + +# Delete handler +delete.messages.cannot_delete = Cannot Delete +delete.messages.cannot_delete.description = You cannot delete a sketch that has not been saved. +delete.messages.cannot_delete.file = Could not do it +delete.messages.cannot_delete.file.description = Could not delete +delete.messages.is_read_only = Sketch is Read-Only +delete.messages.is_read_only.description = Some files are marked "read-only", so you will\nneed to re-save the sketch in another location,\nand try again. + +# Save handler +save_file.messages.is_read_only = Sketch is read-only +save_file.messages.is_read_only.description = Some files are marked "read-only", so you will\nneed to re-save this sketch to another location. +save_file.messages.sketch_exists = Cannot Save +save_file.messages.sketch_exists.description = A sketch with the cleaned name\n“%s” already exists. +save_file.messages.tab_exists = Nope +save_file.messages.tab_exists.description = You cannot save the sketch as "%s"\nbecause the sketch already has a tab with that name. +save_file.messages.recursive_save = How very Borges of you +save_file.messages.recursive_save.description = You cannot save the sketch into a folder\ninside itself. This would go on forever. + +# Add handler +add_file.messages.is_read_only = Sketch is Read-Only +add_file.messages.is_read_only.description = Some files are marked "read-only", so you will\nneed to re-save the sketch in another location,\nand try again. +add_file.messages.confirm_replace = Replace the existing version of %s? +add_file.messages.error_adding = Error adding file +add_file.messages.cannot_delete.description = Could not delete the existing '%s' file. +add_file.messages.cannot_add.description = Could not add '%s' to the sketch. +add_file.messages.same_file = You can't fool me +add_file.messages.same_file.description = This file has already been copied to the\nlocation from which where you're trying to add it.\nI ain't not doin nuthin'. + +# Temp folder creator +temp_dir.messages.bad_build_folder = Build folder bad +temp_dir.messages.bad_build_folder.description = Could not find a place to build the sketch. + +# Ensure Existance +ensure_exist.messages.missing_sketch = Sketch Disappeared +ensure_exist.messages.missing_sketch.description = The sketch folder has disappeared.\nWill attempt to re-save in the same location,\nbut anything besides the code will be lost. +ensure_exist.messages.unrecoverable = Could not re-save sketch +ensure_exist.messages.unrecoverable.description = Could not properly re-save the sketch. You may be in trouble at this point,\nand it might be time to copy and paste your code to another text editor. + +# Check name +check_name.messages.is_name_modified = The sketch name had to be modified. Sketch names can only consist\nof ASCII characters and numbers (but cannot start with a number).\nThey should also be less than 64 characters long. + +# --------------------------------------- +# Contributions + +# Contribution Panel +contrib = Contribution Manager +contrib.manager_title.update = Update Manager +contrib.manager_title.mode = Mode Manager +contrib.manager_title.tool = Tool Manager +contrib.manager_title.library = Library Manager +contrib.manager_title.examples = Examples Manager +contrib.category = Category: +contrib.filter_your_search = Filter your search... +contrib.show_only_compatible.mode = Show Only Compatible Modes +contrib.show_only_compatible.tool = Show Only Compatible Tools +contrib.show_only_compatible.library = Show Only Compatible Libraries +contrib.show_only_compatible.examples = Show Only Compatible Examples +contrib.show_only_compatible.update = Show Only Compatible Updates +contrib.restart = Restart Processing +contrib.unsaved_changes = Unsaved changes have been found +contrib.unsaved_changes.prompt = Are you sure you want to restart Processing without saving first? +contrib.messages.remove_restart = Please restart Processing to finish removing this item. +contrib.messages.install_restart = Please restart Processing to finish installing this item. +contrib.messages.update_restart = Please restart Processing to finish updating this item. +contrib.errors.list_download = Could not download the list of available contributions. +contrib.errors.list_download.timeout = Connection timed out while downloading the contribution list. +contrib.errors.download_and_install = Error during download and install of %s. +contrib.errors.description_unavailable = Description unavailable. +contrib.errors.malformed_url = The link fetched from Processing.org is not valid.\nYou can still install this library manually by visiting\nthe library\'s website. +contrib.errors.needs_repackage = %s needs to be repackaged according to the %s guidelines. +contrib.errors.no_contribution_found = Could not find a %s in the downloaded file. +contrib.errors.overwriting_properties = Error overwriting .properties file. +contrib.errors.install_failed = Install failed. +contrib.errors.update_on_restart_failed = Update on restart of %s failed. +contrib.errors.temporary_directory = Could not write to temporary directory. +contrib.errors.contrib_download.timeout = Connection timed out while downloading %s. +contrib.errors.no_internet_connection = You do not seem to be connected to the Internet. +contrib.status.downloading_list = Downloading contribution list... +contrib.status.connecting = Connecting... +contrib.status.done = Done. +contrib.all = All +contrib.undo = Undo +contrib.remove = Remove +contrib.install = Install +contrib.progress.installing = Installing +contrib.progress.starting = Starting +contrib.progress.downloading = Downloading +contrib.download_error = An error occured while downloading the contribution. +contrib.unsupported_operating_system = Your operating system does not appear to be supported. You should visit the %s\'s library for more info. +contrib.category.3d = 3D +contrib.category.animation = Animation +contrib.category.data = Data +contrib.category.geometry = Geometry +contrib.category.gui = GUI +contrib.category.hardware = Hardware +contrib.category.i_o = I/O +contrib.category.math = Math +contrib.category.simulation = Simulation +contrib.category.sound = Sound +contrib.category.typography = Typography +contrib.category.utilities = Utilities +contrib.category.video_vision = Video & Vision +contrib.category.other = Other + +# Install on Startup +contrib.startup.errors.download_install = Error during download and install of %s +contrib.startup.errors.temp_dir = Could not write to temporary directory during download and install of %s +contrib.startup.errors.new_marker = The unupdated contribution marker seems to not like %s. You may have to install it manually to update... + +# Install on Import +contrib.import.dialog.title = Missing Libraries Available +contrib.import.dialog.primary_text = The following imported libraries are available for download, but have not been installed. +contrib.import.dialog.secondary_text = Would you like to install them now? +contrib.import.progress.download = Downloading %s... +contrib.import.progress.install = Installing %s... +contrib.import.progress.done = %s has been installed. +contrib.import.progress.final_list = The following libraries have been installed: +contrib.import.errors.link = Error: The library %s has a strange looking download link. + +# --------------------------------------- +# Warnings + +warn.delete = Delete +warn.delete.sketch = Are you sure you want to delete this sketch? +warn.delete.file = Are you sure you want to delete "%s"? +warn.cannot_change_mode.title = Cannot change mode +warn.cannot_change_mode.body = Cannot change mode,\nbecause "%s" mode is not compatible with current mode. + + +# --------------------------------------- +# Update Check + +update_check = Update +update_check.updates_available.core = A new version of Processing is available,\nwould you like to visit the Processing download page? +update_check.updates_available.contributions = There are updates available for some of the installed contributions,\nwould you like to open the the Contribution Manager now? + + +# --------------------------------------- +# Color Chooser + +color_chooser = Color Selector +color_chooser.select = Select + +# --------------------------------------- +# Movie Maker + +movie_maker = Movie Maker +movie_maker.title = QuickTime Movie Maker +movie_maker.blurb = This tool creates a QuickTime movie from a sequence of images.

    To avoid artifacts caused by re-compressing images as video,
    use TIFF, TGA (from Processing), or PNG images as the source.

    TIFF and TGA images will write more quickly, but require more disk:
    saveFrame("frames/####.tif");
    saveFrame("frames/####.tga");

    PNG images are smaller, but your sketch will run more slowly:
    saveFrame("frames/####.png");

    This code is based on QuickTime Movie Maker 1.5.1 2011-01-17.
    Copyright © 2010-2011 Werner Randelshofer. All rights reserved.
    +movie_maker.image_folder_help_label = Drag a folder with image files into the field below: +movie_maker.choose_button = Choose... +movie_maker.select_image_folder = Select image folder... +movie_maker.sound_file_help_label = Drag a sound file into the field below (.au, .aiff, .wav, .mp3): +movie_maker.select_sound_file = Select sound file... + +movie_maker.create_movie_button = Create movie... +movie_maker.save_dialog_prompt = Save movie as... +movie_maker.width = Width: +movie_maker.height = Height: +movie_maker.compression = Compression: +movie_maker.compression.animation = Animation +movie_maker.compression.jpeg = JPEG +movie_maker.compression.png = PNG +movie_maker.framerate = Framerate: +movie_maker.orig_size_button = Same size as originals +movie_maker.orig_size_tooltip = Check this box if the folder contains already encoded video frames in the desired size. + +movie_maker.error.avoid_tiff = Try TGA or PNG images instead of TIFF. +movie_maker.error.badnumbers = Width and height must be whole numbers greater than zero; framerate must be a number greater than zero. +movie_maker.error.cannot_read = Could not read %s. +movie_maker.error.cannot_read_maybe_bad = Could not read %s; it may be bad. +movie_maker.error.movie_failed = Creating the QuickTime movie failed. +movie_maker.error.need_input = You need to specify the folder with image files, the sound file, or both. +movie_maker.error.no_images_found = No image files found. +movie_maker.error.sorry = Sorry +movie_maker.error.unknown_tga_format = Unknown .tga file format for %s. + +movie_maker.progress.creating_file_name = Creating %s. +movie_maker.progress.creating_output_file = Creating output file +movie_maker.progress.initializing = Initializing... +movie_maker.progress.processing = Processing %s. diff --git a/build/shared/lib/languages/languages.txt b/build/shared/lib/languages/languages.txt index e86d7da446..5f60ed0dc5 100644 --- a/build/shared/lib/languages/languages.txt +++ b/build/shared/lib/languages/languages.txt @@ -5,6 +5,7 @@ # Add new languages in alphabetical order to (slightly) # reduce the risk of merge conflicts +ar # Arabic de # German, Deutsch en # English, English el # Greek From b98da242b45e8aa52421181926be83a2a58b4f5f Mon Sep 17 00:00:00 2001 From: Omar Hommos <11maxed11@gmail.com> Date: Sun, 5 Mar 2017 18:36:51 +0100 Subject: [PATCH 326/917] First part of translation Includes all the translation for the menus section --- build/shared/lib/languages/PDE_ar.properties | 248 +++++++++---------- 1 file changed, 124 insertions(+), 124 deletions(-) diff --git a/build/shared/lib/languages/PDE_ar.properties b/build/shared/lib/languages/PDE_ar.properties index 1565be130c..9819437a28 100644 --- a/build/shared/lib/languages/PDE_ar.properties +++ b/build/shared/lib/languages/PDE_ar.properties @@ -13,117 +13,117 @@ menu.file = ملف menu.file.new = جديد menu.file.open = افتح... -menu.file.recent = Open Recent -menu.file.sketchbook = Sketchbook... -menu.file.sketchbook.empty = Empty Sketchbook -menu.file.examples = Examples... -menu.file.close = Close -menu.file.save = Save -menu.file.save_as = Save As... -menu.file.export_application = Export Application... -menu.file.page_setup = Page Setup -menu.file.print = Print... -menu.file.preferences = Preferences... -menu.file.quit = Quit +menu.file.recent = فتح من الملفات الأخيرة +menu.file.sketchbook = دفتر المخطوطات... +menu.file.sketchbook.empty = دفتر مخطوطات فارغ +menu.file.examples = أمثلة... +menu.file.close = إغلاق +menu.file.save = حفظ +menu.file.save_as = حفظ ك... +menu.file.export_application = تصدير التطبيق... +menu.file.page_setup = إعدادات الصفحة +menu.file.print = طباعة +menu.file.preferences = إعدادات... +menu.file.quit = خروج # | File | Edit | Sketch | Debug | Tools | Help | # | Edit | -menu.edit = Edit +menu.edit = تعديل menu.edit.undo = تراجع -menu.edit.redo = Redo -menu.edit.action.addition = addition -menu.edit.action.deletion = deletion -menu.edit.cut = Cut -menu.edit.copy = Copy -menu.edit.copy_as_html = Copy as HTML -menu.edit.paste = Paste -menu.edit.select_all = Select All -menu.edit.auto_format = Auto Format -menu.edit.comment_uncomment = Comment/Uncomment -menu.edit.increase_indent = Increase Indent -menu.edit.decrease_indent = Decrease Indent -menu.edit.find = Find... -menu.edit.find_next = Find Next -menu.edit.find_previous = Find Previous -menu.edit.use_selection_for_find = Use Selection for Find +menu.edit.redo = إعادة +menu.edit.action.addition = إضافة +menu.edit.action.deletion = حذف +menu.edit.cut = قص +menu.edit.copy = نسخ +menu.edit.copy_as_html = نسخ ك HTML +menu.edit.paste = لصق +menu.edit.select_all = تحديد الكل +menu.edit.auto_format = فرمتة تلقائية +menu.edit.comment_uncomment = تعليق/إلغاء التعليق +menu.edit.increase_indent = زيادة المسافة البادئة +menu.edit.decrease_indent = انقاص المسافة البادئة +menu.edit.find = بحث... +menu.edit.find_next = النتيجة التالية +menu.edit.find_previous = النتيجة السابقة +menu.edit.use_selection_for_find = ابحث عن المحدد # | File | Edit | Sketch | Debug | Tools | Help | # | Sketch | menu.sketch.run = تشغيل -menu.sketch.present = Present -menu.sketch.tweak = Tweak +menu.sketch.present = الحالي +menu.sketch.tweak = تعديل menu.sketch.stop = إيقاف # --- -menu.library = Import Library... -menu.library.add_library = Add Library... -menu.library.contributed = Contributed -menu.library.no_core_libraries = mode has no core libraries +menu.library = استيراد مكتبة... +menu.library.add_library = إضافة مكتبة... +menu.library.contributed = مساهمات +menu.library.no_core_libraries = لا يوجد مكتبات أساسية لهذا الوضع # --- -menu.sketch = Sketch -menu.sketch.show_sketch_folder = Show Sketch Folder +menu.sketch = المخطوط +menu.sketch.show_sketch_folder = إظهار ملف المخطوطات menu.sketch.add_file = إضافة ملف.. # | File | Edit | Sketch | Debug | Tools | Help | # | Debug | -menu.debug = Debug -menu.debug.enable = Enable Debugger -menu.debug.disable = Disable Debugger -#menu.debug.show_debug_toolbar = Show Debug Toolbar -#menu.debug.debug = Debug -#menu.debug.stop = Stop +menu.debug = تنقيح +menu.debug.enable = تفعيل أداة التنقيح +menu.debug.disable = تعطيل أداة التنقيح +#menu.debug.show_debug_toolbar = إظهار شريط أدواة التنقيح +#menu.debug.debug = تنقيح +#menu.debug.stop = توقف # --- -menu.debug.toggle_breakpoint = Toggle Breakpoint -#menu.debug.list_breakpoints = List breakpoints +menu.debug.toggle_breakpoint = تبديل حالة نقطة الوقوف +#menu.debug.list_breakpoints = قائمة نقاط الوقوف # --- # used for both menus and toolbars -menu.debug.step = Step -menu.debug.step_into = Step Into -menu.debug.step_out = Step Out -menu.debug.continue = Continue +menu.debug.step = تقدم +menu.debug.step_into = تقدم إلى الأمام +menu.debug.step_out = تقدم إلى الخلف +menu.debug.continue = استمر # --- -#menu.debug.print_stack_trace = Print Stack Trace -#menu.debug.print_locals = Print Locals -#menu.debug.print_fields = Print Fields -#menu.debug.print_source_location = Print Source Location -#menu.debug.print_threads = Print Threads +#menu.debug.print_stack_trace = طباعة أثر المكدس +#menu.debug.print_locals = طباعة المتغيرات المحلية +#menu.debug.print_fields = طباعة الحقول +#menu.debug.print_source_location = طباعة مكان المصدر +#menu.debug.print_threads = طباعة شرط التعليمات # --- -#menu.debug.variable_inspector = Variable Inspector -menu.debug.show_variables = Show Variables -menu.debug.hide_variables = Hide Variables -#menu.debug.show_sketch_outline = Show Sketch Outline -#menu.debug.show_tabs_list = Show Tabs List +#menu.debug.variable_inspector = مظهر المتغيرات +menu.debug.show_variables = إظهار المتغيرات +menu.debug.hide_variables = إخفاء المتغيرات +#menu.debug.show_sketch_outline = إظهار موجز المخطوط +#menu.debug.show_tabs_list = إظهار قائمة علامات التبويب # | File | Edit | Sketch | Debug | Tools | Help | # | Tools | -menu.tools = Tools -menu.tools.color_selector = Color Selector... -menu.tools.create_font = Create Font... -menu.tools.archive_sketch = Archive Sketch -menu.tools.fix_the_serial_lbrary = Fix the Serial Library -menu.tools.install_processing_java = Install "processing-java" -menu.tools.add_tool = Add Tool... +menu.tools = أدوات +menu.tools.color_selector = أداة اختيار الألوان... +menu.tools.create_font = أداة صناعة الخطوط +menu.tools.archive_sketch = أرشفة المخطوط +menu.tools.fix_the_serial_lbrary = إصلاح مكتبة الاتصالات التسلسلية +menu.tools.install_processing_java = تثبيت"processing-java" +menu.tools.add_tool = أضف أداة # | File | Edit | Sketch | Debug | Tools | Help | # | Help | -menu.help = Help -menu.help.welcome = Welcome to Processing 3 -menu.help.about = About Processing -menu.help.environment = Environment -menu.help.reference = Reference -menu.help.find_in_reference = Find in Reference -menu.help.libraries_reference = Libraries Reference -menu.help.tools_reference = Tools Reference -menu.help.empty = (empty) -menu.help.online = Online -menu.help.getting_started = Getting Started +menu.help = مساعدة +menu.help.welcome = مرحباً بكم في Processing 3 +menu.help.about = عن Processing +menu.help.environment = البيئة +menu.help.reference = مراجع +menu.help.find_in_reference = إبحث في مرجع +menu.help.libraries_reference = مرجع المكتبات +menu.help.tools_reference = مرجع الأدوات +menu.help.empty = (فارغ) +menu.help.online = متصل +menu.help.getting_started = البدء menu.help.getting_started.url = http://processing.org/learning/gettingstarted/ -menu.help.troubleshooting = Troubleshooting +menu.help.troubleshooting = اكتشاف الأخطاء وإصلاحها menu.help.troubleshooting.url = http://wiki.processing.org/w/Troubleshooting -menu.help.faq = Frequently Asked Questions +menu.help.faq = الأسئلة الشائعة menu.help.faq.url = http://wiki.processing.org/w/FAQ -menu.help.foundation = The Processing Foundation +menu.help.foundation = Processing مؤسسة menu.help.foundation.url = http://processing.org/foundation/ -menu.help.visit = Visit Processing.org +menu.help.visit = Processing.org زيارة menu.help.visit.url = http://processing.org/ @@ -131,43 +131,43 @@ menu.help.visit.url = http://processing.org/ # Basics # Buttons -prompt.yes = Yes -prompt.no = No -prompt.cancel = Cancel -prompt.ok = OK -prompt.browse = Browse -prompt.export = Export +prompt.yes = نعم +prompt.no = لا +prompt.cancel = إلغاء +prompt.ok = موافق +prompt.browse = تصفح +prompt.export = تصدير # --------------------------------------- # Frames # Open (Frame) -open = Open a Processing sketch... +open = فتح مخطوط بروسسنج... # Save (Frame) -save = Save sketch folder as... -save.title = Do you want to save changes to %s
    before closing? -save.hint = If you don't save, your changes will be lost. -save.btn.save = Save -save.btn.dont_save = Don't Save +save = حفظ ملف المخطوطات ك... +save.title = هل تريد حفظ التغييرات على %s
    قبل الإغلاق؟ +save.hint = في حال عدم الحفظ, ستفقد كل التغييرات على الملف +save.btn.save = حفظ +save.btn.dont_save = عدم الحفظ # Close (Frame) also used to prompt on non-OS X machines -close.unsaved_changes = Save changes to %s? +close.unsaved_changes = ؟%s هل تريد حفظ التغييرات على # Preferences (Frame) -preferences = Preferences +preferences = الإعدادات preferences.button.width = 80 -preferences.requires_restart = requires restart of Processing +preferences.requires_restart = تلزم إعادة تشغيل Processing preferences.sketchbook_location = Sketchbook location preferences.sketchbook_location.popup = Sketchbook location -preferences.language = Language +preferences.language = اللغة preferences.editor_and_console_font = Editor and Console font preferences.editor_and_console_font.tip = Select the font used in the Editor and the Console.
    Only monospaced (fixed-width) fonts may be used,
    though the list may be imperfect. -preferences.editor_font_size = Editor font size +preferences.editor_font_size = حجم خط المحرر preferences.console_font_size = Console font size preferences.zoom = Interface scale -preferences.zoom.auto = Automatic +preferences.zoom.auto = تلقائي preferences.background_color = Background color when Presenting preferences.background_color.tip = Select the background color used when using Present.
    Present is used to present a sketch in full-screen,
    accessible from the Sketch menu. preferences.use_smooth_text = Use smooth text in editor window @@ -177,7 +177,7 @@ preferences.continuously_check = Continuously check for errors preferences.show_warnings = Show warnings preferences.code_completion = Code completion with preferences.trigger_with = Trigger with -preferences.cmd_space = space +preferences.cmd_space = فراغ preferences.suggest_imports = Suggest import statements preferences.increase_max_memory = Increase maximum available memory to preferences.delete_previous_folder_on_export = Delete previous folder on export @@ -487,13 +487,13 @@ contrib.errors.no_internet_connection = You do not seem to be connected to the I contrib.status.downloading_list = Downloading contribution list... contrib.status.connecting = Connecting... contrib.status.done = Done. -contrib.all = All -contrib.undo = Undo -contrib.remove = Remove -contrib.install = Install -contrib.progress.installing = Installing -contrib.progress.starting = Starting -contrib.progress.downloading = Downloading +contrib.all = الكل +contrib.undo = تراجع +contrib.remove = إزالة +contrib.install = تثبيت +contrib.progress.installing = يتم تثبيت +contrib.progress.starting = يتم بدأ +contrib.progress.downloading = يتم تنزيل contrib.download_error = An error occured while downloading the contribution. contrib.unsupported_operating_system = Your operating system does not appear to be supported. You should visit the %s\'s library for more info. contrib.category.3d = 3D @@ -509,7 +509,7 @@ contrib.category.sound = Sound contrib.category.typography = Typography contrib.category.utilities = Utilities contrib.category.video_vision = Video & Vision -contrib.category.other = Other +contrib.category.other = آخر # Install on Startup contrib.startup.errors.download_install = Error during download and install of %s @@ -529,9 +529,9 @@ contrib.import.errors.link = Error: The library %s has a strange looking downloa # --------------------------------------- # Warnings -warn.delete = Delete +warn.delete = حذف warn.delete.sketch = Are you sure you want to delete this sketch? -warn.delete.file = Are you sure you want to delete "%s"? +warn.delete.file = هل انت متأكد أنك تود حذف "%s"؟ warn.cannot_change_mode.title = Cannot change mode warn.cannot_change_mode.body = Cannot change mode,\nbecause "%s" mode is not compatible with current mode. @@ -539,34 +539,34 @@ warn.cannot_change_mode.body = Cannot change mode,\nbecause "%s" mode is not com # --------------------------------------- # Update Check -update_check = Update -update_check.updates_available.core = A new version of Processing is available,\nwould you like to visit the Processing download page? +update_check = تحديث +update_check.updates_available.core = يوجد نسخة جديدة من بروسسنج جاهزة للتحميل. \nهل تود زيارة الموقع الرسمي لتحميلها؟ update_check.updates_available.contributions = There are updates available for some of the installed contributions,\nwould you like to open the the Contribution Manager now? # --------------------------------------- # Color Chooser -color_chooser = Color Selector -color_chooser.select = Select +color_chooser = أداة اختيار الألوان +color_chooser.select = تحديد # --------------------------------------- # Movie Maker -movie_maker = Movie Maker -movie_maker.title = QuickTime Movie Maker +movie_maker = صانع الأفلام +movie_maker.title = QuickTime صانع أفلام movie_maker.blurb = This tool creates a QuickTime movie from a sequence of images.

    To avoid artifacts caused by re-compressing images as video,
    use TIFF, TGA (from Processing), or PNG images as the source.

    TIFF and TGA images will write more quickly, but require more disk:
    saveFrame("frames/####.tif");
    saveFrame("frames/####.tga");

    PNG images are smaller, but your sketch will run more slowly:
    saveFrame("frames/####.png");

    This code is based on QuickTime Movie Maker 1.5.1 2011-01-17.
    Copyright © 2010-2011 Werner Randelshofer. All rights reserved.
    movie_maker.image_folder_help_label = Drag a folder with image files into the field below: -movie_maker.choose_button = Choose... -movie_maker.select_image_folder = Select image folder... +movie_maker.choose_button = اختر... +movie_maker.select_image_folder = اختر ملف الصور... movie_maker.sound_file_help_label = Drag a sound file into the field below (.au, .aiff, .wav, .mp3): -movie_maker.select_sound_file = Select sound file... +movie_maker.select_sound_file = اختر ملف الصوت... -movie_maker.create_movie_button = Create movie... -movie_maker.save_dialog_prompt = Save movie as... -movie_maker.width = Width: -movie_maker.height = Height: -movie_maker.compression = Compression: +movie_maker.create_movie_button = فلم جديد... +movie_maker.save_dialog_prompt = حفظ الفلم ك... +movie_maker.width = العرض +movie_maker.height = الارتفاع +movie_maker.compression = الضغط movie_maker.compression.animation = Animation movie_maker.compression.jpeg = JPEG movie_maker.compression.png = PNG From ce948d8aeceb7d078d5b7cf6f93a3e4477022a70 Mon Sep 17 00:00:00 2001 From: gohai Date: Sun, 5 Mar 2017 18:05:19 +0100 Subject: [PATCH 327/917] Add more Raspberry Pi specific fixes to JOGL This adds the following fixes on top of 434455a272 (patches at https://github.com/gohai/jogl): * Fix GL overlay offset when overscan is enabled * Fix the value of mouseButton (#4499) * Change libGLESv2 search order to work around longstanding issue in Raspbian --- core/library/jogl-all.jar | Bin 3402029 -> 3400401 bytes core/src/processing/opengl/PSurfaceJOGL.java | 10 ---------- 2 files changed, 10 deletions(-) diff --git a/core/library/jogl-all.jar b/core/library/jogl-all.jar index e2c7b44b4250009fd3264d19d0e41aaf96777f52..fa8728f209c31b2096ce10efd7809823ad517c55 100644 GIT binary patch delta 1074740 zcmZ6yb99|u&_0|K+h!ZvR%6???VRw$wrwYEY}4g;Xjvi1uEZ0!C5)DQ3> zu`Awrui8{#%&{c%TH=Ef3dpRwM$H3vydTQtV!r3w(K=PU2vOdgC++EbpERhEY?k+p z{IOen_|$w_1_!;9z(3JhfZ1f4$wg-5kZ&NgkcG$*kin%~PbRNxc!jh=2;%f*Fr&j?*J#*W z62ab`TM~~pU%dKhIMg$jIotXxj?nb(yUovOBqM%TW37Yr<@g8>ej+{Y!91|>CgFEe z%J1W@PI=!$t#d&3wZMP`V#YAI+jHn(#;7#Qz=k&>f%36tjpR6sta zRMst&)=6LEV&P8Oe@s(amyG#Z|CILZeRp{~*!*>uN{|nN>obW=D}bM^+*PIEjy~e( z+75%r_t;~5tf4hf`@S`Q-C6Y}z%{eerQ=r!Io(zfHEaFo$3?r8MvIuTjSl^tp7HFl zD{c}0OPe!6&-Mt(HU*L7ymbJ5$x8CeeFY z$eSn8yK+?Rj=FkR+0Ge$&raF)mKy)N>S(K*ukNTPyYFf&hfFNTV;-%6`Y^~gY5`Q4 zyQPWfUl2voalQ4JnDttp^_Yi#MrE@L!W>?ey@uYTA6C3hqupF_mY2Sci#y}>FVonV zyLQ#@D~n(h@4&R(of|$G5v-zN)NfKzNIBkR6c>}B3Bs*XFOzN8r8Ns;#NfDYLn~`z zm8P^+sgzEoTn@VVd6?)lrw770Ry^n5bcBy-v093$jfO;rWBcgzWvk9(l`_x`fpU0y z(}~o2WO{Byh#4u_IcFTbNIApc$=#OFVL}{yK5YPY$A} zpU}_G*=>}*L;U!0VJ4Ene1QrHjNB9Ca0JG>&s6d^=*OV1muVqj{&6eW}Ah{|GK+N;o#NPuYsc`M=8)S4s`xG|YIF#^mD&+ES0%CVZ?mYYsFV6%E^9w1tf3 zRBo(bsWCR;m*@fYCW*K{ zk>)lAFWNGmn`Osk7Vd`Mpz49wpgZk8Kf2GjKG?XvJ!r;+VkLTCiR3xy-(i|n=@`d4 zD!~2))Nlp=t=i7Dn;@Kh-vDZ%fkmCjgRh{+xsl0Zh}^U|Pc9Qb^FwMdWQkn4FJ>rIbv%abv-pG7seHZz^*;Hiobo+vwC@n-Rk8~ehW{X!eczDC zmMrb<+-7Ufsb)z0Y6_rbx~RahB0LqZU9ptle~`uqXi9lOrgaGGyyrtG~vr0zacypn-|_V1+^xvkOevo-OrnV zky^8c~dYLGgR-?}22; zcL*ZgIe*clj2DRs{HS4K;1LgpN>Xu)cqmWAoBTx-c?Cxh$C=hmyAbZ@J3heY$WOvR zJ@8`qK_tz{`2!|Cwp!-FcUlXRd9x2Sf_f=o7!!!s5P;N+C7e<_F5}X$#4jn*wC#Jm zg)U+P3J$j~Pu$GzmlsHQYh|z*n#2Gm}I&NUfj_;3H&8WQtL4r9T^SQ}=-T z8o$HAOyryIS3(tY`
    +0sM!GU7oUNM-2%GLN;P>n(gOn2?{mZs@`Wf)F* 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

    DEVSB*N1Qi?0&iYt)vlBuHyn8H{h;#6svvEo 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≻aWUNr(xEK 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 z%0D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/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

    Ntm;ktV48fz@$^T`-K!(ethko}@j+(}8})v$ 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›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 s>Jur?55dd5)ywT*>7gv z`@Z+RIs7sD|L zcQ{dsI~`2EOMi&y7vup6gEH=xaE}ueI4*{J9axGVIB_3N2oWd6aKD5f3f=?4-X96d zk7fKs#)C3`D&rxc`ol7QCgbNaej(!#8IQ_%OziSY8IOzWuVg$Su1`w%wG)l_tq}K= zgr{ZvPU!x78Gn%RjDuN!l<_BV{j-c`#q}>T{wl72bARGFJTKP$UBU|zULvH$y8Y3@ z3PO3q-f)*1?D2$qv`|;TbD*-)(-k=2*;QFt*RZQLqV}r01KI}F7Yj!YR`J4B{*XVm zhEP#7rIp1y2)3GVr$)$X@Q1XfcyPBCX%$llIsRy^w%_m5TH-xD;YdvDBrGdx@P&h( z#2z6v=6~O>_4-4d;a*Sm?r1E+a_b^$Pq*KfSX))xPRMA9slI)UYL6~ixAql=9J@=x zs|+Iv|0GQFMKm?0wREcyt#g|e4aXxsp8Fa>PCgNo`cO!V)CAOMRErWirmoH?|DYF$DLV%HLp zMIkFrDP$wNL}?01;wmfTASYpl(7+Q=LtUPhSi~RdS{L^RI<*Kxh}Cr~luio4;^(+n zLx15IVUC*@_yfWScR1wk)D`hWwa9)g;??J8D3mF5dR3t;%AUMUEsPZ{q)?7-1LZ1| zN7EF_r|ATjc>=JC3eBLI3b|+&M^vHNRG`otn#+og*fz1Ou3`NFpVkxeheL$Yns7YO z8Co23cWE)UV~-jS#N2faTO#2-95VNwaDOCW9h=4auqAFYku_?My4xS{$NXAU%$ui> zo8~LDfX-rcDO5-c6;F4pbDx~XepI&b||!rmMe5Ntx#wsoqt1E zV77dl7GmURk*#rmWFK4c0rDzTC7`#8>|BhDtf@`-)ICfw0zZ_I^omx#i z646329bl^≀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