55from pyglet .event import EVENT_HANDLED , EVENT_UNHANDLED
66from typing_extensions import override
77
8- from arcade .gui .events import UIMouseDragEvent , UIMouseEvent
8+ import arcade
9+ from arcade .gui .events import UIMouseDragEvent , UIMouseEvent , UIMousePressEvent , UIMouseReleaseEvent
910from arcade .gui .widgets import UILayout , UIWidget
1011
1112
@@ -17,8 +18,7 @@ class UIDraggableMixin(UILayout):
1718 class DraggablePane(UITexturePane, UIDraggableMixin):
1819 ...
1920
20- This does overwrite :class:`UILayout` behavior which position themselves,
21- like :class:`UIAnchorWidget`
21+ This will not work when placed in a layout, as the layout will overwrite the position.
2222
2323 warning:
2424
@@ -27,33 +27,37 @@ class DraggablePane(UITexturePane, UIDraggableMixin):
2727 It does not respect the layout system and can break other widgets
2828 which rely on the layout system.
2929
30- Further the dragging is not smooth, as it uses a very simple approach.
31-
32- Will be fixed in future versions, but might break existing code within a minor update.
33-
3430 """
3531
32+ _dragging = False
33+
3634 @override
3735 def do_layout (self ):
38- # FIXME this breaks all rules, let us not do this
39-
40- # Preserve top left alignment, this overwrites self placing behavior like
41- # from :class:`UIAnchorWidget`
36+ # FIXME this breaks core UI rules "Widgets are placed by parents", let us not do this
4237 rect = self .rect
4338 super ().do_layout ()
4439 self .rect = self .rect .align_top (rect .top ).align_left (rect .left )
4540
4641 @override
4742 def on_event (self , event ) -> Optional [bool ]:
4843 """Handle dragging of the widget."""
49- if isinstance (event , UIMouseDragEvent ) and self .rect .point_in_rect (event .pos ):
44+ if isinstance (event , UIMousePressEvent ):
45+ if event .button == arcade .MOUSE_BUTTON_LEFT and self .rect .point_in_rect (event .pos ):
46+ self ._dragging = True
47+ return EVENT_HANDLED
48+
49+ if isinstance (event , UIMouseDragEvent ) and self ._dragging :
5050 self .rect = self .rect .move (event .dx , event .dy )
5151 self .trigger_full_render ()
52-
53- if super ().on_event (event ):
5452 return EVENT_HANDLED
5553
56- return EVENT_UNHANDLED
54+ if isinstance (event , UIMouseReleaseEvent ):
55+ if event .button == arcade .MOUSE_BUTTON_LEFT and self ._dragging :
56+ self ._dragging = False
57+ self .trigger_full_render ()
58+ return EVENT_HANDLED
59+
60+ return super ().on_event (event )
5761
5862
5963class UIMouseFilterMixin (UIWidget ):
0 commit comments