diff --git a/android/theme/buttons.gif b/android/theme/buttons.gif index 3d8facd00..f3d6319c1 100644 Binary files a/android/theme/buttons.gif and b/android/theme/buttons.gif differ diff --git a/android/theme/resize.gif b/android/theme/resize.gif index 630be1e26..ee6f10a99 100644 Binary files a/android/theme/resize.gif and b/android/theme/resize.gif differ diff --git a/android/theme/tab-sel-left.gif b/android/theme/tab-sel-left.gif index bdee43c25..7ad78e5ad 100644 Binary files a/android/theme/tab-sel-left.gif and b/android/theme/tab-sel-left.gif differ diff --git a/android/theme/tab-sel-menu.gif b/android/theme/tab-sel-menu.gif index d926650e7..66a73566b 100644 Binary files a/android/theme/tab-sel-menu.gif and b/android/theme/tab-sel-menu.gif differ diff --git a/android/theme/tab-sel-mid.gif b/android/theme/tab-sel-mid.gif index fa8ed45fc..e114da1ee 100644 Binary files a/android/theme/tab-sel-mid.gif and b/android/theme/tab-sel-mid.gif differ diff --git a/android/theme/tab-sel-right.gif b/android/theme/tab-sel-right.gif index d901fdba4..edbaa7e81 100644 Binary files a/android/theme/tab-sel-right.gif and b/android/theme/tab-sel-right.gif differ diff --git a/android/theme/tab-unsel-left.gif b/android/theme/tab-unsel-left.gif index eea22d8d8..0f2ed7284 100644 Binary files a/android/theme/tab-unsel-left.gif and b/android/theme/tab-unsel-left.gif differ diff --git a/android/theme/tab-unsel-menu.gif b/android/theme/tab-unsel-menu.gif index a1720a589..490dcf014 100644 Binary files a/android/theme/tab-unsel-menu.gif and b/android/theme/tab-unsel-menu.gif differ diff --git a/android/theme/tab-unsel-mid.gif b/android/theme/tab-unsel-mid.gif index a2c5497b8..05dac6ea4 100644 Binary files a/android/theme/tab-unsel-mid.gif and b/android/theme/tab-unsel-mid.gif differ diff --git a/android/theme/tab-unsel-right.gif b/android/theme/tab-unsel-right.gif index 91c03f5a9..4d7c02a27 100644 Binary files a/android/theme/tab-unsel-right.gif and b/android/theme/tab-unsel-right.gif differ diff --git a/android/theme/theme.txt b/android/theme/theme.txt index 87d2088c1..565344c96 100644 --- a/android/theme/theme.txt +++ b/android/theme/theme.txt @@ -1,17 +1,19 @@ # GUI - STATUS status.notice.fgcolor = #000000 -status.notice.bgcolor = #818b95 +#status.notice.bgcolor = #808080 +status.notice.bgcolor = #87ad3a status.error.fgcolor = #ffffff status.error.bgcolor = #662000 status.edit.fgcolor = #000000 -status.edit.bgcolor = #cc9900 +#status.edit.bgcolor = #cc9900 +status.edit.bgcolor = #6b8a2e status.font = SansSerif,plain,12 #status.font.macosx = Helvetica,plain,12 # GUI - TABS # settings for the tabs at the top # (tab images are stored in the lib/theme folder) -header.bgcolor = #818b95 +header.bgcolor = #92bc3f header.text.selected.color = #1a1a00 header.text.unselected.color = #ffffff header.text.font = SansSerif,plain,12 @@ -24,20 +26,22 @@ console.output.color = #cccccc console.error.color = #ff3000 # GUI - BUTTONS -buttons.bgcolor = #4a545e +buttons.bgcolor = #597226 buttons.status.font = SansSerif,plain,12 #buttons.status.font.macosx = Helvetica,plain,12 buttons.status.color = #ffffff # GUI - MODE mode.button.bgcolor = #9ca6b0 +#mode.button.font = SansSerif,plain,9 mode.button.font = SansSerif,plain,9 #mode.button.font.macosx = Helvetica,plain,9 -mode.button.color = #4a545e +#mode.button.color = #4a545e +mode.button.color = #a8cb62 # GUI - LINESTATUS linestatus.color = #ffffff -linestatus.bgcolor = #29333d +linestatus.bgcolor = #364517 # EDITOR - DETAILS @@ -57,7 +61,8 @@ editor.caret.color = #333300 editor.external.bgcolor = #c8d2dc # selection color -editor.selection.color = #ffcc00 +#editor.selection.color = #ffcc00 +editor.selection.color = #ebf3da # area that's not in use by the text (replaced with tildes) editor.invalid.style = #7e7e7e,bold @@ -74,22 +79,24 @@ editor.brackethighlight.color = #006699 # TEXT - KEYWORDS # e.g abstract, final, private -editor.keyword1.style = #cc6600,plain +editor.keyword1.style = #799b34,plain # e.g. beginShape, point, line -editor.keyword2.style = #cc6600,plain +editor.keyword2.style = #799b34,plain # e.g. byte, char, short, color -editor.keyword3.style = #cc6600,bold +editor.keyword3.style = #799b34,bold # TEXT - LITERALS # constants: e.g. null, true, this, RGB, TWO_PI -editor.literal1.style = #006699,plain +#editor.literal1.style = #627f26,plain +editor.literal1.style = #336598,plain # p5 built in variables: e.g. mouseX, width, pixels -editor.literal2.style = #006699,plain +#editor.literal2.style = #627f26,plain +editor.literal2.style = #336598,plain # e.g. + - = / editor.operator.style = #000000,plain @@ -100,8 +107,10 @@ editor.label.style = #7e7e7e,bold # TEXT - COMMENTS -editor.comment1.style = #7e7e7e,plain -editor.comment2.style = #7e7e7e,plain +#editor.comment1.style = #7e7e7e,plain +#editor.comment2.style = #7e7e7e,plain +editor.comment1.style = #8e8e8e,plain +editor.comment2.style = #8e8e8e,plain # LINE STATUS - editor line number status bar at the bottom of the screen diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 4dfa1fb64..ba2e0eac5 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -85,9 +85,10 @@ public class Base { // a lone file menu to be used when all sketch windows are closed static public JMenu defaultFileMenu; - private Mode defaultMode = new JavaMode(this, getContentFile("modes/java")); - private Mode androidMode = new AndroidMode(this, getContentFile("modes/android")); - private Mode[] modeList = { defaultMode, androidMode }; + private Mode defaultMode; +// private Mode androidMode; + private Mode[] modeList; + private JMenu modeMenu; private JMenu sketchbookMenu; @@ -117,7 +118,7 @@ public class Base { } catch (Exception e) { e.printStackTrace(); } - + initPlatform(); // Use native popups so they don't look so crappy on osx @@ -209,6 +210,22 @@ public class Base { public Base(String[] args) { + // TODO this will be dynamically loading modes in no time + defaultMode = new JavaMode(this, getContentFile("modes/java")); + Mode androidMode = new AndroidMode(this, getContentFile("modes/android")); + modeList = new Mode[] { defaultMode, androidMode }; + modeMenu = new JMenu(); + for (final Mode mode : modeList) { + JMenuItem item = new JMenuItem(mode.getTitle()); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { +// System.out.println(e); + changeMode(mode); + } + }); + modeMenu.add(item); + } + // Get the sketchbook path, and make sure it's set properly determineSketchbookFolder(); @@ -267,14 +284,19 @@ public class Base { * all over the place. While it may seem like fun to send the Arduino guys * on a treasure hunt, it gets old after a while. */ - static protected String getExtension() { - return ".pde"; +// static protected String getExtension() { +// return ".pde"; +// } + + + public JMenu getModeMenu() { + return modeMenu; } - public Mode getDefaultMode() { - return defaultMode; - } +// public Mode getDefaultMode() { +// return defaultMode; +// } /** @@ -478,6 +500,34 @@ public class Base { } + protected void changeMode(Mode mode) { + if (activeEditor.getMode() != mode) { + Sketch sketch = activeEditor.getSketch(); + if (sketch.isModified()) { + Base.showWarning("Save", + "Please save the sketch before changing the mode.", + null); + } else { + String mainPath = sketch.getMainFilePath(); + + // save a mode file into this sketch folder + File sketchProps = new File(sketch.getFolder(), "sketch.properties"); + PrintWriter writer = PApplet.createWriter(sketchProps); + writer.println("mode=" + mode.getTitle()); + writer.flush(); + writer.close(); + + // close this sketch + int[] where = activeEditor.getPlacement(); + handleClose(activeEditor); + + // re-open the sketch + handleOpen(mainPath, where); + } + } + } + + // Because of variations in native windowing systems, no guarantees about // changes to the focused and active Windows can be made. Developers must // never assume that this Window is the focused or active Window until this @@ -537,13 +587,13 @@ public class Base { } -// /** -// * Return the same mode as the active editor, or the default mode, which -// * begins as Java/Standard, but is updated with the last mode used. -// */ -// protected Mode nextEditorMode() { -// return (activeEditor == null) ? defaultMode : activeEditor.getMode(); -// } + /** + * Return the same mode as the active editor, or the default mode, which + * begins as Java/Standard, but is updated with the last mode used. + */ + public Mode nextEditorMode() { + return (activeEditor == null) ? defaultMode : activeEditor.getMode(); + } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -616,7 +666,8 @@ public class Base { newbieDir.mkdirs(); // Make an empty pde file - File newbieFile = new File(newbieDir, newbieName + getExtension()); + //File newbieFile = new File(newbieDir, newbieName + getExtension()); + File newbieFile = new File(newbieDir, newbieName + "." + defaultMode.getDefaultExtension()); new FileOutputStream(newbieFile); // create the file return newbieFile.getAbsolutePath(); } @@ -707,12 +758,22 @@ public class Base { //fd.setDirectory(Preferences.get("sketchbook.path")); //fd.setDirectory(getSketchbookPath()); + final ArrayList extensions = new ArrayList(); + for (Mode mode : modeList) { + extensions.add(mode.getDefaultExtension()); + } + // Only show .pde files as eligible bachelors fd.setFilenameFilter(new FilenameFilter() { public boolean accept(File dir, String name) { // TODO this doesn't seem to ever be used. AWESOME. - //System.out.println("check filter on " + dir + " " + name); - return name.toLowerCase().endsWith(getExtension()); + System.out.println("check filter on " + dir + " " + name); + for (String ext : extensions) { + if (name.toLowerCase().endsWith("." + ext)) { + return true; + } + } + return false; } }); @@ -778,20 +839,28 @@ public class Base { // } // } -// System.err.println(" creating new editor"); -// Editor editor = new Editor(this, defaultMode, path, location); - Editor editor = defaultMode.createEditor(this, path, location); -// Editor editor = null; -// try { -// editor = new Editor(this, path, location); -// } catch (Exception e) { -// e.printStackTrace(); -// System.err.flush(); -// System.out.flush(); -// System.exit(1); -// } -// System.err.println(" done creating new editor"); -// EditorConsole.systemErr.println(" done creating new editor"); + Mode nextMode = nextEditorMode(); + try { + File sketchFolder = new File(path).getParentFile(); + File sketchProps = new File(sketchFolder, "sketch.properties"); + if (sketchProps.exists()) { + Settings props = new Settings(sketchProps); + String modeTitle = props.get("mode"); + if (modeTitle != null) { + nextMode = findMode(modeTitle); + if (nextMode == null) { + Base.showWarning("Depeche Mode", + "This sketch was last used in “" + modeTitle + "” mode,\n" + + "which does not appear to be installed. The sketch will\n" + + "be opened in “" + defaultMode.getTitle() + "” mode instead.", null); + nextMode = defaultMode; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + Editor editor = nextMode.createEditor(this, path, location); // Make sure that the sketch actually loaded if (editor.getSketch() == null) { @@ -807,6 +876,16 @@ public class Base { return editor; } + + + protected Mode findMode(String title) { + for (Mode mode : modeList) { + if (mode.getTitle().equals(title)) { + return mode; + } + } + return null; + } /** @@ -1001,7 +1080,9 @@ public class Base { protected boolean addSketches(JMenu menu, File folder, final boolean replaceExisting) throws IOException { // skip .DS_Store files, etc (this shouldn't actually be necessary) - if (!folder.isDirectory()) return false; + if (!folder.isDirectory()) { + return false; + } if (folder.getName().equals("libraries")) { return false; // let's not go there @@ -1009,12 +1090,12 @@ public class Base { String[] list = folder.list(); // If a bad folder or unreadable or whatever, this will come back null - if (list == null) return false; + if (list == null) { + return false; + } - // Alphabetize list, since it's not always alpha order + // Alphabetize the list, since it's not always alpha order Arrays.sort(list, String.CASE_INSENSITIVE_ORDER); - //processing.core.PApplet.println("adding sketches " + folder.getAbsolutePath()); - //PApplet.println(list); ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -1040,52 +1121,92 @@ public class Base { // offers no speed improvement //menu.addActionListener(listener); - boolean ifound = false; + boolean found = false; - for (int i = 0; i < list.length; i++) { - if ((list[i].charAt(0) == '.') || - list[i].equals("CVS")) continue; +// for (int i = 0; i < list.length; i++) { +// if ((list[i].charAt(0) == '.') || +// list[i].equals("CVS")) continue; + for (String name : list) { + if (name.charAt(0) == '.') { + continue; + } - File subfolder = new File(folder, list[i]); - if (!subfolder.isDirectory()) continue; + File subfolder = new File(folder, name); + if (subfolder.isDirectory()) { + File entry = checkSketchFolder(subfolder, name); + if (entry != null) { - File entry = new File(subfolder, list[i] + getExtension()); - // if a .pde file of the same prefix as the folder exists.. - if (entry.exists()) { - //String sanityCheck = sanitizedName(list[i]); - //if (!sanityCheck.equals(list[i])) { - if (!Sketch.isSanitaryName(list[i])) { - if (!builtOnce) { - String complaining = - "The sketch \"" + list[i] + "\" cannot be used.\n" + - "Sketch names must contain only basic letters and numbers\n" + - "(ASCII-only with no spaces, " + - "and it cannot start with a number).\n" + - "To get rid of this message, remove the sketch from\n" + - entry.getAbsolutePath(); - Base.showMessage("Ignoring sketch with bad name", complaining); +// File entry = new File(subfolder, list[i] + getExtension()); +// // if a .pde file of the same prefix as the folder exists.. +// if (entry.exists()) { +// //String sanityCheck = sanitizedName(list[i]); +// //if (!sanityCheck.equals(list[i])) { +// if (!Sketch.isSanitaryName(list[i])) { +// if (!builtOnce) { +// String complaining = +// "The sketch \"" + list[i] + "\" cannot be used.\n" + +// "Sketch names must contain only basic letters and numbers\n" + +// "(ASCII-only with no spaces, " + +// "and it cannot start with a number).\n" + +// "To get rid of this message, remove the sketch from\n" + +// entry.getAbsolutePath(); +// Base.showMessage("Ignoring sketch with bad name", complaining); +// } +// continue; +// } + + JMenuItem item = new JMenuItem(name); + item.addActionListener(listener); + item.setActionCommand(entry.getAbsolutePath()); + menu.add(item); + found = true; + + } else { + // not a sketch folder, but maybe a subfolder containing sketches + JMenu submenu = new JMenu(name); + // needs to be separate var otherwise would set ifound to false + boolean anything = addSketches(submenu, subfolder, replaceExisting); + if (anything) { + menu.add(submenu); + found = true; } - continue; - } - - JMenuItem item = new JMenuItem(list[i]); - item.addActionListener(listener); - item.setActionCommand(entry.getAbsolutePath()); - menu.add(item); - 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, replaceExisting); - if (found) { - menu.add(submenu); - ifound = true; } } } - return ifound; // actually ignored, but.. + return found; // actually ignored, but.. + } + + + /** + * Check through the various modes and see if this is a legit sketch. + * Because the default mode will be the first in the list, this will always + * prefer that one over the others. + */ + File checkSketchFolder(File subfolder, String item) { + for (Mode mode : modeList) { + File entry = new File(subfolder, item + "." + mode.getDefaultExtension()); + // if a .pde file of the same prefix as the folder exists.. + if (entry.exists()) { + return entry; + } + // for the new releases, don't bother lecturing.. just ignore the sketch + /* + if (!Sketch.isSanitaryName(list[i])) { + if (!builtOnce) { + String complaining = + "The sketch \"" + list[i] + "\" cannot be used.\n" + + "Sketch names must contain only basic letters and numbers\n" + + "(ASCII-only with no spaces, " + + "and it cannot start with a number).\n" + + "To get rid of this message, remove the sketch from\n" + + entry.getAbsolutePath(); + Base.showMessage("Ignoring sketch with bad name", complaining); + } + continue; + } + */ + } + return null; } diff --git a/app/src/processing/app/EditorToolbar.java b/app/src/processing/app/EditorToolbar.java index 3230bbdf9..35f92ac02 100644 --- a/app/src/processing/app/EditorToolbar.java +++ b/app/src/processing/app/EditorToolbar.java @@ -97,6 +97,7 @@ public abstract class EditorToolbar extends JComponent implements MouseInputList // String modeTitle = "ANDROID"; //"Java"; int modeX1, modeY1; int modeX2, modeY2; + JMenu modeMenu; protected ArrayList