summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar YanisBft2023-09-25 23:34:30 +0200
committerGravatar GitHub2023-09-25 22:34:30 +0100
commit1554e32e9384a6bc2cd168e061595917e1687e25 (patch)
treea77971e5a21912bda38a5b7723369bbf92972248
parentFix documenting constructors (again) (#530) (diff)
downloadenigma-fork-1554e32e9384a6bc2cd168e061595917e1687e25.tar.gz
enigma-fork-1554e32e9384a6bc2cd168e061595917e1687e25.tar.xz
enigma-fork-1554e32e9384a6bc2cd168e061595917e1687e25.zip
Search dialog improvements (#529)
* Improve search dialogs * fix checkstyle * change search class keystroke * better dialog title & don't calculate score if not needed
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java34
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java4
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchUtil.java17
-rw-r--r--enigma/src/main/resources/lang/en_us.json1
4 files changed, 47 insertions, 9 deletions
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java
index 7814dd8..536ebca 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java
@@ -29,6 +29,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
29 29
30import javax.swing.DefaultListModel; 30import javax.swing.DefaultListModel;
31import javax.swing.JButton; 31import javax.swing.JButton;
32import javax.swing.JCheckBox;
32import javax.swing.JDialog; 33import javax.swing.JDialog;
33import javax.swing.JLabel; 34import javax.swing.JLabel;
34import javax.swing.JList; 35import javax.swing.JList;
@@ -55,7 +56,9 @@ import cuchaz.enigma.translation.representation.entry.ParentedEntry;
55import cuchaz.enigma.utils.I18n; 56import cuchaz.enigma.utils.I18n;
56 57
57public class SearchDialog { 58public class SearchDialog {
59 private final JPanel inputPanel;
58 private final JTextField searchField; 60 private final JTextField searchField;
61 private final JCheckBox onlyExactMatchesCheckbox;
59 private DefaultListModel<SearchEntryImpl> classListModel; 62 private DefaultListModel<SearchEntryImpl> classListModel;
60 private final JList<SearchEntryImpl> classList; 63 private final JList<SearchEntryImpl> classList;
61 private final JDialog dialog; 64 private final JDialog dialog;
@@ -69,11 +72,15 @@ public class SearchDialog {
69 72
70 su = new SearchUtil<>(); 73 su = new SearchUtil<>();
71 74
72 dialog = new JDialog(parent.getFrame(), I18n.translate("menu.search"), true); 75 dialog = new JDialog(parent.getFrame(), true);
73 JPanel contentPane = new JPanel(); 76 JPanel contentPane = new JPanel();
74 contentPane.setBorder(ScaleUtil.createEmptyBorder(4, 4, 4, 4)); 77 contentPane.setBorder(ScaleUtil.createEmptyBorder(4, 4, 4, 4));
75 contentPane.setLayout(new BorderLayout(ScaleUtil.scale(4), ScaleUtil.scale(4))); 78 contentPane.setLayout(new BorderLayout(ScaleUtil.scale(4), ScaleUtil.scale(4)));
76 79
80 inputPanel = new JPanel();
81 inputPanel.setLayout(new BorderLayout(ScaleUtil.scale(4), ScaleUtil.scale(4)));
82 contentPane.add(inputPanel, BorderLayout.NORTH);
83
77 searchField = new JTextField(); 84 searchField = new JTextField();
78 searchField.getDocument().addDocumentListener(new DocumentListener() { 85 searchField.getDocument().addDocumentListener(new DocumentListener() {
79 @Override 86 @Override
@@ -108,7 +115,11 @@ public class SearchDialog {
108 } 115 }
109 }); 116 });
110 searchField.addActionListener(e -> openSelected()); 117 searchField.addActionListener(e -> openSelected());
111 contentPane.add(searchField, BorderLayout.NORTH); 118 inputPanel.add(searchField, BorderLayout.NORTH);
119
120 onlyExactMatchesCheckbox = new JCheckBox(I18n.translate("menu.search.only_exact_matches"));
121 onlyExactMatchesCheckbox.addActionListener(e -> updateList());
122 inputPanel.add(onlyExactMatchesCheckbox, BorderLayout.SOUTH);
112 123
113 classListModel = new DefaultListModel<>(); 124 classListModel = new DefaultListModel<>();
114 classList = new JList<>(); 125 classList = new JList<>();
@@ -167,6 +178,7 @@ public class SearchDialog {
167 searchField.requestFocus(); 178 searchField.requestFocus();
168 searchField.selectAll(); 179 searchField.selectAll();
169 180
181 dialog.setTitle(I18n.translate(type.getTranslationKey()));
170 dialog.setVisible(true); 182 dialog.setVisible(true);
171 } 183 }
172 184
@@ -238,7 +250,7 @@ public class SearchDialog {
238 } 250 }
239 }; 251 };
240 252
241 currentSearch = su.asyncSearch(searchField.getText(), (idx, e) -> queue.add(new Order(idx, e))); 253 currentSearch = su.asyncSearch(searchField.getText(), (idx, e) -> queue.add(new Order(idx, e)), onlyExactMatchesCheckbox.isSelected());
242 SwingUtilities.invokeLater(updater); 254 SwingUtilities.invokeLater(updater);
243 } 255 }
244 256
@@ -328,8 +340,18 @@ public class SearchDialog {
328 } 340 }
329 341
330 public enum Type { 342 public enum Type {
331 CLASS, 343 CLASS("menu.search.class"),
332 METHOD, 344 METHOD("menu.search.method"),
333 FIELD 345 FIELD("menu.search.field");
346
347 private final String translationKey;
348
349 Type(String translationKey) {
350 this.translationKey = translationKey;
351 }
352
353 public String getTranslationKey() {
354 return translationKey;
355 }
334 } 356 }
335} 357}
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
index 24a69b6..1cfad50 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
@@ -138,7 +138,9 @@ public class MenuBar {
138 ui.add(this.helpMenu); 138 ui.add(this.helpMenu);
139 139
140 this.saveMappingsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); 140 this.saveMappingsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
141 this.searchClassItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.SHIFT_DOWN_MASK)); 141 this.searchClassItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, InputEvent.CTRL_DOWN_MASK));
142 this.searchMethodItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, InputEvent.CTRL_DOWN_MASK));
143 this.searchFieldItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_3, InputEvent.CTRL_DOWN_MASK));
142 144
143 this.jarOpenItem.addActionListener(_e -> this.onOpenJarClicked()); 145 this.jarOpenItem.addActionListener(_e -> this.onOpenJarClicked());
144 this.jarCloseItem.addActionListener(_e -> this.gui.getController().closeJar()); 146 this.jarCloseItem.addActionListener(_e -> this.gui.getController().closeJar());
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchUtil.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchUtil.java
index c8212ce..67414ca 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchUtil.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchUtil.java
@@ -55,7 +55,7 @@ public class SearchUtil<T extends SearchEntry> {
55 return entries.values().parallelStream().map(e -> new Pair<>(e, e.getScore(term, hitCount.getOrDefault(e.searchEntry.getIdentifier(), 0)))).filter(e -> e.b > 0).sorted(Comparator.comparingDouble(o -> -o.b)).map(e -> e.a.searchEntry).sequential(); 55 return entries.values().parallelStream().map(e -> new Pair<>(e, e.getScore(term, hitCount.getOrDefault(e.searchEntry.getIdentifier(), 0)))).filter(e -> e.b > 0).sorted(Comparator.comparingDouble(o -> -o.b)).map(e -> e.a.searchEntry).sequential();
56 } 56 }
57 57
58 public SearchControl asyncSearch(String term, SearchResultConsumer<T> consumer) { 58 public SearchControl asyncSearch(String term, SearchResultConsumer<T> consumer, boolean onlyExactMatches) {
59 Map<String, Integer> hitCount = new HashMap<>(this.hitCount); 59 Map<String, Integer> hitCount = new HashMap<>(this.hitCount);
60 Map<T, Entry<T>> entries = new HashMap<>(this.entries); 60 Map<T, Entry<T>> entries = new HashMap<>(this.entries);
61 float[] scores = new float[entries.size()]; 61 float[] scores = new float[entries.size()];
@@ -71,6 +71,11 @@ public class SearchUtil<T extends SearchEntry> {
71 return; 71 return;
72 } 72 }
73 73
74 // if onlyExactMatches is true, don't add any entries that don't have an exact match
75 if (onlyExactMatches && value.searchEntry.getSearchableNames().stream().noneMatch(name -> name.equalsIgnoreCase(term))) {
76 return;
77 }
78
74 float score = value.getScore(term, hitCount.getOrDefault(value.searchEntry.getIdentifier(), 0)); 79 float score = value.getScore(term, hitCount.getOrDefault(value.searchEntry.getIdentifier(), 0));
75 80
76 if (score <= 0) { 81 if (score <= 0) {
@@ -140,7 +145,15 @@ public class SearchUtil<T extends SearchEntry> {
140 145
141 public float getScore(String term, int hits) { 146 public float getScore(String term, int hits) {
142 String ucTerm = term.toUpperCase(Locale.ROOT); 147 String ucTerm = term.toUpperCase(Locale.ROOT);
143 float maxScore = (float) Arrays.stream(components).mapToDouble(name -> getScoreFor(ucTerm, name)).max().orElse(0.0); 148 float maxScore;
149
150 // if exact match, make sure it's at the top of the list
151 if (searchEntry.getSearchableNames().stream().anyMatch(name -> name.equalsIgnoreCase(term))) {
152 maxScore = Float.MAX_VALUE / 2;
153 } else {
154 maxScore = (float) Arrays.stream(components).mapToDouble(name -> getScoreFor(ucTerm, name)).max().orElse(0.0);
155 }
156
144 return maxScore * (hits + 1); 157 return maxScore * (hits + 1);
145 } 158 }
146 159
diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json
index 5d7ee25..421620e 100644
--- a/enigma/src/main/resources/lang/en_us.json
+++ b/enigma/src/main/resources/lang/en_us.json
@@ -53,6 +53,7 @@
53 "menu.search.class": "Search Classes", 53 "menu.search.class": "Search Classes",
54 "menu.search.method": "Search Methods", 54 "menu.search.method": "Search Methods",
55 "menu.search.field": "Search Fields", 55 "menu.search.field": "Search Fields",
56 "menu.search.only_exact_matches": "Only show exact matches",
56 "menu.collab": "Collab", 57 "menu.collab": "Collab",
57 "menu.collab.connect": "Connect to Server", 58 "menu.collab.connect": "Connect to Server",
58 "menu.collab.connect.error": "Error connecting to server", 59 "menu.collab.connect.error": "Error connecting to server",