Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
kivy-garden-draggable
Advanced tools
Inspired by:
Draggable
is based on this, so please read its documentation first to get the basic idea of this one)This flower adds a drag and drop functionality to layouts and widgets. There are 3 main components used to have drag and drop:
KXDraggableBehavior
. An equivalent of drag_n_drop's
DraggableObjectBehavior
.KXReorderableBehavior
. An equivalent of drag_n_drop's
DraggableLayoutBehavior
.KXDroppableBehavior
. An equivalent of Flutter's DragTarget
.From now on, I use the term droppable
to refer both KXReorderableBehavior
and KXDroppableBehavior
, and use the term draggable
to refer KXDraggableBehavior
.
It's recommended to pin the minor version, because if it changed, it means some important breaking changes occurred.
poetry add kivy_garden.draggable@~0.2
pip install "kivy_garden.draggable>=0.2,<0.3"
draggable.drag_timeout
milli seconds without traveling more than draggable.drag_distance
pixels, it will
be recognized as a dragging gesture.draggable.drag_cancel()
.KXReorderableBehavior
is not officially supported. It may or may
not work depending on how drag_classes
and drag_cls
are set.Once a drag has started, it will go through the following path.
stateDiagram-v2
state cancelled? <<choice>>
state on_a_droppable? <<choice>>
state listed? <<choice>>
state accepted? <<choice>>
[*] --> on_drag_start
on_drag_start --> cancelled?
cancelled? --> on_a_droppable?: User lifted their finger up
cancelled? --> on_drag_cancel: 'draggable.cancel()' was called before the user lifts their finger up
on_a_droppable? --> listed?: Finger was on a droppable
on_a_droppable? --> on_drag_fail: not on a droppable
droppable_is_set: 'ctx.droppable' is set to the droppable
listed? --> droppable_is_set: 'draggable.drag_cls' was listed in the 'droppable.drag_classes'
listed? --> on_drag_fail: not listed
droppable_is_set --> accepted?
accepted? --> on_drag_succeed: Droppable accepted the drag ('droppable.accepts_drag()' returned True.)
accepted? --> on_drag_fail
on_drag_cancel --> on_drag_end
on_drag_fail --> on_drag_end
on_drag_succeed --> on_drag_end
on_drag_end --> [*]
When your app switches a scene, you may want to cancel all the ongoing drags.
ongoing_drags()
and draggable.drag_cancel()
are what you want.
from kivy_garden.draggable import ongoing_drags
def cancel_all_ongoing_drags():
for draggable in ongoing_drags():
draggable.drag_cancel()
Let's say you are creating a card game, and there is a deck on the screen. Say, you want the deck to emit a card when the user drops a finger on it, and want the card to follow the finger until the user lifts it up. In this situation, a widget that triggers a drag and a widget that is dragged are different. You can implement it as follows:
class Card(KXDraggableBehavior, Widget):
pass
class Deck(Widget):
def on_touch_down(self, touch):
if self.collide_point(*touch.opos):
Card(...).start_dragging_from_others_touch(self, touch)
What draggables do on_drag_succeed
/ on_drag_fail
/ on_drag_cancel
are completely customizable.
For example, by default, when a drag fails, the draggable will go back to where it came from with little animation.
This is because the default handler of on_drag_fail
is implemented as follows:
class KXDraggableBehavior:
async def on_drag_fail(self, touch, ctx):
await ak.animate(
self, duration=.1,
x=ctx.original_pos_win[0],
y=ctx.original_pos_win[1],
)
restore_widget_state(self, ctx.original_state)
If you don't need the animation, and want the draggable to go back instantly, overwrite the handler as follows:
class MyDraggable(KXDraggableBehavior, Widget):
def on_drag_fail(self, touch, ctx):
restore_widget_state(self, ctx.original_state)
Or if you want the draggable to not go back, and want it to stay the current position, overwrite the handler as follows:
class MyDraggable(KXDraggableBehavior, Widget):
def on_drag_fail(self, touch, ctx):
pass
Another example: when a drag succeed, the draggable will become a child of droppable, by default. If you don't like it, and want the draggable to fade-out, overwrite the handler as follows:
class MyDraggable(KXDraggableBehavior, Widget):
async def on_drag_succeed(self, touch, ctx):
import asynckivy
await asynckivy.animate(self, opacity=0)
self.parent.remove_widget(self)
Just like that, you have free rein to change those behaviors.
But note that only the default handler of on_drag_succeed
and on_drag_fail
can be an async function. Those two only.
You might say "What's the point of implementing a default handler as an async function,
when you can just launch any number of tasks from a regular function by using asynckivy.start()
?".
Well, if you use asynckivy.start()
, that task will run independently from the dragging process,
which means the draggable might fire on_drag_end
and might start another drag while the task is still running.
If a default handler is an async function,
its code will be a part of dragging process and is guaranteed to be finished before on_drag_end
gets fired.
This software is released under the terms of the MIT License.
FAQs
Drag & Drop Extension for Kivy
We found that kivy-garden-draggable demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.