pythonnative 0.3.0__py3-none-any.whl → 0.5.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 +45 -65
- pythonnative/cli/pn.py +16 -10
- pythonnative/components.py +241 -0
- pythonnative/element.py +47 -0
- pythonnative/native_views.py +800 -0
- pythonnative/page.py +321 -249
- pythonnative/reconciler.py +129 -0
- pythonnative/templates/android_template/app/build.gradle +2 -2
- pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PageFragment.kt +2 -1
- pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +1 -1
- pythonnative/templates/android_template/build.gradle +3 -3
- pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +1 -1
- pythonnative/utils.py +21 -29
- pythonnative-0.5.0.dist-info/METADATA +161 -0
- {pythonnative-0.3.0.dist-info → pythonnative-0.5.0.dist-info}/RECORD +19 -39
- {pythonnative-0.3.0.dist-info → pythonnative-0.5.0.dist-info}/WHEEL +1 -1
- {pythonnative-0.3.0.dist-info → pythonnative-0.5.0.dist-info}/licenses/LICENSE +1 -1
- pythonnative/activity_indicator_view.py +0 -71
- pythonnative/button.py +0 -109
- pythonnative/date_picker.py +0 -72
- pythonnative/image_view.py +0 -76
- pythonnative/label.py +0 -66
- pythonnative/list_view.py +0 -73
- pythonnative/material_activity_indicator_view.py +0 -69
- pythonnative/material_button.py +0 -65
- pythonnative/material_date_picker.py +0 -85
- pythonnative/material_progress_view.py +0 -66
- pythonnative/material_search_bar.py +0 -65
- pythonnative/material_switch.py +0 -65
- pythonnative/material_time_picker.py +0 -72
- pythonnative/picker_view.py +0 -65
- pythonnative/progress_view.py +0 -68
- pythonnative/scroll_view.py +0 -63
- pythonnative/search_bar.py +0 -65
- pythonnative/stack_view.py +0 -60
- pythonnative/switch.py +0 -66
- pythonnative/text_field.py +0 -67
- pythonnative/text_view.py +0 -70
- pythonnative/time_picker.py +0 -73
- pythonnative/view.py +0 -25
- pythonnative/web_view.py +0 -58
- pythonnative-0.3.0.dist-info/METADATA +0 -137
- {pythonnative-0.3.0.dist-info → pythonnative-0.5.0.dist-info}/entry_points.txt +0 -0
- {pythonnative-0.3.0.dist-info → pythonnative-0.5.0.dist-info}/top_level.txt +0 -0
pythonnative/button.py
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import 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) -> None:
|
|
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]) -> None:
|
|
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) -> None:
|
|
47
|
-
self.native_instance.setText(title)
|
|
48
|
-
|
|
49
|
-
def get_title(self) -> str:
|
|
50
|
-
return self.native_instance.getText().toString()
|
|
51
|
-
|
|
52
|
-
def set_on_click(self, callback: Callable[[], None]) -> None:
|
|
53
|
-
class OnClickListener(dynamic_proxy(jclass("android.view.View").OnClickListener)):
|
|
54
|
-
def __init__(self, callback):
|
|
55
|
-
super().__init__()
|
|
56
|
-
self.callback = callback
|
|
57
|
-
|
|
58
|
-
def onClick(self, view):
|
|
59
|
-
self.callback()
|
|
60
|
-
|
|
61
|
-
listener = OnClickListener(callback)
|
|
62
|
-
self.native_instance.setOnClickListener(listener)
|
|
63
|
-
|
|
64
|
-
else:
|
|
65
|
-
# ========================================
|
|
66
|
-
# iOS class
|
|
67
|
-
# https://developer.apple.com/documentation/uikit/uibutton
|
|
68
|
-
# ========================================
|
|
69
|
-
|
|
70
|
-
from rubicon.objc import SEL, ObjCClass, objc_method
|
|
71
|
-
|
|
72
|
-
NSObject = ObjCClass("NSObject")
|
|
73
|
-
|
|
74
|
-
# Mypy cannot understand Rubicon's dynamic subclassing; ignore the base type here.
|
|
75
|
-
class _PNButtonHandler(NSObject): # type: ignore[valid-type]
|
|
76
|
-
# Set by the Button when wiring up the target/action callback.
|
|
77
|
-
_callback: Optional[Callable[[], None]] = None
|
|
78
|
-
|
|
79
|
-
@objc_method
|
|
80
|
-
def onTap_(self, sender) -> None:
|
|
81
|
-
try:
|
|
82
|
-
callback = self._callback
|
|
83
|
-
if callback is not None:
|
|
84
|
-
callback()
|
|
85
|
-
except Exception:
|
|
86
|
-
# Swallow exceptions to avoid crashing the app; logging is handled at higher levels
|
|
87
|
-
pass
|
|
88
|
-
|
|
89
|
-
class Button(ButtonBase, ViewBase):
|
|
90
|
-
def __init__(self, title: str = "") -> None:
|
|
91
|
-
super().__init__()
|
|
92
|
-
self.native_class = ObjCClass("UIButton")
|
|
93
|
-
self.native_instance = self.native_class.alloc().init()
|
|
94
|
-
self.set_title(title)
|
|
95
|
-
|
|
96
|
-
def set_title(self, title: str) -> None:
|
|
97
|
-
self.native_instance.setTitle_forState_(title, 0)
|
|
98
|
-
|
|
99
|
-
def get_title(self) -> str:
|
|
100
|
-
return self.native_instance.titleForState_(0)
|
|
101
|
-
|
|
102
|
-
def set_on_click(self, callback: Callable[[], None]) -> None:
|
|
103
|
-
# Create a handler object with an Objective-C method `onTap:` and attach the Python callback
|
|
104
|
-
handler = _PNButtonHandler.new()
|
|
105
|
-
# Keep strong references to the handler and callback
|
|
106
|
-
self._click_handler = handler
|
|
107
|
-
handler._callback = callback
|
|
108
|
-
# UIControlEventTouchUpInside = 1 << 6
|
|
109
|
-
self.native_instance.addTarget_action_forControlEvents_(handler, SEL("onTap:"), 1 << 6)
|
pythonnative/date_picker.py
DELETED
|
@@ -1,72 +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) -> None:
|
|
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 java import jclass
|
|
32
|
-
|
|
33
|
-
class DatePicker(DatePickerBase, ViewBase):
|
|
34
|
-
def __init__(self, context, year: int = 0, month: int = 0, day: int = 0) -> None:
|
|
35
|
-
super().__init__()
|
|
36
|
-
self.native_class = jclass("android.widget.DatePicker")
|
|
37
|
-
self.native_instance = self.native_class(context)
|
|
38
|
-
self.set_date(year, month, day)
|
|
39
|
-
|
|
40
|
-
def set_date(self, year: int, month: int, day: int) -> None:
|
|
41
|
-
self.native_instance.updateDate(year, month, day)
|
|
42
|
-
|
|
43
|
-
def get_date(self) -> tuple:
|
|
44
|
-
year = self.native_instance.getYear()
|
|
45
|
-
month = self.native_instance.getMonth()
|
|
46
|
-
day = self.native_instance.getDayOfMonth()
|
|
47
|
-
return year, month, day
|
|
48
|
-
|
|
49
|
-
else:
|
|
50
|
-
# ========================================
|
|
51
|
-
# iOS class
|
|
52
|
-
# https://developer.apple.com/documentation/uikit/uidatepicker
|
|
53
|
-
# ========================================
|
|
54
|
-
|
|
55
|
-
from datetime import datetime
|
|
56
|
-
|
|
57
|
-
from rubicon.objc import ObjCClass
|
|
58
|
-
|
|
59
|
-
class DatePicker(DatePickerBase, ViewBase):
|
|
60
|
-
def __init__(self, year: int = 0, month: int = 0, day: int = 0) -> None:
|
|
61
|
-
super().__init__()
|
|
62
|
-
self.native_class = ObjCClass("UIDatePicker")
|
|
63
|
-
self.native_instance = self.native_class.alloc().init()
|
|
64
|
-
self.set_date(year, month, day)
|
|
65
|
-
|
|
66
|
-
def set_date(self, year: int, month: int, day: int) -> None:
|
|
67
|
-
date = datetime(year, month, day)
|
|
68
|
-
self.native_instance.setDate_(date)
|
|
69
|
-
|
|
70
|
-
def get_date(self) -> tuple:
|
|
71
|
-
date = self.native_instance.date()
|
|
72
|
-
return date.year, date.month, date.day
|
pythonnative/image_view.py
DELETED
|
@@ -1,76 +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) -> None:
|
|
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) -> None:
|
|
44
|
-
bitmap = BitmapFactory.decodeFile(image)
|
|
45
|
-
self.native_instance.setImageBitmap(bitmap)
|
|
46
|
-
|
|
47
|
-
def get_image(self) -> str:
|
|
48
|
-
# Please note that this is a simplistic representation, getting image from ImageView
|
|
49
|
-
# in Android would require converting Drawable to Bitmap and then to File
|
|
50
|
-
return "Image file path in Android"
|
|
51
|
-
|
|
52
|
-
else:
|
|
53
|
-
# ========================================
|
|
54
|
-
# iOS class
|
|
55
|
-
# https://developer.apple.com/documentation/uikit/uiimageview
|
|
56
|
-
# ========================================
|
|
57
|
-
|
|
58
|
-
from rubicon.objc import ObjCClass
|
|
59
|
-
from rubicon.objc.api import NSString, UIImage
|
|
60
|
-
|
|
61
|
-
class ImageView(ImageViewBase, ViewBase):
|
|
62
|
-
def __init__(self, image: str = "") -> None:
|
|
63
|
-
super().__init__()
|
|
64
|
-
self.native_class = ObjCClass("UIImageView")
|
|
65
|
-
self.native_instance = self.native_class.alloc().init()
|
|
66
|
-
if image:
|
|
67
|
-
self.set_image(image)
|
|
68
|
-
|
|
69
|
-
def set_image(self, image: str) -> None:
|
|
70
|
-
ns_str = NSString.alloc().initWithUTF8String_(image)
|
|
71
|
-
ui_image = UIImage.imageNamed_(ns_str)
|
|
72
|
-
self.native_instance.setImage_(ui_image)
|
|
73
|
-
|
|
74
|
-
def get_image(self) -> str:
|
|
75
|
-
# Similar to Android, getting the image from UIImageView isn't straightforward.
|
|
76
|
-
return "Image file name in iOS"
|
pythonnative/label.py
DELETED
|
@@ -1,66 +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 LabelBase(ABC):
|
|
12
|
-
@abstractmethod
|
|
13
|
-
def __init__(self) -> None:
|
|
14
|
-
super().__init__()
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def set_text(self, text: str) -> None:
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
@abstractmethod
|
|
21
|
-
def get_text(self) -> str:
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if IS_ANDROID:
|
|
26
|
-
# ========================================
|
|
27
|
-
# Android class
|
|
28
|
-
# https://developer.android.com/reference/android/widget/TextView
|
|
29
|
-
# ========================================
|
|
30
|
-
|
|
31
|
-
from java import jclass
|
|
32
|
-
|
|
33
|
-
class Label(LabelBase, ViewBase):
|
|
34
|
-
def __init__(self, text: str = "") -> None:
|
|
35
|
-
super().__init__()
|
|
36
|
-
self.native_class = jclass("android.widget.TextView")
|
|
37
|
-
context = get_android_context()
|
|
38
|
-
self.native_instance = self.native_class(context)
|
|
39
|
-
self.set_text(text)
|
|
40
|
-
|
|
41
|
-
def set_text(self, text: str) -> None:
|
|
42
|
-
self.native_instance.setText(text)
|
|
43
|
-
|
|
44
|
-
def get_text(self) -> str:
|
|
45
|
-
return self.native_instance.getText().toString()
|
|
46
|
-
|
|
47
|
-
else:
|
|
48
|
-
# ========================================
|
|
49
|
-
# iOS class
|
|
50
|
-
# https://developer.apple.com/documentation/uikit/uilabel
|
|
51
|
-
# ========================================
|
|
52
|
-
|
|
53
|
-
from rubicon.objc import ObjCClass
|
|
54
|
-
|
|
55
|
-
class Label(LabelBase, ViewBase):
|
|
56
|
-
def __init__(self, text: str = "") -> None:
|
|
57
|
-
super().__init__()
|
|
58
|
-
self.native_class = ObjCClass("UILabel")
|
|
59
|
-
self.native_instance = self.native_class.alloc().init()
|
|
60
|
-
self.set_text(text)
|
|
61
|
-
|
|
62
|
-
def set_text(self, text: str) -> None:
|
|
63
|
-
self.native_instance.setText_(text)
|
|
64
|
-
|
|
65
|
-
def get_text(self) -> str:
|
|
66
|
-
return self.native_instance.text()
|
pythonnative/list_view.py
DELETED
|
@@ -1,73 +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 ListViewBase(ABC):
|
|
12
|
-
@abstractmethod
|
|
13
|
-
def __init__(self) -> None:
|
|
14
|
-
super().__init__()
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def set_data(self, data: list) -> None:
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
@abstractmethod
|
|
21
|
-
def get_data(self) -> list:
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if IS_ANDROID:
|
|
26
|
-
# ========================================
|
|
27
|
-
# Android class
|
|
28
|
-
# https://developer.android.com/reference/android/widget/ListView
|
|
29
|
-
# ========================================
|
|
30
|
-
|
|
31
|
-
from java import jclass
|
|
32
|
-
|
|
33
|
-
class ListView(ListViewBase, ViewBase):
|
|
34
|
-
def __init__(self, context, data: list = []) -> None:
|
|
35
|
-
super().__init__()
|
|
36
|
-
self.context = context
|
|
37
|
-
self.native_class = jclass("android.widget.ListView")
|
|
38
|
-
self.native_instance = self.native_class(context)
|
|
39
|
-
self.set_data(data)
|
|
40
|
-
|
|
41
|
-
def set_data(self, data: list) -> None:
|
|
42
|
-
adapter = jclass("android.widget.ArrayAdapter")(
|
|
43
|
-
self.context, jclass("android.R$layout").simple_list_item_1, data
|
|
44
|
-
)
|
|
45
|
-
self.native_instance.setAdapter(adapter)
|
|
46
|
-
|
|
47
|
-
def get_data(self) -> list:
|
|
48
|
-
adapter = self.native_instance.getAdapter()
|
|
49
|
-
return [adapter.getItem(i) for i in range(adapter.getCount())]
|
|
50
|
-
|
|
51
|
-
else:
|
|
52
|
-
# ========================================
|
|
53
|
-
# iOS class
|
|
54
|
-
# https://developer.apple.com/documentation/uikit/uitableview
|
|
55
|
-
# ========================================
|
|
56
|
-
|
|
57
|
-
from rubicon.objc import ObjCClass
|
|
58
|
-
|
|
59
|
-
class ListView(ListViewBase, ViewBase):
|
|
60
|
-
def __init__(self, data: list = []) -> None:
|
|
61
|
-
super().__init__()
|
|
62
|
-
self.native_class = ObjCClass("UITableView")
|
|
63
|
-
self.native_instance = self.native_class.alloc().init()
|
|
64
|
-
self.set_data(data)
|
|
65
|
-
|
|
66
|
-
def set_data(self, data: list) -> None:
|
|
67
|
-
# Note: This is a simplified representation. Normally, you would need to create a UITableViewDataSource.
|
|
68
|
-
self.native_instance.reloadData()
|
|
69
|
-
|
|
70
|
-
def get_data(self) -> list:
|
|
71
|
-
# Note: This is a simplified representation.
|
|
72
|
-
# Normally, you would need to get data from the UITableViewDataSource.
|
|
73
|
-
return []
|
|
@@ -1,69 +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 MaterialActivityIndicatorViewBase(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/com/google/android/material/progressindicator/CircularProgressIndicator
|
|
29
|
-
# ========================================
|
|
30
|
-
|
|
31
|
-
from java import jclass
|
|
32
|
-
|
|
33
|
-
class MaterialActivityIndicatorView(MaterialActivityIndicatorViewBase, ViewBase):
|
|
34
|
-
def __init__(self, context) -> None:
|
|
35
|
-
super().__init__()
|
|
36
|
-
self.native_class = jclass("com.google.android.material.progressindicator.CircularProgressIndicator")
|
|
37
|
-
self.native_instance = self.native_class(context)
|
|
38
|
-
self.native_instance.setIndeterminate(True)
|
|
39
|
-
|
|
40
|
-
def start_animating(self) -> None:
|
|
41
|
-
# self.native_instance.setVisibility(android.view.View.VISIBLE)
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
def stop_animating(self) -> None:
|
|
45
|
-
# self.native_instance.setVisibility(android.view.View.GONE)
|
|
46
|
-
return
|
|
47
|
-
|
|
48
|
-
else:
|
|
49
|
-
# ========================================
|
|
50
|
-
# iOS class
|
|
51
|
-
# https://developer.apple.com/documentation/uikit/uiactivityindicatorview
|
|
52
|
-
# ========================================
|
|
53
|
-
|
|
54
|
-
from rubicon.objc import ObjCClass
|
|
55
|
-
|
|
56
|
-
class MaterialActivityIndicatorView(MaterialActivityIndicatorViewBase, ViewBase):
|
|
57
|
-
def __init__(self) -> None:
|
|
58
|
-
super().__init__()
|
|
59
|
-
self.native_class = ObjCClass("UIActivityIndicatorView")
|
|
60
|
-
self.native_instance = self.native_class.alloc().initWithActivityIndicatorStyle_(
|
|
61
|
-
0
|
|
62
|
-
) # 0: UIActivityIndicatorViewStyleLarge
|
|
63
|
-
self.native_instance.hidesWhenStopped = True
|
|
64
|
-
|
|
65
|
-
def start_animating(self) -> None:
|
|
66
|
-
self.native_instance.startAnimating()
|
|
67
|
-
|
|
68
|
-
def stop_animating(self) -> None:
|
|
69
|
-
self.native_instance.stopAnimating()
|
pythonnative/material_button.py
DELETED
|
@@ -1,65 +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 MaterialButtonBase(ABC):
|
|
12
|
-
@abstractmethod
|
|
13
|
-
def __init__(self) -> None:
|
|
14
|
-
super().__init__()
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def set_title(self, title: str) -> None:
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
@abstractmethod
|
|
21
|
-
def get_title(self) -> str:
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if IS_ANDROID:
|
|
26
|
-
# ========================================
|
|
27
|
-
# Android class
|
|
28
|
-
# https://developer.android.com/reference/com/google/android/material/button/MaterialButton
|
|
29
|
-
# ========================================
|
|
30
|
-
|
|
31
|
-
from java import jclass
|
|
32
|
-
|
|
33
|
-
class MaterialButton(MaterialButtonBase, ViewBase):
|
|
34
|
-
def __init__(self, context, title: str = "") -> None:
|
|
35
|
-
super().__init__()
|
|
36
|
-
self.native_class = jclass("com.google.android.material.button.MaterialButton")
|
|
37
|
-
self.native_instance = self.native_class(context)
|
|
38
|
-
self.set_title(title)
|
|
39
|
-
|
|
40
|
-
def set_title(self, title: str) -> None:
|
|
41
|
-
self.native_instance.setText(title)
|
|
42
|
-
|
|
43
|
-
def get_title(self) -> str:
|
|
44
|
-
return self.native_instance.getText().toString()
|
|
45
|
-
|
|
46
|
-
else:
|
|
47
|
-
# ========================================
|
|
48
|
-
# iOS class
|
|
49
|
-
# https://developer.apple.com/documentation/uikit/uibutton
|
|
50
|
-
# ========================================
|
|
51
|
-
|
|
52
|
-
from rubicon.objc import ObjCClass
|
|
53
|
-
|
|
54
|
-
class MaterialButton(MaterialButtonBase, ViewBase):
|
|
55
|
-
def __init__(self, title: str = "") -> None:
|
|
56
|
-
super().__init__()
|
|
57
|
-
self.native_class = ObjCClass("UIButton") # Apple does not have a direct equivalent for MaterialButton
|
|
58
|
-
self.native_instance = self.native_class.alloc().init()
|
|
59
|
-
self.set_title(title)
|
|
60
|
-
|
|
61
|
-
def set_title(self, title: str) -> None:
|
|
62
|
-
self.native_instance.setTitle_forState_(title, 0)
|
|
63
|
-
|
|
64
|
-
def get_title(self) -> str:
|
|
65
|
-
return self.native_instance.titleForState_(0)
|
|
@@ -1,85 +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 MaterialDatePickerBase(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) -> None:
|
|
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/com/google/android/material/datepicker/MaterialDatePicker
|
|
29
|
-
# ========================================
|
|
30
|
-
|
|
31
|
-
from java import jclass
|
|
32
|
-
|
|
33
|
-
class MaterialDatePicker(MaterialDatePickerBase, ViewBase):
|
|
34
|
-
def __init__(self, year: int = 0, month: int = 0, day: int = 0) -> None:
|
|
35
|
-
super().__init__()
|
|
36
|
-
self.native_class = jclass("com.google.android.material.datepicker.MaterialDatePicker")
|
|
37
|
-
self.builder = self.native_class.Builder.datePicker()
|
|
38
|
-
self.set_date(year, month, day)
|
|
39
|
-
self.native_instance = self.builder.build()
|
|
40
|
-
|
|
41
|
-
def set_date(self, year: int, month: int, day: int) -> None:
|
|
42
|
-
# MaterialDatePicker uses milliseconds since epoch to set date
|
|
43
|
-
from java.util import Calendar
|
|
44
|
-
|
|
45
|
-
cal = Calendar.getInstance()
|
|
46
|
-
cal.set(year, month, day)
|
|
47
|
-
milliseconds = cal.getTimeInMillis()
|
|
48
|
-
self.builder.setSelection(milliseconds)
|
|
49
|
-
|
|
50
|
-
def get_date(self) -> tuple:
|
|
51
|
-
# Convert selection (milliseconds since epoch) back to a date
|
|
52
|
-
from java.util import Calendar
|
|
53
|
-
|
|
54
|
-
cal = Calendar.getInstance()
|
|
55
|
-
cal.setTimeInMillis(self.native_instance.getSelection())
|
|
56
|
-
return (
|
|
57
|
-
cal.get(Calendar.YEAR),
|
|
58
|
-
cal.get(Calendar.MONTH),
|
|
59
|
-
cal.get(Calendar.DAY_OF_MONTH),
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
else:
|
|
63
|
-
# ========================================
|
|
64
|
-
# iOS class
|
|
65
|
-
# https://developer.apple.com/documentation/uikit/uidatepicker
|
|
66
|
-
# ========================================
|
|
67
|
-
|
|
68
|
-
from datetime import datetime
|
|
69
|
-
|
|
70
|
-
from rubicon.objc import ObjCClass
|
|
71
|
-
|
|
72
|
-
class MaterialDatePicker(MaterialDatePickerBase, ViewBase):
|
|
73
|
-
def __init__(self, year: int = 0, month: int = 0, day: int = 0) -> None:
|
|
74
|
-
super().__init__()
|
|
75
|
-
self.native_class = ObjCClass("UIDatePicker")
|
|
76
|
-
self.native_instance = self.native_class.alloc().init()
|
|
77
|
-
self.set_date(year, month, day)
|
|
78
|
-
|
|
79
|
-
def set_date(self, year: int, month: int, day: int) -> None:
|
|
80
|
-
date = datetime(year, month, day)
|
|
81
|
-
self.native_instance.setDate_(date)
|
|
82
|
-
|
|
83
|
-
def get_date(self) -> tuple:
|
|
84
|
-
date = self.native_instance.date()
|
|
85
|
-
return date.year, date.month, date.day
|
|
@@ -1,66 +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 MaterialProgressViewBase(ABC):
|
|
12
|
-
@abstractmethod
|
|
13
|
-
def __init__(self) -> None:
|
|
14
|
-
super().__init__()
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def set_progress(self, progress: float) -> None:
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
@abstractmethod
|
|
21
|
-
def get_progress(self) -> float:
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if IS_ANDROID:
|
|
26
|
-
# ========================================
|
|
27
|
-
# Android class
|
|
28
|
-
# https://developer.android.com/reference/com/google/android/material/progressindicator/LinearProgressIndicator
|
|
29
|
-
# ========================================
|
|
30
|
-
|
|
31
|
-
from java import jclass
|
|
32
|
-
|
|
33
|
-
class MaterialProgressView(MaterialProgressViewBase, ViewBase):
|
|
34
|
-
def __init__(self, context) -> None:
|
|
35
|
-
super().__init__()
|
|
36
|
-
self.native_class = jclass("com.google.android.material.progressindicator.LinearProgressIndicator")
|
|
37
|
-
self.native_instance = self.native_class(context)
|
|
38
|
-
self.native_instance.setIndeterminate(False)
|
|
39
|
-
|
|
40
|
-
def set_progress(self, progress: float) -> None:
|
|
41
|
-
self.native_instance.setProgress(int(progress * 100))
|
|
42
|
-
|
|
43
|
-
def get_progress(self) -> float:
|
|
44
|
-
return self.native_instance.getProgress() / 100.0
|
|
45
|
-
|
|
46
|
-
else:
|
|
47
|
-
# ========================================
|
|
48
|
-
# iOS class
|
|
49
|
-
# https://developer.apple.com/documentation/uikit/uiprogressview
|
|
50
|
-
# ========================================
|
|
51
|
-
|
|
52
|
-
from rubicon.objc import ObjCClass
|
|
53
|
-
|
|
54
|
-
class MaterialProgressView(MaterialProgressViewBase, ViewBase):
|
|
55
|
-
def __init__(self) -> None:
|
|
56
|
-
super().__init__()
|
|
57
|
-
self.native_class = ObjCClass("UIProgressView")
|
|
58
|
-
self.native_instance = self.native_class.alloc().initWithProgressViewStyle_(
|
|
59
|
-
0
|
|
60
|
-
) # 0: UIProgressViewStyleDefault
|
|
61
|
-
|
|
62
|
-
def set_progress(self, progress: float) -> None:
|
|
63
|
-
self.native_instance.setProgress_animated_(progress, False)
|
|
64
|
-
|
|
65
|
-
def get_progress(self) -> float:
|
|
66
|
-
return self.native_instance.progress()
|