Skip to content

Commit

Permalink
publish 0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
gottadiveintopython committed Aug 28, 2023
1 parent b405e18 commit 8ef59de
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 30 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ From now on, I use the term `droppable` to refer both `KXReorderableBehavior` an
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.1
pip install "kivy_garden.draggable>=0.1,<0.2"
poetry add kivy_garden.draggable@~0.2
pip install "kivy_garden.draggable>=0.2,<0.3"
```

## Main differences from drag_n_drop
Expand Down Expand Up @@ -156,7 +156,7 @@ 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 regular function by using ``asynckivy.start()``?".
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,
Expand Down
54 changes: 28 additions & 26 deletions README_jp.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
![](http://img.youtube.com/vi/CjiRZjiSqgA/0.jpg)
[Youtube][youtube]

`kivy_garden.draggable`はdrag&dropの機能を実現するための拡張機能で以下の三つの部品で構成される
`kivy_garden.draggable`はdrag&dropの機能を実現するための拡張機能で以下の三つの部品で構成されます

- `KXDraggableBehavior` ... dragできるようにしたいwidgetが継承すべきclass
- `KXDroppableBehavior``KXReorderableBehavior` ... dragされているwidgetを受け入れられるようにしたいwidgetが継承すべきclass
Expand All @@ -15,17 +15,18 @@
このmoduleのminor versionが変わった時は何らかの重要な互換性の無い変更が加えられた可能性が高いので、使う際はminor versionまでを固定してください。

```
poetry add kivy_garden.draggable@~0.1
pip install "kivy_garden.draggable>=0.1,<0.2"
poetry add kivy_garden.draggable@~0.2
pip install "kivy_garden.draggable>=0.2,<0.3"
```

## dragが始まる条件

dragは長押しによって引き起こされる。より具体的には利用者の指がdraggable内に降りてから`draggable.drag_distance`pixel以上動かずに`draggable.drag_timeout`ミリ秒以上指が離れなかった場合のみ引き起こされる。このためscroll操作(指がすぐさま動き出す)やtap動作(指がすぐに離れる)として誤認されにくい。
dragは長押しによって引き起こされます。より具体的には利用者の指がdraggable内に降りてから`draggable.drag_distance`pixel以上動かずに`draggable.drag_timeout`ミリ秒以上指が離れなかった場合のみ引き起こされます。
このためscroll操作(指がすぐさま動き出す)やtap動作(指がすぐに離れる)として誤認されにくいです。

## dragが始まった後の処理の流れ

ユーザーがdraggableの上に指を降ろしてdragが始まった後の流れは以下のようになる
ユーザーがdraggableの上に指を降ろしてdragが始まった後の流れは以下のようになります

```mermaid
stateDiagram-v2
Expand Down Expand Up @@ -60,26 +61,26 @@ stateDiagram-v2
## 受け入れるdragの選別

図に書かれているように利用者の指が離れた時にdragが受け入れられるか否かの判断がなされ、
指がdroppableの上じゃない所で離れた場合や`draggable.drag_cls``droppable.drag_classes`に含まれていない場合はまず即drag失敗となる
指がdroppableの上じゃない所で離れた場合や`draggable.drag_cls``droppable.drag_classes`に含まれていない場合はまず即drag失敗となります

その選別をくぐり抜けたdraggableは`droppable.accepts_drag()`へ渡され、そこでdragが受け入れられるか否かの最終判断が下される。例えばmethodが
その選別をくぐり抜けたdraggableは`droppable.accepts_drag()`へ渡され、そこでdragが受け入れられるか否かの最終判断が下されます。例えばmethodが

```python
class MyDroppable(KXDroppableBehavior, Widget):
def accepts_drag(self, touch, draggable) -> bool:
return not self.children
```

という風に実装されていたら、このdroppableは自分が子を持っている間は例え適切な`drag_cls`を持つdraggableであっても受け付けない
という風に実装されていたら、このdroppableは自分が子を持っている間は例え適切な`drag_cls`を持つdraggableであっても受け付けません

## dragの中止

アプリが次のシーンに移りたい時にまだdrag中のwidgetがあると不都合かもれしない。そのような事態に備えて
アプリが次のシーンに移りたい時にまだdrag中のwidgetがあると不都合かもしれません。そのような事態に備えて

- 現在進行中のdragを列挙する`ongoing_drags()`
- dragを中止する`draggable.drag_cancel()`がある
- dragを中止する`draggable.drag_cancel()`があります

これらを用いる事で以下のように進行中のdragを全て中止できる
これらを用いる事で以下のように進行中のdragを全て中止できます

```python
from kivy_garden.draggable import ongoing_drags
Expand All @@ -92,17 +93,17 @@ def cancel_all_ongoing_drags():
## dragを引き起こすwidgetとdragされるwidgetを別にする

上で述べたようにdragはdraggableを長押しすることで引き起こされるので、
dragを引き起こすwidgetとdragされるwidgetは基本同じである
でも例えばcard gameを作っているとして画面上に山札があったとする。
そしてdrag操作によって山札から札を引けるようにしたいとする
dragを引き起こすwidgetとdragされるwidgetは基本同じです
でも例えばcard gameを作っているとして画面上に山札があったとして
drag操作によって山札から札を引けるようにしたいとします
具体的には利用者が山札に指を触れた時に札を作り出し、
そのまま指の動きに沿って札を追わせたいとする
そのまま指の動きに沿って札を追わせたいとします
このような

- dragを引き起こすwidget(山札)と
- dragされるwidget(山札から引かれた札)

が別である状況では`draggable.start_dragging_from_others_touch()`が使える
が別である状況では`draggable.start_dragging_from_others_touch()`が使えます

```python
class Card(KXDraggableBehavior, Widget):
Expand All @@ -117,23 +118,24 @@ class Deck(Widget):

## 自由に振る舞いを変える

dragが失敗/成功/中止した時に何をするかは完全にあなたに委ねられている。例えばdrag失敗時は既定ではアニメーションしながら元の場所に戻るが、これをアニメーション無しで瞬時に戻したいなら以下のようにdefault handlerを上書きすれば良い。
dragが失敗/成功/中止した時に何をするかは完全にあなたに委ねられています。
例えばdrag失敗時は既定ではアニメーションしながら元の場所に戻りますが、これをアニメーション無しで瞬時に戻したいなら以下のようにdefault handlerを上書きすれば良いです。

```python
class MyDraggable(KXDraggableBehavior, Widget):
def on_drag_fail(self, touch, ctx):
restore_widget_state(self, ctx.original_state)
```

また何もせずにその場に残って欲しいなら以下のようにすれば良い
また何もせずにその場に残って欲しいなら以下のようにすれば良いです

```python
class MyDraggable(KXDraggableBehavior, Widget):
def on_drag_fail(self, touch, ctx):
pass
```

成功時も同様で、既定では受け入れてくれたdroppableの子widgetになるように実装されているが以下のようにすれば子widgetにはならずに現在の位置で徐々に透明になって消える事になる
成功時も同様で、既定では受け入れてくれたdroppableの子widgetになるように実装されていますが以下のようにすると子widgetにはならずに現在の位置で徐々に透明になって消える事になります

```python
import asynckivy as ak
Expand All @@ -144,17 +146,17 @@ class MyDraggable(KXDraggableBehavior, Widget):
self.parent.remove_widget(self)
```

このようにdefault handlerを上書きすることで自由に振るまいを変えられる
ただし**async関数になれるのは`on_drag_succeed``on_drag_fail`のdefault handlerだけ**なので注意されたし
このようにdefault handlerを上書きすることで自由に振るまいを変えられます
ただし**async関数になれるのは`on_drag_succeed``on_drag_fail`のdefault handlerだけ**なので注意してください

ここで

- default handlerをasync関数にするのと
- default handlerは普通の関数のままにしておいて内部で`asynckivy.start()`を用いてasync関数を立ち上げるのと

の違いについて説明する
前者ではasync関数のcodeがdrag処理の間に挟み込まれ、codeが`on_drag_end`が起こるより前に完遂される事が保証されるのに対し、
後者ではcodeがdrag処理とは独立して進むので`on_drag_end`が起こるより前に完了する保証はない
の違いについて説明します
前者ではasync関数のcodeがdrag処理の間に挟み込まれcodeが`on_drag_end`が起こるより前に完遂される事が保証されるのに対し、
後者ではcodeがdrag処理とは独立して進むので`on_drag_end`が起こるより前に完了する保証はありません
なのでもし上の`on_drag_succeed`の例を後者のやり方で実装すると

```python
Expand All @@ -170,8 +172,8 @@ class MyDraggable(KXDraggableBehavior, Widget):
```

`ak.animate()`の進行中にdragが完了し、そこで利用者が再び指を触れたことで次のdragが始まり、
その最中に`self.parent.remove_widget(self)`が実行されてdraggableが親widgetから切り離されてしまうなんて事が起こりうる
なので **drag完了前に完遂させたい非同期処理があるのなら必ず前者の方法を使うべし**
その最中に`self.parent.remove_widget(self)`が実行されてdraggableが親widgetから切り離されてしまうなんて事が起こりえます
なので **drag完了前に完遂させたい非同期処理があるのなら必ず前者の方法を使ってください**

## その他

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "kivy-garden-draggable"
version = "0.2.0.dev1"
version = "0.2.0"
description = "Drag & Drop Extension for Kivy"
authors = ["Nattōsai Mitō <[email protected]>"]
license = "MIT"
Expand Down

0 comments on commit 8ef59de

Please sign in to comment.