-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmonkey_patching.py
234 lines (166 loc) · 7.23 KB
/
monkey_patching.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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
import ctypes
import pyglet
from pyglet_gui.constants import ANCHOR_TOP_LEFT, VALIGN_TOP
from pyglet_gui.containers import VerticalContainer, HorizontalContainer, Container
from pyglet_gui.controllers import Selector
from pyglet_gui.gui import Frame, Label
from pyglet_gui.manager import Manager as Manager
from pyglet_gui.option_selectors import OptionButton
from pyglet_gui.scrollable import Scrollable
from pyglet_gui.sliders import Slider
from pyglet_gui.option_selectors import Dropdown as _Dropdown
from pyglet_gui.text_input import TextInput as _TextInput
from pyglet_gui.buttons import Button, OneTimeButton, Checkbox
try:
# original WACOM drivers branch: normalize pressure to range [0, 1]
from pyglet.input.wintab import WintabTabletCanvas
from pyglet.libs.win32 import libwintab as wintab
lib = wintab.lib
@pyglet.window.win32.Win32EventHandler(0)
def monkey_patching_WintabTabletCanvas_event_wt_packet(self, msg, wParam, lParam):
if lParam != self._context:
return
packet = wintab.PACKET()
if lib.WTPacket(self._context, wParam, ctypes.byref(packet)) == 0:
return
if not packet.pkChanged:
return
window_x, window_y = self.window.get_location() # TODO cache on window
window_y = self.window.screen.height - window_y - self.window.height
x = packet.pkX - window_x
y = packet.pkY - window_y
pressure = (packet.pkNormalPressure + self._pressure_bias) * \
self._pressure_scale
if self._current_cursor is None:
self._set_current_cursor(packet.pkCursor)
buttons = packet.pkButtons
self.dispatch_event('on_motion', self._current_cursor,
x, y, pressure, buttons)
WintabTabletCanvas._event_wt_packet = monkey_patching_WintabTabletCanvas_event_wt_packet
except:
pass
def monkey_patching_OptionButton_on_mouse_press(self, x, y, button, modifiers):
self.select()
return True
OptionButton.on_mouse_press = monkey_patching_OptionButton_on_mouse_press
def monkey_patching_Slider_set_value(self, value):
if self._min_value <= value <= self._max_value:
super(Slider, self).set_value(value)
self.layout()
Slider.set_value = monkey_patching_Slider_set_value
class Dropdown(_Dropdown):
def __init__(self, options, labels=None, max_height=400, align=VALIGN_TOP, on_select=None):
if options and len(options):
Selector.__init__(self, options, labels, on_select=on_select, selected=options[0])
else:
self._options = []
self._selected = None
OneTimeButton.__init__(self)
self.max_height = max_height
self.align = align
self._pulldown_menu = None
def load_graphics(self):
if self._selected:
self.label = self._options[self._selected].label
else:
self.label = ''
OneTimeButton.load_graphics(self)
def on_gain_highlight(self):
self._delete_pulldown_menu()
def on_lose_highlight(self):
self._delete_pulldown_menu()
def on_mouse_press(self, x, y, button, modifiers):
if not self._is_loaded or not self._options or len(self._options) == 0:
return
"""
A mouse press is going to create a manager with the options.
"""
# if it's already opened, we just close it.
if self._pulldown_menu is not None:
self._delete_pulldown_menu()
return
# the function we pass to the manager.
def on_escape(_):
self._delete_pulldown_menu()
width, height = self._manager.window.get_size()
x = self.x
y = -(height - self.y - 1) + self.height
# we set the manager
self._pulldown_menu = Manager(
Frame(Scrollable(VerticalContainer(list(self._options.values())),
height=self.max_height), path=['dropdown', 'pulldown']),
window=self._manager.window, batch=self._manager.batch,
group=self._manager.root_group.parent, theme=self._manager.theme,
is_movable=False, anchor=ANCHOR_TOP_LEFT, offset=(x, y))
def select(self, option_name):
if self._is_loaded:
Selector.select(self, option_name)
self._delete_pulldown_menu()
self.reload()
self.reset_size()
self.layout()
def monkey_patching_Button_set_state(self, value: bool):
self._is_pressed = value
self.reload()
self.reset_size()
Button.set_state = monkey_patching_Button_set_state
def monkey_patching_Button_change_state(self):
self._is_pressed = not self._is_pressed
if self.is_loaded:
self.reload()
self.reset_size()
self._on_press(self._is_pressed)
Button.change_state = monkey_patching_Button_change_state
class TextInput(_TextInput):
def __init__(self, **kwargs):
_TextInput.__init__(self, **kwargs, max_length=5, length=6)
def set_hidden(self, value):
self._hidden = value
if self._hidden:
if self._is_loaded:
if isinstance(self, Container):
self.unload()
else:
self.unload_graphics()
else:
if not self._is_loaded:
if isinstance(self, Container):
self.load()
else:
self.load_graphics()
self.reset_size(False)
Container.reset_size(self)
def monkey_patch_Container_load(self):
if not self.hidden:
super(Container, self).load()
self.load_content()
HorizontalContainer.load = monkey_patch_Container_load
def monkey_patch_Container_reset_size(self, reset_parent=True):
if not self.hidden:
if not reset_parent:
for item in self._content:
item.reset_size(reset_parent=False)
super(Container, self).reset_size(reset_parent)
HorizontalContainer.reset_size = monkey_patch_Container_reset_size
for widget in [Button, TextInput, Dropdown, Checkbox, Label, HorizontalContainer]:
widget.hidden = property(lambda self: self._hidden, set_hidden)
def make_func(compute_size, init, load_graphics, layout):
def monkey_patching_compute_size(self):
return compute_size(self) if not self.hidden else (0, 0)
def monkey_patching_init(self, *args, **kwargs):
hidden = None
if 'hidden' in kwargs:
hidden = kwargs['hidden']
del kwargs['hidden']
o = init(self, *args, **kwargs)
self._hidden = hidden if hidden else False
return o
def monkey_patching_load_graphics(self):
if not self.hidden:
return load_graphics(self)
def monkey_patching_layout(self):
if not self.hidden:
return layout(self)
return monkey_patching_compute_size, monkey_patching_init, monkey_patching_load_graphics, monkey_patching_layout
widget.compute_size, widget.__init__, widget.load_graphics, widget.layout =\
make_func(widget.compute_size, widget.__init__, widget.load_graphics, widget.layout)