Drag-N-Drop¶
kivy_garden.drag_n_drop
¶
Drag and Drop¶
This adds a drag and drop functionality to layouts and widgets. There are 2 primary and one internal component used to have drag and drop:
The
DraggableObjectBehavior
. Each widget that can be dragged needs to inherit from this. It hasDraggableObjectBehavior.drag_cls
, which is a string that indicates theDraggableLayoutBehavior
instance into which the widget can potentially be dropped.The
DraggableLayoutBehavior
, which any layout that wants to accept drop behavior must inherit from. It has aDraggableLayoutBehavior.drag_classes
, which determines the dragging widgets it accepts - theirDraggableObjectBehavior.drag_cls
must be listed inDraggableLayoutBehavior.drag_classes
.Finally,
DraggableController`which manages the drag and drop coordination. This is created automatically for each :class:`DraggableObjectBehavior.drag_controller
upon first drag, or it can be set by the user to a global controller to save memory.
Layout¶
To use DraggableLayoutBehavior
with a layout,
DraggableLayoutBehavior.compare_pos_to_widget()
must be implement for
each
layout. This determines where in the layout the widget is being previewed and
ultimitely dropped. But, it can be further customized for any type of layout
by overwriting the default
DraggableLayoutBehavior.get_drop_insertion_index_move()
and
DraggableLayoutBehavior.get_drop_insertion_index_up()
.
Similarly, handle_drag_release()
should be implemented. It handles the
actual final drop into the layout. A good default implementation is:
def handle_drag_release(self, index, drag_widget):
self.add_widget(drag_widget, index)
Dragging Widget¶
To use DraggableObjectBehavior
, one should implement
DraggableObjectBehavior.initiate_drag()
and/or
DraggableObjectBehavior.complete_drag()
. Typically, you would want to
remove the widget from it’s current layout as it starts to be dragged, with
e.g.
def initiate_drag(self):
self.parent.remove_widget(self)
Describing Which Widgets can be Dropped Into Which Layout¶
Given some DraggableObjectBehavior
and
some DraggableLayoutBehavior
instances. We can control which widget
can be dragged into which layout using their
DraggableObjectBehavior.drag_cls
and
DraggableLayoutBehavior.drag_classes
.
DraggableObjectBehavior.drag_cls
must be listed in
DraggableLayoutBehavior.drag_classes
for the widget to be draggable
into the layout.
Example¶
Following is an example with kivy.uix.boxlayout.BoxLayout
:
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
class DraggableBoxLayout(DraggableLayoutBehavior, BoxLayout):
def compare_pos_to_widget(self, widget, pos):
if self.orientation == 'vertical':
return 'before' if pos[1] >= widget.center_y else 'after'
return 'before' if pos[0] < widget.center_x else 'after'
def handle_drag_release(self, index, drag_widget):
self.add_widget(drag_widget, index)
class DragLabel(DraggableObjectBehavior, Label):
def initiate_drag(self):
# during a drag, we remove the widget from the original location
self.parent.remove_widget(self)
And then in kv:
BoxLayout:
DraggableBoxLayout:
drag_classes: ['label']
orientation: 'vertical'
Label:
text: 'A'
Label:
text: 'A'
Label:
text: 'A'
DraggableBoxLayout:
drag_classes: ['label']
orientation: 'vertical'
DragLabel:
text: 'A*'
drag_cls: 'label'
DragLabel:
text: 'A*'
drag_cls: 'label'
-
class
kivy_garden.drag_n_drop.
DraggableBoxLayoutBehavior
(**kwargs)¶ Bases:
kivy_garden.drag_n_drop.DraggableLayoutBehavior
-
compare_pos_to_widget
(widget, pos)¶ After we call
get_widget_under_drag()
to find the widget inchildren
that is currently under the given pos (the current mouse pos that drags a widget), we call this to find whether the mouse pos indicates that the dragged widget needs to be added before or after the widget returned byget_widget_under_drag()
.It must return either the string “before”, or “after”.
See
get_drop_insertion_index_move()
andget_drop_insertion_index_up()
.
-
-
class
kivy_garden.drag_n_drop.
DraggableController
(**kwargs)¶ Bases:
kivy._event.EventDispatcher
The controller that manages the dragging process.
-
clean_dragging
()¶ Removes the drag widget preview.
-
drag_distance
¶ Minimum amount of pixel distance a widget needs to be dragged before we start going into drag mode.
-
drag_down
(source, touch)¶ Called by
DraggableObjectBehavior
when it got a touch down.
-
drag_move
(source, touch)¶ Called by
DraggableObjectBehavior
when it got a touch move.
-
drag_up
(source, touch)¶ Called by
DraggableObjectBehavior
when it got a touch up.
-
dragging
¶ Whether the controller is currently dragging something.
-
prepare_preview_widget
(source_widget)¶
-
preview_background_color
¶ The background color of the preview widget as it’s dragged.
Defaults to
rgba=0,0,0,1
, which means the dragging widget will be placed on a black background. To make the background transparent, set it to(0, 0, 0, 0)
.
-
preview_pixels
= None¶
-
preview_widget
= None¶ The widget shown as preview during a drag, which follows the current mouse position. Defaults to a
PreviewWidget
. that f
-
start_widget_pos
= (0, 0)¶
-
touch_dx
= 0¶
-
touch_dy
= 0¶
-
widget_dragged
¶ The
DraggableObjectBehavior
widget currently being dragged by the controller.
-
-
class
kivy_garden.drag_n_drop.
DraggableGridLayoutBehavior
(**kwargs)¶ Bases:
kivy_garden.drag_n_drop.DraggableLayoutBehavior
-
compare_pos_to_widget
(widget, pos)¶ After we call
get_widget_under_drag()
to find the widget inchildren
that is currently under the given pos (the current mouse pos that drags a widget), we call this to find whether the mouse pos indicates that the dragged widget needs to be added before or after the widget returned byget_widget_under_drag()
.It must return either the string “before”, or “after”.
See
get_drop_insertion_index_move()
andget_drop_insertion_index_up()
.
-
-
class
kivy_garden.drag_n_drop.
DraggableLayoutBehavior
(**kwargs)¶ Bases:
object
Adds support to a layout such that we can drag widgets into this layout and preview it while dragging.
Only
DraggableObjectBehavior
widgets whoseDraggableObjectBehavior.drag_cls
are indrag_classes
will be dropable into the layout.-
compare_pos_to_widget
(widget, pos)¶ After we call
get_widget_under_drag()
to find the widget inchildren
that is currently under the given pos (the current mouse pos that drags a widget), we call this to find whether the mouse pos indicates that the dragged widget needs to be added before or after the widget returned byget_widget_under_drag()
.It must return either the string “before”, or “after”.
See
get_drop_insertion_index_move()
andget_drop_insertion_index_up()
.
-
drag_append_end
¶ Whether the
DraggableObjectBehavior
when dragged over the layout’s area should be previewed and return an index that would add it at that location in its children, or if it will only support adding the widget to the end of children.
-
drag_classes
¶ During a drag, the controller will try to preview and add the dragged
DraggableObjectBehavior
to this layout widget when it is over the widget’s area. But, it will only do it if the dragged widget’sDraggableObjectBehavior.drag_cls
is in the layout’sdrag_classes
.This allows selecting which widgets can be dropped where.
-
get_drop_insertion_index_move
(x, y)¶ During a drag, it is called with when we need to figure out where to display the spacer widget in the layout.
It calls
get_widget_under_drag()
to find the widget in the layout currently under the mouse pos. Then it usescompare_pos_to_widget()
to figure out if it should be added before, or after that widget and returns the index inchildren
where the spacer should be added to represent the potential drop.If the spacer is under the current pos, or if no widget is under it (
get_widget_under_drag()
returnedNone
), we return None, otherwise the index.
-
get_drop_insertion_index_up
(x, y)¶ When dropping a drag, it is called to get the index in children of the layout where the widget was dropped and where it needs to be inserted.
It calls
get_widget_under_drag()
to find the widget in the layout currently under the mouse pos. Then it usescompare_pos_to_widget()
to figure out if it should be added before, or after that widget and returns the index inchildren
where the it should be added to complete the drop.
-
get_widget_under_drag
(x, y)¶ Returns the widget in children that is under the given position (current mouse pos that drags the widget).
See
get_drop_insertion_index_move()
andget_drop_insertion_index_up()
.
-
handle_drag_release
(index, drag_widget)¶ This is called when a widget is dropped in the layout.
index
is the index in children where the widget should be added.drag_widget
is theDraggableObjectBehavior
that was dropped there.This must be overwritten by the inherited class to actually do the
add_widget
or something else.
-
on_touch_move
(touch)¶
-
on_touch_up
(touch)¶
-
spacer_props
¶ The properties of
spacer_widget
, which will be set according to this dict. This enables setting the sizing info for the preview widget in the layout.
-
spacer_widget
¶ The widget that is added to the layout to show where the dragged widget could be dropped.
Defaults to
SpacerWidget
if not set.
-
-
class
kivy_garden.drag_n_drop.
DraggableObjectBehavior
¶ Bases:
object
A widget that inherits from this class can participate in a drag by someone dragging it with the mouse.
-
complete_drag
()¶ Called by the
DraggableController
, when a drag is completed.
-
drag_cls
¶ A name to determine where we can potentially drop the dragged widget. For each
DraggableLayoutBehavior
that we hover over, ifdrag_cls
is in thatDraggableLayoutBehavior.drag_classes
, we will preview and allow the widget to be dropped there.
-
drag_controller
¶ A (potentially global)
DraggableController
instance that manages the (potential) drag. If None during the first potential drag, aDraggableController
instance will be created and set.
-
drag_widget
¶ The widget, whose texture will be copied and previewed as the object is dragged. If None, it’s this widget.
-
initiate_drag
()¶ Called by the
DraggableController
, when a drag is initiated on the widget (i.e. thw widget is actually being dragged once it exceeds the minimum drag distance).
-
on_touch_down
(touch)¶
-
on_touch_move
(touch)¶
-
on_touch_up
(touch)¶
-
-
class
kivy_garden.drag_n_drop.
PreviewWidget
(**kwargs)¶ Bases:
kivy.uix.widget.Widget
The widget that is used to preview the widget being dragged, during a drag. Used internally.
-
preview_texture
¶ The texture that is previewed when a widget is being dragged.
-
-
class
kivy_garden.drag_n_drop.
SpacerWidget
(**kwargs)¶ Bases:
kivy.uix.widget.Widget
Widget inserted at the location where the dragged widget may be dropped to show where it’ll be dropped.