pythonnative 0.20.0__py3-none-any.whl → 0.22.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.
Files changed (33) hide show
  1. pythonnative/__init__.py +14 -3
  2. pythonnative/animated.py +420 -135
  3. pythonnative/cli/pn.py +450 -956
  4. pythonnative/components.py +519 -235
  5. pythonnative/events.py +210 -0
  6. pythonnative/gestures.py +875 -0
  7. pythonnative/layout.py +463 -149
  8. pythonnative/mutations.py +130 -0
  9. pythonnative/native_views/__init__.py +161 -97
  10. pythonnative/native_views/android.py +1050 -1124
  11. pythonnative/native_views/base.py +108 -18
  12. pythonnative/native_views/desktop.py +460 -417
  13. pythonnative/native_views/ios.py +1918 -1916
  14. pythonnative/project/__init__.py +68 -0
  15. pythonnative/project/android.py +504 -0
  16. pythonnative/project/builder.py +555 -0
  17. pythonnative/project/config.py +642 -0
  18. pythonnative/project/doctor.py +233 -0
  19. pythonnative/project/icons.py +247 -0
  20. pythonnative/project/ios.py +344 -0
  21. pythonnative/project/permissions.py +343 -0
  22. pythonnative/project/runtime_assets.py +272 -0
  23. pythonnative/reconciler.py +540 -470
  24. pythonnative/screen.py +5 -2
  25. pythonnative/sdk/_components.py +2 -2
  26. pythonnative/templates/android_template/app/build.gradle +2 -0
  27. {pythonnative-0.20.0.dist-info → pythonnative-0.22.0.dist-info}/METADATA +10 -2
  28. {pythonnative-0.20.0.dist-info → pythonnative-0.22.0.dist-info}/RECORD +32 -21
  29. pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PNVirtualListView.java +0 -129
  30. {pythonnative-0.20.0.dist-info → pythonnative-0.22.0.dist-info}/WHEEL +0 -0
  31. {pythonnative-0.20.0.dist-info → pythonnative-0.22.0.dist-info}/entry_points.txt +0 -0
  32. {pythonnative-0.20.0.dist-info → pythonnative-0.22.0.dist-info}/licenses/LICENSE +0 -0
  33. {pythonnative-0.20.0.dist-info → pythonnative-0.22.0.dist-info}/top_level.txt +0 -0
@@ -21,20 +21,32 @@ from typing import Any, Dict, Tuple, Union
21
21
  class ViewHandler:
22
22
  """Protocol implemented by every native-view handler.
23
23
 
24
- A `ViewHandler` knows how to create, update, and re-parent native
25
- views of one element type. The reconciler dispatches through the
26
- [`NativeViewRegistry`][pythonnative.native_views.NativeViewRegistry];
27
- handlers never need to know about `Element` or `VNode`.
28
-
29
- Subclasses must override [`create`][pythonnative.native_views.base.ViewHandler.create]
30
- and [`update`][pythonnative.native_views.base.ViewHandler.update].
31
- Container handlers override the child-management methods; leaf
32
- handlers can leave them as no-ops. Handlers whose intrinsic size
33
- depends on content (text, buttons, images) override
24
+ A `ViewHandler` knows how to create, update, re-parent, and destroy
25
+ native views of one element type. The reconciler never calls a
26
+ handler directly — it emits a batch of mutation ops
27
+ (`pythonnative.mutations`) that the
28
+ [`NativeViewRegistry`][pythonnative.native_views.NativeViewRegistry]
29
+ applies by dispatching to handlers. Handlers never need to know
30
+ about `Element` or `VNode`.
31
+
32
+ Event contract: props delivered to
33
+ [`create`][pythonnative.native_views.base.ViewHandler.create] /
34
+ [`update`][pythonnative.native_views.base.ViewHandler.update]
35
+ contain **no Python callables**. The set of event names wired on
36
+ the element arrives under the ``_pn_events`` key (see
37
+ [`event_names`][pythonnative.events.event_names]); handlers wire
38
+ platform listeners once at create time and forward firings through
39
+ [`dispatch_event`][pythonnative.events.dispatch_event] using the
40
+ tag passed to ``create``.
41
+
42
+ Subclasses must override ``create`` and ``update``. Container
43
+ handlers override the child-management methods; leaf handlers can
44
+ leave them as no-ops. Handlers whose intrinsic size depends on
45
+ content (text, buttons, images) override
34
46
  [`measure_intrinsic`][pythonnative.native_views.base.ViewHandler.measure_intrinsic].
35
47
  """
36
48
 
37
- def create(self, props: Dict[str, Any]) -> Any:
49
+ def create(self, tag: int, props: Dict[str, Any]) -> Any:
38
50
  """Create a fresh native view and apply initial *visual* props.
39
51
 
40
52
  Layout-related props (``width``, ``height``, ``flex``, ``padding``,
@@ -43,7 +55,10 @@ class ViewHandler:
43
55
  so handlers should ignore them here.
44
56
 
45
57
  Args:
46
- props: Initial props dict.
58
+ tag: The reconciler-assigned identity for this view. Used
59
+ when dispatching events back into Python.
60
+ props: Initial props dict (callable-free; event names under
61
+ ``_pn_events``).
47
62
 
48
63
  Returns:
49
64
  The platform-native view object.
@@ -66,15 +81,26 @@ class ViewHandler:
66
81
  """
67
82
  raise NotImplementedError
68
83
 
69
- def add_child(self, parent: Any, child: Any) -> None:
70
- """Append `child` to `parent`. No-op for leaf handlers."""
84
+ def insert_child(self, parent: Any, child: Any, index: int) -> None:
85
+ """Ensure `child` sits at `index` among `parent`'s children.
86
+
87
+ Must be **move-aware**: when `child` is already attached to
88
+ `parent`, reposition it instead of attaching twice. Handlers
89
+ should clamp `index` to the current child count. No-op for
90
+ leaf handlers.
91
+ """
71
92
 
72
93
  def remove_child(self, parent: Any, child: Any) -> None:
73
- """Remove `child` from `parent`. No-op for leaf handlers."""
94
+ """Remove `child` from `parent` without destroying it. No-op for leaf handlers."""
74
95
 
75
- def insert_child(self, parent: Any, child: Any, index: int) -> None:
76
- """Insert `child` at `index`. Defaults to appending."""
77
- self.add_child(parent, child)
96
+ def destroy(self, native_view: Any) -> None:
97
+ """Release platform resources owned by ``native_view``.
98
+
99
+ Called exactly once when the reconciler unmounts the view.
100
+ The default is a no-op; override to detach listeners, cancel
101
+ in-flight work, or destroy widgets that the platform doesn't
102
+ garbage-collect.
103
+ """
78
104
 
79
105
  def set_frame(self, native_view: Any, x: float, y: float, width: float, height: float) -> None:
80
106
  """Position and size ``native_view`` relative to its parent.
@@ -119,6 +145,70 @@ class ViewHandler:
119
145
  """
120
146
  return (0.0, 0.0)
121
147
 
148
+ def command(self, native_view: Any, name: str, args: Dict[str, Any]) -> Any:
149
+ """Execute an imperative command (e.g. ``"scroll_to_offset"``).
150
+
151
+ Commands are the escape hatch for one-shot imperative actions
152
+ that don't fit declarative props — scrolling, focusing,
153
+ flashing indicators. Unknown commands should be ignored.
154
+
155
+ Args:
156
+ native_view: The platform-native view.
157
+ name: Command name.
158
+ args: Command arguments.
159
+
160
+ Returns:
161
+ An optional command-specific result.
162
+ """
163
+ return None
164
+
165
+ def set_animated_property(self, native_view: Any, prop_name: str, value: Any) -> None:
166
+ """Apply one frame of a Python-driven animation immediately.
167
+
168
+ This is the fallback path used by the desktop preview and by
169
+ animations the platform cannot drive natively. ``prop_name``
170
+ is one of ``opacity``, ``background_color``, ``translate_x``,
171
+ ``translate_y``, ``scale``, ``scale_x``, ``scale_y``,
172
+ ``rotate``.
173
+ """
174
+
175
+ def start_animation(
176
+ self,
177
+ native_view: Any,
178
+ anim_id: int,
179
+ prop_name: str,
180
+ spec: Dict[str, Any],
181
+ ) -> bool:
182
+ """Start a natively-driven animation, if the platform supports it.
183
+
184
+ ``spec`` describes the animation::
185
+
186
+ {"kind": "timing", "from": 0.0, "to": 1.0,
187
+ "duration_ms": 300.0, "easing": "ease_in_out"}
188
+ {"kind": "spring", "from": ..., "to": ...,
189
+ "stiffness": 100.0, "damping": 10.0, "mass": 1.0,
190
+ "initial_velocity": 0.0}
191
+
192
+ Implementations must invoke
193
+ ``pythonnative.animated.native_animation_completed(anim_id, finished)``
194
+ when the animation completes or is cancelled.
195
+
196
+ Returns:
197
+ ``True`` when the animation was started natively. ``False``
198
+ tells the caller to fall back to the Python ticker (the
199
+ default).
200
+ """
201
+ return False
202
+
203
+ def cancel_animation(self, native_view: Any, anim_id: int) -> Any:
204
+ """Cancel a natively-driven animation.
205
+
206
+ Returns:
207
+ The property's current (presentation) value when the
208
+ platform can read it, else ``None``.
209
+ """
210
+ return None
211
+
122
212
 
123
213
  # ======================================================================
124
214
  # Color parsing