Added Remembering script+folder scroll/caret position when switching between items, saving for pinned items

This commit is contained in:
Jindra Petřík
2023-01-29 21:45:21 +01:00
parent e123bc699f
commit 07df4a8640
11 changed files with 605 additions and 10 deletions

View File

@@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
### Added
- [#1029] Better separation of library and main app, dependencies inside library zip, library readme
- Remembering script+folder scroll/caret position when switching between items, saving for pinned items
### Fixed
- [#1948] Timeout while deobfuscation did not skip method

View File

@@ -887,6 +887,22 @@ public final class Configuration {
@ConfigurationCategory("display")
public static ConfigurationItem<Boolean> disableBitmapSmoothing = null;
@ConfigurationDefaultString("")
public static ConfigurationItem<String> pinnedItemsScrollPos = null;
@ConfigurationDefaultInt(30)
@ConfigurationCategory("ui")
public static ConfigurationItem<Integer> maxRememberedScrollposItems = null;
@ConfigurationDefaultBoolean(true)
@ConfigurationCategory("ui")
public static ConfigurationItem<Boolean> rememberScriptsScrollPos = null;
@ConfigurationDefaultBoolean(true)
@ConfigurationCategory("ui")
public static ConfigurationItem<Boolean> rememberFoldersScrollPos = null;
private enum OSId {
WINDOWS, OSX, UNIX
}

View File

@@ -2789,6 +2789,10 @@ public class Main {
}
public static void exit() {
if (mainFrame != null && mainFrame.getPanel() != null) {
mainFrame.getPanel().scrollPosStorage.saveScrollPos(mainFrame.getPanel().getCurrentTree().getCurrentTreeItem());
mainFrame.getPanel().savePins();
}
try {
searchResultsStorage.save();
} catch (IOException ex) {

View File

@@ -441,6 +441,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
private List<List<String>> unfilteredTreeExpandedNodes = new ArrayList<>();
private List<List<String>> unfilteredTagListExpandedNodes = new ArrayList<>();
public ScrollPosStorage scrollPosStorage;
public void savePins() {
pinsPanel.save();
@@ -1225,6 +1227,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
});
detailPanel.setVisible(false);
scrollPosStorage = new ScrollPosStorage(this);
updateUi();
this.openables.addCollectionChangedListener((e) -> {
@@ -1321,7 +1325,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
resetAllTimelines();
refreshTree();
}
});
});
}
public void resetAllTimelines() {
@@ -1429,9 +1433,18 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
List<ABCContainerTag> abcList = swf.getAbcList();
boolean hasAbc = !abcList.isEmpty();
if (hasAbc) {
getABCPanel().setAbc(abcList.get(0).getABC());
if (hasAbc) {
boolean abcFound = false;
for (ABCContainerTag c : abcList) {
if (getABCPanel().abc == c.getABC()) {
abcFound = true;
break;
}
}
if (!abcFound) {
getABCPanel().setAbc(abcList.get(0).getABC());
}
}
}
mainMenu.updateComponents(openable);
@@ -1511,6 +1524,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
return false;
}
}
scrollPosStorage.saveScrollPos(getCurrentTree().getCurrentTreeItem());
clearPins();
@@ -4478,7 +4493,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (treeItem == null) {
return;
}
if (!(treeItem instanceof OpenableList)) {
Openable openable = treeItem.getOpenable();
if (openables.isEmpty()) {
@@ -4496,7 +4511,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
} else {
updateUi();
}
reload(false, false);
if (source == dumpTree) {
@@ -5015,7 +5030,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
showDetail(DETAILCARDEMPTYPANEL);
showCard(CARDEMPTYPANEL);
}
public void reload(boolean forceReload) {
reload(forceReload, true);
}
@@ -5066,6 +5081,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
if (oldItem != treeItem) {
scrollPosStorage.saveScrollPos(oldItem);
closeTag();
}
@@ -5247,6 +5263,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
folderPreviewPanel.selectedItems = folderItems;
folderPreviewScrollBar.setValue(scrollValue);
View.execInEventDispatchLater(new Runnable(){
@Override
public void run() {
scrollPosStorage.loadScrollPos(oldItem);
}
});
}
public void repaintTree() {

View File

@@ -47,6 +47,7 @@ public class PinsPanel extends JPanel {
private List<String> missingTagTreePaths = new ArrayList<>();
private List<String> missingTagListPaths = new ArrayList<>();
private List<String> missingScrollPos = new ArrayList<>();
private static final String PATHS_SEPARATOR = "{#sep#}";
@@ -61,6 +62,9 @@ public class PinsPanel extends JPanel {
*/
public void destroy() {
items.clear();
missingScrollPos.clear();
missingTagListPaths.clear();
missingTagTreePaths.clear();
rebuild();
save();
}
@@ -81,8 +85,11 @@ public class PinsPanel extends JPanel {
tagListPath = "";
}
String scrollPos = mainPanel.scrollPosStorage.getSerializedScrollPos(item);
missingTagTreePaths.add(tagTreePath);
missingTagListPaths.add(tagListPath);
missingScrollPos.add(scrollPos);
}
items.clear();
rebuild();
@@ -232,15 +239,18 @@ public class PinsPanel extends JPanel {
public void save() {
StringBuilder tagTreePathsBuilder = new StringBuilder();
StringBuilder tagListPathsBuilder = new StringBuilder();
StringBuilder scrollPosesBuilder = new StringBuilder();
boolean first = true;
for (int i = 0; i < missingTagTreePaths.size(); i++) {
if (!first) {
tagTreePathsBuilder.append(PATHS_SEPARATOR);
tagListPathsBuilder.append(PATHS_SEPARATOR);
scrollPosesBuilder.append(PATHS_SEPARATOR);
}
tagTreePathsBuilder.append(missingTagTreePaths.get(i));
tagListPathsBuilder.append(missingTagListPaths.get(i));
scrollPosesBuilder.append(missingScrollPos.get(i));
first = false;
}
@@ -259,17 +269,23 @@ public class PinsPanel extends JPanel {
if (tagListPath == null) {
tagListPath = "";
}
String scrollPos = mainPanel.scrollPosStorage.getSerializedScrollPos(item);
if (!first) {
tagTreePathsBuilder.append(PATHS_SEPARATOR);
tagListPathsBuilder.append(PATHS_SEPARATOR);
scrollPosesBuilder.append(PATHS_SEPARATOR);
}
tagTreePathsBuilder.append(tagTreePath);
tagListPathsBuilder.append(tagListPath);
scrollPosesBuilder.append(scrollPos);
first = false;
}
Configuration.pinnedItemsTagTreePaths.set(tagTreePathsBuilder.toString());
Configuration.pinnedItemsTagListPaths.set(tagListPathsBuilder.toString());
Configuration.pinnedItemsScrollPos.set(scrollPosesBuilder.toString());
}
public void load() {
@@ -278,10 +294,14 @@ public class PinsPanel extends JPanel {
List<String> missingTagTreePaths = new ArrayList<>();
List<String> missingTagListPaths = new ArrayList<>();
List<String> missingScrollPos = new ArrayList<>();
String tagTreePathsCombined = Configuration.pinnedItemsTagTreePaths.get() + PATHS_SEPARATOR + PATHS_END;
String tagListPathsCombined = Configuration.pinnedItemsTagListPaths.get() + PATHS_SEPARATOR + PATHS_END;
String scrollPosCombined = Configuration.pinnedItemsScrollPos.get() + PATHS_SEPARATOR + PATHS_END;
String[] tagTreePaths = tagTreePathsCombined.split(Pattern.quote(PATHS_SEPARATOR));
String[] tagListPaths = tagListPathsCombined.split(Pattern.quote(PATHS_SEPARATOR));
String[] scrollPoses = scrollPosCombined.split(Pattern.quote(PATHS_SEPARATOR));
if (tagTreePaths.length != tagListPaths.length) {
return;
}
@@ -293,16 +313,24 @@ public class PinsPanel extends JPanel {
if (item == null || (item instanceof TreeRoot)) {
item = mainPanel.tagListTree.getTreeItemFromPathString(tagListPath);
}
String scrollPosStr = "";
if (!Configuration.pinnedItemsScrollPos.get().isEmpty()) {
scrollPosStr = scrollPoses[i];
}
if (item != null && !(item instanceof TreeRoot)) {
items.add(item);
mainPanel.scrollPosStorage.setSerializedScrollPos(item, scrollPosStr);
} else {
missingTagTreePaths.add(tagTreePath);
missingTagListPaths.add(tagListPath);
missingScrollPos.add(scrollPosStr);
}
}
this.items = items;
this.missingTagTreePaths = missingTagTreePaths;
this.missingTagListPaths = missingTagListPaths;
this.missingScrollPos = missingScrollPos;
rebuild();
}
@@ -321,9 +349,12 @@ public class PinsPanel extends JPanel {
if (tagListPath == null) {
tagListPath = "";
}
String scrollPos = mainPanel.scrollPosStorage.getSerializedScrollPos(item);
missingTagTreePaths.add(tagTreePath);
missingTagListPaths.add(tagListPath);
missingScrollPos.add(scrollPos);
items.remove(i);
i--;

View File

@@ -0,0 +1,449 @@
/*
* Copyright (C) 2023 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;
import com.jpexs.decompiler.flash.abc.ScriptPack;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
import com.jpexs.decompiler.flash.timeline.AS2Package;
import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem;
import com.jpexs.decompiler.flash.treeitems.FolderItem;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JScrollPane;
/**
* Storage for remembering scroll/caret positions of scripts / preview folder.
*
* @author JPEXS
*/
public class ScrollPosStorage {
private final MainPanel mainPanel;
private final List<ScrollPosItem> storage = new ArrayList<>();
private static final String PATHS_SEPARATOR = "{#sep#}";
private static final String POS_SEPARATOR = ";";
public ScrollPosStorage(MainPanel mainPanel) {
this.mainPanel = mainPanel;
}
private int indexOf(TreeItem item) {
for (int i = 0; i < storage.size(); i++) {
ScrollPosItem sitem = storage.get(i);
TreeItem titem = sitem.getItem();
if (titem == null) {
storage.remove(i);
i--;
continue;
}
if (titem == item) {
return i;
}
}
return -1;
}
public void setSerializedScrollPos(TreeItem item, String serializedScrollPos) {
if (serializedScrollPos.isEmpty()) {
int index = indexOf(item);
if (index > -1) {
storage.remove(index);
}
return;
}
String[] parts = (serializedScrollPos + POS_SEPARATOR).split(POS_SEPARATOR);
int actionScriptScrollHorizontal = Integer.parseInt(parts[0]);
int actionScriptScrollVertical = Integer.parseInt(parts[1]);
int actionScriptCaret = Integer.parseInt(parts[2]);
int pcodeScrollHorizontal = Integer.parseInt(parts[3]);
int pcodeScrollVertical = Integer.parseInt(parts[4]);
int pcodeCaret = Integer.parseInt(parts[5]);
int folderPreviewScrollVertical = Integer.parseInt(parts[6]);
int folderListScrollVertical = Integer.parseInt(parts[7]);
int index = indexOf(item);
ScrollPosItem sitem = new ScrollPosItem(item, actionScriptScrollHorizontal, actionScriptScrollVertical, actionScriptCaret, pcodeScrollHorizontal, pcodeScrollVertical, pcodeCaret, folderPreviewScrollVertical, folderListScrollVertical);
if (index > -1) {
storage.set(index, sitem);
} else {
storage.add(sitem);
}
}
public String getSerializedScrollPos(TreeItem item) {
int index = indexOf(item);
if (index == -1) {
return "";
}
ScrollPosItem sitem = storage.get(index);
return sitem.getActionScriptScrollHorizontal() + ";"
+ sitem.getActionScriptScrollVertical() + ";"
+ sitem.getActionScriptCaret() + ";"
+ sitem.getPcodeScrollHorizontal() + ";"
+ sitem.getPcodeScrollVertical() + ";"
+ sitem.getPcodeCaret() + ";"
+ sitem.getFolderPreviewScrollVertical() + ";"
+ sitem.getFolderListScrollVertical();
}
public void loadScrollPos(TreeItem item) {
int index = indexOf(item);
if (index == -1) {
return;
}
ScrollPosItem sitem = storage.get(index);
//move to bottom
storage.remove(index);
storage.add(sitem);
if (Configuration.rememberScriptsScrollPos.get()) {
if (item instanceof ScriptPack) {
mainPanel.getABCPanel().decompiledTextArea.runWhenLoaded(new Runnable() {
@Override
public void run() {
if (sitem.getActionScriptCaret() < mainPanel.getABCPanel().decompiledTextArea.getDocument().getLength()) {
mainPanel.getABCPanel().decompiledTextArea.setCaretPosition(sitem.getActionScriptCaret());
}
try {
mainPanel.getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.getSourceTextArea().setCaretPosition(sitem.getPcodeCaret());
} catch (IllegalArgumentException iex) {
}
Timer tim = new Timer();
tim.schedule(new TimerTask() {
@Override
public void run() {
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
mainPanel.getABCPanel().decompiledScrollPane.getHorizontalScrollBar().setValue(sitem.getActionScriptScrollHorizontal());
mainPanel.getABCPanel().decompiledScrollPane.getVerticalScrollBar().setValue(sitem.getActionScriptScrollVertical());
mainPanel.getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.getSourceScrollPane().getHorizontalScrollBar().setValue(sitem.getPcodeScrollHorizontal());
mainPanel.getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.getSourceScrollPane().getVerticalScrollBar().setValue(sitem.getPcodeScrollVertical());
}
});
}
}, 100);
}
});
} else if (item instanceof ASMSource) {
mainPanel.getActionPanel().runWhenLoaded(new Runnable() {
@Override
public void run() {
if (sitem.getActionScriptCaret() < mainPanel.getActionPanel().decompiledEditor.getDocument().getLength()) {
mainPanel.getActionPanel().decompiledEditor.setCaretPosition(sitem.getActionScriptCaret());
}
try {
mainPanel.getActionPanel().editor.setCaretPosition(sitem.getPcodeCaret());
} catch (IllegalArgumentException iex) {
}
Timer tim = new Timer();
tim.schedule(new TimerTask() {
@Override
public void run() {
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
((JScrollPane) mainPanel.getActionPanel().decompiledEditor.getParent().getParent()).getHorizontalScrollBar().setValue(sitem.getActionScriptScrollHorizontal());
((JScrollPane) mainPanel.getActionPanel().decompiledEditor.getParent().getParent()).getVerticalScrollBar().setValue(sitem.getActionScriptScrollVertical());
((JScrollPane) mainPanel.getActionPanel().editor.getParent().getParent()).getHorizontalScrollBar().setValue(sitem.getPcodeScrollHorizontal());
((JScrollPane) mainPanel.getActionPanel().editor.getParent().getParent()).getVerticalScrollBar().setValue(sitem.getPcodeScrollVertical());
}
});
}
}, 100);
}
});
}
}
if (Configuration.rememberFoldersScrollPos.get()) {
Timer tim = new Timer();
tim.schedule(new TimerTask() {
@Override
public void run() {
View.execInEventDispatchLater(new Runnable() {
@Override
public void run() {
((JScrollPane) mainPanel.folderPreviewPanel.getParent().getParent()).getVerticalScrollBar().setValue(sitem.getFolderPreviewScrollVertical());
((JScrollPane) mainPanel.folderListPanel.getParent().getParent()).getVerticalScrollBar().setValue(sitem.getFolderListScrollVertical());
}
});
}
},10);
}
}
public void saveScrollPos(TreeItem item) {
boolean doSave = false;
if (item instanceof ScriptPack) {
doSave = true;
}
if (item instanceof ASMSource) {
doSave = true;
}
if (item instanceof FolderItem) {
doSave = true;
}
if (item instanceof AS3ClassTreeItem) {
doSave = true;
}
if (item instanceof AS2Package) {
doSave = true;
}
if (!doSave) {
return;
}
int actionScriptScrollHorizontal = 0;
int actionScriptScrollVertical = 0;
int actionScriptCaret = 0;
int pcodeScrollHorizontal = 0;
int pcodeScrollVertical = 0;
int pcodeCaret = 0;
if (item instanceof ScriptPack) {
actionScriptScrollHorizontal = mainPanel.getABCPanel().decompiledScrollPane.getHorizontalScrollBar().getValue();
actionScriptScrollVertical = mainPanel.getABCPanel().decompiledScrollPane.getVerticalScrollBar().getValue();
actionScriptCaret = mainPanel.getABCPanel().decompiledTextArea.getCaretPosition();
pcodeScrollHorizontal = mainPanel.getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.getSourceScrollPane().getHorizontalScrollBar().getValue();
pcodeScrollVertical = mainPanel.getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.getSourceScrollPane().getVerticalScrollBar().getValue();
pcodeCaret = mainPanel.getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.getSourceTextArea().getCaretPosition();
} else if (item instanceof ASMSource) {
actionScriptScrollHorizontal = ((JScrollPane) mainPanel.getActionPanel().decompiledEditor.getParent().getParent()).getHorizontalScrollBar().getValue();
actionScriptScrollVertical = ((JScrollPane) mainPanel.getActionPanel().decompiledEditor.getParent().getParent()).getVerticalScrollBar().getValue();
actionScriptCaret = mainPanel.getActionPanel().decompiledEditor.getCaretPosition();
pcodeScrollHorizontal = ((JScrollPane) mainPanel.getActionPanel().editor.getParent().getParent()).getHorizontalScrollBar().getValue();
pcodeScrollVertical = ((JScrollPane) mainPanel.getActionPanel().editor.getParent().getParent()).getVerticalScrollBar().getValue();
pcodeCaret = mainPanel.getActionPanel().editor.getCaretPosition();
}
int folderPreviewScrollVertical = 0;
int folderListScrollVertical = 0;
if (!(item instanceof ScriptPack) && !(item instanceof ASMSource)) {
folderPreviewScrollVertical = ((JScrollPane) mainPanel.folderPreviewPanel.getParent().getParent()).getVerticalScrollBar().getValue();
}
if (!(item instanceof ScriptPack) && !(item instanceof ASMSource)) {
folderListScrollVertical = ((JScrollPane) mainPanel.folderListPanel.getParent().getParent()).getVerticalScrollBar().getValue();
}
ScrollPosItem savedItem = new ScrollPosItem(item,
actionScriptScrollHorizontal,
actionScriptScrollVertical,
actionScriptCaret,
pcodeScrollHorizontal,
pcodeScrollVertical,
pcodeCaret,
folderPreviewScrollVertical,
folderListScrollVertical);
int index = indexOf(item);
if (savedItem.isEmpty()) {
if (index > -1) {
storage.remove(index);
}
return;
}
if (index > -1) {
storage.set(index, savedItem);
} else {
storage.add(savedItem);
}
if (storage.size() > Configuration.maxRememberedScrollposItems.get()) {
for (int i = 0; i < storage.size(); i++) {
TreeItem it = storage.get(i).getItem();
if (it != null && mainPanel.isPinned(item)) {
continue;
}
storage.remove(0);
break;
}
}
}
}
class ScrollPosItem {
private final WeakReference<TreeItem> item;
private final int actionScriptScrollHorizontal;
private final int actionScriptScrollVertical;
private final int actionScriptCaret;
private final int pcodeScrollHorizontal;
private final int pcodeScrollVertical;
private final int pcodeCaret;
private final int folderPreviewScrollVertical;
private final int folderListScrollVertical;
public TreeItem getItem() {
return item.get();
}
public int getActionScriptScrollHorizontal() {
return actionScriptScrollHorizontal;
}
public int getActionScriptScrollVertical() {
return actionScriptScrollVertical;
}
public int getActionScriptCaret() {
return actionScriptCaret;
}
public int getPcodeScrollHorizontal() {
return pcodeScrollHorizontal;
}
public int getPcodeScrollVertical() {
return pcodeScrollVertical;
}
public int getPcodeCaret() {
return pcodeCaret;
}
public int getFolderPreviewScrollVertical() {
return folderPreviewScrollVertical;
}
public int getFolderListScrollVertical() {
return folderListScrollVertical;
}
public ScrollPosItem(TreeItem item, int actionScriptScrollHorizontal, int actionScriptScrollVertical, int actionScriptCaret, int pcodeScrollHorizontal, int pcodeScrollVertical, int pcodeCaret, int folderPreviewScrollVertical, int folderListScrollVertical) {
this.item = new WeakReference<>(item);
this.actionScriptScrollHorizontal = actionScriptScrollHorizontal;
this.actionScriptScrollVertical = actionScriptScrollVertical;
this.actionScriptCaret = actionScriptCaret;
this.pcodeScrollHorizontal = pcodeScrollHorizontal;
this.pcodeScrollVertical = pcodeScrollVertical;
this.pcodeCaret = pcodeCaret;
this.folderPreviewScrollVertical = folderPreviewScrollVertical;
this.folderListScrollVertical = folderListScrollVertical;
}
@Override
public int hashCode() {
int hash = 5;
hash = 79 * hash + Objects.hashCode(this.item.get());
hash = 79 * hash + this.actionScriptScrollHorizontal;
hash = 79 * hash + this.actionScriptScrollVertical;
hash = 79 * hash + this.actionScriptCaret;
hash = 79 * hash + this.pcodeScrollHorizontal;
hash = 79 * hash + this.pcodeScrollVertical;
hash = 79 * hash + this.pcodeCaret;
hash = 79 * hash + this.folderPreviewScrollVertical;
hash = 79 * hash + this.folderListScrollVertical;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ScrollPosItem other = (ScrollPosItem) obj;
if (this.actionScriptScrollHorizontal != other.actionScriptScrollHorizontal) {
return false;
}
if (this.actionScriptScrollVertical != other.actionScriptScrollVertical) {
return false;
}
if (this.actionScriptCaret != other.actionScriptCaret) {
return false;
}
if (this.pcodeScrollHorizontal != other.pcodeScrollHorizontal) {
return false;
}
if (this.pcodeScrollVertical != other.pcodeScrollVertical) {
return false;
}
if (this.pcodeCaret != other.pcodeCaret) {
return false;
}
if (this.folderPreviewScrollVertical != other.folderPreviewScrollVertical) {
return false;
}
if (this.folderListScrollVertical != other.folderListScrollVertical) {
return false;
}
return this.item.get() == other.item.get();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("ScrollPosItem{");
sb.append("actionScriptScrollHorizontal=").append(actionScriptScrollHorizontal);
sb.append(", actionScriptScrollVertical=").append(actionScriptScrollVertical);
sb.append(", actionScriptCaret=").append(actionScriptCaret);
sb.append(", pcodeScrollHorizontal=").append(pcodeScrollHorizontal);
sb.append(", pcodeScrollVertical=").append(pcodeScrollVertical);
sb.append(", pcodeCaret=").append(pcodeCaret);
sb.append(", folderPreviewScrollVertical=").append(folderPreviewScrollVertical);
sb.append(", folderListScrollVertical=").append(folderListScrollVertical);
sb.append('}');
return sb.toString();
}
public boolean isEmpty() {
if (actionScriptScrollHorizontal > 0) {
return false;
}
if (actionScriptScrollVertical > 0) {
return false;
}
if (actionScriptCaret > 0) {
return false;
}
if (pcodeScrollHorizontal > 0) {
return false;
}
if (pcodeScrollVertical > 0) {
return false;
}
if (pcodeCaret > 0) {
return false;
}
if (folderPreviewScrollVertical > 0) {
return false;
}
if (folderListScrollVertical > 0) {
return false;
}
return true;
}
}

View File

@@ -94,10 +94,26 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL
private CancellableWorker setSourceWorker;
private final List<Runnable> scriptListeners = new ArrayList<>();
private boolean scriptLoaded = true;
public void addScriptListener(Runnable l) {
scriptListeners.add(l);
}
public void runWhenLoaded(Runnable l) {
if (scriptLoaded) {
l.run();
} else {
addScriptListener(new Runnable() {
@Override
public void run() {
l.run();
removeScriptListener(this);
}
});
}
}
public ABCPanel getAbcPanel() {
return abcPanel;
@@ -771,11 +787,14 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL
setSourceWorker.cancel(true);
setSourceWorker = null;
}
scriptLoaded = false;
if (!force && this.script == scriptLeaf) {
if (!force && this.script == scriptLeaf) {
scriptLoaded = true;
fireScript();
return;
}
String sn = scriptLeaf.getClassPath().toString();
setScriptName(sn);
@@ -881,6 +900,8 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL
}
}
}
scriptLoaded = true;
fireScript();
}

View File

@@ -47,6 +47,8 @@ public class MethodCodePanel extends JPanel {
private final ASMSourceEditorPane sourceTextArea;
private final FasterScrollPane sourceScrollPane;
public JPanel buttonsPanel;
private final JToggleButton hexButton;
@@ -58,6 +60,10 @@ public class MethodCodePanel extends JPanel {
public ABC getABC() {
return sourceTextArea.abc;
}
public FasterScrollPane getSourceScrollPane() {
return sourceScrollPane;
}
public void refreshMarkers() {
sourceTextArea.refreshMarkers();
@@ -127,9 +133,9 @@ public class MethodCodePanel extends JPanel {
docsPanel = new DocsPanel();
sourceTextArea.addDocsListener(docsPanel);
if (Configuration.displayAs3PCodeDocsPanel.get()) {
add(new JPersistentSplitPane(JSplitPane.VERTICAL_SPLIT, new FasterScrollPane(sourceTextArea), new FasterScrollPane(docsPanel), Configuration.guiAvm2DocsSplitPaneDividerLocationPercent));
add(new JPersistentSplitPane(JSplitPane.VERTICAL_SPLIT, sourceScrollPane = new FasterScrollPane(sourceTextArea), new FasterScrollPane(docsPanel), Configuration.guiAvm2DocsSplitPaneDividerLocationPercent));
} else {
add(new FasterScrollPane(sourceTextArea));
add(sourceScrollPane = new FasterScrollPane(sourceTextArea));
}
sourceTextArea.changeContentType("text/flasm3");
sourceTextArea.setFont(Configuration.getSourceFont());

View File

@@ -182,6 +182,8 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
private CancellableWorker setSourceWorker;
private List<Runnable> scriptListeners = new ArrayList<>();
private boolean scriptLoaded = true;
public void addScriptListener(Runnable listener) {
scriptListeners.add(listener);
@@ -190,6 +192,20 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
public void removeScriptListener(Runnable listener) {
scriptListeners.remove(listener);
}
public void runWhenLoaded(Runnable l) {
if (scriptLoaded) {
l.run();
} else {
addScriptListener(new Runnable() {
@Override
public void run() {
l.run();
removeScriptListener(this);
}
});
}
}
private void fireScript() {
List<Runnable> list = new ArrayList<>(scriptListeners);
@@ -462,6 +478,8 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
public void setSource(final ASMSource src, final boolean useCache) {
View.checkAccess();
scriptLoaded = false;
if (setSourceWorker != null) {
setSourceWorker.cancel(true);
@@ -570,6 +588,7 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
setHex(getExportMode(), asm.getScriptName(), actions);
setDecompiledText(asm.getScriptName(), decompiledText.text);
scriptLoaded = true;
fireScript();
}

View File

@@ -671,3 +671,15 @@ config.description.svgRetainBounds = During SVG export, the x, y position of the
config.name.disableBitmapSmoothing = Disable bitmap smoothing
config.description.disableBitmapSmoothing = Disable smoothed bitmap fills during display - show all as nonsmoothed (pixelated). This does not apply to exported images.
config.name.pinnedItemsScrollPos = Pinned items scroll/caret positions
config.description.pinnedItemsScrollPos = Scroll or caret positions of pinned items.
config.name.maxRememberedScrollposItems = Max number of remembered scroll positions
config.description.maxRememberedScrollposItems = Maximum number of remembered scroll position items.
config.name.rememberScriptsScrollPos = Remember scripts scroll/caret position
config.description.rememberScriptsScrollPos = The script scroll/caret position is retained when switching items and saved for pinned items.
config.name.rememberFoldersScrollPos = Remember folders scroll position
config.description.rememberFoldersScrollPos = Folders scroll position is retained when switching items and saved for pinned items.

View File

@@ -661,3 +661,15 @@ config.description.svgRetainBounds = B\u011bhem exportu SVG bude pozice tvaru x
config.name.disableBitmapSmoothing = Zak\u00e1zat vyhlazov\u00e1n\u00ed bitmap
config.description.disableBitmapSmoothing = Zak\u00e1\u017ee vyhlazovan\u00e9 bitmapov\u00e9 v\u00fdpln\u011b b\u011bhem zobrazen\u00ed - zobraz\u00ed v\u0161e jako nevyhlazen\u00e9 (pixelovan\u00e9). Toto se neaplikuje na exportovan\u00e9 obr\u00e1zky.
config.name.pinnedItemsScrollPos = Pozice odskrolov\u00e1n\u00ed/kurzoru pro p\u0159ipnut\u00e9 polo\u017eky
config.description.pinnedItemsScrollPos = Pozice odskrolov\u00e1n\u00ed \u010di kurzoru p\u0159ipnut\u00fdch polo\u017eek.
config.name.maxRememberedScrollposItems = Maxim\u00e1ln\u00ed po\u010det zapamatovan\u00fdch pozic odskrolov\u00e1n\u00ed
config.description.maxRememberedScrollposItems = Maxim\u00e1ln\u00ed po\u010det zapamatovan\u00fdch pozic odskrolov\u00e1n\u00ed.
config.name.rememberScriptsScrollPos = Zapamatovat pozici odskrolov\u00e1n\u00ed/kurzoru u skript\u016f
config.description.rememberScriptsScrollPos = Pozice odskrolov\u00e1n\u00ed/kurzoru u skript\u016f je zachov\u00e1na p\u0159i p\u0159ep\u00edn\u00e1n\u00ed mezi polo\u017ekami a ukl\u00e1d\u00e1na pro p\u0159ipnut\u00e9 polo\u017eky.
config.name.rememberFoldersScrollPos = Zapamatovat pozici odskrolov\u00e1n\u00ed u slo\u017eek
config.description.rememberFoldersScrollPos = Pozice odskrolov\u00e1n\u00ed u slo\u017eek je zachov\u00e1na p\u0159i p\u0159ep\u00edn\u00e1n\u00ed mezi polo\u017ekami a ukl\u00e1d\u00e1na pro p\u0159ipnut\u00e9 polo\u017eky.