Skip to content

Commit 4c06b67

Browse files
committed
feat(components,utils)!: unify constructors; set Android context
1 parent d9dd821 commit 4c06b67

File tree

18 files changed

+139
-28
lines changed

18 files changed

+139
-28
lines changed

apps/pythonnative_demo/app/main_page.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ def __init__(self, native_instance):
77

88
def on_create(self):
99
super().on_create()
10-
stack_view = pn.StackView(self.native_instance)
10+
stack_view = pn.StackView()
1111
# list_data = ["item_{}".format(i) for i in range(100)]
1212
# list_view = pn.ListView(self.native_instance, list_data)
1313
# stack_view.add_view(list_view)
14-
button = pn.Button(self.native_instance, "Button")
14+
button = pn.Button("Button")
1515
button.set_on_click(lambda: self.navigate_to(""))
1616
# button.set_on_click(lambda: print("Button was clicked!"))
1717
stack_view.add_view(button)

apps/pythonnative_demo/app/second_page.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ def __init__(self, native_instance):
77

88
def on_create(self):
99
super().on_create()
10-
stack_view = pn.StackView(self.native_instance)
11-
label = pn.Label(self.native_instance, "Second page!")
10+
stack_view = pn.StackView()
11+
label = pn.Label("Second page!")
1212
stack_view.add_view(label)
1313
self.set_root_view(stack_view)
1414

docs/api/pythonnative.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
# pythonnative package
22

33
API reference will be generated here via mkdocstrings.
4+
5+
Key flags and helpers (0.2.0):
6+
7+
- `pythonnative.utils.IS_ANDROID`: platform flag with robust detection for Chaquopy/Android.
8+
- `pythonnative.utils.get_android_context()`: returns the current Android Activity/Context when running on Android.
9+
- `pythonnative.utils.set_android_context(ctx)`: set by `pythonnative.Page` on Android; you generally don’t call this directly.

docs/concepts/components.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
11
# Components
22

33
High-level overview of PythonNative components and how they map to native UI.
4+
5+
## Constructor pattern (0.2.0)
6+
7+
- All core components share a consistent, contextless constructor on both platforms.
8+
- On Android, a `Context` is acquired implicitly from the current `Activity` set by `pn.Page`.
9+
- On iOS, UIKit classes are allocated/initialized directly.
10+
11+
Examples:
12+
13+
```python
14+
import pythonnative as pn
15+
16+
class MainPage(pn.Page):
17+
def __init__(self, native_instance):
18+
super().__init__(native_instance)
19+
20+
def on_create(self):
21+
super().on_create()
22+
stack = pn.StackView()
23+
stack.add_view(pn.Label("Hello"))
24+
stack.add_view(pn.Button("Tap me"))
25+
stack.add_view(pn.TextField("initial"))
26+
self.set_root_view(stack)
27+
```
28+
29+
Notes:
30+
- `pn.Page` stores the Android `Activity` so components like `pn.Button()` and `pn.Label()` can construct their native counterparts.
31+
- If you construct views before the `Page` is created on Android, a runtime error will be raised because no `Context` is available.

docs/getting-started.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ pn --help
1010
- Scaffolds `app/`, `pythonnative.json`, `requirements.txt`, `.gitignore`
1111
- Run: `pn run android` or `pn run ios`
1212
- Uses bundled templates; copies your `app/` into the platform project
13+
- On Android, `pn.Page` provides the Activity context so components can be created without passing a context
1314
- Clean: `pn clean`
1415
- Removes the `build/` directory safely

src/pythonnative/activity_indicator_view.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from abc import ABC, abstractmethod
22

3-
from .utils import IS_ANDROID
3+
from .utils import IS_ANDROID, get_android_context
44
from .view import ViewBase
55

66
# ========================================
@@ -31,10 +31,11 @@ def stop_animating(self) -> None:
3131
from java import jclass
3232

3333
class ActivityIndicatorView(ActivityIndicatorViewBase, ViewBase):
34-
def __init__(self, context) -> None:
34+
def __init__(self) -> None:
3535
super().__init__()
3636
self.native_class = jclass("android.widget.ProgressBar")
3737
# self.native_instance = self.native_class(context, None, android.R.attr.progressBarStyleLarge)
38+
context = get_android_context()
3839
self.native_instance = self.native_class(context)
3940
self.native_instance.setIndeterminate(True)
4041

src/pythonnative/button.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from abc import ABC, abstractmethod
22
from typing import Callable
33

4-
from .utils import IS_ANDROID
4+
from .utils import IS_ANDROID, get_android_context
55
from .view import ViewBase
66

77
# ========================================
@@ -36,9 +36,10 @@ def set_on_click(self, callback: Callable[[], None]) -> None:
3636
from java import dynamic_proxy, jclass
3737

3838
class Button(ButtonBase, ViewBase):
39-
def __init__(self, context, title: str = "") -> None:
39+
def __init__(self, title: str = "") -> None:
4040
super().__init__()
4141
self.native_class = jclass("android.widget.Button")
42+
context = get_android_context()
4243
self.native_instance = self.native_class(context)
4344
self.set_title(title)
4445

src/pythonnative/cli/pn.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ def __init__(self, native_instance):
5353
5454
def on_create(self):
5555
super().on_create()
56-
stack = pn.StackView(self.native_instance)
57-
stack.add_view(pn.Label(self.native_instance, \"Hello from PythonNative!\"))
56+
stack = pn.StackView()
57+
stack.add_view(pn.Label(\"Hello from PythonNative!\"))
5858
self.set_root_view(stack)
5959
"""
6060
)

src/pythonnative/image_view.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from abc import ABC, abstractmethod
22

3-
from .utils import IS_ANDROID
3+
from .utils import IS_ANDROID, get_android_context
44
from .view import ViewBase
55

66
# ========================================
@@ -32,9 +32,10 @@ def get_image(self) -> str:
3232
from java import jclass
3333

3434
class ImageView(ImageViewBase, ViewBase):
35-
def __init__(self, context, image: str = "") -> None:
35+
def __init__(self, image: str = "") -> None:
3636
super().__init__()
3737
self.native_class = jclass("android.widget.ImageView")
38+
context = get_android_context()
3839
self.native_instance = self.native_class(context)
3940
if image:
4041
self.set_image(image)

src/pythonnative/label.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from abc import ABC, abstractmethod
22

3-
from .utils import IS_ANDROID
3+
from .utils import IS_ANDROID, get_android_context
44
from .view import ViewBase
55

66
# ========================================
@@ -31,9 +31,10 @@ def get_text(self) -> str:
3131
from java import jclass
3232

3333
class Label(LabelBase, ViewBase):
34-
def __init__(self, context, text: str = "") -> None:
34+
def __init__(self, text: str = "") -> None:
3535
super().__init__()
3636
self.native_class = jclass("android.widget.TextView")
37+
context = get_android_context()
3738
self.native_instance = self.native_class(context)
3839
self.set_text(text)
3940

0 commit comments

Comments
 (0)