diff --git a/processing/app/PdeBase.java b/processing/app/PdeBase.java index 31d244ce0..0bd3df472 100644 --- a/processing/app/PdeBase.java +++ b/processing/app/PdeBase.java @@ -264,6 +264,8 @@ public class PdeBase extends Frame implements ActionListener { menu.addSeparator(); + // "cut" and "copy" should really only be enabled if some text + // is currently selected item = new MenuItem("Cut", new MenuShortcut('X')); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -898,7 +900,10 @@ public class PdeBase extends Frame implements ActionListener { } else if (command.equals("Reference")) { if (platform == WINDOWS) { try { - Runtime.getRuntime().exec("cmd /c reference\\index.html"); + //Runtime.getRuntime().exec("cmd /c reference\\index.html"); + String currentDir = System.getProperty("user.dir"); + Runtime.getRuntime().exec("c:\\progra~1\\intern~1\\iexplore "+ currentDir + + "\\reference\\index.html"); } catch (IOException e) { e.printStackTrace(); } @@ -917,7 +922,8 @@ public class PdeBase extends Frame implements ActionListener { } else if (platform == LINUX) { try { // another wild ass guess - Runtime.getRuntime().exec("mozilla reference/index.html"); + String currentDir = System.getProperty("user.dir"); + Runtime.getRuntime().exec("mozilla "+ currentDir + "/reference/index.html"); } catch (IOException e) { e.printStackTrace(); } diff --git a/processing/app/PdeEditor.java b/processing/app/PdeEditor.java index 809ff1ec3..cb3bbb986 100644 --- a/processing/app/PdeEditor.java +++ b/processing/app/PdeEditor.java @@ -177,22 +177,46 @@ public class PdeEditor extends Panel { rightPanel.add("Center", textarea); - /* Panel statusPanel = new Panel(); //statusPanel.setLayout(new BorderLayout()); statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.Y_AXIS)); + ///statusPanel.setLayout(new BorderLayout()); + //statusPanel.setLayout(new FlowLayout(FlowLayout.VERTICAL)); + status = new PdeEditorStatus(this); statusPanel.add("Center", status); + ///statusPanel.add(BorderLayout.NORTH, status); + console = new PdeEditorConsole(this); statusPanel.add("South", console); + ///statusPanel.add(BorderLayout.NORTH, console); + rightPanel.add("South", statusPanel); - */ + //statusPanel.setMaximumSize(new Dimension(300, 50)); + + +/* not sure why this doesn't work, probably a heavy vs. lightweight component issue + Panel consolePanel = new Panel(); + consolePanel.setLayout(new BoxLayout(consolePanel, BoxLayout.Y_AXIS)); status = new PdeEditorStatus(this); - rightPanel.add(status); + consolePanel.add("North",status); console = new PdeEditorConsole(this); - rightPanel.add(console); + consolePanel.add("South",console); + +/// + JSplitPane splitPane = new JSplitPane( + JSplitPane.VERTICAL_SPLIT, +/// textarea, consolePanel); + //splitPane.setOneTouchExpandable(true); + splitPane.setDividerLocation(100); + + //Provide minimum sizes for the two components in the split pane + Dimension minimumSize = new Dimension(200, 300); + top.setMinimumSize(minimumSize); + bottom.setMinimumSize(minimumSize); +*/ /* //pain = statusPanel; @@ -318,6 +342,7 @@ public class PdeEditor extends Panel { public void mousePressed(MouseEvent e) { //System.out.println("got stop"); //doStop(); + setVisible(true); doClose(); #ifdef JDK13 @@ -340,15 +365,57 @@ public class PdeEditor extends Panel { // windowActivated doesn't seem to do much, so focus listener better presentationWindow.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { - //System.out.println("focusGained: " + e); + //System.out.println("presentationWindow focusGained: " + e); //if (frame != null) frame.toFront(); // editor to front - try { - //System.out.println("moving to front"); - pdeRuntime.window.toFront(); - } catch (Exception ex) { } + if (! pdeRuntime.window.isVisible()) { + try { + //System.out.println("moving to front"); + pdeRuntime.window.toFront(); + } catch (Exception ex) { } + } } }); + textarea.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + //System.err.println("textarea focusGained: " + e); + if (presenting == true) { + try { + presentationWindow.toFront(); + pdeRuntime.window.toFront(); + } catch (Exception ex) { } + } + } + }); + + // if user clicks on background presentationWindow, restore applet window + // ("engine.window") to the front immediately + presentationWindow.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + //System.out.println("mouseClicked: " + e.toString()); + try { + //System.out.println("moving to front"); + pdeRuntime.window.toFront(); + } catch (Exception ex) { } + } + public void mousePressed(MouseEvent e) { +// System.out.println("mousePressed: " + e.toString()); + //presentationWindow.toFront(); + try { + //System.out.println("moving to front"); + pdeRuntime.window.toFront(); + } catch (Exception ex) { } + } + public void mouseReleased(MouseEvent e) { + //System.out.println("mouseReleased: " + e.toString()); + try { + //System.out.println("moving to front"); + pdeRuntime.window.toFront(); + } catch (Exception ex) { } + } + }); + + /* presentationWindow.addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { @@ -654,6 +721,8 @@ public class PdeEditor extends Panel { try { if (presenting) { + //this.toBack(); + this.setVisible(false); presentationWindow.show(); presentationWindow.toFront(); //doRun(true); diff --git a/processing/app/PdeEditorButtons.java b/processing/app/PdeEditorButtons.java index 6cbd6f6de..6cff06218 100644 --- a/processing/app/PdeEditorButtons.java +++ b/processing/app/PdeEditorButtons.java @@ -1,10 +1,14 @@ import java.awt.*; -import java.awt.event.*; +import java.awt.event.MouseEvent; -//import javax.swing.*; +//import java.awt.Image; + +import javax.swing.*; +import javax.swing.event.*; -public class PdeEditorButtons extends Panel /*implements ActionListener*/ { +//public class PdeEditorButtons extends Panel /*implements ActionListener*/ { +public class PdeEditorButtons extends JPanel implements MouseInputListener { static final String EMPTY_STATUS = " "; // run, stop, save, export, open @@ -94,6 +98,9 @@ public class PdeEditorButtons extends Panel /*implements ActionListener*/ { status.setBounds(-5, BUTTON_COUNT*BUTTON_HEIGHT, BUTTON_WIDTH + 15, BUTTON_HEIGHT); status.setAlignment(Label.CENTER); + + addMouseListener(this); + addMouseMotionListener(this); } @@ -212,9 +219,19 @@ public class PdeEditorButtons extends Panel /*implements ActionListener*/ { screen.drawImage(offscreen, 0, 0, null); //screen.fillRect(0, 0, 10, 10); } + + public void mouseMoved(MouseEvent e) { + mouseMove(e); + } - - public boolean mouseMove(Event e, int x, int y) { + public void mouseDragged(MouseEvent e) { + //mouseMove(e); + } + + public void mouseMove(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); + //System.out.println(x + ", " + y); if (currentRollover != -1) { if ((y > y1[currentRollover]) && (x > x1) && @@ -222,7 +239,8 @@ public class PdeEditorButtons extends Panel /*implements ActionListener*/ { //if ((x > x1[currentRollover]) && (y > y1) && // (x < x2[currentRollover]) && (y < y2)) { //System.out.println("same"); - return true; // no change + ///return true; // no change + return; } else { //state[currentRollover] = INACTIVE_STATE; @@ -234,7 +252,8 @@ public class PdeEditorButtons extends Panel /*implements ActionListener*/ { } } int sel = findSelection(x, y); - if (sel == -1) return true; + //if (sel == -1) return true; + if (sel == -1) return; if (state[sel] != ACTIVE) { //state[sel] = ROLLOVER_STATE; @@ -258,7 +277,7 @@ public class PdeEditorButtons extends Panel /*implements ActionListener*/ { } */ //update(); - return true; + ///return true; } private int findSelection(int x, int y) { @@ -295,23 +314,28 @@ public class PdeEditorButtons extends Panel /*implements ActionListener*/ { if (updateAfter) update(); } - public boolean mouseEnter(Event e, int x, int y) { - return mouseMove(e, x, y); + public void mouseEntered(MouseEvent e) { + mouseMove(e); } - public boolean mouseExit(Event e, int x, int y) { + public void mouseExited(MouseEvent e) { // kludge for (int i = 0; i < BUTTON_COUNT; i++) { messageClear(title[i]); } - return mouseMove(e, x, y); + mouseMove(e); } int wasDown = -1; - public boolean mouseDown(Event e, int x, int y) { + //public boolean mouseDown(Event e, int x, int y) { + public void mousePressed(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); + int sel = findSelection(x, y); - if (sel == -1) return false; + ///if (sel == -1) return false; + if (sel == -1) return; currentRollover = -1; currentSelection = sel; setState(sel, ACTIVE, true); @@ -326,7 +350,6 @@ public class PdeEditorButtons extends Panel /*implements ActionListener*/ { editor.base.rebuildSketchbookMenu(popup); popup.show(this, x, y); } - return true; } @@ -340,13 +363,17 @@ public class PdeEditorButtons extends Panel /*implements ActionListener*/ { } */ - - public boolean mouseUp(Event e, int x, int y) { + public void mouseClicked(MouseEvent e) { + // this space intentionally left blank + } + + ///public boolean mouseUp(Event e, int x, int y) { + public void mouseReleased(MouseEvent e) { //switch (which[sel]) { switch (currentSelection) { case RUN: - editor.doRun(e.shiftDown()); + editor.doRun(e.isShiftDown()); //if (e.shiftDown()) { //editor.doPresent(); //} else { @@ -402,7 +429,7 @@ public class PdeEditorButtons extends Panel /*implements ActionListener*/ { currentSelection = -1; //update(); - return true; + ///return true; } public void clear() { // (int button) { diff --git a/processing/app/PdeEditorConsole.java b/processing/app/PdeEditorConsole.java index be91442c9..8c62d857b 100644 --- a/processing/app/PdeEditorConsole.java +++ b/processing/app/PdeEditorConsole.java @@ -1,6 +1,8 @@ import java.awt.*; import java.awt.event.*; import java.io.*; +import javax.swing.*; +import javax.swing.text.*; // might be nice to have option to save this to a file @@ -10,51 +12,22 @@ import java.io.*; // while watching just System.out // or just write directly to systemOut or systemErr -public class PdeEditorConsole extends Component { +public class PdeEditorConsole extends JScrollPane { PdeEditor editor; + StyledDocument consoleDoc; + MutableAttributeSet stdStyle; + MutableAttributeSet errStyle; + +/* for potential cross platform whitespace munging static final byte CR = (byte)'\r'; static final byte LF = (byte)'\n'; static final byte TAB = (byte)'\t'; static final int TAB_SIZE = 2; - //static byte tabchunk[] = new byte[TAB_SIZE]; - //static { - //for (int i = 0; i < TAB_SIZE; i++) { - // tabchunk[i] = ' '; - //} - //} +*/ - int lineCount; - int maxLineCount; - String lines[]; - boolean isError[]; - int firstLine; - int scrollOffset; - - byte cline[] = new byte[4096]; - //byte clength; - int clength; boolean cerror; - Color bgColor; - Color fgColorErr; - Color fgColorOut; - Color scrollEnabledColor; - Color scrollDisabledColor; - - int scrollLeft, scrollRight; - int scrollUpTop, scrollUpBottom; - int scrollDownTop, scrollDownBottom; - - Font font; - FontMetrics metrics; - int ascent; - int leading; - - Image offscreen; - int sizeW, sizeH; - int imageW, imageH; - static final int HINSET = 6; static final int VINSET = 6; @@ -71,22 +44,55 @@ public class PdeEditorConsole extends Component { public PdeEditorConsole(PdeEditor editor) { this.editor = editor; - lineCount = PdeBase.getInteger("editor.console.lines", 6); + JTextPane consoleTextPane = new JTextPane(); + consoleTextPane.setEditable(false); + consoleDoc = consoleTextPane.getStyledDocument(); + + // necessary? + MutableAttributeSet standard = new SimpleAttributeSet(); + StyleConstants.setAlignment(standard, StyleConstants.ALIGN_LEFT); + consoleDoc.setParagraphAttributes(0, 0, standard, true); + + // build styles for different types of console output + Color bgColor = PdeBase.getColor("editor.console.bgcolor", + new Color(26, 26, 26)); + Color fgColorOut = PdeBase.getColor("editor.console.fgcolor.output", + new Color(153, 153, 153)); + Color fgColorErr = PdeBase.getColor("editor.console.fgcolor.error", + new Color(204, 51, 0)); + Font font = PdeBase.getFont("editor.console.font", + new Font("Monospaced", Font.PLAIN, 11)); + + stdStyle = new SimpleAttributeSet(); + StyleConstants.setForeground(stdStyle, fgColorOut); + StyleConstants.setBackground(stdStyle, bgColor); + StyleConstants.setFontSize(stdStyle, font.getSize()); + StyleConstants.setFontFamily(stdStyle, font.getFamily()); + StyleConstants.setBold(stdStyle, font.isBold()); + StyleConstants.setItalic(stdStyle, font.isItalic()); + + errStyle = new SimpleAttributeSet(); + StyleConstants.setForeground(errStyle, fgColorErr); + StyleConstants.setBackground(errStyle, bgColor); + StyleConstants.setFontSize(errStyle, font.getSize()); + StyleConstants.setFontFamily(errStyle, font.getFamily()); + StyleConstants.setBold(errStyle, font.isBold()); + StyleConstants.setItalic(errStyle, font.isItalic()); - maxLineCount = 1000; - lines = new String[maxLineCount]; - isError = new boolean[maxLineCount]; - for (int i = 0; i < maxLineCount; i++) { - lines[i] = ""; - isError[i] = false; - } - firstLine = 0; + consoleTextPane.setBackground(bgColor); + + // add the jtextpane to this scrollpane + this.setViewportView(consoleTextPane); + + // todo: don't think this does anything + //XXX the initial size should be from properties file + this.setPreferredSize(new Dimension(200, 50)); if (systemOut == null) { systemOut = System.out; systemErr = System.err; - // not text thing on macos + // no text thing on macos boolean tod = ((PdeBase.platform != PdeBase.MACOSX) && (PdeBase.platform != PdeBase.MACOS9)); @@ -120,192 +126,28 @@ public class PdeEditorConsole extends Component { System.setErr(consoleErr); } } - - addMouseListener(new MouseAdapter() { - public void mousePressed(MouseEvent e) { - int x = e.getX(); - int y = e.getY(); - if (!((x > scrollLeft) && (x < scrollRight))) - return; - - if ((y > scrollUpTop) && (y < scrollUpBottom)) { - scrollOffset -= lineCount; - update(); - - } else if ((y > scrollDownTop) && (y < scrollDownBottom)) { - scrollOffset += lineCount; - if (scrollOffset > 0) scrollOffset = 0; - update(); - } - } - }); } - public void update() { - //System.out.println("PdeEditorConsole.update"); - Graphics g = this.getGraphics(); - if (g != null) paint(g); - } - - public void update(Graphics g) { - paint(g); - } - - public void paint(Graphics screen) { - if (screen == null) return; - - //systemOut.println("paint()"); - if (bgColor == null) { - - bgColor = PdeBase.getColor("editor.console.bgcolor", - new Color(26, 26, 26)); - fgColorOut = PdeBase.getColor("editor.console.fgcolor.output", - new Color(153, 153, 153)); - fgColorErr = PdeBase.getColor("editor.console.fgcolor.error", - new Color(204, 51, 0)); - scrollEnabledColor = - PdeBase.getColor("editor.console.scrollbox.color.enabled", - new Color(51, 51, 51)); - scrollDisabledColor = - PdeBase.getColor("editor.console.scrollbox.color.disabled", - new Color(35, 35, 35)); - screen.setFont(font); - metrics = screen.getFontMetrics(); - ascent = metrics.getAscent(); - leading = ascent + metrics.getDescent(); - //System.out.println(ascent + " " + leading); - } - - Dimension size = getSize(); - if ((size.width != sizeW) || (size.height != sizeH)) { - // component has been resized - - if ((size.width > imageW) || (size.height > imageH)) { - // nix the image and recreate, it's too small - offscreen = null; - - } else { - // who cares, just resize - sizeW = size.width; - sizeH = size.height; - //setButtonBounds(); - } - } - //systemErr.println("size h, w = " + sizeW + " " + sizeH); - - if (offscreen == null) { - sizeW = size.width; - sizeH = size.height; - //setButtonBounds(); - imageW = sizeW; - imageH = sizeH; - offscreen = createImage(imageW, imageH); - } - - if (offscreen == null) return; - Graphics g = offscreen.getGraphics(); - /* - if (font == null) { - font = PdeBase.getFont("editor.console.font", - new Font("Monospaced", Font.PLAIN, 11)); - //font = new Font("SansSerif", Font.PLAIN, 10); - g.setFont(font); - metrics = g.getFontMetrics(); - ascent = metrics.getAscent(); - } - */ - g.setFont(font); - - g.setColor(bgColor); - g.fillRect(0, 0, imageW, imageH); - - for (int i = 0; i < lineCount; i++) { - //int ii = (firstLine + i) + scrollOffset; - int ii = (firstLine + i + 1) + scrollOffset; - while (ii < 0) ii += maxLineCount; - if (ii >= maxLineCount) ii = ii % maxLineCount; - - g.setColor(isError[ii] ? fgColorErr : fgColorOut); - //System.out.println(leading); - g.drawString(lines[ii], HINSET, VINSET + ascent + i*ascent); - } - - final int SCROLL_INSET = 4; - final int SCROLL_SIZE = 12; - - scrollRight = sizeW - SCROLL_INSET; - scrollLeft = scrollRight - SCROLL_SIZE; - - scrollUpTop = SCROLL_INSET; - scrollUpBottom = scrollUpTop + SCROLL_SIZE; - - scrollDownBottom = sizeH - SCROLL_INSET; - if ((PdeBase.platform == PdeBase.MACOSX) || - (PdeBase.platform == PdeBase.MACOS9)) { - scrollDownBottom -= 16; // because size boxes intrude - } - scrollDownTop = scrollDownBottom - SCROLL_SIZE; - - g.setColor(scrollEnabledColor); - g.fillRect(scrollLeft, scrollUpTop, SCROLL_SIZE, SCROLL_SIZE); - g.setColor((scrollOffset != 0) ? - scrollEnabledColor : scrollDisabledColor); - g.fillRect(scrollLeft, scrollDownTop, SCROLL_SIZE, SCROLL_SIZE); - - screen.drawImage(offscreen, 0, 0, null); - } - public void write(byte b[], int offset, int length, boolean err) { - synchronized (cline) { - if ((clength > 0) && (err != cerror)) { + +// synchronized (cerror) { // has to be an object... + if (err != cerror) { // advance the line because switching between err/out streams - message(new String(cline, 0, clength), cerror, true); - clength = 0; - } - int last = offset+length - 1; - // starting a new line, so set its output type to out or err - if (clength == 0) cerror = err; - for (int i = offset; i <= last; i++) { - if (b[i] == CR) { // mac CR or win CRLF - if ((i != last) && (b[i+1] == LF)) { - // if windows CRLF, skip the LF too - i++; - } - message(new String(cline, 0, clength), cerror, true); - clength = 0; - - } else if (b[i] == LF) { // unix LF only - message(new String(cline, 0, clength), cerror, true); - clength = 0; - - } else if (b[i] == TAB) { - if (clength + TAB_SIZE > cline.length) { - byte temp[] = new byte[clength * 2]; - System.arraycopy(cline, 0, temp, 0, clength); - cline = temp; - } - for (int m = 0; m < TAB_SIZE; m++) { - cline[clength++] = ' '; - } - - } else { - //systemOut.println(clength + " " + cline.length + " " + ((char) b[i])); - if (cline.length == clength) { - //systemOut.println("expanding to " + (clength*2)); - byte temp[] = new byte[clength * 2]; - System.arraycopy(cline, 0, temp, 0, clength); - cline = temp; - } - cline[clength++] = b[i]; - } - } - if (clength != 0) { - message(new String(cline, 0, clength), cerror, false); - } - } + // 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; +// } + } + + public void message(String what, boolean err, boolean advance) { // under osx, suppress the spew about the serial port // to avoid an error every time someone loads their app @@ -314,61 +156,47 @@ public class PdeEditorConsole extends Component { if (what.equals("Caught java.lang.UnsatisfiedLinkError: readRegistrySerial while loading driver com.sun.comm.SolarisDriver")) return; } - int currentLine = (firstLine + lineCount) % maxLineCount; - lines[currentLine] = what; - isError[currentLine] = err; + // to console display + appendText(what, err); + + if (err) { + systemErr.print(what); + } else { + systemOut.print(what); + } if (advance) { - firstLine = (firstLine + 1) % maxLineCount; - //systemOut.println((err ? "ERR: " : "OUT: ") + what); + appendText("\n", err); if (err) { - systemErr.println(what); + systemErr.println(); } else { - systemOut.println(what); + systemOut.println(); } - scrollOffset = 0; - // added so for continual update of lines - currentLine = (firstLine + lineCount) % maxLineCount; - lines[currentLine] = ""; // make sure it's clear } - update(); } - public Dimension getPreferredSize() { - //systemOut.println("pref'd sizde"); - if (font == null) { - font = PdeBase.getFont("editor.console.font", - new Font("Monospaced", Font.PLAIN, 11)); - //font = new Font("SansSerif", Font.PLAIN, 10); - //g.setFont(font); - //metrics = g.getFontMetrics(); - metrics = Toolkit.getDefaultToolkit().getFontMetrics(font); - ascent = metrics.getAscent(); + private void appendText(String text, boolean err) + { + try { + consoleDoc.insertString(consoleDoc.getLength(), text, err ? errStyle : stdStyle); + } + catch(Exception e) {} } - //if (ascent == 0) { - // no useful font information yet - //System.out.println("PdeEditorConsole: setting size w/o metrics"); - //return new Dimension(300, 84); - //} else { - //System.out.println("PdeEditorConsole: got metrics, setting size" + - // new Dimension(300 + HINSET*2, - // leading*lineCount + VINSET*2)); - return new Dimension(300 + HINSET*2, - ascent*lineCount + VINSET*2); - //} + public Dimension getPreferredSize() { + return getMinimumSize(); } public Dimension getMinimumSize() { - return getPreferredSize(); + return new Dimension(600, PdeEditor.GRID_SIZE * 3); } public Dimension getMaximumSize() { - Dimension pref = getPreferredSize(); - return new Dimension(3000, pref.width); - } + return new Dimension(3000, PdeEditor.GRID_SIZE * 3); } + +} class PdeEditorConsoleStream extends OutputStream { PdeEditorConsole parent;