Move PDEX listeners from JavaEditor to PDEX

This commit is contained in:
Jakub Valtar
2016-05-08 19:39:39 +02:00
parent 53f4f16f59
commit 84ad45ec85
2 changed files with 209 additions and 171 deletions

View File

@@ -85,30 +85,6 @@ public class JavaEditor extends Editor {
debugger = new Debugger(this);
inspector = new VariableInspector(this);
// Add show usage option
JMenuItem showUsageItem = new JMenuItem(Language.text("editor.popup.show_usage"));
showUsageItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleShowUsage();
}
});
getTextArea().getRightClickPopup().add(showUsageItem);
// add refactor option
JMenuItem renameItem = new JMenuItem(Language.text("editor.popup.rename"));
renameItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleRefactor();
}
});
// TODO: Add support for word select on right click and rename.
// ta.customPainter.addMouseListener(new MouseAdapter() {
// public void mouseClicked(MouseEvent evt) {
// System.out.println(evt);
// }
// });
textarea.getRightClickPopup().add(renameItem);
// set action on frame close
// addWindowListener(new WindowAdapter() {
// @Override
@@ -117,7 +93,6 @@ public class JavaEditor extends Editor {
// }
// });
Toolkit.setMenuMnemonics(textarea.getRightClickPopup());
// // load settings from theme.txt
// breakpointColor = mode.getColor("breakpoint.bgcolor");
@@ -153,6 +128,8 @@ public class JavaEditor extends Editor {
initPDEX();
Toolkit.setMenuMnemonics(textarea.getRightClickPopup());
// ensure completion is hidden when editor loses focus
addWindowFocusListener(new WindowFocusListener() {
public void windowLostFocus(WindowEvent e) {
@@ -173,60 +150,11 @@ public class JavaEditor extends Editor {
public PdePreprocessor createPreprocessor(final String sketchName) {
return new PdePreprocessor(sketchName);
}
protected void initPDEX() {
preprocessingService = new PreprocessingService(this);
pdex = new PDEX(this, preprocessingService);
// Add ctrl+click listener
getJavaTextArea().getPainter().addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent evt) {
if (evt.getButton() == MouseEvent.BUTTON1) {
if ((evt.isControlDown() && !Platform.isMacOS()) || evt.isMetaDown()) {
handleCtrlClick(evt);
}
} else if (evt.getButton() == MouseEvent.BUTTON2) {
handleCtrlClick(evt);
}
}
});
sketchChanged();
for (SketchCode code : getSketch().getCode()) {
Document document = code.getDocument();
addDocumentListener(document);
}
}
public void addDocumentListener(Document doc) {
if (doc != null) doc.addDocumentListener(sketchChangedListener);
}
protected final DocumentListener sketchChangedListener = new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
sketchChanged();
}
@Override
public void removeUpdate(DocumentEvent e) {
sketchChanged();
}
@Override
public void changedUpdate(DocumentEvent e) {
sketchChanged();
}
};
protected void sketchChanged() {
pdex.notifySketchChanged();
preprocessingService.notifySketchChanged();
}
@@ -257,7 +185,7 @@ public class JavaEditor extends Editor {
if (preprocessingService != null) {
if (hasJavaTabsChanged) {
preprocessingService.handleHasJavaTabsChange(hasJavaTabs);
pdex.handleHasJavaTabsChange(hasJavaTabs);
pdex.hasJavaTabsChanged(hasJavaTabs);
if (hasJavaTabs) {
setProblemList(Collections.emptyList());
}
@@ -266,7 +194,7 @@ public class JavaEditor extends Editor {
int currentTabCount = sketch.getCodeCount();
if (currentTabCount != previousTabCount) {
previousTabCount = currentTabCount;
sketchChanged();
pdex.sketchChanged();
}
}
}
@@ -2298,8 +2226,8 @@ public class JavaEditor extends Editor {
super.setCode(code);
Document newDoc = code.getDocument();
if (oldDoc != newDoc && preprocessingService != null) {
addDocumentListener(newDoc);
if (oldDoc != newDoc && pdex != null) {
pdex.documentChanged(newDoc);
}
// set line background colors for tab
@@ -2717,36 +2645,6 @@ public class JavaEditor extends Editor {
}
/** Handle refactor operation */
private void handleRefactor() {
int startOffset = getSelectionStart();
int stopOffset = getSelectionStop();
int tabIndex = sketch.getCurrentCodeIndex();
pdex.handleRename(tabIndex, startOffset, stopOffset);
}
/** Handle show usage operation */
private void handleShowUsage() {
int startOffset = getSelectionStart();
int stopOffset = getSelectionStop();
int tabIndex = sketch.getCurrentCodeIndex();
pdex.handleShowUsage(tabIndex, startOffset, stopOffset);
}
/** Handle ctrl+click */
private void handleCtrlClick(MouseEvent evt) {
int off = getJavaTextArea().xyToOffset(evt.getX(), evt.getY());
if (off < 0) return;
int tabIndex = sketch.getCurrentCodeIndex();
pdex.handleCtrlClick(tabIndex, off);
}
public boolean hasJavaTabs() {
return hasJavaTabs;
}
@@ -2781,7 +2679,7 @@ public class JavaEditor extends Editor {
jmode.loadPreferences();
Messages.log("Applying prefs");
// trigger it once to refresh UI
sketchChanged();
pdex.preferencesChanged();
}
}

View File

@@ -24,6 +24,10 @@ import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
@@ -47,18 +51,24 @@ import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import processing.app.Language;
import processing.app.Messages;
import processing.app.Platform;
import processing.app.Sketch;
import processing.app.SketchCode;
import processing.app.syntax.SyntaxDocument;
@@ -78,6 +88,7 @@ public class PDEX {
private ErrorChecker errorChecker;
private InspectMode inspectMode;
private ShowUsage showUsage;
private Rename rename;
private DebugTree debugTree;
@@ -94,36 +105,57 @@ public class PDEX {
errorChecker = new ErrorChecker(editor, pps);
inspectMode = new InspectMode(editor, pps);
showUsage = new ShowUsage(editor, pps);
rename = new Rename(editor);
rename = new Rename(editor, pps);
if (SHOW_DEBUG_TREE) {
debugTree = new DebugTree(editor, pps);
}
for (SketchCode code : editor.getSketch().getCode()) {
Document document = code.getDocument();
addDocumentListener(document);
}
sketchChanged();
}
public void handleShowUsage(int tabIndex, int startTabOffset, int stopTabOffset) {
Messages.log("* handleShowUsage");
if (!enabled) return; // show usage disabled if java tabs
pps.whenDoneBlocking(ps -> showUsage.findUsageAndUpdateTree(ps, tabIndex, startTabOffset, stopTabOffset));
public void addDocumentListener(Document doc) {
if (doc != null) doc.addDocumentListener(sketchChangedListener);
}
public void handleRename(int tabIndex, int startTabOffset, int stopTabOffset) {
Messages.log("* handleRename");
if (!enabled) return; // refactoring disabled w/ java tabs
pps.whenDoneBlocking(ps -> rename.handleRename(ps, tabIndex, startTabOffset, stopTabOffset));
protected final DocumentListener sketchChangedListener = new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
sketchChanged();
}
@Override
public void removeUpdate(DocumentEvent e) {
sketchChanged();
}
@Override
public void changedUpdate(DocumentEvent e) {
sketchChanged();
}
};
public void sketchChanged() {
errorChecker.notifySketchChanged();
pps.notifySketchChanged();
}
public void handleCtrlClick(int tabIndex, int offset) {
Messages.log("* handleCtrlClick");
if (!enabled) return; // disabled w/ java tabs
pps.whenDoneBlocking(ps -> handleCtrlClick(ps, tabIndex, offset));
public void preferencesChanged() {
sketchChanged();
}
public void handleHasJavaTabsChange(boolean hasJavaTabs) {
public void hasJavaTabsChanged(boolean hasJavaTabs) {
enabled = !hasJavaTabs;
if (!enabled) {
showUsage.hide();
@@ -131,12 +163,8 @@ public class PDEX {
}
public void notifySketchChanged() {
errorChecker.notifySketchChanged();
}
public void dispose() {
inspectMode.dispose();
errorChecker.dispose();
showUsage.dispose();
rename.dispose();
@@ -146,53 +174,133 @@ public class PDEX {
}
// Thread: worker
private void handleCtrlClick(PreprocessedSketch ps, int tabIndex, int offset) {
ASTNode root = ps.compilationUnit;
int javaOffset = ps.tabOffsetToJavaOffset(tabIndex, offset);
public void documentChanged(Document newDoc) {
addDocumentListener(newDoc);
}
SimpleName simpleName = getSimpleNameAt(root, javaOffset, javaOffset);
if (simpleName == null) {
Messages.log("no simple name found at click location");
return;
}
private class InspectMode {
IBinding binding = resolveBinding(simpleName);
if (binding == null) {
Messages.log("binding not resolved");
return;
}
boolean isMouseDown;
boolean isCtrlDown;
boolean isMetaDown;
boolean inspectModeEnabled;
String key = binding.getKey();
ASTNode decl = ps.compilationUnit.findDeclaringNode(key);
if (decl == null) {
Messages.log("decl not found, showing usage instead");
showUsage.findUsageAndUpdateTree(ps, binding);
return;
}
JavaEditor editor;
PreprocessingService pps;
SimpleName declName = null;
switch (binding.getKind()) {
case IBinding.TYPE: declName = ((TypeDeclaration) decl).getName(); break;
case IBinding.METHOD: declName = ((MethodDeclaration) decl).getName(); break;
case IBinding.VARIABLE: declName = ((VariableDeclaration) decl).getName(); break;
}
if (declName == null) {
Messages.log("decl name not found " + decl);
return;
}
InspectMode(JavaEditor editor, PreprocessingService pps) {
this.editor = editor;
this.pps = pps;
if (declName.equals(simpleName)) {
showUsage.findUsageAndUpdateTree(ps, binding);
} else {
Messages.log("found declaration, offset " + decl.getStartPosition() + ", name: " + declName);
SketchInterval si = ps.mapJavaToSketch(declName);
if (!ps.inRange(si)) return;
EventQueue.invokeLater(() -> {
editor.highlight(si.tabIndex, si.startTabOffset, si.stopTabOffset);
// Add ctrl+click listener
editor.getJavaTextArea().getPainter().addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
isMouseDown = true;
}
@Override
public void mouseReleased(MouseEvent evt) {
isMouseDown = false;
if (inspectModeEnabled && evt.getButton() == MouseEvent.BUTTON1) {
handleInspect(evt);
} else if (!inspectModeEnabled && evt.getButton() == MouseEvent.BUTTON2) {
handleInspect(evt);
}
checkInspectMode();
}
});
editor.getJavaTextArea().addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
isMetaDown = isMetaDown | e.getKeyCode() == KeyEvent.VK_META;
isCtrlDown = isCtrlDown | e.getKeyCode() == KeyEvent.VK_CONTROL;
if (!inspectModeEnabled) checkInspectMode();
}
@Override
public void keyReleased(KeyEvent e) {
isMetaDown = isMetaDown & e.getKeyCode() != KeyEvent.VK_META;
isCtrlDown = isCtrlDown & e.getKeyCode() != KeyEvent.VK_CONTROL;
if (inspectModeEnabled) checkInspectMode();
}
});
}
void checkInspectMode() {
System.out.println(isMouseDown + " " + isCtrlDown + " " + isMetaDown);
inspectModeEnabled = !isMouseDown && (isCtrlDown && !Platform.isMacOS()) || isMetaDown;
}
// Thread: EDT
void handleInspect(MouseEvent evt) {
int off = editor.getJavaTextArea().xyToOffset(evt.getX(), evt.getY());
if (off < 0) return;
int tabIndex = editor.getSketch().getCurrentCodeIndex();
pps.whenDoneBlocking(ps -> handleInspect(ps, tabIndex, off));
}
// Thread: worker
private void handleInspect(PreprocessedSketch ps, int tabIndex, int offset) {
ASTNode root = ps.compilationUnit;
int javaOffset = ps.tabOffsetToJavaOffset(tabIndex, offset);
SimpleName simpleName = getSimpleNameAt(root, javaOffset, javaOffset);
if (simpleName == null) {
Messages.log("no simple name found at click location");
return;
}
IBinding binding = resolveBinding(simpleName);
if (binding == null) {
Messages.log("binding not resolved");
return;
}
String key = binding.getKey();
ASTNode decl = ps.compilationUnit.findDeclaringNode(key);
if (decl == null) {
Messages.log("decl not found, showing usage instead");
showUsage.findUsageAndUpdateTree(ps, binding);
return;
}
SimpleName declName = null;
switch (binding.getKind()) {
case IBinding.TYPE: declName = ((TypeDeclaration) decl).getName(); break;
case IBinding.METHOD: declName = ((MethodDeclaration) decl).getName(); break;
case IBinding.VARIABLE: declName = ((VariableDeclaration) decl).getName(); break;
}
if (declName == null) {
Messages.log("decl name not found " + decl);
return;
}
if (declName.equals(simpleName)) {
showUsage.findUsageAndUpdateTree(ps, binding);
} else {
Messages.log("found declaration, offset " + decl.getStartPosition() + ", name: " + declName);
SketchInterval si = ps.mapJavaToSketch(declName);
if (!ps.inRange(si)) return;
EventQueue.invokeLater(() -> {
editor.highlight(si.tabIndex, si.startTabOffset, si.stopTabOffset);
});
}
}
void dispose() {
// Nothing to do
}
}
@@ -214,6 +322,11 @@ public class PDEX {
this.editor = editor;
this.pps = pps;
// Add show usage option
JMenuItem showUsageItem = new JMenuItem(Language.text("editor.popup.show_usage"));
showUsageItem.addActionListener(e -> handleShowUsage());
editor.getTextArea().getRightClickPopup().add(showUsageItem);
reloadListener = this::reloadShowUsage;
{ // Show Usage window
@@ -265,9 +378,19 @@ public class PDEX {
}
// Thread: EDT
void handleShowUsage() {
int startOffset = editor.getSelectionStart();
int stopOffset = editor.getSelectionStop();
int tabIndex = editor.getSketch().getCurrentCodeIndex();
pps.whenDoneBlocking(ps -> handleShowUsage(ps, tabIndex, startOffset, stopOffset));
}
// Thread: worker
void findUsageAndUpdateTree(PreprocessedSketch ps, int tabIndex,
int startTabOffset, int stopTabOffset) {
void handleShowUsage(PreprocessedSketch ps, int tabIndex,
int startTabOffset, int stopTabOffset) {
// Map offsets
int startJavaOffset = ps.tabOffsetToJavaOffset(tabIndex, startTabOffset);
int stopJavaOffset = ps.tabOffsetToJavaOffset(tabIndex, stopTabOffset);
@@ -484,13 +607,21 @@ public class PDEX {
final JLabel oldNameLabel;
final JavaEditor editor;
final PreprocessingService pps;
IBinding binding;
PreprocessedSketch ps;
Rename(JavaEditor editor) {
Rename(JavaEditor editor, PreprocessingService pps) {
this.editor = editor;
this.pps = pps;
// Add rename option
JMenuItem renameItem = new JMenuItem(Language.text("editor.popup.rename"));
renameItem.addActionListener(e -> handleRename());
editor.getTextArea().getRightClickPopup().add(renameItem);
window = new JDialog(editor);
window.setTitle("Enter new name:");
@@ -567,6 +698,15 @@ public class PDEX {
}
// Thread: EDT
void handleRename() {
int startOffset = editor.getSelectionStart();
int stopOffset = editor.getSelectionStop();
int tabIndex = editor.getSketch().getCurrentCodeIndex();
pps.whenDoneBlocking(ps -> handleRename(ps, tabIndex, startOffset, stopOffset));
}
// Thread: worker
void handleRename(PreprocessedSketch ps, int tabIndex, int startTabOffset, int stopTabOffset) {