Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial sync with Processing 6406. Compiles and runs (on Mac OS X) bu…

…t probably very buggy.
  • Loading branch information...
commit 34579ae440a7bf68ea5ef962b8793b7607589b70 1 parent d36fbfe
@damellis damellis authored
Showing with 22,886 additions and 2,191 deletions.
  1. +201 −51 app/src/processing/app/Base.java
  2. +247 −183 app/src/processing/app/Editor.java
  3. +5 −15 app/src/processing/app/EditorConsole.java
  4. +11 −0 app/src/processing/app/EditorListener.java
  5. +89 −131 app/src/processing/app/EditorToolbar.java
  6. +33 −0 app/src/processing/app/Platform.java
  7. +5 −0 app/src/processing/app/Preferences.java
  8. +150 −79 app/src/processing/app/Sketch.java
  9. +95 −0 app/src/processing/app/StreamRedirectThread.java
  10. +6 −2 app/src/processing/app/WebServer.java
  11. +3 −2 app/src/processing/app/debug/{EventThread.java → EventThread.java.disabled}
  12. +6 −1 app/src/processing/app/debug/MessageSiphon.java
  13. +104 −498 app/src/processing/app/debug/{Runner.java → Runner.java.disabled}
  14. +9 −1 app/src/processing/app/debug/RunnerException.java
  15. +2 −0  app/src/processing/app/debug/RunnerListener.java
  16. +12 −3 app/src/processing/app/linux/Platform.java
  17. +35 −23 app/src/processing/app/macosx/Platform.java
  18. +2 −1  app/src/processing/app/macosx/ThinkDifferent.java
  19. +51 −57 app/src/processing/app/preproc/PdePreprocessor.java
  20. +35 −1 app/src/processing/app/syntax/InputHandler.java
  21. +14 −1 app/src/processing/app/syntax/JEditTextArea.java
  22. +22 −7 app/src/processing/app/syntax/PdeTextAreaDefaults.java
  23. +26 −2 app/src/processing/app/syntax/TextAreaPainter.java
  24. +187 −0 app/src/processing/app/syntax/im/CompositionTextManager.java
  25. +124 −0 app/src/processing/app/syntax/im/CompositionTextPainter.java
  26. +105 −0 app/src/processing/app/syntax/im/InputMethodSupport.java
  27. +20 −7 app/src/processing/app/tools/ColorSelector.java
  28. +525 −57 app/src/processing/app/tools/CreateFont.java
  29. +38 −1 app/src/processing/app/windows/Platform.java
  30. +1 −0  build/macosx/make.sh
  31. +27 −5 build/shared/lib/preferences.txt
  32. +17 −17 core/.project
  33. +271 −261 core/.settings/org.eclipse.jdt.core.prefs
  34. +2 −2 core/.settings/org.eclipse.jdt.ui.prefs
  35. +26 −0 core/build.xml
  36. +55 −0 core/done.txt
  37. +7 −0 core/methods/.classpath
  38. +17 −0 core/methods/.project
  39. +28 −0 core/methods/build.xml
  40. +9,483 −0 core/methods/demo/PApplet.java
  41. +5,075 −0 core/methods/demo/PGraphics.java
  42. +2,862 −0 core/methods/demo/PImage.java
  43. BIN  core/methods/methods.jar
  44. +272 −0 core/methods/src/PAppletMethods.java
  45. +599 −90 core/src/processing/core/PApplet.java
  46. +44 −1 core/src/processing/core/PConstants.java
  47. +522 −356 core/src/processing/core/PFont.java
  48. +815 −159 core/src/processing/core/PGraphics.java
  49. +32 −13 core/src/processing/core/PGraphics3D.java
  50. +10 −0 core/src/processing/core/PGraphicsJava2D.java
  51. +213 −65 core/src/processing/core/PImage.java
  52. +1 −1  core/src/processing/core/PPolygon.java
  53. +129 −16 core/src/processing/core/PShape.java
  54. +5 −1 core/src/processing/core/PShapeSVG.java
  55. +2 −2 core/src/processing/core/PVector.java
  56. +93 −33 core/src/processing/xml/XMLElement.java
  57. +116 −46 core/todo.txt
View
252 app/src/processing/app/Base.java
@@ -3,7 +3,7 @@
/*
Part of the Processing project - http://processing.org
- Copyright (c) 2004-09 Ben Fry and Casey Reas
+ Copyright (c) 2004-10 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
@@ -42,7 +42,10 @@
*/
public class Base {
public static final int REVISION = 18;
+ /** This might be replaced by main() if there's a lib/version.txt file. */
static String VERSION_NAME = "0018";
+ /** Set true if this a proper release rather than a numbered revision. */
+ static public boolean RELEASE = false;
static HashMap<Integer, String> platformNames = new HashMap<Integer, String>();
static {
@@ -101,31 +104,16 @@
// ArrayList editors = Collections.synchronizedList(new ArrayList<Editor>());
Editor activeEditor;
-// int nextEditorX;
-// int nextEditorY;
-
-// import com.sun.jna.Library;
-// import com.sun.jna.Native;
-
-// public interface CLibrary extends Library {
-// CLibrary INSTANCE = (CLibrary)Native.loadLibrary("c", CLibrary.class);
-// int setenv(String name, String value, int overwrite);
-// String getenv(String name);
-// int unsetenv(String name);
-// int putenv(String string);
-// }
-
static public void main(String args[]) {
-// /Users/fry/coconut/sketchbook/libraries/gsvideo/library
-// CLibrary clib = CLibrary.INSTANCE;
-// clib.setenv("DYLD_LIBRARY_PATH", "/Users/fry/coconut/sketchbook/libraries/gsvideo/library", 1);
-// System.out.println("env is now " + clib.getenv("DYLD_LIBRARY_PATH"));
-
try {
File versionFile = getContentFile("lib/version.txt");
if (versionFile.exists()) {
- VERSION_NAME = PApplet.loadStrings(versionFile)[0];
+ String version = PApplet.loadStrings(versionFile)[0];
+ if (!version.equals(VERSION_NAME)) {
+ VERSION_NAME = version;
+ RELEASE = true;
+ }
}
} catch (Exception e) {
e.printStackTrace();
@@ -187,10 +175,12 @@ static public void main(String args[]) {
try {
platform.setLookAndFeel();
} catch (Exception e) {
- System.err.println("Non-fatal error while setting the Look & Feel.");
- System.err.println("The error message follows, however Arduino should run fine.");
- System.err.println(e.getMessage());
- //e.printStackTrace();
+ String mess = e.getMessage();
+ if (mess.indexOf("ch.randelshofer.quaqua.QuaquaLookAndFeel") == -1) {
+ System.err.println("Non-fatal error while setting the Look & Feel.");
+ System.err.println("The error message follows, however Arduino should run fine.");
+ System.err.println(mess);
+ }
}
// Create a location for untitled sketches
@@ -213,7 +203,7 @@ static protected boolean isCommandLine() {
static protected void initPlatform() {
try {
- Class platformClass = Class.forName("processing.app.Platform");
+ Class<?> platformClass = Class.forName("processing.app.Platform");
if (Base.isMacOS()) {
platformClass = Class.forName("processing.app.macosx.Platform");
} else if (Base.isWindows()) {
@@ -270,7 +260,7 @@ public Base(String[] args) {
}
}
- // If not path is set, get the default sketchbook folder for this platform
+ // If no path is set, get the default sketchbook folder for this platform
if (sketchbookPath == null) {
File defaultFolder = getDefaultSketchbookFolder();
Preferences.set("sketchbook.path", defaultFolder.getAbsolutePath());
@@ -456,8 +446,8 @@ protected void handleActivated(Editor whichEditor) {
protected int[] nextEditorLocation() {
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
- int defaultWidth = Preferences.getInteger("default.window.width");
- int defaultHeight = Preferences.getInteger("default.window.height");
+ int defaultWidth = Preferences.getInteger("editor.window.width.default");
+ int defaultHeight = Preferences.getInteger("editor.window.height.default");
if (activeEditor == null) {
// If no current active editor, use default placement
@@ -584,7 +574,7 @@ public void handleNew() {
* Replace the sketch in the current window with a new untitled document.
*/
public void handleNewReplace() {
- if (!activeEditor.checkModified(true)) {
+ if (!activeEditor.checkModified()) {
return; // sketch was modified, and user canceled
}
// Close the running window, avoid window boogers with multiple sketches
@@ -616,7 +606,7 @@ protected void handleNewReplaceImpl() {
* @param path Location of the primary pde file for the sketch.
*/
public void handleOpenReplace(String path) {
- if (!activeEditor.checkModified(true)) {
+ if (!activeEditor.checkModified()) {
return; // sketch was modified, and user canceled
}
// Close the running window, avoid window boogers with multiple sketches
@@ -758,8 +748,8 @@ protected Editor handleOpen(String path, int[] location) {
*/
public boolean handleClose(Editor editor) {
// Check if modified
- boolean immediate = editors.size() == 1;
- if (!editor.checkModified(immediate)) {
+// boolean immediate = editors.size() == 1;
+ if (!editor.checkModified()) {
return false;
}
@@ -862,7 +852,7 @@ public boolean handleQuit() {
protected boolean handleQuitEach() {
int index = 0;
for (Editor editor : editors) {
- if (editor.checkModified(true)) {
+ if (editor.checkModified()) {
// Update to the new/final sketch path for this fella
storeSketchPath(editor, index);
index++;
@@ -914,7 +904,8 @@ public void actionPerformed(ActionEvent e) {
// Add a list of all sketches and subfolders
try {
- boolean sketches = addSketches(menu, getSketchbookFolder(), true);
+ //boolean sketches = addSketches(menu, getSketchbookFolder(), true);
+ boolean sketches = addSketches(menu, getSketchbookFolder());
if (sketches) menu.addSeparator();
} catch (IOException e) {
e.printStackTrace();
@@ -923,11 +914,11 @@ public void actionPerformed(ActionEvent e) {
//System.out.println("rebuilding examples menu");
// Add each of the subfolders of examples directly to the menu
try {
- boolean found = addSketches(menu, examplesFolder, true);
+ boolean found = addSketches(menu, examplesFolder);
if (found) menu.addSeparator();
- found = addSketches(menu, getSketchbookLibrariesFolder(), true);
+ found = addSketches(menu, getSketchbookLibrariesFolder());
if (found) menu.addSeparator();
- addSketches(menu, librariesFolder, true);
+ addSketches(menu, librariesFolder);
} catch (IOException e) {
e.printStackTrace();
}
@@ -939,7 +930,8 @@ protected void rebuildSketchbookMenu(JMenu menu) {
//new Exception().printStackTrace();
try {
menu.removeAll();
- addSketches(menu, getSketchbookFolder(), false);
+ //addSketches(menu, getSketchbookFolder(), false);
+ addSketches(menu, getSketchbookFolder());
} catch (IOException e) {
e.printStackTrace();
}
@@ -983,11 +975,11 @@ public void rebuildExamplesMenu(JMenu menu) {
//System.out.println("rebuilding examples menu");
try {
menu.removeAll();
- boolean found = addSketches(menu, examplesFolder, false);
+ boolean found = addSketches(menu, examplesFolder);
if (found) menu.addSeparator();
- found = addSketches(menu, getSketchbookLibrariesFolder(), false);
+ found = addSketches(menu, getSketchbookLibrariesFolder());
if (found) menu.addSeparator();
- addSketches(menu, librariesFolder, false);
+ addSketches(menu, librariesFolder);
} catch (IOException e) {
e.printStackTrace();
}
@@ -1050,8 +1042,7 @@ public void actionPerformed(ActionEvent actionevent) {
* should replace the sketch in the current window, or false when the
* sketch should open in a new window.
*/
- protected boolean addSketches(JMenu menu, File folder,
- final boolean openReplaces) throws IOException {
+ protected boolean addSketches(JMenu menu, File folder) throws IOException {
// skip .DS_Store files, etc (this shouldn't actually be necessary)
if (!folder.isDirectory()) return false;
@@ -1068,7 +1059,8 @@ protected boolean addSketches(JMenu menu, File folder,
public void actionPerformed(ActionEvent e) {
String path = e.getActionCommand();
if (new File(path).exists()) {
- if (openReplaces) {
+// if (openReplaces) {
+ if ((e.getModifiers() & ActionEvent.SHIFT_MASK) == 0) {
handleOpenReplace(path);
} else {
handleOpen(path);
@@ -1121,14 +1113,15 @@ public void actionPerformed(ActionEvent e) {
} else {
// don't create an extra menu level for a folder named "examples"
if (subfolder.getName().equals("examples")) {
- boolean found = addSketches(menu, subfolder, openReplaces); //, false);
+ boolean found = addSketches(menu, subfolder);
if (found) ifound = true;
} else {
// not a sketch folder, but maybe a subfolder containing sketches
JMenu submenu = new JMenu(list[i]);
// needs to be separate var
// otherwise would set ifound to false
- boolean found = addSketches(submenu, subfolder, openReplaces); //, false);
+ //boolean found = addSketches(submenu, subfolder, openReplaces); //, false);
+ boolean found = addSketches(submenu, subfolder); //, false);
if (found) {
menu.add(submenu);
ifound = true;
@@ -1319,6 +1312,11 @@ public void handlePrefs() {
// }
+ static public Platform getPlatform() {
+ return platform;
+ }
+
+
static public String getPlatformName() {
String osname = System.getProperty("os.name");
@@ -1714,12 +1712,11 @@ static public boolean isCloseWindowEvent(KeyEvent e) {
}
*/
-
/**
* Registers key events for a Ctrl-W and ESC with an ActionListener
* that will take care of disposing the window.
*/
- static public void registerWindowCloseKeys(JRootPane root, //Window window,
+ static public void registerWindowCloseKeys(JRootPane root,
ActionListener disposer) {
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
root.registerKeyboardAction(disposer, stroke,
@@ -1836,6 +1833,129 @@ static public void showError(String title, String message, Throwable e) {
// ...................................................................
+
+ // incomplete
+ static public int showYesNoCancelQuestion(Editor editor, String title,
+ String primary, String secondary) {
+ if (!Base.isMacOS()) {
+ int result =
+ JOptionPane.showConfirmDialog(null, primary + "\n" + secondary, title,
+ JOptionPane.YES_NO_CANCEL_OPTION,
+ JOptionPane.QUESTION_MESSAGE);
+ return result;
+// if (result == JOptionPane.YES_OPTION) {
+//
+// } else if (result == JOptionPane.NO_OPTION) {
+// return true; // ok to continue
+//
+// } else if (result == JOptionPane.CANCEL_OPTION) {
+// return false;
+//
+// } else {
+// throw new IllegalStateException();
+// }
+
+ } else {
+ // Pane formatting adapted from the Quaqua guide
+ // http://www.randelshofer.ch/quaqua/guide/joptionpane.html
+ JOptionPane pane =
+ new JOptionPane("<html> " +
+ "<head> <style type=\"text/css\">"+
+ "b { font: 13pt \"Lucida Grande\" }"+
+ "p { font: 11pt \"Lucida Grande\"; margin-top: 8px }"+
+ "</style> </head>" +
+ "<b>Do you want to save changes to this sketch<BR>" +
+ " before closing?</b>" +
+ "<p>If you don't save, your changes will be lost.",
+ JOptionPane.QUESTION_MESSAGE);
+
+ String[] options = new String[] {
+ "Save", "Cancel", "Don't Save"
+ };
+ pane.setOptions(options);
+
+ // highlight the safest option ala apple hig
+ pane.setInitialValue(options[0]);
+
+ // on macosx, setting the destructive property places this option
+ // away from the others at the lefthand side
+ pane.putClientProperty("Quaqua.OptionPane.destructiveOption",
+ new Integer(2));
+
+ JDialog dialog = pane.createDialog(editor, null);
+ dialog.setVisible(true);
+
+ Object result = pane.getValue();
+ if (result == options[0]) {
+ return JOptionPane.YES_OPTION;
+ } else if (result == options[1]) {
+ return JOptionPane.CANCEL_OPTION;
+ } else if (result == options[2]) {
+ return JOptionPane.NO_OPTION;
+ } else {
+ return JOptionPane.CLOSED_OPTION;
+ }
+ }
+ }
+
+
+//if (result == JOptionPane.YES_OPTION) {
+ //
+// } else if (result == JOptionPane.NO_OPTION) {
+// return true; // ok to continue
+ //
+// } else if (result == JOptionPane.CANCEL_OPTION) {
+// return false;
+ //
+// } else {
+// throw new IllegalStateException();
+// }
+
+ static public int showYesNoQuestion(Frame editor, String title,
+ String primary, String secondary) {
+ if (!Base.isMacOS()) {
+ return JOptionPane.showConfirmDialog(editor,
+ "<html><body>" +
+ "<b>" + primary + "</b>" +
+ "<br>" + secondary, title,
+ JOptionPane.YES_NO_OPTION,
+ JOptionPane.QUESTION_MESSAGE);
+ } else {
+ // Pane formatting adapted from the Quaqua guide
+ // http://www.randelshofer.ch/quaqua/guide/joptionpane.html
+ JOptionPane pane =
+ new JOptionPane("<html> " +
+ "<head> <style type=\"text/css\">"+
+ "b { font: 13pt \"Lucida Grande\" }"+
+ "p { font: 11pt \"Lucida Grande\"; margin-top: 8px }"+
+ "</style> </head>" +
+ "<b>" + primary + "</b>" +
+ "<p>" + secondary + "</p>",
+ JOptionPane.QUESTION_MESSAGE);
+
+ String[] options = new String[] {
+ "Yes", "No"
+ };
+ pane.setOptions(options);
+
+ // highlight the safest option ala apple hig
+ pane.setInitialValue(options[0]);
+
+ JDialog dialog = pane.createDialog(editor, null);
+ dialog.setVisible(true);
+
+ Object result = pane.getValue();
+ if (result == options[0]) {
+ return JOptionPane.YES_OPTION;
+ } else if (result == options[1]) {
+ return JOptionPane.NO_OPTION;
+ } else {
+ return JOptionPane.CLOSED_OPTION;
+ }
+ }
+ }
+
+
/**
* Retrieve a path to something in the Processing folder. Eventually this
* may refer to the Contents subfolder of Processing.app, if we bundle things
@@ -1959,6 +2079,36 @@ static public int countLines(String what) {
}
+
+ /**
+ * Read from a file with a bunch of attribute/value pairs
+ * that are separated by = and ignore comments with #.
+ */
+ static public HashMap<String,String> readSettings(File inputFile) {
+ HashMap<String,String> outgoing = new HashMap<String,String>();
+ if (!inputFile.exists()) return outgoing; // return empty hash
+
+ String lines[] = PApplet.loadStrings(inputFile);
+ for (int i = 0; i < lines.length; i++) {
+ int hash = lines[i].indexOf('#');
+ String line = (hash == -1) ?
+ lines[i].trim() : lines[i].substring(0, hash).trim();
+ if (line.length() == 0) continue;
+
+ int equals = line.indexOf('=');
+ if (equals == -1) {
+ System.err.println("ignoring illegal line in " + inputFile);
+ System.err.println(" " + line);
+ continue;
+ }
+ String attr = line.substring(0, equals).trim();
+ String valu = line.substring(equals + 1).trim();
+ outgoing.put(attr, valu);
+ }
+ return outgoing;
+ }
+
+
static public void copyFile(File sourceFile,
File targetFile) throws IOException {
InputStream from =
@@ -2116,7 +2266,7 @@ static public int calcFolderSize(File folder) {
static public String[] listFiles(File folder, boolean relative) {
String path = folder.getAbsolutePath();
- Vector vector = new Vector();
+ Vector<String> vector = new Vector<String>();
listFiles(relative ? (path + File.separator) : "", path, vector);
String outgoing[] = new String[vector.size()];
vector.copyInto(outgoing);
@@ -2125,7 +2275,7 @@ static public int calcFolderSize(File folder) {
static protected void listFiles(String basePath,
- String path, Vector vector) {
+ String path, Vector<String> vector) {
File folder = new File(path);
String list[] = folder.list();
if (list == null) return;
View
430 app/src/processing/app/Editor.java
@@ -43,7 +43,6 @@
import gnu.io.*;
-
/**
* Main editor panel for the Processing Development Environment.
*/
@@ -114,7 +113,6 @@
EditorLineStatus lineStatus;
- boolean newEditor = true;
JEditorPane editorPane;
JEditTextArea textarea;
@@ -122,14 +120,14 @@
// runtime information and window placement
Point sketchWindowLocation;
- Runner runtime;
+ //Runner runtime;
JMenuItem exportAppItem;
JMenuItem saveMenuItem;
JMenuItem saveAsMenuItem;
boolean running;
- boolean presenting;
+ //boolean presenting;
boolean uploading;
// undo fellers
@@ -142,6 +140,12 @@
FindReplace find;
+ Runnable runHandler;
+ Runnable presentHandler;
+ Runnable stopHandler;
+ Runnable exportHandler;
+ Runnable exportAppHandler;
+
public Editor(Base ibase, String path, int[] location) {
super("Arduino");
@@ -149,6 +153,9 @@ public Editor(Base ibase, String path, int[] location) {
//Base.setIcon(this);
+ // Install default actions for Run, Present, etc.
+ resetHandlers();
+
// add listener to handle window close box hit event
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
@@ -232,22 +239,7 @@ public void windowDeactivated(WindowEvent e) {
lineStatus = new EditorLineStatus(textarea);
consolePanel.add(lineStatus, BorderLayout.SOUTH);
-// if (newEditor) {
-// try {
-// setupEditorPane();
-// upper.add(editorPane);
-// } catch (Exception e1) {
-// PrintWriter w = PApplet.createWriter(new File("/Users/fry/Desktop/blah.txt"));
-// w.println(e1.getMessage());
-// e1.printStackTrace(w);
-// w.flush();
-// w.close();
-//// e1.printStackTrace());
-//// e1.printStackTrace(System.out);
-// }
-// } else {
upper.add(textarea);
-// }
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
upper, consolePanel);
@@ -276,64 +268,10 @@ public void windowDeactivated(WindowEvent e) {
listener = new EditorListener(this, textarea);
pain.add(box);
- pain.setTransferHandler(new TransferHandler() {
+ // get shift down/up events so we can show the alt version of toolbar buttons
+ textarea.addKeyListener(toolbar);
- public boolean canImport(JComponent dest, DataFlavor[] flavors) {
- return true;
- }
-
- public boolean importData(JComponent src, Transferable transferable) {
- int successful = 0;
-
- try {
- DataFlavor uriListFlavor =
- new DataFlavor("text/uri-list;class=java.lang.String");
-
- if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
- java.util.List list = (java.util.List)
- transferable.getTransferData(DataFlavor.javaFileListFlavor);
- for (int i = 0; i < list.size(); i++) {
- File file = (File) list.get(i);
- if (sketch.addFile(file)) {
- successful++;
- }
- }
- } else if (transferable.isDataFlavorSupported(uriListFlavor)) {
- //System.out.println("uri list");
- String data = (String)transferable.getTransferData(uriListFlavor);
- String[] pieces = PApplet.splitTokens(data, "\r\n");
- //PApplet.println(pieces);
- for (int i = 0; i < pieces.length; i++) {
- if (pieces[i].startsWith("#")) continue;
-
- String path = null;
- if (pieces[i].startsWith("file:///")) {
- path = pieces[i].substring(7);
- } else if (pieces[i].startsWith("file:/")) {
- path = pieces[i].substring(5);
- }
- if (sketch.addFile(new File(path))) {
- successful++;
- }
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
-
- if (successful == 0) {
- statusError("No files were added to the sketch.");
-
- } else if (successful == 1) {
- statusNotice("One file added to the sketch.");
-
- } else {
- statusNotice(successful + " files added to the sketch.");
- }
- return true;
- }
- });
+ pain.setTransferHandler(new FileDropHandler());
// System.out.println("t1");
@@ -345,6 +283,20 @@ public boolean importData(JComponent src, Transferable transferable) {
// Set the window bounds and the divider location before setting it visible
setPlacement(location);
+
+ // If the window is resized too small this will resize it again to the
+ // minimums. Adapted by Chris Lonnen from comments here:
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4320050
+ // as a fix for http://dev.processing.org/bugs/show_bug.cgi?id=25
+ final int minW = Preferences.getInteger("editor.window.width.min");
+ final int minH = Preferences.getInteger("editor.window.height.min");
+ addComponentListener(new java.awt.event.ComponentAdapter() {
+ public void componentResized(ComponentEvent event) {
+ setSize((getWidth() < minW) ? minW : getWidth(),
+ (getHeight() < minH) ? minH : getHeight());
+ }
+ });
+
// System.out.println("t3");
// Bring back the general options for the editor
@@ -363,46 +315,71 @@ public boolean importData(JComponent src, Transferable transferable) {
}
- /*
- // http://wiki.netbeans.org/DevFaqEditorCodeCompletionAnyJEditorPane
- void setupEditorPane() throws IOException {
- editorPane = new JEditorPane();
+ /**
+ * Handles files dragged & dropped from the desktop and into the editor
+ * window. Dragging files into the editor window is the same as using
+ * "Sketch &rarr; Add File" for each file.
+ */
+ class FileDropHandler extends TransferHandler {
+ public boolean canImport(JComponent dest, DataFlavor[] flavors) {
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean importData(JComponent src, Transferable transferable) {
+ int successful = 0;
+
+ try {
+ DataFlavor uriListFlavor =
+ new DataFlavor("text/uri-list;class=java.lang.String");
+
+ if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
+ java.util.List list = (java.util.List)
+ transferable.getTransferData(DataFlavor.javaFileListFlavor);
+ for (int i = 0; i < list.size(); i++) {
+ File file = (File) list.get(i);
+ if (sketch.addFile(file)) {
+ successful++;
+ }
+ }
+ } else if (transferable.isDataFlavorSupported(uriListFlavor)) {
+ // Some platforms (Mac OS X and Linux, when this began) preferred
+ // this method of moving files.
+ String data = (String)transferable.getTransferData(uriListFlavor);
+ String[] pieces = PApplet.splitTokens(data, "\r\n");
+ for (int i = 0; i < pieces.length; i++) {
+ if (pieces[i].startsWith("#")) continue;
+
+ String path = null;
+ if (pieces[i].startsWith("file:///")) {
+ path = pieces[i].substring(7);
+ } else if (pieces[i].startsWith("file:/")) {
+ path = pieces[i].substring(5);
+ }
+ if (sketch.addFile(new File(path))) {
+ successful++;
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ if (successful == 0) {
+ statusError("No files were added to the sketch.");
+
+ } else if (successful == 1) {
+ statusNotice("One file added to the sketch.");
+
+ } else {
+ statusNotice(successful + " files added to the sketch.");
+ }
+ return true;
+ }
+ }
+
- // This will find the Java editor kit and associate it with
- // our editor pane. But that does not give us code completion
- // just yet because we have no Java context (i.e. no class path, etc.).
- // However, this does give us syntax coloring.
- EditorKit kit = CloneableEditorSupport.getEditorKit("text/x-java");
- editorPane.setEditorKit(kit);
-
- // You can specify any ".java" file.
- // If the file does not exist, it will be created.
- // The contents of the file does not matter.
- // The extension must be ".java", however.
-// String newSourcePath = "/Users/fry/Desktop/tmp.java";
-
-// File tmpFile = new File(newSourcePath);
-// System.out.println(tmpFile.getParent() + " " + tmpFile.getName());
-// FileObject fob = FileUtil.createData(tmpFile);
- File tmpFile = File.createTempFile("temp", ".java");
- FileObject fob = FileUtil.toFileObject(FileUtil.normalizeFile(tmpFile));
-
- DataObject dob = DataObject.find(fob);
- editorPane.getDocument().putProperty(Document.StreamDescriptionProperty, dob);
-
- // This sets up a default class path for us so that
- // we can find all the JDK classes via code completion.
- DialogBinding.bindComponentToFile(fob, 0, 0, editorPane);
-
- // Last but not least, we need to fill the editor pane with
- // some initial dummy code - as it seems somehow required to
- // kick-start code completion.
- // A simple dummy package declaration will do.
- editorPane.setText("package dummy;");
- }
- */
-
-
protected void setPlacement(int[] location) {
setBounds(location[0], location[1], location[2], location[3]);
if (location[4] != 0) {
@@ -434,10 +411,10 @@ protected void setPlacement(int[] location) {
* This appears to only be required on OS X 10.2, and is not
* even being called on later versions of OS X or Windows.
*/
- public Dimension getMinimumSize() {
- //System.out.println("getting minimum size");
- return new Dimension(500, 550);
- }
+// public Dimension getMinimumSize() {
+// //System.out.println("getting minimum size");
+// return new Dimension(500, 550);
+// }
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@@ -737,7 +714,7 @@ public void menuSelected(MenuEvent e) {
protected void addTools(JMenu menu, File sourceFolder) {
- HashMap toolItems = new HashMap();
+ HashMap<String, JMenuItem> toolItems = new HashMap<String, JMenuItem>();
File[] folders = sourceFolder.listFiles(new FileFilter() {
public boolean accept(File folder) {
@@ -807,7 +784,7 @@ public boolean accept(File dir, String name) {
// If no class name found, just move on.
if (className == null) continue;
- Class toolClass = Class.forName(className, true, loader);
+ Class<?> toolClass = Class.forName(className, true, loader);
final Tool tool = (Tool) toolClass.newInstance();
tool.init(Editor.this);
@@ -817,6 +794,7 @@ public boolean accept(File dir, String name) {
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(tool);
+ //new Thread(tool).start();
}
});
//menu.add(item);
@@ -826,7 +804,7 @@ public void actionPerformed(ActionEvent e) {
e.printStackTrace();
}
}
- ArrayList<String> toolList = new ArrayList(toolItems.keySet());
+ ArrayList<String> toolList = new ArrayList<String>(toolItems.keySet());
if (toolList.size() == 0) return;
menu.addSeparator();
@@ -843,7 +821,7 @@ protected String findClassInZipFile(String base, File file) {
try {
ZipFile zipFile = new ZipFile(file);
- Enumeration entries = zipFile.entries();
+ Enumeration<?> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
@@ -869,7 +847,7 @@ protected String findClassInZipFile(String base, File file) {
protected JMenuItem createToolMenuItem(String className) {
try {
- Class toolClass = Class.forName(className);
+ Class<?> toolClass = Class.forName(className);
final Tool tool = (Tool) toolClass.newInstance();
JMenuItem item = new JMenuItem(tool.getMenuTitle());
@@ -903,12 +881,14 @@ protected JMenu addInternalTools(JMenu menu) {
menu.add(createToolMenuItem("processing.app.tools.Archiver"));
menu.add(createToolMenuItem("processing.app.tools.FixEncoding"));
- /*
- //menu.add(createToolMenuItem("processing.app.tools.android.Build"));
- item = createToolMenuItem("processing.app.tools.android.Build");
- item.setAccelerator(KeyStroke.getKeyStroke('D', modifiers));
- menu.add(item);
- */
+// // These are temporary entries while Android mode is being worked out.
+// // The mode will not be in the tools menu, and won't involve a cmd-key
+// if (!Base.RELEASE) {
+// item = createToolMenuItem("processing.app.tools.android.AndroidTool");
+// item.setAccelerator(KeyStroke.getKeyStroke('D', modifiers));
+// menu.add(item);
+// menu.add(createToolMenuItem("processing.app.tools.android.Reset"));
+// }
return menu;
}
@@ -1363,6 +1343,35 @@ protected void updateRedoState() {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ // these will be done in a more generic way soon, more like:
+ // setHandler("action name", Runnable);
+ // but for the time being, working out the kinks of how many things to
+ // abstract from the editor in this fashion.
+
+
+ public void setHandlers(Runnable runHandler, Runnable presentHandler,
+ Runnable stopHandler,
+ Runnable exportHandler, Runnable exportAppHandler) {
+ this.runHandler = runHandler;
+ this.presentHandler = presentHandler;
+ this.stopHandler = stopHandler;
+ this.exportHandler = exportHandler;
+ this.exportAppHandler = exportAppHandler;
+ }
+
+
+ public void resetHandlers() {
+ runHandler = new DefaultRunHandler();
+ presentHandler = new DefaultPresentHandler();
+ stopHandler = new DefaultStopHandler();
+ exportHandler = new DefaultExportHandler();
+ exportAppHandler = new DefaultExportAppHandler();
+ }
+
+
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+
+
/**
* Gets the current sketch object.
*/
@@ -1799,26 +1808,50 @@ public void handleRun(final boolean verbose) {
console.clear();
}
- //presenting = present;
+ // Cannot use invokeLater() here, otherwise it gets
+ // placed on the event thread and causes a hang--bad idea all around.
+ new Thread(verbose ? presentHandler : runHandler).start();
+ }
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- try {
- sketch.compile(verbose);
- statusNotice("Done compiling.");
- } catch (RunnerException e) {
- //statusError("Error compiling...");
- statusError(e);
+ // DAM: in Arduino, this is compile
+ class DefaultRunHandler implements Runnable {
+ public void run() {
+ try {
+ sketch.prepare();
+ String appletClassName = sketch.build(false);
+ statusNotice("Done compiling.");
+ } catch (Exception e) {
+ statusError(e);
+ }
- } catch (Exception e) {
- e.printStackTrace();
- }
+ toolbar.deactivate(EditorToolbar.RUN);
+ }
+ }
+
+ // DAM: in Arduino, this is compile (with verbose output)
+ class DefaultPresentHandler implements Runnable {
+ public void run() {
+ try {
+ sketch.prepare();
+ String appletClassName = sketch.build(true);
+ statusNotice("Done compiling.");
+ } catch (Exception e) {
+ statusError(e);
+ }
- toolbar.deactivate(EditorToolbar.RUN);
+ toolbar.deactivate(EditorToolbar.RUN);
}
- });
}
+ class DefaultStopHandler implements Runnable {
+ public void run() {
+ try {
+ // DAM: we should try to kill the compilation or upload process here.
+ } catch (Exception e) {
+ statusError(e);
+ }
+ }
+ }
/**
* Set the location of the sketch run window. Used by Runner to update the
@@ -1855,8 +1888,10 @@ public void handleStop() { // called by menu or buttons
/**
- * Called by Runner to notify that the sketch has stopped running.
- * Tools should not call this function, use handleStop() instead.
+ * Deactivate the Run button. This is called by Runner to notify that the
+ * sketch has stopped running, usually in response to an error (or maybe
+ * the sketch completing and exiting?) Tools should not call this function.
+ * To initiate a "stop" action, call handleStop() instead.
*/
public void internalRunnerClosed() {
running = false;
@@ -1870,11 +1905,9 @@ public void internalRunnerClosed() {
public void internalCloseRunner() {
running = false;
+ if (stopHandler != null)
try {
- if (runtime != null) {
- runtime.close(); // kills the window
- runtime = null; // will this help?
- }
+ stopHandler.run();
} catch (Exception e) { }
sketch.cleanup();
@@ -1883,13 +1916,14 @@ public void internalCloseRunner() {
/**
* Check if the sketch is modified and ask user to save changes.
- * Immediately should be set true when quitting, or when the save should
- * not happen asynchronously. Come to think of it, that's always now?
* @return false if canceling the close/quit operation
*/
- protected boolean checkModified(boolean immediately) {
+ protected boolean checkModified() {
if (!sketch.isModified()) return true;
+ // As of Processing 1.0.10, this always happens immediately.
+ // http://dev.processing.org/bugs/show_bug.cgi?id=1456
+
String prompt = "Save changes to " + sketch.getName() + "? ";
if (!Base.isMacOS()) {
@@ -1899,13 +1933,14 @@ protected boolean checkModified(boolean immediately) {
JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
- return handleSave(immediately);
+ return handleSave(true);
} else if (result == JOptionPane.NO_OPTION) {
return true; // ok to continue
} else if (result == JOptionPane.CANCEL_OPTION) {
return false;
+
} else {
throw new IllegalStateException();
}
@@ -1950,7 +1985,7 @@ protected boolean checkModified(boolean immediately) {
Object result = pane.getValue();
if (result == options[0]) { // save (and close/quit)
- return handleSave(immediately);
+ return handleSave(true);
} else if (result == options[2]) { // don't save (still close/quit)
return true;
@@ -2203,39 +2238,69 @@ public boolean handleSaveAs() {
synchronized public void handleExport(final boolean verbose) {
//if (!handleExportCheckModified()) return;
toolbar.activate(EditorToolbar.EXPORT);
-
console.clear();
statusNotice("Uploading to I/O Board...");
- //SwingUtilities.invokeLater(new Runnable() {
- Thread t = new Thread(new Runnable() {
- public void run() {
- try {
- serialMonitor.closeSerialPort();
- serialMonitor.setVisible(false);
+ new Thread(verbose ? exportAppHandler : exportHandler).start();
+ }
+
+ // DAM: in Arduino, this is upload
+ class DefaultExportHandler implements Runnable {
+ public void run() {
+
+ try {
+ serialMonitor.closeSerialPort();
+ serialMonitor.setVisible(false);
- uploading = true;
+ uploading = true;
- boolean success = sketch.exportApplet(verbose);
- if (success) {
- statusNotice("Done uploading.");
- } else {
- // error message will already be visible
- }
- } catch (RunnerException e) {
- //statusError("Error during upload.");
- //e.printStackTrace();
- statusError(e);
- } catch (Exception e) {
- e.printStackTrace();
- }
- uploading = false;
- //toolbar.clear();
- toolbar.deactivate(EditorToolbar.EXPORT);
- }});
- t.start();
+ boolean success = sketch.exportApplet(false);
+ if (success) {
+ statusNotice("Done uploading.");
+ } else {
+ // error message will already be visible
+ }
+ } catch (RunnerException e) {
+ //statusError("Error during upload.");
+ //e.printStackTrace();
+ statusError(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ uploading = false;
+ //toolbar.clear();
+ toolbar.deactivate(EditorToolbar.EXPORT);
+ }
}
+ // DAM: in Arduino, this is upload (with verbose output)
+ class DefaultExportAppHandler implements Runnable {
+ public void run() {
+
+ try {
+ serialMonitor.closeSerialPort();
+ serialMonitor.setVisible(false);
+
+ uploading = true;
+
+ boolean success = sketch.exportApplet(true);
+ if (success) {
+ statusNotice("Done uploading.");
+ } else {
+ // error message will already be visible
+ }
+ } catch (RunnerException e) {
+ //statusError("Error during upload.");
+ //e.printStackTrace();
+ statusError(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ uploading = false;
+ //toolbar.clear();
+ toolbar.deactivate(EditorToolbar.EXPORT);
+ }
+ }
/**
* Checks to see if the sketch has been modified, and if so,
@@ -2418,7 +2483,7 @@ public void statusError(Exception e) {
}
statusError(mess);
}
- e.printStackTrace();
+// e.printStackTrace();
}
@@ -2563,4 +2628,3 @@ public void show(Component component, int x, int y) {
}
}
}
-
View
20 app/src/processing/app/EditorConsole.java
@@ -28,6 +28,7 @@
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
+
import java.util.*;
@@ -47,8 +48,6 @@
MutableAttributeSet stdStyle;
MutableAttributeSet errStyle;
- boolean cerror;
-
int maxLineCount;
static File errFile;
@@ -221,18 +220,9 @@ public void handleQuit() {
public void write(byte b[], int offset, int length, boolean err) {
- if (err != cerror) {
- // advance the line because switching between err/out streams
- // potentially, could check whether we're already on a new line
- message("", cerror, true);
- }
-
// we could do some cross platform CR/LF mangling here before outputting
-
// add text to output document
message(new String(b, offset, length), err, false);
- // set last error state
- cerror = err;
}
@@ -291,10 +281,10 @@ public void clear() {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- class EditorConsoleStream extends OutputStream {
+ private static class EditorConsoleStream extends OutputStream {
//static EditorConsole current;
- boolean err; // whether stderr or stdout
- byte single[] = new byte[1];
+ final boolean err; // whether stderr or stdout
+ final byte single[] = new byte[1];
public EditorConsoleStream(boolean err) {
this.err = err;
@@ -389,7 +379,7 @@ public void write(int b) {
* swing event thread, so they need to be synchronized
*/
class BufferedStyledDocument extends DefaultStyledDocument {
- ArrayList elements = new ArrayList();
+ ArrayList<ElementSpec> elements = new ArrayList<ElementSpec>();
int maxLineLength, maxLineCount;
int currentLineLength = 0;
boolean needLineBreak = false;
View
11 app/src/processing/app/EditorListener.java
@@ -103,6 +103,10 @@ public boolean keyPressed(KeyEvent event) {
char c = event.getKeyChar();
int code = event.getKeyCode();
+// if (code == KeyEvent.VK_SHIFT) {
+// editor.toolbar.setShiftPressed(true);
+// }
+
//System.out.println((int)c + " " + code + " " + event);
//System.out.println();
@@ -457,6 +461,13 @@ public boolean keyPressed(KeyEvent event) {
}
+// public boolean keyReleased(KeyEvent event) {
+// if (code == KeyEvent.VK_SHIFT) {
+// editor.toolbar.setShiftPressed(false);
+// }
+// }
+
+
public boolean keyTyped(KeyEvent event) {
char c = event.getKeyChar();
View
220 app/src/processing/app/EditorToolbar.java
@@ -3,7 +3,7 @@
/*
Part of the Processing project - http://processing.org
- Copyright (c) 2004-08 Ben Fry and Casey Reas
+ Copyright (c) 2004-09 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
@@ -25,6 +25,7 @@
import java.awt.*;
import java.awt.event.*;
+
import javax.swing.*;
import javax.swing.event.*;
@@ -32,12 +33,18 @@
/**
* run/stop/etc buttons for the ide
*/
-public class EditorToolbar extends JComponent implements MouseInputListener {
+public class EditorToolbar extends JComponent implements MouseInputListener, KeyListener {
+ /** Rollover titles for each button. */
static final String title[] = {
"Verify", "Stop", "New", "Open", "Save", "Upload", "Serial Monitor"
};
+ /** Titles for each button when the shift key is pressed. */
+ static final String titleShift[] = {
+ "Verify (w/ Verbose Output)", "Stop", "New Editor Window", "Open in Another Window", "Save", "Upload (w/ Verbose Output)", "Serial Monitor"
+ };
+
static final int BUTTON_COUNT = title.length;
/** Width of each toolbar button. */
static final int BUTTON_WIDTH = 27;
@@ -45,6 +52,9 @@
static final int BUTTON_HEIGHT = 32;
/** The amount of space between groups of buttons on the toolbar. */
static final int BUTTON_GAP = 5;
+ /** Size of the button image being chopped up. */
+ static final int BUTTON_IMAGE_SIZE = 33;
+
static final int RUN = 0;
static final int STOP = 1;
@@ -61,45 +71,35 @@
static final int ACTIVE = 2;
Editor editor;
- //boolean disableRun; // this was for library
- //Label status;
Image offscreen;
int width, height;
Color bgcolor;
- static Image buttons;
- static Image inactive[];
- static Image rollover[];
- static Image active[];
+ static Image[][] buttonImages;
int currentRollover;
- //int currentSelection;
JPopupMenu popup;
JMenu menu;
int buttonCount;
- int state[] = new int[BUTTON_COUNT];
- Image stateImage[];
+ int[] state = new int[BUTTON_COUNT];
+ Image[] stateImage;
int which[]; // mapping indices to implementation
int x1[], x2[];
int y1, y2;
- String status;
Font statusFont;
Color statusColor;
+ boolean shiftPressed;
public EditorToolbar(Editor editor, JMenu menu) {
this.editor = editor;
this.menu = menu;
- if (buttons == null) {
- buttons = Base.getThemeImage("buttons.gif", this);
- }
-
buttonCount = 0;
which = new int[BUTTON_COUNT];
@@ -115,9 +115,6 @@ public EditorToolbar(Editor editor, JMenu menu) {
currentRollover = -1;
bgcolor = Theme.getColor("buttons.bgcolor");
-
- status = "";
-
statusFont = Theme.getFont("buttons.status.font");
statusColor = Theme.getColor("buttons.status.color");
@@ -125,30 +122,28 @@ public EditorToolbar(Editor editor, JMenu menu) {
addMouseMotionListener(this);
}
-
- public void paintComponent(Graphics screen) {
- // this data is shared by all EditorToolbar instances
- if (inactive == null) {
- inactive = new Image[BUTTON_COUNT];
- rollover = new Image[BUTTON_COUNT];
- active = new Image[BUTTON_COUNT];
-
- int IMAGE_SIZE = 33;
+ protected void loadButtons() {
+ Image allButtons = Base.getThemeImage("buttons.gif", this);
+ buttonImages = new Image[BUTTON_COUNT][3];
for (int i = 0; i < BUTTON_COUNT; i++) {
- inactive[i] = createImage(BUTTON_WIDTH, BUTTON_HEIGHT);
- Graphics g = inactive[i].getGraphics();
- g.drawImage(buttons, -(i*IMAGE_SIZE) - 3, -2*IMAGE_SIZE, null);
-
- rollover[i] = createImage(BUTTON_WIDTH, BUTTON_HEIGHT);
- g = rollover[i].getGraphics();
- g.drawImage(buttons, -(i*IMAGE_SIZE) - 3, -1*IMAGE_SIZE, null);
-
- active[i] = createImage(BUTTON_WIDTH, BUTTON_HEIGHT);
- g = active[i].getGraphics();
- g.drawImage(buttons, -(i*IMAGE_SIZE) - 3, -0*IMAGE_SIZE, null);
+ for (int state = 0; state < 3; state++) {
+ Image image = createImage(BUTTON_WIDTH, BUTTON_HEIGHT);
+ Graphics g = image.getGraphics();
+ g.drawImage(allButtons,
+ -(i*BUTTON_IMAGE_SIZE) - 3,
+ (-2 + state)*BUTTON_IMAGE_SIZE, null);
+ buttonImages[i][state] = image;
}
}
+ }
+
+ @Override
+ public void paintComponent(Graphics screen) {
+ // this data is shared by all EditorToolbar instances
+ if (buttonImages == null) {
+ loadButtons();
+ }
// this happens once per instance of EditorToolbar
if (stateImage == null) {
@@ -191,21 +186,34 @@ public void paintComponent(Graphics screen) {
/*
// if i ever find the guy who wrote the java2d api, i will hurt him.
+ *
+ * whereas I love the Java2D API. --jdf. lol.
+ *
Graphics2D g2 = (Graphics2D) g;
FontRenderContext frc = g2.getFontRenderContext();
float statusW = (float) statusFont.getStringBounds(status, frc).getWidth();
float statusX = (getSize().width - statusW) / 2;
g2.drawString(status, statusX, statusY);
*/
- //int statusY = (BUTTON_HEIGHT + statusFont.getAscent()) / 2;
+ if (currentRollover != -1) {
int statusY = (BUTTON_HEIGHT + g.getFontMetrics().getAscent()) / 2;
+ String status = shiftPressed ? titleShift[currentRollover] : title[currentRollover];
g.drawString(status, buttonCount * BUTTON_WIDTH + 3 * BUTTON_GAP, statusY);
+ }
screen.drawImage(offscreen, 0, 0, null);
+
+ if (!isEnabled()) {
+ screen.setColor(new Color(0,0,0,100));
+ screen.fillRect(0, 0, getWidth(), getHeight());
+ }
}
public void mouseMoved(MouseEvent e) {
+ if (!isEnabled())
+ return;
+
// mouse events before paint();
if (state == null) return;
@@ -213,16 +221,17 @@ public void mouseMoved(MouseEvent e) {
// avoid flicker, since there will probably be an update event
setState(OPEN, INACTIVE, false);
}
- //System.out.println(e);
- //mouseMove(e);
- handleMouse(e.getX(), e.getY());
+ handleMouse(e);
}
public void mouseDragged(MouseEvent e) { }
- public void handleMouse(int x, int y) {
+ public void handleMouse(MouseEvent e) {
+ int x = e.getX();
+ int y = e.getY();
+
if (currentRollover != -1) {
if ((x > x1[currentRollover]) && (y > y1) &&
(x < x2[currentRollover]) && (y < y2)) {
@@ -230,7 +239,6 @@ public void handleMouse(int x, int y) {
} else {
setState(currentRollover, INACTIVE, true);
- messageClear(title[currentRollover]);
currentRollover = -1;
}
}
@@ -238,10 +246,8 @@ public void handleMouse(int x, int y) {
if (sel == -1) return;
if (state[sel] != ACTIVE) {
- //if (!(disableRun && ((sel == RUN) || (sel == STOP)))) {
setState(sel, ROLLOVER, true);
currentRollover = sel;
- //}
}
}
@@ -263,32 +269,16 @@ private int findSelection(int x, int y) {
private void setState(int slot, int newState, boolean updateAfter) {
- //if (inactive == null) return;
state[slot] = newState;
- switch (newState) {
- case INACTIVE:
- stateImage[slot] = inactive[which[slot]];
- break;
- case ACTIVE:
- stateImage[slot] = active[which[slot]];
- break;
- case ROLLOVER:
- stateImage[slot] = rollover[which[slot]];
- message(title[which[slot]]);
- break;
- }
+ stateImage[slot] = buttonImages[which[slot]][newState];
if (updateAfter) {
- //System.out.println("trying to update " + slot + " " + state[slot]);
- //new Exception("setting slot " + slot + " to " + state[slot]).printStackTrace();
- repaint(); // changed for swing from update();
- //Toolkit.getDefaultToolkit().sync();
+ repaint();
}
}
public void mouseEntered(MouseEvent e) {
- //mouseMove(e);
- handleMouse(e.getX(), e.getY());
+ handleMouse(e);
}
@@ -300,14 +290,18 @@ public void mouseExited(MouseEvent e) {
if (state[OPEN] != INACTIVE) {
setState(OPEN, INACTIVE, true);
}
- status = "";
- handleMouse(e.getX(), e.getY());
+ handleMouse(e);
}
int wasDown = -1;
public void mousePressed(MouseEvent e) {
+
+ // jdf
+ if (!isEnabled())
+ return;
+
final int x = e.getX();
final int y = e.getY();
@@ -331,8 +325,11 @@ public void mousePressed(MouseEvent e) {
break;
case NEW:
- //editor.base.handleNew(e.isShiftDown());
+ if (shiftPressed) {
+ editor.base.handleNew();
+ } else {
editor.base.handleNewReplace();
+ }
break;
case SAVE:
@@ -353,84 +350,26 @@ public void mousePressed(MouseEvent e) {
public void mouseClicked(MouseEvent e) { }
- public void mouseReleased(MouseEvent e) {
- /*
- switch (currentSelection) {
-
- case OPEN:
- setState(OPEN, INACTIVE, true);
- break;
- }
- currentSelection = -1;
- */
- }
-
-
- //public void disableRun(boolean what) {
- //disableRun = what;
- //}
-
-
- /*
- public void run() {
- if (inactive == null) return;
- clear();
- setState(RUN, ACTIVE, true);
- }
- */
-
-// public void running(boolean yesno) {
-// setState(RUN, yesno ? ACTIVE : INACTIVE, true);
-// }
+ public void mouseReleased(MouseEvent e) { }
/**
* Set a particular button to be active.
*/
public void activate(int what) {
- //System.out.println("activating " + what);
- if (inactive == null) return;
+ if (buttonImages != null) {
setState(what, ACTIVE, true);
}
-
- //public void clearRun() {
- //if (inactive == null) return;
- //setState(RUN, INACTIVE, true);
- //}
+ }
/**
* Set a particular button to be active.
*/
public void deactivate(int what) {
- if (inactive == null) return; // don't draw if not ready
+ if (buttonImages != null) {
setState(what, INACTIVE, true);
}
-
- /**
- * Clear all the state of all buttons.
- */
-// public void clear() { // (int button) {
-// if (inactive == null) return;
-//
-// System.out.println("clearing state of buttons");
-// // skip the run button, do the others
-// for (int i = 1; i < buttonCount; i++) {
-// setState(i, INACTIVE, false);
-// }
-// repaint(); // changed for swing from update();
-// }
-
-
- public void message(String msg) {
- //status.setText(msg + " "); // don't mind the hack
- status = msg;
- }
-
-
- public void messageClear(String msg) {
- //if (status.getText().equals(msg + " ")) status.setText(Editor.EMPTY);
- if (status.equals(msg)) status = "";
}
@@ -447,4 +386,23 @@ public Dimension getMinimumSize() {
public Dimension getMaximumSize() {
return new Dimension(3000, BUTTON_HEIGHT);
}
+
+
+ public void keyPressed(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
+ shiftPressed = true;
+ repaint();
+}
+ }
+
+
+ public void keyReleased(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
+ shiftPressed = false;
+ repaint();
+ }
+ }
+
+
+ public void keyTyped(KeyEvent e) { }
}
View
33 app/src/processing/app/Platform.java
@@ -26,6 +26,9 @@
import javax.swing.UIManager;
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+
/**
* Used by Base for platform-specific tweaking, for instance finding the
@@ -129,6 +132,36 @@ public void openFolder(File file) throws Exception {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ public interface CLibrary extends Library {
+ CLibrary INSTANCE = (CLibrary)Native.loadLibrary("c", CLibrary.class);
+ int setenv(String name, String value, int overwrite);
+ String getenv(String name);
+ int unsetenv(String name);
+ int putenv(String string);
+ }
+
+
+ public void setenv(String variable, String value) {
+ CLibrary clib = CLibrary.INSTANCE;
+ clib.setenv(variable, value, 1);
+ }
+
+
+ public String getenv(String variable) {
+ CLibrary clib = CLibrary.INSTANCE;
+ return clib.getenv(variable);
+ }
+
+
+ public int unsetenv(String variable) {
+ CLibrary clib = CLibrary.INSTANCE;
+ return clib.unsetenv(variable);
+ }
+
+
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+
+
protected void showLauncherWarning() {
Base.showWarning("No launcher available",
"Unspecified platform, no launcher available.\n" +
View
5 app/src/processing/app/Preferences.java
@@ -626,6 +626,11 @@ static public void set(String attribute, String value) {
}
+ static public void unset(String attribute) {
+ table.remove(attribute);
+ }
+
+
static public boolean getBoolean(String attribute) {
String value = get(attribute); //, null);
return (new Boolean(value)).booleanValue();
View
229 app/src/processing/app/Sketch.java
@@ -3,7 +3,7 @@
/*
Part of the Processing project - http://processing.org
- Copyright (c) 2004-09 Ben Fry and Casey Reas
+ Copyright (c) 2004-10 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
@@ -95,6 +95,9 @@
* DLLs or JNILIBs.
*/
private String libraryPath;
+ /**
+ * List of library folders.
+ */
private ArrayList<File> importedLibraries;
/**
@@ -1165,11 +1168,14 @@ protected void cleanup() {
* X. afterwards, some of these steps need a cleanup function
* </PRE>
*/
- protected String compile(boolean verbose)
- throws RunnerException {
-
- String name;
-
+ //protected String compile() throws RunnerException {
+
+
+ /**
+ * When running from the editor, take care of preparations before running
+ * the build.
+ */
+ public void prepare() {
// make sure the user didn't hide the sketch folder
ensureExistence();
@@ -1199,11 +1205,8 @@ protected String compile(boolean verbose)
// better connected to the dataFolder stuff below.
cleanup();
- // handle preprocessing the main file's code
- name = build(tempBuildFolder.getAbsolutePath(), verbose);
- size(tempBuildFolder.getAbsolutePath(), name);
-
- return name;
+// // handle preprocessing the main file's code
+// return build(tempBuildFolder.getAbsolutePath());
}
@@ -1255,14 +1258,6 @@ public String preprocess(String buildPath, PdePreprocessor preprocessor) throws
// 1. concatenate all .pde files to the 'main' pde
// store line number for starting point of each code bit
- // Unfortunately, the header has to be written on a single line, because
- // there's no way to determine how long it will be until the code has
- // already been preprocessed. The header will vary in length based on
- // the programming mode (STATIC, ACTIVE, or JAVA), which is determined
- // by the preprocessor. So the preprocOffset for the primary class remains
- // zero, even though it'd be nice to have a legitimate offset, and be able
- // to remove the 'pretty' boolean for preproc.write().
-
StringBuffer bigCode = new StringBuffer();
int bigCount = 0;
for (SketchCode sc : code) {
@@ -1271,28 +1266,8 @@ public String preprocess(String buildPath, PdePreprocessor preprocessor) throws
bigCode.append(sc.getProgram());
bigCode.append('\n');
bigCount += sc.getLineCount();
-// if (sc != code[0]) {
-// sc.setPreprocName(null); // don't compile me
-// }
- }
- }
-
- /*
- String program = code[0].getProgram();
- StringBuffer bigCode = new StringBuffer(program);
- int bigCount = code[0].getLineCount();
- bigCode.append('\n');
-
- for (int i = 1; i < codeCount; i++) {
- if (code[i].isExtension("pde")) {
- code[i].setPreprocOffset(bigCount);
- bigCode.append(code[i].getProgram());
- bigCode.append('\n');
- bigCount += code[i].getLineCount();
- code[i].setPreprocName(null); // don't compile me
}
}
- */
// Note that the headerOffset isn't applied until compile and run, because
// it only applies to the code after it's been written to the .java file.
@@ -1391,6 +1366,134 @@ public String preprocess(String buildPath, PdePreprocessor preprocessor) throws
}
+ public ArrayList<File> getImportedLibraries() {
+ return importedLibraries;
+ }
+
+
+ /**
+ * Map an error from a set of processed .java files back to its location
+ * in the actual sketch.
+ * @param message The error message.
+ * @param filename The .java file where the exception was found.
+ * @param line Line number of the .java file for the exception (1-indexed)
+ * @return A RunnerException to be sent to the editor, or null if it wasn't
+ * possible to place the exception to the sketch code.
+ */
+// public RunnerException placeExceptionAlt(String message,
+// String filename, int line) {
+// String appletJavaFile = appletClassName + ".java";
+// SketchCode errorCode = null;
+// if (filename.equals(appletJavaFile)) {
+// for (SketchCode code : getCode()) {
+// if (code.isExtension("pde")) {
+// if (line >= code.getPreprocOffset()) {
+// errorCode = code;
+// }
+// }
+// }
+// } else {
+// for (SketchCode code : getCode()) {
+// if (code.isExtension("java")) {
+// if (filename.equals(code.getFileName())) {
+// errorCode = code;
+// }
+// }
+// }
+// }
+// int codeIndex = getCodeIndex(errorCode);
+//
+// if (codeIndex != -1) {
+// //System.out.println("got line num " + lineNumber);
+// // in case this was a tab that got embedded into the main .java
+// line -= getCode(codeIndex).getPreprocOffset();
+//
+// // lineNumber is 1-indexed, but editor wants zero-indexed
+// line--;
+//
+// // getMessage() will be what's shown in the editor
+// RunnerException exception =
+// new RunnerException(message, codeIndex, line, -1);
+// exception.hideStackTrace();
+// return exception;
+// }
+// return null;
+// }
+
+
+ /**
+ * Map an error from a set of processed .java files back to its location
+ * in the actual sketch.
+ * @param message The error message.
+ * @param filename The .java file where the exception was found.
+ * @param line Line number of the .java file for the exception (0-indexed!)
+ * @return A RunnerException to be sent to the editor, or null if it wasn't
+ * possible to place the exception to the sketch code.
+ */
+ public RunnerException placeException(String message,
+ String dotJavaFilename,
+ int dotJavaLine) {
+ int codeIndex = 0; //-1;
+ int codeLine = -1;
+
+// System.out.println("placing " + dotJavaFilename + " " + dotJavaLine);
+// System.out.println("code count is " + getCodeCount());
+
+ // first check to see if it's a .java file
+ for (int i = 0; i < getCodeCount(); i++) {
+ SketchCode code = getCode(i);
+ if (code.isExtension("java")) {
+ if (dotJavaFilename.equals(code.getFileName())) {
+ codeIndex = i;
+ codeLine = dotJavaLine;
+ return new RunnerException(message, codeIndex, codeLine);
+ }
+ }
+ }
+
+ // If not the preprocessed file at this point, then need to get out
+ if (!dotJavaFilename.equals(name + ".java")) {
+ return null;
+ }
+
+ // if it's not a .java file, codeIndex will still be 0
+ // this section searches through the list of .pde files
+ codeIndex = 0;
+ for (int i = 0; i < getCodeCount(); i++) {
+ SketchCode code = getCode(i);
+
+ if (code.isExtension("pde")) {
+// System.out.println("preproc offset is " + code.getPreprocOffset());
+// System.out.println("looking for line " + dotJavaLine);
+ if (code.getPreprocOffset() <= dotJavaLine) {
+ codeIndex = i;
+// System.out.println("i'm thinkin file " + i);
+ codeLine = dotJavaLine - code.getPreprocOffset();
+ }
+ }
+ }
+ // could not find a proper line number, so deal with this differently.
+ // but if it was in fact the .java file we're looking for, though,
+ // send the error message through.
+ // this is necessary because 'import' statements will be at a line
+ // that has a lower number than the preproc offset, for instance.
+// if (codeLine == -1 && !dotJavaFilename.equals(name + ".java")) {
+// return null;
+// }
+ return new RunnerException(message, codeIndex, codeLine);
+ }
+
+
+ /**
+ * Run the build inside the temporary build folder.
+ * @return null if compilation failed, main class name if not
+ * @throws RunnerException
+ */
+ public String build(boolean verbose) throws RunnerException {
+ return build(tempBuildFolder.getAbsolutePath(), verbose);
+ }
+
+
/**
* Preprocess and compile all the code for this sketch.
*
@@ -1410,6 +1513,7 @@ public String build(String buildPath, boolean verbose)
// that will bubble up to whomever called build().
Compiler compiler = new Compiler();
if (compiler.compile(this, buildPath, primaryClassName, verbose)) {
+ size(buildPath, primaryClassName);
return primaryClassName;
}
return null;
@@ -1500,7 +1604,7 @@ protected String upload(String buildPath, String suggestedClassName, boolean ver
verbose);
return success ? suggestedClassName : null;
- }
+ }
/**
* Replace all commented portions of a given String as spaces.
@@ -1538,7 +1642,8 @@ static public String scrubComments(String what) {
break;
} else {
- index++;
+ // continue blanking this area
+ p[index++] = ' ';
}
}
if (!endOfRainbow) {
@@ -1562,8 +1667,8 @@ public boolean exportApplicationPrompt() throws IOException, RunnerException {
* Export to application via GUI.
*/
protected boolean exportApplication() throws IOException, RunnerException {
- return false;
- }
+ return false;
+ }
/**
@@ -1571,8 +1676,8 @@ protected boolean exportApplication() throws IOException, RunnerException {
*/
public boolean exportApplication(String destPath,
int exportPlatform) throws IOException, RunnerException {
- return false;
- }
+ return false;
+ }
protected void addManifest(ZipOutputStream zos) throws IOException {
@@ -1589,35 +1694,6 @@ protected void addManifest(ZipOutputStream zos) throws IOException {
/**
- * Read from a file with a bunch of attribute/value pairs
- * that are separated by = and ignore comments with #.
- */
- protected HashMap<String,String> readSettings(File inputFile) {
- HashMap<String,String> outgoing = new HashMap<String,String>();
- if (!inputFile.exists()) return outgoing; // return empty hash
-
- String lines[] = PApplet.loadStrings(inputFile);
- for (int i = 0; i < lines.length; i++) {
- int hash = lines[i].indexOf('#');
- String line = (hash == -1) ?
- lines[i].trim() : lines[i].substring(0, hash).trim();
- if (line.length() == 0) continue;
-
- int equals = line.indexOf('=');
- if (equals == -1) {
- System.err.println("ignoring illegal line in " + inputFile);
- System.err.println(" " + line);
- continue;
- }
- String attr = line.substring(0, equals).trim();
- String valu = line.substring(equals + 1).trim();
- outgoing.put(attr, valu);
- }
- return outgoing;
- }
-
-
- /**
* Slurps up .class files from a colon (or semicolon on windows)
* separated list of paths and adds them to a ZipOutputStream.
*/
@@ -1923,11 +1999,6 @@ public File prepareCodeFolder() {
}
- public ArrayList<File> getImportedLibraries() {
- return importedLibraries;
- }
-
-
public String getClassPath() {
return classPath;
}
View
95 app/src/processing/app/StreamRedirectThread.java
@@ -0,0 +1,95 @@
+/*
+
+ * @(#)StreamRedirectThread.java 1.4 03/01/23
+ *
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 1997-2001 by Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
+ * modify and redistribute this software in source and binary code form,
+ * provided that i) this copyright notice and license appear on all copies of
+ * the software; and ii) Licensee does not utilize the software in a manner
+ * which is disparaging to Sun.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
+ * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
+ * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
+ * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
+ * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * This software is not designed or intended for use in on-line control of
+ * aircraft, air traffic, aircraft navigation or aircraft communications; or in
+ * the design, construction, operation or maintenance of any nuclear
+ * facility. Licensee represents and warrants that it will not use or
+ * redistribute the Software for such purposes.
+ */
+package processing.app;
+
+import java.io.*;
+
+/**
+ * StreamRedirectThread is a thread which copies it's input to
+ * it's output and terminates when it completes.
+ *
+ * @version @(#) StreamRedirectThread.java 1.4 03/01/23 23:33:38
+ * @author Robert Field
+ */
+public class StreamRedirectThread extends Thread {
+
+ private final Reader in;
+ private final Writer out;
+
+ private static final int BUFFER_SIZE = 2048;
+
+
+ /**
+ * Set up for copy.
+ * @param name Name of the thread
+ * @param in Stream to copy from
+ * @param out Stream to copy to
+ */
+ public StreamRedirectThread(String name, InputStream in, OutputStream out) {
+ super(name);
+ this.in = new InputStreamReader(in);
+ this.out = new OutputStreamWriter(out);
+ setPriority(Thread.MAX_PRIORITY-1);
+ }
+
+
+ public StreamRedirectThread(String name, Reader in, Writer out) {
+ super(name);
+ this.in = in;
+ this.out = out;
+ setPriority(Thread.MAX_PRIORITY-1);
+ }
+
+
+ /**
+ * Copy.
+ */
+ public void run() {
+ try {
+ char[] cbuf = new char[BUFFER_SIZE];
+ int count;
+ //System.out.println("opening streamredirectthread");
+ while ((count = in.read(cbuf, 0, BUFFER_SIZE)) >= 0) {
+ out.write(cbuf, 0, count);
+ // had to add the flush() here.. maybe shouldn't be using writer? [fry]
+ out.flush();
+ }
+ //System.out.println("exiting streamredirectthread");
+ out.flush();
+ } catch(IOException exc) {
+ System.err.println("Child I/O Transfer - " + exc);
+ }
+ }
+}
View
8 app/src/processing/app/WebServer.java
@@ -8,8 +8,12 @@
//import javax.swing.SwingUtilities;
/**
- * An example of a very simple, multi-threaded HTTP server.
- * Taken from <a href="http://java.sun.com/developer/technicalArticles/Networking/Webserver/">this</a> article on java.sun.com.
+ * This code is placed here in anticipation of running the reference from an
+ * internal web server that reads the docs from a zip file, instead of using
+ * thousands of .html files on the disk, which is really inefficient.
+ * <p/>
+ * This is a very simple, multi-threaded HTTP server, originally based on
+ * <a href="http://j.mp/6BQwpI">this</a> article on java.sun.com.
*/
public class WebServer implements HttpConstants {
View
5 app/src/processing/app/debug/EventThread.java → ...rc/processing/app/debug/EventThread.java.disabled