diff --git a/CHANGELOG.md b/CHANGELOG.md index de37487..f7fa4a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Version 0.13.2 + +- refactor: avoid loading kivy when constants are imported + ## Version 0.13.1 - feat: widen the notification text horizontally if it doesn't have any actions on the left diff --git a/poetry.lock b/poetry.lock index a117371..0fa853a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] @@ -134,13 +134,13 @@ files = [ [[package]] name = "headless-kivy" -version = "0.9.7" +version = "0.9.8" description = "Headless renderer for Kivy framework" optional = false python-versions = "<4.0,>=3.11" files = [ - {file = "headless_kivy-0.9.7-py3-none-any.whl", hash = "sha256:647f012d289a4c64e366e526ad113c85646d5f1cb034fa5d76713b3aaa7c3bf2"}, - {file = "headless_kivy-0.9.7.tar.gz", hash = "sha256:247534b46f80732621e1336b1ff83d5d05a023042ba16b27c572d04323cd5c37"}, + {file = "headless_kivy-0.9.8-py3-none-any.whl", hash = "sha256:a08eaa488ca16bbe37bc40d65f2074972c646f7d30540f8cff17a58885a3ec48"}, + {file = "headless_kivy-0.9.8.tar.gz", hash = "sha256:deae8fd400cca370f285aaaa1499011f9129d943aa2cf6feb04820e30d006c9c"}, ] [package.dependencies] @@ -154,15 +154,18 @@ test = ["pypng (>=0.20220715.0,<0.20220716.0)"] [[package]] name = "idna" -version = "3.7" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "kivy" version = "2.3.0" @@ -426,13 +429,13 @@ files = [ [[package]] name = "pyright" -version = "1.1.376" +version = "1.1.381" description = "Command line wrapper for pyright" optional = false python-versions = ">=3.7" files = [ - {file = "pyright-1.1.376-py3-none-any.whl", hash = "sha256:0f2473b12c15c46b3207f0eec224c3cea2bdc07cd45dd4a037687cbbca0fbeff"}, - {file = "pyright-1.1.376.tar.gz", hash = "sha256:bffd63b197cd0810395bb3245c06b01f95a85ddf6bfa0e5644ed69c841e954dd"}, + {file = "pyright-1.1.381-py3-none-any.whl", hash = "sha256:5dc0aa80a265675d36abab59c674ae01dbe476714f91845b61b841d34aa99081"}, + {file = "pyright-1.1.381.tar.gz", hash = "sha256:314cf0c1351c189524fb10c7ac20688ecd470e8cc505c394d642c9c80bf7c3a5"}, ] [package.dependencies] @@ -536,29 +539,29 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.6.1" +version = "0.6.6" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.1-py3-none-linux_armv6l.whl", hash = "sha256:b4bb7de6a24169dc023f992718a9417380301b0c2da0fe85919f47264fb8add9"}, - {file = "ruff-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:45efaae53b360c81043e311cdec8a7696420b3d3e8935202c2846e7a97d4edae"}, - {file = "ruff-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc60c7d71b732c8fa73cf995efc0c836a2fd8b9810e115be8babb24ae87e0850"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c7477c3b9da822e2db0b4e0b59e61b8a23e87886e727b327e7dcaf06213c5cf"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a0af7ab3f86e3dc9f157a928e08e26c4b40707d0612b01cd577cc84b8905cc9"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392688dbb50fecf1bf7126731c90c11a9df1c3a4cdc3f481b53e851da5634fa5"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5278d3e095ccc8c30430bcc9bc550f778790acc211865520f3041910a28d0024"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe6d5f65d6f276ee7a0fc50a0cecaccb362d30ef98a110f99cac1c7872df2f18"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2e0dd11e2ae553ee5c92a81731d88a9883af8db7408db47fc81887c1f8b672e"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d812615525a34ecfc07fd93f906ef5b93656be01dfae9a819e31caa6cfe758a1"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faaa4060f4064c3b7aaaa27328080c932fa142786f8142aff095b42b6a2eb631"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99d7ae0df47c62729d58765c593ea54c2546d5de213f2af2a19442d50a10cec9"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9eb18dfd7b613eec000e3738b3f0e4398bf0153cb80bfa3e351b3c1c2f6d7b15"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c62bc04c6723a81e25e71715aa59489f15034d69bf641df88cb38bdc32fd1dbb"}, - {file = "ruff-0.6.1-py3-none-win32.whl", hash = "sha256:9fb4c4e8b83f19c9477a8745e56d2eeef07a7ff50b68a6998f7d9e2e3887bdc4"}, - {file = "ruff-0.6.1-py3-none-win_amd64.whl", hash = "sha256:c2ebfc8f51ef4aca05dad4552bbcf6fe8d1f75b2f6af546cc47cc1c1ca916b5b"}, - {file = "ruff-0.6.1-py3-none-win_arm64.whl", hash = "sha256:3bc81074971b0ffad1bd0c52284b22411f02a11a012082a76ac6da153536e014"}, - {file = "ruff-0.6.1.tar.gz", hash = "sha256:af3ffd8c6563acb8848d33cd19a69b9bfe943667f0419ca083f8ebe4224a3436"}, + {file = "ruff-0.6.6-py3-none-linux_armv6l.whl", hash = "sha256:f5bc5398457484fc0374425b43b030e4668ed4d2da8ee7fdda0e926c9f11ccfb"}, + {file = "ruff-0.6.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:515a698254c9c47bb84335281a170213b3ee5eb47feebe903e1be10087a167ce"}, + {file = "ruff-0.6.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6bb1b4995775f1837ab70f26698dd73852bbb82e8f70b175d2713c0354fe9182"}, + {file = "ruff-0.6.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69c546f412dfae8bb9cc4f27f0e45cdd554e42fecbb34f03312b93368e1cd0a6"}, + {file = "ruff-0.6.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:59627e97364329e4eae7d86fa7980c10e2b129e2293d25c478ebcb861b3e3fd6"}, + {file = "ruff-0.6.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94c3f78c3d32190aafbb6bc5410c96cfed0a88aadb49c3f852bbc2aa9783a7d8"}, + {file = "ruff-0.6.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:704da526c1e137f38c8a067a4a975fe6834b9f8ba7dbc5fd7503d58148851b8f"}, + {file = "ruff-0.6.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:efeede5815a24104579a0f6320660536c5ffc1c91ae94f8c65659af915fb9de9"}, + {file = "ruff-0.6.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e368aef0cc02ca3593eae2fb8186b81c9c2b3f39acaaa1108eb6b4d04617e61f"}, + {file = "ruff-0.6.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2653fc3b2a9315bd809725c88dd2446550099728d077a04191febb5ea79a4f79"}, + {file = "ruff-0.6.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:bb858cd9ce2d062503337c5b9784d7b583bcf9d1a43c4df6ccb5eab774fbafcb"}, + {file = "ruff-0.6.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:488f8e15c01ea9afb8c0ba35d55bd951f484d0c1b7c5fd746ce3c47ccdedce68"}, + {file = "ruff-0.6.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:aefb0bd15f1cfa4c9c227b6120573bb3d6c4ee3b29fb54a5ad58f03859bc43c6"}, + {file = "ruff-0.6.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a4c0698cc780bcb2c61496cbd56b6a3ac0ad858c966652f7dbf4ceb029252fbe"}, + {file = "ruff-0.6.6-py3-none-win32.whl", hash = "sha256:aadf81ddc8ab5b62da7aae78a91ec933cbae9f8f1663ec0325dae2c364e4ad84"}, + {file = "ruff-0.6.6-py3-none-win_amd64.whl", hash = "sha256:0adb801771bc1f1b8cf4e0a6fdc30776e7c1894810ff3b344e50da82ef50eeb1"}, + {file = "ruff-0.6.6-py3-none-win_arm64.whl", hash = "sha256:4b4d32c137bc781c298964dd4e52f07d6f7d57c03eae97a72d97856844aa510a"}, + {file = "ruff-0.6.6.tar.gz", hash = "sha256:0fc030b6fd14814d69ac0196396f6761921bd20831725c7361e1b8100b818034"}, ] [[package]] @@ -585,13 +588,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.2" +version = "2.2.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, ] [package.extras] @@ -603,4 +606,4 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "a70661c40f07ab5031a08606d14acb31e3ccb0938884338d36457d19f0ee2055" +content-hash = "bcb89c9048869c0f84ee165625a86f18c0852244c8e566539e5889e2569f50ad" diff --git a/pyproject.toml b/pyproject.toml index deef562..85dfd9a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "ubo-gui" -version = "0.13.1" +version = "0.13.2" description = "GUI sdk for Ubo Pod" authors = ["Sassan Haradji "] license = "Apache-2.0" @@ -9,7 +9,7 @@ packages = [{ include = "ubo_gui" }] include = ['ubo_gui/assets/fonts/*'] [tool.poetry.dependencies] -headless-kivy = "^0.9.7" +headless-kivy = "^0.9.8" python = "^3.11" python-immutable = "^1.0.2" qrcode = "^7.4.2" diff --git a/ubo_gui/__init__.py b/ubo_gui/__init__.py index e8e1d39..c22f945 100644 --- a/ubo_gui/__init__.py +++ b/ubo_gui/__init__.py @@ -5,22 +5,44 @@ from pathlib import Path -from kivy.factory import Factory - -__import__('ubo_gui.constants') -__import__('ubo_gui.menu.constants') - ROOT_PATH = Path(__file__).parent ASSETS_PATH = ROOT_PATH.joinpath('assets') FONTS_PATH = ASSETS_PATH.joinpath('fonts') -Factory.register('AnimatedSlider', module='ubo_gui.animated_slider') -Factory.register('GaugeWidget', module='ubo_gui.gauge') -Factory.register('ItemWidget', module='ubo_gui.menu.widgets.item_widget') -Factory.register('MenuWidget', module='ubo_gui.menu') -Factory.register('NotificationWidget', module='ubo_gui.notification') -Factory.register('ProgressRingWidget', module='ubo_gui.progress_ring') -Factory.register('PromptWidget', module='ubo_gui.prompt') -Factory.register('QRCodeWidget', module='ubo_gui.qrcode') -Factory.register('VolumeWidget', module='ubo_gui.volume') +def setup() -> None: + """Register various widgets using Kivy Factory and sets up the constants.""" + from kivy.factory import Factory + from kivy.lang.builder import Builder + + from ubo_gui import constants + from ubo_gui.menu import constants as menu_constants + + Builder.load_string( + f""" + #:set UBO_GUI_PRIMARY_COLOR '{constants.PRIMARY_COLOR}' + #:set UBO_GUI_SECONDARY_COLOR '{constants.SECONDARY_COLOR}' + #:set UBO_GUI_SECONDARY_COLOR_LIGHT '{constants.SECONDARY_COLOR_LIGHT}' + #:set UBO_GUI_TEXT_COLOR '{constants.TEXT_COLOR}' + + #:set UBO_GUI_INFO_COLOR '{constants.INFO_COLOR}' + #:set UBO_GUI_DANGER_COLOR '{constants.DANGER_COLOR}' + #:set UBO_GUI_WARNING_COLOR '{constants.WARNING_COLOR}' + #:set UBO_GUI_SUCCESS_COLOR '{constants.SUCCESS_COLOR}' + + #:set UBO_GUI_PAGE_SIZE {menu_constants.PAGE_SIZE} + #:set UBO_GUI_SHORT_WIDTH {menu_constants.SHORT_WIDTH} + #:set UBO_GUI_MENU_ITEM_HEIGHT {menu_constants.MENU_ITEM_HEIGHT} + #:set UBO_GUI_MENU_ITEM_GAP {menu_constants.MENU_ITEM_GAP} + """, + ) + + Factory.register('AnimatedSlider', module='ubo_gui.animated_slider') + Factory.register('GaugeWidget', module='ubo_gui.gauge') + Factory.register('ItemWidget', module='ubo_gui.menu.widgets.item_widget') + Factory.register('MenuWidget', module='ubo_gui.menu') + Factory.register('NotificationWidget', module='ubo_gui.notification') + Factory.register('ProgressRingWidget', module='ubo_gui.progress_ring') + Factory.register('PromptWidget', module='ubo_gui.prompt') + Factory.register('QRCodeWidget', module='ubo_gui.qrcode') + Factory.register('VolumeWidget', module='ubo_gui.volume') diff --git a/ubo_gui/constants.py b/ubo_gui/constants.py index ce68740..d47895d 100644 --- a/ubo_gui/constants.py +++ b/ubo_gui/constants.py @@ -1,7 +1,5 @@ """Module to store constants used in the application.""" -from kivy.lang.builder import Builder - PRIMARY_COLOR = '#68B7FF' SECONDARY_COLOR = '#363F4B' SECONDARY_COLOR_LIGHT = '#ABA7A7' @@ -11,17 +9,3 @@ DANGER_COLOR = '#FF3F51' WARNING_COLOR = '#FFC107' SUCCESS_COLOR = '#03F7AE' - -Builder.load_string( - f""" -#:set UBO_GUI_PRIMARY_COLOR '{PRIMARY_COLOR}' -#:set UBO_GUI_SECONDARY_COLOR '{SECONDARY_COLOR}' -#:set UBO_GUI_SECONDARY_COLOR_LIGHT '{SECONDARY_COLOR_LIGHT}' -#:set UBO_GUI_TEXT_COLOR '{TEXT_COLOR}' - -#:set UBO_GUI_INFO_COLOR '{INFO_COLOR}' -#:set UBO_GUI_DANGER_COLOR '{DANGER_COLOR}' -#:set UBO_GUI_WARNING_COLOR '{WARNING_COLOR}' -#:set UBO_GUI_SUCCESS_COLOR '{SUCCESS_COLOR}' -""", -) diff --git a/ubo_gui/menu/constants.py b/ubo_gui/menu/constants.py index 0f2a08a..5aed6e1 100644 --- a/ubo_gui/menu/constants.py +++ b/ubo_gui/menu/constants.py @@ -1,19 +1,6 @@ """Module for defining constants used in the `Menu` widget.""" -from kivy.lang.builder import Builder - -from ubo_gui.page import PAGE_MAX_ITEMS - -PAGE_SIZE = PAGE_MAX_ITEMS +PAGE_SIZE = 3 # PAGE_MAX_ITEMS SHORT_WIDTH = 46 MENU_ITEM_HEIGHT = 52 MENU_ITEM_GAP = 7 - -Builder.load_string( - f""" -#:set UBO_GUI_PAGE_SIZE {PAGE_SIZE} -#:set UBO_GUI_SHORT_WIDTH {SHORT_WIDTH} -#:set UBO_GUI_MENU_ITEM_HEIGHT {MENU_ITEM_HEIGHT} -#:set UBO_GUI_MENU_ITEM_GAP {MENU_ITEM_GAP} -""", -) diff --git a/ubo_gui/menu/menu_widget.py b/ubo_gui/menu/menu_widget.py index 8d51ebd..72abce7 100644 --- a/ubo_gui/menu/menu_widget.py +++ b/ubo_gui/menu/menu_widget.py @@ -218,14 +218,18 @@ def select_action_item(self: MenuWidget, item: ActionItem) -> None: result = item.action() if not result: return - if isinstance(result, type) and issubclass(result, PageWidget): - self.open_application(result()) + if isinstance(result, type): + if issubclass(result, PageWidget): + self.open_application(result()) + else: + msg = f'Unsupported returned value by `ActionItem`: {result}' + raise TypeError(msg) elif isinstance(result, PageWidget): self.open_application(result) elif isinstance(result, Menu) or callable(result): self.open_menu(result) else: - msg = f'Unsupported returned value by `ActionItem`: {type(result)}' + msg = f'Unsupported returned value by `ActionItem`: {result}' raise TypeError(msg) def select_application_item(self: MenuWidget, item: ApplicationItem) -> None: diff --git a/ubo_gui/prompt/__init__.py b/ubo_gui/prompt/__init__.py index 144284e..a402dff 100644 --- a/ubo_gui/prompt/__init__.py +++ b/ubo_gui/prompt/__init__.py @@ -7,7 +7,7 @@ import pathlib import warnings -from abc import ABC, abstractmethod +from abc import ABC, ABCMeta, abstractmethod from typing import TYPE_CHECKING, Sequence from kivy.lang.builder import Builder @@ -17,22 +17,23 @@ ColorProperty, StringProperty, ) +from kivy.uix.widget import WidgetMetaclass from ubo_gui.constants import DANGER_COLOR, SUCCESS_COLOR from ubo_gui.menu.types import ActionItem -from ubo_gui.page import PageWidget if TYPE_CHECKING: from ubo_gui.menu.types import Item, Menu + from ubo_gui.page import PageWidget PROMPT_OPTIONS = 2 -class PromptWidgetMetaClass(type(ABC), type(PageWidget)): +class PromptWidgetMetaClass(ABCMeta, WidgetMetaclass): """Metaclass merging `ABC` and `PageWidget` for `PromptWidget` class.""" -class PromptWidget(PageWidget, ABC, metaclass=PromptWidgetMetaClass): +class PromptWidget(ABC, metaclass=PromptWidgetMetaClass): """A widget that renders a prompt.""" icon: str = StringProperty()