Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@
import org.quiltmc.enigma.api.source.TokenType;
import org.quiltmc.enigma.api.translation.representation.entry.Entry;

import javax.annotation.Nullable;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.event.ItemEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* A panel with buttons to navigate to the next and previous items in its entry collection.
Expand All @@ -31,7 +34,8 @@ public class NavigatorPanel extends JPanel {

private final Gui gui;
private final JLabel statsLabel;
private final Map<TokenType, List<Entry<?>>> entries = new HashMap<>();
private final Set<Entry<?>> allEntries = new LinkedHashSet<>();
private final Map<TokenType, Map<Entry<?>, Integer>> entryIndexesByType = new HashMap<>();

private int currentIndex = 0;
private TokenType selectedType;
Expand All @@ -54,9 +58,7 @@ public NavigatorPanel(Gui gui) {
});
this.selectedType = TokenType.OBFUSCATED;

for (TokenType type : SUPPORTED_TOKEN_TYPES) {
this.entries.put(type, new ArrayList<>());
}
this.initEntryIndexesByType();

JButton up = new JButton(GuiUtil.getUpChevron());
up.addActionListener(event -> this.navigateUp());
Expand All @@ -72,6 +74,12 @@ public NavigatorPanel(Gui gui) {
this.setBackground(new Color(0, 0, 0, 0));
}

private void initEntryIndexesByType() {
for (TokenType type : SUPPORTED_TOKEN_TYPES) {
this.entryIndexesByType.put(type, new LinkedHashMap<>());
}
}

/**
* Navigates to the next entry matching the current filter.
*/
Expand All @@ -92,10 +100,10 @@ private void onTypeChange() {
}

private void wrapIndex() {
List<Entry<?>> currentEntrySet = this.entries.get(this.selectedType);
final int selectedEntryTypeCount = this.entryIndexesByType.get(this.selectedType).size();
if (this.currentIndex < 0) {
this.currentIndex = currentEntrySet.size() - 1;
} else if (this.currentIndex >= currentEntrySet.size()) {
this.currentIndex = selectedEntryTypeCount - 1;
} else if (this.currentIndex >= selectedEntryTypeCount) {
this.currentIndex = 0;
}
}
Expand All @@ -105,16 +113,16 @@ public void decrementIndex() {
}

private void tryNavigate(boolean reverse) {
List<Entry<?>> currentEntrySet = this.entries.get(this.selectedType);
if (!currentEntrySet.isEmpty()) {
Entry<?> entry = this.getClosestEntryToCursor(currentEntrySet, reverse);
Map<Entry<?>, Integer> selectedEntryIndexes = this.entryIndexesByType.get(this.selectedType);
if (!selectedEntryIndexes.isEmpty()) {
Entry<?> entry = this.getClosestEntryToCursor(selectedEntryIndexes.keySet(), reverse);
this.gui.getController().navigateTo(entry);
this.currentIndex = currentEntrySet.indexOf(entry);
this.currentIndex = selectedEntryIndexes.get(entry);
this.updateStatsLabel();
}
}

public Entry<?> getClosestEntryToCursor(List<Entry<?>> currentEntrySet, boolean reverse) {
public Entry<?> getClosestEntryToCursor(Collection<Entry<?>> currentEntrySet, boolean reverse) {
List<Entry<?>> possibleEntriesCopy = new ArrayList<>(currentEntrySet);
if (reverse) {
Collections.reverse(possibleEntriesCopy);
Expand All @@ -134,54 +142,40 @@ public Entry<?> getClosestEntryToCursor(List<Entry<?>> currentEntrySet, boolean
return possibleEntriesCopy.get(0);
}

/**
* Adds the provided entry to this navigator's pool and sorts it.
* @param entry the entry to add
*/
public void addEntry(@Nullable Entry<?> entry) {
EnigmaProject project = this.gui.getController().getProject();
if (entry != null && this.gui.isEditable(EditableType.fromEntry(entry)) && project.isRenamable(entry) && project.isNavigable(entry)) {
TokenType tokenType = this.getTokenType(entry);
List<Entry<?>> entries = this.entries.get(tokenType);
public void resetEntries(Iterable<Entry<?>> newEntries) {
this.allEntries.clear();
this.initEntryIndexesByType();

if (!entries.contains(entry)) {
entries.add(entry);
this.updateStatsLabel();
EnigmaProject project = this.gui.getController().getProject();
for (Entry<?> entry : newEntries) {
if (entry != null && this.gui.isEditable(EditableType.fromEntry(entry)) && project.isRenamable(entry) && project.isNavigable(entry)) {
if (!this.allEntries.contains(entry)) {
Map<Entry<?>, Integer> entryIndexesOfType = this.entryIndexesByType.get(this.getTokenType(entry));
if (entryIndexesOfType != null) {
this.allEntries.add(entry);
entryIndexesOfType.put(entry, entryIndexesOfType.size());
}
}
}
}

this.updateStatsLabel();
}

/**
* Rechecks and updates all token types.
* @see #updateTokenType(Entry)
*/
public void updateAllTokenTypes() {
for (var list : this.entries.values()) {
var copy = new ArrayList<>(list);
this.initEntryIndexesByType();

for (var target : copy) {
this.updateTokenType(target);
for (Entry<?> entry : this.allEntries) {
Map<Entry<?>, Integer> entryIndexesOfType = this.entryIndexesByType.get(this.getTokenType(entry));
if (entryIndexesOfType != null) {
entryIndexesOfType.put(entry, entryIndexesOfType.size());
}
}
}

/**
* Checks if the entry should be moved to a different token type, and updates it if so.
* Assumes that the entry's old token type matches the currently selected token type.
* @param target the entry to check
*/
public void updateTokenType(Entry<?> target) {
TokenType tokenType = this.getTokenType(target);
for (var entry : this.entries.entrySet()) {
if (entry.getValue() != null && entry.getValue().remove(target)) {
break;
}
}

this.entries.get(tokenType).add(target);
this.updateStatsLabel();
}

private TokenType getTokenType(Entry<?> target) {
// make sure we're checking from the root of the inheritance tree
EnigmaProject project = this.gui.getController().getProject();
Expand All @@ -191,8 +185,13 @@ private TokenType getTokenType(Entry<?> target) {
}

private void updateStatsLabel() {
int index = this.entries.get(this.selectedType).isEmpty() ? 0 : this.currentIndex + 1;
String indexString = String.valueOf(index).length() == 1 ? "0" + index : String.valueOf(index);
this.statsLabel.setText(indexString + "/" + this.entries.get(this.selectedType).size());
final Map<Entry<?>, Integer> entryIndexesOfType = this.entryIndexesByType.get(this.selectedType);
final String index = String.valueOf(entryIndexesOfType.isEmpty() ? 0 : this.currentIndex + 1);
final String total = String.valueOf(entryIndexesOfType.size());

final int lengthDiff = total.length() - index.length();
final String paddedIndex = lengthDiff == 0 ? index : "0".repeat(lengthDiff) + index;

this.statsLabel.setText(paddedIndex + "/" + total);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,7 @@ public void setSource(DecompiledClassSource source) {
this.setHighlightedTokens(source.getTokenStore(), source.getHighlightedTokens());
if (this.source != null) {
this.editor.setCaretPosition(newCaretPos);

for (Entry<?> entry : this.source.getIndex().declarations()) {
this.navigatorPanel.addEntry(entry);
}
this.navigatorPanel.resetEntries(this.source.getIndex().declarations());
}

this.setCursorReference(this.getReference(this.getToken(this.editor.getCaretPosition())));
Expand Down