mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-01 19:04:38 +00:00
Added: AS1/2 - hilight variables and errors on scrollbar
This commit is contained in:
@@ -21,6 +21,7 @@ All notable changes to this project will be documented in this file.
|
||||
- AS1/2 - highlight variable definition and all its instances on cursor place
|
||||
(also in edit mode)
|
||||
- AS1/2 - underline errors in the code (also in edit mode)
|
||||
- AS1/2 - highlight variables and errors on scrollbar
|
||||
|
||||
### Changed
|
||||
- AS1/2 - Single DoAction tag inside frame is now displayed directly as frame node
|
||||
|
||||
@@ -57,7 +57,6 @@ import com.jpexs.decompiler.flash.gui.ViewMessages;
|
||||
import com.jpexs.decompiler.flash.gui.controls.JPersistentSplitPane;
|
||||
import com.jpexs.decompiler.flash.gui.controls.NoneSelectedButtonGroup;
|
||||
import com.jpexs.decompiler.flash.gui.editor.DebuggableEditorPane;
|
||||
import com.jpexs.decompiler.flash.gui.editor.LinkHandler;
|
||||
import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTreeModel;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedText;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
|
||||
@@ -96,7 +95,6 @@ import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
@@ -111,7 +109,6 @@ import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Highlighter;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.text.Utilities;
|
||||
import javax.swing.tree.TreePath;
|
||||
@@ -947,8 +944,11 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
|
||||
brokenHintPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED), new EmptyBorder(5, 5, 5, 5)));
|
||||
|
||||
panelWithHint.add(brokenHintPanel, BorderLayout.NORTH);
|
||||
panelWithHint.add(new FasterScrollPane(decompiledEditor), BorderLayout.CENTER);
|
||||
|
||||
|
||||
JPanel panelDecompiled = new JPanel(new BorderLayout(0, 0));
|
||||
panelDecompiled.add(new FasterScrollPane(decompiledEditor), BorderLayout.CENTER);
|
||||
panelWithHint.add(panelDecompiled, BorderLayout.CENTER);
|
||||
|
||||
brokenHintPanel.setVisible(false);
|
||||
|
||||
JPanel iconsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
|
||||
@@ -23,7 +23,10 @@ import com.jpexs.decompiler.flash.action.parser.script.variables.ActionVariableP
|
||||
import com.jpexs.decompiler.flash.gui.editor.DebuggableEditorPane;
|
||||
import com.jpexs.decompiler.flash.gui.editor.LineMarkedEditorPane;
|
||||
import com.jpexs.decompiler.flash.gui.editor.LinkHandler;
|
||||
import com.jpexs.decompiler.flash.gui.editor.ScrollbarOverlay;
|
||||
import com.jpexs.decompiler.flash.gui.editor.TrackRectSubstanceScrollbarUI;
|
||||
import com.jpexs.decompiler.flash.gui.editor.WavyUnderLinePainter;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionAdapter;
|
||||
@@ -38,12 +41,22 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.logging.Level;
|
||||
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;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.plaf.ScrollBarUI;
|
||||
import javax.swing.plaf.ScrollPaneUI;
|
||||
import javax.swing.plaf.basic.BasicScrollPaneUI;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Highlighter;
|
||||
import jsyntaxpane.SyntaxDocument;
|
||||
@@ -53,6 +66,7 @@ import jsyntaxpane.actions.ActionUtils;
|
||||
import jsyntaxpane.components.Markers;
|
||||
import jsyntaxpane.components.SyntaxComponent;
|
||||
import jsyntaxpane.util.Configuration;
|
||||
import org.pushingpixels.substance.internal.ui.SubstanceScrollBarUI;
|
||||
|
||||
/**
|
||||
* This class highlights Variable tokens of ActionScript 1/2
|
||||
@@ -64,7 +78,10 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
public static final String PROPERTY_ERRORCOLOR = "ActionVariableMarker.ErrorColor";
|
||||
public static final String PROPERTY_TOKENTYPES = "ActionVariableMarker.TokenTypes";
|
||||
private static final Color DEFAULT_COLOR = new Color(0xffeedd);
|
||||
private static final Color DEFAULT_ERRORCOLOR = new Color(0xffaaaa);
|
||||
private static final Color DEFAULT_ERRORCOLOR = new Color(0xff0000);
|
||||
|
||||
private static final Color SCROLLBAR_VARIABLE_COLOR = new Color(0xb59070);
|
||||
private static final Color SCROLLBAR_ERROR_COLOR = new Color(0xff0000);
|
||||
private JEditorPane pane;
|
||||
private final Set<TokenType> tokenTypes = new HashSet<>();
|
||||
private Markers.SimpleMarker marker;
|
||||
@@ -81,6 +98,14 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
|
||||
private MouseMotionAdapter mouseMotionAdapter;
|
||||
|
||||
private JLayer<JScrollBar> layer;
|
||||
|
||||
private ScrollbarOverlay scrollbarOverlay;
|
||||
|
||||
private ScrollPaneUI originalScrollPaneUI;
|
||||
|
||||
private ScrollBarUI originalScrollBarUI;
|
||||
|
||||
/**
|
||||
* Constructs a new Token highlighter
|
||||
*/
|
||||
@@ -106,6 +131,7 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
if (token != null && tokenTypes.contains(token.type)) {
|
||||
addMarkers(token);
|
||||
}
|
||||
layer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,11 +140,13 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
*/
|
||||
public void removeMarkers() {
|
||||
Markers.removeMarkers(pane, marker);
|
||||
scrollbarOverlay.removeMarkers(SCROLLBAR_VARIABLE_COLOR);
|
||||
}
|
||||
|
||||
public void removeErrorMarkers() {
|
||||
Markers.removeMarkers(pane, errorMarker);
|
||||
errorsShown = false;
|
||||
scrollbarOverlay.removeMarkers(SCROLLBAR_ERROR_COLOR);
|
||||
}
|
||||
|
||||
private Token getIdentifierTokenAt(SyntaxDocument sDoc, int pos) {
|
||||
@@ -173,8 +201,10 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
Token token = getNearestTokenAt(doc, position);
|
||||
if (token != null) {
|
||||
Markers.markToken(pane, token, errorMarker);
|
||||
markPositionOnScrollbar(position, SCROLLBAR_ERROR_COLOR);
|
||||
}
|
||||
}
|
||||
layer.repaint();
|
||||
doc.readUnlock();
|
||||
errorsShown = true;
|
||||
}
|
||||
@@ -195,10 +225,12 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
if (definitionToken != null) {
|
||||
if (definitionPosToReferences.containsKey(definitionPos)) {
|
||||
Markers.markToken(pane, definitionToken, marker);
|
||||
markPositionOnScrollbar(definitionToken.start, SCROLLBAR_VARIABLE_COLOR);
|
||||
for (int i : definitionPosToReferences.get(definitionPos)) {
|
||||
Token referenceToken = getIdentifierTokenAt(sDoc, i);
|
||||
if (referenceToken != null) {
|
||||
Markers.markToken(pane, referenceToken, marker);
|
||||
markPositionOnScrollbar(referenceToken.start, SCROLLBAR_VARIABLE_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -206,12 +238,20 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
sDoc.readUnlock();
|
||||
}
|
||||
|
||||
private void markPositionOnScrollbar(int position, Color color) {
|
||||
try {
|
||||
scrollbarOverlay.addMarker(ActionUtils.getLineNumber(pane, position), color);
|
||||
} catch (BadLocationException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void config(Configuration config) {
|
||||
Color markerColor = config.getColor(PROPERTY_COLOR, DEFAULT_COLOR);
|
||||
Color errorColor = config.getColor(PROPERTY_ERRORCOLOR, DEFAULT_ERRORCOLOR);
|
||||
this.marker = new Markers.SimpleMarker(markerColor);
|
||||
this.errorMarker = new WavyUnderLinePainter(Color.red); //Markers.SimpleMarker(errorColor);
|
||||
this.errorMarker = new WavyUnderLinePainter(errorColor); //Markers.SimpleMarker(errorColor);
|
||||
String types = config.getString(
|
||||
PROPERTY_TOKENTYPES, DEFAULT_TOKENTYPES);
|
||||
|
||||
@@ -236,8 +276,6 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
if (editor instanceof LineMarkedEditorPane) {
|
||||
((LineMarkedEditorPane) editor).setLinkHandler(this);
|
||||
}
|
||||
documentUpdated();
|
||||
markTokenAt(editor.getCaretPosition());
|
||||
mouseMotionAdapter = new MouseMotionAdapter() {
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
@@ -245,6 +283,28 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
}
|
||||
};
|
||||
editor.addMouseMotionListener(mouseMotionAdapter);
|
||||
|
||||
JScrollPane scrollPane = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, editor);
|
||||
|
||||
originalScrollPaneUI = scrollPane.getUI();
|
||||
scrollPane.setUI(new BasicScrollPaneUI());
|
||||
|
||||
JScrollBar verticalScrollBar = scrollPane.getVerticalScrollBar();
|
||||
originalScrollBarUI = verticalScrollBar.getUI();
|
||||
if (originalScrollBarUI instanceof SubstanceScrollBarUI) {
|
||||
verticalScrollBar.setUI(new TrackRectSubstanceScrollbarUI(verticalScrollBar));
|
||||
}
|
||||
|
||||
scrollbarOverlay = new ScrollbarOverlay((LineMarkedEditorPane) pane);
|
||||
|
||||
layer = new JLayer<>(verticalScrollBar, scrollbarOverlay);
|
||||
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
|
||||
|
||||
JPanel panel = (JPanel) SwingUtilities.getAncestorOfClass(JPanel.class, scrollPane);
|
||||
panel.add(layer, BorderLayout.EAST);
|
||||
|
||||
documentUpdated();
|
||||
markTokenAt(editor.getCaretPosition());
|
||||
status = Status.INSTALLING;
|
||||
}
|
||||
|
||||
@@ -278,6 +338,14 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
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(layer);
|
||||
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
|
||||
panel.revalidate();
|
||||
panel.repaint();
|
||||
scrollPane.setUI(originalScrollPaneUI);
|
||||
scrollPane.getVerticalScrollBar().setUI(originalScrollBarUI);
|
||||
}
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ActionVariableMarker.class.getName());
|
||||
@@ -299,6 +367,7 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
private void documentUpdated() {
|
||||
errors.clear();
|
||||
removeErrorMarkers();
|
||||
layer.repaint();
|
||||
try {
|
||||
SyntaxDocument sDoc = (SyntaxDocument) pane.getDocument();
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLayer;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.plaf.LayerUI;
|
||||
import javax.swing.plaf.ScrollBarUI;
|
||||
import jsyntaxpane.actions.ActionUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ScrollbarOverlay extends LayerUI<JScrollBar> {
|
||||
|
||||
private final LineMarkedEditorPane editorPane;
|
||||
private final Map<Integer, Color> markedLines = new LinkedHashMap<>();
|
||||
|
||||
public ScrollbarOverlay(LineMarkedEditorPane editorPane) {
|
||||
this.editorPane = editorPane;
|
||||
}
|
||||
|
||||
public void removeMarkers(Color color) {
|
||||
Set<Integer> lines = new HashSet<>(markedLines.keySet());
|
||||
for (int key : lines) {
|
||||
if (markedLines.get(key).equals(color)) {
|
||||
markedLines.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clearMarkers() {
|
||||
markedLines.clear();
|
||||
}
|
||||
|
||||
public void addMarker(int line, Color color) {
|
||||
markedLines.put(line, color);
|
||||
}
|
||||
|
||||
public void setMarkedLines(Map<Integer, Color> markedLines) {
|
||||
this.markedLines.clear();
|
||||
this.markedLines.putAll(markedLines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
super.paint(g, c);
|
||||
JScrollBar bar = (JScrollBar) ((JLayer<?>) c).getView();
|
||||
ScrollBarUI ui = bar.getUI();
|
||||
Rectangle r;
|
||||
if (ui instanceof TrackRectSubstanceScrollbarUI) {
|
||||
r = ((TrackRectSubstanceScrollbarUI) ui).getTrackBounds();
|
||||
} else {
|
||||
r = new Rectangle(0, 16, 16, bar.getHeight() - 32);
|
||||
}
|
||||
|
||||
int totalLineCount = ActionUtils.getLineCount(editorPane);
|
||||
for (Map.Entry<Integer, Color> entry : markedLines.entrySet()) {
|
||||
g.setColor(entry.getValue());
|
||||
|
||||
float ratio = (float) entry.getKey() / totalLineCount;
|
||||
int y = r.y + (int) (ratio * r.height);
|
||||
g.drawLine(0, y, bar.getWidth(), y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.Rectangle;
|
||||
import javax.swing.JComponent;
|
||||
import org.pushingpixels.substance.internal.ui.SubstanceScrollBarUI;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TrackRectSubstanceScrollbarUI extends SubstanceScrollBarUI {
|
||||
public TrackRectSubstanceScrollbarUI(JComponent b) {
|
||||
super(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getTrackBounds() {
|
||||
return super.getTrackBounds();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user