summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/gui/ClassSelector.java
diff options
context:
space:
mode:
authorGravatar Michael Smith2015-05-21 23:30:00 +0100
committerGravatar Michael Smith2015-05-21 23:30:00 +0100
commite3f452250e51b7271f3989c7dfd12e4422934942 (patch)
tree5aa482f9a6e21eb318a3e23e7d8274d77c73faf6 /src/cuchaz/enigma/gui/ClassSelector.java
downloadenigma-fork-e3f452250e51b7271f3989c7dfd12e4422934942.tar.gz
enigma-fork-e3f452250e51b7271f3989c7dfd12e4422934942.tar.xz
enigma-fork-e3f452250e51b7271f3989c7dfd12e4422934942.zip
Support Gradle alongside SSJB
This makes builds faster, simpler and better automated but still keeps Cuchaz happy. :)
Diffstat (limited to 'src/cuchaz/enigma/gui/ClassSelector.java')
-rw-r--r--src/cuchaz/enigma/gui/ClassSelector.java293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/cuchaz/enigma/gui/ClassSelector.java b/src/cuchaz/enigma/gui/ClassSelector.java
new file mode 100644
index 0000000..11333a9
--- /dev/null
+++ b/src/cuchaz/enigma/gui/ClassSelector.java
@@ -0,0 +1,293 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13import java.awt.event.MouseAdapter;
14import java.awt.event.MouseEvent;
15import java.util.Collection;
16import java.util.Collections;
17import java.util.Comparator;
18import java.util.Enumeration;
19import java.util.List;
20import java.util.Map;
21
22import javax.swing.JTree;
23import javax.swing.tree.DefaultMutableTreeNode;
24import javax.swing.tree.DefaultTreeModel;
25import javax.swing.tree.TreePath;
26
27import com.google.common.collect.ArrayListMultimap;
28import com.google.common.collect.Lists;
29import com.google.common.collect.Maps;
30import com.google.common.collect.Multimap;
31
32import cuchaz.enigma.mapping.ClassEntry;
33
34public class ClassSelector extends JTree {
35
36 private static final long serialVersionUID = -7632046902384775977L;
37
38 public interface ClassSelectionListener {
39 void onSelectClass(ClassEntry classEntry);
40 }
41
42 public static Comparator<ClassEntry> ObfuscatedClassEntryComparator;
43 public static Comparator<ClassEntry> DeobfuscatedClassEntryComparator;
44
45 static {
46 ObfuscatedClassEntryComparator = new Comparator<ClassEntry>() {
47 @Override
48 public int compare(ClassEntry a, ClassEntry b) {
49 String aname = a.getName();
50 String bname = a.getName();
51 if (aname.length() != bname.length()) {
52 return aname.length() - bname.length();
53 }
54 return aname.compareTo(bname);
55 }
56 };
57
58 DeobfuscatedClassEntryComparator = new Comparator<ClassEntry>() {
59 @Override
60 public int compare(ClassEntry a, ClassEntry b) {
61 if (a instanceof ScoredClassEntry && b instanceof ScoredClassEntry) {
62 return Float.compare(
63 ((ScoredClassEntry)b).getScore(),
64 ((ScoredClassEntry)a).getScore()
65 );
66 }
67 return a.getName().compareTo(b.getName());
68 }
69 };
70 }
71
72 private ClassSelectionListener m_listener;
73 private Comparator<ClassEntry> m_comparator;
74
75 public ClassSelector(Comparator<ClassEntry> comparator) {
76 m_comparator = comparator;
77
78 // configure the tree control
79 setRootVisible(false);
80 setShowsRootHandles(false);
81 setModel(null);
82
83 // hook events
84 addMouseListener(new MouseAdapter() {
85 @Override
86 public void mouseClicked(MouseEvent event) {
87 if (m_listener != null && event.getClickCount() == 2) {
88 // get the selected node
89 TreePath path = getSelectionPath();
90 if (path != null && path.getLastPathComponent() instanceof ClassSelectorClassNode) {
91 ClassSelectorClassNode node = (ClassSelectorClassNode)path.getLastPathComponent();
92 m_listener.onSelectClass(node.getClassEntry());
93 }
94 }
95 }
96 });
97
98 // init defaults
99 m_listener = null;
100 }
101
102 public void setListener(ClassSelectionListener val) {
103 m_listener = val;
104 }
105
106 public void setClasses(Collection<ClassEntry> classEntries) {
107 if (classEntries == null) {
108 setModel(null);
109 return;
110 }
111
112 // build the package names
113 Map<String,ClassSelectorPackageNode> packages = Maps.newHashMap();
114 for (ClassEntry classEntry : classEntries) {
115 packages.put(classEntry.getPackageName(), null);
116 }
117
118 // sort the packages
119 List<String> sortedPackageNames = Lists.newArrayList(packages.keySet());
120 Collections.sort(sortedPackageNames, new Comparator<String>() {
121 @Override
122 public int compare(String a, String b) {
123 // I can never keep this rule straight when writing these damn things...
124 // a < b => -1, a == b => 0, a > b => +1
125
126 String[] aparts = a.split("/");
127 String[] bparts = b.split("/");
128 for (int i = 0; true; i++) {
129 if (i >= aparts.length) {
130 return -1;
131 } else if (i >= bparts.length) {
132 return 1;
133 }
134
135 int result = aparts[i].compareTo(bparts[i]);
136 if (result != 0) {
137 return result;
138 }
139 }
140 }
141 });
142
143 // create the root node and the package nodes
144 DefaultMutableTreeNode root = new DefaultMutableTreeNode();
145 for (String packageName : sortedPackageNames) {
146 ClassSelectorPackageNode node = new ClassSelectorPackageNode(packageName);
147 packages.put(packageName, node);
148 root.add(node);
149 }
150
151 // put the classes into packages
152 Multimap<String,ClassEntry> packagedClassEntries = ArrayListMultimap.create();
153 for (ClassEntry classEntry : classEntries) {
154 packagedClassEntries.put(classEntry.getPackageName(), classEntry);
155 }
156
157 // build the class nodes
158 for (String packageName : packagedClassEntries.keySet()) {
159 // sort the class entries
160 List<ClassEntry> classEntriesInPackage = Lists.newArrayList(packagedClassEntries.get(packageName));
161 Collections.sort(classEntriesInPackage, m_comparator);
162
163 // create the nodes in order
164 for (ClassEntry classEntry : classEntriesInPackage) {
165 ClassSelectorPackageNode node = packages.get(packageName);
166 node.add(new ClassSelectorClassNode(classEntry));
167 }
168 }
169
170 // finally, update the tree control
171 setModel(new DefaultTreeModel(root));
172 }
173
174 public ClassEntry getSelectedClass() {
175 if (!isSelectionEmpty()) {
176 Object selectedNode = getSelectionPath().getLastPathComponent();
177 if (selectedNode instanceof ClassSelectorClassNode) {
178 ClassSelectorClassNode classNode = (ClassSelectorClassNode)selectedNode;
179 return classNode.getClassEntry();
180 }
181 }
182 return null;
183 }
184
185 public String getSelectedPackage() {
186 if (!isSelectionEmpty()) {
187 Object selectedNode = getSelectionPath().getLastPathComponent();
188 if (selectedNode instanceof ClassSelectorPackageNode) {
189 ClassSelectorPackageNode packageNode = (ClassSelectorPackageNode)selectedNode;
190 return packageNode.getPackageName();
191 } else if (selectedNode instanceof ClassSelectorClassNode) {
192 ClassSelectorClassNode classNode = (ClassSelectorClassNode)selectedNode;
193 return classNode.getClassEntry().getPackageName();
194 }
195 }
196 return null;
197 }
198
199 public Iterable<ClassSelectorPackageNode> packageNodes() {
200 List<ClassSelectorPackageNode> nodes = Lists.newArrayList();
201 DefaultMutableTreeNode root = (DefaultMutableTreeNode)getModel().getRoot();
202 Enumeration<?> children = root.children();
203 while (children.hasMoreElements()) {
204 ClassSelectorPackageNode packageNode = (ClassSelectorPackageNode)children.nextElement();
205 nodes.add(packageNode);
206 }
207 return nodes;
208 }
209
210 public Iterable<ClassSelectorClassNode> classNodes(ClassSelectorPackageNode packageNode) {
211 List<ClassSelectorClassNode> nodes = Lists.newArrayList();
212 Enumeration<?> children = packageNode.children();
213 while (children.hasMoreElements()) {
214 ClassSelectorClassNode classNode = (ClassSelectorClassNode)children.nextElement();
215 nodes.add(classNode);
216 }
217 return nodes;
218 }
219
220 public void expandPackage(String packageName) {
221 if (packageName == null) {
222 return;
223 }
224 for (ClassSelectorPackageNode packageNode : packageNodes()) {
225 if (packageNode.getPackageName().equals(packageName)) {
226 expandPath(new TreePath(new Object[] {getModel().getRoot(), packageNode}));
227 return;
228 }
229 }
230 }
231
232 public void expandAll() {
233 for (ClassSelectorPackageNode packageNode : packageNodes()) {
234 expandPath(new TreePath(new Object[] {getModel().getRoot(), packageNode}));
235 }
236 }
237
238 public ClassEntry getFirstClass() {
239 for (ClassSelectorPackageNode packageNode : packageNodes()) {
240 for (ClassSelectorClassNode classNode : classNodes(packageNode)) {
241 return classNode.getClassEntry();
242 }
243 }
244 return null;
245 }
246
247 public ClassSelectorPackageNode getPackageNode(ClassEntry entry) {
248 for (ClassSelectorPackageNode packageNode : packageNodes()) {
249 if (packageNode.getPackageName().equals(entry.getPackageName())) {
250 return packageNode;
251 }
252 }
253 return null;
254 }
255
256 public ClassEntry getNextClass(ClassEntry entry) {
257 boolean foundIt = false;
258 for (ClassSelectorPackageNode packageNode : packageNodes()) {
259 if (!foundIt) {
260 // skip to the package with our target in it
261 if (packageNode.getPackageName().equals(entry.getPackageName())) {
262 for (ClassSelectorClassNode classNode : classNodes(packageNode)) {
263 if (!foundIt) {
264 if (classNode.getClassEntry().equals(entry)) {
265 foundIt = true;
266 }
267 } else {
268 // return the next class
269 return classNode.getClassEntry();
270 }
271 }
272 }
273 } else {
274 // return the next class
275 for (ClassSelectorClassNode classNode : classNodes(packageNode)) {
276 return classNode.getClassEntry();
277 }
278 }
279 }
280 return null;
281 }
282
283 public void setSelectionClass(ClassEntry classEntry) {
284 expandPackage(classEntry.getPackageName());
285 for (ClassSelectorPackageNode packageNode : packageNodes()) {
286 for (ClassSelectorClassNode classNode : classNodes(packageNode)) {
287 if (classNode.getClassEntry().equals(classEntry)) {
288 setSelectionPath(new TreePath(new Object[] {getModel().getRoot(), packageNode, classNode}));
289 }
290 }
291 }
292 }
293}