mirror of
https://github.com/processing/processing4.git
synced 2026-02-03 21:59:20 +01:00
Merge pull request #4446 from JakubValtar/pdex-cleanup
Move PDEX listeners from JavaEditor to PDEX
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user