summaryrefslogtreecommitdiff
path: root/enigma-swing
diff options
context:
space:
mode:
authorGravatar Joe2025-08-20 17:15:23 +0100
committerGravatar modmuss2025-09-13 09:14:23 +0100
commitd0a52bb6de19c81705094b26132931a57dc40866 (patch)
tree1ed5009b5c84acef7f1d67e564899a77c327eded /enigma-swing
parentAdd I18n service (diff)
downloadenigma-d0a52bb6de19c81705094b26132931a57dc40866.tar.gz
enigma-d0a52bb6de19c81705094b26132931a57dc40866.tar.xz
enigma-d0a52bb6de19c81705094b26132931a57dc40866.zip
Add GuiService for plugins to make additions to the GUI. Also add enough context to do something useful.
Diffstat (limited to 'enigma-swing')
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java5
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java16
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CustomMenuItem.java49
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java71
4 files changed, 105 insertions, 36 deletions
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java
index 5881900c..12877fed 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java
@@ -45,6 +45,7 @@ import org.jetbrains.annotations.Nullable;
45 45
46import cuchaz.enigma.Enigma; 46import cuchaz.enigma.Enigma;
47import cuchaz.enigma.analysis.EntryReference; 47import cuchaz.enigma.analysis.EntryReference;
48import cuchaz.enigma.api.service.GuiService;
48import cuchaz.enigma.gui.config.Themes; 49import cuchaz.enigma.gui.config.Themes;
49import cuchaz.enigma.gui.config.UiConfig; 50import cuchaz.enigma.gui.config.UiConfig;
50import cuchaz.enigma.gui.dialog.JavadocDialog; 51import cuchaz.enigma.gui.dialog.JavadocDialog;
@@ -142,6 +143,10 @@ public class Gui {
142 LanguageUtil.addListener(this::retranslateUi); 143 LanguageUtil.addListener(this::retranslateUi);
143 Themes.addListener((lookAndFeel, boxHighlightPainters) -> SwingUtilities.updateComponentTreeUI(this.getFrame())); 144 Themes.addListener((lookAndFeel, boxHighlightPainters) -> SwingUtilities.updateComponentTreeUI(this.getFrame()));
144 145
146 for (GuiService guiService : enigma.getServices().get(GuiService.TYPE)) {
147 guiService.onStart(controller);
148 }
149
145 this.mainWindow.setVisible(true); 150 this.mainWindow.setVisible(true);
146 } 151 }
147 152
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
index e1e8521a..3609427d 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
@@ -31,6 +31,7 @@ import javax.swing.JOptionPane;
31import javax.swing.SwingUtilities; 31import javax.swing.SwingUtilities;
32 32
33import org.jetbrains.annotations.ApiStatus; 33import org.jetbrains.annotations.ApiStatus;
34import org.jetbrains.annotations.Nullable;
34 35
35import cuchaz.enigma.Enigma; 36import cuchaz.enigma.Enigma;
36import cuchaz.enigma.EnigmaProject; 37import cuchaz.enigma.EnigmaProject;
@@ -46,6 +47,8 @@ import cuchaz.enigma.analysis.MethodReferenceTreeNode;
46import cuchaz.enigma.analysis.StructureTreeNode; 47import cuchaz.enigma.analysis.StructureTreeNode;
47import cuchaz.enigma.analysis.StructureTreeOptions; 48import cuchaz.enigma.analysis.StructureTreeOptions;
48import cuchaz.enigma.api.service.ObfuscationTestService; 49import cuchaz.enigma.api.service.ObfuscationTestService;
50import cuchaz.enigma.api.view.GuiView;
51import cuchaz.enigma.api.view.entry.EntryReferenceView;
49import cuchaz.enigma.classhandle.ClassHandle; 52import cuchaz.enigma.classhandle.ClassHandle;
50import cuchaz.enigma.classhandle.ClassHandleProvider; 53import cuchaz.enigma.classhandle.ClassHandleProvider;
51import cuchaz.enigma.classprovider.ClasspathClassProvider; 54import cuchaz.enigma.classprovider.ClasspathClassProvider;
@@ -91,7 +94,7 @@ import cuchaz.enigma.utils.Utils;
91import cuchaz.enigma.utils.validation.PrintValidatable; 94import cuchaz.enigma.utils.validation.PrintValidatable;
92import cuchaz.enigma.utils.validation.ValidationContext; 95import cuchaz.enigma.utils.validation.ValidationContext;
93 96
94public class GuiController implements ClientPacketHandler { 97public class GuiController implements ClientPacketHandler, GuiView {
95 private final Gui gui; 98 private final Gui gui;
96 public final Enigma enigma; 99 public final Enigma enigma;
97 100
@@ -115,6 +118,11 @@ public class GuiController implements ClientPacketHandler {
115 this.enigma = enigma; 118 this.enigma = enigma;
116 } 119 }
117 120
121 @Override
122 public EnigmaProject getProject() {
123 return project;
124 }
125
118 public boolean isDirty() { 126 public boolean isDirty() {
119 return project != null && project.getMapper().isDirty(); 127 return project != null && project.getMapper().isDirty();
120 } 128 }
@@ -330,6 +338,12 @@ public class GuiController implements ClientPacketHandler {
330 } 338 }
331 } 339 }
332 340
341 @Override
342 @Nullable
343 public EntryReferenceView getCursorReference() {
344 return gui.getCursorReference();
345 }
346
333 /** 347 /**
334 * Navigates to the declaration with respect to navigation history. 348 * Navigates to the declaration with respect to navigation history.
335 * 349 *
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CustomMenuItem.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CustomMenuItem.java
new file mode 100644
index 00000000..055a00f7
--- /dev/null
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CustomMenuItem.java
@@ -0,0 +1,49 @@
1package cuchaz.enigma.gui.elements;
2
3import java.util.function.BooleanSupplier;
4import java.util.function.Supplier;
5
6import javax.swing.JMenuItem;
7import javax.swing.KeyStroke;
8
9import cuchaz.enigma.api.service.GuiService;
10import cuchaz.enigma.utils.I18n;
11
12public class CustomMenuItem implements GuiService.MenuItemBuilder {
13 private final JMenuItem menuItem;
14 private final Supplier<String> translationKey;
15 private BooleanSupplier enabledCondition = () -> true;
16
17 public CustomMenuItem(JMenuItem menuItem, Supplier<String> translationKey) {
18 this.menuItem = menuItem;
19 this.translationKey = translationKey;
20 menuItem.setText(translationKey.get());
21 }
22
23 @Override
24 public GuiService.MenuItemBuilder setAccelerator(KeyStroke accelerator) {
25 menuItem.setAccelerator(accelerator);
26 return this;
27 }
28
29 @Override
30 public GuiService.MenuItemBuilder setEnabledWhen(BooleanSupplier condition) {
31 this.enabledCondition = condition;
32 return this;
33 }
34
35 @Override
36 public GuiService.MenuItemBuilder setAction(Runnable action) {
37 menuItem.addActionListener(e -> action.run());
38 return this;
39 }
40
41 public void updateUiState() {
42 menuItem.setEnabled(enabledCondition.getAsBoolean());
43 menuItem.setText(I18n.translate(translationKey.get()));
44 }
45
46 public void retranslateUi() {
47 menuItem.setText(I18n.translate(translationKey.get()));
48 }
49}
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java
index dd37798a..8f968f38 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java
@@ -1,13 +1,18 @@
1package cuchaz.enigma.gui.elements; 1package cuchaz.enigma.gui.elements;
2 2
3import java.awt.Component;
3import java.awt.event.InputEvent; 4import java.awt.event.InputEvent;
4import java.awt.event.KeyEvent; 5import java.awt.event.KeyEvent;
6import java.util.ArrayList;
7import java.util.List;
8import java.util.function.Supplier;
5 9
6import javax.swing.JMenuItem; 10import javax.swing.JMenuItem;
7import javax.swing.JPopupMenu; 11import javax.swing.JPopupMenu;
8import javax.swing.KeyStroke; 12import javax.swing.KeyStroke;
9 13
10import cuchaz.enigma.analysis.EntryReference; 14import cuchaz.enigma.analysis.EntryReference;
15import cuchaz.enigma.api.service.GuiService;
11import cuchaz.enigma.gui.EditableType; 16import cuchaz.enigma.gui.EditableType;
12import cuchaz.enigma.gui.Gui; 17import cuchaz.enigma.gui.Gui;
13import cuchaz.enigma.gui.GuiController; 18import cuchaz.enigma.gui.GuiController;
@@ -36,6 +41,7 @@ public class EditorPopupMenu {
36 private final JMenuItem zoomInItem = new JMenuItem(); 41 private final JMenuItem zoomInItem = new JMenuItem();
37 private final JMenuItem zoomOutMenu = new JMenuItem(); 42 private final JMenuItem zoomOutMenu = new JMenuItem();
38 private final JMenuItem resetZoomItem = new JMenuItem(); 43 private final JMenuItem resetZoomItem = new JMenuItem();
44 private final List<CustomMenuItem> customItems = new ArrayList<>();
39 45
40 private final EditorPanel editor; 46 private final EditorPanel editor;
41 private final Gui gui; 47 private final Gui gui;
@@ -102,48 +108,35 @@ public class EditorPopupMenu {
102 this.zoomInItem.addActionListener(event -> editor.offsetEditorZoom(2)); 108 this.zoomInItem.addActionListener(event -> editor.offsetEditorZoom(2));
103 this.zoomOutMenu.addActionListener(event -> editor.offsetEditorZoom(-2)); 109 this.zoomOutMenu.addActionListener(event -> editor.offsetEditorZoom(-2));
104 this.resetZoomItem.addActionListener(event -> editor.resetEditorZoom()); 110 this.resetZoomItem.addActionListener(event -> editor.resetEditorZoom());
111
112 for (GuiService guiService : gui.getController().enigma.getServices().get(GuiService.TYPE)) {
113 guiService.addToEditorContextMenu(gui.getController(), new GuiService.MenuRegistrar() {
114 @Override
115 public void addSeparator() {
116 ui.addSeparator();
117 }
118
119 @Override
120 public GuiService.MenuItemBuilder add(Supplier<String> translationKey) {
121 JMenuItem menuItem = new JMenuItem();
122 ui.add(menuItem);
123 CustomMenuItem item = new CustomMenuItem(menuItem, translationKey);
124 customItems.add(item);
125 return item;
126 }
127 });
128 }
105 } 129 }
106 130
107 // TODO have editor redirect key event to menu so that the actions get 131 // TODO have editor redirect key event to menu so that the actions get
108 // triggered without having to hardcode them here, because this 132 // triggered without having to hardcode them here, because this
109 // is a hack 133 // is a hack
110 public boolean handleKeyEvent(KeyEvent event) { 134 public boolean handleKeyEvent(KeyEvent event) {
111 if (event.isControlDown()) { 135 KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(event);
112 switch (event.getKeyCode()) {
113 case KeyEvent.VK_I:
114 this.showInheritanceItem.doClick();
115 return true;
116 case KeyEvent.VK_M:
117 this.showImplementationsItem.doClick();
118 return true;
119 case KeyEvent.VK_N:
120 this.openEntryItem.doClick();
121 return true;
122 case KeyEvent.VK_P:
123 this.openPreviousItem.doClick();
124 return true;
125 case KeyEvent.VK_E:
126 this.openNextItem.doClick();
127 return true;
128 case KeyEvent.VK_C:
129 if (event.isShiftDown()) {
130 this.showCallsSpecificItem.doClick();
131 } else {
132 this.showCallsItem.doClick();
133 }
134 136
135 return true; 137 for (Component component : ui.getComponents()) {
136 case KeyEvent.VK_O: 138 if (component instanceof JMenuItem menuItem && keyStroke.equals(menuItem.getAccelerator())) {
137 this.toggleMappingItem.doClick(); 139 menuItem.doClick();
138 return true;
139 case KeyEvent.VK_R:
140 this.renameItem.doClick();
141 return true;
142 case KeyEvent.VK_D:
143 this.editJavadocItem.doClick();
144 return true;
145 case KeyEvent.VK_V:
146 this.pasteItem.doClick();
147 return true; 140 return true;
148 } 141 }
149 } 142 }
@@ -184,6 +177,10 @@ public class EditorPopupMenu {
184 } 177 }
185 178
186 this.toggleMappingItem.setText(I18n.translate("popup_menu." + (isDeobfuscated ? "reset_obfuscated" : "mark_deobfuscated"))); 179 this.toggleMappingItem.setText(I18n.translate("popup_menu." + (isDeobfuscated ? "reset_obfuscated" : "mark_deobfuscated")));
180
181 for (CustomMenuItem customItem : customItems) {
182 customItem.updateUiState();
183 }
187 } 184 }
188 185
189 public void retranslateUi() { 186 public void retranslateUi() {
@@ -201,6 +198,10 @@ public class EditorPopupMenu {
201 this.zoomInItem.setText(I18n.translate("popup_menu.zoom.in")); 198 this.zoomInItem.setText(I18n.translate("popup_menu.zoom.in"));
202 this.zoomOutMenu.setText(I18n.translate("popup_menu.zoom.out")); 199 this.zoomOutMenu.setText(I18n.translate("popup_menu.zoom.out"));
203 this.resetZoomItem.setText(I18n.translate("popup_menu.zoom.reset")); 200 this.resetZoomItem.setText(I18n.translate("popup_menu.zoom.reset"));
201
202 for (CustomMenuItem customItem : customItems) {
203 customItem.retranslateUi();
204 }
204 } 205 }
205 206
206 public JPopupMenu getUi() { 207 public JPopupMenu getUi() {