-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmouse_glide_scrolling.py
More file actions
184 lines (147 loc) · 5.28 KB
/
Copy pathmouse_glide_scrolling.py
File metadata and controls
184 lines (147 loc) · 5.28 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
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
from collections import deque
from math import trunc
from talon import Module, Context, cron, actions, ctrl, imgui, settings
mod = Module()
mod.tag(
"mouse_glide_active",
desc="commands for stopping mouse glide",
)
mod.setting(
"mouse_glide_hide_cursor_on_stop",
type=bool,
default=False,
desc="Enable to hide the cursor when stopping mouse glide",
)
mod.setting(
"mouse_glide_show_cursor_on_start",
type=bool,
default=False,
desc="Enable to show the cursor when starting mouse glide",
)
mod.setting(
"mouse_glide_restore_tracking_state_on_stop",
type=bool,
default=True,
desc="Enable to restore eye-tracking state when stopping mouse glide",
)
ctx = Context()
position_tuple = [None, None]
scroll_job = None
delta_y_previous = 0
delta_x_previous = 0
has_stopped = True
inertia_buffer_x = deque(maxlen=10)
inertia_buffer_y = deque(maxlen=10)
@imgui.open(x=700, y=0)
def gui_wheel(gui: imgui.GUI):
gui.text("Scroll mode: Mouse Glide")
gui.line()
if gui.button("Glide Stop [stop scrolling]"):
actions.user.mouse_glide_stop()
def scroll_glide_helper(horizontal: bool, vertical: bool):
global delta_y_previous, delta_x_previous, has_stopped
current_x, current_y = ctrl.mouse_pos()
previous_x, previous_y = get_position()
delta_y_accel, delta_x_accel = (0, 0)
if vertical:
delta_y_accel = calc_accel(*calc_vector(current_y, previous_y))
if horizontal:
delta_x_accel = calc_accel(*calc_vector(current_x, previous_x))
has_stopped = delta_x_accel == 0 and delta_y_accel == 0
set_previous_delta()
buffer(delta_x_accel, delta_y_accel)
delta_y_inertia = delta_y_previous if has_stopped else 0.0
delta_x_inertia = delta_x_previous if has_stopped else 0.0
if horizontal and vertical:
actions.mouse_scroll(
delta_y_accel + delta_y_inertia, delta_x_accel + delta_x_inertia
)
actions.mouse_move(previous_x, previous_y)
return
if horizontal:
actions.mouse_scroll(x=delta_x_accel + delta_x_inertia)
actions.mouse_move(previous_x, current_y)
if vertical:
actions.mouse_scroll(y=delta_y_accel + delta_y_inertia)
actions.mouse_move(current_x, previous_y)
def set_previous_delta():
global delta_y_previous, delta_x_previous
if has_stopped:
delta_y_previous = delta_y_previous / 1.1
delta_x_previous = delta_x_previous / 1.1
else:
delta_y_previous = calc_buffer_avg("y")
delta_x_previous = calc_buffer_avg("x")
def calc_vector(curr, prev):
delta = trunc(curr - prev)
direction = int(delta >= 0) or -1
return delta, direction
def calc_accel(delta, direction):
acceleration = 1.5
if -1 < delta < 1:
return delta * -acceleration
return abs(delta**acceleration) * -direction
def initialize_position():
x, y = ctrl.mouse_pos()
set_position(x, y)
def set_position(x: int, y: int):
global position_tuple
position_tuple.clear()
position_tuple.append(x)
position_tuple.append(y)
def get_position():
global position_tuple
return position_tuple
def calc_buffer_avg(dir):
inertia_buffer = inertia_buffer_y if dir == "y" else inertia_buffer_x
return sum(inertia_buffer) / (len(inertia_buffer) or 1)
def buffer(x, y):
inertia_buffer_x.append(x)
inertia_buffer_y.append(y)
control_enabled = None
control1_enabled = None
def save_tracking_state():
global control_enabled, control1_enabled
control_enabled = actions.tracking.control_enabled()
control1_enabled = actions.tracking.control1_enabled()
actions.tracking.control_toggle(False)
actions.tracking.control1_toggle(False)
def restore_tracking_state():
global control_enabled, control1_enabled
actions.tracking.control_toggle(control_enabled)
actions.tracking.control1_toggle(control1_enabled)
@mod.action_class
class Actions:
def is_mouse_glide_active():
"""Returns whether mouse glide is active"""
return scroll_job is not None
def mouse_glide_toggle(horizontal: bool = True, vertical: bool = True):
"""Toggle mouse glide scrolling"""
if scroll_job is not None:
return actions.user.mouse_glide_stop()
actions.user.mouse_glide_start(horizontal, vertical)
def mouse_glide_start(horizontal: bool = True, vertical: bool = True):
"""begin mouse glide scrolling"""
global scroll_job
if scroll_job is None:
save_tracking_state()
scroll_job = cron.interval(
"16ms", lambda: scroll_glide_helper(horizontal, vertical)
)
initialize_position()
ctx.tags = ["user.mouse_glide_active"]
if settings.get("user.mouse_glide_show_cursor_on_start"):
actions.user.mouse_cursor_show()
if not settings.get("user.mouse_hide_mouse_gui"):
gui_wheel.show()
def mouse_glide_stop():
"""stop mouse glide scrolling"""
global scroll_job
cron.cancel(scroll_job)
scroll_job = None
gui_wheel.hide()
ctx.tags = []
if settings.get("user.mouse_glide_hide_cursor_on_stop"):
actions.user.mouse_cursor_hide()
if settings.get("user.mouse_glide_restore_tracking_state_on_stop"):
restore_tracking_state()