|
4 | 4 | from typing import Unpack
|
5 | 5 |
|
6 | 6 | import pygame
|
7 |
| -from pygame import Color, Event |
| 7 | +from pygame import Color, Event, Surface |
8 | 8 | import pygame.constants as C
|
9 | 9 | import asyncpygame as apg
|
10 | 10 |
|
11 | 11 |
|
12 |
| -class Ring: |
13 |
| - __slots__ = ('draw', 'pos', ) |
14 |
| - |
15 |
| - def __init__(self, draw_target: pygame.Surface, color, initial_pos, radius, line_width): |
16 |
| - ring_img = pygame.Surface((radius * 2, radius * 2)).convert(draw_target) |
17 |
| - color = Color(color) |
18 |
| - bgcolor = Color("black") |
19 |
| - if color == bgcolor: |
20 |
| - bgcolor = Color("white") |
21 |
| - ring_img.fill(bgcolor) |
22 |
| - ring_img.set_colorkey(bgcolor) |
23 |
| - pygame.draw.circle(ring_img, color, (radius, radius), radius, line_width) |
24 |
| - |
25 |
| - self.draw = partial(self.__class__._draw, self, draw_target.blit, ring_img, ring_img.get_rect()) |
26 |
| - self.pos = initial_pos |
27 |
| - |
28 |
| - def _draw(self, blit, ring_img, ring_dest): |
29 |
| - ring_dest.center = self.pos |
30 |
| - blit(ring_img, ring_dest) |
| 12 | +def generate_ring_image(color, radius, line_width) -> Surface: |
| 13 | + ring_img = Surface((radius * 2, radius * 2)) |
| 14 | + color = Color(color) |
| 15 | + bgcolor = Color("black") |
| 16 | + if color == bgcolor: |
| 17 | + bgcolor = Color("white") |
| 18 | + ring_img.fill(bgcolor) |
| 19 | + pygame.draw.circle(ring_img, color, (radius, radius), radius, line_width) |
| 20 | + ring_img = ring_img.convert() |
| 21 | + ring_img.set_colorkey(bgcolor) |
| 22 | + return ring_img |
31 | 23 |
|
32 | 24 |
|
33 | 25 | async def touch_indicator(*, color="white", radius=60, line_width=4, priority, **kwargs: Unpack[apg.CommonParams]):
|
34 |
| - color = Color(color) |
35 |
| - draw_target = kwargs["draw_target"] |
| 26 | + ring_img = generate_ring_image(color, radius, line_width) |
36 | 27 | async with (
|
37 | 28 | apg.open_nursery() as nursery,
|
38 | 29 | kwargs["sdlevent"].wait_freq(
|
39 | 30 | C.MOUSEBUTTONDOWN, C.FINGERDOWN, priority=priority,
|
40 | 31 | filter=lambda e: not getattr(e, 'touch', False)
|
41 | 32 | ) as touch_down,
|
42 | 33 | ):
|
| 34 | + funcs = (draw_ring_under_finger, draw_ring_under_mouse_cursor, ) |
43 | 35 | while True:
|
44 | 36 | e_down = await touch_down()
|
45 |
| - if e_down.type == C.MOUSEBUTTONDOWN: |
46 |
| - f = draw_ring_under_mouse_cursor |
47 |
| - else: |
48 |
| - f = draw_ring_under_finger |
49 |
| - nursery.start(f(e_down, priority=priority, ring=Ring(draw_target, color, e_down.pos, radius, line_width), **kwargs)) |
| 37 | + nursery.start(funcs[e_down.type == C.MOUSEBUTTONDOWN](ring_img, e_down, priority=priority, **kwargs)) |
| 38 | + |
50 | 39 |
|
| 40 | +def on_mouse_motion(dest, e: Event): |
| 41 | + dest.center = e.pos |
51 | 42 |
|
52 |
| -async def draw_ring_under_mouse_cursor(e_down: Event, *, priority, executor, sdlevent, ring, **__): |
53 |
| - with executor.register(ring.draw, priority): |
54 |
| - async with ( |
55 |
| - apg.move_on_when(sdlevent.wait(C.MOUSEBUTTONUP, filter=lambda e: e.button == e_down.button, priority=priority)), |
56 |
| - sdlevent.wait_freq(C.MOUSEMOTION, priority=priority) as mouse_motion, |
57 |
| - ): |
58 |
| - while True: |
59 |
| - e = await mouse_motion() |
60 |
| - ring.pos = e.pos |
61 | 43 |
|
| 44 | +async def draw_ring_under_mouse_cursor( |
| 45 | + ring_img: Surface, e_down: Event, *, priority, executor, sdlevent, draw_target, **__): |
| 46 | + dest = ring_img.get_rect(center=e_down.pos) |
| 47 | + with ( |
| 48 | + executor.register(partial(draw_target.blit, ring_img, dest), priority), |
| 49 | + sdlevent.subscribe((C.MOUSEMOTION, ), partial(on_mouse_motion, dest), priority), |
62 | 50 |
|
63 |
| -async def draw_ring_under_finger(e_down: Event, *, priority, executor, sdlevent, ring, **__): |
64 |
| - with executor.register(ring.draw, priority): |
65 |
| - async with ( |
66 |
| - apg.move_on_when(sdlevent.wait(C.FINGERUP, filter=lambda e: e.finger_id == e_down.finger_id, priority=priority)), |
67 |
| - sdlevent.wait_freq(C.FINGERMOTION, filter=lambda e: e.finger_id == e_down.finger_id, priority=priority) as finger_motion, |
68 |
| - ): |
69 |
| - while True: |
70 |
| - e = await finger_motion() |
71 |
| - ring.pos = e.pos |
| 51 | + ): |
| 52 | + await sdlevent.wait(C.MOUSEBUTTONUP, filter=lambda e: e.button == e_down.button, priority=priority) |
| 53 | + |
| 54 | + |
| 55 | +def on_finger_motion(finger_id, dest, e: Event): |
| 56 | + if finger_id == e.finger_id: |
| 57 | + dest.center = e.pos |
| 58 | + |
| 59 | + |
| 60 | +async def draw_ring_under_finger( |
| 61 | + ring_img: Surface, e_down: Event, *, priority, executor, sdlevent, draw_target, **__): |
| 62 | + dest = ring_img.get_rect(center=e_down.pos) |
| 63 | + with ( |
| 64 | + executor.register(partial(draw_target.blit, ring_img, dest), priority), |
| 65 | + sdlevent.subscribe((C.FINGERMOTION, ), partial(on_finger_motion, e_down.finger_id, dest), priority), |
| 66 | + ): |
| 67 | + await sdlevent.wait(C.FINGERUP, filter=lambda e: e.finger_id == e_down.finger_id, priority=priority) |
0 commit comments