toga-iOS 0.5.2__tar.gz → 0.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- toga_ios-0.5.4/CONTRIBUTING.md +7 -0
- toga_ios-0.5.4/PKG-INFO +67 -0
- toga_ios-0.5.4/README.md +31 -0
- toga_ios-0.5.4/pyproject.toml +134 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/app.py +3 -8
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/colors.py +1 -1
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/constraints.py +34 -23
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/container.py +64 -23
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/factory.py +10 -2
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/fonts.py +9 -1
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/images.py +4 -7
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/libs/core_graphics.py +18 -10
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/libs/webkit.py +14 -1
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/activityindicator.py +7 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/base.py +1 -1
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/canvas.py +233 -159
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/dateinput.py +10 -2
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/detailedlist.py +52 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/optioncontainer.py +4 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/scrollcontainer.py +14 -1
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/selection.py +52 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/timeinput.py +3 -2
- toga_ios-0.5.4/src/toga_iOS/widgets/webview.py +297 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/window.py +50 -5
- toga_ios-0.5.4/src/toga_iOS.egg-info/PKG-INFO +67 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS.egg-info/SOURCES.txt +2 -1
- toga_ios-0.5.4/src/toga_iOS.egg-info/entry_points.txt +43 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS.egg-info/requires.txt +1 -1
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/app.py +4 -2
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/fonts.py +1 -3
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/probe.py +15 -6
- toga_ios-0.5.4/tests_backend/widgets/__init__.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/activityindicator.py +1 -1
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/base.py +3 -2
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/canvas.py +6 -1
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/detailedlist.py +17 -2
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/multilinetextinput.py +1 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/numberinput.py +1 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/optioncontainer.py +5 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/properties.py +2 -2
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/scrollcontainer.py +15 -2
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/switch.py +6 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/textinput.py +1 -0
- toga_ios-0.5.4/tests_backend/window.py +95 -0
- toga_ios-0.5.2/CONTRIBUTING.md +0 -11
- toga_ios-0.5.2/PKG-INFO +0 -94
- toga_ios-0.5.2/README.rst +0 -58
- toga_ios-0.5.2/pyproject.toml +0 -83
- toga_ios-0.5.2/src/toga_iOS/widgets/webview.py +0 -143
- toga_ios-0.5.2/src/toga_iOS.egg-info/PKG-INFO +0 -94
- toga_ios-0.5.2/src/toga_iOS.egg-info/entry_points.txt +0 -2
- toga_ios-0.5.2/tests_backend/window.py +0 -75
- {toga_ios-0.5.2 → toga_ios-0.5.4}/LICENSE +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/setup.cfg +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/__init__.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/command.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/dialogs.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/hardware/__init__.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/hardware/camera.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/hardware/location.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/icons.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/libs/__init__.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/libs/av_foundation.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/libs/core_location.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/libs/core_text.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/libs/foundation.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/libs/mapkit.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/libs/uikit.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/paths.py +0 -0
- {toga_ios-0.5.2/src/toga_iOS/widgets → toga_ios-0.5.4/src/toga_iOS/resources}/__init__.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/resources/optioncontainer-tab.png +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/resources/toga.icns +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/screens.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/statusicons.py +0 -0
- {toga_ios-0.5.2/tests_backend → toga_ios-0.5.4/src/toga_iOS/widgets}/__init__.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/box.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/button.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/divider.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/imageview.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/label.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/mapview.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/multilinetextinput.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/numberinput.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/passwordinput.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/progressbar.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/slider.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/switch.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS/widgets/textinput.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS.egg-info/dependency_links.txt +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/src/toga_iOS.egg-info/top_level.txt +0 -0
- {toga_ios-0.5.2/tests_backend/hardware → toga_ios-0.5.4/tests_backend}/__init__.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/dialogs.py +0 -0
- {toga_ios-0.5.2/tests_backend/widgets → toga_ios-0.5.4/tests_backend/hardware}/__init__.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/hardware/camera.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/hardware/location.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/icons.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/images.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/screens.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/box.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/button.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/dateinput.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/divider.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/imageview.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/label.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/mapview.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/passwordinput.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/progressbar.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/selection.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/slider.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/timeinput.py +0 -0
- {toga_ios-0.5.2 → toga_ios-0.5.4}/tests_backend/widgets/webview.py +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
BeeWare <3's contributions!
|
|
4
|
+
|
|
5
|
+
Please be aware that BeeWare operates under a [Code of Conduct](https://beeware.org/community/behavior/code-of-conduct/).
|
|
6
|
+
|
|
7
|
+
If you'd like to contribute to Toga development, our [contribution guide](https://toga.beeware.org/en/latest/how-to/contribute/) details how to set up a development environment, and other requirements we have as part of our contribution process.
|
toga_ios-0.5.4/PKG-INFO
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: toga-iOS
|
|
3
|
+
Version: 0.5.4
|
|
4
|
+
Summary: An iOS backend for the Toga widget toolkit.
|
|
5
|
+
Author-email: Russell Keith-Magee <russell@keith-magee.com>
|
|
6
|
+
Maintainer-email: BeeWare Team <team@beeware.org>
|
|
7
|
+
License-Expression: BSD-3-Clause
|
|
8
|
+
Project-URL: Homepage, https://beeware.org/project/projects/libraries/toga/
|
|
9
|
+
Project-URL: Funding, https://beeware.org/contributing/membership/
|
|
10
|
+
Project-URL: Documentation, https://toga.beeware.org/
|
|
11
|
+
Project-URL: Tracker, https://github.com/beeware/toga/issues
|
|
12
|
+
Project-URL: Source, https://github.com/beeware/toga
|
|
13
|
+
Project-URL: Changelog, https://toga.beeware.org/en/stable/background/project/releases
|
|
14
|
+
Keywords: gui,widget,cross-platform,toga,mobile,iOS
|
|
15
|
+
Classifier: Development Status :: 4 - Beta
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
24
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
25
|
+
Classifier: Topic :: Software Development
|
|
26
|
+
Classifier: Topic :: Software Development :: User Interfaces
|
|
27
|
+
Classifier: Topic :: Software Development :: Widget Sets
|
|
28
|
+
Requires-Python: >=3.10
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: fonttools<5.0.0,>=4.42.1
|
|
32
|
+
Requires-Dist: rubicon-objc<0.6.0,>=0.5.1
|
|
33
|
+
Requires-Dist: toga-core==0.5.4
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
Dynamic: requires-dist
|
|
36
|
+
|
|
37
|
+
# toga-iOS
|
|
38
|
+
|
|
39
|
+
<!-- rumdl-disable MD013 -->
|
|
40
|
+
[](https://pypi.python.org/pypi/toga-ios)
|
|
41
|
+
[](https://github.com/beeware/toga-ios/blob/main/LICENSE)
|
|
42
|
+
[](https://pypi.python.org/pypi/toga-ios)
|
|
43
|
+
<!-- rumdl-enable MD013 -->
|
|
44
|
+
|
|
45
|
+
An iOS backend for the [Toga widget toolkit](https://beeware.org/toga).
|
|
46
|
+
|
|
47
|
+
This package isn't much use by itself; it needs to be combined with [the core Toga library](https://pypi.python.org/pypi/toga-core).
|
|
48
|
+
|
|
49
|
+
For platform requirements, see the [iOS platform documentation](https://toga.beeware.org/en/latest/reference/platforms/iOS#prerequisites).
|
|
50
|
+
|
|
51
|
+
For more details, see [Toga's documentation](https://toga.beeware.org), or the [Toga project on GitHub](https://github.com/beeware/toga).
|
|
52
|
+
|
|
53
|
+
## Community
|
|
54
|
+
|
|
55
|
+
Toga is part of the [BeeWare suite](https://beeware.org). You can talk to the community through:
|
|
56
|
+
|
|
57
|
+
- [@beeware@fosstodon.org on Mastodon](https://fosstodon.org/@beeware)
|
|
58
|
+
- [Discord](https://beeware.org/bee/chat/)
|
|
59
|
+
- The Toga [GitHub Discussions forum](https://github.com/beeware/toga/discussions)
|
|
60
|
+
|
|
61
|
+
We foster a welcoming and respectful community as described in our [BeeWare Community Code of Conduct](https://beeware.org/community/behavior/).
|
|
62
|
+
|
|
63
|
+
## Contributing
|
|
64
|
+
|
|
65
|
+
If you experience problems with Toga, [log them on GitHub](https://github.com/beeware/toga/issues).
|
|
66
|
+
|
|
67
|
+
If you'd like to contribute to Toga development, our [contribution guide](https://toga.beeware.org/en/latest/how-to/contribute/) details how to set up a development environment, and other requirements we have as part of our contribution process.
|
toga_ios-0.5.4/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# toga-iOS
|
|
2
|
+
|
|
3
|
+
<!-- rumdl-disable MD013 -->
|
|
4
|
+
[](https://pypi.python.org/pypi/toga-ios)
|
|
5
|
+
[](https://github.com/beeware/toga-ios/blob/main/LICENSE)
|
|
6
|
+
[](https://pypi.python.org/pypi/toga-ios)
|
|
7
|
+
<!-- rumdl-enable MD013 -->
|
|
8
|
+
|
|
9
|
+
An iOS backend for the [Toga widget toolkit](https://beeware.org/toga).
|
|
10
|
+
|
|
11
|
+
This package isn't much use by itself; it needs to be combined with [the core Toga library](https://pypi.python.org/pypi/toga-core).
|
|
12
|
+
|
|
13
|
+
For platform requirements, see the [iOS platform documentation](https://toga.beeware.org/en/latest/reference/platforms/iOS#prerequisites).
|
|
14
|
+
|
|
15
|
+
For more details, see [Toga's documentation](https://toga.beeware.org), or the [Toga project on GitHub](https://github.com/beeware/toga).
|
|
16
|
+
|
|
17
|
+
## Community
|
|
18
|
+
|
|
19
|
+
Toga is part of the [BeeWare suite](https://beeware.org). You can talk to the community through:
|
|
20
|
+
|
|
21
|
+
- [@beeware@fosstodon.org on Mastodon](https://fosstodon.org/@beeware)
|
|
22
|
+
- [Discord](https://beeware.org/bee/chat/)
|
|
23
|
+
- The Toga [GitHub Discussions forum](https://github.com/beeware/toga/discussions)
|
|
24
|
+
|
|
25
|
+
We foster a welcoming and respectful community as described in our [BeeWare Community Code of Conduct](https://beeware.org/community/behavior/).
|
|
26
|
+
|
|
27
|
+
## Contributing
|
|
28
|
+
|
|
29
|
+
If you experience problems with Toga, [log them on GitHub](https://github.com/beeware/toga/issues).
|
|
30
|
+
|
|
31
|
+
If you'd like to contribute to Toga development, our [contribution guide](https://toga.beeware.org/en/latest/how-to/contribute/) details how to set up a development environment, and other requirements we have as part of our contribution process.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = [
|
|
3
|
+
"setuptools==82.0.1",
|
|
4
|
+
"setuptools_scm==10.0.5",
|
|
5
|
+
"setuptools_dynamic_dependencies==1.0.0",
|
|
6
|
+
]
|
|
7
|
+
build-backend = "setuptools.build_meta"
|
|
8
|
+
|
|
9
|
+
[project]
|
|
10
|
+
dynamic = ["version", "dependencies"]
|
|
11
|
+
name = "toga-iOS"
|
|
12
|
+
description = "An iOS backend for the Toga widget toolkit."
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">= 3.10"
|
|
15
|
+
license = "BSD-3-Clause"
|
|
16
|
+
license-files = [
|
|
17
|
+
"LICENSE",
|
|
18
|
+
]
|
|
19
|
+
authors = [
|
|
20
|
+
{name="Russell Keith-Magee", email="russell@keith-magee.com"},
|
|
21
|
+
]
|
|
22
|
+
maintainers = [
|
|
23
|
+
{name="BeeWare Team", email="team@beeware.org"},
|
|
24
|
+
]
|
|
25
|
+
keywords = [
|
|
26
|
+
"gui",
|
|
27
|
+
"widget",
|
|
28
|
+
"cross-platform",
|
|
29
|
+
"toga",
|
|
30
|
+
"mobile",
|
|
31
|
+
"iOS",
|
|
32
|
+
]
|
|
33
|
+
classifiers = [
|
|
34
|
+
"Development Status :: 4 - Beta",
|
|
35
|
+
"Intended Audience :: Developers",
|
|
36
|
+
"Operating System :: OS Independent",
|
|
37
|
+
"Programming Language :: Python :: 3",
|
|
38
|
+
"Programming Language :: Python :: 3.10",
|
|
39
|
+
"Programming Language :: Python :: 3.11",
|
|
40
|
+
"Programming Language :: Python :: 3.12",
|
|
41
|
+
"Programming Language :: Python :: 3.13",
|
|
42
|
+
"Programming Language :: Python :: 3.14",
|
|
43
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
44
|
+
"Topic :: Software Development",
|
|
45
|
+
"Topic :: Software Development :: User Interfaces",
|
|
46
|
+
"Topic :: Software Development :: Widget Sets",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[project.urls]
|
|
50
|
+
Homepage = "https://beeware.org/project/projects/libraries/toga/"
|
|
51
|
+
Funding = "https://beeware.org/contributing/membership/"
|
|
52
|
+
Documentation = "https://toga.beeware.org/"
|
|
53
|
+
Tracker = "https://github.com/beeware/toga/issues"
|
|
54
|
+
Source = "https://github.com/beeware/toga"
|
|
55
|
+
Changelog = "https://toga.beeware.org/en/stable/background/project/releases"
|
|
56
|
+
|
|
57
|
+
[project.entry-points."toga.backends"]
|
|
58
|
+
iOS = "toga_iOS"
|
|
59
|
+
|
|
60
|
+
[project.entry-points."toga_core.backend.toga_iOS"]
|
|
61
|
+
App = "toga_iOS.app:App"
|
|
62
|
+
Command = "toga_iOS.command:Command"
|
|
63
|
+
Font = "toga_iOS.fonts:Font"
|
|
64
|
+
Icon = "toga_iOS.icons:Icon"
|
|
65
|
+
Image = "toga_iOS.images:Image"
|
|
66
|
+
Paths = "toga_iOS.paths:Paths"
|
|
67
|
+
native_color = "toga_iOS.colors:native_color"
|
|
68
|
+
dialogs = "toga_iOS.dialogs"
|
|
69
|
+
resources = "toga_iOS.resources"
|
|
70
|
+
|
|
71
|
+
# Hardware
|
|
72
|
+
Camera = "toga_iOS.hardware.camera:Camera"
|
|
73
|
+
Location = "toga_iOS.hardware.location:Location"
|
|
74
|
+
|
|
75
|
+
# Status Icons
|
|
76
|
+
MenuStatusIcon = "toga_iOS.statusicons:MenuStatusIcon"
|
|
77
|
+
SimpleStatusIcon = "toga_iOS.statusicons:SimpleStatusIcon"
|
|
78
|
+
StatusIconSet = "toga_iOS.statusicons:StatusIconSet"
|
|
79
|
+
|
|
80
|
+
# Widgets
|
|
81
|
+
ActivityIndicator = "toga_iOS.widgets.activityindicator:ActivityIndicator"
|
|
82
|
+
Box = "toga_iOS.widgets.box:Box"
|
|
83
|
+
Button = "toga_iOS.widgets.button:Button"
|
|
84
|
+
Canvas = "toga_iOS.widgets.canvas:Canvas"
|
|
85
|
+
DateInput = "toga_iOS.widgets.dateinput:DateInput"
|
|
86
|
+
DetailedList = "toga_iOS.widgets.detailedlist:DetailedList"
|
|
87
|
+
Divider = "toga_iOS.widgets.divider:Divider"
|
|
88
|
+
ImageView = "toga_iOS.widgets.imageview:ImageView"
|
|
89
|
+
Label = "toga_iOS.widgets.label:Label"
|
|
90
|
+
MapView = "toga_iOS.widgets.mapview:MapView"
|
|
91
|
+
MultilineTextInput = "toga_iOS.widgets.multilinetextinput:MultilineTextInput"
|
|
92
|
+
NumberInput = "toga_iOS.widgets.numberinput:NumberInput"
|
|
93
|
+
OptionContainer = "toga_iOS.widgets.optioncontainer:OptionContainer"
|
|
94
|
+
PasswordInput = "toga_iOS.widgets.passwordinput:PasswordInput"
|
|
95
|
+
ProgressBar = "toga_iOS.widgets.progressbar:ProgressBar"
|
|
96
|
+
ScrollContainer = "toga_iOS.widgets.scrollcontainer:ScrollContainer"
|
|
97
|
+
# SplitContainer = "toga_iOS.widgets.splitcontainer:SplitContainer"
|
|
98
|
+
Selection = "toga_iOS.widgets.selection:Selection"
|
|
99
|
+
Slider = "toga_iOS.widgets.slider:Slider"
|
|
100
|
+
Switch = "toga_iOS.widgets.switch:Switch"
|
|
101
|
+
Table = "toga_iOS.widgets.table:Table"
|
|
102
|
+
# Tree = "toga_iOS.widgets.tree:Tree"
|
|
103
|
+
TextInput = "toga_iOS.widgets.textinput:TextInput"
|
|
104
|
+
TimeInput = "toga_iOS.widgets.timeinput:TimeInput"
|
|
105
|
+
WebView = "toga_iOS.widgets.webview:WebView"
|
|
106
|
+
|
|
107
|
+
# Windows
|
|
108
|
+
MainWindow = "toga_iOS.window:MainWindow"
|
|
109
|
+
Window = "toga_iOS.window:Window"
|
|
110
|
+
|
|
111
|
+
[tool.setuptools_scm]
|
|
112
|
+
root = ".."
|
|
113
|
+
|
|
114
|
+
[tool.setuptools_dynamic_dependencies]
|
|
115
|
+
dependencies = [
|
|
116
|
+
"fonttools >= 4.42.1, < 5.0.0",
|
|
117
|
+
"rubicon-objc >= 0.5.1, < 0.6.0",
|
|
118
|
+
"toga-core == {version}",
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
[tool.coverage.run]
|
|
122
|
+
parallel = true
|
|
123
|
+
branch = true
|
|
124
|
+
relative_files = true
|
|
125
|
+
|
|
126
|
+
# See notes in the root pyproject.toml file.
|
|
127
|
+
source = ["src"]
|
|
128
|
+
source_pkgs = ["toga_iOS"]
|
|
129
|
+
|
|
130
|
+
[tool.coverage.paths]
|
|
131
|
+
source = [
|
|
132
|
+
"src/toga_iOS",
|
|
133
|
+
"**/toga_iOS",
|
|
134
|
+
]
|
|
@@ -42,14 +42,6 @@ class PythonAppDelegate(UIResponder):
|
|
|
42
42
|
def applicationWillTerminate_(self, application) -> None:
|
|
43
43
|
print("App about to Terminate.")
|
|
44
44
|
|
|
45
|
-
@objc_method
|
|
46
|
-
def application_didChangeStatusBarOrientation_(
|
|
47
|
-
self, application, oldStatusBarOrientation: int
|
|
48
|
-
) -> None:
|
|
49
|
-
"""This callback is invoked when rotating the device from landscape to portrait
|
|
50
|
-
and vice versa."""
|
|
51
|
-
App.app.interface.main_window.content.refresh()
|
|
52
|
-
|
|
53
45
|
|
|
54
46
|
class App:
|
|
55
47
|
# iOS apps exit when the last window is closed
|
|
@@ -61,12 +53,15 @@ class App:
|
|
|
61
53
|
def __init__(self, interface):
|
|
62
54
|
self.interface = interface
|
|
63
55
|
self.interface._impl = self
|
|
56
|
+
|
|
64
57
|
# Native instance doesn't exist until the lifecycle completes.
|
|
65
58
|
self.native = None
|
|
66
59
|
|
|
67
60
|
# Add a reference for the PythonAppDelegate class to use.
|
|
68
61
|
App.app = self
|
|
69
62
|
|
|
63
|
+
self._exiting_presentation = False
|
|
64
|
+
|
|
70
65
|
self.loop = RubiconEventLoop()
|
|
71
66
|
|
|
72
67
|
def create(self):
|
|
@@ -12,7 +12,7 @@ def native_color(c):
|
|
|
12
12
|
color = CACHE[c]
|
|
13
13
|
except KeyError:
|
|
14
14
|
color = UIColor.colorWithRed(
|
|
15
|
-
c.
|
|
15
|
+
c.rgb.r / 255, green=c.rgb.g / 255, blue=c.rgb.b / 255, alpha=c.rgb.a
|
|
16
16
|
)
|
|
17
17
|
CACHE[c] = color
|
|
18
18
|
|
|
@@ -26,6 +26,8 @@ class Constraints:
|
|
|
26
26
|
self.left_constraint = None
|
|
27
27
|
self.top_constraint = None
|
|
28
28
|
|
|
29
|
+
self.constraints_created = False
|
|
30
|
+
|
|
29
31
|
# Deletion isn't an event we can programmatically invoke; deletion
|
|
30
32
|
# of constraints can take several iterations before it occurs.
|
|
31
33
|
def __del__(self): # pragma: nocover
|
|
@@ -38,28 +40,46 @@ class Constraints:
|
|
|
38
40
|
# the native object of the window's container to be deleted on the ObjC
|
|
39
41
|
# side before the constraints for the window have been removed. Protect
|
|
40
42
|
# against this possibility.
|
|
41
|
-
|
|
43
|
+
# Also protect against the possibility that the constraints have
|
|
44
|
+
# already been cleared.
|
|
45
|
+
if self.container.native and self.constraints_created:
|
|
42
46
|
self.container.native.removeConstraint(self.width_constraint)
|
|
43
47
|
self.container.native.removeConstraint(self.height_constraint)
|
|
44
48
|
self.container.native.removeConstraint(self.left_constraint)
|
|
45
49
|
self.container.native.removeConstraint(self.top_constraint)
|
|
46
50
|
|
|
51
|
+
self.constraints_created = False
|
|
52
|
+
|
|
47
53
|
@property
|
|
48
54
|
def container(self):
|
|
49
55
|
return self._container
|
|
50
56
|
|
|
51
57
|
@container.setter
|
|
52
58
|
def container(self, value):
|
|
53
|
-
# This will
|
|
54
|
-
#
|
|
55
|
-
|
|
59
|
+
# This will invalidate our created constraints, as the container would've
|
|
60
|
+
# changed. Constraints are not created until the actual first layout
|
|
61
|
+
# update, as we do not want the native layer performing any layout passes
|
|
62
|
+
# with wrong initial dummy constrained values.
|
|
56
63
|
self._remove_constraints()
|
|
57
64
|
self._container = value
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
|
|
66
|
+
def update(self, x, y, width, height):
|
|
67
|
+
# print(
|
|
68
|
+
# f"UPDATE CONSTRAINTS {self.widget} in {self.container} "
|
|
69
|
+
# f"{width}x{height}@{x},{y}"
|
|
70
|
+
# )
|
|
71
|
+
y += self.container.top_inset
|
|
72
|
+
x += self.container.left_inset
|
|
73
|
+
|
|
74
|
+
if self.constraints_created:
|
|
75
|
+
# We already have constraints set up; reuse them.
|
|
76
|
+
self.left_constraint.constant = x
|
|
77
|
+
self.top_constraint.constant = y
|
|
78
|
+
|
|
79
|
+
self.width_constraint.constant = width
|
|
80
|
+
self.height_constraint.constant = height
|
|
81
|
+
|
|
82
|
+
else:
|
|
63
83
|
self.left_constraint = NSLayoutConstraint.constraintWithItem(
|
|
64
84
|
self.widget.native,
|
|
65
85
|
attribute__1=NSLayoutAttributeLeft,
|
|
@@ -67,7 +87,7 @@ class Constraints:
|
|
|
67
87
|
toItem=self.container.native,
|
|
68
88
|
attribute__2=NSLayoutAttributeLeft,
|
|
69
89
|
multiplier=1.0,
|
|
70
|
-
constant=
|
|
90
|
+
constant=x,
|
|
71
91
|
)
|
|
72
92
|
self.container.native.addConstraint(self.left_constraint)
|
|
73
93
|
|
|
@@ -78,7 +98,7 @@ class Constraints:
|
|
|
78
98
|
toItem=self.container.native,
|
|
79
99
|
attribute__2=NSLayoutAttributeTop,
|
|
80
100
|
multiplier=1.0,
|
|
81
|
-
constant=
|
|
101
|
+
constant=y,
|
|
82
102
|
)
|
|
83
103
|
self.container.native.addConstraint(self.top_constraint)
|
|
84
104
|
|
|
@@ -89,7 +109,7 @@ class Constraints:
|
|
|
89
109
|
toItem=self.widget.native,
|
|
90
110
|
attribute__2=NSLayoutAttributeLeft,
|
|
91
111
|
multiplier=1.0,
|
|
92
|
-
constant=
|
|
112
|
+
constant=width,
|
|
93
113
|
)
|
|
94
114
|
self.container.native.addConstraint(self.width_constraint)
|
|
95
115
|
|
|
@@ -100,17 +120,8 @@ class Constraints:
|
|
|
100
120
|
toItem=self.widget.native,
|
|
101
121
|
attribute__2=NSLayoutAttributeTop,
|
|
102
122
|
multiplier=1.0,
|
|
103
|
-
constant=
|
|
123
|
+
constant=height,
|
|
104
124
|
)
|
|
105
125
|
self.container.native.addConstraint(self.height_constraint)
|
|
106
126
|
|
|
107
|
-
|
|
108
|
-
# print(
|
|
109
|
-
# f"UPDATE CONSTRAINTS {self.widget} in {self.container} "
|
|
110
|
-
# f"{width}x{height}@{x},{y}"
|
|
111
|
-
# )
|
|
112
|
-
self.left_constraint.constant = x
|
|
113
|
-
self.top_constraint.constant = y
|
|
114
|
-
|
|
115
|
-
self.width_constraint.constant = width
|
|
116
|
-
self.height_constraint.constant = height
|
|
127
|
+
self.constraints_created = True
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
from rubicon.objc import objc_method, objc_property, send_super
|
|
2
|
+
|
|
1
3
|
from .libs import (
|
|
2
|
-
UIApplication,
|
|
3
4
|
UINavigationController,
|
|
4
5
|
UIView,
|
|
5
6
|
UIViewAutoresizing,
|
|
@@ -15,16 +16,36 @@ from .libs import (
|
|
|
15
16
|
#######################################################################################
|
|
16
17
|
|
|
17
18
|
|
|
19
|
+
class TogaContainerView(UIView):
|
|
20
|
+
container = objc_property(object, weak=True)
|
|
21
|
+
|
|
22
|
+
@objc_method
|
|
23
|
+
def layoutSubviews(self):
|
|
24
|
+
send_super(__class__, self, "layoutSubviews")
|
|
25
|
+
if self.container.on_native_layout:
|
|
26
|
+
self.container.on_native_layout(self.container)
|
|
27
|
+
|
|
28
|
+
@objc_method
|
|
29
|
+
def safeAreaInsetsDidChange(self):
|
|
30
|
+
send_super(__class__, self, "safeAreaInsetsDidChange")
|
|
31
|
+
if self.container.on_native_layout:
|
|
32
|
+
self.container.on_native_layout(self.container)
|
|
33
|
+
|
|
34
|
+
|
|
18
35
|
class BaseContainer:
|
|
19
|
-
def __init__(self, content=None, on_refresh=None):
|
|
36
|
+
def __init__(self, content=None, on_refresh=None, on_native_layout=None):
|
|
20
37
|
"""A base class for iOS containers.
|
|
21
38
|
|
|
22
39
|
:param content: The widget impl that is the container's initial content.
|
|
23
40
|
:param on_refresh: The callback to be notified when this container's layout is
|
|
24
41
|
refreshed.
|
|
42
|
+
:param on_native_layout: The callback to be notified when the container's native
|
|
43
|
+
widget has finished laying out, i.e. when native values such as size
|
|
44
|
+
*may* have changed.
|
|
25
45
|
"""
|
|
26
46
|
self._content = content
|
|
27
47
|
self.on_refresh = on_refresh
|
|
48
|
+
self.on_native_layout = on_native_layout
|
|
28
49
|
|
|
29
50
|
@property
|
|
30
51
|
def content(self):
|
|
@@ -52,7 +73,13 @@ class BaseContainer:
|
|
|
52
73
|
|
|
53
74
|
|
|
54
75
|
class Container(BaseContainer):
|
|
55
|
-
def __init__(
|
|
76
|
+
def __init__(
|
|
77
|
+
self,
|
|
78
|
+
content=None,
|
|
79
|
+
layout_native=None,
|
|
80
|
+
on_refresh=None,
|
|
81
|
+
on_native_layout=None,
|
|
82
|
+
):
|
|
56
83
|
"""
|
|
57
84
|
:param content: The widget impl that is the container's initial content.
|
|
58
85
|
:param layout_native: The native widget that should be used to provide size
|
|
@@ -62,9 +89,17 @@ class Container(BaseContainer):
|
|
|
62
89
|
the size can be different.
|
|
63
90
|
:param on_refresh: The callback to be notified when this container's layout is
|
|
64
91
|
refreshed.
|
|
92
|
+
:param on_native_layout: The callback to be notified when the container's native
|
|
93
|
+
widget has finished laying out, i.e. when native values such as size
|
|
94
|
+
*may* have changed.
|
|
65
95
|
"""
|
|
66
|
-
super().__init__(
|
|
67
|
-
|
|
96
|
+
super().__init__(
|
|
97
|
+
content=content,
|
|
98
|
+
on_refresh=on_refresh,
|
|
99
|
+
on_native_layout=on_native_layout,
|
|
100
|
+
)
|
|
101
|
+
self.native = TogaContainerView.alloc().init()
|
|
102
|
+
self.native.container = self
|
|
68
103
|
self.native.translatesAutoresizingMaskIntoConstraints = True
|
|
69
104
|
self.native.autoresizingMask = (
|
|
70
105
|
UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
|
|
@@ -72,6 +107,11 @@ class Container(BaseContainer):
|
|
|
72
107
|
|
|
73
108
|
self.layout_native = self.native if layout_native is None else layout_native
|
|
74
109
|
|
|
110
|
+
self.top_inset = 0
|
|
111
|
+
self.left_inset = 0
|
|
112
|
+
self.bottom_inset = 0
|
|
113
|
+
self.right_inset = 0
|
|
114
|
+
|
|
75
115
|
def __del__(self):
|
|
76
116
|
# Mark the contained native object as explicitly None so that the
|
|
77
117
|
# constraints know the object has been deleted.
|
|
@@ -79,15 +119,13 @@ class Container(BaseContainer):
|
|
|
79
119
|
|
|
80
120
|
@property
|
|
81
121
|
def width(self):
|
|
82
|
-
return self.layout_native.bounds.size.width
|
|
122
|
+
return self.layout_native.bounds.size.width - self.left_inset - self.right_inset
|
|
83
123
|
|
|
84
124
|
@property
|
|
85
125
|
def height(self):
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def top_offset(self):
|
|
90
|
-
return 0
|
|
126
|
+
return (
|
|
127
|
+
self.layout_native.bounds.size.height - self.top_inset - self.bottom_inset
|
|
128
|
+
)
|
|
91
129
|
|
|
92
130
|
|
|
93
131
|
class ControlledContainer(Container):
|
|
@@ -96,6 +134,7 @@ class ControlledContainer(Container):
|
|
|
96
134
|
content=None,
|
|
97
135
|
layout_native=None,
|
|
98
136
|
on_refresh=None,
|
|
137
|
+
on_native_layout=None,
|
|
99
138
|
):
|
|
100
139
|
"""
|
|
101
140
|
:param content: The widget impl that is the container's initial content.
|
|
@@ -106,11 +145,15 @@ class ControlledContainer(Container):
|
|
|
106
145
|
rendered, the source of the size can be different.
|
|
107
146
|
:param on_refresh: The callback to be notified when this container's layout is
|
|
108
147
|
refreshed.
|
|
148
|
+
:param on_native_layout: The callback to be notified when the container's native
|
|
149
|
+
widget has finished laying out, i.e. when native values such as size
|
|
150
|
+
*may* have changed.
|
|
109
151
|
"""
|
|
110
152
|
super().__init__(
|
|
111
153
|
content=content,
|
|
112
154
|
layout_native=layout_native,
|
|
113
155
|
on_refresh=on_refresh,
|
|
156
|
+
on_native_layout=on_native_layout,
|
|
114
157
|
)
|
|
115
158
|
|
|
116
159
|
# Construct a ViewController that provides a navigation bar, and
|
|
@@ -128,6 +171,7 @@ class RootContainer(Container):
|
|
|
128
171
|
content=None,
|
|
129
172
|
layout_native=None,
|
|
130
173
|
on_refresh=None,
|
|
174
|
+
on_native_layout=None,
|
|
131
175
|
):
|
|
132
176
|
"""A bare content container.
|
|
133
177
|
|
|
@@ -141,11 +185,15 @@ class RootContainer(Container):
|
|
|
141
185
|
rendered, the source of the size can be different.
|
|
142
186
|
:param on_refresh: The callback to be notified when this container's layout is
|
|
143
187
|
refreshed.
|
|
188
|
+
:param on_native_layout: The callback to be notified when the container's native
|
|
189
|
+
widget has finished laying out, i.e. when native values such as size
|
|
190
|
+
*may* have changed.
|
|
144
191
|
"""
|
|
145
192
|
super().__init__(
|
|
146
193
|
content=content,
|
|
147
194
|
layout_native=layout_native,
|
|
148
195
|
on_refresh=on_refresh,
|
|
196
|
+
on_native_layout=on_native_layout,
|
|
149
197
|
)
|
|
150
198
|
|
|
151
199
|
# Construct a UIViewController to hold the root content
|
|
@@ -154,11 +202,6 @@ class RootContainer(Container):
|
|
|
154
202
|
# Set the controller's view to be the root content widget
|
|
155
203
|
self.controller.view = self.native
|
|
156
204
|
|
|
157
|
-
# The testbed app won't instantiate a simple app, so we can't test these properties
|
|
158
|
-
@property
|
|
159
|
-
def top_offset(self): # pragma: no cover
|
|
160
|
-
return UIApplication.sharedApplication.statusBarFrame.size.height
|
|
161
|
-
|
|
162
205
|
@property
|
|
163
206
|
def title(self): # pragma: no cover
|
|
164
207
|
return self._title
|
|
@@ -174,6 +217,7 @@ class NavigationContainer(Container):
|
|
|
174
217
|
content=None,
|
|
175
218
|
layout_native=None,
|
|
176
219
|
on_refresh=None,
|
|
220
|
+
on_native_layout=None,
|
|
177
221
|
):
|
|
178
222
|
"""A top level container that provides a navigation/title bar.
|
|
179
223
|
|
|
@@ -185,11 +229,15 @@ class NavigationContainer(Container):
|
|
|
185
229
|
rendered, the source of the size can be different.
|
|
186
230
|
:param on_refresh: The callback to be notified when this container's layout is
|
|
187
231
|
refreshed.
|
|
232
|
+
:param on_native_layout: The callback to be notified when the container's native
|
|
233
|
+
widget has finished laying out, i.e. when native values such as size
|
|
234
|
+
*may* have changed.
|
|
188
235
|
"""
|
|
189
236
|
super().__init__(
|
|
190
237
|
content=content,
|
|
191
238
|
layout_native=layout_native,
|
|
192
239
|
on_refresh=on_refresh,
|
|
240
|
+
on_native_layout=on_native_layout,
|
|
193
241
|
)
|
|
194
242
|
|
|
195
243
|
# Construct a NavigationController that provides a navigation bar, and
|
|
@@ -203,13 +251,6 @@ class NavigationContainer(Container):
|
|
|
203
251
|
# Set the controller's view to be the root content widget
|
|
204
252
|
self.content_controller.view = self.native
|
|
205
253
|
|
|
206
|
-
@property
|
|
207
|
-
def top_offset(self):
|
|
208
|
-
return (
|
|
209
|
-
UIApplication.sharedApplication.statusBarFrame.size.height
|
|
210
|
-
+ self.controller.navigationBar.frame.size.height
|
|
211
|
-
)
|
|
212
|
-
|
|
213
254
|
@property
|
|
214
255
|
def title(self):
|
|
215
256
|
return self.controller.topViewController.title
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
1
3
|
from toga import NotImplementedWarning
|
|
2
4
|
|
|
3
5
|
from . import dialogs
|
|
@@ -43,8 +45,14 @@ from .widgets.timeinput import TimeInput
|
|
|
43
45
|
from .widgets.webview import WebView
|
|
44
46
|
from .window import MainWindow, Window
|
|
45
47
|
|
|
48
|
+
warnings.warn(
|
|
49
|
+
"Factory modules are deprecated. Use 'toga.platform.get_factory' instead.",
|
|
50
|
+
DeprecationWarning,
|
|
51
|
+
stacklevel=1,
|
|
52
|
+
)
|
|
53
|
+
|
|
46
54
|
|
|
47
|
-
def not_implemented(feature):
|
|
55
|
+
def not_implemented(feature): # pragma: no cover
|
|
48
56
|
NotImplementedWarning.warn("iOS", feature)
|
|
49
57
|
|
|
50
58
|
|
|
@@ -98,5 +106,5 @@ __all__ = [
|
|
|
98
106
|
]
|
|
99
107
|
|
|
100
108
|
|
|
101
|
-
def __getattr__(name):
|
|
109
|
+
def __getattr__(name):
|
|
102
110
|
raise NotImplementedError(f"Toga's iOS backend doesn't implement {name}")
|
|
@@ -97,7 +97,15 @@ class Font:
|
|
|
97
97
|
|
|
98
98
|
def load_arbitrary_system_font(self):
|
|
99
99
|
"""Use a font available on the system."""
|
|
100
|
-
|
|
100
|
+
self._assign_native(self.interface.family)
|
|
101
|
+
# Fonts *can* fail safe - creating a font object where the family doesn't match
|
|
102
|
+
# the requested name. If a font wasn't loaded, or the loaded font name doesn't
|
|
103
|
+
# match the font request, assume the font wasn't found.
|
|
104
|
+
if self.native is None or self.native.fontName != self.interface.family:
|
|
105
|
+
# If it wasn't a match, purge the font cache of the loaded font
|
|
106
|
+
self.native = None
|
|
107
|
+
del _IMPL_CACHE[self.interface]
|
|
108
|
+
raise UnknownFontError(f"Unknown system font: {self.interface.family}")
|
|
101
109
|
|
|
102
110
|
def _assign_native(self, font_name):
|
|
103
111
|
if self.interface.size == SYSTEM_DEFAULT_FONT_SIZE:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from ctypes import POINTER, c_char, cast
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
|
|
4
|
+
from toga.images import ImageLoadError
|
|
4
5
|
from toga_iOS.libs import (
|
|
5
6
|
NSData,
|
|
6
7
|
UIImage,
|
|
@@ -20,19 +21,15 @@ def nsdata_to_bytes(data: NSData) -> bytes:
|
|
|
20
21
|
class Image:
|
|
21
22
|
RAW_TYPE = UIImage
|
|
22
23
|
|
|
23
|
-
def __init__(self, interface,
|
|
24
|
+
def __init__(self, interface, data=None, raw=None):
|
|
24
25
|
self.interface = interface
|
|
25
26
|
|
|
26
|
-
if
|
|
27
|
-
self.native = UIImage.imageWithContentsOfFile(str(path))
|
|
28
|
-
if self.native is None:
|
|
29
|
-
raise ValueError(f"Unable to load image from {path}")
|
|
30
|
-
elif data:
|
|
27
|
+
if data:
|
|
31
28
|
self.native = UIImage.imageWithData(
|
|
32
29
|
NSData.dataWithBytes(data, length=len(data))
|
|
33
30
|
)
|
|
34
31
|
if self.native is None:
|
|
35
|
-
raise
|
|
32
|
+
raise ImageLoadError
|
|
36
33
|
else:
|
|
37
34
|
self.native = raw
|
|
38
35
|
|