1 | #!/usr/bin/python |
---|
2 | from rgbkbd.core import Keyboard |
---|
3 | from rgbkbd.geometry import Keys |
---|
4 | |
---|
5 | # Keyboard Modes |
---|
6 | from rgbkbd.modes.basicmodes import StaticMode |
---|
7 | from rgbkbd.modes.commandmode import CommandMode |
---|
8 | |
---|
9 | |
---|
10 | class KeyboardManager(object): |
---|
11 | def __init__(self, device): |
---|
12 | self.keyboard = Keyboard(device=device) |
---|
13 | |
---|
14 | self.active_modes = [] |
---|
15 | # Initialize variables for key chord tracking |
---|
16 | self.key_state = {} |
---|
17 | self.chord = [] |
---|
18 | |
---|
19 | self.notifier_number, notify_filename = self.keyboard.alloc_notify() |
---|
20 | self.notifier = open(notify_filename) |
---|
21 | |
---|
22 | # CommandMode is always the last thing available |
---|
23 | self.mode_start(CommandMode(self, self.keyboard)) |
---|
24 | # Setup default keyboard mode and start it. |
---|
25 | self.mode_start(StaticMode(self, self.keyboard)) |
---|
26 | |
---|
27 | def shutdown(self): |
---|
28 | # Set the keyboard to a reasonable default mode |
---|
29 | self.mode_start(StaticMode(self, self.keyboard)) |
---|
30 | self.keyboard.free_notify(self.notifier_number) |
---|
31 | |
---|
32 | def mode_return(self): |
---|
33 | """Discards the currently active KeyboardMode mode and initializes the |
---|
34 | previously active mode. |
---|
35 | """ |
---|
36 | prev_mode = self.active_modes.pop() |
---|
37 | self.current_mode().start(prev_mode) |
---|
38 | |
---|
39 | def mode_start(self, mode): |
---|
40 | """Makes the given mode the current mode and initializes it""" |
---|
41 | self.active_modes.append(mode) |
---|
42 | self.current_mode().start() |
---|
43 | |
---|
44 | def current_mode(self): |
---|
45 | """Returns the currently active KeyboardMode object""" |
---|
46 | # Never goes empty because the CommandMode doesn't go away |
---|
47 | return self.active_modes[-1] |
---|
48 | |
---|
49 | def key_event(self, key, state): |
---|
50 | """Dispatches key up, key down, and chord events to the current mode. |
---|
51 | """ |
---|
52 | #print key, state # DEBUG |
---|
53 | # Directly pass on up/down key events |
---|
54 | self.current_mode().event(key, state) |
---|
55 | |
---|
56 | # Then track key chords. (Individual typed keys count as a single-key |
---|
57 | # chord.) |
---|
58 | self.key_state[key] = state |
---|
59 | if state == '+': # key down |
---|
60 | self.chord.append(key) |
---|
61 | else: # key up |
---|
62 | if set(self.key_state.values()) != set('-'): |
---|
63 | # There are still keys that are being held down, so this is an |
---|
64 | # incomplete chord |
---|
65 | return |
---|
66 | # All keys are up |
---|
67 | chord = self.chord |
---|
68 | self.chord = [] |
---|
69 | self.current_mode().chord_event(chord) |
---|
70 | |
---|
71 | def tick_rate(self): |
---|
72 | return self.current_mode().tick_rate |
---|