from pyglet.event import EVENT_HANDLED, EVENT_UNHANDLED
from arcade.gui.widgets import UIWidget, UILayout
from arcade.gui.events import UIMouseDragEvent, UIMouseEvent
[docs]class UIDraggableMixin(UILayout):
"""
UIDraggableMixin can be used to make any :class:`UIWidget` draggable.
Example, create a draggable Frame, with a background, useful for window like constructs:
class DraggablePane(UITexturePane, UIDraggableMixin):
...
This does overwrite :class:`UILayout` behaviour which position themselves, like :class:`UIAnchorWidget`
"""
def do_layout(self):
# Preserve top left alignment, this overwrites self placing behaviour like from :class:`UIAnchorWidget`
rect = self.rect
super().do_layout()
self.rect = self.rect.align_top(rect.top).align_left(rect.left)
def on_event(self, event) -> bool:
if isinstance(event, UIMouseDragEvent) and self.rect.collide_with_point(event.x, event.y):
self.rect = self.rect.move(event.dx, event.dy)
self.trigger_full_render()
if super().on_event(event):
return EVENT_HANDLED
return EVENT_UNHANDLED
[docs]class UIMouseFilterMixin(UIWidget):
"""
:class:`UIMouseFilterMixin` can be used to catch all mouse events which occur inside this widget.
Usefull for window like widgets, :class:`UIMouseEvents` should not trigger effects which are under the widget.
"""
def on_event(self, event):
if super().on_event(event):
return EVENT_HANDLED
if isinstance(event, UIMouseEvent):
# Catch all mouse events, that are inside this widget, to act like a window
if self.rect.collide_with_point(*event.pos):
return EVENT_HANDLED
[docs]class UIWindowLikeMixin(UIMouseFilterMixin, UIDraggableMixin, UIWidget):
"""
Makes a widget window like:
- handles all mouse events that occur within the widgets boundaries
- can be dragged
"""