diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 4bff2cdb0..e3d22f3fc 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -46,9 +46,9 @@ import processing.mode.java.JavaMode; 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 = 226; + static private final int REVISION = 227; /** This might be replaced by main() if there's a lib/version.txt file. */ - static private String VERSION_NAME = "0226"; //$NON-NLS-1$ + static private String VERSION_NAME = "0227"; //$NON-NLS-1$ /** Set true if this a proper release rather than a numbered revision. */ // static private boolean RELEASE = false; @@ -127,7 +127,11 @@ public class Base { private JMenu sketchbookMenu; private Recent recent; -// private JMenu recentMenu; + + // Used by handleOpen(), this saves the chooser to remember the directory. + // Doesn't appear to be necessary with the AWT native file dialog. + // https://github.com/processing/processing/pull/2366 + private JFileChooser openChooser; static protected File sketchbookFolder; // protected File toolsFolder; @@ -833,12 +837,15 @@ public class Base { } final String prompt = "Open a Processing sketch..."; - if (Preferences.getBoolean("chooser.files.native")) { // don't use native dialogs on Linux //$NON-NLS-1$ - // get the front-most window frame for placing file dialog - FileDialog fd = new FileDialog(activeEditor, prompt, FileDialog.LOAD); + + // don't use native dialogs on Linux (or anyone else w/ override) + if (Preferences.getBoolean("chooser.files.native")) { //$NON-NLS-1$ + // use the front-most window frame for placing file dialog + FileDialog openDialog = + new FileDialog(activeEditor, prompt, FileDialog.LOAD); // Only show .pde files as eligible bachelors - fd.setFilenameFilter(new FilenameFilter() { + openDialog.setFilenameFilter(new FilenameFilter() { public boolean accept(File dir, String name) { // confirmed to be working properly [fry 110128] for (String ext : extensions) { @@ -850,20 +857,22 @@ public class Base { } }); - fd.setVisible(true); + openDialog.setVisible(true); - String directory = fd.getDirectory(); - String filename = fd.getFile(); + String directory = openDialog.getDirectory(); + String filename = openDialog.getFile(); if (filename != null) { File inputFile = new File(directory, filename); handleOpen(inputFile.getAbsolutePath()); } } else { - JFileChooser fc = new JFileChooser(); - fc.setDialogTitle(prompt); + if (openChooser == null) { + openChooser = new JFileChooser(); + } + openChooser.setDialogTitle(prompt); - fc.setFileFilter(new javax.swing.filechooser.FileFilter() { + openChooser.setFileFilter(new javax.swing.filechooser.FileFilter() { public boolean accept(File file) { // JFileChooser requires you to explicitly say yes to directories // as well (unlike the AWT chooser). Useful, but... different. @@ -883,8 +892,8 @@ public class Base { return "Processing Sketch"; } }); - if (fc.showOpenDialog(activeEditor) == JFileChooser.APPROVE_OPTION) { - handleOpen(fc.getSelectedFile().getAbsolutePath()); + if (openChooser.showOpenDialog(activeEditor) == JFileChooser.APPROVE_OPTION) { + handleOpen(openChooser.getSelectedFile().getAbsolutePath()); } } } diff --git a/app/src/processing/app/ColorChooser.java b/app/src/processing/app/ColorChooser.java new file mode 100644 index 000000000..b4a6ccac8 --- /dev/null +++ b/app/src/processing/app/ColorChooser.java @@ -0,0 +1,701 @@ +/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2006-14 Ben Fry and Casey Reas + + 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; + +import processing.core.*; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.event.*; + +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.event.*; +import javax.swing.text.*; + + +/** + * Generic color selector frame, pulled from the Tool object. API not really + * worked out here (what should the constructor be? how flexible?) So use with + * caution and be ready for it to break in future releases. + */ +public class ColorChooser { //extends JFrame implements DocumentListener { + + int hue, saturation, brightness; // range 360, 100, 100 + int red, green, blue; // range 256, 256, 256 + + ColorRange range; + ColorSlider slider; + + JTextField hueField, saturationField, brightnessField; + JTextField redField, greenField, blueField; + + JTextField hexField; + + JPanel colorPanel; + DocumentListener colorListener; + + JDialog window; + + +// public String getMenuTitle() { +// return "Color Selector"; +// } + + + public ColorChooser(Frame owner, boolean modal, Color initialColor, + String buttonName, ActionListener buttonListener) { + //super("Color Selector"); + window = new JDialog(owner, "Color Selector", modal); + window.getContentPane().setLayout(new BorderLayout()); + + Box box = Box.createHorizontalBox(); + box.setBorder(new EmptyBorder(12, 12, 12, 12)); + + range = new ColorRange(); + range.init(); + Box rangeBox = new Box(BoxLayout.Y_AXIS); + rangeBox.setAlignmentY(0); + rangeBox.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); + rangeBox.add(range); + box.add(rangeBox); + box.add(Box.createHorizontalStrut(10)); + + slider = new ColorSlider(); + slider.init(); + Box sliderBox = new Box(BoxLayout.Y_AXIS); + sliderBox.setAlignmentY(0); + sliderBox.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); + sliderBox.add(slider); + box.add(sliderBox); + box.add(Box.createHorizontalStrut(10)); + + box.add(createColorFields(buttonName, buttonListener)); +// System.out.println("1: " + hexField.getInsets()); + + box.add(Box.createHorizontalStrut(10)); + +// System.out.println("2: " + hexField.getInsets()); + + window.getContentPane().add(box, BorderLayout.CENTER); +// System.out.println(hexField); +// System.out.println("3: " + hexField.getInsets()); +// colorPanel.setInsets(hexField.getInsets()); + + window.pack(); + window.setResizable(false); + +// Dimension size = getSize(); +// Dimension screen = Toolkit.getScreenSize(); +// setLocation((screen.width - size.width) / 2, +// (screen.height - size.height) / 2); + window.setLocationRelativeTo(null); + + window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + window.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + hide(); + } + }); + Toolkit.registerWindowCloseKeys(window.getRootPane(), new ActionListener() { + public void actionPerformed(ActionEvent actionEvent) { + hide(); + } + }); + + Toolkit.setIcon(window); + + colorListener = new ColorListener(); + hueField.getDocument().addDocumentListener(colorListener); + saturationField.getDocument().addDocumentListener(colorListener); + brightnessField.getDocument().addDocumentListener(colorListener); + redField.getDocument().addDocumentListener(colorListener); + greenField.getDocument().addDocumentListener(colorListener); + blueField.getDocument().addDocumentListener(colorListener); + hexField.getDocument().addDocumentListener(colorListener); + + setColor(initialColor); +// System.out.println("4: " + hexField.getInsets()); + } + + + //hexField.setText("#FFFFFF"); + + + public void show() { + window.setVisible(true); + window.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); + } + + + public void hide() { + window.setVisible(false); + } + + + public Color getColor() { + return new Color(red, green, blue); + } + + + public void setColor(Color color) { + updateRGB(color.getRGB()); + } + + + public String getHexColor() { + return "#" + PApplet.hex(red, 2) + PApplet.hex(green, 2) + PApplet.hex(blue, 2); + } + + + public class ColorListener implements DocumentListener { + + public void changedUpdate(DocumentEvent e) { + //System.out.println("changed"); + } + + public void removeUpdate(DocumentEvent e) { + //System.out.println("remove"); + } + + + boolean updating; + + public void insertUpdate(DocumentEvent e) { + if (updating) return; // don't update forever recursively + updating = true; + + Document doc = e.getDocument(); + if (doc == hueField.getDocument()) { + hue = bounded(hue, hueField, 359); + updateRGB(); + updateHex(); + + } else if (doc == saturationField.getDocument()) { + saturation = bounded(saturation, saturationField, 99); + updateRGB(); + updateHex(); + + } else if (doc == brightnessField.getDocument()) { + brightness = bounded(brightness, brightnessField, 99); + updateRGB(); + updateHex(); + + } else if (doc == redField.getDocument()) { + red = bounded(red, redField, 255); + updateHSB(); + updateHex(); + + } else if (doc == greenField.getDocument()) { + green = bounded(green, greenField, 255); + updateHSB(); + updateHex(); + + } else if (doc == blueField.getDocument()) { + blue = bounded(blue, blueField, 255); + updateHSB(); + updateHex(); + + } else if (doc == hexField.getDocument()) { + String str = hexField.getText(); + if (str.startsWith("#")) { + str = str.substring(1); + } + while (str.length() < 6) { + str += "0"; + } + if (str.length() > 6) { + str = str.substring(0, 6); + } + updateRGB(Integer.parseInt(str, 16)); + updateHSB(); + } + range.redraw(); + slider.redraw(); + //colorPanel.setBackground(new Color(red, green, blue)); + colorPanel.repaint(); + updating = false; + } +} + + + /** + * Set the RGB values based on the current HSB values. + */ + protected void updateRGB() { + updateRGB(Color.HSBtoRGB(hue / 359f, + saturation / 99f, + brightness / 99f)); + } + + + /** + * Set the RGB values based on a calculated ARGB int. + * Used by both updateRGB() to set the color from the HSB values, + * and by updateHex(), to unpack the hex colors and assign them. + */ + protected void updateRGB(int rgb) { + red = (rgb >> 16) & 0xff; + green = (rgb >> 8) & 0xff; + blue = rgb & 0xff; + + redField.setText(String.valueOf(red)); + greenField.setText(String.valueOf(green)); + blueField.setText(String.valueOf(blue)); + } + + + /** + * Set the HSB values based on the current RGB values. + */ + protected void updateHSB() { + float hsb[] = new float[3]; + Color.RGBtoHSB(red, green, blue, hsb); + + hue = (int) (hsb[0] * 359.0f); + saturation = (int) (hsb[1] * 99.0f); + brightness = (int) (hsb[2] * 99.0f); + + hueField.setText(String.valueOf(hue)); + saturationField.setText(String.valueOf(saturation)); + brightnessField.setText(String.valueOf(brightness)); + } + + + protected void updateHex() { + hexField.setText(getHexColor()); + } + + + /** + * Get the bounded value for a specific range. If the value is outside + * the max, you can't edit right away, so just act as if it's already + * been bounded and return the bounded value, then fire an event to set + * it to the value that was just returned. + */ + protected int bounded(int current, final JTextField field, final int max) { + String text = field.getText(); + if (text.length() == 0) { + return 0; + } + try { + int value = Integer.parseInt(text); + if (value > max) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + field.setText(String.valueOf(max)); + } + }); + return max; + } + return value; + + } catch (NumberFormatException e) { + return current; // should not be reachable + } + } + + + protected Container createColorFields(String buttonName, ActionListener buttonListener) { + Box box = Box.createVerticalBox(); + box.setAlignmentY(0); + + final int GAP = Base.isWindows() ? 5 : 0; + final int BETWEEN = Base.isWindows() ? 8 : 6; //10; + + Box row; + + row = Box.createHorizontalBox(); + if (Base.isMacOS()) { + row.add(Box.createHorizontalStrut(17)); + } else { + row.add(createFixedLabel("")); + } + // Can't just set the bg color of the panel because it also tints the bevel + // (on OS X), which looks odd. So instead we override paintComponent(). + colorPanel = new JPanel() { + public void paintComponent(Graphics g) { + g.setColor(new Color(red, green, blue)); + Dimension size = getSize(); + g.fillRect(0, 0, size.width, size.height); + } + }; + colorPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); + Dimension dim = new Dimension(70, 25); + colorPanel.setMinimumSize(dim); + colorPanel.setMaximumSize(dim); + colorPanel.setPreferredSize(dim); + row.add(colorPanel); + row.add(Box.createHorizontalGlue()); + box.add(row); + box.add(Box.createVerticalStrut(BETWEEN)); +// if (Base.isMacOS()) { // need a little extra +// box.add(Box.createVerticalStrut(BETWEEN)); +// } + + + row = Box.createHorizontalBox(); + row.add(createFixedLabel("H")); + row.add(hueField = new NumberField(4, false)); + row.add(new JLabel(" \u00B0")); // degree symbol + row.add(Box.createHorizontalGlue()); + box.add(row); + box.add(Box.createVerticalStrut(GAP)); + + row = Box.createHorizontalBox(); + row.add(createFixedLabel("S")); + row.add(saturationField = new NumberField(4, false)); + row.add(new JLabel(" %")); + row.add(Box.createHorizontalGlue()); + box.add(row); + box.add(Box.createVerticalStrut(GAP)); + + row = Box.createHorizontalBox(); + row.add(createFixedLabel("B")); + row.add(brightnessField = new NumberField(4, false)); + row.add(new JLabel(" %")); + row.add(Box.createHorizontalGlue()); + box.add(row); + box.add(Box.createVerticalStrut(BETWEEN)); + + // + + row = Box.createHorizontalBox(); + row.add(createFixedLabel("R")); + row.add(redField = new NumberField(4, false)); + row.add(Box.createHorizontalGlue()); + box.add(row); + box.add(Box.createVerticalStrut(GAP)); + + row = Box.createHorizontalBox(); + row.add(createFixedLabel("G")); + row.add(greenField = new NumberField(4, false)); + row.add(Box.createHorizontalGlue()); + box.add(row); + box.add(Box.createVerticalStrut(GAP)); + + row = Box.createHorizontalBox(); + row.add(createFixedLabel("B")); + row.add(blueField = new NumberField(4, false)); + row.add(Box.createHorizontalGlue()); + box.add(row); + box.add(Box.createVerticalStrut(BETWEEN)); + + // + + row = Box.createHorizontalBox(); + row.add(createFixedLabel("")); + // Windows needs extra space, OS X and Linux do not + // Mac OS X needs 6 because #CCCCCC is quite wide + final int hexCount = Base.isWindows() ? 7 : 6; + row.add(hexField = new NumberField(hexCount, true)); + row.add(Box.createHorizontalGlue()); + box.add(row); + box.add(Box.createVerticalStrut(GAP)); + + // + +// // Not great, because the insets make things weird anyway +// //Dimension dim = new Dimension(hexField.getPreferredSize()); +// Dimension dim = new Dimension(70, 20); +// colorPanel.setMinimumSize(dim); +// colorPanel.setMaximumSize(dim); +// colorPanel.setPreferredSize(dim); +//// colorPanel.setBorder(new EmptyBorder(hexField.getInsets())); + + // + + row = Box.createHorizontalBox(); + if (Base.isMacOS()) { + row.add(Box.createHorizontalStrut(11)); + } else { + row.add(createFixedLabel("")); + } + JButton button = new JButton(buttonName); + button.addActionListener(buttonListener); + //System.out.println("button: " + button.getInsets()); + row.add(button); + row.add(Box.createHorizontalGlue()); + box.add(row); + + // + + box.add(Box.createVerticalGlue()); + return box; + } + + + int labelH; + + /** + * return a label of a fixed width + */ + protected JLabel createFixedLabel(String title) { + JLabel label = new JLabel(title); + if (labelH == 0) { + labelH = label.getPreferredSize().height; + } + Dimension dim = new Dimension(15, labelH); + label.setPreferredSize(dim); + label.setMinimumSize(dim); + label.setMaximumSize(dim); + return label; + } + + + public class ColorRange extends PApplet { + + static final int WIDE = 256; + static final int HIGH = 256; + + int lastX, lastY; + + + public void setup() { + size(WIDE, HIGH); //, P3D); + noLoop(); + + colorMode(HSB, 360, 256, 256); + noFill(); + rectMode(CENTER); + + loadPixels(); + } + + public void draw() { +// if ((g == null) || (g.pixels == null)) return; + if ((width != WIDE) || (height < HIGH)) { + //System.out.println("bad size " + width + " " + height); + return; + } + + int index = 0; + for (int j = 0; j < 256; j++) { + for (int i = 0; i < 256; i++) { + pixels[index++] = color(hue, i, 255 - j); + } + } + + updatePixels(); + stroke((brightness > 50) ? 0 : 255); + rect(lastX, lastY, 9, 9); + } + + public void mousePressed() { + updateMouse(); + } + + public void mouseDragged() { + updateMouse(); + } + + public void updateMouse() { + if ((mouseX >= 0) && (mouseX < 256) && + (mouseY >= 0) && (mouseY < 256)) { + int nsaturation = (int) (100 * (mouseX / 255.0f)); + int nbrightness = 100 - ((int) (100 * (mouseY / 255.0f))); + saturationField.setText(String.valueOf(nsaturation)); + brightnessField.setText(String.valueOf(nbrightness)); + + lastX = mouseX; + lastY = mouseY; + } + } + + public Dimension getPreferredSize() { + return new Dimension(WIDE, HIGH); + } + + public Dimension getMinimumSize() { + return new Dimension(WIDE, HIGH); + } + + public Dimension getMaximumSize() { + return new Dimension(WIDE, HIGH); + } + + public void keyPressed() { + if (key == ESC) { + ColorChooser.this.hide(); + // don't quit out of processing + // http://dev.processing.org/bugs/show_bug.cgi?id=1006 + key = 0; + } + } + } + + + public class ColorSlider extends PApplet { + + static final int WIDE = 20; + static final int HIGH = 256; + + public void setup() { + size(WIDE, HIGH); //, P3D); + colorMode(HSB, 255, 100, 100); + noLoop(); + loadPixels(); + } + + public void draw() { +// if ((g == null) || (g.pixels == null)) return; + if ((width != WIDE) || (height < HIGH)) { + //System.out.println("bad size " + width + " " + height); + return; + } + + int index = 0; + int sel = 255 - (int) (255 * (hue / 359f)); + for (int j = 0; j < 256; j++) { + int c = color(255 - j, 100, 100); + if (j == sel) c = 0xFF000000; + for (int i = 0; i < WIDE; i++) { + g.pixels[index++] = c; + } + } + updatePixels(); + } + + public void mousePressed() { + updateMouse(); + } + + public void mouseDragged() { + updateMouse(); + } + + public void updateMouse() { + if ((mouseX >= 0) && (mouseX < 256) && + (mouseY >= 0) && (mouseY < 256)) { + int nhue = 359 - (int) (359 * (mouseY / 255.0f)); + hueField.setText(String.valueOf(nhue)); + } + } + + public Dimension getPreferredSize() { + return new Dimension(WIDE, HIGH); + } + + public Dimension getMinimumSize() { + return new Dimension(WIDE, HIGH); + } + + public Dimension getMaximumSize() { + return new Dimension(WIDE, HIGH); + } + + public void keyPressed() { + if (key == ESC) { + ColorChooser.this.hide(); + // don't quit out of processing + // http://dev.processing.org/bugs/show_bug.cgi?id=1006 + key = 0; + } + } + } + + + /** + * Extension of JTextField that only allows numbers + */ + class NumberField extends JTextField { + + public boolean allowHex; + + public NumberField(int cols, boolean allowHex) { + super(cols); + this.allowHex = allowHex; + } + + protected Document createDefaultModel() { + return new NumberDocument(this); + } + + public Dimension getPreferredSize() { + if (!allowHex) { + return new Dimension(45, super.getPreferredSize().height); + } + return super.getPreferredSize(); + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + public Dimension getMaximumSize() { + return getPreferredSize(); + } + } + + + /** + * Document model to go with JTextField that only allows numbers. + */ + class NumberDocument extends PlainDocument { + + NumberField parentField; + + public NumberDocument(NumberField parentField) { + this.parentField = parentField; + //System.out.println("setting parent to " + parentSelector); + } + + public void insertString(int offs, String str, AttributeSet a) + throws BadLocationException { + + if (str == null) return; + + char chars[] = str.toCharArray(); + int charCount = 0; + // remove any non-digit chars + for (int i = 0; i < chars.length; i++) { + boolean ok = Character.isDigit(chars[i]); + if (parentField.allowHex) { + if ((chars[i] >= 'A') && (chars[i] <= 'F')) ok = true; + if ((chars[i] >= 'a') && (chars[i] <= 'f')) ok = true; + if ((offs == 0) && (i == 0) && (chars[i] == '#')) ok = true; + } + if (ok) { + if (charCount != i) { // shift if necessary + chars[charCount] = chars[i]; + } + charCount++; + } + } + super.insertString(offs, new String(chars, 0, charCount), a); + // can't call any sort of methods on the enclosing class here + // seems to have something to do with how Document objects are set up + } + } + + +// static public void main(String[] args) { +// ColorSelector cs = new ColorSelector(); +// cs.init(null); +// EventQueue.invokeLater(cs); +// } +} diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 8cfb77773..cfe93d750 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -1021,11 +1021,21 @@ public abstract class Editor extends JFrame implements RunnerListener { } catch (NoSuchMethodError nsme) { System.err.println("\"" + tool.getMenuTitle() + "\" is not " + "compatible with this version of Processing"); - System.err.println("This method no longer exists: " + nsme.getMessage()); + System.err.println("The " + nsme.getMessage() + " method no longer exists."); Base.log("Incompatible Tool found during tool.init()", nsme); - } catch (Exception ex) { + } catch (NoClassDefFoundError ncdfe) { + System.err.println("\"" + tool.getMenuTitle() + "\" is not " + + "compatible with this version of Processing"); + System.err.println("The " + ncdfe.getMessage() + " class is no longer available."); + Base.log("Incompatible Tool found during tool.init()", ncdfe); + + } catch (Error err) { System.err.println("An error occurred inside \"" + tool.getMenuTitle() + "\""); + err.printStackTrace(); + + } catch (Exception ex) { + System.err.println("An exception occurred inside \"" + tool.getMenuTitle() + "\""); ex.printStackTrace(); } } diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index 8c5d6dcde..68f94d44b 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -430,8 +430,8 @@ public class Preferences { deletePreviousBox.setBounds(left, top, d.width + 10, d.height); right = Math.max(right, left + d.width); top += d.height + GUI_BETWEEN; - - + + // // [ ] Use external editor // // externalEditorBox = new JCheckBox("Use external editor"); diff --git a/app/src/processing/app/Toolkit.java b/app/src/processing/app/Toolkit.java index e549371af..357621714 100644 --- a/app/src/processing/app/Toolkit.java +++ b/app/src/processing/app/Toolkit.java @@ -24,12 +24,12 @@ package processing.app; import java.awt.Dimension; import java.awt.Font; import java.awt.FontFormatException; -import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Image; +import java.awt.Window; import java.awt.datatransfer.Clipboard; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -151,12 +151,21 @@ public class Toolkit { static ArrayList iconImages; + + // Removed in favor of Window being the base object, so that dialogs can + // be supported as well. If this breaks tools/modes, we can bring it back, + // but it was essentially an undocumented feature. +// static public void setIcon(Frame frame) { +// setIcon(frame); +// } + + /** * Give this Frame the Processing icon set. Ignored on OS X, because they * thought different and made this function set the minified image of the * window, not the window icon for the dock or cmd-tab. */ - static public void setIcon(Frame frame) { + static public void setIcon(Window window) { if (!Base.isMacOS()) { // // too low-res, prepping for nicer icons in 2.0 timeframe // Image image = awtToolkit.createImage(PApplet.ICON_IMAGE); @@ -169,7 +178,7 @@ public class Toolkit { iconImages.add(Toolkit.getLibImage("icons/pde-" + sz + ".png")); } } - frame.setIconImages(iconImages); + window.setIconImages(iconImages); } } diff --git a/app/src/processing/app/exec/ProcessHelper.java b/app/src/processing/app/exec/ProcessHelper.java index 66e9d331f..0bbd2aa97 100644 --- a/app/src/processing/app/exec/ProcessHelper.java +++ b/app/src/processing/app/exec/ProcessHelper.java @@ -128,37 +128,19 @@ public class ProcessHelper { } -// static public ProcessResult execute(String exe, String[] args, File dir) -// throws InterruptedException, IOException { -// final StringWriter outWriter = new StringWriter(); -// final StringWriter errWriter = new StringWriter(); -// final long startTime = System.currentTimeMillis(); -// -// final String prettyCommand = exe + " " + PApplet.join(args, " "); -// System.out.println("pretty cmd is " + prettyCommand); -// final Process process = dir == null ? -// Runtime.getRuntime().exec(exe, args) : -// Runtime.getRuntime().exec(exe, args, dir); -// ProcessRegistry.watch(process); -// try { -// String title = prettyCommand; -// new StreamPump(process.getInputStream(), "out: " + title).addTarget(outWriter).start(); -// new StreamPump(process.getErrorStream(), "err: " + title).addTarget(errWriter).start(); -// try { -// final int result = process.waitFor(); -// final long time = System.currentTimeMillis() - startTime; -// // System.err.println("ProcessHelper: <<<<< " -// // + Thread.currentThread().getId() + " " + cmd[0] + " (" + time -// // + "ms)"); -// return new ProcessResult(prettyCommand, result, outWriter.toString(), -// errWriter.toString(), time); -// } catch (final InterruptedException e) { -// System.err.println("Interrupted: " + prettyCommand); -// throw e; -// } -// } finally { -// process.destroy(); -// ProcessRegistry.unwatch(process); -// } -// } + static public boolean ffs(final String... cmd) { + try { + ProcessHelper helper = new ProcessHelper(cmd); + ProcessResult result = helper.execute(); + if (result.succeeded()) { + return true; + } + System.out.println(result.getStdout()); + System.err.println(result.getStderr()); + + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } } \ No newline at end of file diff --git a/app/src/processing/app/syntax/TextAreaPainter.java b/app/src/processing/app/syntax/TextAreaPainter.java index 8bafb1d4e..8c971605c 100644 --- a/app/src/processing/app/syntax/TextAreaPainter.java +++ b/app/src/processing/app/syntax/TextAreaPainter.java @@ -672,10 +672,11 @@ public class TextAreaPainter extends JComponent implements TabExpander { y += fm.getHeight(); // doesn't respect fixed width like it should // x = Utilities.drawTabbedText(currentLine, x, y, gfx, this, 0); - int w = fm.charWidth(' '); +// int w = fm.charWidth(' '); for (int i = 0; i < currentLine.count; i++) { gfx.drawChars(currentLine.array, currentLine.offset+i, 1, x, y); - x += w; + x = currentLine.array[currentLine.offset + i] == '\t' ? (int)nextTabStop(x, i) : + x + fm.charWidth(currentLine.array[currentLine.offset+i]); } // Draw characters via input method. @@ -767,10 +768,11 @@ public class TextAreaPainter extends JComponent implements TabExpander { // doesn't respect mono metrics, insists on spacing w/ fractional or something // x = Utilities.drawTabbedText(line, x, y, gfx, this, 0); // gfx.drawChars(line.array, line.offset, line.count, x, y); - int w = fm.charWidth(' '); +// int w = fm.charWidth(' '); for (int i = 0; i < line.count; i++) { gfx.drawChars(line.array, line.offset+i, 1, x, y); - x += w; + x = line.array[line.offset + i] == '\t' ? (int)nextTabStop(x, i) : + x + fm.charWidth(line.array[line.offset+i]); } //x += fm.charsWidth(line.array, line.offset, line.count); //x += fm.charWidth(' ') * line.count; @@ -908,4 +910,4 @@ public class TextAreaPainter extends JComponent implements TabExpander { } } } -} \ No newline at end of file +} diff --git a/app/src/processing/app/tools/ColorSelector.java b/app/src/processing/app/tools/ColorSelector.java index ed3de640b..68bc92b68 100644 --- a/app/src/processing/app/tools/ColorSelector.java +++ b/app/src/processing/app/tools/ColorSelector.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2006-12 Ben Fry and Casey Reas + Copyright (c) 2006-14 Ben Fry and Casey Reas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 @@ -22,19 +22,11 @@ package processing.app.tools; import processing.app.*; -import processing.core.*; -import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Container; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.Graphics; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.awt.event.*; -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.event.*; -import javax.swing.text.*; /** @@ -45,597 +37,36 @@ import javax.swing.text.*; * auto-insert of colorMode() or fill() or stroke() code cuz we couldn't * decide on a good way to do this.. your contributions welcome). */ -public class ColorSelector implements Tool, DocumentListener { - -// Editor editor; +public class ColorSelector implements Tool { /** * Only create one instance, otherwise we'll have dozens of animation * threads going if you open/close a lot of editor windows. */ - static JFrame frame; - - int hue, saturation, brightness; // range 360, 100, 100 - int red, green, blue; // range 256, 256, 256 - - ColorRange range; - ColorSlider slider; - - JTextField hueField, saturationField, brightnessField; - JTextField redField, greenField, blueField; - - JTextField hexField; - - JPanel colorPanel; - + static ColorChooser selector; + public String getMenuTitle() { return "Color Selector"; } public void init(Editor editor) { -// this.editor = editor; - if (frame == null) { - createFrame(); + if (selector == null) { + selector = new ColorChooser(editor, false, Color.WHITE, + "Copy", new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + Clipboard clipboard = Toolkit.getSystemClipboard(); + clipboard.setContents(new StringSelection(selector.getHexColor()), null); + } + }); } } - void createFrame() { - frame = new JFrame("Color Selector"); - frame.getContentPane().setLayout(new BorderLayout()); - - Box box = Box.createHorizontalBox(); - box.setBorder(new EmptyBorder(12, 12, 12, 12)); - - range = new ColorRange(); - range.init(); - Box rangeBox = new Box(BoxLayout.Y_AXIS); - rangeBox.setAlignmentY(0); - rangeBox.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - rangeBox.add(range); - box.add(rangeBox); - box.add(Box.createHorizontalStrut(10)); - - slider = new ColorSlider(); - slider.init(); - Box sliderBox = new Box(BoxLayout.Y_AXIS); - sliderBox.setAlignmentY(0); - sliderBox.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - sliderBox.add(slider); - box.add(sliderBox); - box.add(Box.createHorizontalStrut(10)); - - box.add(createColorFields()); - box.add(Box.createHorizontalStrut(10)); - - frame.getContentPane().add(box, BorderLayout.CENTER); - frame.pack(); - frame.setResizable(false); - - // these don't help either.. they fix the component size but - // leave a gap where the component is located - //range.setSize(256, 256); - //slider.setSize(256, 20); - - Dimension size = frame.getSize(); - Dimension screen = Toolkit.getScreenSize(); - frame.setLocation((screen.width - size.width) / 2, - (screen.height - size.height) / 2); - - frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - frame.setVisible(false); - } - }); - Toolkit.registerWindowCloseKeys(frame.getRootPane(), new ActionListener() { - public void actionPerformed(ActionEvent actionEvent) { - frame.setVisible(false); - } - }); - - Toolkit.setIcon(frame); - - hueField.getDocument().addDocumentListener(this); - saturationField.getDocument().addDocumentListener(this); - brightnessField.getDocument().addDocumentListener(this); - redField.getDocument().addDocumentListener(this); - greenField.getDocument().addDocumentListener(this); - blueField.getDocument().addDocumentListener(this); - hexField.getDocument().addDocumentListener(this); - - hexField.setText("#FFFFFF"); - } - - public void run() { - frame.setVisible(true); - // You've got to be f--ing kidding me.. why did the following line - // get deprecated for the pile of s-- that follows it? - //frame.setCursor(Cursor.CROSSHAIR_CURSOR); - frame.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); + selector.show(); } - - - public void changedUpdate(DocumentEvent e) { - //System.out.println("changed"); - } - - public void removeUpdate(DocumentEvent e) { - //System.out.println("remove"); - } - - - boolean updating; - - public void insertUpdate(DocumentEvent e) { - if (updating) return; // don't update forever recursively - updating = true; - - Document doc = e.getDocument(); - if (doc == hueField.getDocument()) { - hue = bounded(hue, hueField, 359); - updateRGB(); - updateHex(); - - } else if (doc == saturationField.getDocument()) { - saturation = bounded(saturation, saturationField, 99); - updateRGB(); - updateHex(); - - } else if (doc == brightnessField.getDocument()) { - brightness = bounded(brightness, brightnessField, 99); - updateRGB(); - updateHex(); - - } else if (doc == redField.getDocument()) { - red = bounded(red, redField, 255); - updateHSB(); - updateHex(); - - } else if (doc == greenField.getDocument()) { - green = bounded(green, greenField, 255); - updateHSB(); - updateHex(); - - } else if (doc == blueField.getDocument()) { - blue = bounded(blue, blueField, 255); - updateHSB(); - updateHex(); - - } else if (doc == hexField.getDocument()) { - String str = hexField.getText(); - if (str.startsWith("#")) { - str = str.substring(1); - } - while (str.length() < 6) { - str += "0"; - } - if (str.length() > 6) { - str = str.substring(0, 6); - } - updateRGB2(Integer.parseInt(str, 16)); - updateHSB(); - } - range.redraw(); - slider.redraw(); - colorPanel.repaint(); - updating = false; - } - - - /** - * Set the RGB values based on the current HSB values. - */ - protected void updateRGB() { - int rgb = Color.HSBtoRGB(hue / 359f, - saturation / 99f, - brightness / 99f); - updateRGB2(rgb); - } - - - /** - * Set the RGB values based on a calculated ARGB int. - * Used by both updateRGB() to set the color from the HSB values, - * and by updateHex(), to unpack the hex colors and assign them. - */ - protected void updateRGB2(int rgb) { - red = (rgb >> 16) & 0xff; - green = (rgb >> 8) & 0xff; - blue = rgb & 0xff; - - redField.setText(String.valueOf(red)); - greenField.setText(String.valueOf(green)); - blueField.setText(String.valueOf(blue)); - } - - - /** - * Set the HSB values based on the current RGB values. - */ - protected void updateHSB() { - float hsb[] = new float[3]; - Color.RGBtoHSB(red, green, blue, hsb); - - hue = (int) (hsb[0] * 359.0f); - saturation = (int) (hsb[1] * 99.0f); - brightness = (int) (hsb[2] * 99.0f); - - hueField.setText(String.valueOf(hue)); - saturationField.setText(String.valueOf(saturation)); - brightnessField.setText(String.valueOf(brightness)); - } - - - protected void updateHex() { - hexField.setText("#" + - PApplet.hex(red, 2) + - PApplet.hex(green, 2) + - PApplet.hex(blue, 2)); - } - - - /** - * Get the bounded value for a specific range. If the value is outside - * the max, you can't edit right away, so just act as if it's already - * been bounded and return the bounded value, then fire an event to set - * it to the value that was just returned. - */ - protected int bounded(int current, final JTextField field, final int max) { - String text = field.getText(); - if (text.length() == 0) { - return 0; - } - try { - int value = Integer.parseInt(text); - if (value > max) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - field.setText(String.valueOf(max)); - } - }); - return max; - } - return value; - - } catch (NumberFormatException e) { - return current; // should not be reachable - } - } - - - protected Container createColorFields() { - Box box = Box.createVerticalBox(); - box.setAlignmentY(0); - - colorPanel = new JPanel() { - public void paintComponent(Graphics g) { - g.setColor(new Color(red, green, blue)); - Dimension size = getSize(); - g.fillRect(0, 0, size.width, size.height); - } - }; - colorPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - Dimension dim = new Dimension(60, 40); - colorPanel.setMinimumSize(dim); - //colorPanel.setMaximumSize(dim); - //colorPanel.setPreferredSize(dim); - box.add(colorPanel); - box.add(Box.createVerticalStrut(10)); - - Box row; - - row = Box.createHorizontalBox(); - row.add(createFixedLabel("H")); - row.add(hueField = new NumberField(4, false)); - row.add(new JLabel(" \u00B0")); // degree symbol - row.add(Box.createHorizontalGlue()); - box.add(row); - box.add(Box.createVerticalStrut(5)); - - row = Box.createHorizontalBox(); - row.add(createFixedLabel("S")); - row.add(saturationField = new NumberField(4, false)); - row.add(new JLabel(" %")); - row.add(Box.createHorizontalGlue()); - box.add(row); - box.add(Box.createVerticalStrut(5)); - - row = Box.createHorizontalBox(); - row.add(createFixedLabel("B")); - row.add(brightnessField = new NumberField(4, false)); - row.add(new JLabel(" %")); - row.add(Box.createHorizontalGlue()); - box.add(row); - box.add(Box.createVerticalStrut(10)); - - // - - row = Box.createHorizontalBox(); - row.add(createFixedLabel("R")); - row.add(redField = new NumberField(4, false)); - row.add(Box.createHorizontalGlue()); - box.add(row); - box.add(Box.createVerticalStrut(5)); - - row = Box.createHorizontalBox(); - row.add(createFixedLabel("G")); - row.add(greenField = new NumberField(4, false)); - row.add(Box.createHorizontalGlue()); - box.add(row); - box.add(Box.createVerticalStrut(5)); - - row = Box.createHorizontalBox(); - row.add(createFixedLabel("B")); - row.add(blueField = new NumberField(4, false)); - row.add(Box.createHorizontalGlue()); - box.add(row); - box.add(Box.createVerticalStrut(10)); - - // - - row = Box.createHorizontalBox(); - row.add(createFixedLabel("")); - row.add(hexField = new NumberField(5, true)); - row.add(Box.createHorizontalGlue()); - box.add(row); - box.add(Box.createVerticalStrut(10)); - - box.add(Box.createVerticalGlue()); - return box; - } - - - int labelH; - - /** - * return a label of a fixed width - */ - protected JLabel createFixedLabel(String title) { - JLabel label = new JLabel(title); - if (labelH == 0) { - labelH = label.getPreferredSize().height; - } - Dimension dim = new Dimension(20, labelH); - label.setPreferredSize(dim); - label.setMinimumSize(dim); - label.setMaximumSize(dim); - return label; - } - - - public class ColorRange extends PApplet { - - static final int WIDE = 256; - static final int HIGH = 256; - - int lastX, lastY; - - - public void setup() { - size(WIDE, HIGH); //, P3D); - noLoop(); - - colorMode(HSB, 360, 256, 256); - noFill(); - rectMode(CENTER); - - loadPixels(); - } - - public void draw() { -// if ((g == null) || (g.pixels == null)) return; - if ((width != WIDE) || (height < HIGH)) { - //System.out.println("bad size " + width + " " + height); - return; - } - - int index = 0; - for (int j = 0; j < 256; j++) { - for (int i = 0; i < 256; i++) { - pixels[index++] = color(hue, i, 255 - j); - } - } - - updatePixels(); - stroke((brightness > 50) ? 0 : 255); - rect(lastX, lastY, 9, 9); - } - - public void mousePressed() { - updateMouse(); - } - - public void mouseDragged() { - updateMouse(); - } - - public void updateMouse() { - if ((mouseX >= 0) && (mouseX < 256) && - (mouseY >= 0) && (mouseY < 256)) { - int nsaturation = (int) (100 * (mouseX / 255.0f)); - int nbrightness = 100 - ((int) (100 * (mouseY / 255.0f))); - saturationField.setText(String.valueOf(nsaturation)); - brightnessField.setText(String.valueOf(nbrightness)); - - lastX = mouseX; - lastY = mouseY; - } - } - - public Dimension getPreferredSize() { - return new Dimension(WIDE, HIGH); - } - - public Dimension getMinimumSize() { - return new Dimension(WIDE, HIGH); - } - - public Dimension getMaximumSize() { - return new Dimension(WIDE, HIGH); - } - - public void keyPressed() { - if (key == ESC) { - ColorSelector.frame.setVisible(false); - // don't quit out of processing - // http://dev.processing.org/bugs/show_bug.cgi?id=1006 - key = 0; - } - } - } - - - public class ColorSlider extends PApplet { - - static final int WIDE = 20; - static final int HIGH = 256; - - public void setup() { - size(WIDE, HIGH); //, P3D); - colorMode(HSB, 255, 100, 100); - noLoop(); - loadPixels(); - } - - public void draw() { -// if ((g == null) || (g.pixels == null)) return; - if ((width != WIDE) || (height < HIGH)) { - //System.out.println("bad size " + width + " " + height); - return; - } - - int index = 0; - int sel = 255 - (int) (255 * (hue / 359f)); - for (int j = 0; j < 256; j++) { - int c = color(255 - j, 100, 100); - if (j == sel) c = 0xFF000000; - for (int i = 0; i < WIDE; i++) { - g.pixels[index++] = c; - } - } - updatePixels(); - } - - public void mousePressed() { - updateMouse(); - } - - public void mouseDragged() { - updateMouse(); - } - - public void updateMouse() { - if ((mouseX >= 0) && (mouseX < 256) && - (mouseY >= 0) && (mouseY < 256)) { - int nhue = 359 - (int) (359 * (mouseY / 255.0f)); - hueField.setText(String.valueOf(nhue)); - } - } - - public Dimension getPreferredSize() { - return new Dimension(WIDE, HIGH); - } - - public Dimension getMinimumSize() { - return new Dimension(WIDE, HIGH); - } - - public Dimension getMaximumSize() { - return new Dimension(WIDE, HIGH); - } - - public void keyPressed() { - if (key == ESC) { - ColorSelector.frame.setVisible(false); - // don't quit out of processing - // http://dev.processing.org/bugs/show_bug.cgi?id=1006 - key = 0; - } - } - } - - - /** - * Extension of JTextField that only allows numbers - */ - class NumberField extends JTextField { - - public boolean allowHex; - - public NumberField(int cols, boolean allowHex) { - super(cols); - this.allowHex = allowHex; - } - - protected Document createDefaultModel() { - return new NumberDocument(this); - } - - public Dimension getPreferredSize() { - if (!allowHex) { - return new Dimension(45, super.getPreferredSize().height); - } - return super.getPreferredSize(); - } - - public Dimension getMinimumSize() { - return getPreferredSize(); - } - - public Dimension getMaximumSize() { - return getPreferredSize(); - } - } - - - /** - * Document model to go with JTextField that only allows numbers. - */ - class NumberDocument extends PlainDocument { - - NumberField parentField; - - public NumberDocument(NumberField parentField) { - this.parentField = parentField; - //System.out.println("setting parent to " + parentSelector); - } - - public void insertString(int offs, String str, AttributeSet a) - throws BadLocationException { - - if (str == null) return; - - char chars[] = str.toCharArray(); - int charCount = 0; - // remove any non-digit chars - for (int i = 0; i < chars.length; i++) { - boolean ok = Character.isDigit(chars[i]); - if (parentField.allowHex) { - if ((chars[i] >= 'A') && (chars[i] <= 'F')) ok = true; - if ((chars[i] >= 'a') && (chars[i] <= 'f')) ok = true; - if ((offs == 0) && (i == 0) && (chars[i] == '#')) ok = true; - } - if (ok) { - if (charCount != i) { // shift if necessary - chars[charCount] = chars[i]; - } - charCount++; - } - } - super.insertString(offs, new String(chars, 0, charCount), a); - // can't call any sort of methods on the enclosing class here - // seems to have something to do with how Document objects are set up - } - } - - -// static public void main(String[] args) { -// ColorSelector cs = new ColorSelector(); -// cs.init(null); -// EventQueue.invokeLater(cs); -// } } diff --git a/app/src/processing/app/tools/InstallCommander.java b/app/src/processing/app/tools/InstallCommander.java index c3133de1b..3f5b47748 100644 --- a/app/src/processing/app/tools/InstallCommander.java +++ b/app/src/processing/app/tools/InstallCommander.java @@ -101,6 +101,7 @@ public class InstallCommander implements Tool { String javaRoot = Base.getContentFile(".").getCanonicalPath(); writer.println("cd \"" + javaRoot + "\" && " + Base.getJavaPath() + + " -Djna.nosys=true" + " -cp \"" + classPath + "\"" + " processing.mode.java.Commander \"$@\""); writer.flush(); diff --git a/app/src/processing/mode/java/AutoFormat.java b/app/src/processing/mode/java/AutoFormat.java index f7a86a0bf..935e2a903 100644 --- a/app/src/processing/mode/java/AutoFormat.java +++ b/app/src/processing/mode/java/AutoFormat.java @@ -133,7 +133,7 @@ public class AutoFormat implements Formatter { private void writeIndentedLine() { if (buf.length() == 0) { if (s_flag) { - s_flag = a_flg = false; + s_flag = a_flg = e_flg = false; } return; } @@ -150,9 +150,26 @@ public class AutoFormat implements Formatter { } a_flg = false; } + if (e_flg) { + if (lastNonSpaceChar() == '}') { + trimRight(result); + result.append(" "); + } + e_flg = false; + } result.append(buf); buf.setLength(0); } + + + private char lastNonSpaceChar() { + for (int i=result.length()-1; i>=0; i--) { + char c_i = result.charAt(i); + if (c_i == ' ' || c_i == '\n') continue; + else return c_i; + } + return 0; + } private void writeIndentedComment() { @@ -371,16 +388,12 @@ public class AutoFormat implements Formatter { case ' ': case '\t': - if (lookup("else")) { + e_flg = lookup("else"); + if (e_flg) { gotelse(); if ((!s_flag) || buf.length() > 0) { buf.append(c); } -// // issue https://github.com/processing/processing/issues/364 -// s_flag = false; -// trimRight(result); -// result.append(" "); - writeIndentedLine(); s_flag = false; break; @@ -418,7 +431,8 @@ public class AutoFormat implements Formatter { break; case '{': - if (lookup("else")) { + e_flg = lookup("else"); + if (e_flg) { gotelse(); } if (s_if_lev.length == c_level) { diff --git a/app/src/processing/mode/java/JavaBuild.java b/app/src/processing/mode/java/JavaBuild.java index 5bb3bcf4f..46c18816d 100644 --- a/app/src/processing/mode/java/JavaBuild.java +++ b/app/src/processing/mode/java/JavaBuild.java @@ -26,8 +26,15 @@ import java.io.*; import java.util.*; import java.util.zip.*; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DefaultLogger; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; + import processing.app.*; +import processing.app.exec.ProcessHelper; import processing.core.*; +import processing.data.XML; import processing.mode.java.preproc.*; // Would you believe there's a java.lang.Compiler class? I wouldn't. @@ -397,7 +404,7 @@ public class JavaBuild { throw new SketchException(ex.toString()); } - // grab the imports from the code just preproc'd + // grab the imports from the code just preprocessed importedLibraries = new ArrayList(); Library core = mode.getCoreLibrary(); @@ -408,10 +415,21 @@ public class JavaBuild { // System.out.println("extra imports: " + result.extraImports); for (String item : result.extraImports) { +// System.out.println("item = '" + item + "'"); // remove things up to the last dot int dot = item.lastIndexOf('.'); // http://dev.processing.org/bugs/show_bug.cgi?id=1145 String entry = (dot == -1) ? item : item.substring(0, dot); +// System.out.print(entry + " => "); + + if (item.startsWith("static ")) { + // import static - https://github.com/processing/processing/issues/8 + // Remove more stuff. + int dot2 = item.lastIndexOf('.'); + entry = entry.substring(7, (dot2 == -1) ? entry.length() : dot2); +// System.out.println(entry); + } + // System.out.println("library searching for " + entry); Library library = mode.getLibrary(entry); // System.out.println(" found " + library); @@ -427,7 +445,7 @@ public class JavaBuild { // If someone insists on unnecessarily repeating the code folder // import, don't show an error for it. if (codeFolderPackages != null) { - String itemPkg = item.substring(0, item.lastIndexOf('.')); + String itemPkg = entry; for (String pkg : codeFolderPackages) { if (pkg.equals(itemPkg)) { found = true; @@ -435,7 +453,7 @@ public class JavaBuild { } } } - if (ignorableImport(item)) { + if (ignorableImport(entry + '.')) { found = true; } if (!found) { @@ -1092,32 +1110,36 @@ public class JavaBuild { return false; } - /* File folder = null; for (String platformName : PConstants.platformNames) { int platform = Base.getPlatformIndex(platformName); + + // Can only embed Java on the native platform + boolean embedJava = (platform == PApplet.platform) && + Preferences.getBoolean("export.application.embed_java"); + if (Preferences.getBoolean("export.application.platform." + platformName)) { if (Library.hasMultipleArch(platform, importedLibraries)) { // export the 32-bit version folder = new File(sketch.getFolder(), "application." + platformName + "32"); - if (!exportApplication(folder, platform, 32)) { + if (!exportApplication(folder, platform, 32, embedJava && Base.getNativeBits() == 32)) { return false; } // export the 64-bit version folder = new File(sketch.getFolder(), "application." + platformName + "64"); - if (!exportApplication(folder, platform, 64)) { + if (!exportApplication(folder, platform, 64, embedJava && Base.getNativeBits() == 64)) { return false; } } else { // just make a single one for this platform folder = new File(sketch.getFolder(), "application." + platformName); - if (!exportApplication(folder, platform, 0)) { + if (!exportApplication(folder, platform, 0, embedJava)) { return false; } } } } - */ - + + /* File folder = null; String platformName = Base.getPlatformName(); boolean embedJava = Preferences.getBoolean("export.application.embed_java"); @@ -1141,6 +1163,7 @@ public class JavaBuild { return false; } } + */ return true; // all good } @@ -1182,8 +1205,8 @@ public class JavaBuild { /// on macosx, need to copy .app skeleton since that's /// also where the jar files will be placed File dotAppFolder = null; -// String jdkFolderName = null; String jvmRuntime = ""; + String jdkPath = null; if (exportPlatform == PConstants.MACOSX) { dotAppFolder = new File(destFolder, sketch.getName() + ".app"); @@ -1193,10 +1216,9 @@ public class JavaBuild { File jdkFolder = new File(Base.getJavaHome(), "../../.."); String jdkFolderName = jdkFolder.getCanonicalFile().getName(); jvmRuntime = "JVMRuntime\n " + jdkFolderName + ""; + jdkPath = new File(dotAppFolder, "Contents/PlugIns/" + jdkFolderName + ".jdk").getAbsolutePath(); } -// File dotAppSkeleton = mode.getContentFile("application/template.app"); -// Base.copyDir(dotAppSkeleton, dotAppFolder); File contentsFolder = new File(dotAppFolder, "Contents"); contentsFolder.mkdirs(); @@ -1270,6 +1292,7 @@ public class JavaBuild { if (!jarFolder.exists()) jarFolder.mkdirs(); + /* /// on windows, copy the exe file if (exportPlatform == PConstants.WINDOWS) { @@ -1279,7 +1302,7 @@ public class JavaBuild { PrintWriter writer = PApplet.createWriter(batFile); writer.println("@echo off"); String javaPath = embedJava ? ".\\java\\bin\\java.exe" : "java"; - writer.println(javaPath + " -Djava.ext.dirs=lib -Djava.library.path=lib " + sketch.getName()); + writer.println(javaPath + " -Djna.nosys=true -Djava.ext.dirs=lib -Djava.library.path=lib " + sketch.getName()); writer.flush(); writer.close(); } else { @@ -1287,8 +1310,9 @@ public class JavaBuild { new File(destFolder, sketch.getName() + ".exe")); } } + */ - + /// start copying all jar files Vector jarListVector = new Vector(); @@ -1342,7 +1366,6 @@ public class JavaBuild { String includes = Base.contentsToClassPath(sketch.getCodeFolder()); // Use tokens to get rid of extra blanks, which causes huge exports String[] codeList = PApplet.splitTokens(includes, File.pathSeparator); -// String cp = ""; for (int i = 0; i < codeList.length; i++) { if (codeList[i].toLowerCase().endsWith(".jar") || codeList[i].toLowerCase().endsWith(".zip")) { @@ -1354,7 +1377,6 @@ public class JavaBuild { // cp += codeList[i] + File.pathSeparator; } } -// packClassPathIntoZipFile(cp, zos, zipFileContents); // this was double adding the code folder prior to 2.0a2 } zos.flush(); @@ -1363,15 +1385,6 @@ public class JavaBuild { jarListVector.add(sketch.getName() + ".jar"); -// /// add core.jar to the jar destination folder -// -// File bagelJar = Base.isMacOS() ? -// Base.getContentFile("core.jar") : -// Base.getContentFile("lib/core.jar"); -// Base.copyFile(bagelJar, new File(jarFolder, "core.jar")); -// jarListVector.add("core.jar"); - - /// add contents of 'library' folders to the export for (Library library : importedLibraries) { // add each item from the library folder / export list to the output @@ -1384,38 +1397,13 @@ public class JavaBuild { "a big fat lie and does not exist."); } else if (exportFile.isDirectory()) { - //System.err.println("Ignoring sub-folder \"" + exportList[i] + "\""); -// if (exportPlatform == PConstants.MACOSX) { -// // For OS X, copy subfolders to Contents/Resources/Java Base.copyDir(exportFile, new File(jarFolder, exportName)); -// } else { -// // For other platforms, just copy the folder to the same directory -// // as the application. -// Base.copyDir(exportFile, new File(destFolder, exportName)); -// } } else if (exportName.toLowerCase().endsWith(".zip") || exportName.toLowerCase().endsWith(".jar")) { Base.copyFile(exportFile, new File(jarFolder, exportName)); jarListVector.add(exportName); - // old style, prior to 2.0a2 -// } else if ((exportPlatform == PConstants.MACOSX) && -// (exportFile.getName().toLowerCase().endsWith(".jnilib"))) { -// // jnilib files can be placed in Contents/Resources/Java -// Base.copyFile(exportFile, new File(jarFolder, exportName)); -// -// } else { -// // copy the file to the main directory.. prolly a .dll or something -// Base.copyFile(exportFile, new File(destFolder, exportName)); -// } - - // first 2.0a2 attempt, until below... -// } else if (exportPlatform == PConstants.MACOSX) { -// Base.copyFile(exportFile, new File(jarFolder, exportName)); -// -// } else { -// Base.copyFile(exportFile, new File(destFolder, exportName)); } else { // Starting with 2.0a2 put extra export files (DLLs, plugins folder, // anything else for libraries) inside lib or Contents/Resources/Java @@ -1451,42 +1439,30 @@ public class JavaBuild { /// figure out run options for the VM - // this is too vague. if anyone is using it, we can bring it back -// String runOptions = Preferences.get("run.options"); List runOptions = new ArrayList(); if (Preferences.getBoolean("run.options.memory")) { runOptions.add("-Xms" + Preferences.get("run.options.memory.initial") + "m"); runOptions.add("-Xmx" + Preferences.get("run.options.memory.maximum") + "m"); } + // https://github.com/processing/processing/issues/2239 + runOptions.add("-Djna.nosys=true"); - StringBuilder jvmOptionsList = new StringBuilder(); - for (String opt : runOptions) { - jvmOptionsList.append(" "); - jvmOptionsList.append(opt); - jvmOptionsList.append(""); - jvmOptionsList.append('\n'); - } - -// if (exportPlatform == PConstants.MACOSX) { -// // If no bits specified (libs are all universal, or no native libs) -// // then exportBits will be 0, and can be controlled via "Get Info". -// // Otherwise, need to specify the bits as a VM option. -// if (exportBits == 32) { -// runOptions += " -d32"; -// } else if (exportBits == 64) { -// runOptions += " -d64"; -// } -// } /// macosx: write out Info.plist (template for classpath, etc) if (exportPlatform == PConstants.MACOSX) { - //String PLIST_TEMPLATE = "template.plist"; + StringBuilder runOptionsXML = new StringBuilder(); + for (String opt : runOptions) { + runOptionsXML.append(" "); + runOptionsXML.append(opt); + runOptionsXML.append(""); + runOptionsXML.append('\n'); + } + String PLIST_TEMPLATE = "Info.plist.tmpl"; File plistTemplate = new File(sketch.getFolder(), PLIST_TEMPLATE); if (!plistTemplate.exists()) { - //plistTemplate = mode.getContentFile("application/template.plist"); - plistTemplate = mode.getContentFile("application/Info.plist.tmpl"); + plistTemplate = mode.getContentFile("application/" + PLIST_TEMPLATE); } File plistFile = new File(dotAppFolder, "Contents/Info.plist"); PrintWriter pw = PApplet.createWriter(plistFile); @@ -1502,31 +1478,16 @@ public class JavaBuild { } while ((index = sb.indexOf("@@jvm_options_list@@")) != -1) { sb.replace(index, index + "@@jvm_options_list@@".length(), - jvmOptionsList.toString()); + runOptionsXML.toString()); } while ((index = sb.indexOf("@@sketch@@")) != -1) { sb.replace(index, index + "@@sketch@@".length(), sketch.getName()); } -// while ((index = sb.indexOf("@@classpath@@")) != -1) { -// sb.replace(index, index + "@@classpath@@".length(), -// exportClassPath.toString()); -// } while ((index = sb.indexOf("@@lsuipresentationmode@@")) != -1) { sb.replace(index, index + "@@lsuipresentationmode@@".length(), Preferences.getBoolean("export.application.fullscreen") ? "4" : "0"); } -// while ((index = sb.indexOf("@@lsarchitecturepriority@@")) != -1) { -// // More about this mess: http://support.apple.com/kb/TS2827 -// // First default to exportBits == 0 case -// String arch = "x86_64\n i386"; -// if (exportBits == 32) { -// arch = "i386"; -// } else if (exportBits == 64) { -// arch = "x86_64"; -// } -// sb.replace(index, index + "@@lsarchitecturepriority@@".length(), arch); -// } lines[i] = sb.toString(); } @@ -1536,17 +1497,93 @@ public class JavaBuild { pw.flush(); pw.close(); + // attempt to code sign if the Xcode tools appear to be installed + if (Base.isMacOS() && new File("/usr/bin/codesign_allocate").exists()) { + if (embedJava) { + ProcessHelper.ffs("codesign", "--force", "--sign", "-", jdkPath); + } + String appPath = dotAppFolder.getAbsolutePath(); + ProcessHelper.ffs("codesign", "--force", "--sign", "-", appPath); + } + } else if (exportPlatform == PConstants.WINDOWS) { - File argsFile = new File(destFolder + "/lib/args.txt"); - PrintWriter pw = PApplet.createWriter(argsFile); + File buildFile = new File(destFolder, "launch4j-build.xml"); + File configFile = new File(destFolder, "launch4j-config.xml"); - // Since this is only on Windows, make sure we use Windows CRLF - pw.print(PApplet.join(runOptions.toArray(new String[0]), " ") + "\r\n"); - pw.print(sketch.getName() + "\r\n"); - pw.print(exportClassPath); + XML project = new XML("project"); + XML target = project.addChild("target"); + target.setString("name", "windows"); + + XML taskdef = target.addChild("taskdef"); + taskdef.setString("name", "launch4j"); + taskdef.setString("classname", "net.sf.launch4j.ant.Launch4jTask"); + String launchPath = mode.getContentFile("application/launch4j").getAbsolutePath(); + taskdef.setString("classpath", launchPath + "/launch4j.jar:" + launchPath + "/lib/xstream.jar"); + + XML launch4j = target.addChild("launch4j"); + // not all launch4j options are available when embedded inside the ant + // build file (i.e. the icon param doesn't work), so use a config file + // + launch4j.setString("configFile", configFile.getAbsolutePath()); + + XML config = new XML("launch4jConfig"); + config.addChild("headerType").setContent("gui"); + config.addChild("dontWrapJar").setContent("true"); + config.addChild("downloadUrl").setContent("http://java.com/download"); + + File exeFile = new File(destFolder, sketch.getName() + ".exe"); + config.addChild("outfile").setContent(exeFile.getAbsolutePath()); + + File iconFile = mode.getContentFile("application/sketch.ico"); + config.addChild("icon").setContent(iconFile.getAbsolutePath()); - pw.flush(); - pw.close(); + XML clazzPath = config.addChild("classPath"); + clazzPath.addChild("mainClass").setContent(sketch.getName()); + for (String jarName : jarList) { + clazzPath.addChild("cp").setContent("lib/" + jarName); + } + XML jre = config.addChild("jre"); + if (embedJava) { + jre.addChild("path").setContent("java"); + } + jre.addChild("minVersion").setContent("1.7.0_40"); + for (String opt : runOptions) { + jre.addChild("opt").setContent(opt); + } + + /* + XML config = launch4j.addChild("config"); + config.setString("headerType", "gui"); + File exeFile = new File(destFolder, sketch.getName() + ".exe"); + config.setString("outfile", exeFile.getAbsolutePath()); + config.setString("dontWrapJar", "true"); + config.setString("jarPath", "lib\\" + jarList[0]); + + File iconFile = mode.getContentFile("application/sketch.ico"); + config.addChild("icon").setContent(iconFile.getAbsolutePath()); + + XML clazzPath = config.addChild("classPath"); + clazzPath.setString("mainClass", sketch.getName()); + for (int i = 1; i < jarList.length; i++) { + String jarName = jarList[i]; + clazzPath.addChild("cp").setContent("lib\\" + jarName); + } + XML jre = config.addChild("jre"); + jre.setString("minVersion", "1.7.0_40"); + //PApplet.join(runOptions.toArray(new String[0]), " ") + for (String opt : runOptions) { + jre.addChild("opt").setContent(opt); + } + */ + + config.save(configFile); + project.save(buildFile); + if (!buildWindowsLauncher(buildFile, "windows")) { + // don't delete the build file, might be useful for debugging + return false; + } + configFile.delete(); + buildFile.delete(); } else { File shellScript = new File(destFolder, sketch.getName()); @@ -1563,7 +1600,9 @@ public class JavaBuild { // https://github.com/processing/processing/issues/2349 pw.print("$APPDIR/java/bin/"); } - pw.print("java " + Preferences.get("run.options") + + String runOptionsStr = + PApplet.join(runOptions.toArray(new String[0]), " "); + pw.print("java " + runOptionsStr + " -Djava.library.path=\"$APPDIR:$APPDIR/lib\"" + " -cp \"" + exportClassPath + "\"" + " " + sketch.getName() + " \"$@\"\n"); @@ -1602,23 +1641,66 @@ public class JavaBuild { } - /// remove the .class files from the export folder. -// for (File file : classFiles) { -// if (!file.delete()) { -// Base.showWarning("Could not delete", -// file.getName() + " could not \n" + -// "be deleted from the applet folder. \n" + -// "You'll need to remove it by hand.", null); -// } -// } - // these will now be removed automatically via the temp folder deleteOnExit() - - /// goodbye return true; } + /** + * Run the launch4j build.xml file through ant to create the exe. + * Most of this code was lifted from Android mode. + */ + protected boolean buildWindowsLauncher(File buildFile, String target) { + Project p = new Project(); + String path = buildFile.getAbsolutePath().replace('\\', '/'); + p.setUserProperty("ant.file", path); + + // deals with a problem where javac error messages weren't coming through + p.setUserProperty("build.compiler", "extJavac"); + + // too chatty + /* + // try to spew something useful to the console + final DefaultLogger consoleLogger = new DefaultLogger(); + consoleLogger.setErrorPrintStream(System.err); + consoleLogger.setOutputPrintStream(System.out); + // WARN, INFO, VERBOSE, DEBUG + consoleLogger.setMessageOutputLevel(Project.MSG_ERR); + p.addBuildListener(consoleLogger); + */ + + DefaultLogger errorLogger = new DefaultLogger(); + ByteArrayOutputStream errb = new ByteArrayOutputStream(); + PrintStream errp = new PrintStream(errb); + errorLogger.setErrorPrintStream(errp); + ByteArrayOutputStream outb = new ByteArrayOutputStream(); + PrintStream outp = new PrintStream(outb); + errorLogger.setOutputPrintStream(outp); + errorLogger.setMessageOutputLevel(Project.MSG_INFO); + p.addBuildListener(errorLogger); + + try { + p.fireBuildStarted(); + p.init(); + final ProjectHelper helper = ProjectHelper.getProjectHelper(); + p.addReference("ant.projectHelper", helper); + helper.parse(p, buildFile); + p.executeTarget(target); + return true; + + } catch (final BuildException e) { + // Send a "build finished" event to the build listeners for this project. + p.fireBuildFinished(e); + + String out = new String(outb.toByteArray()); + String err = new String(errb.toByteArray()); + System.out.println(out); + System.err.println(err); + } + return false; + } + + protected void addManifest(ZipOutputStream zos) throws IOException { ZipEntry entry = new ZipEntry("META-INF/MANIFEST.MF"); zos.putNextEntry(entry); diff --git a/app/src/processing/mode/java/JavaEditor.java b/app/src/processing/mode/java/JavaEditor.java index 676db1272..70e083ea4 100644 --- a/app/src/processing/mode/java/JavaEditor.java +++ b/app/src/processing/mode/java/JavaEditor.java @@ -251,15 +251,18 @@ public class JavaEditor extends Editor { toolbar.deactivate(JavaToolbar.EXPORT); } - + +// JPanel presentColorPanel; +// JTextField presentColorPanel; + protected boolean exportApplicationPrompt() throws IOException, SketchException { JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); panel.add(Box.createVerticalStrut(6)); String line1 = "Export to Application creates double-clickable,"; - //String line2 = "standalone applications for the selected plaforms."; - String line2 = "standalone application for the current plaform."; + String line2 = "standalone applications for the selected plaforms."; + //String line2 = "standalone application for the current plaform."; JLabel label1 = new JLabel(line1, SwingConstants.CENTER); JLabel label2 = new JLabel(line2, SwingConstants.CENTER); label1.setAlignmentX(Component.LEFT_ALIGNMENT); @@ -267,11 +270,10 @@ public class JavaEditor extends Editor { panel.add(label1); panel.add(label2); // The longer line is different between Windows and OS X. - int wide = Math.max(label1.getPreferredSize().width, - label2.getPreferredSize().width); +// int wide = Math.max(label1.getPreferredSize().width, +// label2.getPreferredSize().width); panel.add(Box.createVerticalStrut(12)); - /* final JCheckBox windowsButton = new JCheckBox("Windows"); //windowsButton.setMnemonic(KeyEvent.VK_W); windowsButton.setSelected(Preferences.getBoolean("export.application.platform.windows")); @@ -282,7 +284,6 @@ public class JavaEditor extends Editor { }); final JCheckBox macosxButton = new JCheckBox("Mac OS X"); - //macosxButton.setMnemonic(KeyEvent.VK_M); macosxButton.setSelected(Preferences.getBoolean("export.application.platform.macosx")); macosxButton.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { @@ -309,11 +310,13 @@ public class JavaEditor extends Editor { platformPanel.setBorder(new TitledBorder("Platforms")); //Dimension goodIdea = new Dimension(wide, platformPanel.getPreferredSize().height); //platformPanel.setMaximumSize(goodIdea); - wide = Math.max(wide, platformPanel.getPreferredSize().width); +// wide = Math.max(wide, platformPanel.getPreferredSize().width); platformPanel.setAlignmentX(Component.LEFT_ALIGNMENT); panel.add(platformPanel); - */ + int divWidth = platformPanel.getPreferredSize().width; + // + //int indent = new JCheckBox().getPreferredSize().width; int indent = 0; @@ -338,13 +341,101 @@ public class JavaEditor extends Editor { }); fullScreenButton.setBorder(new EmptyBorder(3, 13, 3, 13)); - boolean embed = Preferences.getBoolean("export.application.embed_java"); - final String embedWarning = "Embedding Java makes larger applications"; - final String nopeWarning = "Users will have to install the latest Java 7"; - final JLabel warningLabel = new JLabel(embed ? embedWarning : nopeWarning); - warningLabel.setBorder(new EmptyBorder(3, 13 + indent, 3, 13)); + JPanel presentPanel = new JPanel(); + presentPanel.setLayout(new BoxLayout(presentPanel, BoxLayout.Y_AXIS)); + Box fullScreenBox = Box.createHorizontalBox(); + fullScreenBox.add(fullScreenButton); - final JCheckBox embedJavaButton = new JCheckBox("Embed Java"); + /* + //run.present.stop.color +// presentColorPanel = new JTextField(); +// presentColorPanel.setFocusable(false); +// presentColorPanel.setEnabled(false); + presentColorPanel = new JPanel() { + public void paintComponent(Graphics g) { + g.setColor(Preferences.getColor("run.present.bgcolor")); + Dimension size = getSize(); + g.fillRect(0, 0, size.width, size.height); + } + }; + presentColorPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); +// presentColorPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED)); + presentColorPanel.setMaximumSize(new Dimension(30, 20)); + fullScreenBox.add(presentColorPanel); + */ + fullScreenBox.add(new ColorPreference("run.present.bgcolor")); + //presentPanel.add(fullScreenButton); + fullScreenBox.add(Box.createHorizontalStrut(10)); + fullScreenBox.add(Box.createHorizontalGlue()); + + presentPanel.add(fullScreenBox); + +// presentColorPanel.addMouseListener(new MouseAdapter() { +// public void mousePressed(MouseEvent e) { +// new ColorListener("run.present.bgcolor"); +// } +// }); + + Box showStopBox = Box.createHorizontalBox(); + showStopBox.add(showStopButton); + showStopBox.add(new ColorPreference("run.present.stop.color")); + showStopBox.add(Box.createHorizontalStrut(10)); + showStopBox.add(Box.createHorizontalGlue()); + presentPanel.add(showStopBox); + + //presentPanel.add(showStopButton); +// presentPanel.add(Box.createHorizontalStrut(10)); +// presentPanel.add(Box.createHorizontalGlue()); + presentPanel.setBorder(new TitledBorder("Full Screen")); +// wide = Math.max(wide, platformPanel.getPreferredSize().width); + presentPanel.setAlignmentX(Component.LEFT_ALIGNMENT); + panel.add(presentPanel); + +// Dimension good; +// good = new Dimension(wide, label1.getPreferredSize().height); +// label1.setMaximumSize(good); +// good = new Dimension(wide, label2.getPreferredSize().height); +// label2.setMaximumSize(good); +// good = new Dimension(wide, presentPanel.getPreferredSize().height); + + // + + JPanel embedPanel = new JPanel(); + embedPanel.setLayout(new BoxLayout(embedPanel, BoxLayout.Y_AXIS)); + + String platformName = null; + if (Base.isMacOS()) { + platformName = "Mac OS X"; + } else if (Base.isWindows()) { + platformName = "Windows (" + Base.getNativeBits() + "-bit)"; + } else if (Base.isLinux()) { + platformName = "Linux (" + Base.getNativeBits() + "-bit)"; + } + + boolean embed = Preferences.getBoolean("export.application.embed_java"); + final String embedWarning = + "
" + +// "" + + "Embedding Java will make the " + platformName + " application " + + "larger, but it will be far more likely to work. " + + "Users on other platforms will need to install Java 7."; + final String nopeWarning = + "
" + +// "" + + "Users on all platforms will have to install the latest " + + "version of Java 7 from http://java.com/download. " + + "
 "; + //"from java.com/download."; + final JLabel warningLabel = new JLabel(embed ? embedWarning : nopeWarning); + warningLabel.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent event) { + Base.openURL("http://java.com/download"); + } + }); + warningLabel.setBorder(new EmptyBorder(3, 13 + indent, 3, 13)); + + final JCheckBox embedJavaButton = + new JCheckBox("Embed Java for " + platformName); embedJavaButton.setSelected(embed); embedJavaButton.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { @@ -359,27 +450,76 @@ public class JavaEditor extends Editor { }); embedJavaButton.setBorder(new EmptyBorder(3, 13, 3, 13)); - JPanel optionPanel = new JPanel(); - optionPanel.setLayout(new BoxLayout(optionPanel, BoxLayout.Y_AXIS)); - optionPanel.add(fullScreenButton); - optionPanel.add(showStopButton); - optionPanel.add(embedJavaButton); - optionPanel.add(warningLabel); - optionPanel.setBorder(new TitledBorder("Options")); -// wide = Math.max(wide, platformPanel.getPreferredSize().width); - optionPanel.setAlignmentX(Component.LEFT_ALIGNMENT); - panel.add(optionPanel); - - Dimension good; - //label1, label2, platformPanel, optionPanel - good = new Dimension(wide, label1.getPreferredSize().height); - label1.setMaximumSize(good); - good = new Dimension(wide, label2.getPreferredSize().height); - label2.setMaximumSize(good); -// good = new Dimension(wide, platformPanel.getPreferredSize().height); -// platformPanel.setMaximumSize(good); - good = new Dimension(wide, optionPanel.getPreferredSize().height); -// optionPanel.setMaximumSize(good); + embedPanel.add(embedJavaButton); + embedPanel.add(warningLabel); + embedPanel.setBorder(new TitledBorder("Embed Java")); + panel.add(embedPanel); + + // + + if (Base.isMacOS()) { + JPanel signPanel = new JPanel(); + signPanel.setLayout(new BoxLayout(signPanel, BoxLayout.Y_AXIS)); + signPanel.setBorder(new TitledBorder("Code Signing")); + + // gatekeeper: http://support.apple.com/kb/ht5290 + // for developers: https://developer.apple.com/developer-id/ + String thePain = + //"" + + "In recent versions of OS X, Apple has introduced the \u201CGatekeeper\u201D system, " + + "which makes it more difficult to run applications like those exported from Processing. "; + + if (new File("/usr/bin/codesign_allocate").exists()) { + thePain += + "This application will be \u201Cself-signed\u201D which means that Finder may report that the " + + "application is from an \u201Cunidentified developer\u201D. If the application will not " + + "run, try right-clicking the app and selecting Open from the pop-up menu. Or you can visit " + + "System Preferences \u2192 Security & Privacy and select Allow apps downloaded from: anywhere. "; + } else { + thePain += + "Gatekeeper requires applications to be \u201Csigned\u201D, or they will be reported as damaged. " + + "To prevent this message, install Xcode (and the Command Line Tools) from the App Store, or visit " + + "System Preferences \u2192 Security & Privacy and select Allow apps downloaded from: anywhere. "; + } + thePain += + "To avoid the messages entirely, manually code sign your app. " + + "For more information: https://developer.apple.com/developer-id/"; + + // xattr -d com.apple.quarantine thesketch.app + + //signPanel.add(new JLabel(thePain)); + //JEditorPane area = new JEditorPane("text/html", thePain); + //JTextPane area = new JEditorPane("text/html", thePain); + +// JTextArea area = new JTextArea(thePain); +// area.setBackground(null); +// area.setFont(new Font("Dialog", Font.PLAIN, 10)); +// area.setLineWrap(true); +// area.setWrapStyleWord(true); + // Are you f-king serious, Java API developers? + JLabel area = new JLabel("
" + thePain + "
"); + + area.setBorder(new EmptyBorder(3, 13, 3, 13)); +// area.setPreferredSize(new Dimension(embedPanel.getPreferredSize().width, 100)); +// area.setPreferredSize(new Dimension(300, 200)); + signPanel.add(area); +// signPanel.add(Box.createHorizontalGlue()); + signPanel.setAlignmentX(Component.LEFT_ALIGNMENT); + + area.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent event) { + Base.openURL("https://developer.apple.com/developer-id/"); + } + }); + + panel.add(signPanel); + } + //System.out.println(panel.getPreferredSize()); +// panel.setMinimumSize(new Dimension(316, 461)); +// panel.setPreferredSize(new Dimension(316, 461)); +// panel.setMaximumSize(new Dimension(316, 461)); + + // String[] options = { "Export", "Cancel" }; final JOptionPane optionPane = new JOptionPane(panel, @@ -391,7 +531,8 @@ public class JavaEditor extends Editor { final JDialog dialog = new JDialog(this, "Export Application", true); dialog.setContentPane(optionPane); - +// System.out.println(optionPane.getLayout()); + optionPane.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { String prop = e.getPropertyName(); @@ -406,12 +547,17 @@ public class JavaEditor extends Editor { } }); dialog.pack(); +// System.out.println("after pack: " + panel.getPreferredSize()); +// dialog.setSize(optionPane.getPreferredSize()); dialog.setResizable(false); - + + // Center the window in the middle of the editor Rectangle bounds = getBounds(); dialog.setLocation(bounds.x + (bounds.width - dialog.getSize().width) / 2, bounds.y + (bounds.height - dialog.getSize().height) / 2); dialog.setVisible(true); + + //System.out.println(panel.getSize()); Object value = optionPane.getValue(); if (value.equals(options[0])) { @@ -423,7 +569,90 @@ public class JavaEditor extends Editor { return false; } + /* + Color bgcolor = Preferences.getColor("run.present.bgcolor"); + final ColorChooser c = new ColorChooser(JavaEditor.this, true, bgcolor, + "Select", new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + Preferences.setColor("run.present.bgcolor", c.getColor()); + } + }); + */ + /* + class ColorListener implements ActionListener { + ColorChooser chooser; + String prefName; + + public ColorListener(String prefName) { + this.prefName = prefName; + Color color = Preferences.getColor(prefName); + chooser = new ColorChooser(JavaEditor.this, true, color, "Select", this); + chooser.show(); + } + + @Override + public void actionPerformed(ActionEvent e) { + Color color = chooser.getColor(); + Preferences.setColor(prefName, color); +// presentColorPanel.setBackground(color); + presentColorPanel.repaint(); + chooser.hide(); + } + } + */ + + class ColorPreference extends JPanel implements ActionListener { + ColorChooser chooser; + String prefName; + + public ColorPreference(String pref) { + prefName = pref; + + setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); + setPreferredSize(new Dimension(30, 20)); + setMaximumSize(new Dimension(30, 20)); + + addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + Color color = Preferences.getColor(prefName); + chooser = new ColorChooser(JavaEditor.this, true, color, "Select", ColorPreference.this); + chooser.show(); + } + }); + } + + public void paintComponent(Graphics g) { + g.setColor(Preferences.getColor(prefName)); + Dimension size = getSize(); + g.fillRect(0, 0, size.width, size.height); + } + + public void actionPerformed(ActionEvent e) { + Color color = chooser.getColor(); + Preferences.setColor(prefName, color); + //presentColorPanel.repaint(); + repaint(); + chooser.hide(); + } + } + + +// protected void selectColor(String prefName) { +// Color color = Preferences.getColor(prefName); +// final ColorChooser chooser = new ColorChooser(JavaEditor.this, true, color, +// "Select", new ActionListener() { +// +// @Override +// public void actionPerformed(ActionEvent e) { +// Preferences.setColor(prefName, c.getColor()); +// } +// }); +// } + + /** * Checks to see if the sketch has been modified, and if so, * asks the user to save the sketch or cancel the export. diff --git a/build/build.xml b/build/build.xml index 2b3d91b8d..4d0f0b233 100755 --- a/build/build.xml +++ b/build/build.xml @@ -78,14 +78,14 @@ - - + + @@ -268,118 +268,15 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - @@ -387,17 +284,7 @@ - - - - - + @@ -543,6 +430,9 @@ @@ -710,12 +598,16 @@ - + + + + + - - @@ -732,11 +624,6 @@ - - - - - @@ -886,12 +773,16 @@ - + + + + + - - @@ -900,28 +791,7 @@ - - - - - - @@ -935,38 +805,10 @@ classname="net.sf.launch4j.ant.Launch4jTask" classpath="${launch4j.dir}/launch4j.jar; ${launch4j.dir}/lib/xstream.jar" /> - - - - - - - - - - + + + @@ -974,10 +816,6 @@ - diff --git a/build/google.pem b/build/google.pem deleted file mode 100644 index ed0bd764f..000000000 --- a/build/google.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV -UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy -dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 -MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx -dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f -BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A -cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC -AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ -MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm -aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw -ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj -IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF -MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA -A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y -7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh -1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 ------END CERTIFICATE----- diff --git a/build/googlecode_upload.py b/build/googlecode_upload.py deleted file mode 100755 index d2d5f974c..000000000 --- a/build/googlecode_upload.py +++ /dev/null @@ -1,248 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2006, 2007 Google Inc. All Rights Reserved. -# Author: danderson@google.com (David Anderson) -# -# Script for uploading files to a Google Code project. -# -# This is intended to be both a useful script for people who want to -# streamline project uploads and a reference implementation for -# uploading files to Google Code projects. -# -# To upload a file to Google Code, you need to provide a path to the -# file on your local machine, a small summary of what the file is, a -# project name, and a valid account that is a member or owner of that -# project. You can optionally provide a list of labels that apply to -# the file. The file will be uploaded under the same name that it has -# in your local filesystem (that is, the "basename" or last path -# component). Run the script with '--help' to get the exact syntax -# and available options. -# -# Note that the upload script requests that you enter your -# googlecode.com password. This is NOT your Gmail account password! -# This is the password you use on googlecode.com for committing to -# Subversion and uploading files. You can find your password by going -# to http://code.google.com/hosting/settings when logged in with your -# Gmail account. If you have already committed to your project's -# Subversion repository, the script will automatically retrieve your -# credentials from there (unless disabled, see the output of '--help' -# for details). -# -# If you are looking at this script as a reference for implementing -# your own Google Code file uploader, then you should take a look at -# the upload() function, which is the meat of the uploader. You -# basically need to build a multipart/form-data POST request with the -# right fields and send it to https://PROJECT.googlecode.com/files . -# Authenticate the request using HTTP Basic authentication, as is -# shown below. -# -# Licensed under the terms of the Apache Software License 2.0: -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Questions, comments, feature requests and patches are most welcome. -# Please direct all of these to the Google Code users group: -# http://groups.google.com/group/google-code-hosting - -"""Google Code file uploader script. -""" - -__author__ = 'danderson@google.com (David Anderson)' - -import httplib -import os.path -import optparse -import getpass -import base64 -import sys - - -def upload(file, project_name, user_name, password, summary, labels=None): - """Upload a file to a Google Code project's file server. - - Args: - file: The local path to the file. - project_name: The name of your project on Google Code. - user_name: Your Google account name. - password: The googlecode.com password for your account. - Note that this is NOT your global Google Account password! - summary: A small description for the file. - labels: an optional list of label strings with which to tag the file. - - Returns: a tuple: - http_status: 201 if the upload succeeded, something else if an - error occured. - http_reason: The human-readable string associated with http_status - file_url: If the upload succeeded, the URL of the file on Google - Code, None otherwise. - """ - # The login is the user part of user@gmail.com. If the login provided - # is in the full user@domain form, strip it down. - if user_name.endswith('@gmail.com'): - user_name = user_name[:user_name.index('@gmail.com')] - - form_fields = [('summary', summary)] - if labels is not None: - form_fields.extend([('label', l.strip()) for l in labels]) - - content_type, body = encode_upload_request(form_fields, file) - - upload_host = '%s.googlecode.com' % project_name - upload_uri = '/files' - auth_token = base64.b64encode('%s:%s'% (user_name, password)) - headers = { - 'Authorization': 'Basic %s' % auth_token, - 'User-Agent': 'Googlecode.com uploader v0.9.4', - 'Content-Type': content_type, - } - - server = httplib.HTTPSConnection(upload_host) - server.request('POST', upload_uri, body, headers) - resp = server.getresponse() - server.close() - - if resp.status == 201: - location = resp.getheader('Location', None) - else: - location = None - return resp.status, resp.reason, location - - -def encode_upload_request(fields, file_path): - """Encode the given fields and file into a multipart form body. - - fields is a sequence of (name, value) pairs. file is the path of - the file to upload. The file will be uploaded to Google Code with - the same file name. - - Returns: (content_type, body) ready for httplib.HTTP instance - """ - BOUNDARY = '----------Googlecode_boundary_reindeer_flotilla' - CRLF = '\r\n' - - body = [] - - # Add the metadata about the upload first - for key, value in fields: - body.extend( - ['--' + BOUNDARY, - 'Content-Disposition: form-data; name="%s"' % key, - '', - value, - ]) - - # Now add the file itself - file_name = os.path.basename(file_path) - f = open(file_path, 'rb') - file_content = f.read() - f.close() - - body.extend( - ['--' + BOUNDARY, - 'Content-Disposition: form-data; name="filename"; filename="%s"' - % file_name, - # The upload server determines the mime-type, no need to set it. - 'Content-Type: application/octet-stream', - '', - file_content, - ]) - - # Finalize the form body - body.extend(['--' + BOUNDARY + '--', '']) - - return 'multipart/form-data; boundary=%s' % BOUNDARY, CRLF.join(body) - - -def upload_find_auth(file_path, project_name, summary, labels=None, - user_name=None, password=None, tries=3): - """Find credentials and upload a file to a Google Code project's file server. - - file_path, project_name, summary, and labels are passed as-is to upload. - - Args: - file_path: The local path to the file. - project_name: The name of your project on Google Code. - summary: A small description for the file. - labels: an optional list of label strings with which to tag the file. - config_dir: Path to Subversion configuration directory, 'none', or None. - user_name: Your Google account name. - tries: How many attempts to make. - """ - - while tries > 0: - if user_name is None: - # Read username if not specified or loaded from svn config, or on - # subsequent tries. - sys.stdout.write('Please enter your googlecode.com username: ') - sys.stdout.flush() - user_name = sys.stdin.readline().rstrip() - if password is None: - # Read password if not loaded from svn config, or on subsequent tries. - print 'Please enter your googlecode.com password.' - print '** Note that this is NOT your Gmail account password! **' - print 'It is the password you use to access Subversion repositories,' - print 'and can be found here: http://code.google.com/hosting/settings' - password = getpass.getpass() - - status, reason, url = upload(file_path, project_name, user_name, password, - summary, labels) - # Returns 403 Forbidden instead of 401 Unauthorized for bad - # credentials as of 2007-07-17. - if status in [httplib.FORBIDDEN, httplib.UNAUTHORIZED]: - # Rest for another try. - user_name = password = None - tries = tries - 1 - else: - # We're done. - break - - return status, reason, url - - -def main(): - parser = optparse.OptionParser(usage='googlecode-upload.py -s SUMMARY ' - '-p PROJECT [options] FILE') - parser.add_option('-s', '--summary', dest='summary', - help='Short description of the file') - parser.add_option('-p', '--project', dest='project', - help='Google Code project name') - parser.add_option('-u', '--user', dest='user', - help='Your Google Code username') - parser.add_option('-w', '--password', dest='password', - help='Your Google Code password') - parser.add_option('-l', '--labels', dest='labels', - help='An optional list of comma-separated labels to attach ' - 'to the file') - - options, args = parser.parse_args() - - if not options.summary: - parser.error('File summary is missing.') - elif not options.project: - parser.error('Project name is missing.') - elif len(args) < 1: - parser.error('File to upload not provided.') - elif len(args) > 1: - parser.error('Only one file may be specified.') - - file_path = args[0] - - if options.labels: - labels = options.labels.split(',') - else: - labels = None - - status, reason, url = upload_find_auth(file_path, options.project, - options.summary, labels, - options.user, options.password) - if url: - print 'The file was uploaded successfully.' - print 'URL: %s' % url - return 0 - else: - print 'An error occurred. Your file was not uploaded.' - print 'Google Code upload server said: %s (%s)' % (reason, status) - return 1 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/build/linux/processing b/build/linux/processing index 14708c1ed..eedceaa5f 100755 --- a/build/linux/processing +++ b/build/linux/processing @@ -103,7 +103,7 @@ cmd_name='processing-java' if [ $current_name = $cmd_name ] then - java processing.mode.java.Commander "$@" + java -Djna.nosys=true processing.mode.java.Commander "$@" exit $? else # Start Processing in the same directory as this script @@ -114,5 +114,5 @@ else fi cd "$APPDIR" - java processing.app.Base "$SKETCH" & + java -Djna.nosys=true processing.app.Base "$SKETCH" & fi diff --git a/build/shared/launch4j/bin/README.txt b/build/shared/launch4j/bin/README.txt deleted file mode 100644 index 5346d1e28..000000000 --- a/build/shared/launch4j/bin/README.txt +++ /dev/null @@ -1,68 +0,0 @@ -The MinGW binutils for Mac OS were built on OS X 10.6 by Ben Fry. - -The 64-bit Linux version was built on Ubuntu 12.04. - -The other binaries come from the original downloads on SourceForge. - - -Ben Fry - - -. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - -Mac OS X build instructions -12 November 2011 - -# Grab the launch4j download -wget http://downloads.sourceforge.net/launch4j/launch4j-3.0.2-macosx.tgz -tar xvfz launch4j-3.0.2-macosx.tgz -# Rename it so that we remember it's an Intel version -mv launch4j launch4j-3.0.2-macosx-intel - -# Find MinGW files here: http://sourceforge.net/projects/mingw/files/ -# Specifically this file: -wget http://downloads.sourceforge.net/mingw/binutils-2.19-src.tar.gz - -# To build the 32-bit version on Mac OS X -tar xvfz binutils-2.19-src.tar.gz -mv binutils-2.19 binutils-2.19-i386 -cd binutils-2.19-i386 -CXX='g++ -m32' CC='gcc -m32' CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 ./configure --disable-werror --target=i686-pc-mingw32 --with-gnu-ld -make -# Lots of gibberish, followed by "make[1]: Nothing to be done for `all-target'." -# Files will be at ld/ld-new and binutils/windres -cd .. - -# Now build the 64-bit version -tar xvfz binutils-2.19-src.tar.gz -mv binutils-2.19 binutils-2.19-x64 -cd binutils-2.19-x64 -./configure --disable-werror --target=i686-pc-mingw32 -make -cd .. - -# Finally, merge the 32- and 64-bit versions together -lipo -create binutils-2.19-i386/ld/ld-new binutils-2.19-x64/ld/ld-new -output launch4j-3.0.2-macosx-intel/bin/ld -lipo -create binutils-2.19-i386/binutils/windres binutils-2.19-x64/binutils/windres -output launch4j-3.0.2-macosx-intel/bin/windres - - -. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - -Linux 64-bit build instructions -21 July 2012 - -# Find MinGW files here: http://sourceforge.net/projects/mingw/files/ - -wget http://downloads.sourceforge.net/mingw/binutils-2.19-src.tar.gz -tar xvfz binutils-2.19-src.tar.gz -cd binutils-2.19 -./configure --disable-werror --target=i686-pc-mingw32 -make -cd .. - -# Then copy them out -cp binutils-2.19/ld/ld-new ld-linux64 -cp binutils-2.19/binutils/windres windres-linux64 - diff --git a/build/shared/launch4j/bin/ld-linux32 b/build/shared/launch4j/bin/ld-linux32 deleted file mode 100755 index 1d3f4091d..000000000 Binary files a/build/shared/launch4j/bin/ld-linux32 and /dev/null differ diff --git a/build/shared/launch4j/bin/ld-linux64 b/build/shared/launch4j/bin/ld-linux64 deleted file mode 100755 index 3b6f8944c..000000000 Binary files a/build/shared/launch4j/bin/ld-linux64 and /dev/null differ diff --git a/build/shared/launch4j/bin/ld-macosx b/build/shared/launch4j/bin/ld-macosx deleted file mode 100755 index 14bc7196b..000000000 Binary files a/build/shared/launch4j/bin/ld-macosx and /dev/null differ diff --git a/build/shared/launch4j/bin/ld-windows32.exe b/build/shared/launch4j/bin/ld-windows32.exe deleted file mode 100755 index f388b9513..000000000 Binary files a/build/shared/launch4j/bin/ld-windows32.exe and /dev/null differ diff --git a/build/shared/launch4j/bin/windres-linux32 b/build/shared/launch4j/bin/windres-linux32 deleted file mode 100755 index a67a74be4..000000000 Binary files a/build/shared/launch4j/bin/windres-linux32 and /dev/null differ diff --git a/build/shared/launch4j/bin/windres-linux64 b/build/shared/launch4j/bin/windres-linux64 deleted file mode 100755 index f8f0be94d..000000000 Binary files a/build/shared/launch4j/bin/windres-linux64 and /dev/null differ diff --git a/build/shared/launch4j/bin/windres-macosx b/build/shared/launch4j/bin/windres-macosx deleted file mode 100755 index 6a9822cc7..000000000 Binary files a/build/shared/launch4j/bin/windres-macosx and /dev/null differ diff --git a/build/shared/launch4j/bin/windres-windows32.exe b/build/shared/launch4j/bin/windres-windows32.exe deleted file mode 100755 index 4ad2ae98a..000000000 Binary files a/build/shared/launch4j/bin/windres-windows32.exe and /dev/null differ diff --git a/build/shared/launch4j/head/head.o b/build/shared/launch4j/head/head.o deleted file mode 100644 index d595f9e78..000000000 Binary files a/build/shared/launch4j/head/head.o and /dev/null differ diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index 0f7004242..32f287df0 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -1,3 +1,117 @@ +PROCESSING 2.2 (REV 0226) - 12 May 2014 + +Major changes to, and improvements upon, how "Export to Application" works. +Plus dozens of bug fixes for all manner of atrocities. + + +[ bug fixes and additions ] + ++ Sketches only starting once, or half-starting and hanging on Mac OS X. + A major problem on OS X, thanks to David Fokkema for tracking down a fix. + https://github.com/processing/processing/issues/2402 + https://github.com/processing/processing/pull/2455 + ++ Re-open current sketch in new mode editor if file extension is compatible. + This was a regression in 2.1.2 due to the Python Mode changes. + https://github.com/processing/processing/pull/2457 + https://github.com/processing/processing/issues/2456 + ++ Crash in the 'recent' menu on startup + https://github.com/processing/processing/issues/2463 + ++ Avoid conflict when some goofball has installed JNA DLLs in your path. + https://github.com/processing/processing/issues/2239 + ++ Add support for "import static" syntax from Java + https://github.com/processing/processing/issues/8 + https://github.com/processing/processing/pull/2273 + ++ Improve error handling during Tool loading. In previous releases, an + out of date QuickReference Tool was able to hang Processing. No longer. + https://github.com/processing/processing/issues/2229 + ++ Save the previous open dialog so that we return to the directory + https://github.com/processing/processing/pull/2366 + ++ "if-else" block formatting wasn't following Processing conventions + https://github.com/processing/processing/issues/364 + https://github.com/processing/processing/pull/2477 + ++ Tab characters not recognized or handled in the editor (since 2.1) + https://github.com/processing/processing/issues/2180 + https://github.com/processing/processing/issues/2183 + ++ Chinese text is overlapped in Processing 2.1 editor + https://github.com/processing/processing/issues/2173 + https://github.com/processing/processing/pull/2318 + https://github.com/processing/processing/pull/2323 + + +[ export to application ] + ++ The return of multi-platform export! Create applications for Windows + and Linux while using OS X. Create a Linux application from Windows. + Against my better judgement, we're supporting it again. It's extremely + difficult, but was disappointing to remove it earlier. + ++ When exporting with local Java embedded, always use that version + https://github.com/processing/processing/issues/2349 + ++ Change Windows export to use launch4j instead of our custom launcher. + This will fix many, many problems, but may introduce some new ones. + ++ Windows (64-bit) now creates a proper .exe instead of a .bat file + https://github.com/processing/processing/issues/923 + ++ Exported apps on Windows 64 were not quite working correctly + https://github.com/processing/processing/issues/2468 + ++ Improved icons on Windows for exported apps + ++ Add additional language and explanation to the Export dialog box + ++ Make it possible to edit the background colors for full screen as well as + the stop button color directly from the Export dialog box + https://github.com/processing/processing/issues/69 + ++ Exported apps reporting as "damaged" on OS X + https://github.com/processing/processing/issues/2095 + You'll have to install Xcode to remove the warnings, but it's possible + + +[ core ] + ++ Fix for splice() throwing a ClassCastException with other object types + https://github.com/processing/processing/issues/1445 + https://github.com/processing/processing/pull/2461 + ++ Add candDraw() method to the retina renderer to fix embedding problems + ++ Fix sketchPath() issue when used in other environments (i.e. Eclipse) + ++ Substitute MOVE cursor with HAND on OS X + https://github.com/processing/processing/issues/2358 + ++ Allow textWidth() with the default font + https://github.com/processing/processing/issues/2331 + https://github.com/processing/processing/pull/2338 + ++ Bug in relative moveto commands for SVG + https://github.com/processing/processing/issues/2377 + ++ Add a constructor to bind Server to a specific address + https://github.com/processing/processing/issues/2356 + ++ Fonts from loadFont() show up as blocks in P3D (regression) + https://github.com/processing/processing/issues/2465 + ++ loadPixels() problems in OpenGL + https://github.com/processing/processing/issues/2493 + + +. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + PROCESSING 2.1.2 (REV 0225) - 15 April 2014 Lots of small bug fixes plus some additional changes to support diff --git a/build/windows/launcher/about.bmp b/build/windows/about.bmp similarity index 100% rename from build/windows/launcher/about.bmp rename to build/windows/about.bmp diff --git a/build/windows/launcher/application.ico b/build/windows/application.ico similarity index 100% rename from build/windows/launcher/application.ico rename to build/windows/application.ico diff --git a/build/windows/launcher/config-cmd.xml b/build/windows/config-cmd.xml similarity index 67% rename from build/windows/launcher/config-cmd.xml rename to build/windows/config-cmd.xml index e06dffdd1..44c7b4aa7 100755 --- a/build/windows/launcher/config-cmd.xml +++ b/build/windows/config-cmd.xml @@ -2,17 +2,17 @@ true console lib - processing-java.exe + work/processing-java.exe . normal - http://java.sun.com/javase/downloads/ + http://java.com/download false false - + processing.mode.java.Commander lib/pde.jar @@ -20,7 +20,7 @@ lib/jna.jar lib/antlr.jar lib/ant.jar - lib/ant-launcher.jar + lib/ant-launcher.jar lib/org-netbeans-swing-outline.jar lib/com.ibm.icu_4.4.2.v20110823.jar lib/jdi.jar @@ -30,18 +30,16 @@ java - + + -Djna.nosys=true + + 1.7.0_40 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. - This application requires at least Java Development Kit (not JRE) - The registry refers to a nonexistent Java Development Kit installation or the runtime is corrupted. + This application requires Java to be installed + The registry refers to a nonexistent Java installation or the runtime is corrupted. An application instance is already running. diff --git a/build/windows/launcher/config.xml b/build/windows/config.xml similarity index 74% rename from build/windows/launcher/config.xml rename to build/windows/config.xml index dc7d954f2..4a3e91c5c 100755 --- a/build/windows/launcher/config.xml +++ b/build/windows/config.xml @@ -2,12 +2,12 @@ true gui lib - processing.exe + work/processing.exe . normal - http://java.sun.com/javase/downloads/ + http://java.com/download false false @@ -30,12 +30,10 @@ java - + + -Djna.nosys=true + + 1.7.0_40 about.bmp @@ -46,8 +44,8 @@ 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. - This application requires at least Java Development Kit (not JRE) - The registry refers to a nonexistent Java Development Kit installation or the runtime is corrupted. + This application requires Java to be installed + The registry refers to a nonexistent Java installation or the runtime is corrupted. An application instance is already running. diff --git a/build/windows/export/Makefile b/build/windows/export/Makefile deleted file mode 100755 index 6c1dce21c..000000000 --- a/build/windows/export/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -CXXFLAGS = -mwindows -mno-cygwin -O2 -Wall -#POBJS = launcher.o launcher-rc.o -# don't want to include the p5 icons for the exported feller -AOBJS = launcher.o - -#processing.exe: $(POBJS) -# $(LINK.cc) $(CXXFLAGS) -o $@ $(POBJS) -# cp processing.exe ../work/ - -application.exe: $(AOBJS) - $(LINK.cc) $(CXXFLAGS) -DEXPORT -o $@ $(AOBJS) - cp application.exe ../work/modes/java/application/template.exe - cp application.exe ../../../java/application/template.exe - -$(POBJS): Makefile - -#launcher-rc.o: launcher.rc -# windres -i $< -o $@ - -clean: - $(RM) $(OBJS) application.exe -# $(RM) $(OBJS) processing.exe application.exe diff --git a/build/windows/export/application.exe b/build/windows/export/application.exe deleted file mode 100755 index 03d8d5753..000000000 Binary files a/build/windows/export/application.exe and /dev/null differ diff --git a/build/windows/export/launcher.cpp b/build/windows/export/launcher.cpp deleted file mode 100644 index eb09b8334..000000000 --- a/build/windows/export/launcher.cpp +++ /dev/null @@ -1,403 +0,0 @@ -// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - -// if this code looks shitty, that's because it is. people are likely -// to have the durndest things in their CLASSPATH environment variable. -// mostly because installers often mangle them without the user knowing. -// so who knows where and when the quotes will show up. the code below is -// based on a couple years of trial and error with processing releases. - -// For revision 0102, a lot of changes were made to deal with stripping -// the quotes from the PATH, CLASSPATH, and QTJAVA environment variables. -// Any elements of the PATH and CLASSPATH that don't exist (whether files -// or directories) are also stripped out before being set. -// (Bug 112) - -// For revision 0201 (love that symmetry), the 'lib' folder was added to -// the java.library.path, so that we can hide the pile of DLLs included -// with some libraries (I'm looking at you, video), inside the lib folder. -// QTJAVA mess was also excised, now that we're switching to gstreamer. - -// The size of all of the strings was made sort of ambiguously large, since -// 1) nothing is hurt by allocating an extra few bytes temporarily and -// 2) if the user has a long path, and it gets copied five times over for the -// CLASSPATH, the program runs the risk of crashing. Bad bad. - -// TODO this code leaks memory all over the place because nothing has been -// done to properly handle creation/deletion of new strings. - -// TODO switch to unicode versions of all methods in order to better support -// running on non-English (non-Roman especially) versions of Windows. - -#define ARGS_FILE_PATH "\\lib\\args.txt" - -#include -#include -#include - - -void removeLineEndings(char *what); -char *scrubPath(char *incoming); -char *mallocChars(int count); -void removeQuotes(char *quoted); -void removeTrailingSlash(char *slashed); - -//#define DEBUG - -int STDCALL -WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) -{ - // command line that was passed to this application - char *incoming_cmd_line = (char *)malloc((strlen(lpCmd) + 1) * sizeof(char)); - strcpy(incoming_cmd_line, lpCmd); - - // get the full path to the application that was launched, - // drop the app name but keep the path - char *exe_directory = (char *)malloc(MAX_PATH * sizeof(char)); - //*exe_directory = 0; - GetModuleFileName(NULL, exe_directory, MAX_PATH); - // remove the application name - *(strrchr(exe_directory, '\\')) = '\0'; - - - // open the file that contains the main class name and java args - - char *args_file_path = (char*) - malloc(strlen(exe_directory) * sizeof(char) + - strlen(ARGS_FILE_PATH) * sizeof(char) + 1); - strcpy(args_file_path, exe_directory); - strcat(args_file_path, ARGS_FILE_PATH); - - char java_args[512]; - char java_main_class[512]; - char jar_list[512]; - char *app_classpath = (char *)malloc(10 * strlen(exe_directory) + 4096); - - FILE *argsfile = fopen(args_file_path, "r"); - if (argsfile == NULL) { - sprintf(app_classpath, - "This program is missing the \"lib\" folder, " - "which should be located at\n%s", - exe_directory); - MessageBox(NULL, app_classpath, "Folder Missing", MB_OK); - return 0; - - } else { - fgets(java_args, 511, argsfile); - removeLineEndings(java_args); - fgets(java_main_class, 511, argsfile); - removeLineEndings(java_main_class); - fgets(jar_list, 511, argsfile); - removeLineEndings(jar_list); - -#ifdef DEBUG - MessageBox(NULL, java_args, "args", MB_OK); - MessageBox(NULL, java_main_class, "class", MB_OK); - MessageBox(NULL, jar_list, "jarlist", MB_OK); -#endif - - app_classpath[0] = 0; - char *jar = (char*) strtok(jar_list, ","); - while (jar != NULL) { - char entry[1024]; - sprintf(entry, "%s\\lib\\%s;", exe_directory, jar); - strcat(app_classpath, entry); - jar = (char*) strtok(NULL, ","); - } - fclose(argsfile); - } - - // - - char *cp = (char *)malloc(10 * strlen(exe_directory) + 4096); - - // test to see if running with a java runtime nearby or not - char *testpath = (char *)malloc(MAX_PATH * sizeof(char)); - *testpath = 0; - strcpy(testpath, exe_directory); - strcat(testpath, "\\java\\bin\\java.exe"); - FILE *fp = fopen(testpath, "rb"); - int local_jre_installed = (fp != NULL); - if (fp != NULL) fclose(fp); - - //const char *envClasspath = getenv("CLASSPATH"); - //char *env_classpath = (char *)malloc(16384 * sizeof(char)); - - // ignoring CLASSPATH for now, because it's not needed - // and causes more trouble than it's worth [0060] - //env_classpath[0] = 0; - - // don't put quotes around contents of cp, even though %s might have - // spaces in it. don't put quotes in it, because it's setting the - // environment variable for CLASSPATH, not being included on the - // command line. so setting the env var it's ok to have spaces, - // and the quotes prevent javax.comm.properties from being found. - - strcpy(cp, app_classpath); - if (local_jre_installed) { - char *local_jre = mallocChars(64 + strlen(exe_directory) * 2); - sprintf(local_jre, "%s\\java\\lib\\rt.jar;%s\\java\\lib\\tools.jar;", exe_directory, exe_directory); - strcat(cp, local_jre); - } - - char *clean_cp = scrubPath(cp); - //if (!SetEnvironmentVariable("CLASSPATH", cp)) { - if (!SetEnvironmentVariable("CLASSPATH", clean_cp)) { - MessageBox(NULL, "Could not set CLASSPATH environment variable", - "Processing Error", MB_OK); - return 1; - } - -#ifdef DEBUG - MessageBox(NULL, "done with classpath cleaning", "2", MB_OK); -#endif - - int env_path_length = strlen(getenv("PATH")); - char *env_path = mallocChars(env_path_length); - strcpy(env_path, getenv("PATH")); - char *clean_path; - - // need to add the local jre to the path for 'java mode' in the env - if (local_jre_installed) { - char *path_to_clean = - mallocChars(env_path_length + strlen(exe_directory) + 30); - sprintf(path_to_clean, "%s\\java\\bin;%s", exe_directory, env_path); - clean_path = scrubPath(path_to_clean); - } else { - clean_path = scrubPath(getenv("PATH")); - } - - //MessageBox(NULL, clean_path, "after scrubbing PATH", MB_OK); - //MessageBox(NULL, "3", "checking", MB_OK); - - if (!SetEnvironmentVariable("PATH", clean_path)) { - MessageBox(NULL, "Could not set PATH environment variable", - "Processing Error", MB_OK); - return 0; - } - - // what gets put together to pass to jre - char *outgoing_cmd_line = (char *)malloc(16384 * sizeof(char)); - - // prepend the args for -mx and -ms - strcpy(outgoing_cmd_line, java_args); - strcat(outgoing_cmd_line, " "); - - // for 2.0a2, add the 'lib' folder to the java.library.path - strcat(outgoing_cmd_line, "\"-Djava.library.path="); - strcat(outgoing_cmd_line, exe_directory); - strcat(outgoing_cmd_line, "\\lib\" "); - - // add the name of the class to execute and a space before the next arg - strcat(outgoing_cmd_line, java_main_class); - strcat(outgoing_cmd_line, " "); - - // append additional incoming stuff (document names), if any - strcat(outgoing_cmd_line, incoming_cmd_line); - - //MessageBox(NULL, outgoing_cmd_line, "cmd_line", MB_OK); - - char *executable = - (char *)malloc((strlen(exe_directory) + 256) * sizeof(char)); - // exe_directory is the name path to the current application - - if (local_jre_installed) { - strcpy(executable, exe_directory); - // copy in the path for javaw, relative to launcher.exe - strcat(executable, "\\java\\bin\\javaw.exe"); - } else { -#ifdef DEBUG - strcpy(executable, "java.exe"); -#else - strcpy(executable, "javaw.exe"); -#endif - } - - SHELLEXECUTEINFO ShExecInfo; - -#ifdef DEBUG - MessageBox(NULL, outgoing_cmd_line, executable, MB_OK); -#endif - - // set up the execution info - ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); - ShExecInfo.fMask = 0; - ShExecInfo.hwnd = 0; - ShExecInfo.lpVerb = "open"; - ShExecInfo.lpFile = executable; - ShExecInfo.lpParameters = outgoing_cmd_line; - ShExecInfo.lpDirectory = exe_directory; - ShExecInfo.nShow = SW_SHOWNORMAL; - ShExecInfo.hInstApp = NULL; - - if (!ShellExecuteEx(&ShExecInfo)) { - MessageBox(NULL, "Error calling ShellExecuteEx()", - "Processing Error", MB_OK); - return 0; - } - - if (reinterpret_cast(ShExecInfo.hInstApp) <= 32) { - // some type of error occurred - switch (reinterpret_cast(ShExecInfo.hInstApp)) { - case ERROR_FILE_NOT_FOUND: - case ERROR_PATH_NOT_FOUND: - MessageBox(NULL, "A required file could not be found. \n" - "You may need to install a Java runtime\n" - "or re-install Processing.", - "Processing Error", MB_OK); - break; - case 0: - case SE_ERR_OOM: - MessageBox(NULL, "Not enough memory or resources to run at" - " this time.", "Processing Error", MB_OK); - - break; - default: - MessageBox(NULL, "There is a problem with your installation.\n" - "If the problem persists, re-install the program.", - "Processing Error", MB_OK); - break; - } - } - - return 0; - - /* - PROCESS_INFORMATION pi; - memset(&pi, 0, sizeof(pi)); - STARTUPINFO si; - memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - int wait = 0; - - DWORD dwExitCode = (DWORD) -1; - char cmdline[32768]; - //executable; - //outgoing_cmd_line; - //exe_directory; - strcpy(cmdline, "\""); - strcat(cmdline, executable); - strcat(cmdline, "\" "); - strcat(cmdline, outgoing_cmd_line); - - if (CreateProcess(NULL, cmdline, NULL, NULL, - //TRUE, priority, NULL, NULL, - TRUE, 0, NULL, exe_directory, - &si, &pi)) { - if (wait) { - WaitForSingleObject(pi.hProcess, INFINITE); - GetExitCodeProcess(pi.hProcess, &dwExitCode); - //debug("Exit code:\t%d\n", dwExitCode); - //closeHandles(); - char big_trouble[128]; - sprintf(big_trouble, "Sorry, could not launch. (Error %d)", - (int) dwExitCode); - MessageBox(NULL, big_trouble, "Apologies", MB_OK); - } else { - dwExitCode = 0; - } - } - return dwExitCode; - */ -} - - -void removeLineEndings(char *what) { - int index = strlen(what) - 1; - while (index >= 0) { - if ((what[index] == 10) || (what[index] == 13)) { - what[index] = 0; - --index; - } else { - return; - } - } -} - - -// take a PATH environment variable, split on semicolons, -// remove extraneous quotes, perhaps even make 8.3 syntax if necessary -char *scrubPath(char *incoming) { - char *cleaned = mallocChars(strlen(incoming) * 2); - - int found_so_far = 0; - char *p = (char*) strtok(incoming, ";"); - while (p != NULL) { - char entry[1024]; - /* - if (*p == '\"') { - // if this segment of the path contains quotes, remove them - int fixed_length = strlen(p) - 2; - strncpy(entry, &p[1], fixed_length); - entry[fixed_length] = 0; - //MessageBox(NULL, entry, "clipped", MB_OK); - - // if it doesn't actually end with a quote, then the person - // is screwed anyway.. they can deal with that themselves - } else { - strcpy(entry, p); - } - */ - strcpy(entry, p); - removeQuotes(entry); - // a trailing slash will cause FindFirstFile to fail.. grr [0109] - removeTrailingSlash(entry); - //MessageBox(NULL, entry, "entry", MB_OK); - - // if this path doesn't exist, don't add it - WIN32_FIND_DATA find_file_data; - HANDLE hfind = FindFirstFile(entry, &find_file_data); - if (hfind != INVALID_HANDLE_VALUE) { - if (found_so_far) strcat(cleaned, ";"); - strcat(cleaned, entry); - //MessageBox(NULL, cleaned, "cleaned so far", MB_OK); - FindClose(hfind); - found_so_far = 1; - //} else { - //MessageBox(NULL, entry, "removing", MB_OK); - } - // grab the next entry - p = (char*) strtok(NULL, ";"); - } - //MessageBox(NULL, cleaned, "scrubPath", MB_OK); - return cleaned; -} - - -// eventually make this handle unicode -char *mallocChars(int count) { - // add one for the terminator - char *outgoing = (char*) malloc(count * sizeof(char) + 1); - outgoing[0] = 0; // for safety - return outgoing; -} - - -void removeQuotes(char *quoted) { - int len = strlen(quoted); - // remove quote at the front - if (quoted[0] == '\"') { - for (int i = 0; i < len - 1; i++) { - quoted[i] = quoted[i+1]; - } - len--; - quoted[len] = 0; - } - // remove quote at the end - if (len > 1) { - if (quoted[len - 1] == '\"') { - len--; - quoted[len] = 0; - } - } -} - - -void removeTrailingSlash(char *slashed) { - int len = strlen(slashed); - if (len > 1) { - if (slashed[len - 1] == '\\') { - len--; - slashed[len] = 0; - } - } -} diff --git a/build/windows/launcher/processing.bat b/build/windows/processing.bat similarity index 100% rename from build/windows/launcher/processing.bat rename to build/windows/processing.bat diff --git a/core/done.txt b/core/done.txt index 02382bf8b..99dda8671 100644 --- a/core/done.txt +++ b/core/done.txt @@ -1,3 +1,58 @@ +0226 core (2.2) +X fix parsing with missing categorical values +X fix for splice() throwing a ClassCastException with other object types +X https://github.com/processing/processing/issues/1445 +X https://github.com/processing/processing/pull/2461 +X add candDraw() method to the retina renderer +X fix sketchPath() issue when used in another environment +X XML.getChildren() throwing NPE when getInt() called on non-existent var +X https://github.com/processing/processing/issues/2367 +X need to sort out with docs what's happening here +X just a reference issue +X substitute MOVE cursor with HAND on OS X +X https://github.com/processing/processing/issues/2358 +X Allow textWidth() with the default font +X https://github.com/processing/processing/issues/2331 +X https://github.com/processing/processing/pull/2338 +X bug in relative moveto commands for SVG +X https://github.com/processing/processing/issues/2377 +X Add a constructor to bind Server to a specific address +X https://github.com/processing/processing/issues/2356 +X add disconnectEvent() to Server +X https://github.com/processing/processing/pull/2466 +X https://github.com/processing/processing/issues/2133 +X don't document for now + +cleaning +o how much of com.benfry.* should go in? +o Table? StringIntPairs? JSON? MD5? Integrator? ColorIntegrator? +o decision: depends on if we can think of a good name +X finished these up in the 2.x series +o check on DXFWriter, since it used to subclass P3D +o at least implement is3D? +X should be working, barring recent regression +o sleep time needs to be set *much* higher for dormant applets +o 10s should be fine--no need to keep spinning (bad for android too) +o just call interrupt() when it's time to get back to work +X applets removed +X test PGraphicsRetina2D w/ 7u40 +X make sure that 7u40 doesn't reintroduce starvation issue on retina Macs +X createGraphics() with no renderer param to point to JAVA2D +X docs: P2D and P3D are now OpenGL variations +X shader support - make decisions, Andres email, etc +X antialias -> smoothMode(), smoothQuality(), quality() +o NEAREST, BILINEAR, BICUBIC, or 0, 2, 4? (need 8x too, so maybe numbers) +X setAntiAlias() should instead just use parent.smooth +X final decision on pg.setQuality(sketchQuality()) +X should probably be setQuality(parent.sketchQuality()) + +andres +X Fonts from loadFont() show up as blocks in P3D (regression) +X https://github.com/processing/processing/issues/2465 +X loadPixels problem in OpenGL +X https://github.com/processing/processing/issues/2493 + + 0225 core (2.1.2) X bug with StringDict(Reader) that wasn't setting the indices hashmap X check this with other versions of this class diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index e9d694b92..110814425 100755 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -2773,10 +2773,14 @@ public class PApplet extends Applet // also prevents mouseExited() on the mac from hosing the mouse // position, because x/y are bizarre values on the exit event. // see also the id check below.. both of these go together. - // Not necessary to set mouseX/Y on PRESS or RELEASE events because the - // actual position will have been set by a MOVE or DRAG event. - if (event.getAction() == MouseEvent.DRAG || - event.getAction() == MouseEvent.MOVE) { + // Not necessary to set mouseX/Y on RELEASE events because the + // actual position will have been set by a PRESS or DRAG event. + // However, PRESS events might come without a preceeding move, + // if the sketch window gains focus on that PRESS. + final int action = event.getAction(); + if (action == MouseEvent.DRAG || + action == MouseEvent.MOVE || + action == MouseEvent.PRESS) { pmouseX = emouseX; pmouseY = emouseY; mouseX = event.getX(); @@ -2810,7 +2814,7 @@ public class PApplet extends Applet // Do this up here in case a registered method relies on the // boolean for mousePressed. - switch (event.getAction()) { + switch (action) { case MouseEvent.PRESS: mousePressed = true; break; @@ -2821,7 +2825,7 @@ public class PApplet extends Applet handleMethods("mouseEvent", new Object[] { event }); - switch (event.getAction()) { + switch (action) { case MouseEvent.PRESS: // mousePressed = true; mousePressed(event); @@ -2850,8 +2854,8 @@ public class PApplet extends Applet break; } - if ((event.getAction() == MouseEvent.DRAG) || - (event.getAction() == MouseEvent.MOVE)) { + if ((action == MouseEvent.DRAG) || + (action == MouseEvent.MOVE)) { emouseX = mouseX; emouseY = mouseY; } @@ -4324,6 +4328,11 @@ public class PApplet extends Applet * @param kind either ARROW, CROSS, HAND, MOVE, TEXT, or WAIT */ public void cursor(int kind) { + // Swap the HAND cursor because MOVE doesn't seem to be available on OS X + // https://github.com/processing/processing/issues/2358 + if (platform == MACOSX && kind == MOVE) { + kind = HAND; + } setCursor(Cursor.getPredefinedCursor(kind)); cursorVisible = true; this.cursorType = kind; diff --git a/core/src/processing/core/PGraphicsJava2D.java b/core/src/processing/core/PGraphicsJava2D.java index df5d2e725..4b43c7e90 100644 --- a/core/src/processing/core/PGraphicsJava2D.java +++ b/core/src/processing/core/PGraphicsJava2D.java @@ -1582,7 +1582,7 @@ public class PGraphicsJava2D extends PGraphics { @Override public float textDescent() { if (textFont == null) { - defaultFontOrDeath("textAscent"); + defaultFontOrDeath("textDescent"); } Font font = (Font) textFont.getNative(); //if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) { @@ -1621,7 +1621,7 @@ public class PGraphicsJava2D extends PGraphics { @Override public void textSize(float size) { if (textFont == null) { - defaultFontOrDeath("textAscent", size); + defaultFontOrDeath("textSize", size); } // if a native version available, derive this font @@ -1668,6 +1668,10 @@ public class PGraphicsJava2D extends PGraphics { @Override protected float textWidthImpl(char buffer[], int start, int stop) { + if (textFont == null) { + defaultFontOrDeath("textWidth"); + } + Font font = (Font) textFont.getNative(); //if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) { if (font != null) { diff --git a/core/src/processing/core/PShapeSVG.java b/core/src/processing/core/PShapeSVG.java index 1be0b30d6..7bac4fb62 100644 --- a/core/src/processing/core/PShapeSVG.java +++ b/core/src/processing/core/PShapeSVG.java @@ -586,6 +586,8 @@ public class PShapeSVG extends PShape { case 'm': // m - move to (relative) cx = cx + PApplet.parseFloat(pathTokens[i + 1]); cy = cy + PApplet.parseFloat(pathTokens[i + 2]); + movetoX = cx; + movetoY = cy; parsePathMoveto(cx, cy); implicitCommand = 'l'; i += 3; diff --git a/core/src/processing/data/XML.java b/core/src/processing/data/XML.java index 5860eafc2..27ce09342 100644 --- a/core/src/processing/data/XML.java +++ b/core/src/processing/data/XML.java @@ -260,6 +260,11 @@ public class XML implements Serializable { // } + public boolean save(File file) { + return save(file, null); + } + + public boolean save(File file, String options) { PrintWriter writer = PApplet.createWriter(file); boolean result = write(writer); diff --git a/core/src/processing/event/MouseEvent.java b/core/src/processing/event/MouseEvent.java index ce48658fb..bde328ff3 100644 --- a/core/src/processing/event/MouseEvent.java +++ b/core/src/processing/event/MouseEvent.java @@ -117,4 +117,33 @@ public class MouseEvent extends Event { // public void setClickCount(int clickCount) { // this.clickCount = clickCount; // } + + private String actionString() { + switch (action) { + default: + return "UNKNOWN"; + case CLICK: + return "CLICK"; + case DRAG: + return "DRAG"; + case ENTER: + return "ENTER"; + case EXIT: + return "EXIT"; + case MOVE: + return "MOVE"; + case PRESS: + return "PRESS"; + case RELEASE: + return "RELEASE"; + case WHEEL: + return "WHEEL"; + } + } + + @Override + public String toString() { + return String.format("", + actionString(), x, y, count, button); + } } diff --git a/core/todo.txt b/core/todo.txt index 96f30e092..abe9963fe 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,52 +1,25 @@ -0226 core -X fix parsing with missing categorical values -X fix for splice() throwing a ClassCastException with other object types -X https://github.com/processing/processing/issues/1445 -X https://github.com/processing/processing/pull/2461 -X add candDraw() method to the retina renderer -X fix sketchPath() issue when used in another environment - -andres -X Fonts from loadFont() show up as blocks in P3D (regression) -X https://github.com/processing/processing/issues/2465 - -_ "Buffers have not been created" error for sketches w/o draw() -_ https://github.com/processing/processing/issues/2469 -_ could not reproduce - -net -X add disconnectEvent() to Server -X https://github.com/processing/processing/pull/2466 -X https://github.com/processing/processing/issues/2133 -_ decide how this should actually be handled -_ was disconnect always there? -_ will need documentation -_ modernize Client/Server code to use synchronized lists -_ do we let people use the public vars in Server and Client? -_ are they documented? - - -_ XML.getChildren() throwing NPE when getInt() called on non-existent var -_ https://github.com/processing/processing/issues/2367 -_ need to sort out with docs what's happening here - -_ point() rendering differently in 2.0.3 and 2.1 -_ https://github.com/processing/processing/issues/2278 - -_ Sketch runs with default size if size() is followed by large memory allocation -_ https://github.com/processing/processing/issues/2039 +0227 core high +_ "Buffers have not been created" error for sketches w/o draw() +_ https://github.com/processing/processing/issues/2469 +_ could not reproduce +_ Sketch runs with default size if size() is followed by large memory allocation +_ some sort of threading issue happening here +_ https://github.com/processing/processing/issues/1672 +_ https://github.com/processing/processing/issues/2039 (dupe) +_ https://github.com/processing/processing/issues/2294 (dupe) +_ point() rendering differently in 2.0.3 and 2.1 +_ https://github.com/processing/processing/issues/2278 +_ internally, we probably have to call set() if it's a 1 pixel point +_ but that's going to be a mess.. need to first check the CTM _ tint() not working in PDF (regression between 2.0.3 and 2.1) _ https://github.com/processing/processing/issues/2428 _ default font fixes _ https://github.com/processing/processing/issues/2331 _ https://github.com/processing/processing/pull/2338 -_ saveFrame() with retina render is making black images _ add print() method to other data types (not just IntList) -_ zero alpha values still a problem with retina renderer -_ https://github.com/processing/processing/issues/2030 _ Sort out blending differences with P2D/P3D _ might be that compatible images not setting alpha mode correctly _ image = gc.createCompatibleVolatileImage(source.width, source.height, Transparency.TRANSLUCENT); @@ -62,10 +35,6 @@ _ https://github.com/processing/processing/issues/2483 _ add option to have full screen span across screens _ display=all in cmd line _ sketchDisplay() -> 0 for all, or 1, 2, 3... -_ test PGraphicsRetina2D w/ 7u40 -_ make sure that 7u40 doesn't reintroduce starvation issue on retina Macs -_ Linux sometimes not responding correctly w/ the size() command -_ https://github.com/processing/processing/issues/1672 _ clean up requestFocus() stuff _ make sure it works with retina/canvas/strategy as well _ finish PFont.getShape() implementation @@ -74,6 +43,25 @@ _ draw(s) doesn't work on the returned PShape _ TGA files writing strangely _ https://github.com/processing/processing/issues/2096 +hidpi +_ saveFrame() with retina render is making black images +_ zero alpha values still a problem with retina renderer +_ https://github.com/processing/processing/issues/2030 +_ how to name the retina pixel stuff +_ hint(ENABLE_RETINA_PIXELS) or hint(ENABLE_HIDPI_PIXELS) +_ hint(ENABLE_2X_PIXELS)? +_ hidpi is Apple's name as well +_ no high-res display support for OpenGL +_ no high-dpi support for core on Windows +_ https://github.com/processing/processing/issues/2411 +_ retina sketches slow to start +_ https://github.com/processing/processing/issues/2357 + +cantfix +_ crash on startup when "Mirror Displays" selected +_ suspect that this is a specific chipset since Oracle didn't reproduce +_ https://github.com/processing/processing/issues/2186 + table _ addRow() is not efficient, probably need to do the doubling _ or have a setIncrement() function? @@ -86,6 +74,8 @@ _ save the constructor for the version that actually copies data _ the table pointer version will be speedy and allow chaining decisions/misc +_ make join() work with Iterable? +_ will this collide with the current String[] version? _ add options for image.save() (or saveImage?) _ add quality=[0,1] for jpeg images _ add dpi=[0,n] for for png images @@ -94,7 +84,7 @@ _ possible addition for 'implementation' variable X http://code.google.com/p/processing/issues/detail?id=281 _ https://github.com/processing/processing/issues/320 _ should map() actually constrain to the low and high values? -_ or have an alternate version that does that? (boolean param at end?) +_ or have an alternate version that does that? (or boolean param at end?) _ decide whether to keep: _ public float textWidth(char[] chars, int start, int length) _ add version of math functions that use doubles? @@ -123,14 +113,6 @@ _ nasty errors when loadImage/Font/createFont/etc used outside _ decision: add error messages where possible _ idea: set frameCount to -1 when setup not run yet? _ then set frameCount to 0 when setup() starts? -_ how much of com.benfry.* should go in? -_ Table? StringIntPairs? JSON? MD5? Integrator? ColorIntegrator? -_ decision: depends on if we can think of a good name -_ check on DXFWriter, since it used to subclass P3D -_ at least implement is3D? -_ sleep time needs to be set *much* higher for dormant applets -_ 10s should be fine--no need to keep spinning (bad for android too) -_ just call interrupt() when it's time to get back to work _ need to clean up the hints in the reference/source _ sort out edge + 1 issue on stroke/fill for rectangles _ http://code.google.com/p/processing/issues/detail?id=509 @@ -169,14 +151,6 @@ _ online is there but deprecated _ doesn't test net connection to see if 'online' _ only tests whether running inside an applet viewer (not relevant) _ remove 'online' from the docs -_ createGraphics() with no renderer param to point to JAVA2D -_ docs: P2D and P3D are now OpenGL variations -_ shader support - make decisions, Andres email, etc -_ setAntiAlias() should instead just use parent.smooth -_ antialias -> smoothMode(), smoothQuality(), quality() -_ NEAREST, BILINEAR, BICUBIC, or 0, 2, 4? (need 8x too, so maybe numbers) -_ final decision on pg.setQuality(sketchQuality()) -_ should probably be setQuality(parent.sketchQuality()) _ add reference/docs for urlEncode() and urlDecode() _ verify (and document) public access members of PApplet _ http://code.google.com/p/processing/issues/detail?id=83 @@ -192,10 +166,9 @@ _ OpenGL offscreen requires primary surface to be OpenGL _ explain the new PGL interface _ can't really change the smoothing/options on offscreen _ is this still true? -_ how to name the retina pixel stuff -_ hint(ENABLE_RETINA_PIXELS) or hint(ENABLE_HIDPI_PIXELS) -_ hint(ENABLE_2X_PIXELS)? -_ hidpi is Apple's name as well +_ decide how disconnectEvent should actually be handled (and name?) +_ was disconnect always there? +_ will need documentation @@ -499,6 +472,8 @@ _ Updating graphics drivers may prevent the problem _ ellipse scaling method isn't great _ http://code.google.com/p/processing/issues/detail?id=87 _ improve hint(ENABLE_DEPTH_SORT) to use proper painter's algo +_ https://github.com/processing/processing/issues/90 +_ for begin/endRaw: https://github.com/processing/processing/issues/2235 _ http://code.google.com/p/processing/issues/detail?id=51 _ polygon z-order depth sorting with alpha in opengl _ complete the implementation of hint() with proper implementation diff --git a/done.txt b/done.txt index b3e569697..172d7230a 100644 --- a/done.txt +++ b/done.txt @@ -1,3 +1,109 @@ +0226 pde (2.2) +X sketches only starting once, or half-starting and hanging +X https://github.com/processing/processing/issues/2402 +X https://github.com/processing/processing/pull/2455 +X reopen current sketch in new mode editor if file extension is compatible +X https://github.com/processing/processing/pull/2457 +X https://github.com/processing/processing/issues/2456 +X crash in the 'recent' menu on startup +X https://github.com/processing/processing/issues/2463 +X sketchbook location is set to an actual sketch (huh?) +X sketch sometimes simply does not launch +X https://github.com/processing/processing/issues/2402 +X https://github.com/processing/processing/pull/2455 +X helpful fix contributed by David Fokkema +X remove the google code uploader +X JNA conflicts can be avoided with "-Djna.nosys=true" +X https://github.com/processing/processing/issues/2239 +X fix for Windows launchers +X fix for Windows export +X fix for Windows export 64-bit +X fix for Windows command line +X fix for Linux launcher +X fix for Linux export +X fix for Linux command line +X fix for OS X launcher +X fix for OS X export +X fix for OS X command line +X import static causes exception (with fix) +X https://github.com/processing/processing/issues/8 +o https://github.com/processing/processing/pull/2273 +X improve handling of tool loading +X QuickReference tool was able to bring down the environment +X https://github.com/processing/processing/issues/2229 +X save the previous open dialog so that we return to the directory +X https://github.com/processing/processing/pull/2366 +X "if-else" block formatting doesn't follow Processing conventions +X https://github.com/processing/processing/issues/364 +X https://github.com/processing/processing/pull/2477 +X tab characters not recognized/drawn in the editor (2.1) +X https://github.com/processing/processing/issues/2180 +X https://github.com/processing/processing/issues/2183 +o udp library has tabs in the text +X decision to be made on nextTabStop() inside TextAreaPainter +X Chinese text is overlapped in Processing 2.1 editor +X https://github.com/processing/processing/issues/2173 +X https://github.com/processing/processing/pull/2318 +X https://github.com/processing/processing/pull/2323 +o maybe user prefs should only cover things that've changed? +o how to balance colors/etc being stored elsewhere +o ton of work to maintain this... +X yeah, no +X remove video for macosx32 from the repo permanently +o fix for various net issues +o https://github.com/processing/processing/pull/2475 +X incorporates other unrelated code, had to close + +earlier (2.1.2) +X added get/set methods for status lines (Manindra) +X https://github.com/processing/processing/issues/2430 +X https://github.com/processing/processing/pull/2433 +X allow non-pde file extensions (JDF) +X https://github.com/processing/processing/issues/2420 + +export +X exported apps on Windows 64 not working? +X https://github.com/processing/processing/issues/2468 +X just needed to add the local path for Java +X when exporting with local Java embedded, use that version +X https://github.com/processing/processing/issues/2349 +X (we can do this now since we're actually doing the embedding) +o export application folder location (for Manindra) +X https://github.com/processing/processing/issues/2399 +X incorporate new launch4j 3.4 +X http://sourceforge.net/projects/launch4j/files/launch4j-3/3.4/ +X change Windows export to use launch4j instead of the launcher.cpp file +X actually call ant from inside p5? +X re-implement an icon for exported applications on Windows +X make sure that Windows export uses the local Java +X double-checked with a clean XP install +X make sure Windows export includes library DLLs +X remove build/windows/export from repo +o make sure launch4j export isn't printing to console unless trouble +X OS X is doing this, though Windows is pushing some stuff through +X bring back multi-platform export? +X embed Java only works for the current platform +o OS X applications can only be exported from OS X +X actually it's just the embedding, which is a problem on any platform +X add all sorts of language to the export dialog +X make available the background colors for present mode, stop button color +X isolate color chooser into a simpler/smaller class outside tools +X then can also use from inside processing applications as well +X http://code.google.com/p/processing/issues/detail?id=30 +X https://github.com/processing/processing/issues/69 +X exported apps reporting as "damaged" on OS X +X https://github.com/processing/processing/issues/2095 +X implement a call to codesign, and a message box re: installing Xcode +X use launch4j for export and p5 app itself +X perhaps even calling it through an ant task +X windows exported exe problems (pcho) +o updated launch4j 3.1 beta +o http://sourceforge.net/projects/launch4j/files/launch4j-3/ +X exe instead of bat to make exported apps run in 64-bit +X http://code.google.com/p/processing/issues/detail?id=885 +X https://github.com/processing/processing/issues/923 + + 0225 pde (2.1.2) X Fix exception caused by Runner when it can't find location X https://github.com/processing/processing/issues/2346 diff --git a/java/application/Info.plist.tmpl b/java/application/Info.plist.tmpl index 28a2e0277..9cc224c08 100644 --- a/java/application/Info.plist.tmpl +++ b/java/application/Info.plist.tmpl @@ -59,7 +59,7 @@ JVMOptions - @@jvm_options_list@@ +@@jvm_options_list@@ -Xdock:icon=Contents/Resources/sketch.icns -Dapple.laf.useScreenMenuBar=true -Dcom.apple.macos.use-file-dialog-packages=true diff --git a/build/shared/launch4j/LICENSE.txt b/java/application/launch4j/LICENSE.txt similarity index 93% rename from build/shared/launch4j/LICENSE.txt rename to java/application/launch4j/LICENSE.txt index 0ade5f46f..d09ff0065 100644 --- a/build/shared/launch4j/LICENSE.txt +++ b/java/application/launch4j/LICENSE.txt @@ -1,7 +1,7 @@ Launch4j (http://launch4j.sourceforge.net/) Cross-platform Java application wrapper for creating Windows native executables. -Copyright (c) 2004, 2008 Grzegorz Kowal +Copyright (c) 2004, 2014 Grzegorz Kowal All rights reserved. diff --git a/build/shared/launch4j/bin/LICENSE.txt b/java/application/launch4j/bin/LICENSE.txt similarity index 100% rename from build/shared/launch4j/bin/LICENSE.txt rename to java/application/launch4j/bin/LICENSE.txt diff --git a/java/application/launch4j/bin/ld-linux b/java/application/launch4j/bin/ld-linux new file mode 100755 index 000000000..2e2983e88 Binary files /dev/null and b/java/application/launch4j/bin/ld-linux differ diff --git a/java/application/launch4j/bin/ld-macosx b/java/application/launch4j/bin/ld-macosx new file mode 100755 index 000000000..3defcfa52 Binary files /dev/null and b/java/application/launch4j/bin/ld-macosx differ diff --git a/java/application/launch4j/bin/ld-windows.exe b/java/application/launch4j/bin/ld-windows.exe new file mode 100644 index 000000000..5985c0e27 Binary files /dev/null and b/java/application/launch4j/bin/ld-windows.exe differ diff --git a/java/application/launch4j/bin/windres-linux b/java/application/launch4j/bin/windres-linux new file mode 100755 index 000000000..5b83b9349 Binary files /dev/null and b/java/application/launch4j/bin/windres-linux differ diff --git a/java/application/launch4j/bin/windres-macosx b/java/application/launch4j/bin/windres-macosx new file mode 100755 index 000000000..95405de0c Binary files /dev/null and b/java/application/launch4j/bin/windres-macosx differ diff --git a/java/application/launch4j/bin/windres-windows.exe b/java/application/launch4j/bin/windres-windows.exe new file mode 100644 index 000000000..855b195b0 Binary files /dev/null and b/java/application/launch4j/bin/windres-windows.exe differ diff --git a/build/shared/launch4j/head/LICENSE.txt b/java/application/launch4j/head/LICENSE.txt similarity index 95% rename from build/shared/launch4j/head/LICENSE.txt rename to java/application/launch4j/head/LICENSE.txt index 536488e61..c30f34a8e 100644 --- a/build/shared/launch4j/head/LICENSE.txt +++ b/java/application/launch4j/head/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2004, 2007 Grzegorz Kowal +Copyright (c) 2004, 2014 Grzegorz Kowal Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/build/shared/launch4j/head/consolehead.o b/java/application/launch4j/head/consolehead.o similarity index 100% rename from build/shared/launch4j/head/consolehead.o rename to java/application/launch4j/head/consolehead.o diff --git a/build/shared/launch4j/head/guihead.o b/java/application/launch4j/head/guihead.o similarity index 100% rename from build/shared/launch4j/head/guihead.o rename to java/application/launch4j/head/guihead.o diff --git a/java/application/launch4j/head/head.o b/java/application/launch4j/head/head.o new file mode 100644 index 000000000..32c147675 Binary files /dev/null and b/java/application/launch4j/head/head.o differ diff --git a/build/shared/launch4j/lib/LICENSE.txt b/java/application/launch4j/lib/LICENSE.txt similarity index 100% rename from build/shared/launch4j/lib/LICENSE.txt rename to java/application/launch4j/lib/LICENSE.txt diff --git a/build/shared/launch4j/w32api/LICENSE.txt b/java/application/launch4j/w32api/LICENSE.txt similarity index 100% rename from build/shared/launch4j/w32api/LICENSE.txt rename to java/application/launch4j/w32api/LICENSE.txt diff --git a/build/shared/launch4j/w32api/crt2.o b/java/application/launch4j/w32api/crt2.o similarity index 100% rename from build/shared/launch4j/w32api/crt2.o rename to java/application/launch4j/w32api/crt2.o diff --git a/build/shared/launch4j/w32api/libadvapi32.a b/java/application/launch4j/w32api/libadvapi32.a similarity index 100% rename from build/shared/launch4j/w32api/libadvapi32.a rename to java/application/launch4j/w32api/libadvapi32.a diff --git a/build/shared/launch4j/w32api/libgcc.a b/java/application/launch4j/w32api/libgcc.a similarity index 100% rename from build/shared/launch4j/w32api/libgcc.a rename to java/application/launch4j/w32api/libgcc.a diff --git a/build/shared/launch4j/w32api/libkernel32.a b/java/application/launch4j/w32api/libkernel32.a similarity index 100% rename from build/shared/launch4j/w32api/libkernel32.a rename to java/application/launch4j/w32api/libkernel32.a diff --git a/build/shared/launch4j/w32api/libmingw32.a b/java/application/launch4j/w32api/libmingw32.a similarity index 100% rename from build/shared/launch4j/w32api/libmingw32.a rename to java/application/launch4j/w32api/libmingw32.a diff --git a/build/shared/launch4j/w32api/libmsvcrt.a b/java/application/launch4j/w32api/libmsvcrt.a similarity index 100% rename from build/shared/launch4j/w32api/libmsvcrt.a rename to java/application/launch4j/w32api/libmsvcrt.a diff --git a/build/shared/launch4j/w32api/libshell32.a b/java/application/launch4j/w32api/libshell32.a similarity index 100% rename from build/shared/launch4j/w32api/libshell32.a rename to java/application/launch4j/w32api/libshell32.a diff --git a/build/shared/launch4j/w32api/libuser32.a b/java/application/launch4j/w32api/libuser32.a similarity index 100% rename from build/shared/launch4j/w32api/libuser32.a rename to java/application/launch4j/w32api/libuser32.a diff --git a/java/application/sketch.ico b/java/application/sketch.ico new file mode 100644 index 000000000..c7dbbe92b Binary files /dev/null and b/java/application/sketch.ico differ diff --git a/java/application/template.exe b/java/application/template.exe deleted file mode 100755 index 03d8d5753..000000000 Binary files a/java/application/template.exe and /dev/null differ diff --git a/java/application/template.plist b/java/application/template.plist deleted file mode 100755 index a9e22b9c5..000000000 --- a/java/application/template.plist +++ /dev/null @@ -1,77 +0,0 @@ - - - - - CFBundleName - @@sketch@@ - CFBundleVersion - 1.0 - CFBundleAllowMixedLocalizations - true - CFBundleExecutable - JavaApplicationStub - CFBundleDevelopmentRegion - English - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleInfoDictionaryVersion - 6.0 - CFBundleIconFile - sketch.icns - CFBundleIdentifier - @@sketch@@ - - - LSUIPresentationMode - @@lsuipresentationmode@@ - - LSArchitecturePriority - - @@lsarchitecturepriority@@ - - - Java - - VMOptions - @@vmoptions@@ - - MainClass - @@sketch@@ - - - JVMVersion - 1.6* - - ClassPath - @@classpath@@ - - - Properties - - apple.laf.useScreenMenuBar - true - apple.awt.showGrowBox - false - com.apple.smallTabs - true - apple.awt.Antialiasing - false - apple.awt.TextAntialiasing - true - com.apple.hwaccel - true - - apple.awt.use-file-dialog-packages - true - - - - diff --git a/java/libraries/net/src/processing/net/Server.java b/java/libraries/net/src/processing/net/Server.java index b9d076fba..4cfeb784d 100644 --- a/java/libraries/net/src/processing/net/Server.java +++ b/java/libraries/net/src/processing/net/Server.java @@ -67,11 +67,25 @@ public class Server implements Runnable { * @param port port used to transfer data */ public Server(PApplet parent, int port) { + this(parent, port, null); + } + + + /** + * @param parent typically use "this" + * @param port port used to transfer data + * @param host when multiple NICs are in use, the ip (or name) to bind from + */ + public Server(PApplet parent, int port, String host) { this.parent = parent; this.port = port; try { - server = new ServerSocket(this.port); + if (host == null) { + server = new ServerSocket(this.port); + } else { + server = new ServerSocket(this.port, 10, InetAddress.getByName(host)); + } //clients = new Vector(); clients = new Client[10]; @@ -168,8 +182,8 @@ public class Server implements Runnable { return InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); + return null; } - return null; } @@ -265,6 +279,10 @@ public class Server implements Runnable { } } } + } catch (SocketException e) { + //thrown when server.close() is called and server is waiting on accept + System.err.println("Server SocketException: " + e.getMessage()); + thread = null; } catch (IOException e) { //errorMessage("run", e); e.printStackTrace(); diff --git a/java/libraries/video/src/processing/video/Movie.java b/java/libraries/video/src/processing/video/Movie.java index 93a74ab64..a98781059 100644 --- a/java/libraries/video/src/processing/video/Movie.java +++ b/java/libraries/video/src/processing/video/Movie.java @@ -297,6 +297,34 @@ public class Movie extends PImage implements PConstants { * @brief Jumps to a specific location */ public void jump(float where) { + if (seeking) return; + + if (!sinkReady) { + initSink(); + } + + // Round the time to a multiple of the source framerate, in + // order to eliminate stutter. Suggested by Daniel Shiffman + float fps = getSourceFrameRate(); + int frame = (int)(where * fps); + where = frame / fps; + + boolean res; + long pos = Video.secToNanoLong(where); + + res = playbin.seek(rate, Format.TIME, SeekFlags.FLUSH, + SeekType.SET, pos, SeekType.NONE, -1); + + if (!res) { + PGraphics.showWarning("Seek operation failed."); + } + + // getState() will wait until any async state change + // (like seek in this case) has completed + seeking = true; + playbin.getState(); + seeking = false; + /* if (seeking) return; // don't seek again until the current seek operation is done. if (!sinkReady) { @@ -329,6 +357,7 @@ public class Movie extends PImage implements PConstants { } }; seeker.start(); + */ } diff --git a/todo.txt b/todo.txt index a25038197..c69083e14 100644 --- a/todo.txt +++ b/todo.txt @@ -1,50 +1,19 @@ -0226 pde -X sketches only starting once, or half-starting and hanging -X https://github.com/processing/processing/issues/2402 -X https://github.com/processing/processing/pull/2455 -X reopen current sketch in new mode editor if file extension is compatible -X https://github.com/processing/processing/pull/2457 -X https://github.com/processing/processing/issues/2456 -X crash in the 'recent' menu on startup -X https://github.com/processing/processing/issues/2463 -X sketchbook location is set to an actual sketch (huh?) -X exported apps on Windows 64 not working? -X https://github.com/processing/processing/issues/2468 -X just needed to add the local path for Java -X when exporting with local Java embedded, use that version -X https://github.com/processing/processing/issues/2349 -X (we can do this now since we're actually doing the embedding) - - -high -_ new launch4j 3.4 -_ http://sourceforge.net/projects/launch4j/files/launch4j-3/3.4/ -_ sketch sometimes simply does not launch -_ https://github.com/processing/processing/issues/2402 -_ https://github.com/processing/processing/pull/2455 -_ exported apps reporting as "damaged" on OS X -_ JNA conflicts can be avoided with a -D option -_ https://github.com/processing/processing/issues/2239 -_ QuickReference tool was able to bring down the environment -_ https://github.com/processing/processing/issues/2229 -_ tab characters not recognized/drawn in the editor (2.1) -_ https://github.com/processing/processing/issues/2180 -_ https://github.com/processing/processing/issues/2183 -_ udp library has tabs in the text -_ decision to be made on nextTabStop() inside TextAreaPainter -_ Chinese text is overlapped in Processing 2.1 editor -_ https://github.com/processing/processing/issues/2173 -_ https://github.com/processing/processing/pull/2318 -_ https://github.com/processing/processing/pull/2323 -_ check on why 2x core.jar inside the Java folder -_ maybe OS X Java can't look in subfolders? (just auto-adds things) +0227 pde +X use mouseReleased() instead of mousePressed() in color selector +X otherwise it registers the release as a click in the color window +X https://github.com/processing/processing/issues/2514 medium -_ import static causes exception (with fix) -_ https://github.com/processing/processing/issues/8 -o https://github.com/processing/processing/pull/2273 -X can't use this patch, too confusing +_ possible to open a sketch multiple times +_ by double-clicking one of its files instead of the main pde file +_ https://github.com/processing/processing/issues/2506 +_ closing the color selector makes things freeze (only Linux and Windows?) +_ https://github.com/processing/processing/issues/2381 +_ check on why 2x core.jar inside the Java folder +_ maybe OS X Java can't look in subfolders? (just auto-adds things) +_ display "1" is not correct in 2.1.2 +_ https://github.com/processing/processing/issues/2502 _ re/move things from Google Code downloads _ https://code.google.com/p/support/wiki/DownloadsFAQ _ clean out the repo @@ -57,9 +26,7 @@ _ add font fixes to the rest of the API _ https://github.com/processing/processing/commit/eaff673d173b2d27f276cf5c59e3abf6c0fab86b _ g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, _ RenderingHints.VALUE_FRACTIONALMETRICS_ON); -_ get stack trace issues with NPE -_ https://github.com/processing/processing/pull/2359 -_ dataPath() not working when app is not run from app dir +_ dataPath() not working when app is not run from app dir on Linux _ https://github.com/processing/processing/issues/2195 _ should default to the local Java on Windows and Linux _ have export apps default to the local JRE @@ -68,6 +35,7 @@ _ launch4j may be all set, but double-check _ try installing 10.7.3 on Mac Mini and check whether things run _ make sure it's only running on 64-bit machines? _ use platformDelete() to remove untitled sketches? +_ would allow us to use the /tmp folder _ change to using platformDelete() instead of Base.removeDir() where possible _ verify that the OS X version uses the real call _ and doesn't just look for .Trash @@ -83,23 +51,18 @@ _ "String index out of range" error _ https://github.com/processing/processing/issues/1940 _ look through all isPopupTrigger() code _ make sure both press/release are implemented -_ change Windows export to use launch4j instead of the launcher.cpp file -_ actually call ant from inside p5? _ emacs style errors in commander aren't quite right _ https://github.com/processing/processing/issues/2158 -_ export application folder location (for Manindra) -_ https://github.com/processing/processing/issues/2399 _ add documentation for how to run mode development from Eclipse _ implementation/changes from JDF _ modes are being loaded multiple times, which can cause trouble _ add minimum version required (or max version?) to libraries/modes/etc +_ no high-res display support for the PDE +_ PDE and sketches are 2x smaller on high-res Windows 8 machines +_ https://github.com/processing/processing/issues/2411 pulls -_ if/else formatting is broken -_ https://github.com/processing/processing/pull/2477 -_ fix for various net issues -_ https://github.com/processing/processing/pull/2475 _ may need a progress bar for "save as" _ or just the file copy function in general _ since it may take a long time (i.e. 1000s of screen grabs) @@ -109,7 +72,6 @@ _ https://github.com/processing/processing/pull/2370 post 2.1 cleaning -_ remove video for macosx32 from the repo permanently _ remove the prefs for 32/64-bit from Preferences _ remove the extra OS X cruft inside Runner.java _ exclude 'fonts' folder from build (since it's going into the JRE) @@ -472,9 +434,6 @@ _ http://code.google.com/p/processing/issues/detail?id=746 PDE / Export -_ use launch4j for export and p5 app itself -_ perhaps even calling it through an ant task -_ windows exported exe problems (pcho) _ if the lib folder goes missing from export, give an error _ also any .jar files that are missing, give an error _ showing more debug messages (command line?) @@ -666,13 +625,6 @@ _ redo panel to use proper Box layout etc _ also needs to look good across all platforms _ http://code.google.com/p/processing/issues/detail?id=28 _ https://github.com/processing/processing/issues/67 -_ make available the background colors for present mode, stop button color -_ isolate color chooser into a simpler/smaller class outside tools -_ then can also use from inside processing applications as well -_ http://code.google.com/p/processing/issues/detail?id=30 -_ maybe user prefs should only cover things that've changed? -_ how to balance colors/etc being stored elsewhere -_ ton of work to maintain this... PDE / Runner @@ -769,6 +721,13 @@ _ need to unpack InvocationTargetException in xxxxxxEvent calls _ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=VideoCamera;action=display;num=1116850328#3 +LIBRARIES / Net + +_ modernize Client/Server code to use synchronized lists +_ do we let people use the public vars in Server and Client? +_ are they documented? + + //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// @@ -825,13 +784,8 @@ DIST / Windows _ processing-java output as UTF-8 makes Windows unhappy _ https://github.com/processing/processing/issues/1633 -_ updated launch4j 3.1 beta -_ http://sourceforge.net/projects/launch4j/files/launch4j-3/ _ does launching p5 from inside the .zip folder cause it to quit immediately? _ how can we provide an error message here? -_ exe instead of bat to make exported apps run in 64-bit -_ http://code.google.com/p/processing/issues/detail?id=885 -_ might not be necessary with new launch4j! _ how to handle double-clicked files on windows? _ big deal for psk and others _ this may already work with SingleInstance stuff