pythonnative 0.23.0__py3-none-any.whl → 0.24.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 +29 -50
- pythonnative/animated.py +1 -1
- pythonnative/cli/pn.py +3 -3
- pythonnative/components.py +250 -513
- pythonnative/diagnostics.py +214 -0
- pythonnative/element.py +5 -2
- pythonnative/events.py +13 -8
- pythonnative/hooks.py +413 -49
- pythonnative/hot_reload.py +9 -1
- pythonnative/native_views/android.py +78 -1
- pythonnative/native_views/desktop.py +38 -1
- pythonnative/native_views/ios.py +241 -7
- pythonnative/navigation.py +41 -17
- pythonnative/preview.py +43 -7
- pythonnative/reconciler.py +863 -441
- pythonnative/screen.py +324 -27
- pythonnative/storage.py +3 -3
- pythonnative/style.py +83 -0
- pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +22 -0
- {pythonnative-0.23.0.dist-info → pythonnative-0.24.0.dist-info}/METADATA +5 -4
- {pythonnative-0.23.0.dist-info → pythonnative-0.24.0.dist-info}/RECORD +25 -24
- {pythonnative-0.23.0.dist-info → pythonnative-0.24.0.dist-info}/WHEEL +0 -0
- {pythonnative-0.23.0.dist-info → pythonnative-0.24.0.dist-info}/entry_points.txt +0 -0
- {pythonnative-0.23.0.dist-info → pythonnative-0.24.0.dist-info}/licenses/LICENSE +0 -0
- {pythonnative-0.23.0.dist-info → pythonnative-0.24.0.dist-info}/top_level.txt +0 -0
pythonnative/preview.py
CHANGED
|
@@ -231,17 +231,13 @@ class DesktopApp:
|
|
|
231
231
|
host.on_pause()
|
|
232
232
|
except Exception:
|
|
233
233
|
pass
|
|
234
|
+
# ``on_destroy`` unmounts the host's reconciler: effect cleanups
|
|
235
|
+
# run, native widgets are destroyed, and event registrations are
|
|
236
|
+
# released (see ``screen._destroy_host``).
|
|
234
237
|
try:
|
|
235
238
|
host.on_destroy()
|
|
236
239
|
except Exception:
|
|
237
240
|
pass
|
|
238
|
-
reconciler = getattr(host, "_reconciler", None)
|
|
239
|
-
tree = getattr(reconciler, "_tree", None) if reconciler is not None else None
|
|
240
|
-
if reconciler is not None and tree is not None:
|
|
241
|
-
try:
|
|
242
|
-
reconciler._destroy_tree(tree)
|
|
243
|
-
except Exception:
|
|
244
|
-
pass
|
|
245
241
|
container = getattr(host, "_pn_container", None)
|
|
246
242
|
if container is not None:
|
|
247
243
|
try:
|
|
@@ -249,6 +245,29 @@ class DesktopApp:
|
|
|
249
245
|
except Exception:
|
|
250
246
|
pass
|
|
251
247
|
|
|
248
|
+
def teardown_all(self) -> None:
|
|
249
|
+
"""Destroy every screen on the stack (preview window closing)."""
|
|
250
|
+
while self._stack:
|
|
251
|
+
self._teardown(self._stack.pop())
|
|
252
|
+
|
|
253
|
+
def back_pressed(self) -> None:
|
|
254
|
+
"""Route a desktop back gesture (Escape) like a hardware back press.
|
|
255
|
+
|
|
256
|
+
``use_back_handler`` subscribers on the active screen get the
|
|
257
|
+
first chance to consume the event; otherwise the stack pops
|
|
258
|
+
(matching Android's default back behavior). At the root the
|
|
259
|
+
event is ignored.
|
|
260
|
+
"""
|
|
261
|
+
host = self.active_host()
|
|
262
|
+
if host is None:
|
|
263
|
+
return
|
|
264
|
+
try:
|
|
265
|
+
if host.on_back_pressed():
|
|
266
|
+
return
|
|
267
|
+
except Exception:
|
|
268
|
+
pass
|
|
269
|
+
self.pop_screen()
|
|
270
|
+
|
|
252
271
|
# -- viewport / resize --------------------------------------------
|
|
253
272
|
|
|
254
273
|
def resize(self, width: float, height: float) -> None:
|
|
@@ -391,6 +410,12 @@ def run_preview(
|
|
|
391
410
|
root_dir, watched = _resolve_paths(component_path, project_root, watch_dir)
|
|
392
411
|
_publish_desktop_color_scheme()
|
|
393
412
|
|
|
413
|
+
# The preview is inherently a development surface: turn on dev
|
|
414
|
+
# diagnostics (validation warnings, hook-order checks, RedBox).
|
|
415
|
+
from . import diagnostics
|
|
416
|
+
|
|
417
|
+
diagnostics.set_dev_mode(True)
|
|
418
|
+
|
|
394
419
|
root = tk.Tk()
|
|
395
420
|
root.title(title)
|
|
396
421
|
root.geometry(f"{int(width)}x{int(height)}")
|
|
@@ -414,6 +439,11 @@ def run_preview(
|
|
|
414
439
|
|
|
415
440
|
stage.bind("<Configure>", _on_configure)
|
|
416
441
|
|
|
442
|
+
# Escape acts as the desktop stand-in for the hardware back button:
|
|
443
|
+
# ``use_back_handler`` subscribers can intercept it, and otherwise
|
|
444
|
+
# the navigation stack pops.
|
|
445
|
+
root.bind("<Escape>", lambda _event: app.back_pressed())
|
|
446
|
+
|
|
417
447
|
watcher = _build_watcher(watched, root_dir, app, main_queue) if hot_reload else None
|
|
418
448
|
if watcher is not None:
|
|
419
449
|
watcher.start()
|
|
@@ -446,6 +476,12 @@ def run_preview(
|
|
|
446
476
|
watcher.stop()
|
|
447
477
|
except Exception:
|
|
448
478
|
pass
|
|
479
|
+
# Unmount every screen first so effect cleanups (timers, tasks,
|
|
480
|
+
# subscriptions) run before the Tk interpreter goes away.
|
|
481
|
+
try:
|
|
482
|
+
app.teardown_all()
|
|
483
|
+
except Exception:
|
|
484
|
+
pass
|
|
449
485
|
runtime_module.set_desktop_main_dispatch(None)
|
|
450
486
|
desktop_backend.clear_root_container()
|
|
451
487
|
try:
|