pythonnative 0.4.0__py3-none-any.whl → 0.6.0__py3-none-any.whl
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.
- pythonnative/__init__.py +94 -66
- pythonnative/cli/pn.py +153 -24
- pythonnative/components.py +563 -0
- pythonnative/element.py +53 -0
- pythonnative/hooks.py +287 -0
- pythonnative/hot_reload.py +143 -0
- pythonnative/native_modules/__init__.py +19 -0
- pythonnative/native_modules/camera.py +105 -0
- pythonnative/native_modules/file_system.py +131 -0
- pythonnative/native_modules/location.py +61 -0
- pythonnative/native_modules/notifications.py +151 -0
- pythonnative/native_views.py +1334 -0
- pythonnative/page.py +320 -247
- pythonnative/reconciler.py +262 -0
- pythonnative/style.py +115 -0
- pythonnative/templates/android_template/app/build.gradle +2 -7
- pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PageFragment.kt +2 -1
- pythonnative/templates/android_template/build.gradle +1 -1
- pythonnative/utils.py +21 -29
- {pythonnative-0.4.0.dist-info → pythonnative-0.6.0.dist-info}/METADATA +20 -19
- {pythonnative-0.4.0.dist-info → pythonnative-0.6.0.dist-info}/RECORD +25 -40
- pythonnative/activity_indicator_view.py +0 -71
- pythonnative/button.py +0 -113
- pythonnative/collection_view.py +0 -0
- pythonnative/date_picker.py +0 -76
- pythonnative/image_view.py +0 -78
- pythonnative/label.py +0 -133
- pythonnative/list_view.py +0 -76
- pythonnative/material_activity_indicator_view.py +0 -71
- pythonnative/material_bottom_navigation_view.py +0 -0
- pythonnative/material_button.py +0 -69
- pythonnative/material_date_picker.py +0 -87
- pythonnative/material_progress_view.py +0 -70
- pythonnative/material_search_bar.py +0 -69
- pythonnative/material_switch.py +0 -69
- pythonnative/material_time_picker.py +0 -76
- pythonnative/material_toolbar.py +0 -0
- pythonnative/picker_view.py +0 -69
- pythonnative/progress_view.py +0 -70
- pythonnative/scroll_view.py +0 -101
- pythonnative/search_bar.py +0 -69
- pythonnative/stack_view.py +0 -199
- pythonnative/switch.py +0 -68
- pythonnative/text_field.py +0 -132
- pythonnative/text_view.py +0 -135
- pythonnative/time_picker.py +0 -77
- pythonnative/view.py +0 -173
- pythonnative/web_view.py +0 -60
- {pythonnative-0.4.0.dist-info → pythonnative-0.6.0.dist-info}/WHEEL +0 -0
- {pythonnative-0.4.0.dist-info → pythonnative-0.6.0.dist-info}/entry_points.txt +0 -0
- {pythonnative-0.4.0.dist-info → pythonnative-0.6.0.dist-info}/licenses/LICENSE +0 -0
- {pythonnative-0.4.0.dist-info → pythonnative-0.6.0.dist-info}/top_level.txt +0 -0
|
@@ -1,47 +1,32 @@
|
|
|
1
|
-
pythonnative/__init__.py,sha256=
|
|
2
|
-
pythonnative/
|
|
3
|
-
pythonnative/
|
|
4
|
-
pythonnative/
|
|
5
|
-
pythonnative/
|
|
6
|
-
pythonnative/
|
|
7
|
-
pythonnative/
|
|
8
|
-
pythonnative/
|
|
9
|
-
pythonnative/
|
|
10
|
-
pythonnative/
|
|
11
|
-
pythonnative/material_button.py,sha256=goRoILCKBXSOPTAfaAtfDOasedBJpCDxU2sIMIJvBKI,2148
|
|
12
|
-
pythonnative/material_date_picker.py,sha256=zOcnSyoNWjLGpkNlQjRZwIyc9RY95Ya_A2yd_S7EwLA,2988
|
|
13
|
-
pythonnative/material_progress_view.py,sha256=h1lmaab-nqwIyGjmU8L-4l7Zm8jG5x3Dx-SWTZ4DQpk,2288
|
|
14
|
-
pythonnative/material_search_bar.py,sha256=kHYOYTTBjPTYOtQyxjH8ZpVPOJRWoCu2wyWIzkk-DVY,2104
|
|
15
|
-
pythonnative/material_switch.py,sha256=3pct4sIfFvC6LJ1XXh4SCIik087hzxUyvHVrnE8eQDI,2065
|
|
16
|
-
pythonnative/material_time_picker.py,sha256=2UwYugsUqX6sGLo-Uco_yLtLtvrPgCh64Hqg4j8EA1Q,2452
|
|
17
|
-
pythonnative/material_toolbar.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
pythonnative/page.py,sha256=AaAAy4cY8goxq3dtSZvsd84eOjmYQ4yoLe3xmHcVsgM,14992
|
|
19
|
-
pythonnative/picker_view.py,sha256=Is_GNRn22TmNWu77soo7mrQ-jxXuEbaJ9nciVdZvIbE,2069
|
|
20
|
-
pythonnative/progress_view.py,sha256=_NxSqagfYcdiOQ4gtVhrmgAhFNUFGEcMZ7pxyvHSAFs,2333
|
|
21
|
-
pythonnative/scroll_view.py,sha256=DQf4k3H6PQaSTeMWYE9z7-s3K4FKfuFXstwVNSBENWQ,3697
|
|
22
|
-
pythonnative/search_bar.py,sha256=mkCE7qxMwqCzJO8-Kk9sCwoq0yXDNqGnG0E6H81qq08,1990
|
|
23
|
-
pythonnative/stack_view.py,sha256=mTypUjpOoI12KSDmTgku0JepGYj_aBPyGvDIWPG3PtQ,7923
|
|
24
|
-
pythonnative/switch.py,sha256=OGyd_QEprf5_M9ZMV6DlP2lePC7AstiFTHINjwTAjtw,1960
|
|
25
|
-
pythonnative/text_field.py,sha256=bQFbC-Bk78BxS9hwy9aj3hePm5IsOOm_wZ6qEp4ZpsE,4154
|
|
26
|
-
pythonnative/text_view.py,sha256=kcOskJghS0cUJeVBtXTht6Tj4P0RzMWT33ANenps3RQ,4323
|
|
27
|
-
pythonnative/time_picker.py,sha256=OPQ_44QYA9dtB1bQu5vfQ8rMM44cmxE0m5eOz050kzI,2367
|
|
28
|
-
pythonnative/utils.py,sha256=0Ub6DDg4uX4ToqoyioQzUJ-_ERzXlJ2r70pBSmeiaYY,3038
|
|
29
|
-
pythonnative/view.py,sha256=nsoXnX1HsVKQ3ppuO9PkGNf3cDr48JBRrP0dryKYURA,6528
|
|
30
|
-
pythonnative/web_view.py,sha256=OxduGbNgzfI6YNGzEPEGVHdLNhmCqUpTS57QZ7kVHms,1842
|
|
1
|
+
pythonnative/__init__.py,sha256=dfJgG3b1IreiKKiqA0gBj9sx5YCkNbAHuR66pgkufsM,1837
|
|
2
|
+
pythonnative/components.py,sha256=sV0FGV7fQQ9MtL_Yu26Asm2E9G-ODvWQaUfZ4g0Sx54,17753
|
|
3
|
+
pythonnative/element.py,sha256=RBUsXzzzM7KdK-NqMD-InVPKdAb8XJ0h0VpI2rwsfHs,1795
|
|
4
|
+
pythonnative/hooks.py,sha256=L8VdJ9YIhPVTdhUzgOqRYPgqo2484mynjgine77tFm0,8889
|
|
5
|
+
pythonnative/hot_reload.py,sha256=GoooBkRm2_zu_bQGOsOvUx-x9GdFcvRwSWEkhltFg2Y,4498
|
|
6
|
+
pythonnative/native_views.py,sha256=gar5Os9XsfbA-A1b69woRe-Wq2KhmJ6LJ5L3mnIbRAo,59753
|
|
7
|
+
pythonnative/page.py,sha256=16XrRXsl2m6NuOa2vw_Wtt1BqBP_GP-AhX-EG0dmb70,15214
|
|
8
|
+
pythonnative/reconciler.py,sha256=4Ah8NtYawZH9ZHXoMMjMTfdrTkZ0b4OT3e_85WLTrbU,9850
|
|
9
|
+
pythonnative/style.py,sha256=-ZHbPsfky6YyCQEmirPrUu-yQjWjFbyXvtV_pHZbg5U,3221
|
|
10
|
+
pythonnative/utils.py,sha256=IqR_GYknveM_NfAblcaizg9S66hCZfrfiH08HzpOc-4,2537
|
|
31
11
|
pythonnative/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
-
pythonnative/cli/pn.py,sha256=
|
|
33
|
-
pythonnative/
|
|
12
|
+
pythonnative/cli/pn.py,sha256=krn6WkdZ7QIfHVe0razroCPXdHlzlgFcGX1Q3NFNtyI,33027
|
|
13
|
+
pythonnative/native_modules/__init__.py,sha256=M_4SW-wCZ8azLuB0JLwUc8PESw00xMCM887-HuN9YNo,647
|
|
14
|
+
pythonnative/native_modules/camera.py,sha256=b3UErkABhBm2nQ-e72lEeFOgXoVDY6245cV6TN9iPBk,3509
|
|
15
|
+
pythonnative/native_modules/file_system.py,sha256=2fvYsIboCtjEyxmVeV72glOjtc9fJN3jTM6uaccru6E,4478
|
|
16
|
+
pythonnative/native_modules/location.py,sha256=bMSNbtG60hAorKXh4RR2vybX88M_BwHkCpTprRbMsZU,1883
|
|
17
|
+
pythonnative/native_modules/notifications.py,sha256=g-zT1GD-ojPsLN5eGXWkyNHTncSxdiEYtjllCXlsBSc,5377
|
|
18
|
+
pythonnative/templates/android_template/build.gradle,sha256=4gE6CRS6RuBu9kp-_e_uYYU9mBgHVZrqQg9caSxgyuc,352
|
|
34
19
|
pythonnative/templates/android_template/gradle.properties,sha256=REPaKLRfQiiVfIV8wYmgwzPWvF1f3bhh_kAMV9p4HME,1358
|
|
35
20
|
pythonnative/templates/android_template/gradlew,sha256=YxNShxF6Hm0SyEWA8fScYdG6AiGOzShmBgXpf5dufWU,5766
|
|
36
21
|
pythonnative/templates/android_template/gradlew.bat,sha256=xGonx5AHdG3lkisXq7YjDWStixujrRWF7lxlQ8KpsSk,2674
|
|
37
22
|
pythonnative/templates/android_template/settings.gradle,sha256=GKZiYUYWsaXxaiKOB65xnOs4jLmf0rhvI_3f8x0ic-o,333
|
|
38
|
-
pythonnative/templates/android_template/app/build.gradle,sha256=
|
|
23
|
+
pythonnative/templates/android_template/app/build.gradle,sha256=CpLxgnjwd4_WempE8ptbQ1C_GudMjZ1tFLB_4C-ZTAo,1669
|
|
39
24
|
pythonnative/templates/android_template/app/proguard-rules.pro,sha256=Vv2WDPIl9spA-YKxOl27DYvD394T_3ZCKCXGBw0KGJA,750
|
|
40
25
|
pythonnative/templates/android_template/app/src/androidTest/java/com/pythonnative/android_template/ExampleInstrumentedTest.kt,sha256=Am8Yla3i1eR_ac5FVgPU_RsuMrCbyT79h1BcajGE-zI,693
|
|
41
26
|
pythonnative/templates/android_template/app/src/main/AndroidManifest.xml,sha256=MdWrXxOrwUjnqtDbV952NI4nVF2dTUX9xwSS8chhd9I,940
|
|
42
27
|
pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt,sha256=sqOQ4k--WVyfnrhfNkzqAEQ211uYNPxhmIUXDrIb0zY,1321
|
|
43
28
|
pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/Navigator.kt,sha256=dWOpdJFuGO2CWZZQjYPmSNxljjDyGUuys7-ehHhAqyM,931
|
|
44
|
-
pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PageFragment.kt,sha256=
|
|
29
|
+
pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PageFragment.kt,sha256=fMQUugt9WqUIA9CbE4BafrVdPAbBTR_K_LH6bLed7XQ,4047
|
|
45
30
|
pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml,sha256=7UI8c6b0Ck0pCfCQHmBSezqAfNWeG1WTvKrhgIscYyE,5606
|
|
46
31
|
pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml,sha256=AdGmpsEjTrf-Jw0JfrKD1yucla5RGIhvG2VzqtKA8fc,1702
|
|
47
32
|
pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml,sha256=HIgdCNktb3YoJC8QOTIv-0qZRtMRoPdARK59nyYFO6g,461
|
|
@@ -81,9 +66,9 @@ pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/x
|
|
|
81
66
|
pythonnative/templates/ios_template/ios_templateTests/ios_templateTests.swift,sha256=YnwzZx7yXB13xKAXEGNgz17VuhWeqkHTRTtBJ2Vu3_E,1238
|
|
82
67
|
pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITests.swift,sha256=l2Pwa50F_rv-qPu2go6e4bQernM6PTQJeNPFl_c4ivY,1387
|
|
83
68
|
pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITestsLaunchTests.swift,sha256=f5JrG0uVtLMeJQy26Yyz7Om-JUkT220osqcbeIVkj2g,815
|
|
84
|
-
pythonnative-0.
|
|
85
|
-
pythonnative-0.
|
|
86
|
-
pythonnative-0.
|
|
87
|
-
pythonnative-0.
|
|
88
|
-
pythonnative-0.
|
|
89
|
-
pythonnative-0.
|
|
69
|
+
pythonnative-0.6.0.dist-info/licenses/LICENSE,sha256=A69iG7TIAe6KkGQf6xoVHkc5JSZtOr5eRSvC5iuivnI,1067
|
|
70
|
+
pythonnative-0.6.0.dist-info/METADATA,sha256=wjQGgxqLGAUj8pxfqpNDpJIyBJgcHS9C4ymDuonm6Hw,6648
|
|
71
|
+
pythonnative-0.6.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
72
|
+
pythonnative-0.6.0.dist-info/entry_points.txt,sha256=iUtDawWSAJAEyWTycpZxDuYz73ol31butpzDIEAgPO0,48
|
|
73
|
+
pythonnative-0.6.0.dist-info/top_level.txt,sha256=kT4SEATY2ywzrZ2Pgea6_zxyym44Q_PbOsUoOYjJLFE,13
|
|
74
|
+
pythonnative-0.6.0.dist-info/RECORD,,
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
|
|
3
|
-
from .utils import IS_ANDROID, get_android_context
|
|
4
|
-
from .view import ViewBase
|
|
5
|
-
|
|
6
|
-
# ========================================
|
|
7
|
-
# Base class
|
|
8
|
-
# ========================================
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class ActivityIndicatorViewBase(ABC):
|
|
12
|
-
@abstractmethod
|
|
13
|
-
def __init__(self) -> None:
|
|
14
|
-
super().__init__()
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def start_animating(self) -> None:
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
@abstractmethod
|
|
21
|
-
def stop_animating(self) -> None:
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if IS_ANDROID:
|
|
26
|
-
# ========================================
|
|
27
|
-
# Android class
|
|
28
|
-
# https://developer.android.com/reference/android/widget/ProgressBar
|
|
29
|
-
# ========================================
|
|
30
|
-
|
|
31
|
-
from java import jclass
|
|
32
|
-
|
|
33
|
-
class ActivityIndicatorView(ActivityIndicatorViewBase, ViewBase):
|
|
34
|
-
def __init__(self) -> None:
|
|
35
|
-
super().__init__()
|
|
36
|
-
self.native_class = jclass("android.widget.ProgressBar")
|
|
37
|
-
# self.native_instance = self.native_class(context, None, android.R.attr.progressBarStyleLarge)
|
|
38
|
-
context = get_android_context()
|
|
39
|
-
self.native_instance = self.native_class(context)
|
|
40
|
-
self.native_instance.setIndeterminate(True)
|
|
41
|
-
|
|
42
|
-
def start_animating(self) -> None:
|
|
43
|
-
# self.native_instance.setVisibility(android.view.View.VISIBLE)
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
def stop_animating(self) -> None:
|
|
47
|
-
# self.native_instance.setVisibility(android.view.View.GONE)
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
else:
|
|
51
|
-
# ========================================
|
|
52
|
-
# iOS class
|
|
53
|
-
# https://developer.apple.com/documentation/uikit/uiactivityindicatorview
|
|
54
|
-
# ========================================
|
|
55
|
-
|
|
56
|
-
from rubicon.objc import ObjCClass
|
|
57
|
-
|
|
58
|
-
class ActivityIndicatorView(ActivityIndicatorViewBase, ViewBase):
|
|
59
|
-
def __init__(self) -> None:
|
|
60
|
-
super().__init__()
|
|
61
|
-
self.native_class = ObjCClass("UIActivityIndicatorView")
|
|
62
|
-
self.native_instance = self.native_class.alloc().initWithActivityIndicatorStyle_(
|
|
63
|
-
0
|
|
64
|
-
) # 0: UIActivityIndicatorViewStyleLarge
|
|
65
|
-
self.native_instance.hidesWhenStopped = True
|
|
66
|
-
|
|
67
|
-
def start_animating(self) -> None:
|
|
68
|
-
self.native_instance.startAnimating()
|
|
69
|
-
|
|
70
|
-
def stop_animating(self) -> None:
|
|
71
|
-
self.native_instance.stopAnimating()
|
pythonnative/button.py
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Any, Callable, Optional
|
|
3
|
-
|
|
4
|
-
from .utils import IS_ANDROID, get_android_context
|
|
5
|
-
from .view import ViewBase
|
|
6
|
-
|
|
7
|
-
# ========================================
|
|
8
|
-
# Base class
|
|
9
|
-
# ========================================
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ButtonBase(ABC):
|
|
13
|
-
@abstractmethod
|
|
14
|
-
def __init__(self) -> None:
|
|
15
|
-
super().__init__()
|
|
16
|
-
|
|
17
|
-
@abstractmethod
|
|
18
|
-
def set_title(self, title: str) -> "ButtonBase":
|
|
19
|
-
pass
|
|
20
|
-
|
|
21
|
-
@abstractmethod
|
|
22
|
-
def get_title(self) -> str:
|
|
23
|
-
pass
|
|
24
|
-
|
|
25
|
-
@abstractmethod
|
|
26
|
-
def set_on_click(self, callback: Callable[[], None]) -> "ButtonBase":
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if IS_ANDROID:
|
|
31
|
-
# ========================================
|
|
32
|
-
# Android class
|
|
33
|
-
# https://developer.android.com/reference/android/widget/Button
|
|
34
|
-
# ========================================
|
|
35
|
-
|
|
36
|
-
from java import dynamic_proxy, jclass
|
|
37
|
-
|
|
38
|
-
class Button(ButtonBase, ViewBase):
|
|
39
|
-
def __init__(self, title: str = "") -> None:
|
|
40
|
-
super().__init__()
|
|
41
|
-
self.native_class = jclass("android.widget.Button")
|
|
42
|
-
context = get_android_context()
|
|
43
|
-
self.native_instance = self.native_class(context)
|
|
44
|
-
self.set_title(title)
|
|
45
|
-
|
|
46
|
-
def set_title(self, title: str) -> "Button":
|
|
47
|
-
self.native_instance.setText(title)
|
|
48
|
-
return self
|
|
49
|
-
|
|
50
|
-
def get_title(self) -> str:
|
|
51
|
-
return self.native_instance.getText().toString()
|
|
52
|
-
|
|
53
|
-
def set_on_click(self, callback: Callable[[], None]) -> "Button":
|
|
54
|
-
class OnClickListener(dynamic_proxy(jclass("android.view.View").OnClickListener)):
|
|
55
|
-
def __init__(self, callback: Callable[[], None]) -> None:
|
|
56
|
-
super().__init__()
|
|
57
|
-
self.callback = callback
|
|
58
|
-
|
|
59
|
-
def onClick(self, view: Any) -> None:
|
|
60
|
-
self.callback()
|
|
61
|
-
|
|
62
|
-
listener = OnClickListener(callback)
|
|
63
|
-
self.native_instance.setOnClickListener(listener)
|
|
64
|
-
return self
|
|
65
|
-
|
|
66
|
-
else:
|
|
67
|
-
# ========================================
|
|
68
|
-
# iOS class
|
|
69
|
-
# https://developer.apple.com/documentation/uikit/uibutton
|
|
70
|
-
# ========================================
|
|
71
|
-
|
|
72
|
-
from rubicon.objc import SEL, ObjCClass, objc_method
|
|
73
|
-
|
|
74
|
-
NSObject = ObjCClass("NSObject")
|
|
75
|
-
|
|
76
|
-
# Mypy cannot understand Rubicon's dynamic subclassing; ignore the base type here.
|
|
77
|
-
class _PNButtonHandler(NSObject): # type: ignore[valid-type]
|
|
78
|
-
# Set by the Button when wiring up the target/action callback.
|
|
79
|
-
_callback: Optional[Callable[[], None]] = None
|
|
80
|
-
|
|
81
|
-
@objc_method
|
|
82
|
-
def onTap_(self, sender: object) -> None:
|
|
83
|
-
try:
|
|
84
|
-
callback = self._callback
|
|
85
|
-
if callback is not None:
|
|
86
|
-
callback()
|
|
87
|
-
except Exception:
|
|
88
|
-
# Swallow exceptions to avoid crashing the app; logging is handled at higher levels
|
|
89
|
-
pass
|
|
90
|
-
|
|
91
|
-
class Button(ButtonBase, ViewBase):
|
|
92
|
-
def __init__(self, title: str = "") -> None:
|
|
93
|
-
super().__init__()
|
|
94
|
-
self.native_class = ObjCClass("UIButton")
|
|
95
|
-
self.native_instance = self.native_class.alloc().init()
|
|
96
|
-
self.set_title(title)
|
|
97
|
-
|
|
98
|
-
def set_title(self, title: str) -> "Button":
|
|
99
|
-
self.native_instance.setTitle_forState_(title, 0)
|
|
100
|
-
return self
|
|
101
|
-
|
|
102
|
-
def get_title(self) -> str:
|
|
103
|
-
return self.native_instance.titleForState_(0)
|
|
104
|
-
|
|
105
|
-
def set_on_click(self, callback: Callable[[], None]) -> "Button":
|
|
106
|
-
# Create a handler object with an Objective-C method `onTap:` and attach the Python callback
|
|
107
|
-
handler = _PNButtonHandler.new()
|
|
108
|
-
# Keep strong references to the handler and callback
|
|
109
|
-
self._click_handler = handler
|
|
110
|
-
handler._callback = callback
|
|
111
|
-
# UIControlEventTouchUpInside = 1 << 6
|
|
112
|
-
self.native_instance.addTarget_action_forControlEvents_(handler, SEL("onTap:"), 1 << 6)
|
|
113
|
-
return self
|
pythonnative/collection_view.py
DELETED
|
File without changes
|
pythonnative/date_picker.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
|
|
3
|
-
from .utils import IS_ANDROID
|
|
4
|
-
from .view import ViewBase
|
|
5
|
-
|
|
6
|
-
# ========================================
|
|
7
|
-
# Base class
|
|
8
|
-
# ========================================
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class DatePickerBase(ABC):
|
|
12
|
-
@abstractmethod
|
|
13
|
-
def __init__(self) -> None:
|
|
14
|
-
super().__init__()
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def set_date(self, year: int, month: int, day: int) -> "DatePickerBase":
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
@abstractmethod
|
|
21
|
-
def get_date(self) -> tuple:
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if IS_ANDROID:
|
|
26
|
-
# ========================================
|
|
27
|
-
# Android class
|
|
28
|
-
# https://developer.android.com/reference/android/widget/DatePicker
|
|
29
|
-
# ========================================
|
|
30
|
-
|
|
31
|
-
from typing import Any
|
|
32
|
-
|
|
33
|
-
from java import jclass
|
|
34
|
-
|
|
35
|
-
class DatePicker(DatePickerBase, ViewBase):
|
|
36
|
-
def __init__(self, context: Any, year: int = 0, month: int = 0, day: int = 0) -> None:
|
|
37
|
-
super().__init__()
|
|
38
|
-
self.native_class = jclass("android.widget.DatePicker")
|
|
39
|
-
self.native_instance = self.native_class(context)
|
|
40
|
-
self.set_date(year, month, day)
|
|
41
|
-
|
|
42
|
-
def set_date(self, year: int, month: int, day: int) -> "DatePicker":
|
|
43
|
-
self.native_instance.updateDate(year, month, day)
|
|
44
|
-
return self
|
|
45
|
-
|
|
46
|
-
def get_date(self) -> tuple:
|
|
47
|
-
year = self.native_instance.getYear()
|
|
48
|
-
month = self.native_instance.getMonth()
|
|
49
|
-
day = self.native_instance.getDayOfMonth()
|
|
50
|
-
return year, month, day
|
|
51
|
-
|
|
52
|
-
else:
|
|
53
|
-
# ========================================
|
|
54
|
-
# iOS class
|
|
55
|
-
# https://developer.apple.com/documentation/uikit/uidatepicker
|
|
56
|
-
# ========================================
|
|
57
|
-
|
|
58
|
-
from datetime import datetime
|
|
59
|
-
|
|
60
|
-
from rubicon.objc import ObjCClass
|
|
61
|
-
|
|
62
|
-
class DatePicker(DatePickerBase, ViewBase):
|
|
63
|
-
def __init__(self, year: int = 0, month: int = 0, day: int = 0) -> None:
|
|
64
|
-
super().__init__()
|
|
65
|
-
self.native_class = ObjCClass("UIDatePicker")
|
|
66
|
-
self.native_instance = self.native_class.alloc().init()
|
|
67
|
-
self.set_date(year, month, day)
|
|
68
|
-
|
|
69
|
-
def set_date(self, year: int, month: int, day: int) -> "DatePicker":
|
|
70
|
-
date = datetime(year, month, day)
|
|
71
|
-
self.native_instance.setDate_(date)
|
|
72
|
-
return self
|
|
73
|
-
|
|
74
|
-
def get_date(self) -> tuple:
|
|
75
|
-
date = self.native_instance.date()
|
|
76
|
-
return date.year, date.month, date.day
|
pythonnative/image_view.py
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
|
|
3
|
-
from .utils import IS_ANDROID, get_android_context
|
|
4
|
-
from .view import ViewBase
|
|
5
|
-
|
|
6
|
-
# ========================================
|
|
7
|
-
# Base class
|
|
8
|
-
# ========================================
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class ImageViewBase(ABC):
|
|
12
|
-
@abstractmethod
|
|
13
|
-
def __init__(self) -> None:
|
|
14
|
-
super().__init__()
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def set_image(self, image: str) -> "ImageViewBase":
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
@abstractmethod
|
|
21
|
-
def get_image(self) -> str:
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if IS_ANDROID:
|
|
26
|
-
# ========================================
|
|
27
|
-
# Android class
|
|
28
|
-
# https://developer.android.com/reference/android/widget/ImageView
|
|
29
|
-
# ========================================
|
|
30
|
-
|
|
31
|
-
from android.graphics import BitmapFactory
|
|
32
|
-
from java import jclass
|
|
33
|
-
|
|
34
|
-
class ImageView(ImageViewBase, ViewBase):
|
|
35
|
-
def __init__(self, image: str = "") -> None:
|
|
36
|
-
super().__init__()
|
|
37
|
-
self.native_class = jclass("android.widget.ImageView")
|
|
38
|
-
context = get_android_context()
|
|
39
|
-
self.native_instance = self.native_class(context)
|
|
40
|
-
if image:
|
|
41
|
-
self.set_image(image)
|
|
42
|
-
|
|
43
|
-
def set_image(self, image: str) -> "ImageView":
|
|
44
|
-
bitmap = BitmapFactory.decodeFile(image)
|
|
45
|
-
self.native_instance.setImageBitmap(bitmap)
|
|
46
|
-
return self
|
|
47
|
-
|
|
48
|
-
def get_image(self) -> str:
|
|
49
|
-
# Please note that this is a simplistic representation, getting image from ImageView
|
|
50
|
-
# in Android would require converting Drawable to Bitmap and then to File
|
|
51
|
-
return "Image file path in Android"
|
|
52
|
-
|
|
53
|
-
else:
|
|
54
|
-
# ========================================
|
|
55
|
-
# iOS class
|
|
56
|
-
# https://developer.apple.com/documentation/uikit/uiimageview
|
|
57
|
-
# ========================================
|
|
58
|
-
|
|
59
|
-
from rubicon.objc import ObjCClass
|
|
60
|
-
from rubicon.objc.api import NSString, UIImage
|
|
61
|
-
|
|
62
|
-
class ImageView(ImageViewBase, ViewBase):
|
|
63
|
-
def __init__(self, image: str = "") -> None:
|
|
64
|
-
super().__init__()
|
|
65
|
-
self.native_class = ObjCClass("UIImageView")
|
|
66
|
-
self.native_instance = self.native_class.alloc().init()
|
|
67
|
-
if image:
|
|
68
|
-
self.set_image(image)
|
|
69
|
-
|
|
70
|
-
def set_image(self, image: str) -> "ImageView":
|
|
71
|
-
ns_str = NSString.alloc().initWithUTF8String_(image)
|
|
72
|
-
ui_image = UIImage.imageNamed_(ns_str)
|
|
73
|
-
self.native_instance.setImage_(ui_image)
|
|
74
|
-
return self
|
|
75
|
-
|
|
76
|
-
def get_image(self) -> str:
|
|
77
|
-
# Similar to Android, getting the image from UIImageView isn't straightforward.
|
|
78
|
-
return "Image file name in iOS"
|
pythonnative/label.py
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Any
|
|
3
|
-
|
|
4
|
-
from .utils import IS_ANDROID, get_android_context
|
|
5
|
-
from .view import ViewBase
|
|
6
|
-
|
|
7
|
-
# ========================================
|
|
8
|
-
# Base class
|
|
9
|
-
# ========================================
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class LabelBase(ABC):
|
|
13
|
-
@abstractmethod
|
|
14
|
-
def __init__(self) -> None:
|
|
15
|
-
super().__init__()
|
|
16
|
-
|
|
17
|
-
@abstractmethod
|
|
18
|
-
def set_text(self, text: str) -> "LabelBase":
|
|
19
|
-
pass
|
|
20
|
-
|
|
21
|
-
@abstractmethod
|
|
22
|
-
def get_text(self) -> str:
|
|
23
|
-
pass
|
|
24
|
-
|
|
25
|
-
@abstractmethod
|
|
26
|
-
def set_text_color(self, color: Any) -> "LabelBase":
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
@abstractmethod
|
|
30
|
-
def set_text_size(self, size: float) -> "LabelBase":
|
|
31
|
-
pass
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if IS_ANDROID:
|
|
35
|
-
# ========================================
|
|
36
|
-
# Android class
|
|
37
|
-
# https://developer.android.com/reference/android/widget/TextView
|
|
38
|
-
# ========================================
|
|
39
|
-
|
|
40
|
-
from java import jclass
|
|
41
|
-
|
|
42
|
-
class Label(LabelBase, ViewBase):
|
|
43
|
-
def __init__(self, text: str = "") -> None:
|
|
44
|
-
super().__init__()
|
|
45
|
-
self.native_class = jclass("android.widget.TextView")
|
|
46
|
-
context = get_android_context()
|
|
47
|
-
self.native_instance = self.native_class(context)
|
|
48
|
-
self.set_text(text)
|
|
49
|
-
|
|
50
|
-
def set_text(self, text: str) -> "Label":
|
|
51
|
-
self.native_instance.setText(text)
|
|
52
|
-
return self
|
|
53
|
-
|
|
54
|
-
def get_text(self) -> str:
|
|
55
|
-
return self.native_instance.getText().toString()
|
|
56
|
-
|
|
57
|
-
def set_text_color(self, color: Any) -> "Label":
|
|
58
|
-
# Accept int ARGB or hex string
|
|
59
|
-
if isinstance(color, str):
|
|
60
|
-
c = color.strip()
|
|
61
|
-
if c.startswith("#"):
|
|
62
|
-
c = c[1:]
|
|
63
|
-
if len(c) == 6:
|
|
64
|
-
c = "FF" + c
|
|
65
|
-
color_int = int(c, 16)
|
|
66
|
-
else:
|
|
67
|
-
color_int = int(color)
|
|
68
|
-
try:
|
|
69
|
-
self.native_instance.setTextColor(color_int)
|
|
70
|
-
except Exception:
|
|
71
|
-
pass
|
|
72
|
-
return self
|
|
73
|
-
|
|
74
|
-
def set_text_size(self, size_sp: float) -> "Label":
|
|
75
|
-
try:
|
|
76
|
-
self.native_instance.setTextSize(float(size_sp))
|
|
77
|
-
except Exception:
|
|
78
|
-
pass
|
|
79
|
-
return self
|
|
80
|
-
|
|
81
|
-
else:
|
|
82
|
-
# ========================================
|
|
83
|
-
# iOS class
|
|
84
|
-
# https://developer.apple.com/documentation/uikit/uilabel
|
|
85
|
-
# ========================================
|
|
86
|
-
|
|
87
|
-
from rubicon.objc import ObjCClass
|
|
88
|
-
|
|
89
|
-
class Label(LabelBase, ViewBase):
|
|
90
|
-
def __init__(self, text: str = "") -> None:
|
|
91
|
-
super().__init__()
|
|
92
|
-
self.native_class = ObjCClass("UILabel")
|
|
93
|
-
self.native_instance = self.native_class.alloc().init()
|
|
94
|
-
self.set_text(text)
|
|
95
|
-
|
|
96
|
-
def set_text(self, text: str) -> "Label":
|
|
97
|
-
self.native_instance.setText_(text)
|
|
98
|
-
return self
|
|
99
|
-
|
|
100
|
-
def get_text(self) -> str:
|
|
101
|
-
return self.native_instance.text()
|
|
102
|
-
|
|
103
|
-
def set_text_color(self, color: Any) -> "Label":
|
|
104
|
-
# Accept int ARGB or hex string
|
|
105
|
-
if isinstance(color, str):
|
|
106
|
-
c = color.strip()
|
|
107
|
-
if c.startswith("#"):
|
|
108
|
-
c = c[1:]
|
|
109
|
-
if len(c) == 6:
|
|
110
|
-
c = "FF" + c
|
|
111
|
-
color_int = int(c, 16)
|
|
112
|
-
else:
|
|
113
|
-
color_int = int(color)
|
|
114
|
-
try:
|
|
115
|
-
UIColor = ObjCClass("UIColor")
|
|
116
|
-
a = ((color_int >> 24) & 0xFF) / 255.0
|
|
117
|
-
r = ((color_int >> 16) & 0xFF) / 255.0
|
|
118
|
-
g = ((color_int >> 8) & 0xFF) / 255.0
|
|
119
|
-
b = (color_int & 0xFF) / 255.0
|
|
120
|
-
color_obj = UIColor.colorWithRed_green_blue_alpha_(r, g, b, a)
|
|
121
|
-
self.native_instance.setTextColor_(color_obj)
|
|
122
|
-
except Exception:
|
|
123
|
-
pass
|
|
124
|
-
return self
|
|
125
|
-
|
|
126
|
-
def set_text_size(self, size: float) -> "Label":
|
|
127
|
-
try:
|
|
128
|
-
UIFont = ObjCClass("UIFont")
|
|
129
|
-
font = UIFont.systemFontOfSize_(float(size))
|
|
130
|
-
self.native_instance.setFont_(font)
|
|
131
|
-
except Exception:
|
|
132
|
-
pass
|
|
133
|
-
return self
|
pythonnative/list_view.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Any
|
|
3
|
-
|
|
4
|
-
from .utils import IS_ANDROID
|
|
5
|
-
from .view import ViewBase
|
|
6
|
-
|
|
7
|
-
# ========================================
|
|
8
|
-
# Base class
|
|
9
|
-
# ========================================
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ListViewBase(ABC):
|
|
13
|
-
@abstractmethod
|
|
14
|
-
def __init__(self) -> None:
|
|
15
|
-
super().__init__()
|
|
16
|
-
|
|
17
|
-
@abstractmethod
|
|
18
|
-
def set_data(self, data: list) -> "ListViewBase":
|
|
19
|
-
pass
|
|
20
|
-
|
|
21
|
-
@abstractmethod
|
|
22
|
-
def get_data(self) -> list:
|
|
23
|
-
pass
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if IS_ANDROID:
|
|
27
|
-
# ========================================
|
|
28
|
-
# Android class
|
|
29
|
-
# https://developer.android.com/reference/android/widget/ListView
|
|
30
|
-
# ========================================
|
|
31
|
-
|
|
32
|
-
from java import jclass
|
|
33
|
-
|
|
34
|
-
class ListView(ListViewBase, ViewBase):
|
|
35
|
-
def __init__(self, context: Any, data: list = []) -> None:
|
|
36
|
-
super().__init__()
|
|
37
|
-
self.context = context
|
|
38
|
-
self.native_class = jclass("android.widget.ListView")
|
|
39
|
-
self.native_instance = self.native_class(context)
|
|
40
|
-
self.set_data(data)
|
|
41
|
-
|
|
42
|
-
def set_data(self, data: list) -> "ListView":
|
|
43
|
-
adapter = jclass("android.widget.ArrayAdapter")(
|
|
44
|
-
self.context, jclass("android.R$layout").simple_list_item_1, data
|
|
45
|
-
)
|
|
46
|
-
self.native_instance.setAdapter(adapter)
|
|
47
|
-
return self
|
|
48
|
-
|
|
49
|
-
def get_data(self) -> list:
|
|
50
|
-
adapter = self.native_instance.getAdapter()
|
|
51
|
-
return [adapter.getItem(i) for i in range(adapter.getCount())]
|
|
52
|
-
|
|
53
|
-
else:
|
|
54
|
-
# ========================================
|
|
55
|
-
# iOS class
|
|
56
|
-
# https://developer.apple.com/documentation/uikit/uitableview
|
|
57
|
-
# ========================================
|
|
58
|
-
|
|
59
|
-
from rubicon.objc import ObjCClass
|
|
60
|
-
|
|
61
|
-
class ListView(ListViewBase, ViewBase):
|
|
62
|
-
def __init__(self, data: list = []) -> None:
|
|
63
|
-
super().__init__()
|
|
64
|
-
self.native_class = ObjCClass("UITableView")
|
|
65
|
-
self.native_instance = self.native_class.alloc().init()
|
|
66
|
-
self.set_data(data)
|
|
67
|
-
|
|
68
|
-
def set_data(self, data: list) -> "ListView":
|
|
69
|
-
# Note: This is a simplified representation. Normally, you would need to create a UITableViewDataSource.
|
|
70
|
-
self.native_instance.reloadData()
|
|
71
|
-
return self
|
|
72
|
-
|
|
73
|
-
def get_data(self) -> list:
|
|
74
|
-
# Note: This is a simplified representation.
|
|
75
|
-
# Normally, you would need to get data from the UITableViewDataSource.
|
|
76
|
-
return []
|