diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 2e2bcd8e1..5337571cc 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -755,8 +755,7 @@ public class Base { // 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); + // confirmed to be working properly [fry 110128] for (String ext : extensions) { if (name.toLowerCase().endsWith("." + ext)) { return true; diff --git a/app/src/processing/app/EditorHeader.java b/app/src/processing/app/EditorHeader.java index 46890edaa..2388424ef 100644 --- a/app/src/processing/app/EditorHeader.java +++ b/app/src/processing/app/EditorHeader.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-11 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 @@ package processing.app; import java.awt.*; import java.awt.event.*; +import java.util.Arrays; import javax.swing.*; @@ -38,8 +39,8 @@ public class EditorHeader extends JComponent { Editor editor; - int tabLeft[]; - int tabRight[]; + Tab[] tabs = new Tab[0]; + Tab[] visitOrder; Font font; FontMetrics metrics; @@ -89,14 +90,35 @@ public class EditorHeader extends JComponent { } else { Sketch sketch = editor.getSketch(); - for (int i = 0; i < sketch.getCodeCount(); i++) { - if ((x > tabLeft[i]) && (x < tabRight[i])) { - sketch.setCurrentCode(i); +// for (int i = 0; i < sketch.getCodeCount(); i++) { +// if ((x > tabLeft[i]) && (x < tabRight[i])) { +// sketch.setCurrentCode(i); +// repaint(); +// } +// } + for (Tab tab : tabs) { + if (tab.contains(x)) { + sketch.setCurrentCode(tab.index); repaint(); } } } } + + public void mouseExited(MouseEvent e) { + editor.statusEmpty(); + } + }); + + addMouseMotionListener(new MouseMotionAdapter() { + public void mouseMoved(MouseEvent e) { + int x = e.getX(); + for (Tab tab : tabs) { + if (tab.contains(x) && !tab.textVisible) { + editor.statusNotice(editor.getSketch().getCode(tab.index).getPrettyName()); + } + } + } }); } @@ -146,7 +168,7 @@ public class EditorHeader extends JComponent { imageH = sizeH; offscreen = createImage(imageW, imageH); } - + Graphics g = offscreen.getGraphics(); g.setFont(font); // need to set this each time through metrics = g.getFontMetrics(); @@ -160,59 +182,155 @@ public class EditorHeader extends JComponent { g.setColor(backgroundColor); g.fillRect(0, 0, imageW, imageH); - int codeCount = sketch.getCodeCount(); - if ((tabLeft == null) || (tabLeft.length < codeCount)) { - tabLeft = new int[codeCount]; - tabRight = new int[codeCount]; +// int codeCount = sketch.getCodeCount(); +// if ((tabLeft == null) || (tabLeft.length < codeCount)) { +// tabLeft = new int[codeCount]; +// tabRight = new int[codeCount]; +// } + if (tabs.length != sketch.getCodeCount()) { + tabs = new Tab[sketch.getCodeCount()]; + for (int i = 0; i < tabs.length; i++) { + tabs[i] = new Tab(i); + } + visitOrder = new Tab[sketch.getCodeCount() - 1]; } - int x = 6; // offset from left edge of the component - for (int i = 0; i < sketch.getCodeCount(); i++) { - SketchCode code = sketch.getCode(i); +// int x = 6; // offset from left edge of the component + menuRight = sizeW - 16; + menuLeft = menuRight - pieces[0][MENU].getWidth(this); +// int tabMax = menuLeft - x; + int tabLeft = 6; + int tabMax = menuLeft - tabLeft; + // reset all tab positions + for (Tab tab : tabs) { + SketchCode code = sketch.getCode(tab.index); + tab.textVisible = true; + tab.lastVisited = code.lastVisited(); + // hide extensions for .pde files (or whatever else is the norm elsewhere boolean hide = editor.getMode().hideExtension(code.getExtension()); String codeName = hide ? code.getPrettyName() : code.getFileName(); - // if modified, add the li'l glyph next to the name - String text = " " + codeName + (code.isModified() ? " \u00A7" : " "); - - int textWidth = (int) - font.getStringBounds(text, g2.getFontRenderContext()).getWidth(); - - int pieceCount = 2 + (textWidth / PIECE_WIDTH); - int pieceWidth = pieceCount * PIECE_WIDTH; - - int state = (code == sketch.getCurrentCode()) ? SELECTED : UNSELECTED; - g.drawImage(pieces[state][LEFT], x, 0, null); - x += PIECE_WIDTH; - - int contentLeft = x; - tabLeft[i] = x; - for (int j = 0; j < pieceCount; j++) { - g.drawImage(pieces[state][MIDDLE], x, 0, null); - x += PIECE_WIDTH; - } - tabRight[i] = x; - int textLeft = contentLeft + (pieceWidth - textWidth) / 2; - - g.setColor(textColor[state]); - int baseline = (sizeH + fontAscent) / 2; - //g.drawString(sketch.code[i].name, textLeft, baseline); - g.drawString(text, textLeft, baseline); - - g.drawImage(pieces[state][RIGHT], x, 0, null); - x += PIECE_WIDTH - 1; // overlap by 1 pixel + tab.text = " " + codeName + (code.isModified() ? " \u00A7" : " "); + + tab.textWidth = (int) + font.getStringBounds(tab.text, g2.getFontRenderContext()).getWidth(); } - menuLeft = sizeW - (16 + pieces[0][MENU].getWidth(this)); - menuRight = sizeW - 16; + // make sure everything can fit + if (!placeTabs(tabLeft, tabMax, null)) { + //System.arraycopy(tabs, 0, visitOrder, 0, tabs.length); + // always show the tab with the sketch's name +// System.arraycopy(tabs, 1, visitOrder, 0, tabs.length - 1); + int index = 0; + // stock the array backwards so that the rightmost tabs are closed by default + for (int i = tabs.length - 1; i > 0; --i) { + visitOrder[index++] = tabs[i]; + } + Arrays.sort(visitOrder); // sort on when visited +// for (int i = 0; i < visitOrder.length; i++) { +// System.out.println(visitOrder[i].index + " " + visitOrder[i].text); +// } +// System.out.println(); + + for (int i = 0; i < visitOrder.length; i++) { + tabs[visitOrder[i].index].textVisible = false; + if (placeTabs(tabLeft, tabMax, null)) { + break; + } + } + } + + // now actually draw the tabs + placeTabs(tabLeft, tabMax, g); + +// for (int i = 0; i < sketch.getCodeCount(); i++) { +// SketchCode code = sketch.getCode(i); +// Tab tab = tabs[i]; +// +// int pieceCount = 2 + (tab.textWidth / PIECE_WIDTH); +// int pieceWidth = pieceCount * PIECE_WIDTH; +// +// int state = (code == sketch.getCurrentCode()) ? SELECTED : UNSELECTED; +// g.drawImage(pieces[state][LEFT], x, 0, null); +// x += PIECE_WIDTH; +// +// int contentLeft = x; +// tab.left = x; +// for (int j = 0; j < pieceCount; j++) { +// g.drawImage(pieces[state][MIDDLE], x, 0, null); +// x += PIECE_WIDTH; +// } +// tab.right = x; +// int textLeft = contentLeft + (pieceWidth - tab.textWidth) / 2; +// +// g.setColor(textColor[state]); +// int baseline = (sizeH + fontAscent) / 2; +// //g.drawString(sketch.code[i].name, textLeft, baseline); +// g.drawString(tab.text, textLeft, baseline); +// +// g.drawImage(pieces[state][RIGHT], x, 0, null); +// x += PIECE_WIDTH - 1; // overlap by 1 pixel +// } + +// menuLeft = sizeW - (16 + pieces[0][MENU].getWidth(this)); +// menuRight = sizeW - 16; // draw the dropdown menu target g.drawImage(pieces[popup.isVisible() ? SELECTED : UNSELECTED][MENU], menuLeft, 0, null); screen.drawImage(offscreen, 0, 0, null); } + + + private boolean placeTabs(int left, int right, Graphics g) { + Sketch sketch = editor.getSketch(); + int x = left; + + for (int i = 0; i < sketch.getCodeCount(); i++) { + SketchCode code = sketch.getCode(i); + Tab tab = tabs[i]; + + int pieceCount = 2 + (tab.textWidth / PIECE_WIDTH); + if (tab.textVisible == false) { + pieceCount = 4; + } + int pieceWidth = pieceCount * PIECE_WIDTH; + + int state = (code == sketch.getCurrentCode()) ? SELECTED : UNSELECTED; + if (g != null) { + g.drawImage(pieces[state][LEFT], x, 0, null); + } + x += PIECE_WIDTH; + + int contentLeft = x; + tab.left = x; + for (int j = 0; j < pieceCount; j++) { + if (g != null) { + g.drawImage(pieces[state][MIDDLE], x, 0, null); + } + x += PIECE_WIDTH; + } + tab.right = x; + + if (tab.textVisible) { + int textLeft = contentLeft + (pieceWidth - tab.textWidth) / 2; + if (g != null) { + g.setColor(textColor[state]); + int baseline = (sizeH + fontAscent) / 2; + //g.drawString(sketch.code[i].name, textLeft, baseline); + g.drawString(tab.text, textLeft, baseline); + } + } + + if (g != null) { + g.drawImage(pieces[state][RIGHT], x, 0, null); + } + x += PIECE_WIDTH - 1; // overlap by 1 pixel + } + return x <= right; + } /** @@ -387,4 +505,42 @@ public class EditorHeader extends JComponent { } return new Dimension(3000, Preferences.GRID_SIZE - 1); } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + class Tab implements Comparable { + int index; + int left; + int right; + String text; + int textWidth; + boolean textVisible; + long lastVisited; + + Tab(int index) { + this.index = index; + } + + boolean contains(int x) { + return x >= left && x <= right; + } + + // sort by the last time visited + public int compareTo(Object o) { + Tab other = (Tab) o; + // do this here to deal with situation where both are 0 + if (lastVisited == other.lastVisited) { + return 0; + } + if (lastVisited == 0) { + return -1; + } + if (other.lastVisited == 0) { + return 1; + } + return (int) (lastVisited - other.lastVisited); + } + } } diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 1949dd13a..20cb54d2e 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -1080,6 +1080,11 @@ public class Sketch { * */ public void setCurrentCode(int which) { +// // for the tab sizing +// if (current != null) { +// current.visited = System.currentTimeMillis(); +// System.out.println(current.visited); +// } // if current is null, then this is the first setCurrent(0) if ((currentIndex == which) && (current != null)) { return; @@ -1095,9 +1100,11 @@ public class Sketch { current = code[which]; currentIndex = which; + current.visited = System.currentTimeMillis(); editor.setCode(current); - editor.header.rebuild(); +// editor.header.rebuild(); + editor.header.repaint(); } diff --git a/app/src/processing/app/SketchCode.java b/app/src/processing/app/SketchCode.java index 0c71d8660..dfcec187c 100644 --- a/app/src/processing/app/SketchCode.java +++ b/app/src/processing/app/SketchCode.java @@ -49,6 +49,9 @@ public class SketchCode { /** Document object for this tab. Currently this is a SyntaxDocument. */ private Document document; + /** Last time this tab was visited */ + long visited; + /** * Undo Manager for this tab, each tab keeps track of their own * Editor.undo will be set to this object when this code is the tab @@ -240,6 +243,11 @@ public class SketchCode { scrollPosition = pos; } + + public long lastVisited() { + return visited; + } + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . diff --git a/todo.txt b/todo.txt index c8f2c7897..26cbecdf7 100644 --- a/todo.txt +++ b/todo.txt @@ -54,30 +54,33 @@ X and rather than trying to figure out a complicated scheme for inclusion X we can have something that takes care of auto-copying per-mode examples X implement option to change modes X preliminary, ugly version of android coloring +X can't do fileMenu.add(base.getSketchbookMenu()); inside ThinkDifferent +X sketchbook location hasn't been determined yet +X change 'export' to 'export applet' +X android will be "Export Project", "Export Release Application" +X along with "Run in Emulator" and "Run on Device" -_ remove PdeKeyListener, roll it into the Java InputHandler for JEditTextArea +serial +X updated serial lib for mac osx +X http://code.google.com/p/processing/issues/detail?id=503 +X http://rxtx.qbang.org/wiki/index.php/Download -_ can't do fileMenu.add(base.getSketchbookMenu()); inside ThinkDifferent -_ sketchbook location hasn't been determined yet - -_ remove any reference to 'Editor' from Sketch.java -_ or is that excessive, since Document is in there, etc -_ Build does the heavy lifting anyway... - -_ export is broken in 0192 -_ http://code.google.com/p/processing/issues/detail?id=487 - -_ the build is broken! the build is broken! -_ http://code.google.com/p/processing/issues/detail?id=519 - -DO NOT USE "JVMArchs". It is deprecated, and manually overrides the natural architecture launching and ordering that LaunchServices does, including accommodating the 32-bit checkbox in the Get Info window. - -_ updated serial lib for mac osx -_ http://code.google.com/p/processing/issues/detail?id=503 - -_ casey's vote: -_ Standard, Android, JavaScript, Jython -_ or: Processing, Android, Processing.js, Processing.py +editor +X accented letter input is broken (on os x and windows) +X http://code.google.com/p/processing/issues/detail?id=335 +X disabled input method support for now +X make some fancy extendo things because the tabs get too big +X either condense or popdown menu thingy +o http://dev.processing.org/bugs/show_bug.cgi?id=54 +X http://code.google.com/p/processing/issues/detail?id=17 +X don't show tabs when there are too many +X maybe move the list of files to the top? +X or indicate which are visible somehow +X slightly longer.. rearrange? +X or just show tabs in (alpha?) order based on what's most recently used +X have some indicator that shows the tabs when they've disappeared +X or little mini tabs that expand/contract? +X and a way to control who's expanded and not examples menu X top level directories will be grayed out categories @@ -90,9 +93,30 @@ _ window that opens and contains list of examples _ also, move open to a submenu? _ then we'd have open / recent / sketchbook -change 'export' to 'export applet' -android will be "Export Project", "Export Release Application" - along with "Run in Emulator" and "Run on Device" + +_ library/export testing +_ test controlp5 +_ test code folder on desktop +_ test code folder on android +_ test libraries on android +_ test opengl on android + +_ the build is broken! the build is broken! +_ http://code.google.com/p/processing/issues/detail?id=519 + +_ remove PdeKeyListener, roll it into the Java InputHandler for JEditTextArea +_ remove any reference to 'Editor' from Sketch.java +_ or is that excessive, since Document is in there, etc +_ Build does the heavy lifting anyway... + +_ export is broken in 0192 +_ http://code.google.com/p/processing/issues/detail?id=487 + +DO NOT USE "JVMArchs". It is deprecated, and manually overrides the natural architecture launching and ordering that LaunchServices does, including accommodating the 32-bit checkbox in the Get Info window. + +_ casey's vote: +_ Standard, Android, JavaScript, Jython +_ or: Processing, Android, Processing.js, Processing.py _ note for reference: auto-format has been moved to edit _ this might be the same as arduino? @@ -161,9 +185,6 @@ _ need to get a new stable release out there, the docs/ref are out of sync _ build is currently broken for p5 because of changes to the file layout _ something that gets fixed my 'make clean' -_ Debugger highlights wrong line, and sometimes the wrong file -_ http://code.google.com/p/processing/issues/detail?id=412 - . . . . _ "save" clears undo information @@ -220,9 +241,8 @@ _ add processing.js export tool from florian _ http://github.com/fjenett/processingjstool/ _ http://github.com/fjenett/processingjstool/zipball/v0.0.6 -_ accented letter input is broken (on os x and windows) -_ http://code.google.com/p/processing/issues/detail?id=335 -_ disabled input method support for now +_ Input Method support (for Japanese et al.) has been disabled +_ http://code.google.com/p/processing/issues/detail?id=526 _ launch4j problem - FIXABLE _ no crash when double-clicking a sketch and loading it @@ -905,6 +925,8 @@ PDE / Compiler & Preprocessor need examples _ Improve detection and handling of missing semicolons _ http://dev.processing.org/bugs/show_bug.cgi?id=1036 +_ Debugger highlights wrong line, and sometimes the wrong file +_ http://code.google.com/p/processing/issues/detail?id=412 medium (bugs/features) _ mismatched square brackets generate bizarre and/or misleading error messages @@ -983,15 +1005,6 @@ _ either synchronize the open (at a minimum) _ or wait for mac handlers to register an open event _ can also cause problems with opening multiple copies of same sketch _ after fixing name of sketch, ensure sketch of that name does not exist -_ do quick fix for tab bar -_ don't show tabs when there are too many -_ maybe move the list of files to the top? -_ or indicate which are visible somehow -_ slightly longer.. rearrange? -_ or just show tabs in (alpha?) order based on what's most recently used -_ have some indicator that shows the tabs when they've disappeared -_ or little mini tabs that expand/contract? -_ and a way to control who's expanded and not _ add auto-save to the editor _ http://dev.processing.org/bugs/show_bug.cgi?id=739 _ dragging title bar while sketch running causes strange selection behavior @@ -1062,9 +1075,6 @@ _ http://dev.processing.org/bugs/show_bug.cgi?id=37 PDE / Editor Header -2 _ make some fancy extendo things because the tabs get too big -2 _ either condense or popdown menu thingy -2 _ http://dev.processing.org/bugs/show_bug.cgi?id=54 5 _ key command for prev/next tab works, but not menu 5 _ menu options are actually disabled because of inconsistency 5 _ http://dev.processing.org/bugs/show_bug.cgi?id=1044