mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-09 08:58:48 +00:00
Painting underline fixes, Goto declaration fix (also freezing)
This commit is contained in:
@@ -435,7 +435,13 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
private Map<Openable, ABCExplorerDialog> abcExplorerDialogs = new WeakHashMap<>();
|
||||
|
||||
private Map<SWF, BreakpointListDialog> breakpointsListDialogs = new WeakHashMap<>();
|
||||
|
||||
private boolean loadingScrollPosEnabled = true;
|
||||
|
||||
public synchronized void setLoadingScrollPosEnabled(boolean loadingScrollPosEnabled) {
|
||||
this.loadingScrollPosEnabled = loadingScrollPosEnabled;
|
||||
}
|
||||
|
||||
public void savePins() {
|
||||
pinsPanel.save();
|
||||
}
|
||||
@@ -6361,16 +6367,19 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
folderPreviewPanel.setSelectedItems(folderItems);
|
||||
folderPreviewScrollBar.setValue(scrollValue);
|
||||
}
|
||||
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollPosStorage.loadScrollPos(oldItem);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (loadingScrollPosEnabled) {
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollPosStorage.loadScrollPos(oldItem);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void repaintTree() {
|
||||
tagTree.repaint();
|
||||
tagListTree.repaint();
|
||||
|
||||
@@ -1040,7 +1040,7 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setText(String t) {
|
||||
public void setText(String t) {
|
||||
super.setText(t);
|
||||
setCaretPosition(0);
|
||||
}
|
||||
@@ -1076,7 +1076,7 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setCaretPosition(int position) {
|
||||
public void setCaretPosition(int position) {
|
||||
super.setCaretPosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.jpexs.decompiler.flash.abc.usages.multinames.MultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.multinames.TraitMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.gui.AppDialog;
|
||||
import com.jpexs.decompiler.flash.gui.FasterScrollPane;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import java.awt.BorderLayout;
|
||||
@@ -36,6 +37,8 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
@@ -142,9 +145,17 @@ public class UsageFrame extends AppDialog implements MouseListener {
|
||||
} else {
|
||||
decompiledTextArea.gotoClassHeader();
|
||||
}
|
||||
Timer tim = new Timer();
|
||||
tim.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
Main.getMainFrame().getPanel().setLoadingScrollPosEnabled(true);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
Main.getMainFrame().getPanel().setLoadingScrollPosEnabled(false);
|
||||
if (decompiledTextArea.getClassIndex() == icu.getClassIndex() && abcPanel.abc == newAbc) {
|
||||
setTrait.run();
|
||||
} else {
|
||||
|
||||
@@ -21,19 +21,11 @@ import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
import com.jpexs.decompiler.flash.simpleparser.SimpleParser;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.KeyEventPostProcessor;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -76,8 +68,6 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
|
||||
|
||||
private Token lastUnderlined = null;
|
||||
|
||||
private static final HighlightPainter underLinePainter = new UnderLinePainter(new Color(0, 0, 255));
|
||||
|
||||
private LinkHandler linkHandler = this;
|
||||
|
||||
private Point lastCursorPos = new Point(0, 0);
|
||||
@@ -338,29 +328,7 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
final LinkAdapter la = new LinkAdapter();
|
||||
addMouseMotionListener(la);
|
||||
addMouseListener(la);
|
||||
|
||||
//No standard AddKeyListener as we want to catch Ctrl globally no matter of focus
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||
.addKeyEventPostProcessor(new KeyEventPostProcessor() {
|
||||
@Override
|
||||
public boolean postProcessKeyEvent(KeyEvent e) {
|
||||
if (e.getID() == KeyEvent.KEY_PRESSED) {
|
||||
la.keyPressed(e);
|
||||
}
|
||||
if (e.getID() == KeyEvent.KEY_RELEASED) {
|
||||
la.keyReleased(e);
|
||||
}
|
||||
if (e.getID() == KeyEvent.KEY_TYPED) {
|
||||
la.keyTyped(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public Token tokenAtPos(Point lastPos) {
|
||||
@@ -399,85 +367,7 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
|
||||
public Token getTokenUnderCursor() {
|
||||
return tokenAtPos(lastCursorPos);
|
||||
}
|
||||
|
||||
private class LinkAdapter extends MouseAdapter implements KeyListener {
|
||||
|
||||
private boolean ctrlDown = false;
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
|
||||
ctrlDown = true;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
|
||||
ctrlDown = false;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if (ctrlDown) {
|
||||
Token t = tokenAtPos(lastCursorPos);
|
||||
|
||||
if (t != lastUnderlined) {
|
||||
if (t == null || lastUnderlined == null || !t.equals(lastUnderlined)) {
|
||||
MyMarkers.removeMarkers(LineMarkedEditorPane.this, underLinePainter);
|
||||
|
||||
if (t != null && linkHandler.isLink(t)) {
|
||||
lastUnderlined = t;
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
|
||||
} else {
|
||||
lastUnderlined = null;
|
||||
}
|
||||
} else {
|
||||
lastUnderlined = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastUnderlined != null) {
|
||||
MyMarkers.markToken(LineMarkedEditorPane.this, lastUnderlined, underLinePainter);
|
||||
} else {
|
||||
setCursor(Cursor.getDefaultCursor());
|
||||
}
|
||||
repaint();
|
||||
} else {
|
||||
lastUnderlined = null;
|
||||
MyMarkers.removeMarkers(LineMarkedEditorPane.this, underLinePainter);
|
||||
setCursor(Cursor.getDefaultCursor());
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (ctrlDown) {
|
||||
Token t = tokenAtPos(lastCursorPos);
|
||||
if (t != null && linkHandler.isLink(t)) {
|
||||
linkHandler.handleLink(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
|
||||
ctrlDown = (e.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0;
|
||||
lastCursorPos = e.getPoint();
|
||||
update();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setLinkHandler(LinkHandler linkHandler) {
|
||||
if (linkHandler == null) {
|
||||
@@ -492,7 +382,7 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
|
||||
|
||||
@Override
|
||||
public HighlightPainter linkPainter() {
|
||||
return underLinePainter;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -586,78 +476,7 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnderLinePainter extends DefaultHighlighter.DefaultHighlightPainter {
|
||||
|
||||
public UnderLinePainter(Color color) {
|
||||
super(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) {
|
||||
try {
|
||||
// --- determine locations ---
|
||||
TextUI mapper = c.getUI();
|
||||
|
||||
Color col = getColor();
|
||||
if (col == null) {
|
||||
col = Color.black;
|
||||
}
|
||||
g.setColor(col);
|
||||
for (int i = offs0; i < offs1; i++) {
|
||||
|
||||
Rectangle2D r = com.jpexs.decompiler.flash.gui.View.textUIModelToView(mapper, c, i, Position.Bias.Forward);
|
||||
Rectangle2D r1 = com.jpexs.decompiler.flash.gui.View.textUIModelToView(mapper, c, i + 1, Position.Bias.Forward);
|
||||
if (r1.getY() == r.getY()) {
|
||||
g.drawLine((int) r.getX(), (int) (r.getY() + r.getHeight() - 3), (int) r1.getX(), (int) (r.getY() + r.getHeight() - 3));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
// can't render
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape paintLayer(Graphics g, int offs0, int offs1,
|
||||
Shape bounds, JTextComponent c, View view) {
|
||||
|
||||
g.setColor(c.getSelectionColor());
|
||||
|
||||
Rectangle r;
|
||||
|
||||
if (offs0 == view.getStartOffset()
|
||||
&& offs1 == view.getEndOffset()) {
|
||||
// Contained in view, can just use bounds.
|
||||
if (bounds instanceof Rectangle) {
|
||||
r = (Rectangle) bounds;
|
||||
} else {
|
||||
r = bounds.getBounds();
|
||||
}
|
||||
} else {
|
||||
// Should only render part of View.
|
||||
try {
|
||||
// --- determine locations ---
|
||||
Shape shape = view.modelToView(offs0, Position.Bias.Forward,
|
||||
offs1, Position.Bias.Backward,
|
||||
bounds);
|
||||
r = (shape instanceof Rectangle)
|
||||
? (Rectangle) shape : shape.getBounds();
|
||||
} catch (BadLocationException e) {
|
||||
// can't render
|
||||
r = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (r != null) {
|
||||
r.width = Math.max(r.width, 1);
|
||||
|
||||
paint(g, offs0, offs1, r, c);
|
||||
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int cut(double val) {
|
||||
int ival = (int) Math.round(val);
|
||||
|
||||
113
src/com/jpexs/decompiler/flash/gui/editor/UnderlinePainter.java
Normal file
113
src/com/jpexs/decompiler/flash/gui/editor/UnderlinePainter.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2025 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import javax.swing.plaf.TextUI;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.DefaultHighlighter;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.text.Position;
|
||||
import javax.swing.text.View;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class UnderlinePainter extends OccurencesMarker {
|
||||
|
||||
private final Color underlineColor;
|
||||
|
||||
public UnderlinePainter(Color underLineColor, Color backgroundColor) {
|
||||
super(backgroundColor);
|
||||
this.underlineColor = underLineColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) {
|
||||
if (getColor() != null) {
|
||||
super.paint(g, offs0, offs1, bounds, c);
|
||||
}
|
||||
|
||||
try {
|
||||
// --- determine locations ---
|
||||
TextUI mapper = c.getUI();
|
||||
|
||||
Color col = underlineColor;
|
||||
if (col == null) {
|
||||
col = Color.black;
|
||||
}
|
||||
g.setColor(col);
|
||||
for (int i = offs0; i < offs1; i++) {
|
||||
|
||||
Rectangle2D r = com.jpexs.decompiler.flash.gui.View.textUIModelToView(mapper, c, i, Position.Bias.Forward);
|
||||
Rectangle2D r1 = com.jpexs.decompiler.flash.gui.View.textUIModelToView(mapper, c, i + 1, Position.Bias.Forward);
|
||||
if (r1.getY() == r.getY()) {
|
||||
g.drawLine((int) r.getX(), (int) (r.getY() + r.getHeight() - 3), (int) r1.getX(), (int) (r.getY() + r.getHeight() - 3));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
// can't render
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape paintLayer(Graphics g, int offs0, int offs1,
|
||||
Shape bounds, JTextComponent c, View view) {
|
||||
|
||||
g.setColor(c.getSelectionColor());
|
||||
|
||||
Rectangle r;
|
||||
|
||||
if (offs0 == view.getStartOffset()
|
||||
&& offs1 == view.getEndOffset()) {
|
||||
// Contained in view, can just use bounds.
|
||||
if (bounds instanceof Rectangle) {
|
||||
r = (Rectangle) bounds;
|
||||
} else {
|
||||
r = bounds.getBounds();
|
||||
}
|
||||
} else {
|
||||
// Should only render part of View.
|
||||
try {
|
||||
// --- determine locations ---
|
||||
Shape shape = view.modelToView(offs0, Position.Bias.Forward,
|
||||
offs1, Position.Bias.Backward,
|
||||
bounds);
|
||||
r = (shape instanceof Rectangle)
|
||||
? (Rectangle) shape : shape.getBounds();
|
||||
} catch (BadLocationException e) {
|
||||
// can't render
|
||||
r = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (r != null) {
|
||||
r.width = Math.max(r.width, 1);
|
||||
|
||||
paint(g, offs0, offs1, r, c);
|
||||
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,14 @@ import com.jpexs.decompiler.flash.simpleparser.SimpleParseException;
|
||||
import com.jpexs.decompiler.flash.simpleparser.SimpleParser;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.KeyEventPostProcessor;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionAdapter;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
@@ -35,11 +43,9 @@ import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JLayer;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
@@ -93,6 +99,17 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
|
||||
|
||||
private ScrollBarUI originalScrollBarUI;
|
||||
|
||||
private LinkAdapter linkAdapter;
|
||||
|
||||
private KeyEventPostProcessor kevEventPostProcessor;
|
||||
|
||||
private Set<Integer> occurencesPositions = new HashSet<>();
|
||||
|
||||
private UnderlinePainter underLinePainter = new UnderlinePainter(new Color(0, 0, 255), null);
|
||||
private UnderlinePainter underLineMarkOccurencesPainter = new UnderlinePainter(new Color(0, 0, 255), DEFAULT_COLOR);
|
||||
|
||||
private Token lastUnderlined;
|
||||
|
||||
/**
|
||||
* Constructs a new Token highlighter
|
||||
*/
|
||||
@@ -127,6 +144,9 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
|
||||
*/
|
||||
public void removeMarkers() {
|
||||
Markers.removeMarkers(pane, marker);
|
||||
Markers.removeMarkers(pane, underLinePainter);
|
||||
Markers.removeMarkers(pane, underLineMarkOccurencesPainter);
|
||||
occurencesPositions.clear();
|
||||
}
|
||||
|
||||
public void removeErrorMarkers() {
|
||||
@@ -158,14 +178,14 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
|
||||
private Token getNearestTokenAt(SyntaxDocument sDoc, int pos) {
|
||||
Token thisToken = sDoc.getTokenAt(pos);
|
||||
if (thisToken != null) {
|
||||
|
||||
|
||||
if (thisToken.length == 1) {
|
||||
Token nextToken = sDoc.getTokenAt(pos + 1);
|
||||
if (nextToken != null && nextToken.start == pos && nextToken.length > 1) {
|
||||
return nextToken;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return thisToken;
|
||||
}
|
||||
|
||||
@@ -185,7 +205,7 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
|
||||
|
||||
void addErrorMarkers() {
|
||||
highlightsPanel.setErrors(errors);
|
||||
|
||||
|
||||
SyntaxDocument doc = ActionUtils.getSyntaxDocument(pane);
|
||||
if (doc == null) {
|
||||
return;
|
||||
@@ -216,11 +236,13 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
|
||||
Token definitionToken = getIdentifierTokenAt(sDoc, definitionPos < 0 ? -(definitionPos + 1) : definitionPos);
|
||||
if (definitionToken != null) {
|
||||
if (definitionPosToReferences.containsKey(definitionPos)) {
|
||||
Markers.markToken(pane, definitionToken, marker);
|
||||
Markers.markToken(pane, definitionToken, lastUnderlined == definitionToken ? underLineMarkOccurencesPainter : marker);
|
||||
occurencesPositions.add(definitionToken.start);
|
||||
for (int i : definitionPosToReferences.get(definitionPos)) {
|
||||
Token referenceToken = getIdentifierTokenAt(sDoc, i);
|
||||
if (referenceToken != null) {
|
||||
Markers.markToken(pane, referenceToken, marker);
|
||||
Markers.markToken(pane, referenceToken, lastUnderlined == referenceToken ? underLineMarkOccurencesPainter : marker);
|
||||
occurencesPositions.add(referenceToken.start);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,9 +277,9 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
|
||||
editor.addCaretListener(this);
|
||||
editor.addPropertyChangeListener(this);
|
||||
editor.getDocument().addDocumentListener(this);
|
||||
if (editor instanceof LineMarkedEditorPane) {
|
||||
/*if (editor instanceof LineMarkedEditorPane) {
|
||||
((LineMarkedEditorPane) editor).setLinkHandler(this);
|
||||
}
|
||||
}*/
|
||||
mouseMotionAdapter = new MouseMotionAdapter() {
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
@@ -282,11 +304,128 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
|
||||
JPanel panel = (JPanel) SwingUtilities.getAncestorOfClass(JPanel.class, scrollPane);
|
||||
panel.add(highlightsPanel, BorderLayout.EAST);
|
||||
|
||||
linkAdapter = new LinkAdapter();
|
||||
|
||||
pane.addMouseListener(linkAdapter);
|
||||
pane.addMouseMotionListener(linkAdapter);
|
||||
|
||||
//No standard AddKeyListener as we want to catch Ctrl globally no matter of focus
|
||||
kevEventPostProcessor = new KeyEventPostProcessor() {
|
||||
@Override
|
||||
public boolean postProcessKeyEvent(KeyEvent e) {
|
||||
if (e.getID() == KeyEvent.KEY_PRESSED) {
|
||||
linkAdapter.keyPressed(e);
|
||||
}
|
||||
if (e.getID() == KeyEvent.KEY_RELEASED) {
|
||||
linkAdapter.keyReleased(e);
|
||||
}
|
||||
if (e.getID() == KeyEvent.KEY_TYPED) {
|
||||
linkAdapter.keyTyped(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(kevEventPostProcessor);
|
||||
|
||||
documentUpdated();
|
||||
markTokenAt(editor.getCaretPosition());
|
||||
status = Status.INSTALLING;
|
||||
}
|
||||
|
||||
private class LinkAdapter extends MouseAdapter implements KeyListener {
|
||||
|
||||
private boolean ctrlDown = false;
|
||||
|
||||
private Point lastCursorPos;
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
|
||||
ctrlDown = true;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
|
||||
ctrlDown = false;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if (ctrlDown) {
|
||||
Token t = ((LineMarkedEditorPane) pane).tokenAtPos(lastCursorPos);
|
||||
|
||||
if (t != lastUnderlined) {
|
||||
if (t == null || lastUnderlined == null || !t.equals(lastUnderlined)) {
|
||||
MyMarkers.removeMarkers(pane, underLinePainter);
|
||||
MyMarkers.removeMarkers(pane, underLineMarkOccurencesPainter);
|
||||
|
||||
if (t != null && isLink(t)) {
|
||||
lastUnderlined = t;
|
||||
pane.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
|
||||
} else {
|
||||
lastUnderlined = null;
|
||||
|
||||
removeMarkers();
|
||||
markTokenAt(pane.getCaretPosition());
|
||||
}
|
||||
} else {
|
||||
lastUnderlined = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastUnderlined != null) {
|
||||
Highlighter.HighlightPainter painter = underLinePainter;
|
||||
if (occurencesPositions.contains(lastUnderlined.start)) {
|
||||
painter = underLineMarkOccurencesPainter;
|
||||
removeMarkers();
|
||||
markTokenAt(pane.getCaretPosition());
|
||||
} else {
|
||||
MyMarkers.markToken(pane, lastUnderlined, painter);
|
||||
}
|
||||
} else {
|
||||
pane.setCursor(Cursor.getDefaultCursor());
|
||||
}
|
||||
} else {
|
||||
lastUnderlined = null;
|
||||
MyMarkers.removeMarkers(pane, underLinePainter);
|
||||
MyMarkers.removeMarkers(pane, underLineMarkOccurencesPainter);
|
||||
removeMarkers();
|
||||
markTokenAt(pane.getCaretPosition());
|
||||
pane.setCursor(Cursor.getDefaultCursor());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (ctrlDown) {
|
||||
Token t = ((LineMarkedEditorPane) pane).tokenAtPos(lastCursorPos);
|
||||
if (t != null && isLink(t)) {
|
||||
e.consume();
|
||||
handleLink(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
|
||||
ctrlDown = (e.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0;
|
||||
lastCursorPos = e.getPoint();
|
||||
update();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void editorMouseMoved(MouseEvent e) {
|
||||
if (pane instanceof LineMarkedEditorPane) {
|
||||
Token token = ((LineMarkedEditorPane) pane).getTokenUnderCursor();
|
||||
@@ -313,10 +452,13 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
|
||||
pane.getDocument().removeDocumentListener(this);
|
||||
pane.removeCaretListener(this);
|
||||
pane.removeMouseMotionListener(mouseMotionAdapter);
|
||||
pane.removeMouseMotionListener(linkAdapter);
|
||||
pane.removeMouseListener(linkAdapter);
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventPostProcessor(kevEventPostProcessor);
|
||||
mouseMotionAdapter = null;
|
||||
if (editor instanceof LineMarkedEditorPane) {
|
||||
/*if (editor instanceof LineMarkedEditorPane) {
|
||||
((LineMarkedEditorPane) editor).setLinkHandler(null);
|
||||
}
|
||||
}*/
|
||||
JScrollPane scrollPane = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, editor);
|
||||
JPanel panel = (JPanel) SwingUtilities.getAncestorOfClass(JPanel.class, scrollPane);
|
||||
panel.remove(highlightsPanel);
|
||||
@@ -376,7 +518,7 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
|
||||
} catch (SimpleParseException ex) {
|
||||
definitionPosToReferences.clear();
|
||||
referenceToDefinition.clear();
|
||||
errors.put((int) ex.position, ex.getMessage());
|
||||
errors.put((int) ex.position, ex.getMessage());
|
||||
}
|
||||
Timer tim = errorsTimer;
|
||||
if (tim != null) {
|
||||
@@ -412,14 +554,27 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
|
||||
|
||||
@Override
|
||||
public boolean isLink(Token token) {
|
||||
return referenceToDefinition.containsKey(token.start) && referenceToDefinition.get(token.start) >= 0;
|
||||
boolean linkBasic = referenceToDefinition.containsKey(token.start) && referenceToDefinition.get(token.start) >= 0;
|
||||
if (linkBasic) {
|
||||
return true;
|
||||
}
|
||||
if (pane.isEditable()) {
|
||||
return false;
|
||||
}
|
||||
return ((LineMarkedEditorPane) pane).getLinkHandler().isLink(token);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLink(Token token) {
|
||||
Integer definition = referenceToDefinition.get(token.start);
|
||||
if (definition != null) {
|
||||
if (definition != null && definition >= 0) {
|
||||
pane.setCaretPosition(definition);
|
||||
} else if (!pane.isEditable()) {
|
||||
lastUnderlined = null;
|
||||
removeErrorMarkers();
|
||||
removeMarkers();
|
||||
pane.repaint();
|
||||
((LineMarkedEditorPane) pane).getLinkHandler().handleLink(token);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user