pythonnative 0.26.0__py3-none-any.whl → 0.28.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.
@@ -307,6 +307,9 @@ class Reconciler:
307
307
  # Transaction state for the in-flight pass.
308
308
  self._ops: List[Mutation] = []
309
309
  self._created: List[VNode] = []
310
+ # ``(tag, frame)`` pairs whose ``on_layout`` should fire after
311
+ # the layout pass commits (frames are only queued on change).
312
+ self._pending_layout_events: List[Tuple[int, Tuple[float, float, float, float]]] = []
310
313
  # Function-component VNodes whose own state changed since the
311
314
  # last flush, keyed by ``id`` to dedupe while keeping a strong
312
315
  # reference. Drained by
@@ -485,6 +488,7 @@ class Reconciler:
485
488
  if self._tree is not None:
486
489
  self._run_layout()
487
490
  self._flush_ops()
491
+ self._dispatch_layout_events()
488
492
 
489
493
  # ------------------------------------------------------------------
490
494
  # Back handlers (use_back_handler)
@@ -610,6 +614,7 @@ class Reconciler:
610
614
  self._fix_tree_links()
611
615
  self._run_layout()
612
616
  self._flush_ops()
617
+ self._dispatch_layout_events()
613
618
  self._flush_layout_effects()
614
619
  self._flush_ops()
615
620
  self._flush_passive_effects()
@@ -2216,6 +2221,8 @@ class Reconciler:
2216
2221
  ref._pn_frame = frame
2217
2222
  except Exception:
2218
2223
  pass
2224
+ if vnode.element.props and "on_layout" in vnode.element.props:
2225
+ self._pending_layout_events.append((vnode.tag, frame))
2219
2226
  child_offset_x = 0.0
2220
2227
  child_offset_y = 0.0
2221
2228
  else:
@@ -2225,6 +2232,27 @@ class Reconciler:
2225
2232
  for child in layout_node.children:
2226
2233
  self._collect_frames(child, child_offset_x, child_offset_y)
2227
2234
 
2235
+ def _dispatch_layout_events(self) -> None:
2236
+ """Fire queued ``on_layout`` callbacks after frames were applied.
2237
+
2238
+ Runs post-commit (alongside layout effects), so callbacks may
2239
+ set state; the resulting re-render is scheduled normally.
2240
+ """
2241
+ if not self._pending_layout_events:
2242
+ return
2243
+ from .events import dispatch_event
2244
+
2245
+ pending, self._pending_layout_events = self._pending_layout_events, []
2246
+ for tag, frame in pending:
2247
+ try:
2248
+ dispatch_event(
2249
+ tag,
2250
+ "on_layout",
2251
+ {"x": frame[0], "y": frame[1], "width": frame[2], "height": frame[3]},
2252
+ )
2253
+ except Exception as exc:
2254
+ diagnostics.report_error(exc, phase="event")
2255
+
2228
2256
  # ------------------------------------------------------------------
2229
2257
  # Hot-reload support
2230
2258
  # ------------------------------------------------------------------
pythonnative/style.py CHANGED
@@ -230,6 +230,16 @@ KeyboardType = Literal[
230
230
  ]
231
231
  AutoCapitalize = Literal["none", "sentences", "words", "characters"]
232
232
  ReturnKeyType = Literal["default", "done", "go", "next", "send", "search"]
233
+ PointerEvents = Literal["auto", "none", "box_none", "box_only"]
234
+ """Touch-handling mode for a view and its subtree:
235
+
236
+ - ``"auto"``: the view and its children receive touches (default).
237
+ - ``"none"``: neither the view nor its children receive touches;
238
+ touches pass through to whatever is underneath.
239
+ - ``"box_none"``: the view itself ignores touches but its children
240
+ still receive them (decorative overlays with interactive content).
241
+ - ``"box_only"``: the view receives touches but its children do not.
242
+ """
233
243
 
234
244
 
235
245
  # ======================================================================
@@ -331,6 +341,10 @@ class Style(TypedDict, total=False):
331
341
  # --- Visual: borders ---
332
342
  border_width: float
333
343
  border_radius: float
344
+ border_top_left_radius: float
345
+ border_top_right_radius: float
346
+ border_bottom_left_radius: float
347
+ border_bottom_right_radius: float
334
348
  border_top_width: float
335
349
  border_right_width: float
336
350
  border_bottom_width: float
@@ -361,6 +375,10 @@ class Style(TypedDict, total=False):
361
375
  opacity: float
362
376
  transform: TransformSpec
363
377
 
378
+ # --- Interaction & stacking ---
379
+ z_index: int
380
+ pointer_events: PointerEvents
381
+
364
382
 
365
383
  StyleProp = Union[Style, Dict[str, Any], List[Optional[Union[Style, Dict[str, Any]]]], None]
366
384
  """Public type for the ``style`` parameter on every component factory.
@@ -665,6 +683,7 @@ __all__ = [
665
683
  "JustifyContent",
666
684
  "KeyboardType",
667
685
  "Overflow",
686
+ "PointerEvents",
668
687
  "Position",
669
688
  "ReturnKeyType",
670
689
  "ScaleType",
@@ -56,6 +56,10 @@ dependencies {
56
56
  implementation 'androidx.recyclerview:recyclerview:1.3.2'
57
57
  // Pull-to-refresh (ScrollView's refresh_control prop)
58
58
  implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
59
+ // SecureStore (EncryptedSharedPreferences)
60
+ implementation 'androidx.security:security-crypto:1.1.0'
61
+ // Biometrics (BiometricPrompt)
62
+ implementation 'androidx.biometric:biometric:1.1.0'
59
63
  // AndroidX Navigation for Fragment-based navigation
60
64
  implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7'
61
65
  implementation 'androidx.navigation:navigation-ui-ktx:2.7.7'
@@ -2,6 +2,10 @@
2
2
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
3
  xmlns:tools="http://schemas.android.com/tools">
4
4
 
5
+ <!-- Runtime-gated on Android 13+ (API 33); requested by the
6
+ pythonnative notifications module before posting. -->
7
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
8
+
5
9
  <application
6
10
  android:allowBackup="true"
7
11
  android:dataExtractionRules="@xml/data_extraction_rules"
@@ -1,8 +1,12 @@
1
1
  package com.pythonnative.android_template
2
2
 
3
+ import android.content.Context
3
4
  import android.content.Intent
4
5
  import android.graphics.Color
5
6
  import android.graphics.Typeface
7
+ import android.net.ConnectivityManager
8
+ import android.net.Network
9
+ import android.net.NetworkCapabilities
6
10
  import android.os.Bundle
7
11
  import android.util.Log
8
12
  import android.util.TypedValue
@@ -15,6 +19,7 @@ import com.chaquo.python.android.AndroidPlatform
15
19
  class MainActivity : AppCompatActivity() {
16
20
  private val TAG = javaClass.simpleName
17
21
  private var pythonReady = false
22
+ private var networkCallback: ConnectivityManager.NetworkCallback? = null
18
23
 
19
24
  override fun onCreate(savedInstanceState: Bundle?) {
20
25
  super.onCreate(savedInstanceState)
@@ -47,6 +52,21 @@ class MainActivity : AppCompatActivity() {
47
52
 
48
53
  // A cold start from a deep link carries the URL on the launch intent.
49
54
  intent?.dataString?.let { dispatchUrl(it) }
55
+
56
+ registerNetworkCallback()
57
+ }
58
+
59
+ override fun onDestroy() {
60
+ super.onDestroy()
61
+ networkCallback?.let {
62
+ try {
63
+ (getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager)
64
+ .unregisterNetworkCallback(it)
65
+ } catch (e: Exception) {
66
+ Log.e("PythonNative", "unregisterNetworkCallback failed", e)
67
+ }
68
+ networkCallback = null
69
+ }
50
70
  }
51
71
 
52
72
  override fun onNewIntent(intent: Intent) {
@@ -83,6 +103,46 @@ class MainActivity : AppCompatActivity() {
83
103
  }
84
104
  }
85
105
 
106
+ // MARK: - NetInfo forwarding
107
+
108
+ // Live connectivity updates. The callback must be a NetworkCallback
109
+ // subclass, which Chaquopy's dynamic_proxy can't create from Python
110
+ // (interfaces only), so the registration lives here and forwards
111
+ // into the pythonnative net_info module.
112
+ private fun registerNetworkCallback() {
113
+ if (!pythonReady || networkCallback != null) return
114
+ try {
115
+ val manager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
116
+ val callback = object : ConnectivityManager.NetworkCallback() {
117
+ override fun onAvailable(network: Network) = dispatchNetInfo()
118
+ override fun onLost(network: Network) = dispatchNetInfo()
119
+ override fun onCapabilitiesChanged(
120
+ network: Network,
121
+ capabilities: NetworkCapabilities
122
+ ) = dispatchNetInfo()
123
+ }
124
+ manager.registerDefaultNetworkCallback(callback)
125
+ networkCallback = callback
126
+ } catch (e: Exception) {
127
+ Log.e("PythonNative", "registerDefaultNetworkCallback failed", e)
128
+ }
129
+ }
130
+
131
+ private fun dispatchNetInfo() {
132
+ // NetworkCallback fires on a ConnectivityManager binder thread;
133
+ // hop to the main thread before crossing into Python.
134
+ runOnUiThread {
135
+ if (!pythonReady) return@runOnUiThread
136
+ try {
137
+ Python.getInstance()
138
+ .getModule("pythonnative.native_modules.net_info")
139
+ .callAttr("dispatch_android_change")
140
+ } catch (e: Exception) {
141
+ Log.e("PythonNative", "dispatch_android_change failed", e)
142
+ }
143
+ }
144
+ }
145
+
86
146
  // MARK: - Deep links
87
147
 
88
148
  private fun dispatchUrl(url: String) {
@@ -0,0 +1,50 @@
1
+ package com.pythonnative.android_template
2
+
3
+ import android.content.Context
4
+ import android.view.MotionEvent
5
+ import android.widget.FrameLayout
6
+
7
+ /**
8
+ * Container `FrameLayout` with React Native-style `pointer_events`
9
+ * semantics. Python's Android view handlers create these for flex
10
+ * containers and drive the mode via [setPointerEventsMode]:
11
+ *
12
+ * - `"auto"` (default): normal dispatch; the view and its children
13
+ * both receive touches.
14
+ * - `"none"`: neither the view nor its children receive touches; the
15
+ * event falls through to whatever sits underneath.
16
+ * - `"box_none"`: children receive touches, but the view itself never
17
+ * intercepts or consumes them (the Python side also mutes the
18
+ * view's own touch listeners).
19
+ * - `"box_only"`: the view receives touches and its children don't;
20
+ * every event in the subtree is intercepted at this level.
21
+ *
22
+ * Interception can't be expressed from Python because Chaquopy can't
23
+ * subclass `ViewGroup`, so this class owns the two overrides and
24
+ * exposes the mode as a plain setter.
25
+ */
26
+ class PNFrameLayout(context: Context) : FrameLayout(context) {
27
+ private var pointerEventsMode: String = "auto"
28
+
29
+ /** Set the pointer-events mode; `null` restores `"auto"`. */
30
+ fun setPointerEventsMode(mode: String?) {
31
+ pointerEventsMode = mode ?: "auto"
32
+ }
33
+
34
+ override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
35
+ if (pointerEventsMode == "none") {
36
+ // Declining the whole dispatch lets the event pass through
37
+ // to views underneath, matching RN's "none".
38
+ return false
39
+ }
40
+ return super.dispatchTouchEvent(ev)
41
+ }
42
+
43
+ override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
44
+ return when (pointerEventsMode) {
45
+ "box_only" -> true
46
+ "box_none" -> false
47
+ else -> super.onInterceptTouchEvent(ev)
48
+ }
49
+ }
50
+ }
@@ -2,6 +2,11 @@
2
2
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
3
  <plist version="1.0">
4
4
  <dict>
5
+ <!-- PythonNative's StatusBar element drives the bar through the legacy
6
+ UIApplication setters, which UIKit only honors when view-controller-based
7
+ status bar appearance is turned off. -->
8
+ <key>UIViewControllerBasedStatusBarAppearance</key>
9
+ <false/>
5
10
  <key>UIApplicationSceneManifest</key>
6
11
  <dict>
7
12
  <key>UIApplicationSupportsMultipleScenes</key>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonnative
3
- Version: 0.26.0
3
+ Version: 0.28.0
4
4
  Summary: Cross-platform native UI toolkit for Android and iOS
5
5
  Author: Owen Carey
6
6
  License: MIT License
@@ -110,8 +110,8 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
110
110
  - **Typed `style` prop:** Pass all visual and layout properties through a single `style` dict, fully described by the `pn.Style` `TypedDict` and the ergonomic `pn.style(...)` helper for IDE autocomplete and static checking. Compose reusable styles with `StyleSheet`.
111
111
  - **Cross-platform flexbox engine:** A pure-Python, Yoga-style layout engine computes frames once and applies them to native views, so `flex`, `padding`, `aspect_ratio`, and `position: "absolute"` produce the same geometry on Android and iOS.
112
112
  - **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation. Each commit lands as **one batched transaction** of mutation ops, and event callbacks are routed through a tag-based registry so re-renders that only change closures cost zero native calls. State updates re-render **locally**: only the component whose state changed (and its subtree) re-runs, and unchanged leaves reuse cached intrinsic measurements, so deep UIs stay responsive instead of re-rendering the whole app from the root on every tap.
113
- - **Native-driven animations:** The `Animated` API (timing / spring / decay, awaitable or fire-and-forget) hands animations to Core Animation and `ViewPropertyAnimator` whenever possible, so no Python code runs per frame; a pure-Python ticker covers the rest.
114
- - **Native gesture system:** Attach `Tap`, `LongPress`, `Pan`, `Swipe`, `Pinch`, and `Rotation` recognizers to any view via the `gestures=` prop, backed by `UIGestureRecognizer` on iOS and a unit-testable pure-Python arbiter on Android and desktop.
113
+ - **Native-driven animations:** The `Animated` API (timing / spring / decay / loop / stagger, awaitable or fire-and-forget) hands animations to Core Animation and `ViewPropertyAnimator` whenever possible, so no Python code runs per frame; a pure-Python ticker covers the rest. `interpolate`, arithmetic operators on animated nodes, `Animated.event` scroll binding, and `diff_clamp` cover the scroll-driven patterns (collapsing headers, parallax) that define native feel.
114
+ - **Native gesture system:** Attach `Tap`, `LongPress`, `Pan`, `Swipe`, `Fling`, `Pinch`, and `Rotation` recognizers to any view via the `gestures=` prop, backed by `UIGestureRecognizer` on iOS and a unit-testable pure-Python arbiter on Android and desktop. Compose them with `Race`, `Exclusive`, and `Simultaneous` for cross-gesture arbitration (single vs. double tap, drag vs. long press).
115
115
  - **Virtualized lists:** `FlatList` / `SectionList` window their rows in Python over the platform scroll view: uniform, exact, or measured variable heights, grids, headers/footers, infinite scroll, and an imperative scroll controller, identical on every platform.
116
116
  - **Direct native bindings:** Python calls platform APIs directly through Chaquopy and rubicon-objc, with no JavaScript bridge.
117
117
  - **Custom-component SDK:** Wrap any platform widget as a first-class element with type-checked props via `pythonnative.sdk` (`Props`, `@native_component`, `element_factory`). Plugins distributed on PyPI auto-register through the `pythonnative.handlers` entry-point group.
@@ -1,13 +1,13 @@
1
- pythonnative/__init__.py,sha256=8g6jcrxEL0JkYye7C4AAYqoDUiI5Wyte3JmLJqT6v-Y,8680
1
+ pythonnative/__init__.py,sha256=cKoregrvgUaM43CDPb7jwsUNTa9Rs7Wh1t7Z8yQeLfE,8680
2
2
  pythonnative/_ios_log.py,sha256=Oi7V28VxcVoZyrpAirvLeEmUW18McqnU87V4d37Zzlw,2582
3
3
  pythonnative/alerts.py,sha256=mIANysFlaHwL5EqKnvNcyiJN9rGiZi9XDrD9Jpz1RFM,9340
4
- pythonnative/animated.py,sha256=OzDqG9ijkxF0rfU0glmgmGikbVB1s5ExoWndy74EhBw,36214
4
+ pythonnative/animated.py,sha256=A4IOBf_GD6lUn0H8ArFH6URf0-m0PG__8uaxcw6-ECE,60373
5
5
  pythonnative/appearance.py,sha256=vMkDRIz9ptaprMmlPmiYJLVwrDslfnc1bhwyE27M2ZI,3891
6
- pythonnative/components.py,sha256=xmJFHw88xPzUQQGeVVhujrIiNLQiQTBZZkPxOD8iWoA,108436
6
+ pythonnative/components.py,sha256=nhUgNmM8q-rIBHTLeH5cf8AfsnSfjkdTewkWVifkOy8,111097
7
7
  pythonnative/diagnostics.py,sha256=x33RG_kWTInuVcfQRTQZfA1ZGDk3lkjZemIfX0IEJS4,7992
8
8
  pythonnative/element.py,sha256=jbCMPiVq4oRgbSAbKdltBJ1BU6Aom1qKoc6-FsbpJ74,2902
9
9
  pythonnative/events.py,sha256=EFYz8HxVOTA3soAe0Z9P2gZN9ShLjXhKH7I34DmnNbM,7895
10
- pythonnative/gestures.py,sha256=6qe_s3Cv2M5_V-_PgAQ5y9QbYV812B0xVmh8dRDHYMY,29940
10
+ pythonnative/gestures.py,sha256=1gTiii-ROosOcmsglfffmQL8CBNq26CF-2uqQpEjdR0,46464
11
11
  pythonnative/hooks.py,sha256=tpMHxESLndaI_PXHNOcV_4B_u7ZzijQtSXH8_RU5kko,65422
12
12
  pythonnative/hot_reload.py,sha256=2HI6u-fc4JRudc35BAe8RXmPIXLWh1imoH4fMVqu_Ks,25502
13
13
  pythonnative/images.py,sha256=JFjBJdZzZoQmAOfQ7QHqi7dYJ75XTs3u2lweQHGbdPc,6466
@@ -18,16 +18,16 @@ pythonnative/net.py,sha256=8D7EyEC8-JkYxlrtVfTDApOGzzdcA4P4kaCdYBBZI8E,8082
18
18
  pythonnative/platform.py,sha256=WtjxR04CqVhSnjJu-3upk8bwXYaSWr2N0MOVoNov-h0,4994
19
19
  pythonnative/platform_metrics.py,sha256=1r1kMbgS9LcVTbdpP5qRD4oHEvw70te5BXEyd_16Ihc,8961
20
20
  pythonnative/preview.py,sha256=RoZv1s142GWj9xpg9v5Kh-0YuuhpEfwwb_JdnzboRLw,19355
21
- pythonnative/reconciler.py,sha256=6tzn5CsGvGypTnQ7sglEimfrdl7K3dP9W464n9naWZU,96412
21
+ pythonnative/reconciler.py,sha256=DAgGS-iEDTnJ7t_GtZ41XbLiToFaHkdBIEqLhwksBXU,97689
22
22
  pythonnative/runtime.py,sha256=m4MllJcApoor822LrceIWNLa2YPbd5lgeijQd3yqp0c,25701
23
23
  pythonnative/screen.py,sha256=Z0jYl_ZfZkde_Kel2m7kGMNEQesHQudshvI5WmXLvhU,83246
24
24
  pythonnative/storage.py,sha256=DNhRJWkT_iwb8lb-8YgTx2P_BHnYkOePLeOPPxcvREc,11983
25
- pythonnative/style.py,sha256=-XP1vbqiTEkQraFF0JknZLHIzVsou-GUhrKz5zQ7vVk,20030
25
+ pythonnative/style.py,sha256=yL0v7V_Y7r_M22rlq3SwjqSvXPrSAgIewM7Bq9ufzY0,20791
26
26
  pythonnative/suspense.py,sha256=IxWGXFP3Odriy0uQe9zhrNrObdKer0_WT6v9Vi8Vatg,14665
27
27
  pythonnative/utils.py,sha256=-hwe_YS19ebpjeygdl3dGeVsYzO4G74rYD53svSi0rI,7593
28
28
  pythonnative/virtual_rows.py,sha256=4YK3CeZobW-6F6GCXzGNFfmOaAiigmH4HXtqjYDRbyU,5056
29
29
  pythonnative/cli/__init__.py,sha256=NM1psvKe8jT0vzp8Ak4MMoygZz4P_msk5g-YEsY8xLk,232
30
- pythonnative/cli/pn.py,sha256=-bFLj77OmnFymfo9kdcJk_JaZDoq8CxQwK8l98exl60,34498
30
+ pythonnative/cli/pn.py,sha256=Vej6NiT3N_PoNrEZ-Z94o38m-IaoRi9KYx8Gk2IrQTg,34697
31
31
  pythonnative/native_modules/__init__.py,sha256=pgigpHuzT-rqwcjlwJvu93_4L8Nozal1HJid0S_JlmM,2636
32
32
  pythonnative/native_modules/app_state.py,sha256=CKAwDQIwoGElSLE3l7Bekk0qRbFVFOTSuSCBybumZEk,2742
33
33
  pythonnative/native_modules/battery.py,sha256=-lJu8LURw-yEObXUyhNq_jHFDa1_33lgzbJzXaGqUL4,4429
@@ -38,16 +38,16 @@ pythonnative/native_modules/file_system.py,sha256=ucO-Z36S1mDyZ-B0qG-HJrf17m3t1W
38
38
  pythonnative/native_modules/haptics.py,sha256=GXbwRe-lofQOjL6TCjoQAsb6L4xR1BzhxN7-oeEL5KI,5967
39
39
  pythonnative/native_modules/linking.py,sha256=kghghDXL1-rGp5q0rQgFVsMiJLo5MH32Zh6p6Txpb60,6908
40
40
  pythonnative/native_modules/location.py,sha256=0PrZ3wfjgsC2IKvGiS1GZusOPYsTojl3t2rEDrDraoU,8134
41
- pythonnative/native_modules/net_info.py,sha256=TwumrIAyGIMLAvI4INQYQWULWz6-_ME67ZFOTxPzjyc,5178
42
- pythonnative/native_modules/notifications.py,sha256=X1407ca6eDWDVgQNve4eFcIkSjxkDHoZeZtQtJifoXk,12046
41
+ pythonnative/native_modules/net_info.py,sha256=Qr2mcULW2ZHV0gfh5A42pF-t8W6w4YR-CIgEQPOSKcM,7650
42
+ pythonnative/native_modules/notifications.py,sha256=vbcYM89CjbftNdFtP2IlPAGBTx3LVK0jXgWLGrdn5bY,13250
43
43
  pythonnative/native_modules/permissions.py,sha256=yP627uvGzqg21LiV0WNvn-HOfGDDGtCj6xvf8W7O4l4,7874
44
44
  pythonnative/native_modules/secure_store.py,sha256=PsnUwHzUPt-CzCAwM6BhidOBi9yofRD2uNtQIqAGofU,5953
45
45
  pythonnative/native_modules/share.py,sha256=I20y7WBMAak8yPGxnU_S4kdNLk51HHYLjlEPd5D3TVc,4803
46
46
  pythonnative/native_views/__init__.py,sha256=93v7pt0_7f8BWqOiwSvlq20F1oJLfCnmQBvLlCDA-Xk,15340
47
- pythonnative/native_views/android.py,sha256=5AIziFPIOI4YOajChbThIu6YSzRIu9jO_HIBxLf668Q,141579
47
+ pythonnative/native_views/android.py,sha256=V_B6wmRo8Pl-u_K4ktiomzo0-38H0bG8YdxDOXbzgNo,155152
48
48
  pythonnative/native_views/base.py,sha256=NFDlEIoKCINzcVkf2uobT9TgujPb1RClLS3TzwH72MY,9668
49
- pythonnative/native_views/desktop.py,sha256=Y5IwGFq3vpLZcqiUHF4_b6ulLkfOSFfCjA86dR_dylM,63763
50
- pythonnative/native_views/ios.py,sha256=RYk6UZhxSzRQgAQeq3qM4-5Otl3aM5KBqM9aqo9Is_s,189915
49
+ pythonnative/native_views/desktop.py,sha256=UOTGmI1AdAd-PzEuQ6r1gMQk9aQoLHIScJCBoahoY7Y,94046
50
+ pythonnative/native_views/ios.py,sha256=cZNc5F9q01WLWhjNJu-24EZDK5SvtSuuSc3mxJL4OOI,211334
51
51
  pythonnative/project/__init__.py,sha256=kAhWLONs53H1L7xVtczLmzYcQSOOkdRZTAJnIMhpBts,2064
52
52
  pythonnative/project/android.py,sha256=ynRQwVvv1trFB2eFaUv38-48q4m0_Z4cTbAFEOiKnhE,19797
53
53
  pythonnative/project/builder.py,sha256=TTN_ymdSyF4wVtSRRwOnSmc91LMn_g_M7_jTI0NtbVU,23946
@@ -65,14 +65,15 @@ pythonnative/templates/android_template/gradle.properties,sha256=REPaKLRfQiiVfIV
65
65
  pythonnative/templates/android_template/gradlew,sha256=YxNShxF6Hm0SyEWA8fScYdG6AiGOzShmBgXpf5dufWU,5766
66
66
  pythonnative/templates/android_template/gradlew.bat,sha256=xGonx5AHdG3lkisXq7YjDWStixujrRWF7lxlQ8KpsSk,2674
67
67
  pythonnative/templates/android_template/settings.gradle,sha256=GKZiYUYWsaXxaiKOB65xnOs4jLmf0rhvI_3f8x0ic-o,333
68
- pythonnative/templates/android_template/app/build.gradle,sha256=ofKayIPkSfQ8S5K-nAo4De2RcHEzFaEPzd6gAoFdd4s,1999
68
+ pythonnative/templates/android_template/app/build.gradle,sha256=DRXz9t1iDzjsU0ZMr2mkO0l_EQtojompT3SToAdSZVM,2200
69
69
  pythonnative/templates/android_template/app/proguard-rules.pro,sha256=Vv2WDPIl9spA-YKxOl27DYvD394T_3ZCKCXGBw0KGJA,750
70
70
  pythonnative/templates/android_template/app/src/androidTest/java/com/pythonnative/android_template/ExampleInstrumentedTest.kt,sha256=Am8Yla3i1eR_ac5FVgPU_RsuMrCbyT79h1BcajGE-zI,693
71
- pythonnative/templates/android_template/app/src/main/AndroidManifest.xml,sha256=q4P2cNNy0N1YssiHVKMynb8AdCkIGFhyVT31IOzRCgo,1039
72
- pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt,sha256=s-sN96WslbC3Jcb8Gm-k3xLKoqCe2m2tcmW8K-BfTh8,3734
71
+ pythonnative/templates/android_template/app/src/main/AndroidManifest.xml,sha256=BYJG1s2BZKY-WenCpgWYpHFUiioB9LGHAdoNV0ry9cE,1245
72
+ pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt,sha256=GW7jFHzUB2YB_9To_eOfqr3f9R5jCKMantyKAjVS0Xw,6144
73
73
  pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/Navigator.kt,sha256=mDfzKTTXRP-zbSnfIPxAYyjtr9_IyyQwXM-dovcfVbg,1723
74
74
  pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PNAccessibilityDelegate.kt,sha256=R2PC6BA3VCaKET0XV33tXTFf4Ht9udvvLu9TT_RfWp4,1819
75
75
  pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PNBorderDrawable.kt,sha256=ejdFhpzn0-2TZa0nvG41r2m0xoejU2fXXuJSmO6tnBU,2205
76
+ pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PNFrameLayout.kt,sha256=DLozfPlPPCnv4bUgFR39Lw3Nf7CQbaEWz3TaVobJ6qo,1888
76
77
  pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PNVirtualListView.java,sha256=1ve74nvOFqsduyaLOGPb8Sd9Jrwz-sELRB9y1NMN1AI,6072
77
78
  pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt,sha256=pMxpHiguY8MToTZaMKwEF88xaGh-zLqcfYy1g5DV6eI,6051
78
79
  pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml,sha256=7UI8c6b0Ck0pCfCQHmBSezqAfNWeG1WTvKrhgIscYyE,5606
@@ -102,7 +103,7 @@ pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar,sha256
102
103
  pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties,sha256=nG5CWg_8OmJISSdiSxhYMPnob2ji-O7t0vYmSsW48vc,232
103
104
  pythonnative/templates/ios_template/ios_template/AppDelegate.swift,sha256=zF6b8VTLPlF4RhsceQHtyJyIDDMSK4A9eDf-fsPcPyU,1937
104
105
  pythonnative/templates/ios_template/ios_template/BridgingHeader.h,sha256=JwlbCXMf3xsSrZYhTbW-F6JJw7xrXkA1W7ctc6Qc2Nw,332
105
- pythonnative/templates/ios_template/ios_template/Info.plist,sha256=C7OzxBUcFwoATAwUiMIe5lHQcCugdtss8xEUYoJu5ZQ,639
106
+ pythonnative/templates/ios_template/ios_template/Info.plist,sha256=9EPyWeNNhKOwEMqaFFPTTmJdWA8iCe9zZvWqYC1yn6Q,902
106
107
  pythonnative/templates/ios_template/ios_template/PythonRuntime.swift,sha256=HGEiC0i5aM75dpBZfO7EyDq3OmJUNGP0astWWmZ7dUg,15706
107
108
  pythonnative/templates/ios_template/ios_template/SceneDelegate.swift,sha256=74bnoTZ4mSRiGGM4HA8d_zM0wvpCueHjcf4Q7Uhm-ng,2083
108
109
  pythonnative/templates/ios_template/ios_template/ViewController.swift,sha256=pxVLREzkimfMz5yOZkHlVMuOdu0pE-Ltxp4dYFvcPS4,5578
@@ -115,9 +116,9 @@ pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/x
115
116
  pythonnative/templates/ios_template/ios_templateTests/ios_templateTests.swift,sha256=YnwzZx7yXB13xKAXEGNgz17VuhWeqkHTRTtBJ2Vu3_E,1238
116
117
  pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITests.swift,sha256=HLRr3cmouRqQeXG13WrZ2XSAmgMgCsNXfZpbwkxeFcs,1385
117
118
  pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITestsLaunchTests.swift,sha256=f5JrG0uVtLMeJQy26Yyz7Om-JUkT220osqcbeIVkj2g,815
118
- pythonnative-0.26.0.dist-info/licenses/LICENSE,sha256=A69iG7TIAe6KkGQf6xoVHkc5JSZtOr5eRSvC5iuivnI,1067
119
- pythonnative-0.26.0.dist-info/METADATA,sha256=lGTQ4j3hGUGXOBE3u2Tl-n__pt4Wqcqyo2EiwS84BPg,11541
120
- pythonnative-0.26.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
121
- pythonnative-0.26.0.dist-info/entry_points.txt,sha256=iUtDawWSAJAEyWTycpZxDuYz73ol31butpzDIEAgPO0,48
122
- pythonnative-0.26.0.dist-info/top_level.txt,sha256=kT4SEATY2ywzrZ2Pgea6_zxyym44Q_PbOsUoOYjJLFE,13
123
- pythonnative-0.26.0.dist-info/RECORD,,
119
+ pythonnative-0.28.0.dist-info/licenses/LICENSE,sha256=A69iG7TIAe6KkGQf6xoVHkc5JSZtOr5eRSvC5iuivnI,1067
120
+ pythonnative-0.28.0.dist-info/METADATA,sha256=nSbCHw3bxTSAKbBHn_52uknD35eTKr9_F1OD9Rcyqt4,11895
121
+ pythonnative-0.28.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
122
+ pythonnative-0.28.0.dist-info/entry_points.txt,sha256=iUtDawWSAJAEyWTycpZxDuYz73ol31butpzDIEAgPO0,48
123
+ pythonnative-0.28.0.dist-info/top_level.txt,sha256=kT4SEATY2ywzrZ2Pgea6_zxyym44Q_PbOsUoOYjJLFE,13
124
+ pythonnative-0.28.0.dist-info/RECORD,,