package com.kartoflane.superluminal2.components; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.ToolItem; import com.kartoflane.superluminal2.components.interfaces.Action; public class Hotkey { private Action onPressAction; private Action onReleaseAction; private boolean enabled = true; private boolean shift = false; private boolean ctrl = false; private boolean alt = false; /** the Mac Command button */ private boolean command = false; private int key = '\0'; public Hotkey() { } public Hotkey(Action onPress, Action onRelease) { onPressAction = onPress; onReleaseAction = onRelease; } /** * Creates a shallow copy of the Hotkey passed in argument. * * @param h */ public Hotkey(Hotkey h) { if (h == null) throw new IllegalArgumentException("Argument must not be null."); onPressAction = h.onPressAction; onReleaseAction = h.onReleaseAction; enabled = h.enabled; shift = h.shift; ctrl = h.ctrl; alt = h.alt; command = h.command; key = h.key; } public void executePress() { if (onPressAction == null) return; onPressAction.execute(); } public void executeRelease() { if (onReleaseAction == null) return; onReleaseAction.execute(); } public void setOnPress(Action action) { this.onPressAction = action; } public void setOnRelease(Action action) { this.onReleaseAction = action; } /** * Sets whether the hotkey is active. An inactive hotkey is considered to not be bound to anything. */ public void setEnabled(boolean e) { enabled = e; } /** * @return whether the hotkey is active. An inactive hotkey is considered to not be bound to anything. */ public boolean isEnabled() { return enabled; } /** * Sets the character that this hotkey is bound to. * * @param ch * the code point representing the character, according to {@link Character} * * @see Character */ public void setKey(int ch) { key = ch; } /** * @return the code point representing the character to which this hotkey is bound, according to {@link Character} */ public int getKey() { return key; } /** * @see Character#toString(char) */ public String getKeyString() { if (key == '\0') return ""; else return Character.toString((char) getKey()); } /** Sets whether the hotkey's activation requires Shift modifier to be pressed. */ public void setShift(boolean shift) { this.shift = shift; } public boolean getShift() { return shift; } /** Sets whether the hotkey's activation requires Control modifier to be pressed. */ public void setCtrl(boolean control) { ctrl = control; } public boolean getCtrl() { return ctrl; } /** Sets whether the hotkey's activation requires Alt / Function(?) modifier to be pressed. */ public void setAlt(boolean alt) { this.alt = alt; } public boolean getAlt() { return alt; } /** Sets whether the hotkey's activation requires Command modifier to be pressed. */ public void setCommand(boolean command) { this.command = command; } public boolean getCommand() { return command; } /** * Checks whether the hotkey is to be activated by comparing the hotkey's modifier settings with currently * active modifiers, and the hotkey's trigger key with currently pressed key. * * @param keyCode * int representing the currently pressed key * @return true if the hotkey is tiggered, false otherwise */ public boolean passes(boolean shift, boolean ctrl, boolean alt, boolean cmd, int keyCode) { return this.shift == shift && this.ctrl == ctrl && this.alt == alt && this.command == cmd && compareKeyCodes(key, keyCode); } private boolean compareKeyCodes(int key1, int key2) { if ((key1 == SWT.CR || key1 == SWT.LF || key1 == SWT.KEYPAD_CR) && (key2 == SWT.CR || key2 == SWT.LF || key2 == SWT.KEYPAD_CR)) { return true; } else { return Character.toLowerCase(key1) == Character.toLowerCase(key2); } } /** * Checks whether the receiver collides with the hotkey passed in argument, ie. whether their actvation * requirements are the same.<br> * Basically a customised {@link #equals(Object)}. */ public boolean collides(Hotkey h) { return shift == h.shift && ctrl == h.ctrl && alt == h.alt && command == h.command && compareKeyCodes(key, h.key); } public boolean equals(Object o) { if (o instanceof Hotkey == true) return collides((Hotkey) o); return super.equals(o); } @Override public String toString() { if (key == '\0') return ""; String msg = ""; if (shift) msg += "Shift+"; if (ctrl) msg += "Ctrl+"; if (alt) msg += "Alt+"; if (command) msg += "⌘+"; // @formatter:off switch (key) { case SWT.SPACE: msg += "Spacebar"; break; case SWT.KEYPAD_CR: case SWT.CR: case SWT.LF: msg += "Enter"; break; case SWT.BS: msg += "Backspace"; break; case SWT.TAB: msg += "Tab"; break; case SWT.F1: msg += "F1"; break; case SWT.F2: msg += "F2"; break; case SWT.F3: msg += "F3"; break; case SWT.F4: msg += "F4"; break; case SWT.F5: msg += "F5"; break; case SWT.F6: msg += "F6"; break; case SWT.F7: msg += "F7"; break; case SWT.F8: msg += "F8"; break; case SWT.F9: msg += "F9"; break; case SWT.F10: msg += "F10"; break; case SWT.F11: msg += "F11"; break; case SWT.F12: msg += "F12"; break; case SWT.CAPS_LOCK: msg += "Caps Lock"; break; case SWT.NUM_LOCK: msg += "Num Lock"; break; case SWT.SCROLL_LOCK: msg += "Scroll Lock"; break; case SWT.PRINT_SCREEN: msg += "Print Screen"; break; case SWT.PAUSE: msg += "Pause"; break; case SWT.BREAK: msg += "Break"; break; case SWT.INSERT: msg += "Insert"; break; case SWT.DEL: msg += "Delete"; break; case SWT.HOME: msg += "Home"; break; case SWT.END: msg += "End"; break; case SWT.PAGE_UP: msg += "Page Up"; break; case SWT.PAGE_DOWN: msg += "Page Down"; break; default: msg += getKeyString().toUpperCase(); } // @formatter:on return msg; } /** * Adds an action to send the widget specified in the argument a Selection event, if it is enabled. */ public void addNotifyAction(final MenuItem item, boolean onPress) { Action a = new Action() { public void execute() { if (item.isEnabled()) item.notifyListeners(SWT.Selection, null); } }; if (onPress) setOnPress(a); else setOnRelease(a); } /** * Adds an action to send the widget specified in the argument a Selection event, if it is enabled. */ public void addNotifyAction(final ToolItem item, boolean onPress) { Action a = new Action() { public void execute() { if (item.isEnabled()) item.notifyListeners(SWT.Selection, null); } }; if (onPress) setOnPress(a); else setOnRelease(a); } /** * Adds an action to send the widget specified in the argument a Selection event, if it is enabled. */ public void addNotifyAction(final Button item, boolean onPress) { Action a = new Action() { public void execute() { if (item.isEnabled()) item.notifyListeners(SWT.Selection, null); } }; if (onPress) setOnPress(a); else setOnRelease(a); } /** * Adds an action to send the widget specified in the argument a Selection event and toggle it, if it is enabled. */ public void addNotifyAndToggleAction(final MenuItem item, boolean onPress) { Action a = new Action() { public void execute() { if (item.isEnabled()) { item.setSelection(!item.getSelection()); item.notifyListeners(SWT.Selection, null); } } }; if (onPress) setOnPress(a); else setOnRelease(a); } /** * Adds an action to send the widget specified in the argument a Selection event and toggle it, if it is enabled. */ public void addNotifyAndToggleAction(final ToolItem item, boolean onPress) { Action a = new Action() { public void execute() { if (item.isEnabled()) { item.setSelection(!item.getSelection()); item.notifyListeners(SWT.Selection, null); } } }; if (onPress) setOnPress(a); else setOnRelease(a); } /** * Adds an action to send the widget specified in the argument a Selection event and toggle it, if it is enabled. */ public void addNotifyAndToggleAction(final Button item, boolean onPress) { Action a = new Action() { public void execute() { if (item.isEnabled()) { item.setSelection(!item.getSelection()); item.notifyListeners(SWT.Selection, null); } } }; if (onPress) setOnPress(a); else setOnRelease(a); } }