-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path__main__.py
167 lines (134 loc) · 4.95 KB
/
__main__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
from os import system
from collections import deque
from PIL import Image
from pystray import Icon, Menu, MenuItem
from pynput.keyboard import Controller, Listener, Key
from constants import PROJECT_NAME, PROJECT_CODENAME, PROJECT_ICON_PATH
from setting_panel import start_setting_panel
from util import get_pack_list, get_pack_data, remove_pack
class EventHandler:
def __init__(self, abbreviations: dict):
self.buffer = deque()
self.abbreviations = abbreviations
self.controller = Controller()
def on_press(self, key):
print(self.buffer)
if key == Key.backspace:
if self.buffer:
self.buffer.pop()
return
if key == Key.space:
buffer_string = "".join(self.buffer)
for pack in self.abbreviations.values():
for key, value in pack.items():
if buffer_string.endswith(key):
for _ in range(len(key) + 1):
self.controller.press(Key.backspace)
self.controller.release(Key.backspace)
self.controller.type(value[0])
break
self.buffer.clear()
return
if key in [Key.shift, Key.shift_l, Key.shift_r]:
return
if not hasattr(key, "char"):
self.buffer.clear()
return
if key.char is None:
return
self.buffer.append(key.char)
while len(self.buffer) > 20:
self.buffer.popleft()
def on_release(self, _):
pass
def start(self):
listener = Listener(on_press=self.on_press, on_release=self.on_release)
listener.start()
class Program:
def __init__(self):
self.abbreviations: dict[str, dict[str, tuple[str, bool]]] = dict()
self.amount = 0
self.icon = Icon(
PROJECT_CODENAME,
Image.open(PROJECT_ICON_PATH),
PROJECT_NAME,
self.generate_menu(),
)
self.enabled = True
def add_abbreviation(
self, pack_name: str, key: str, term: str, *, autogenerated: bool = False
):
if pack_name not in self.abbreviations:
self.abbreviations[pack_name] = dict()
self.abbreviations[pack_name][key] = (term, autogenerated)
self.amount += 1
if term.upper() != term:
self.add_abbreviation(
pack_name, key.upper(), term.upper(), autogenerated=True
)
def load_abbreviations(self):
for pack_name in get_pack_list():
if pack_name not in self.abbreviations:
self.abbreviations[pack_name] = dict()
pack = get_pack_data(pack_name)
for datum in pack:
self.add_abbreviation(pack_name, datum, pack[datum])
def remove_abbreviation(self, pack_name: str, key: str):
# check existence
if key not in self.abbreviations.get(pack_name, dict()):
return
# remove abbreviation
self.amount -= 1
del self.abbreviations[pack_name][key]
# remove upper case abbreviation
if (upper := key.upper()) in self.abbreviations[pack_name]:
self.remove_abbreviation(pack_name, upper)
def remove_pack(self, pack_name: str):
for key, value in tuple(self.abbreviations[pack_name].items()):
if value[1]:
continue
self.remove_abbreviation(pack_name, key)
del self.abbreviations[pack_name]
remove_pack(pack_name)
def remove_all_abbreviations(self):
self.abbreviations.clear()
self.amount = 0
def toggle_enable(self):
if self.enabled:
self.remove_all_abbreviations()
else:
self.reload()
self.enabled = not self.enabled
def is_enable_checked(self, _: MenuItem) -> bool:
return self.enabled
def generate_menu(self) -> Menu:
return Menu(
MenuItem(f"{self.amount} Abbreviations", lambda: None, enabled=False),
Menu.SEPARATOR,
MenuItem(
"Enable Abbreviation",
self.toggle_enable,
checked=self.is_enable_checked,
),
MenuItem("Open Setting Panel", lambda: start_setting_panel(self)),
MenuItem(
"Open Packs Directory", lambda: system("start %APPDATA%\\Aice\\packs")
),
MenuItem("Reload", self.reload),
MenuItem("Exit", self.terminate),
)
def reload(self):
self.remove_all_abbreviations()
self.load_abbreviations()
self.icon.menu = self.generate_menu()
def terminate(self):
self.icon.stop()
def main(self):
self.load_abbreviations()
handler = EventHandler(self.abbreviations)
handler.start()
self.icon.menu = self.generate_menu()
self.icon.run()
if __name__ == "__main__":
program = Program()
program.main()