-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodeswitch.py
More file actions
137 lines (113 loc) · 5.21 KB
/
modeswitch.py
File metadata and controls
137 lines (113 loc) · 5.21 KB
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
"""模式切换模块
该模块负责管理应用程序的不同操作模式,包括普通模式、鼠标控制模式和区域选择模式。
同时提供了键盘钩子的控制功能。
"""
import threading
from enum import Enum, auto
from typing import Optional, Dict, Any, Callable
from key_mapping_mode import KeyMappingMode
class AppMode(Enum):
"""应用程序模式枚举类"""
# auto()函数会自动为枚举成员分配数值,从1开始递增
# 相当于 NORMAL = 1, MOUSE_CONTROL = 2, REGION_SELECT = 3, COMMAND_MODE = 4
NORMAL = auto()
MOUSE_CONTROL = auto()
REGION_SELECT = auto()
COMMAND_MODE = auto()
KEY_MAPPING = auto()
class ControlStateManager:
"""控制状态管理类"""
def __init__(self):
self.mouse_speed_caplock_active: bool = False
self.mouse_speed_shift_active: bool = False
self.is_left_mouse_button_held_by_keyboard: bool = False
self.is_right_mouse_button_held_by_keyboard: bool = False
self.is_middle_mouse_button_held_by_keyboard: bool = False
self.sticky_left_click_active: bool = False
class ModeSwitch:
"""模式切换管理类"""
def __init__(self, config: dict, tray_icon: Optional[object] = None) -> None:
"""初始化模式切换管理器
Args:
config: 配置字典
tray_icon: 托盘图标对象
"""
self.config = config
self.tray_icon = tray_icon
self.current_mode: AppMode = AppMode.NORMAL
self.previous_mode_before_region_select: AppMode = AppMode.NORMAL
self.previous_mode_before_command: AppMode = AppMode.NORMAL
#用于控制 pynput 钩子是否激活
self.keyboard_hook_active: bool = True
self._hook_lock = threading.Lock() # 线程锁
self.key_mapping_mode: Optional[KeyMappingMode] = None
def is_mouse_control_mode(self) -> bool:
"""检查是否处于鼠标控制模式"""
return self.current_mode == AppMode.MOUSE_CONTROL
def is_region_select_mode(self) -> bool:
"""检查是否处于区域选择模式"""
return self.current_mode == AppMode.REGION_SELECT
def is_command_mode(self) -> bool:
"""检查是否处于命令模式"""
return self.current_mode == AppMode.COMMAND_MODE
def toggle_mouse_control_mode(self) -> None:
"""切换鼠标控制模式"""
if self.current_mode == AppMode.NORMAL:
self.set_mode(AppMode.MOUSE_CONTROL)
elif self.current_mode == AppMode.MOUSE_CONTROL:
self.set_mode(AppMode.NORMAL)
def toggle_command_mode(self) -> None:
"""切换命令模式"""
if self.current_mode != AppMode.COMMAND_MODE:
# 记录进入命令模式前的模式
self.previous_mode_before_command = self.current_mode
self.set_mode(AppMode.COMMAND_MODE)
else:
# 从命令模式返回之前的模式
self.set_mode(self.previous_mode_before_command)
def toggle_key_mapping_mode(self) -> None:
"""切换按键映射模式"""
if self.current_mode == AppMode.NORMAL:
self.set_mode(AppMode.KEY_MAPPING)
elif self.current_mode == AppMode.KEY_MAPPING:
self.set_mode(AppMode.NORMAL)
def set_mode(self, new_mode: AppMode) -> None:
"""设置应用程序模式
Args:
new_mode: 新的应用程序模式
"""
if self.current_mode == new_mode:
return
# Deactivate current mode's specific behaviors
if self.current_mode == AppMode.KEY_MAPPING and self.key_mapping_mode:
self.key_mapping_mode.deactivate()
self.resume_keyboard_hook()
if new_mode == AppMode.REGION_SELECT:
self.previous_mode_before_region_select = self.current_mode
self.current_mode = new_mode
print(f"模式切换:>>> 进入 {self.current_mode.name} 模式 <<<")
# Activate new mode's specific behaviors
if self.current_mode == AppMode.KEY_MAPPING:
if self.key_mapping_mode is None:
self.key_mapping_mode = KeyMappingMode(self.config, lambda: self.set_mode(AppMode.NORMAL))
self.key_mapping_mode.activate()
self.pause_keyboard_hook()
elif self.current_mode == AppMode.NORMAL:
self.resume_keyboard_hook()
# 检查托盘图标对象是否有update_icon方法,如果有则调用该方法更新图标
# 这段代码用于在模式切换时更新托盘图标的显示状态
if hasattr(self.tray_icon, 'update_icon'):
self.tray_icon.update_icon()
def return_from_region_select(self) -> None:
"""从区域选择模式返回到之前的模式"""
self.set_mode(self.previous_mode_before_region_select)
def pause_keyboard_hook(self) -> None:
"""暂停键盘钩子,让事件可以传递给其他窗口(如tkinter)"""
with self._hook_lock:
print("主程序键盘钩子已暂停。")
self.keyboard_hook_active = False
def resume_keyboard_hook(self) -> None:
"""恢复键盘钩子"""
with self._hook_lock:
print("主程序键盘钩子已恢复。")
self.keyboard_hook_active = True