From 6ec2e4a4829dba019fb3d527d6429822b1738900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natt=C5=8Dsai=20Mit=C5=8D?= Date: Tue, 22 Aug 2023 17:17:50 +0900 Subject: [PATCH 1/4] update dependencies --- .github/workflows/pythonapp.yml | 35 ++++++++++----------------------- pyproject.toml | 8 ++++---- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index 40a259a..ab8949e 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -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 @@ -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 diff --git a/pyproject.toml b/pyproject.toml index 1b519d0..9a827bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,10 +13,10 @@ 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', ] @@ -28,13 +28,13 @@ exclude = [ ] [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"] From 6dceffc01188e8588f6306d63c70930b922034dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natt=C5=8Dsai=20Mit=C5=8D?= Date: Tue, 22 Aug 2023 17:39:21 +0900 Subject: [PATCH 2/4] re-arrange the repository --- Makefile | 4 ++-- pyproject.toml | 5 +---- {kivy_garden => src/kivy_garden}/draggable/__init__.py | 0 {kivy_garden => src/kivy_garden}/draggable/_impl.py | 0 {kivy_garden => src/kivy_garden}/draggable/_utils.py | 0 {kivy_garden/draggable/tests => tests}/test_import.py | 0 .../tests => tests}/test_utils_restore_widget_location.py | 0 .../tests => tests}/test_utils_save_widget_location.py | 0 8 files changed, 3 insertions(+), 6 deletions(-) rename {kivy_garden => src/kivy_garden}/draggable/__init__.py (100%) rename {kivy_garden => src/kivy_garden}/draggable/_impl.py (100%) rename {kivy_garden => src/kivy_garden}/draggable/_utils.py (100%) rename {kivy_garden/draggable/tests => tests}/test_import.py (100%) rename {kivy_garden/draggable/tests => tests}/test_utils_restore_widget_location.py (100%) rename {kivy_garden/draggable/tests => tests}/test_utils_save_widget_location.py (100%) diff --git a/Makefile b/Makefile index 1a410c5..50c9472 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/pyproject.toml b/pyproject.toml index 9a827bd..d27f0a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,10 +21,7 @@ classifiers=[ 'Operating System :: OS Independent', ] packages = [ - { include = "kivy_garden" }, -] -exclude = [ - "kivy_garden/draggable/tests", + { include = "kivy_garden", from = "src" }, ] [tool.poetry.dependencies] diff --git a/kivy_garden/draggable/__init__.py b/src/kivy_garden/draggable/__init__.py similarity index 100% rename from kivy_garden/draggable/__init__.py rename to src/kivy_garden/draggable/__init__.py diff --git a/kivy_garden/draggable/_impl.py b/src/kivy_garden/draggable/_impl.py similarity index 100% rename from kivy_garden/draggable/_impl.py rename to src/kivy_garden/draggable/_impl.py diff --git a/kivy_garden/draggable/_utils.py b/src/kivy_garden/draggable/_utils.py similarity index 100% rename from kivy_garden/draggable/_utils.py rename to src/kivy_garden/draggable/_utils.py diff --git a/kivy_garden/draggable/tests/test_import.py b/tests/test_import.py similarity index 100% rename from kivy_garden/draggable/tests/test_import.py rename to tests/test_import.py diff --git a/kivy_garden/draggable/tests/test_utils_restore_widget_location.py b/tests/test_utils_restore_widget_location.py similarity index 100% rename from kivy_garden/draggable/tests/test_utils_restore_widget_location.py rename to tests/test_utils_restore_widget_location.py diff --git a/kivy_garden/draggable/tests/test_utils_save_widget_location.py b/tests/test_utils_save_widget_location.py similarity index 100% rename from kivy_garden/draggable/tests/test_utils_save_widget_location.py rename to tests/test_utils_save_widget_location.py From a93a2e88d3af3f31e3e21effeff27e0c6c22cd22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natt=C5=8Dsai=20Mit=C5=8D?= Date: Wed, 23 Aug 2023 08:34:55 +0900 Subject: [PATCH 3/4] adapt to asynckivy 0.6.0 --- examples/customizing_animation_ver2.py | 3 +-- examples/shopping.py | 6 +++--- src/kivy_garden/draggable/_impl.py | 8 ++++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/examples/customizing_animation_ver2.py b/examples/customizing_animation_ver2.py index 16956fa..2efbf1d 100644 --- a/examples/customizing_animation_ver2.py +++ b/examples/customizing_animation_ver2.py @@ -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 diff --git a/examples/shopping.py b/examples/shopping.py index 88e94c4..12370ce 100644 --- a/examples/shopping.py +++ b/examples/shopping.py @@ -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( diff --git a/src/kivy_garden/draggable/_impl.py b/src/kivy_garden/draggable/_impl.py index 3d7512f..a91cc0e 100644 --- a/src/kivy_garden/draggable/_impl.py +++ b/src/kivy_garden/draggable/_impl.py @@ -107,7 +107,7 @@ async def _see_if_a_touch_actually_is_a_dragging_gesture(self, touch): ak.sleep(self.drag_timeout / 1000.), self._true_when_a_touch_ended_false_when_it_moved_too_much(touch), ) - if tasks[0].done: + if tasks[0].finished: # The given touch is a dragging gesture. if self._can_be_dragged: await self._treat_a_touch_as_a_drag(touch, do_transform=True) @@ -187,7 +187,7 @@ async def _treat_a_touch_as_a_drag(self, touch, *, do_transform=False, touch_rec # store the task object so that the user can cancel it 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) @@ -207,11 +207,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 From 77ec6a6486f2c81b4b08be2d92edc4d00354f645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natt=C5=8Dsai=20Mit=C5=8D?= Date: Wed, 23 Aug 2023 09:49:25 +0900 Subject: [PATCH 4/4] refactor --- src/kivy_garden/draggable/_impl.py | 72 +++++++++++++----------------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/src/kivy_garden/draggable/_impl.py b/src/kivy_garden/draggable/_impl.py index a91cc0e..9bebdef 100644 --- a/src/kivy_garden/draggable/_impl.py +++ b/src/kivy_garden/draggable/_impl.py @@ -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 ( @@ -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 @@ -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 @@ -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: @@ -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].finished: - # 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): ''' @@ -180,12 +172,12 @@ 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.current_task()