00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 package com.realtime.crossfire.jxclient.window;
00023
00024 import com.realtime.crossfire.jxclient.gui.gui.Gui;
00025 import com.realtime.crossfire.jxclient.gui.keybindings.KeyBindings;
00026 import com.realtime.crossfire.jxclient.gui.label.JXCWindowRenderer;
00027 import com.realtime.crossfire.jxclient.queue.CommandQueue;
00028 import java.awt.event.InputEvent;
00029 import java.awt.event.KeyEvent;
00030 import java.io.IOException;
00031 import java.io.Writer;
00032 import java.text.DateFormat;
00033 import java.text.SimpleDateFormat;
00034 import java.util.Arrays;
00035 import java.util.Date;
00036 import org.jetbrains.annotations.NotNull;
00037 import org.jetbrains.annotations.Nullable;
00038
00044 public class KeyHandler {
00045
00049 private static final int KEY_SHIFT_SHIFT = 0;
00050
00054 private static final int KEY_SHIFT_CTRL = 1;
00055
00059 private static final int KEY_SHIFT_ALT = 2;
00060
00064 private static final int KEY_SHIFT_ALT_GR = 3;
00065
00070 @Nullable
00071 private final Writer debugKeyboard;
00072
00076 @NotNull
00077 private final KeybindingsManager keybindingsManager;
00078
00082 @NotNull
00083 private final CommandQueue commandQueue;
00084
00088 @NotNull
00089 private final JXCWindowRenderer windowRenderer;
00090
00094 @NotNull
00095 private final KeyHandlerListener keyHandlerListener;
00096
00100 @NotNull
00101 private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS ");
00102
00106 @NotNull
00107 private final boolean[] keyShift = {
00108 false,
00109 false,
00110 false,
00111 false
00112 };
00113
00118 @Nullable
00119 private KeyBindings keyBindings = null;
00120
00129 public KeyHandler(@Nullable final Writer debugKeyboard, @NotNull final KeybindingsManager keybindingsManager, @NotNull final CommandQueue commandQueue, @NotNull final JXCWindowRenderer windowRenderer, @NotNull final KeyHandlerListener keyHandlerListener) {
00130 this.debugKeyboard = debugKeyboard;
00131 this.keybindingsManager = keybindingsManager;
00132 this.commandQueue = commandQueue;
00133 this.windowRenderer = windowRenderer;
00134 this.keyHandlerListener = keyHandlerListener;
00135 }
00136
00140 public void reset() {
00141 Arrays.fill(keyShift, false);
00142 }
00143
00148 @SuppressWarnings("NullableProblems")
00149 public void setKeyBindings(@NotNull final KeyBindings keyBindings) {
00150 this.keyBindings = keyBindings;
00151 }
00152
00158 private boolean getKeyShift(final int keyId) {
00159 return keyShift[keyId];
00160 }
00161
00167 private void setKeyShift(final int keyId, final boolean state) {
00168 if (keyShift[keyId] != state) {
00169 debugKeyboardWrite("setKeyShift: "+keyId+"="+state);
00170 }
00171 keyShift[keyId] = state;
00172 }
00173
00178 private void handleKeyPress(@NotNull final KeyEvent e) {
00179 updateModifiers(e);
00180
00181 switch (e.getKeyCode()) {
00182 case KeyEvent.VK_ALT:
00183 case KeyEvent.VK_ALT_GRAPH:
00184 case KeyEvent.VK_SHIFT:
00185 case KeyEvent.VK_CONTROL:
00186 debugKeyboardWrite("keyPressed: ignoring modifier key");
00187 return;
00188 }
00189
00190 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
00191 debugKeyboardWrite("keyPressed: ESC");
00192 keyHandlerListener.escPressed();
00193 return;
00194 }
00195
00196 if (keybindingsManager.keyPressed(e.getKeyCode(), e.getModifiers())) {
00197 debugKeyboardWrite("keyPressed: keybindingsManager consumed key");
00198 return;
00199 }
00200
00201 for (final Gui dialog : windowRenderer.getOpenDialogs()) {
00202 if (!dialog.isHidden(windowRenderer.getGuiState())) {
00203 if (dialog.handleKeyPress(e)) {
00204 debugKeyboardWrite("keyPressed: dialog "+dialog+" consumed key");
00205 return;
00206 }
00207 if (dialog.isModal()) {
00208 debugKeyboardWrite("keyPressed: dialog "+dialog+" is modal");
00209 return;
00210 }
00211 debugKeyboardWrite("keyPressed: dialog "+dialog+" didn't consume key");
00212 }
00213 }
00214
00215 if (windowRenderer.handleKeyPress(e)) {
00216 debugKeyboardWrite("keyPressed: main gui consumed key");
00217 return;
00218 }
00219
00220 if (keybindingsManager.handleKeyPress(e)) {
00221 debugKeyboardWrite("keyPressed: keybindingsManager consumed key");
00222 return;
00223 }
00224
00225 if (keyBindings != null && keyBindings.handleKeyPress(e)) {
00226 debugKeyboardWrite("keyPressed: skin default key bindings consumed key");
00227 return;
00228 }
00229
00230 if (e.getModifiers() == 0) {
00231 switch (e.getKeyCode()) {
00232 case KeyEvent.VK_0:
00233 debugKeyboardWrite("keyPressed: number key");
00234 commandQueue.addToRepeatCount(0);
00235 break;
00236
00237 case KeyEvent.VK_1:
00238 debugKeyboardWrite("keyPressed: number key");
00239 commandQueue.addToRepeatCount(1);
00240 break;
00241
00242 case KeyEvent.VK_2:
00243 debugKeyboardWrite("keyPressed: number key");
00244 commandQueue.addToRepeatCount(2);
00245 break;
00246
00247 case KeyEvent.VK_3:
00248 debugKeyboardWrite("keyPressed: number key");
00249 commandQueue.addToRepeatCount(3);
00250 break;
00251
00252 case KeyEvent.VK_4:
00253 debugKeyboardWrite("keyPressed: number key");
00254 commandQueue.addToRepeatCount(4);
00255 break;
00256
00257 case KeyEvent.VK_5:
00258 debugKeyboardWrite("keyPressed: number key");
00259 commandQueue.addToRepeatCount(5);
00260 break;
00261
00262 case KeyEvent.VK_6:
00263 debugKeyboardWrite("keyPressed: number key");
00264 commandQueue.addToRepeatCount(6);
00265 break;
00266
00267 case KeyEvent.VK_7:
00268 debugKeyboardWrite("keyPressed: number key");
00269 commandQueue.addToRepeatCount(7);
00270 break;
00271
00272 case KeyEvent.VK_8:
00273 debugKeyboardWrite("keyPressed: number key");
00274 commandQueue.addToRepeatCount(8);
00275 break;
00276
00277 case KeyEvent.VK_9:
00278 debugKeyboardWrite("keyPressed: number key");
00279 commandQueue.addToRepeatCount(9);
00280 break;
00281
00282 default:
00283 debugKeyboardWrite("keyPressed: ignoring key");
00284 break;
00285 }
00286 return;
00287 }
00288
00289 debugKeyboardWrite("keyPressed: ignoring key because modifiers != 0");
00290 }
00291
00296 private void handleKeyRelease(@NotNull final KeyEvent e) {
00297 updateModifiers(e);
00298
00299 switch (e.getKeyCode()) {
00300 case KeyEvent.VK_ALT:
00301 case KeyEvent.VK_ALT_GRAPH:
00302 case KeyEvent.VK_SHIFT:
00303 case KeyEvent.VK_CONTROL:
00304 debugKeyboardWrite("keyReleased: ignoring modifier key");
00305 return;
00306 }
00307
00308 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
00309 debugKeyboardWrite("keyReleased: ignoring ESC");
00310 return;
00311 }
00312
00313 if (keybindingsManager.keyReleased()) {
00314 debugKeyboardWrite("keyReleased: keybindingsManager consumed key");
00315 keyHandlerListener.keyReleased();
00316 return;
00317 }
00318
00319 debugKeyboardWrite("keyReleased: ignoring key");
00320 }
00321
00326 public void keyPressed(@NotNull final KeyEvent e) {
00327 debugKeyboardWrite("pressed", e);
00328 try {
00329 handleKeyPress(e);
00330 } finally {
00331 debugKeyboardWrite("");
00332 }
00333 }
00334
00339 public void keyReleased(@NotNull final KeyEvent e) {
00340 debugKeyboardWrite("released", e);
00341 try {
00342 handleKeyRelease(e);
00343 } finally {
00344 debugKeyboardWrite("");
00345 }
00346 }
00347
00352 private void updateModifiers(@NotNull final InputEvent keyEvent) {
00353 final int mask = keyEvent.getModifiersEx();
00354 setKeyShift(KEY_SHIFT_SHIFT, (mask&InputEvent.SHIFT_DOWN_MASK) != 0);
00355 setKeyShift(KEY_SHIFT_CTRL, (mask&InputEvent.CTRL_DOWN_MASK) != 0);
00356 setKeyShift(KEY_SHIFT_ALT, (mask&InputEvent.ALT_DOWN_MASK) != 0);
00357 setKeyShift(KEY_SHIFT_ALT_GR, (mask&InputEvent.ALT_GRAPH_DOWN_MASK) != 0);
00358 if (!getKeyShift(KEY_SHIFT_CTRL) && commandQueue.stopRunning()) {
00359 debugKeyboardWrite("updateModifiers: stopping run");
00360 }
00361 }
00362
00368 private void debugKeyboardWrite(@NotNull final String type, @NotNull final KeyEvent e) {
00369 if (debugKeyboard == null) {
00370 return;
00371 }
00372
00373 debugKeyboardWrite(type+" "+e);
00374 }
00375
00380 private void debugKeyboardWrite(@NotNull final CharSequence message) {
00381 if (debugKeyboard == null) {
00382 return;
00383 }
00384
00385 try {
00386 debugKeyboard.append(simpleDateFormat.format(new Date()));
00387 debugKeyboard.append(message);
00388 debugKeyboard.append("\n");
00389 debugKeyboard.flush();
00390 } catch (final IOException ex) {
00391 System.err.println("Cannot write keyboard debug: "+ex.getMessage());
00392 System.exit(1);
00393 throw new AssertionError();
00394 }
00395 }
00396
00397 }