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

Adapt to the latest asynckivy #26

Merged
merged 4 commits into from
Aug 23, 2023
Merged
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
35 changes: 10 additions & 25 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
name: Garden flower
on: [push, pull_request]
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
linux_test:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
python-version: ['3.8', '3.9', '3.10', '3.11']
env:
DISPLAY: ':99.0'
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Setup env
Expand All @@ -23,29 +27,10 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest flake8 kivy[base]
python -m pip install pytest flake8 kivy[base]==2.2.1 "asynckivy>=0.6<0.7" "asyncgui>=0.6<0.7"
- name: Install flower
run: python -m pip install -e .
- name: Lint with flake8
run: make style
- name: Test with pytest
run: make test

windows_test:
runs-on: windows-latest
env:
KIVY_GL_BACKEND: angle_sdl2
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest kivy[base]
- name: Install flower
run: python -m pip install -e .
- name: Test with pytest
run: make test
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ PYTEST = $(PYTHON) -m pytest
FLAKE8 = $(PYTHON) -m flake8

test:
$(PYTEST) ./kivy_garden/draggable/tests
$(PYTEST) ./tests

style:
$(FLAKE8) ./kivy_garden/draggable
$(FLAKE8) ./src/kivy_garden/draggable
3 changes: 1 addition & 2 deletions examples/customizing_animation_ver2.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
from kivy.graphics import Rotate, Scale

import asynckivy as ak
from asynckivy import vanim
from asynckivy.utils import transform
from asynckivy import vanim, transform

from kivy_garden.draggable import KXDroppableBehavior, KXDraggableBehavior

Expand Down
6 changes: 3 additions & 3 deletions examples/shopping.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,12 @@ async def _init_database(conn: sqlite3.Connection):
# FIXME: The Session object may not be thread-safe so it's probably better not to share it between threads...
with ThreadPoolExecutor() as executer, requests.Session() as session:
async def download_one_image(name, image_url) -> Tuple[bytes, str]:
image = await ak.run_in_executer(lambda: session.get(image_url).content, executer)
image = await ak.run_in_executor(executer, lambda: session.get(image_url).content)
return (image, name)
tasks = await ak.and_from_iterable(
tasks = await ak.wait_all(*(
download_one_image(name, image_url)
for name, image_url in cur.execute("SELECT name, image_url FROM Foods")
)
))

# save images
cur.executemany(
Expand Down
13 changes: 5 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,25 @@ classifiers=[
'License :: OSI Approved :: MIT License',
'Intended Audience :: Developers',
'Programming Language :: Python',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Topic :: Software Development :: Libraries',
'Operating System :: OS Independent',
]
packages = [
{ include = "kivy_garden" },
]
exclude = [
"kivy_garden/draggable/tests",
{ include = "kivy_garden", from = "src" },
]

[tool.poetry.dependencies]
python = "^3.7"
asynckivy = "~0.5"
python = "^3.8.1"
asynckivy = "~0.6"

[tool.poetry.group.dev.dependencies]
pytest = "^7.1.2"
flake8 = "^5.0.4"
kivy = "==2.1.0"
kivy = "==2.2.1"

[build-system]
requires = ["poetry-core"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from kivy.factory import Factory
import kivy.core.window
from kivy.uix.widget import Widget
from kivy.uix.scrollview import ScrollView
import asynckivy as ak

from ._utils import (
Expand All @@ -23,13 +24,6 @@
)


# When we are generating documentation, Config doesn't exist
_scroll_timeout = _scroll_distance = 0
if Config:
_scroll_timeout = Config.getint('widgets', 'scroll_timeout')
_scroll_distance = Config.get('widgets', 'scroll_distance') + 'sp'


@dataclass
class DragContext:
original_pos_win: tuple = None
Expand All @@ -54,9 +48,9 @@ class KXDraggableBehavior:
drag_cls = StringProperty()
'''Same as drag_n_drop's '''

drag_distance = NumericProperty(_scroll_distance)
drag_distance = NumericProperty(ScrollView.scroll_distance.defaultvalue)

drag_timeout = NumericProperty(_scroll_timeout)
drag_timeout = NumericProperty(ScrollView.scroll_timeout.defaultvalue)

drag_enabled = BooleanProperty(True)
'''Indicates whether this draggable can be dragged or not. Changing this
Expand All @@ -70,14 +64,14 @@ class KXDraggableBehavior:
'''(read-only)'''

def drag_cancel(self):
'''Cancels drag as soon as possible. Does nothing if the draggable is
not being dragged.
'''
If the draggable is currently being dragged, cancel it.
'''
self._drag_task.cancel()

def __init__(self, **kwargs):
self._drag_task = ak.dummy_task
super().__init__(**kwargs)
self._drag_task = ak.dummy_task
self.__ud_key = 'KXDraggableBehavior.' + str(self.uid)

def _is_a_touch_potentially_a_dragging_gesture(self, touch) -> bool:
Expand All @@ -103,33 +97,31 @@ def on_touch_down(self, touch):
return super().on_touch_down(touch)

async def _see_if_a_touch_actually_is_a_dragging_gesture(self, touch):
tasks = await ak.or_(
ak.sleep(self.drag_timeout / 1000.),
self._true_when_a_touch_ended_false_when_it_moved_too_much(touch),
)
if tasks[0].done:
# The given touch is a dragging gesture.
if self._can_be_dragged:
await self._treat_a_touch_as_a_drag(touch, do_transform=True)
else:
await self._simulate_a_normal_touch(touch, do_transform=True)
else:
# The given touch is not a dragging gesture.
await self._simulate_a_normal_touch(touch, do_touch_up=tasks[1].result)
async with ak.wait_any_cm(ak.sleep(self.drag_timeout / 1000.)): # <- 'trio.move_on_after()' equivalent
# LOAD_FAST
abs_ = abs
drag_distance = self.drag_distance
ox, oy = touch.opos

do_touch_up = True
async with ak.watch_touch(self, touch) as in_progress:
while await in_progress():
dx = abs_(touch.x - ox)
dy = abs_(touch.y - oy)
if dy > drag_distance or dx > drag_distance:
do_touch_up = False
break

# Reaching here means the given touch is not a dragging gesture.
ak.start(self._simulate_a_normal_touch(touch, do_touch_up=do_touch_up))
return

async def _true_when_a_touch_ended_false_when_it_moved_too_much(self, touch):
# LOAD_FAST
abs_ = abs
drag_distance = self.drag_distance

ox, oy = touch.opos
async with ak.watch_touch(self, touch) as is_touch_move:
while await is_touch_move():
dx = abs_(touch.x - ox)
dy = abs_(touch.y - oy)
if dy > drag_distance or dx > drag_distance:
return False
return True
# Reaching here means the given touch is a dragging gesture.
ak.start(
self._treat_a_touch_as_a_drag(touch, do_transform=True)
if self._can_be_dragged else
self._simulate_a_normal_touch(touch, do_transform=True)
)

def start_dragging_from_others_touch(self, receiver: Widget, touch):
'''
Expand Down Expand Up @@ -180,14 +172,14 @@ async def _treat_a_touch_as_a_drag(self, touch, *, do_transform=False, touch_rec
)
window.add_widget(self)

# mark the touch so that other widgets can react to the drag
# mark the touch so that other widgets can react to this drag
touch_ud['kivyx_drag_cls'] = self.drag_cls
touch_ud['kivyx_draggable'] = self
touch_ud['kivyx_drag_ctx'] = ctx

# store the task object so that the user can cancel it
# store the task instance so that the user can cancel it later
self._drag_task.cancel()
self._drag_task = await ak.get_current_task()
self._drag_task = await ak.current_task()

# actual dragging process
self.dispatch('on_drag_start', touch, ctx)
Expand All @@ -207,11 +199,11 @@ async def _treat_a_touch_as_a_drag(self, touch, *, do_transform=False, touch_rec
else:
r = self.dispatch('on_drag_succeed', touch, ctx)
self.drag_state = 'succeeded'
async with ak.cancel_protection():
async with ak.disable_cancellation():
if isawaitable(r):
await r
await ak.sleep(-1) # This is necessary in order to work with Magnet iirc.
except GeneratorExit:
except ak.Cancelled:
self.dispatch('on_drag_cancel', touch, ctx)
self.drag_state = 'cancelled'
raise
Expand Down
File renamed without changes.
File renamed without changes.