diff options
| author | 2025-10-18 17:50:51 +0200 | |
|---|---|---|
| committer | 2025-10-18 16:50:51 +0100 | |
| commit | 79751d99e8a0945a21344684df43edda3ba21e0c (patch) | |
| tree | 5b112c017a2f242c71d91c97edb07d20e7c2f9e1 /enigma-swing/src/main | |
| parent | Track mapping loading progress for the Enigma directory format (#577) (diff) | |
| download | enigma-fork-79751d99e8a0945a21344684df43edda3ba21e0c.tar.gz enigma-fork-79751d99e8a0945a21344684df43edda3ba21e0c.tar.xz enigma-fork-79751d99e8a0945a21344684df43edda3ba21e0c.zip | |
Move to next token when using the tabulator (#573)
Diffstat (limited to 'enigma-swing/src/main')
3 files changed, 58 insertions, 17 deletions
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java index 301ae7f..2b80765 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java | |||
| @@ -18,6 +18,7 @@ import javax.swing.text.Document; | |||
| 18 | import com.formdev.flatlaf.FlatClientProperties; | 18 | import com.formdev.flatlaf.FlatClientProperties; |
| 19 | 19 | ||
| 20 | import cuchaz.enigma.gui.events.ConvertingTextFieldListener; | 20 | import cuchaz.enigma.gui.events.ConvertingTextFieldListener; |
| 21 | import cuchaz.enigma.gui.events.ConvertingTextFieldListener.StopEditingCause; | ||
| 21 | import cuchaz.enigma.gui.util.GuiUtil; | 22 | import cuchaz.enigma.gui.util.GuiUtil; |
| 22 | import cuchaz.enigma.utils.validation.ParameterizedMessage; | 23 | import cuchaz.enigma.utils.validation.ParameterizedMessage; |
| 23 | import cuchaz.enigma.utils.validation.Validatable; | 24 | import cuchaz.enigma.utils.validation.Validatable; |
| @@ -38,6 +39,7 @@ public class ConvertingTextField implements Validatable { | |||
| 38 | this.ui = new JPanel(); | 39 | this.ui = new JPanel(); |
| 39 | this.ui.setLayout(new GridLayout(1, 1, 0, 0)); | 40 | this.ui.setLayout(new GridLayout(1, 1, 0, 0)); |
| 40 | this.textField = new ValidatableTextField(text); | 41 | this.textField = new ValidatableTextField(text); |
| 42 | this.textField.setFocusTraversalKeysEnabled(false); | ||
| 41 | this.textField.putClientProperty(FlatClientProperties.SELECT_ALL_ON_FOCUS_POLICY, FlatClientProperties.SELECT_ALL_ON_FOCUS_POLICY_NEVER); | 43 | this.textField.putClientProperty(FlatClientProperties.SELECT_ALL_ON_FOCUS_POLICY, FlatClientProperties.SELECT_ALL_ON_FOCUS_POLICY_NEVER); |
| 42 | this.label = GuiUtil.unboldLabel(new JLabel(text)); | 44 | this.label = GuiUtil.unboldLabel(new JLabel(text)); |
| 43 | this.label.setBorder(BorderFactory.createLoweredBevelBorder()); | 45 | this.label.setBorder(BorderFactory.createLoweredBevelBorder()); |
| @@ -53,7 +55,7 @@ public class ConvertingTextField implements Validatable { | |||
| 53 | @Override | 55 | @Override |
| 54 | public void focusLost(FocusEvent e) { | 56 | public void focusLost(FocusEvent e) { |
| 55 | if (!hasChanges()) { | 57 | if (!hasChanges()) { |
| 56 | stopEditing(true); | 58 | stopEditing(StopEditingCause.ABORT); |
| 57 | } | 59 | } |
| 58 | } | 60 | } |
| 59 | }); | 61 | }); |
| @@ -61,10 +63,18 @@ public class ConvertingTextField implements Validatable { | |||
| 61 | this.textField.addKeyListener(new KeyAdapter() { | 63 | this.textField.addKeyListener(new KeyAdapter() { |
| 62 | @Override | 64 | @Override |
| 63 | public void keyPressed(KeyEvent e) { | 65 | public void keyPressed(KeyEvent e) { |
| 64 | if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { | 66 | switch (e.getKeyCode()) { |
| 65 | stopEditing(true); | 67 | case KeyEvent.VK_ESCAPE: |
| 66 | } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { | 68 | stopEditing(StopEditingCause.ABORT); |
| 67 | stopEditing(false); | 69 | break; |
| 70 | case KeyEvent.VK_ENTER: | ||
| 71 | stopEditing(StopEditingCause.DO); | ||
| 72 | break; | ||
| 73 | case KeyEvent.VK_TAB: | ||
| 74 | stopEditing(StopEditingCause.TAB); | ||
| 75 | break; | ||
| 76 | default: | ||
| 77 | break; | ||
| 68 | } | 78 | } |
| 69 | } | 79 | } |
| 70 | }); | 80 | }); |
| @@ -87,16 +97,16 @@ public class ConvertingTextField implements Validatable { | |||
| 87 | this.listeners.forEach(l -> l.onStartEditing(this)); | 97 | this.listeners.forEach(l -> l.onStartEditing(this)); |
| 88 | } | 98 | } |
| 89 | 99 | ||
| 90 | public void stopEditing(boolean abort) { | 100 | public void stopEditing(StopEditingCause cause) { |
| 91 | if (!editing) { | 101 | if (!editing) { |
| 92 | return; | 102 | return; |
| 93 | } | 103 | } |
| 94 | 104 | ||
| 95 | if (!listeners.stream().allMatch(l -> l.tryStopEditing(this, abort))) { | 105 | if (!listeners.stream().allMatch(l -> l.tryStopEditing(this, cause))) { |
| 96 | return; | 106 | return; |
| 97 | } | 107 | } |
| 98 | 108 | ||
| 99 | if (abort) { | 109 | if (cause == StopEditingCause.ABORT) { |
| 100 | this.textField.setText(this.label.getText()); | 110 | this.textField.setText(this.label.getText()); |
| 101 | } else { | 111 | } else { |
| 102 | this.label.setText(this.textField.getText()); | 112 | this.label.setText(this.textField.getText()); |
| @@ -107,11 +117,11 @@ public class ConvertingTextField implements Validatable { | |||
| 107 | this.editing = false; | 117 | this.editing = false; |
| 108 | this.ui.validate(); | 118 | this.ui.validate(); |
| 109 | this.ui.repaint(); | 119 | this.ui.repaint(); |
| 110 | this.listeners.forEach(l -> l.onStopEditing(this, abort)); | 120 | this.listeners.forEach(l -> l.onStopEditing(this, cause)); |
| 111 | } | 121 | } |
| 112 | 122 | ||
| 113 | public void setText(String text) { | 123 | public void setText(String text) { |
| 114 | stopEditing(true); | 124 | stopEditing(StopEditingCause.ABORT); |
| 115 | this.label.setText(text); | 125 | this.label.setText(text); |
| 116 | this.textField.setText(text); | 126 | this.textField.setText(text); |
| 117 | } | 127 | } |
| @@ -126,7 +136,7 @@ public class ConvertingTextField implements Validatable { | |||
| 126 | 136 | ||
| 127 | public void setEditable(boolean editable) { | 137 | public void setEditable(boolean editable) { |
| 128 | if (!editable) { | 138 | if (!editable) { |
| 129 | this.stopEditing(true); | 139 | this.stopEditing(StopEditingCause.ABORT); |
| 130 | } | 140 | } |
| 131 | 141 | ||
| 132 | this.label.setEnabled(editable); | 142 | this.label.setEnabled(editable); |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ConvertingTextFieldListener.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ConvertingTextFieldListener.java index d9ec95c..9f20100 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ConvertingTextFieldListener.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ConvertingTextFieldListener.java | |||
| @@ -3,13 +3,19 @@ package cuchaz.enigma.gui.events; | |||
| 3 | import cuchaz.enigma.gui.elements.ConvertingTextField; | 3 | import cuchaz.enigma.gui.elements.ConvertingTextField; |
| 4 | 4 | ||
| 5 | public interface ConvertingTextFieldListener { | 5 | public interface ConvertingTextFieldListener { |
| 6 | enum StopEditingCause { | ||
| 7 | ABORT, | ||
| 8 | DO, | ||
| 9 | TAB | ||
| 10 | } | ||
| 11 | |||
| 6 | default void onStartEditing(ConvertingTextField field) { | 12 | default void onStartEditing(ConvertingTextField field) { |
| 7 | } | 13 | } |
| 8 | 14 | ||
| 9 | default boolean tryStopEditing(ConvertingTextField field, boolean abort) { | 15 | default boolean tryStopEditing(ConvertingTextField field, StopEditingCause cause) { |
| 10 | return true; | 16 | return true; |
| 11 | } | 17 | } |
| 12 | 18 | ||
| 13 | default void onStopEditing(ConvertingTextField field, boolean abort) { | 19 | default void onStopEditing(ConvertingTextField field, StopEditingCause cause) { |
| 14 | } | 20 | } |
| 15 | } | 21 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java index 4d8ceea..6a8d734 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java | |||
| @@ -13,6 +13,7 @@ import javax.swing.BorderFactory; | |||
| 13 | import javax.swing.JComboBox; | 13 | import javax.swing.JComboBox; |
| 14 | import javax.swing.JLabel; | 14 | import javax.swing.JLabel; |
| 15 | import javax.swing.JPanel; | 15 | import javax.swing.JPanel; |
| 16 | import javax.swing.SwingUtilities; | ||
| 16 | 17 | ||
| 17 | import cuchaz.enigma.EnigmaProject; | 18 | import cuchaz.enigma.EnigmaProject; |
| 18 | import cuchaz.enigma.gui.EditableType; | 19 | import cuchaz.enigma.gui.EditableType; |
| @@ -22,6 +23,8 @@ import cuchaz.enigma.gui.events.ConvertingTextFieldListener; | |||
| 22 | import cuchaz.enigma.gui.util.GridBagConstraintsBuilder; | 23 | import cuchaz.enigma.gui.util.GridBagConstraintsBuilder; |
| 23 | import cuchaz.enigma.gui.util.GuiUtil; | 24 | import cuchaz.enigma.gui.util.GuiUtil; |
| 24 | import cuchaz.enigma.gui.util.ScaleUtil; | 25 | import cuchaz.enigma.gui.util.ScaleUtil; |
| 26 | import cuchaz.enigma.source.RenamableTokenType; | ||
| 27 | import cuchaz.enigma.source.Token; | ||
| 25 | import cuchaz.enigma.translation.mapping.AccessModifier; | 28 | import cuchaz.enigma.translation.mapping.AccessModifier; |
| 26 | import cuchaz.enigma.translation.mapping.EntryChange; | 29 | import cuchaz.enigma.translation.mapping.EntryChange; |
| 27 | import cuchaz.enigma.translation.mapping.EntryMapping; | 30 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| @@ -181,8 +184,8 @@ public class IdentifierPanel { | |||
| 181 | } | 184 | } |
| 182 | 185 | ||
| 183 | @Override | 186 | @Override |
| 184 | public boolean tryStopEditing(ConvertingTextField field, boolean abort) { | 187 | public boolean tryStopEditing(ConvertingTextField field, StopEditingCause cause) { |
| 185 | if (abort) { | 188 | if (cause == StopEditingCause.ABORT) { |
| 186 | return true; | 189 | return true; |
| 187 | } | 190 | } |
| 188 | 191 | ||
| @@ -193,11 +196,33 @@ public class IdentifierPanel { | |||
| 193 | } | 196 | } |
| 194 | 197 | ||
| 195 | @Override | 198 | @Override |
| 196 | public void onStopEditing(ConvertingTextField field, boolean abort) { | 199 | public void onStopEditing(ConvertingTextField field, StopEditingCause cause) { |
| 197 | if (!abort) { | 200 | if (cause != StopEditingCause.ABORT) { |
| 198 | vc.reset(); | 201 | vc.reset(); |
| 199 | vc.setActiveElement(field); | 202 | vc.setActiveElement(field); |
| 200 | doRename(field.getText()); | 203 | doRename(field.getText()); |
| 204 | |||
| 205 | if (cause == StopEditingCause.TAB) { | ||
| 206 | EditorPanel editor = gui.getActiveEditor(); | ||
| 207 | |||
| 208 | if (editor == null) { | ||
| 209 | return; | ||
| 210 | } | ||
| 211 | |||
| 212 | Token token = editor.getToken(editor.getEditor().getCaretPosition()); | ||
| 213 | |||
| 214 | SwingUtilities.invokeLater(() -> { | ||
| 215 | Token next = editor.getSource().getTokenStore().getByType().get(RenamableTokenType.OBFUSCATED).higher(token); | ||
| 216 | |||
| 217 | if (next == null) { | ||
| 218 | editor.getEditor().requestFocusInWindow(); | ||
| 219 | } else { | ||
| 220 | editor.navigateToToken(next); | ||
| 221 | } | ||
| 222 | }); | ||
| 223 | |||
| 224 | return; | ||
| 225 | } | ||
| 201 | } | 226 | } |
| 202 | 227 | ||
| 203 | EditorPanel e = gui.getActiveEditor(); | 228 | EditorPanel e = gui.getActiveEditor(); |