24
24
corner_radius = 0 # radius of the outer corners (window edges)
27
_fallback_size = (40, 40)
28
_hit_proximity_factor = 1.5
28
30
_scale = 1.0 # scale of handle relative to resize handles
29
31
_handle_alpha = 0.45
30
32
_shadow_alpha = 0.04
32
34
_shadow_offset = (0.0, 2.0)
34
37
_handle_angles = {} # dictionary at class scope!
36
42
def __init__(self, id):
109
115
self._rect = Rect(x, y, w, h)
111
117
def hit_test(self, point):
112
rect = self.get_rect()
118
rect = self.get_rect().grow(self._hit_proximity_factor)
119
radius = self.get_radius() * self._hit_proximity_factor
113
121
if rect and rect.is_point_within(point):
114
122
_win = self._window.get_window()
116
124
context = _win.cairo_create()
117
self._build_handle_path(context)
125
self._build_handle_path(context, rect, radius)
118
126
return context.in_fill(*point)
121
radius = self.get_radius()
122
129
xc, yc = rect.get_center()
123
130
dx = xc - point[0]
124
131
dy = yc - point[1]
198
205
radius = self.get_radius()
199
206
xc, yc = self.get_rect().get_center()
200
207
scale = radius / 2.0 / self._scale * 1.2
201
num_arrows = 4 if self.id == Handle.MOVE else 2
202
209
angle = self.get_arrow_angle()
210
if self.id == Handle.MOVE:
203
219
angle_step = 2.0 * pi / num_arrows
207
221
for i in range(num_arrows):
210
m.rotate(angle + i * angle_step)
211
m.scale(scale, scale)
224
context.translate(xc, yc)
225
context.rotate(angle + i * angle_step)
226
context.scale(scale, scale)
213
228
# arrow distance from center
214
229
if self.id is Handle.MOVE:
230
context.translate(0.9, 0)
232
context.translate(0.30, 0)
219
context.set_matrix(m)
220
234
self._draw_arrow(context)
224
238
def _draw_arrow(self, context):
225
239
context.move_to( 0.0, -0.5)
234
248
context.set_line_width(0)
237
def _build_handle_path(self, context):
238
rect = self.get_rect()
251
def _build_handle_path(self, context, rect = None, radius = None):
253
rect = self.get_rect()
255
radius = self.get_radius()
239
256
xc, yc = rect.get_center()
240
radius = self.get_radius()
241
257
corner_radius = self.corner_radius
243
259
angle = self.get_arrow_angle()
293
309
def __init__(self):
294
self.handles = [TouchHandle(Handle.MOVE),
295
TouchHandle(Handle.NORTH_WEST),
296
TouchHandle(Handle.NORTH),
297
TouchHandle(Handle.NORTH_EAST),
298
TouchHandle(Handle.EAST),
299
TouchHandle(Handle.SOUTH_EAST),
300
TouchHandle(Handle.SOUTH),
301
TouchHandle(Handle.SOUTH_WEST),
302
TouchHandle(Handle.WEST)]
311
self._handle_pool = [TouchHandle(Handle.MOVE),
312
TouchHandle(Handle.NORTH_WEST),
313
TouchHandle(Handle.NORTH),
314
TouchHandle(Handle.NORTH_EAST),
315
TouchHandle(Handle.EAST),
316
TouchHandle(Handle.SOUTH_EAST),
317
TouchHandle(Handle.SOUTH),
318
TouchHandle(Handle.SOUTH_WEST),
319
TouchHandle(Handle.WEST)]
321
def set_active_handles(self, handle_ids):
323
for handle in self._handle_pool:
324
if handle.id in handle_ids:
325
self.handles.append(handle)
304
327
def set_window(self, window):
305
for handle in self.handles:
328
for handle in self._handle_pool:
306
329
handle._window = window
308
331
def update_positions(self, canvas_rect):
356
379
for handle in self.handles:
357
380
handle.corner_radius = corner_radius
382
def set_monitor_dimensions(self, size_px, size_mm):
384
target_size_mm = (5, 5)
385
min_size = TouchHandle._fallback_size
387
if size_mm[0] < min_monitor_mm or \
388
size_mm[1] < min_monitor_mm:
392
w = size_px[0] / size_mm[0] * target_size_mm[0]
393
h = size_px[0] / size_mm[0] * target_size_mm[0]
394
size = max(w, min_size[0]), max(h, min_size[1])
395
TouchHandle._size = size
397
def lock_x_axis(self, lock):
398
""" Set to False to constraint movement in x. """
399
for handle in self.handles:
400
handle.lock_x_axis = lock
402
def lock_y_axis(self, lock):
403
""" Set to True to constraint movement in y. """
404
for handle in self.handles:
405
handle.lock_y_axis = lock