Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor & edit doc & update dependencies #35

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.9', '3.10', '3.11', '3.12']
env:
DISPLAY: ':99.0'
steps:
Expand All @@ -27,7 +27,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest flake8 kivy[base]==2.2.1 "asynckivy>=0.6<0.7" "asyncgui>=0.6<0.7"
python -m pip install pytest flake8 kivy[base]==2.3.0 "asynckivy>=0.6<0.7" "asyncgui>=0.6<0.7"
- name: Install flower
run: python -m pip install -e .
- name: Lint with flake8
Expand Down
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ venv/
ENV/
env.bak/
venv.bak/
Pipfile.lock
poetry.lock
.vscode

# Spyder project settings
Expand Down
49 changes: 22 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ From now on, I use the term `droppable` to refer both `KXReorderableBehavior` an

## Installation

It's recommended to pin the minor version, because if it changed, it means some important breaking changes occurred.
Pin the minor version.

```
poetry add kivy_garden.draggable@~0.2
Expand Down Expand Up @@ -76,8 +76,8 @@ stateDiagram-v2

## Cancellation

When your app switches a scene, you may want to cancel all ongoing drags.
`ongoing_drags()` and `draggable.drag_cancel()` are what you want.
When your app changes scenes, you might want to cancel all ongoing drags.
For this, you can use `ongoing_drags()` and `draggable.drag_cancel()`.

```python
from kivy_garden.draggable import ongoing_drags
Expand All @@ -87,13 +87,12 @@ def cancel_all_ongoing_drags():
draggable.drag_cancel()
```

## Using other widgets as an emitter
## Using other widgets as emitters

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:
Imagine you're creating a card game, and there's a deck on the screen.
Suppose you want the deck to emit a card when the user places a finger on it, and you want the card to follow the finger until the user lifts it.
In this scenario, the widget that triggers the drag and the widget being dragged are distinct.
Here's how you can implement it:

```python
class Card(KXDraggableBehavior, Widget):
Expand All @@ -108,9 +107,9 @@ class Deck(Widget):

## Customization

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:
The behavior of `on_drag_succeed`, `on_drag_fail`, and `on_drag_cancel` for draggables is fully customizable.
For instance, by default, when a drag fails, the draggable returns to its original position with a brief animation.
This happens because the default handler for `on_drag_fail` is implemented as follows:

```python
class KXDraggableBehavior:
Expand All @@ -123,25 +122,24 @@ class KXDraggableBehavior:
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:
If you don't need the animation and want the draggable to return instantly, you can override the handler like this:

```python
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:
Or, if you'd prefer the draggable to stay in its current position and not return at all, override the handler as follows:

```python
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:
Another example: by default, when a drag succeeds, the draggable becomes a child of the droppable.
If you don't like this behavior and prefer the draggable to fade out instead, you can override the handler like this:

```python
class MyDraggable(KXDraggableBehavior, Widget):
Expand All @@ -151,20 +149,17 @@ class MyDraggable(KXDraggableBehavior, Widget):
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.**
As you can see, you have full control to customize these behaviors.
However, note that only the default handlers for `on_drag_succeed` and `on_drag_fail` can be async functions—just those two.

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.
You might wonder, "Why implement a default handler as an async function when you can simply launch tasks from a regular function using `asynckivy.start()`?"
The key difference is that tasks started with `asynckivy.start()` run independently of the dragging process.
This means the draggable might trigger `on_drag_end` and even start another drag while the task is still running.
In contrast, if the default handler is an async function, its code is integrated into the dragging process and is guaranteed to finish before `on_drag_end` is triggered.

## License

This software is released under the terms of the MIT License.
MIT

[drag_n_drop]:https://github.com/kivy-garden/drag_n_drop
[flutter]:https://api.flutter.dev/flutter/widgets/Draggable-class.html
Expand Down
Loading