diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index e34211a5a..b0b8454c5 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -2050,6 +2050,16 @@ public abstract class Editor extends JFrame implements RunnerListener { public void statusEmpty() { statusNotice(EMPTY); } + + + public void startIndeterminate() { + status.startIndeterminate(); + } + + + public void stopIndeterminate() { + status.stopIndeterminate(); + } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . diff --git a/app/src/processing/app/EditorStatus.java b/app/src/processing/app/EditorStatus.java index 054ba735a..09776b415 100644 --- a/app/src/processing/app/EditorStatus.java +++ b/app/src/processing/app/EditorStatus.java @@ -66,6 +66,10 @@ public class EditorStatus extends JPanel { JTextField editField; int response; + + boolean indeterminate; + Thread thread; + public EditorStatus(Editor editor) { @@ -107,6 +111,7 @@ public class EditorStatus extends JPanel { repaint(); } + public void unnotice(String unmessage) { if (message.equals(unmessage)) empty(); } @@ -134,12 +139,36 @@ public class EditorStatus extends JPanel { repaint(); } + public void unedit() { okButton.setVisible(false); cancelButton.setVisible(false); editField.setVisible(false); empty(); } + + + public void startIndeterminate() { + indeterminate = true; + thread = new Thread() { + public void run() { + while (Thread.currentThread() == thread) { + System.out.println("knight rider"); + repaint(); + try { + Thread.sleep(1000 / 10); + } catch (InterruptedException e) { } + } + } + }; + thread.start(); + } + + + public void stopIndeterminate() { + indeterminate = false; + thread = null; + } public void paintComponent(Graphics screen) { @@ -186,6 +215,17 @@ public class EditorStatus extends JPanel { g.setFont(font); // needs to be set each time on osx g.drawString(message, Preferences.GUI_SMALL, (sizeH + ascent) / 2); + if (indeterminate) { + int x = cancelButton.getX(); + int y = cancelButton.getY(); + int w = cancelButton.getWidth(); + int h = cancelButton.getHeight(); + g.setColor(fgcolor[mode]); + g.drawRect(x, y, w, h); + int r = (int) (x + Math.random() * w); + g.drawLine(r, y, r, y+h); + } + screen.drawImage(offscreen, 0, 0, null); } diff --git a/app/src/processing/app/RunnerListener.java b/app/src/processing/app/RunnerListener.java index e9d3392ea..cd3777cfa 100644 --- a/app/src/processing/app/RunnerListener.java +++ b/app/src/processing/app/RunnerListener.java @@ -30,4 +30,10 @@ public interface RunnerListener { public void statusError(Exception exception); public void statusNotice(String message); + + // + + public void startIndeterminate(); + + public void stopIndeterminate(); } \ No newline at end of file diff --git a/app/src/processing/mode/android/AndroidBuild.java b/app/src/processing/mode/android/AndroidBuild.java index af8654706..5532d6309 100644 --- a/app/src/processing/mode/android/AndroidBuild.java +++ b/app/src/processing/mode/android/AndroidBuild.java @@ -57,7 +57,11 @@ class AndroidBuild extends JavaBuild { tmpFolder = createTempBuildFolder(sketch); // Create the 'src' folder with the preprocessed code. - final File srcFolder = new File(tmpFolder, "src"); +// final File srcFolder = new File(tmpFolder, "src"); + srcFolder = new File(tmpFolder, "src"); + // this folder isn't actually used, but it's used by the java preproc to + // figure out the classpath, so we have to set it to something + binFolder = new File(tmpFolder, "bin"); if (processing.app.Base.DEBUG) { Base.openFolder(tmpFolder); } @@ -65,7 +69,7 @@ class AndroidBuild extends JavaBuild { manifest = new Manifest(sketch); // grab code from current editing window (GUI only) // prepareExport(null); - + // build the preproc and get to work AndroidPreprocessor preproc = new AndroidPreprocessor(sketch, getPackageName()); if (!preproc.parseSketchSize()) { @@ -333,7 +337,8 @@ class AndroidBuild extends JavaBuild { private void writeDefaultProps(final File file) { final PrintWriter writer = PApplet.createWriter(file); - writer.println("target=Google Inc.:Google APIs:" + sdkVersion); + //writer.println("target=Google Inc.:Google APIs:" + sdkVersion); + writer.println("target=android-" + sdkVersion); writer.flush(); writer.close(); } diff --git a/app/src/processing/mode/android/AndroidEditor.java b/app/src/processing/mode/android/AndroidEditor.java index bbbaa0569..eb701a3c2 100644 --- a/app/src/processing/mode/android/AndroidEditor.java +++ b/app/src/processing/mode/android/AndroidEditor.java @@ -55,9 +55,9 @@ import processing.mode.java.runner.Runner; // may as well do the auto-download thing. -public class AndroidEditor extends JavaEditor implements DeviceListener { - private AndroidSDK sdk; +public class AndroidEditor extends JavaEditor implements DeviceListener { private AndroidBuild build; + private AndroidMode amode; // private static final String ANDROID_CORE_FILENAME = // "processing-android-core-" + Base.VERSION_NAME + ".zip"; @@ -65,18 +65,29 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { // private static final String ANDROID_CORE_URL = // "http://processing.googlecode.com/files/" + ANDROID_CORE_FILENAME; - AndroidMode amode; protected AndroidEditor(Base base, String path, int[] location, Mode mode) { super(base, path, location, mode); amode = (AndroidMode) mode; - statusNotice("Loading Android tools."); + try { + AndroidSDK sdk = amode.loadSDK(); + if (sdk == null) { + sdk = AndroidSDK.locate(this); + } + } catch (BadSDKException bse) { + statusError(bse); + + } catch (IOException e) { + statusError(e); + } + /* if (sdk == null) { + statusNotice("Loading Android tools."); try { - sdk = AndroidSDK.find(this); + sdk = AndroidSDK.load(); statusNotice("Done loading Android tools."); } catch (Exception e) { @@ -84,6 +95,7 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { statusError("Android Mode is disabled."); } } + */ // Make sure that the processing.android.core.* classes are available // if (!checkCore()) { @@ -168,7 +180,7 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { item = new JMenuItem("Android SDK & AVD Manager"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - File file = sdk.getAndroidTool(); + File file = amode.getSDK().getAndroidTool(); PApplet.exec(new String[] { file.getAbsolutePath() }); } }); @@ -338,6 +350,7 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { new IndeterminateProgressMonitor(this, "Building and launching...", "Creating project..."); + build = new AndroidBuild(sketch, amode.getSDK()); try { try { if (build.createProject(target, amode.getCoreZipLocation()) == null) { @@ -495,7 +508,6 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { return; } } - } } @@ -511,7 +523,7 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { */ public void handleRunEmulator() { prepareRun(); - AVD.ensureEclairAVD(sdk); + AVD.ensureEclairAVD(amode.getSDK()); try { runSketchOnDevice(Environment.getInstance().getEmulator(), "debug"); } catch (final MonitorCanceled ok) { @@ -562,7 +574,7 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { public void handleExportPackage() { // Need to implement an entire signing setup first // http://dev.processing.org/bugs/show_bug.cgi?id=1430 - statusError("Export application not yet implemented."); + statusError("Exporting signed packages is not yet implemented."); deactivateExport(); // make a release build diff --git a/app/src/processing/mode/android/AndroidMode.java b/app/src/processing/mode/android/AndroidMode.java index 5262b62e1..73362cd41 100644 --- a/app/src/processing/mode/android/AndroidMode.java +++ b/app/src/processing/mode/android/AndroidMode.java @@ -22,6 +22,7 @@ package processing.mode.android; import java.io.File; +import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; @@ -30,6 +31,7 @@ import processing.mode.java.JavaMode; public class AndroidMode extends JavaMode { + static private AndroidSDK sdk; static private File coreZipLocation; @@ -75,6 +77,19 @@ public class AndroidMode extends JavaMode { } + public AndroidSDK loadSDK() throws BadSDKException, IOException { + if (sdk == null) { + sdk = AndroidSDK.load(); + } + return sdk; + } + + + public AndroidSDK getSDK() { + return sdk; + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . diff --git a/app/src/processing/mode/android/AndroidSDK.java b/app/src/processing/mode/android/AndroidSDK.java index a1d04e8cf..ee5143a8b 100644 --- a/app/src/processing/mode/android/AndroidSDK.java +++ b/app/src/processing/mode/android/AndroidSDK.java @@ -38,8 +38,8 @@ class AndroidSDK { "http://developer.android.com/sdk/"; - public AndroidSDK(final String sdkPath) throws BadSDKException, IOException { - folder = new File(sdkPath); + public AndroidSDK(File folder) throws BadSDKException, IOException { + this.folder = folder; if (!folder.exists()) { throw new BadSDKException(folder + " does not exist"); } @@ -64,12 +64,8 @@ class AndroidSDK { path = platformTools.getCanonicalPath() + File.pathSeparator + tools.getCanonicalPath() + File.pathSeparator + path; - final String javaHomeProp = System.getProperty("java.home"); - if (javaHomeProp == null) { - throw new RuntimeException("I don't know how to deal with " + - "a null java.home proprty, to be quite frank."); - } - final File javaHome = new File(javaHomeProp).getCanonicalFile(); + String javaHomeProp = System.getProperty("java.home"); + File javaHome = new File(javaHomeProp).getCanonicalFile(); p.setenv("JAVA_HOME", javaHome.getCanonicalPath()); path = new File(javaHome, "bin").getCanonicalPath() + File.pathSeparator + path; @@ -138,22 +134,20 @@ class AndroidSDK { * @throws BadSDKException * @throws IOException */ - public static AndroidSDK find(final Frame window) - throws BadSDKException, IOException { + public static AndroidSDK load() throws BadSDKException, IOException { final Platform platform = Base.getPlatform(); // The environment variable is king. The preferences.txt entry is a page. final String sdkEnvPath = platform.getenv("ANDROID_SDK"); if (sdkEnvPath != null) { try { - final AndroidSDK androidSDK = new AndroidSDK(sdkEnvPath); + final AndroidSDK androidSDK = new AndroidSDK(new File(sdkEnvPath)); // Set this value in preferences.txt, in case ANDROID_SDK // gets knocked out later. For instance, by that pesky Eclipse, // which nukes all env variables when launching from the IDE. Preferences.set("android.sdk.path", sdkEnvPath); return androidSDK; - } catch (final BadSDKException drop) { - } + } catch (final BadSDKException drop) { } } // If android.sdk.path exists as a preference, make sure that the folder @@ -161,7 +155,7 @@ class AndroidSDK { final String sdkPrefsPath = Preferences.get("android.sdk.path"); if (sdkPrefsPath != null) { try { - final AndroidSDK androidSDK = new AndroidSDK(sdkPrefsPath); + final AndroidSDK androidSDK = new AndroidSDK(new File(sdkPrefsPath)); // Set this value in preferences.txt, in case ANDROID_SDK // gets knocked out later. For instance, by that pesky Eclipse, // which nukes all env variables when launching from the IDE. @@ -171,7 +165,12 @@ class AndroidSDK { Preferences.unset("android.sdk.path"); } } - + return null; + } + + + static public AndroidSDK locate(final Frame window) + throws BadSDKException, IOException { final int result = Base.showYesNoQuestion(window, "Android SDK", ANDROID_SDK_PRIMARY, ANDROID_SDK_SECONDARY); if (result == JOptionPane.CANCEL_OPTION) { @@ -183,17 +182,16 @@ class AndroidSDK { throw new BadSDKException("No SDK installed."); } while (true) { - final File folder = Base.selectFolder(SELECT_ANDROID_SDK_FOLDER, null, - window); + File folder = Base.selectFolder(SELECT_ANDROID_SDK_FOLDER, null, window); if (folder == null) { - throw new BadSDKException("User cancelled attempt to find SDK."); + throw new BadSDKException("User canceled attempt to find SDK."); } - final String selectedPath = folder.getAbsolutePath(); try { - final AndroidSDK androidSDK = new AndroidSDK(selectedPath); - Preferences.set("android.sdk.path", selectedPath); + final AndroidSDK androidSDK = new AndroidSDK(folder); + Preferences.set("android.sdk.path", folder.getAbsolutePath()); return androidSDK; + } catch (final BadSDKException nope) { JOptionPane.showMessageDialog(window, NOT_ANDROID_SDK); } diff --git a/app/src/processing/mode/android/AndroidToolbar.java b/app/src/processing/mode/android/AndroidToolbar.java index 08483d481..e13176333 100644 --- a/app/src/processing/mode/android/AndroidToolbar.java +++ b/app/src/processing/mode/android/AndroidToolbar.java @@ -72,9 +72,9 @@ public class AndroidToolbar extends EditorToolbar { switch (sel) { case RUN: if (shift) { - aeditor.handlePresent(); + aeditor.handleRunEmulator(); } else { - aeditor.handleRun(); + aeditor.handleRunDevice(); } break; @@ -102,7 +102,7 @@ public class AndroidToolbar extends EditorToolbar { case EXPORT: if (shift) { - aeditor.handleExportApplication(); + aeditor.handleExportPackage(); } else { aeditor.handleExportProject(); } diff --git a/app/src/processing/mode/java/JavaBuild.java b/app/src/processing/mode/java/JavaBuild.java index 99af07436..050623261 100644 --- a/app/src/processing/mode/java/JavaBuild.java +++ b/app/src/processing/mode/java/JavaBuild.java @@ -53,8 +53,8 @@ public class JavaBuild { // what happens in the build, stays in the build. // (which is to say that everything below this line, stays within this class) - private File srcFolder; - private File binFolder; + protected File srcFolder; + protected File binFolder; private boolean foundMain = false; private String classPath; protected String sketchClassName; diff --git a/build/build.xml b/build/build.xml index e229e1e4c..40f202362 100644 --- a/build/build.xml +++ b/build/build.xml @@ -117,6 +117,7 @@ +