forked from External/mage
* UI: added CTRL/SHIFT/ALT supports for hotkeys (#2042);
This commit is contained in:
parent
b18428f68f
commit
10234d508f
4 changed files with 302 additions and 221 deletions
|
|
@ -1,118 +1,176 @@
|
|||
package mage.client.components;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Campbell Suter <znix@znix.xyz>
|
||||
* @author Campbell Suter <znix@znix.xyz>, JayDi85
|
||||
*/
|
||||
public class KeyBindButton extends JButton implements ActionListener {
|
||||
|
||||
private final PreferencesDialog preferences;
|
||||
private final String key;
|
||||
private PopupItem item;
|
||||
private JPopupMenu menu;
|
||||
private int keyCode;
|
||||
private String text;
|
||||
private final PreferencesDialog preferences;
|
||||
private final String key;
|
||||
private PopupItem item;
|
||||
private JPopupMenu menu;
|
||||
private int keyCode;
|
||||
private int modifierCode;
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* For the IDE only, do not use!
|
||||
*/
|
||||
public KeyBindButton() {
|
||||
this(null, null);
|
||||
}
|
||||
/**
|
||||
* For the IDE only, do not use!
|
||||
*/
|
||||
public KeyBindButton() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
public KeyBindButton(PreferencesDialog preferences, String key) {
|
||||
this.preferences = preferences;
|
||||
this.key = key;
|
||||
addActionListener(this);
|
||||
fixText();
|
||||
}
|
||||
public KeyBindButton(PreferencesDialog preferences, String key) {
|
||||
this.preferences = preferences;
|
||||
this.key = key;
|
||||
addActionListener(this);
|
||||
fixText();
|
||||
}
|
||||
|
||||
private JPopupMenu getMenu() {
|
||||
menu = new JPopupMenu();
|
||||
menu.add(item = new PopupItem());
|
||||
return menu;
|
||||
}
|
||||
private JPopupMenu createPopupMenu() {
|
||||
menu = new JPopupMenu();
|
||||
menu.add(item = new PopupItem());
|
||||
return menu;
|
||||
}
|
||||
|
||||
private void applyNewKeycode(int code) {
|
||||
preferences.getKeybindButtons().stream()
|
||||
.filter(b -> b != KeyBindButton.this)
|
||||
.filter(b -> {
|
||||
return b.keyCode == code;
|
||||
private void applyNewKeycode(int code, int modifier) {
|
||||
// clear used keys
|
||||
preferences.getKeybindButtons().stream()
|
||||
.filter(b -> b != KeyBindButton.this)
|
||||
.filter(b -> {
|
||||
return b.keyCode == code && b.modifierCode == modifier;
|
||||
})
|
||||
.forEach(b -> b.setKeyCode(0));
|
||||
.forEach(b -> {
|
||||
b.setKeyCode(0);
|
||||
b.setModifierCode(0);
|
||||
});
|
||||
|
||||
setKeyCode(code);
|
||||
menu.setVisible(false);
|
||||
}
|
||||
// set new
|
||||
setKeyCode(code);
|
||||
setModifierCode(modifier);
|
||||
menu.setVisible(false);
|
||||
}
|
||||
|
||||
private void fixText() {
|
||||
if (keyCode == 0) {
|
||||
text = "<None>";
|
||||
} else {
|
||||
text = KeyEvent.getKeyText(keyCode);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
private void fixText() {
|
||||
if (keyCode == 0) {
|
||||
text = "<none>";
|
||||
} else {
|
||||
String codeStr = KeyEvent.getKeyText(keyCode);
|
||||
String modStr = KeyEvent.getKeyModifiersText(modifierCode);
|
||||
text = (modStr.isEmpty() ? "" : modStr + " + ") + codeStr;
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void setKeyCode(int keyCode) {
|
||||
this.keyCode = keyCode;
|
||||
switch (keyCode) {
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
case KeyEvent.VK_SPACE:
|
||||
keyCode = 0;
|
||||
}
|
||||
fixText();
|
||||
setSize(getPreferredSize());
|
||||
}
|
||||
public void setKeyCode(int keyCode) {
|
||||
this.keyCode = keyCode;
|
||||
switch (keyCode) {
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
case KeyEvent.VK_SPACE:
|
||||
this.keyCode = 0;
|
||||
}
|
||||
fixText();
|
||||
//setSize(getPreferredSize());
|
||||
}
|
||||
|
||||
public int getKeyCode() {
|
||||
return keyCode;
|
||||
}
|
||||
public int getKeyCode() {
|
||||
return keyCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
public void setModifierCode(int modifierCode) {
|
||||
this.modifierCode = modifierCode;
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
// only single modifier allowed
|
||||
if (!(modifierCode == InputEvent.ALT_MASK
|
||||
|| modifierCode == InputEvent.CTRL_MASK
|
||||
|| modifierCode == InputEvent.SHIFT_MASK)) {
|
||||
this.modifierCode = 0;
|
||||
}
|
||||
fixText();
|
||||
//setSize(getPreferredSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
getMenu().show(this, 0, 0);
|
||||
item.requestFocusInWindow();
|
||||
}
|
||||
public int getModifierCode() {
|
||||
return modifierCode;
|
||||
}
|
||||
|
||||
private class PopupItem extends JLabel implements KeyListener {
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public PopupItem() {
|
||||
super("Press a key");
|
||||
addKeyListener(this);
|
||||
setFocusable(true);
|
||||
}
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JPopupMenu m = createPopupMenu();
|
||||
m.setPopupSize(this.getWidth(), this.getHeight());
|
||||
m.show(this, 0, 0);
|
||||
item.requestFocusInWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
applyNewKeycode(e.getKeyCode());
|
||||
}
|
||||
private class PopupItem extends JLabel implements KeyListener {
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
public PopupItem() {
|
||||
super("Press a key");
|
||||
addKeyListener(this);
|
||||
setFocusable(true);
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
|
||||
// cancel on ESC
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
menu.setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// clear on SPACE
|
||||
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
|
||||
setKeyCode(0);
|
||||
setModifierCode(0);
|
||||
menu.setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore multiple mod keys
|
||||
switch (e.getModifiers()) {
|
||||
case KeyEvent.CTRL_MASK:
|
||||
case KeyEvent.SHIFT_MASK:
|
||||
case KeyEvent.ALT_MASK:
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// skip single mod keys without chars
|
||||
switch (e.getKeyCode()) {
|
||||
case KeyEvent.VK_CONTROL:
|
||||
case KeyEvent.VK_SHIFT:
|
||||
case KeyEvent.VK_ALT:
|
||||
return;
|
||||
}
|
||||
|
||||
// all done, can save
|
||||
applyNewKeycode(e.getKeyCode(), e.getModifiers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue