diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 4625917e2..89768a6e0 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -242,7 +242,7 @@ public abstract class Editor extends JFrame implements RunnerListener { toolbar = createToolbar(); upper.add(toolbar); - header = new EditorHeader(this); + header = createHeader(); upper.add(header); textarea = createTextArea(); @@ -593,6 +593,11 @@ public abstract class Editor extends JFrame implements RunnerListener { // } + public EditorHeader createHeader() { + return new EditorHeader(this); + } + + abstract public EditorToolbar createToolbar(); diff --git a/app/src/processing/app/EditorHeader.java b/app/src/processing/app/EditorHeader.java index 2462627e5..e74979428 100644 --- a/app/src/processing/app/EditorHeader.java +++ b/app/src/processing/app/EditorHeader.java @@ -469,8 +469,8 @@ public class EditorHeader extends JComponent { */ } JMenuItem item; - InputMap mInputMap = editor.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - ActionMap mActionMap = editor.getRootPane().getActionMap(); + InputMap inputMap = editor.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + ActionMap actionMap = editor.getRootPane().getActionMap(); Action action; String mapKey; KeyStroke keyStroke; @@ -515,8 +515,8 @@ public class EditorHeader extends JComponent { }; mapKey = "editor.header.new_tab"; keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.SHORTCUT_SHIFT_KEY_MASK); - mInputMap.put(keyStroke, mapKey); - mActionMap.put(mapKey, action); + inputMap.put(keyStroke, mapKey); + actionMap.put(mapKey, action); item.addActionListener(action); menu.add(item); @@ -553,8 +553,8 @@ public class EditorHeader extends JComponent { }; mapKey = "editor.header.delete"; keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit.SHORTCUT_ALT_KEY_MASK); - mInputMap.put(keyStroke, mapKey); - mActionMap.put(mapKey, action); + inputMap.put(keyStroke, mapKey); + actionMap.put(mapKey, action); item.addActionListener(action); menu.add(item); @@ -572,8 +572,8 @@ public class EditorHeader extends JComponent { }; mapKey = "editor.header.previous_tab"; keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, Toolkit.SHORTCUT_ALT_KEY_MASK); - mInputMap.put(keyStroke, mapKey); - mActionMap.put(mapKey, action); + inputMap.put(keyStroke, mapKey); + actionMap.put(mapKey, action); item.addActionListener(action); menu.add(item); @@ -588,8 +588,8 @@ public class EditorHeader extends JComponent { }; mapKey = "editor.header.next_tab"; keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, Toolkit.SHORTCUT_ALT_KEY_MASK); - mInputMap.put(keyStroke, mapKey); - mActionMap.put(mapKey, action); + inputMap.put(keyStroke, mapKey); + actionMap.put(mapKey, action); item.addActionListener(action); menu.add(item); diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 09fc78305..a4950f796 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -327,27 +327,26 @@ public class Sketch { String oldName = (current.isExtension(mode.getDefaultExtension())) ? current.getPrettyName() : current.getFileName(); // editor.status.edit(prompt, oldName); - promptForTabName(prompt+":", oldName); + promptForTabName(prompt + ":", oldName); } - + + /** * Displays a dialog for renaming or creating a new tab - * @param prompt - msg to display - * @param oldName */ protected void promptForTabName(String prompt, String oldName) { final JTextField field = new JTextField(oldName); - + field.addKeyListener(new KeyAdapter() { // Forget ESC, the JDialog should handle it. - // Use keyTyped to catch when the feller is actually added to the text - // field. With keyTyped, as opposed to keyPressed, the keyCode will be - // zero, even if it's enter or backspace or whatever, so the keychar + // Use keyTyped to catch when the feller is actually added to the text + // field. With keyTyped, as opposed to keyPressed, the keyCode will be + // zero, even if it's enter or backspace or whatever, so the keychar // should be used instead. Grr. public void keyTyped(KeyEvent event) { //System.out.println("got event " + event); char ch = event.getKeyChar(); - if ((ch == '_') || (ch == '.') || // allow.pde and .java + if ((ch == '_') || (ch == '.') || // allow.pde and .java (('A' <= ch) && (ch <= 'Z')) || (('a' <= ch) && (ch <= 'z'))) { // These events are allowed straight through. } else if (ch == ' ') { @@ -363,13 +362,13 @@ public class Sketch { // getSelectionStart means that it *will be* the first // char, because the selection is about to be replaced // with whatever is typed. - if (field.getCaretPosition() == 0 || + if (field.getCaretPosition() == 0 || field.getSelectionStart() == 0) { // number not allowed as first digit event.consume(); } } else if (ch == KeyEvent.VK_ENTER) { - // Slightly ugly hack that ensures OK button of the dialog consumes + // Slightly ugly hack that ensures OK button of the dialog consumes // the Enter key event. Since the text field is the default component // in the dialog, OK doesn't consume Enter key event, by default. Container parent = field.getParent(); @@ -377,14 +376,14 @@ public class Sketch { parent = parent.getParent(); } JOptionPane pane = (JOptionPane) parent; - final JPanel pnlBottom = (JPanel) + final JPanel pnlBottom = (JPanel) pane.getComponent(pane.getComponentCount() - 1); for (int i = 0; i < pnlBottom.getComponents().length; i++) { Component component = pnlBottom.getComponents()[i]; if (component instanceof JButton) { final JButton okButton = (JButton) component; if (okButton.getText().equalsIgnoreCase("OK")) { - ActionListener[] actionListeners = + ActionListener[] actionListeners = okButton.getActionListeners(); if (actionListeners.length > 0) { actionListeners[0].actionPerformed(null); @@ -621,12 +620,12 @@ public class Sketch { } // don't allow if untitled - if (currentIndex == 0 && isUntitled()) { + if (currentIndex == 0 && isUntitled()) { Base.showMessage(Language.text("delete.messages.cannot_delete"), Language.text("delete.messages.cannot_delete.description")); return; } - + // confirm deletion with user, yes/no Object[] options = { Language.text("prompt.ok"), Language.text("prompt.cancel") }; String prompt = (currentIndex == 0) ? @@ -798,7 +797,7 @@ public class Sketch { protected boolean saveAs() throws IOException { String newParentDir = null; String newName = null; - + final String oldName2 = folder.getName(); // TODO rewrite this to use shared version from PApplet final String PROMPT = Language.text("save"); @@ -934,12 +933,12 @@ public class Sketch { return true; } }); - + final File newFolder2 = newFolder; final File[] copyItems2 = copyItems; - final String newName2 = newName; - + final String newName2 = newName; + // Create a new event dispatch thread- to display ProgressBar // while Saving As javax.swing.SwingUtilities.invokeLater(new Runnable() { @@ -947,8 +946,8 @@ public class Sketch { new ProgressFrame(copyItems2, newFolder2, oldName2, newName2, editor); } }); - - + + // save the other tabs to their new location for (int i = 1; i < codeCount; i++) { File newFile = new File(newFolder, code[i].getFileName()); @@ -985,7 +984,7 @@ public class Sketch { */ protected void updateInternal(String sketchName, File sketchFolder) { // reset all the state information for the sketch object - String oldPath = getMainFilePath(); + String oldPath = getMainFilePath(); primaryFile = code[0].getFile(); // String newPath = getMainFilePath(); // editor.base.renameRecent(oldPath, newPath); diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 500f41072..5ed28ce6a 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -87,9 +87,8 @@ public class JavaEditor extends Editor { protected JPanel consoleProblemsPane; protected XQErrorTable errorTable; - // TODO how is this different from hasJavaTabs? -// public boolean compilationCheckEnabled = true; private boolean hasJavaTabs; + private boolean javaTabWarned; protected JavaEditor(Base base, String path, EditorState state, Mode mode) { @@ -151,9 +150,58 @@ public class JavaEditor extends Editor { getJavaTextArea().setECSandThemeforTextArea(errorCheckerService, jmode); - addXQModeUI(); -// debugToolbarEnabled = new AtomicBoolean(false); - //log("Sketch Path: " + path); + // Adding ErrorBar + JPanel textAndError = new JPanel(); + Box box = (Box) textarea.getParent(); + box.remove(2); // Remove textArea from it's container, i.e Box + textAndError.setLayout(new BorderLayout()); + errorBar = new ErrorBar(this, textarea.getMinimumSize().height, jmode); + textAndError.add(errorBar, BorderLayout.EAST); + textarea.setBounds(0, 0, errorBar.getX() - 1, textarea.getHeight()); + textAndError.add(textarea); + box.add(textAndError); + + // Adding Error Table in a scroll pane + errorTableScrollPane = new JScrollPane(); + errorTable = new XQErrorTable(errorCheckerService); + // errorTableScrollPane.setBorder(new EmptyBorder(2, 2, 2, 2)); + errorTableScrollPane.setBorder(new EtchedBorder()); + errorTableScrollPane.setViewportView(errorTable); + + // Adding toggle console button + consolePanel.remove(2); + JPanel lineStatusPanel = new JPanel(); + lineStatusPanel.setLayout(new BorderLayout()); + btnShowConsole = new XQConsoleToggle(this, Language.text("editor.footer.console"), lineStatus.getHeight()); + btnShowErrors = new XQConsoleToggle(this, Language.text("editor.footer.errors"), lineStatus.getHeight()); + btnShowConsole.addMouseListener(btnShowConsole); + btnShowErrors.addMouseListener(btnShowErrors); + + JPanel toggleButtonPanel = new JPanel(new BorderLayout()); + toggleButtonPanel.add(btnShowConsole, BorderLayout.EAST); + toggleButtonPanel.add(btnShowErrors, BorderLayout.WEST); + lineStatusPanel.add(toggleButtonPanel, BorderLayout.EAST); + lineStatus.setBounds(0, 0, toggleButtonPanel.getX() - 1, + toggleButtonPanel.getHeight()); + lineStatusPanel.add(lineStatus); + consolePanel.add(lineStatusPanel, BorderLayout.SOUTH); + lineStatusPanel.repaint(); + + // Adding JPanel with CardLayout for Console/Problems Toggle + consolePanel.remove(1); + consoleProblemsPane = new JPanel(new CardLayout()); + consoleProblemsPane.add(errorTableScrollPane, Language.text("editor.footer.errors")); + consoleProblemsPane.add(console, Language.text("editor.footer.console")); + consolePanel.add(consoleProblemsPane, BorderLayout.CENTER); + + // ensure completion gets hidden on editor losing focus + addWindowFocusListener(new WindowFocusListener() { + public void windowLostFocus(WindowEvent e) { + getJavaTextArea().hideSuggestion(); + } + + public void windowGainedFocus(WindowEvent e) { } + }); } @@ -167,6 +215,17 @@ public class JavaEditor extends Editor { } + public EditorHeader createHeader() { + return new EditorHeader(this) { + public void rebuild() { + super.rebuild(); + System.out.println("checking for Java tabs"); + hasJavaTabs = checkForJavaTabs(); + } + }; + } + + public Formatter createFormatter() { return new AutoFormat(); } @@ -1115,11 +1174,13 @@ public class JavaEditor extends Editor { } + /* public void handleSave() { // toolbar.activate(JavaToolbar.SAVE); super.handleSave(true); // toolbar.deactivate(JavaToolbar.SAVE); } + */ public boolean handleSaveAs() { @@ -1139,15 +1200,13 @@ public class JavaEditor extends Editor { debugger.setBreakpoint(line); } // add breakpoint marker comments to source file - for (int i = 0; i < getSketch().getCodeCount(); i++) { - addBreakpointComments(getSketch().getCode(i).getFileName()); + for (SketchCode code : getSketch().getCode()) { + addBreakpointComments(code.getFileName()); } // set new name of variable inspector - inspector.setTitle(getSketch().getName()); + //inspector.setTitle(getSketch().getName()); } - // if file location has changed, update autosaver - // autosaver.reloadAutosaveDir(); return saved; } @@ -1179,7 +1238,6 @@ public class JavaEditor extends Editor { // commented out, then this will be a problem. String[] list = lib.getSpecifiedImports(); // ask the library for its imports if (list == null) { - // Default to old behavior and load each package in the primary jar list = Base.packageListFromClassPath(lib.getJarPath()); } @@ -1220,79 +1278,6 @@ public class JavaEditor extends Editor { // Additions from PDE X, Debug Mode, Twerk Mode... - private void addXQModeUI(){ - // Adding ErrorBar - JPanel textAndError = new JPanel(); - Box box = (Box) textarea.getParent(); - box.remove(2); // Remove textArea from it's container, i.e Box - textAndError.setLayout(new BorderLayout()); - errorBar = new ErrorBar(this, textarea.getMinimumSize().height, jmode); - textAndError.add(errorBar, BorderLayout.EAST); - textarea.setBounds(0, 0, errorBar.getX() - 1, textarea.getHeight()); - textAndError.add(textarea); - box.add(textAndError); - - // Adding Error Table in a scroll pane - errorTableScrollPane = new JScrollPane(); - errorTable = new XQErrorTable(errorCheckerService); - // errorTableScrollPane.setBorder(new EmptyBorder(2, 2, 2, 2)); - errorTableScrollPane.setBorder(new EtchedBorder()); - errorTableScrollPane.setViewportView(errorTable); - - // Adding toggle console button - consolePanel.remove(2); - JPanel lineStatusPanel = new JPanel(); - lineStatusPanel.setLayout(new BorderLayout()); - btnShowConsole = new XQConsoleToggle(this, - XQConsoleToggle.CONSOLE, lineStatus.getHeight()); - btnShowErrors = new XQConsoleToggle(this, - XQConsoleToggle.ERRORSLIST, lineStatus.getHeight()); - btnShowConsole.addMouseListener(btnShowConsole); - - // lineStatusPanel.add(btnShowConsole, BorderLayout.EAST); - // lineStatusPanel.add(btnShowErrors); - btnShowErrors.addMouseListener(btnShowErrors); - - JPanel toggleButtonPanel = new JPanel(new BorderLayout()); - toggleButtonPanel.add(btnShowConsole, BorderLayout.EAST); - toggleButtonPanel.add(btnShowErrors, BorderLayout.WEST); - lineStatusPanel.add(toggleButtonPanel, BorderLayout.EAST); - lineStatus.setBounds(0, 0, toggleButtonPanel.getX() - 1, - toggleButtonPanel.getHeight()); - lineStatusPanel.add(lineStatus); - consolePanel.add(lineStatusPanel, BorderLayout.SOUTH); - lineStatusPanel.repaint(); - - // Adding JPanel with CardLayout for Console/Problems Toggle - consolePanel.remove(1); - consoleProblemsPane = new JPanel(new CardLayout()); - consoleProblemsPane.add(errorTableScrollPane, XQConsoleToggle.ERRORSLIST); - consoleProblemsPane.add(console, XQConsoleToggle.CONSOLE); - consolePanel.add(consoleProblemsPane, BorderLayout.CENTER); - - // ensure completion gets hidden on editor losing focus - addWindowFocusListener(new WindowFocusListener() { - public void windowLostFocus(WindowEvent e) { - getJavaTextArea().hideSuggestion(); - } - - public void windowGainedFocus(WindowEvent e) { } - }); - } - -// /** -// * Event handler called when closing the editor window. Kills the variable -// * inspector window. -// * -// * @param e the event object -// */ -// protected void onWindowClosing(WindowEvent e) { -// // remove var.inspector -// vi.dispose(); -// // quit running debug session -// dbg.stopDebug(); -// } - /** * Used instead of the windowClosing event handler, since it's not called on * mode switch. Called when closing the editor window. Stops running debug @@ -2608,10 +2593,13 @@ public class JavaEditor extends Editor { private boolean checkForJavaTabs() { for (SketchCode code : getSketch().getCode()) { if (code.getExtension().equals("java")) { - final String msg = - getSketch().getName() + " contains .java tabs. Some editor " + - "features are not supported for .java tabs and will be disabled."; - Base.showWarning("Cannot debug advanced sketches", msg); + if (!javaTabWarned) { + System.out.println(getSketch().getName() + " contains .java tabs. "); + System.out.println("Some editor features (like completion " + + "and error checking) will be disabled."); + //Base.showWarning("Cannot debug advanced sketches", msg); + javaTabWarned = true; + } return true; } } diff --git a/java/src/processing/mode/java/pdex/ErrorCheckerService.java b/java/src/processing/mode/java/pdex/ErrorCheckerService.java index d7786957f..0bab8d53f 100644 --- a/java/src/processing/mode/java/pdex/ErrorCheckerService.java +++ b/java/src/processing/mode/java/pdex/ErrorCheckerService.java @@ -52,6 +52,7 @@ import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import processing.app.Base; import processing.app.Editor; import processing.app.EditorStatus; +import processing.app.Language; import processing.app.Library; import processing.app.SketchCode; import processing.app.syntax.SyntaxDocument; @@ -331,7 +332,7 @@ public class ErrorCheckerService implements Runnable { lastErrorCheckCall = System.currentTimeMillis(); if(!hasSyntaxErrors()) - editor.showProblemListView(XQConsoleToggle.CONSOLE); + editor.showProblemListView(Language.text("editor.footer.console")); // Make sure astGen has at least one CU to start with // This is when the loaded sketch already has syntax errors. // Completion wouldn't be complete, but it'd be still something diff --git a/java/src/processing/mode/java/pdex/XQConsoleToggle.java b/java/src/processing/mode/java/pdex/XQConsoleToggle.java index d256d4c39..13afaba4d 100644 --- a/java/src/processing/mode/java/pdex/XQConsoleToggle.java +++ b/java/src/processing/mode/java/pdex/XQConsoleToggle.java @@ -30,23 +30,20 @@ import java.awt.event.MouseListener; import javax.swing.JPanel; -import processing.app.Language; import processing.mode.java.JavaEditor; -/** - * Toggle Button displayed in the editor line status panel for toggling bewtween - * console and problems list. Glorified JPanel. - * - * @author Manindra Moharana <me@mkmoharana.com> - * - */ +/** + * Toggle Button displayed in the editor line status panel for toggling between + * console and problems list. Glorified JPanel. + * + * @author Manindra Moharana <me@mkmoharana.com> + * + */ public class XQConsoleToggle extends JPanel implements MouseListener { - public static final String CONSOLE = Language.text("editor.footer.console"), ERRORSLIST = Language.text("editor.footer.errors") ; - private boolean toggleText = true; private boolean toggleBG = true; - + /** * Height of the component */ @@ -75,8 +72,8 @@ public class XQConsoleToggle extends JPanel implements MouseListener { public void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + // On mouse hover, text and background color are changed. if (toggleBG) { g.setColor(new Color(0xff9DA7B0)); @@ -91,7 +88,7 @@ public class XQConsoleToggle extends JPanel implements MouseListener { g.fillRect(0, 0, 4, this.getHeight()); g.setColor(Color.WHITE); } - + g.drawString(buttonName, getWidth() / 2 + 2 // + 2 is a offset - getFontMetrics(getFont()).stringWidth(buttonName) / 2, this.getHeight() - 6); @@ -100,8 +97,8 @@ public class XQConsoleToggle extends JPanel implements MouseListener { g.fillRect(4, 0, 2, this.getHeight()); } } - - boolean drawMarker = false; + + boolean drawMarker = false; protected Color markerColor; public void updateMarker(boolean value, Color color){ drawMarker = value; diff --git a/todo.txt b/todo.txt index 1ce70702f..144956eba 100644 --- a/todo.txt +++ b/todo.txt @@ -14,6 +14,15 @@ X almost all of the debugger menu needs to disappear X https://github.com/processing/processing/issues/3267 X everything below toggle breakpoint, plus show/hide inspector X debugger button should show/hide toolbar buttons for step/continue +X name of toggle debug and variable inspector +X Enable Debugger (with or without a checkbox) +X "show inspector" "hide inspector" "variable inspector" (with a check) +o need unavailable/deactivate state for debug toolbar items +o or hide the tray when not debugging? Debug just a menu checkbox? +o fix hasJavaTabs() function +o almost always used as a negative, or tied to a 'return' from fxn +o name isn't tied to its function, but the symptom +X update hasJavaTabs on editor header rebuild in alpha 8 (but not confirmed in time) X "step" not working properly @@ -23,13 +32,6 @@ _ https://github.com/processing/processing/issues/3242 pdex -_ name of toggle debug and variable inspector -_ Enable Debugger (with or without a checkbox) -_ "show inspector" "hide inspector" "variable inspector" (with a check) -_ fix hasJavaTabs() function -_ almost always used as a negative, or tied to a 'return' from fxn -_ name isn't tied to its function, but the symptom -_ only checked once (when the editor is created) _ crashed on startup w/ JavaScript mode as default b/c PdeKeyListener not found _ because it's in the other ClassLoader, can no longer rely on it _ remove JavaMode.errorLogsEnabled and JavaEditor.writeErrorsToFile() @@ -49,9 +51,19 @@ _ move Library to LibraryContribution and into contrib? gui _ finish the gui _ https://github.com/processing/processing/issues/3072 -_ remove EditorLineStatus (we have line numbers) -_ editor window draws in stages (at least on OS X) on first view +_ implement the bottom half of the editor window +_ editor window draws in stages (at least on OS X) on first view _ the console/bottom area stays white until an additional repaint? +_ remove EditorLineStatus (we have line numbers) +_ need active state for the butterfly + + +gui (lower, not blocking for beta) +_ need 'actively pressed' version of 'play' and 'stop' +_ could do rollover as well, but do other apps use them? +_ iTunes has no rollover state but has a 'down' state +_ swaps to stop after release +_ remove focus border from the Variables window _ fonts are still really ugly (on non-retina) _ may need to drop use of Source Sans _ what do these do, and are we doing it already? @@ -61,13 +73,7 @@ _ how are we going to handle fonts for other languages? _ two new fonts have been added, other languages will need more _ need a decent sans with with Unicode coverage _ i.e. https://github.com/processing/processing/pull/3025 -_ need 'actively pressed' version of 'play' and 'stop' -_ could do rollover as well, but do other apps use them? -_ iTunes has no rollover state but has a 'down' state -_ swaps to stop after release -_ need unavailable/deactivate state for debug toolbar items -_ or hide the tray when not debugging? Debug just a menu checkbox? -_ need active state for the butterfly +_ deactivate step, continue, stop when not running? pde/build