ui: extract and optimize mouse event processing (#36564)

* extract and optimize mouse event processing

* rm slot

* merge mici mastere

* add mouse

---------

Co-authored-by: Shane Smiskol <shane@smiskol.com>
This commit is contained in:
Dean Lee
2025-11-27 17:50:36 +08:00
committed by GitHub
parent 26261387f8
commit b8d55987c2
+42 -35
View File
@@ -104,46 +104,53 @@ class Widget(abc.ABC):
# Keep track of whether mouse down started within the widget's rectangle
if self.enabled and self.__was_awake:
for mouse_event in gui_app.mouse_events:
if not self._multi_touch and mouse_event.slot != 0:
continue
# Ignores touches/presses that start outside our rect
# Allows touch to leave the rect and come back in focus if mouse did not release
if mouse_event.left_pressed and self._touch_valid():
if rl.check_collision_point_rec(mouse_event.pos, self._hit_rect):
self._handle_mouse_press(mouse_event.pos)
self.__is_pressed[mouse_event.slot] = True
self.__tracking_is_pressed[mouse_event.slot] = True
self._handle_mouse_event(mouse_event)
# Callback such as scroll panel signifies user is scrolling
elif not self._touch_valid():
self.__is_pressed[mouse_event.slot] = False
self.__tracking_is_pressed[mouse_event.slot] = False
elif mouse_event.left_released:
self._handle_mouse_event(mouse_event)
if self.__is_pressed[mouse_event.slot] and rl.check_collision_point_rec(mouse_event.pos, self._hit_rect):
self._handle_mouse_release(mouse_event.pos)
self.__is_pressed[mouse_event.slot] = False
self.__tracking_is_pressed[mouse_event.slot] = False
# Mouse/touch is still within our rect
elif rl.check_collision_point_rec(mouse_event.pos, self._hit_rect):
if self.__tracking_is_pressed[mouse_event.slot]:
self.__is_pressed[mouse_event.slot] = True
self._handle_mouse_event(mouse_event)
# Mouse/touch left our rect but may come back into focus later
elif not rl.check_collision_point_rec(mouse_event.pos, self._hit_rect):
self.__is_pressed[mouse_event.slot] = False
self._handle_mouse_event(mouse_event)
self._process_mouse_events()
self.__was_awake = device.awake
return ret
def _process_mouse_events(self) -> None:
hit_rect = self._hit_rect
touch_valid = self._touch_valid()
for mouse_event in gui_app.mouse_events:
if not self._multi_touch and mouse_event.slot != 0:
continue
mouse_in_rect = rl.check_collision_point_rec(mouse_event.pos, hit_rect)
# Ignores touches/presses that start outside our rect
# Allows touch to leave the rect and come back in focus if mouse did not release
if mouse_event.left_pressed and touch_valid:
if mouse_in_rect:
self._handle_mouse_press(mouse_event.pos)
self.__is_pressed[mouse_event.slot] = True
self.__tracking_is_pressed[mouse_event.slot] = True
self._handle_mouse_event(mouse_event)
# Callback such as scroll panel signifies user is scrolling
elif not touch_valid:
self.__is_pressed[mouse_event.slot] = False
self.__tracking_is_pressed[mouse_event.slot] = False
elif mouse_event.left_released:
self._handle_mouse_event(mouse_event)
if self.__is_pressed[mouse_event.slot] and mouse_in_rect:
self._handle_mouse_release(mouse_event.pos)
self.__is_pressed[mouse_event.slot] = False
self.__tracking_is_pressed[mouse_event.slot] = False
# Mouse/touch is still within our rect
elif mouse_in_rect:
if self.__tracking_is_pressed[mouse_event.slot]:
self.__is_pressed[mouse_event.slot] = True
self._handle_mouse_event(mouse_event)
# Mouse/touch left our rect but may come back into focus later
elif not mouse_in_rect:
self.__is_pressed[mouse_event.slot] = False
self._handle_mouse_event(mouse_event)
@abc.abstractmethod
def _render(self, rect: rl.Rectangle) -> bool | int | None:
"""Render the widget within the given rectangle."""