pythonnative 0.40.0__cp313-cp313-win_amd64.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 (418) hide show
  1. pythonnative/__init__.py +411 -0
  2. pythonnative/_ios_log.py +92 -0
  3. pythonnative/_yoga.cp313-win_amd64.pyd +0 -0
  4. pythonnative/alerts.py +236 -0
  5. pythonnative/animated.py +1687 -0
  6. pythonnative/animation_graph.py +78 -0
  7. pythonnative/appearance.py +124 -0
  8. pythonnative/bootstrap.py +100 -0
  9. pythonnative/bridge/__init__.py +302 -0
  10. pythonnative/bridge/android.py +78 -0
  11. pythonnative/bridge/codec.py +170 -0
  12. pythonnative/bridge/commits.py +114 -0
  13. pythonnative/bridge/fake.py +243 -0
  14. pythonnative/bridge/ios.py +138 -0
  15. pythonnative/bridge/web.py +489 -0
  16. pythonnative/cli/__init__.py +7 -0
  17. pythonnative/cli/pn.py +1214 -0
  18. pythonnative/component.py +271 -0
  19. pythonnative/components/__init__.py +111 -0
  20. pythonnative/components/_base.py +166 -0
  21. pythonnative/components/controls.py +521 -0
  22. pythonnative/components/layout.py +518 -0
  23. pythonnative/components/lists.py +785 -0
  24. pythonnative/components/media.py +204 -0
  25. pythonnative/components/overlays.py +107 -0
  26. pythonnative/components/pressable.py +252 -0
  27. pythonnative/components/structural.py +167 -0
  28. pythonnative/components/text.py +291 -0
  29. pythonnative/devclient.py +824 -0
  30. pythonnative/devserver/__init__.py +34 -0
  31. pythonnative/devserver/server.py +718 -0
  32. pythonnative/devserver/static/animation_graph.js +82 -0
  33. pythonnative/devserver/static/bridge.js +147 -0
  34. pythonnative/devserver/static/colors.js +70 -0
  35. pythonnative/devserver/static/host.js +552 -0
  36. pythonnative/devserver/static/index.html +60 -0
  37. pythonnative/devserver/static/layout.js +85 -0
  38. pythonnative/devserver/static/preview.css +415 -0
  39. pythonnative/devserver/static/renderer.js +1994 -0
  40. pythonnative/devserver/static/shell.js +345 -0
  41. pythonnative/devserver/static/yoga/LICENSE +21 -0
  42. pythonnative/devserver/static/yoga/binaries/yoga-wasm-base64-esm.js +75 -0
  43. pythonnative/devserver/static/yoga/src/generated/YGEnums.d.ts +189 -0
  44. pythonnative/devserver/static/yoga/src/generated/YGEnums.js +211 -0
  45. pythonnative/devserver/static/yoga/src/generated/YGEnums.js.map +1 -0
  46. pythonnative/devserver/static/yoga/src/index.d.ts +12 -0
  47. pythonnative/devserver/static/yoga/src/index.js +16 -0
  48. pythonnative/devserver/static/yoga/src/index.js.map +1 -0
  49. pythonnative/devserver/static/yoga/src/load.d.ts +11 -0
  50. pythonnative/devserver/static/yoga/src/load.js +17 -0
  51. pythonnative/devserver/static/yoga/src/load.js.map +1 -0
  52. pythonnative/devserver/static/yoga/src/wrapAssembly.d.ts +155 -0
  53. pythonnative/devserver/static/yoga/src/wrapAssembly.js +125 -0
  54. pythonnative/devserver/static/yoga/src/wrapAssembly.js.map +1 -0
  55. pythonnative/devserver/watcher.py +267 -0
  56. pythonnative/devserver/ws.py +421 -0
  57. pythonnative/diagnostics.py +241 -0
  58. pythonnative/element.py +159 -0
  59. pythonnative/equality.py +19 -0
  60. pythonnative/events.py +231 -0
  61. pythonnative/gestures.py +1333 -0
  62. pythonnative/hooks.py +1621 -0
  63. pythonnative/hosts/__init__.py +63 -0
  64. pythonnative/hosts/base.py +596 -0
  65. pythonnative/hosts/native.py +302 -0
  66. pythonnative/hot_reload.py +585 -0
  67. pythonnative/layout.py +328 -0
  68. pythonnative/mutations.py +142 -0
  69. pythonnative/native/android/build.gradle +52 -0
  70. pythonnative/native/android/gradle.properties +3 -0
  71. pythonnative/native/android/settings.gradle +12 -0
  72. pythonnative/native/android/src/main/AndroidManifest.xml +11 -0
  73. pythonnative/native/android/src/main/cpp/CMakeLists.txt +9 -0
  74. pythonnative/native/android/src/main/cpp/yoga_jni.cpp +52 -0
  75. pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeModules.kt +5 -0
  76. pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeProps.kt +3705 -0
  77. pythonnative/native/android/src/main/java/com/pythonnative/generated/PNContracts.kt +129 -0
  78. pythonnative/native/android/src/main/java/com/pythonnative/runtime/PNBridge.kt +261 -0
  79. pythonnative/native/android/src/main/java/com/pythonnative/runtime/PythonHost.kt +20 -0
  80. pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/AnimationGraph.kt +108 -0
  81. pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/AnimationSpecs.kt +141 -0
  82. pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/PNAnimator.kt +257 -0
  83. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/CommitState.kt +106 -0
  84. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/JsonUtil.kt +175 -0
  85. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/MainThread.kt +40 -0
  86. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNLog.kt +33 -0
  87. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNRegistry.kt +82 -0
  88. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNTransaction.kt +80 -0
  89. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/TransactionApplier.kt +117 -0
  90. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/ViewRegistry.kt +74 -0
  91. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/BuiltinComponents.kt +37 -0
  92. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ButtonManager.kt +32 -0
  93. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ComponentManager.kt +213 -0
  94. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ContainerManagers.kt +69 -0
  95. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ControlManagers.kt +186 -0
  96. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/DatePickerManager.kt +123 -0
  97. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ImageLoader.kt +141 -0
  98. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ImageManager.kt +162 -0
  99. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ModalManager.kt +134 -0
  100. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PNColor.kt +201 -0
  101. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PickerManager.kt +86 -0
  102. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PortalManager.kt +55 -0
  103. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PressableManager.kt +122 -0
  104. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScreenStackManager.kt +110 -0
  105. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScrollViewManager.kt +214 -0
  106. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/SegmentedControlManager.kt +113 -0
  107. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/StatusBarManager.kt +52 -0
  108. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TabBarManager.kt +131 -0
  109. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TextInputManager.kt +250 -0
  110. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TextManager.kt +233 -0
  111. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ViewStyler.kt +355 -0
  112. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/VirtualListManager.kt +159 -0
  113. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/WebViewManager.kt +149 -0
  114. pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureArbiter.kt +233 -0
  115. pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureCoordinator.kt +127 -0
  116. pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureRecognizers.kt +527 -0
  117. pythonnative/native/android/src/main/java/com/pythonnative/runtime/layout/NativeLayout.kt +145 -0
  118. pythonnative/native/android/src/main/java/com/pythonnative/runtime/layout/YogaNode.kt +29 -0
  119. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/BuiltinModules.kt +73 -0
  120. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/DeviceModules.kt +316 -0
  121. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/HostModule.kt +61 -0
  122. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/MediaModules.kt +200 -0
  123. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/NativeModule.kt +158 -0
  124. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/NotificationsModule.kt +100 -0
  125. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/PermissionsModule.kt +99 -0
  126. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/StorageModules.kt +89 -0
  127. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/SystemModules.kt +178 -0
  128. pythonnative/native/android/src/main/java/com/pythonnative/runtime/plugins/GeneratedPlugins.kt +16 -0
  129. pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/PNScreenFragment.kt +188 -0
  130. pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/ScreenRegistry.kt +80 -0
  131. pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNAccessibilityDelegate.kt +48 -0
  132. pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNBorderDrawable.kt +76 -0
  133. pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNEditText.kt +18 -0
  134. pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNFrameLayout.kt +49 -0
  135. pythonnative/native/android/src/test/java/com/pythonnative/runtime/AnimationSpecsTest.kt +75 -0
  136. pythonnative/native/android/src/test/java/com/pythonnative/runtime/GestureArbiterTest.kt +197 -0
  137. pythonnative/native/android/src/test/java/com/pythonnative/runtime/PNColorTest.kt +47 -0
  138. pythonnative/native/android/src/test/java/com/pythonnative/runtime/PNTransactionTest.kt +78 -0
  139. pythonnative/native/android/src/test/java/com/pythonnative/runtime/PromiseTest.kt +89 -0
  140. pythonnative/native/ios/Package.swift +23 -0
  141. pythonnative/native/ios/Sources/PythonNativeKit/Animation/PNAnimationGraph.swift +199 -0
  142. pythonnative/native/ios/Sources/PythonNativeKit/Animation/PNAnimator.swift +312 -0
  143. pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNBridge.swift +255 -0
  144. pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNCommit.swift +104 -0
  145. pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNRegistry.swift +142 -0
  146. pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNTransaction.swift +166 -0
  147. pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNViewRegistry.swift +53 -0
  148. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNButtonManagers.swift +207 -0
  149. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNColor.swift +173 -0
  150. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNComponentManager.swift +183 -0
  151. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNContainerView.swift +56 -0
  152. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNControlManagers.swift +281 -0
  153. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNImageManager.swift +222 -0
  154. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNOverlayManagers.swift +243 -0
  155. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNPressableManager.swift +114 -0
  156. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNScreenStackManager.swift +107 -0
  157. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNScrollViewManager.swift +197 -0
  158. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTabBarManager.swift +106 -0
  159. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTextInputManager.swift +297 -0
  160. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTextManager.swift +230 -0
  161. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTransform.swift +82 -0
  162. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewManager.swift +86 -0
  163. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewState.swift +87 -0
  164. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewStyler.swift +340 -0
  165. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNVirtualListManager.swift +155 -0
  166. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNWebViewManager.swift +124 -0
  167. pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeModules.swift +1 -0
  168. pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeProps.swift +3775 -0
  169. pythonnative/native/ios/Sources/PythonNativeKit/Generated/PNContracts.swift +46 -0
  170. pythonnative/native/ios/Sources/PythonNativeKit/Gestures/PNGestureCoordinator.swift +260 -0
  171. pythonnative/native/ios/Sources/PythonNativeKit/Layout/PNLayout.swift +173 -0
  172. pythonnative/native/ios/Sources/PythonNativeKit/Modules/AlertModule.swift +92 -0
  173. pythonnative/native/ios/Sources/PythonNativeKit/Modules/HostModule.swift +80 -0
  174. pythonnative/native/ios/Sources/PythonNativeKit/Modules/LifecycleModules.swift +174 -0
  175. pythonnative/native/ios/Sources/PythonNativeKit/Modules/MediaModules.swift +177 -0
  176. pythonnative/native/ios/Sources/PythonNativeKit/Modules/PNNativeModule.swift +168 -0
  177. pythonnative/native/ios/Sources/PythonNativeKit/Modules/PermissionModules.swift +266 -0
  178. pythonnative/native/ios/Sources/PythonNativeKit/Modules/SystemModules.swift +251 -0
  179. pythonnative/native/ios/Sources/PythonNativeKit/Plugins/PNPluginRegistration.swift +8 -0
  180. pythonnative/native/ios/Sources/PythonNativeKit/Screens/PNScreenRegistry.swift +46 -0
  181. pythonnative/native/ios/Sources/PythonNativeKit/Screens/PNViewController.swift +237 -0
  182. pythonnative/native/ios/Sources/PythonNativeKit/Support/PNCompat.swift +46 -0
  183. pythonnative/native/ios/Sources/PythonNativeKit/Support/PNJSON.swift +173 -0
  184. pythonnative/native/ios/Sources/PythonNativeKit/Support/PNLog.swift +47 -0
  185. pythonnative/native/ios/Sources/PythonNativeKit/Support/PNWindow.swift +51 -0
  186. pythonnative/native/ios/Tests/PythonNativeKitTests/PNAnimationGraphTests.swift +26 -0
  187. pythonnative/native/ios/Tests/PythonNativeKitTests/PNColorTests.swift +50 -0
  188. pythonnative/native/ios/Tests/PythonNativeKitTests/PNCommitTests.swift +86 -0
  189. pythonnative/native/ios/Tests/PythonNativeKitTests/PNGestureTests.swift +101 -0
  190. pythonnative/native/ios/Tests/PythonNativeKitTests/PNManagerTests.swift +126 -0
  191. pythonnative/native/ios/Tests/PythonNativeKitTests/PNModuleTests.swift +111 -0
  192. pythonnative/native/ios/Tests/PythonNativeKitTests/PNTransactionTests.swift +91 -0
  193. pythonnative/native/yoga/LICENSE +21 -0
  194. pythonnative/native/yoga/Package.swift +9 -0
  195. pythonnative/native/yoga/VENDORED.md +2 -0
  196. pythonnative/native/yoga/include/PNStyle.h +10 -0
  197. pythonnative/native/yoga/include/module.modulemap +5 -0
  198. pythonnative/native/yoga/include/yoga/YGConfig.h +158 -0
  199. pythonnative/native/yoga/include/yoga/YGEnums.h +142 -0
  200. pythonnative/native/yoga/include/yoga/YGMacros.h +99 -0
  201. pythonnative/native/yoga/include/yoga/YGNode.h +304 -0
  202. pythonnative/native/yoga/include/yoga/YGNodeLayout.h +35 -0
  203. pythonnative/native/yoga/include/yoga/YGNodeStyle.h +130 -0
  204. pythonnative/native/yoga/include/yoga/YGPixelGrid.h +29 -0
  205. pythonnative/native/yoga/include/yoga/YGValue.h +84 -0
  206. pythonnative/native/yoga/include/yoga/Yoga.h +21 -0
  207. pythonnative/native/yoga/python.cpp +16 -0
  208. pythonnative/native/yoga/style.cpp +272 -0
  209. pythonnative/native/yoga/yoga/CMakeLists.txt +41 -0
  210. pythonnative/native/yoga/yoga/YGConfig.cpp +92 -0
  211. pythonnative/native/yoga/yoga/YGConfig.h +158 -0
  212. pythonnative/native/yoga/yoga/YGEnums.cpp +262 -0
  213. pythonnative/native/yoga/yoga/YGEnums.h +142 -0
  214. pythonnative/native/yoga/yoga/YGMacros.h +99 -0
  215. pythonnative/native/yoga/yoga/YGNode.cpp +366 -0
  216. pythonnative/native/yoga/yoga/YGNode.h +304 -0
  217. pythonnative/native/yoga/yoga/YGNodeLayout.cpp +92 -0
  218. pythonnative/native/yoga/yoga/YGNodeLayout.h +35 -0
  219. pythonnative/native/yoga/yoga/YGNodeStyle.cpp +405 -0
  220. pythonnative/native/yoga/yoga/YGNodeStyle.h +130 -0
  221. pythonnative/native/yoga/yoga/YGPixelGrid.cpp +22 -0
  222. pythonnative/native/yoga/yoga/YGPixelGrid.h +29 -0
  223. pythonnative/native/yoga/yoga/YGValue.cpp +20 -0
  224. pythonnative/native/yoga/yoga/YGValue.h +84 -0
  225. pythonnative/native/yoga/yoga/Yoga.h +21 -0
  226. pythonnative/native/yoga/yoga/algorithm/AbsoluteLayout.cpp +563 -0
  227. pythonnative/native/yoga/yoga/algorithm/AbsoluteLayout.h +41 -0
  228. pythonnative/native/yoga/yoga/algorithm/Align.h +72 -0
  229. pythonnative/native/yoga/yoga/algorithm/Baseline.cpp +78 -0
  230. pythonnative/native/yoga/yoga/algorithm/Baseline.h +21 -0
  231. pythonnative/native/yoga/yoga/algorithm/BoundAxis.h +79 -0
  232. pythonnative/native/yoga/yoga/algorithm/Cache.cpp +121 -0
  233. pythonnative/native/yoga/yoga/algorithm/Cache.h +30 -0
  234. pythonnative/native/yoga/yoga/algorithm/CalculateLayout.cpp +2428 -0
  235. pythonnative/native/yoga/yoga/algorithm/CalculateLayout.h +38 -0
  236. pythonnative/native/yoga/yoga/algorithm/FlexDirection.h +120 -0
  237. pythonnative/native/yoga/yoga/algorithm/FlexLine.cpp +124 -0
  238. pythonnative/native/yoga/yoga/algorithm/FlexLine.h +75 -0
  239. pythonnative/native/yoga/yoga/algorithm/PixelGrid.cpp +132 -0
  240. pythonnative/native/yoga/yoga/algorithm/PixelGrid.h +29 -0
  241. pythonnative/native/yoga/yoga/algorithm/SizingMode.h +73 -0
  242. pythonnative/native/yoga/yoga/algorithm/TrailingPosition.h +44 -0
  243. pythonnative/native/yoga/yoga/config/Config.cpp +135 -0
  244. pythonnative/native/yoga/yoga/config/Config.h +92 -0
  245. pythonnative/native/yoga/yoga/debug/AssertFatal.cpp +53 -0
  246. pythonnative/native/yoga/yoga/debug/AssertFatal.h +29 -0
  247. pythonnative/native/yoga/yoga/debug/Log.cpp +107 -0
  248. pythonnative/native/yoga/yoga/debug/Log.h +34 -0
  249. pythonnative/native/yoga/yoga/enums/Align.h +47 -0
  250. pythonnative/native/yoga/yoga/enums/BoxSizing.h +40 -0
  251. pythonnative/native/yoga/yoga/enums/Dimension.h +40 -0
  252. pythonnative/native/yoga/yoga/enums/Direction.h +41 -0
  253. pythonnative/native/yoga/yoga/enums/Display.h +41 -0
  254. pythonnative/native/yoga/yoga/enums/Edge.h +47 -0
  255. pythonnative/native/yoga/yoga/enums/Errata.h +41 -0
  256. pythonnative/native/yoga/yoga/enums/ExperimentalFeature.h +39 -0
  257. pythonnative/native/yoga/yoga/enums/FlexDirection.h +42 -0
  258. pythonnative/native/yoga/yoga/enums/Gutter.h +41 -0
  259. pythonnative/native/yoga/yoga/enums/Justify.h +44 -0
  260. pythonnative/native/yoga/yoga/enums/LogLevel.h +44 -0
  261. pythonnative/native/yoga/yoga/enums/MeasureMode.h +41 -0
  262. pythonnative/native/yoga/yoga/enums/NodeType.h +40 -0
  263. pythonnative/native/yoga/yoga/enums/Overflow.h +41 -0
  264. pythonnative/native/yoga/yoga/enums/PhysicalEdge.h +21 -0
  265. pythonnative/native/yoga/yoga/enums/PositionType.h +41 -0
  266. pythonnative/native/yoga/yoga/enums/Unit.h +42 -0
  267. pythonnative/native/yoga/yoga/enums/Wrap.h +41 -0
  268. pythonnative/native/yoga/yoga/enums/YogaEnums.h +85 -0
  269. pythonnative/native/yoga/yoga/event/event.cpp +87 -0
  270. pythonnative/native/yoga/yoga/event/event.h +130 -0
  271. pythonnative/native/yoga/yoga/module.modulemap +21 -0
  272. pythonnative/native/yoga/yoga/node/CachedMeasurement.h +53 -0
  273. pythonnative/native/yoga/yoga/node/LayoutResults.cpp +48 -0
  274. pythonnative/native/yoga/yoga/node/LayoutResults.h +122 -0
  275. pythonnative/native/yoga/yoga/node/LayoutableChildren.h +148 -0
  276. pythonnative/native/yoga/yoga/node/Node.cpp +443 -0
  277. pythonnative/native/yoga/yoga/node/Node.h +337 -0
  278. pythonnative/native/yoga/yoga/numeric/Comparison.h +81 -0
  279. pythonnative/native/yoga/yoga/numeric/FloatOptional.h +93 -0
  280. pythonnative/native/yoga/yoga/style/SmallValueBuffer.h +133 -0
  281. pythonnative/native/yoga/yoga/style/Style.h +757 -0
  282. pythonnative/native/yoga/yoga/style/StyleLength.h +107 -0
  283. pythonnative/native/yoga/yoga/style/StyleValueHandle.h +98 -0
  284. pythonnative/native/yoga/yoga/style/StyleValuePool.h +127 -0
  285. pythonnative/native_modules/__init__.py +124 -0
  286. pythonnative/native_modules/app_state.py +99 -0
  287. pythonnative/native_modules/battery.py +75 -0
  288. pythonnative/native_modules/biometrics.py +42 -0
  289. pythonnative/native_modules/camera.py +65 -0
  290. pythonnative/native_modules/clipboard.py +46 -0
  291. pythonnative/native_modules/fallback.py +324 -0
  292. pythonnative/native_modules/file_system.py +145 -0
  293. pythonnative/native_modules/haptics.py +75 -0
  294. pythonnative/native_modules/linking.py +123 -0
  295. pythonnative/native_modules/location.py +75 -0
  296. pythonnative/native_modules/net_info.py +112 -0
  297. pythonnative/native_modules/notifications.py +129 -0
  298. pythonnative/native_modules/permissions.py +108 -0
  299. pythonnative/native_modules/registry.py +526 -0
  300. pythonnative/native_modules/secure_store.py +52 -0
  301. pythonnative/native_modules/share.py +51 -0
  302. pythonnative/native_views/__init__.py +375 -0
  303. pythonnative/native_views/base.py +316 -0
  304. pythonnative/native_views/bridge_backend.py +277 -0
  305. pythonnative/navigation/__init__.py +103 -0
  306. pythonnative/navigation/container.py +154 -0
  307. pythonnative/navigation/handle.py +540 -0
  308. pythonnative/navigation/hooks.py +133 -0
  309. pythonnative/navigation/host.py +58 -0
  310. pythonnative/navigation/linking.py +200 -0
  311. pythonnative/navigation/navigators.py +659 -0
  312. pythonnative/navigation/screen.py +149 -0
  313. pythonnative/navigation/state.py +269 -0
  314. pythonnative/net.py +248 -0
  315. pythonnative/platform.py +166 -0
  316. pythonnative/platform_metrics.py +252 -0
  317. pythonnative/preview.py +287 -0
  318. pythonnative/profiling.py +101 -0
  319. pythonnative/project/__init__.py +68 -0
  320. pythonnative/project/android.py +557 -0
  321. pythonnative/project/builder.py +817 -0
  322. pythonnative/project/config.py +773 -0
  323. pythonnative/project/deps.py +719 -0
  324. pythonnative/project/devices.py +304 -0
  325. pythonnative/project/doctor.py +283 -0
  326. pythonnative/project/fingerprint.py +171 -0
  327. pythonnative/project/icons.py +247 -0
  328. pythonnative/project/ios.py +325 -0
  329. pythonnative/project/lockfile.py +100 -0
  330. pythonnative/project/permissions.py +361 -0
  331. pythonnative/project/plugins.py +519 -0
  332. pythonnative/project/runtime_assets.py +183 -0
  333. pythonnative/py.typed +0 -0
  334. pythonnative/query.py +153 -0
  335. pythonnative/reconciler/__init__.py +29 -0
  336. pythonnative/reconciler/boundaries.py +375 -0
  337. pythonnative/reconciler/children.py +88 -0
  338. pythonnative/reconciler/core.py +1165 -0
  339. pythonnative/reconciler/layout_pass.py +393 -0
  340. pythonnative/reconciler/vnode.py +266 -0
  341. pythonnative/refresh.py +55 -0
  342. pythonnative/runtime.py +306 -0
  343. pythonnative/scheduler.py +159 -0
  344. pythonnative/sdk/__init__.py +153 -0
  345. pythonnative/sdk/_components.py +427 -0
  346. pythonnative/sdk/builtins.py +91 -0
  347. pythonnative/sdk/codegen.py +149 -0
  348. pythonnative/sdk/module_codegen.py +184 -0
  349. pythonnative/sdk/schema.py +224 -0
  350. pythonnative/sdk/templates/contracts.kt +46 -0
  351. pythonnative/sdk/templates/contracts.swift +46 -0
  352. pythonnative/storage.py +184 -0
  353. pythonnative/style.py +841 -0
  354. pythonnative/suspense.py +183 -0
  355. pythonnative/templates/android_template/app/build.gradle +75 -0
  356. pythonnative/templates/android_template/app/proguard-rules.pro +21 -0
  357. pythonnative/templates/android_template/app/src/androidTest/java/com/pythonnative/android_template/ExampleInstrumentedTest.kt +24 -0
  358. pythonnative/templates/android_template/app/src/debug/AndroidManifest.xml +7 -0
  359. pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +32 -0
  360. pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +130 -0
  361. pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +13 -0
  362. pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
  363. pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +30 -0
  364. pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml +10 -0
  365. pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +6 -0
  366. pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +6 -0
  367. pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
  368. pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
  369. pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
  370. pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
  371. pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
  372. pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
  373. pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
  374. pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
  375. pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
  376. pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
  377. pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +22 -0
  378. pythonnative/templates/android_template/app/src/main/res/values/colors.xml +5 -0
  379. pythonnative/templates/android_template/app/src/main/res/values/strings.xml +5 -0
  380. pythonnative/templates/android_template/app/src/main/res/values/themes.xml +9 -0
  381. pythonnative/templates/android_template/app/src/main/res/values-night/themes.xml +7 -0
  382. pythonnative/templates/android_template/app/src/main/res/xml/backup_rules.xml +13 -0
  383. pythonnative/templates/android_template/app/src/main/res/xml/data_extraction_rules.xml +19 -0
  384. pythonnative/templates/android_template/app/src/test/java/com/pythonnative/android_template/ExampleUnitTest.kt +17 -0
  385. pythonnative/templates/android_template/build.gradle +10 -0
  386. pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar +0 -0
  387. pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +6 -0
  388. pythonnative/templates/android_template/gradle.properties +23 -0
  389. pythonnative/templates/android_template/gradlew +185 -0
  390. pythonnative/templates/android_template/gradlew.bat +89 -0
  391. pythonnative/templates/android_template/settings.gradle +17 -0
  392. pythonnative/templates/ios_template/ios_template/AppDelegate.swift +51 -0
  393. pythonnative/templates/ios_template/ios_template/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  394. pythonnative/templates/ios_template/ios_template/Assets.xcassets/AppIcon.appiconset/Contents.json +13 -0
  395. pythonnative/templates/ios_template/ios_template/Assets.xcassets/Contents.json +6 -0
  396. pythonnative/templates/ios_template/ios_template/Base.lproj/LaunchScreen.storyboard +25 -0
  397. pythonnative/templates/ios_template/ios_template/BridgingHeader.h +14 -0
  398. pythonnative/templates/ios_template/ios_template/Info.plist +28 -0
  399. pythonnative/templates/ios_template/ios_template/PythonRuntime.swift +390 -0
  400. pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +61 -0
  401. pythonnative/templates/ios_template/ios_template/ViewController.swift +23 -0
  402. pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +745 -0
  403. pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  404. pythonnative/templates/ios_template/ios_templateTests/ios_templateTests.swift +36 -0
  405. pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITests.swift +41 -0
  406. pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITestsLaunchTests.swift +32 -0
  407. pythonnative/testing/__init__.py +53 -0
  408. pythonnative/testing/backend.py +276 -0
  409. pythonnative/testing/harness.py +369 -0
  410. pythonnative/utils.py +145 -0
  411. pythonnative-0.40.0.dist-info/DELVEWHEEL +2 -0
  412. pythonnative-0.40.0.dist-info/METADATA +150 -0
  413. pythonnative-0.40.0.dist-info/RECORD +418 -0
  414. pythonnative-0.40.0.dist-info/WHEEL +5 -0
  415. pythonnative-0.40.0.dist-info/entry_points.txt +2 -0
  416. pythonnative-0.40.0.dist-info/licenses/LICENSE +21 -0
  417. pythonnative-0.40.0.dist-info/top_level.txt +1 -0
  418. pythonnative.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
@@ -0,0 +1,277 @@
1
+ """Revisioned native view backend.
2
+
3
+ Each commit is validated, sent as a protocol-2 envelope, and acknowledged before
4
+ Python updates its native tag index. Rejected commits poison the surface until
5
+ it is remounted. Native events carry application, revision, sequence, and text
6
+ edit identities. NativeViewRef holds a live native tag rather than a UI object.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import math
12
+ import uuid
13
+ from typing import Any, Dict, List, Optional, Sequence, Tuple
14
+
15
+ from ..bridge import codec, get_transport
16
+ from ..bridge.commits import PROTOCOL_VERSION, CommitError, CommitState
17
+ from ..mutations import CreateOp, DestroyOp, Mutation, UpdateOp
18
+
19
+ __all__ = ["BridgeBackend", "NativeViewRef"]
20
+
21
+ _MEASURE_UNBOUNDED = 1e6
22
+
23
+
24
+ class NativeViewRef:
25
+ """Opaque handle to a native view living on the other side of the bridge.
26
+
27
+ Attributes:
28
+ tag: The reconciler-assigned tag; pass it to
29
+ ``Reconciler.dispatch_command`` or ``get_registry().command``.
30
+ type_name: The element type (``"Text"``, ``"ScrollView"``, ...).
31
+ """
32
+
33
+ __slots__ = ("tag", "type_name")
34
+
35
+ def __init__(self, tag: int, type_name: str) -> None:
36
+ self.tag = tag
37
+ self.type_name = type_name
38
+
39
+ def __repr__(self) -> str:
40
+ return f"<NativeViewRef {self.type_name} tag={self.tag}>"
41
+
42
+ def __int__(self) -> int:
43
+ return self.tag
44
+
45
+
46
+ class BridgeBackend:
47
+ """Registry protocol implementation that forwards to the native runtime."""
48
+
49
+ def __init__(self, transport: Any = None) -> None:
50
+ self._transport = transport
51
+ self._commit = CommitState(str(uuid.uuid4()), 1)
52
+ self._births: dict[int, int] = {}
53
+ self._event_sequences: dict[tuple[int, str], int] = {}
54
+ self._edit_revisions: dict[int, int] = {}
55
+ self._failed = False
56
+ self.on_layout: Any = None
57
+ self._types: Dict[int, str] = {}
58
+ self._refs: Dict[int, NativeViewRef] = {}
59
+ self._python_props: Dict[int, Dict[str, Any]] = {}
60
+ self._handlers: Dict[str, Any] = {}
61
+
62
+ @property
63
+ def transport(self) -> Any:
64
+ """The transport in use (resolved lazily on first access)."""
65
+ if self._transport is None:
66
+ self._transport = get_transport()
67
+ return self._transport
68
+
69
+ @property
70
+ def native_layout(self) -> bool:
71
+ """Whether layout runs beside the renderer's native widgets."""
72
+ return self.transport.name in {"ios", "android", "web"}
73
+
74
+ def compute_layout(self, roots: list[int], width: float, height: float) -> None:
75
+ """Compute native Yoga layout in one request, returning changed frames."""
76
+ raw = self.transport.call(
77
+ "Layout", "compute", codec.dumps({"call_id": 0, "args": {"roots": roots, "width": width, "height": height}})
78
+ )
79
+ result = codec.loads(raw)
80
+ if not isinstance(result, dict) or not result.get("ok"):
81
+ raise CommitError(f"Native layout failed: {result!r}")
82
+ if self.on_layout is not None:
83
+ self.on_layout(result.get("value", []))
84
+
85
+ # ------------------------------------------------------------------
86
+ # Registration (kept for protocol parity with NativeViewRegistry)
87
+ # ------------------------------------------------------------------
88
+
89
+ def register(self, type_name: str, handler: Any) -> None:
90
+ """Record a Python handler for diagnostics only.
91
+
92
+ On device, rendering is native; a Python ``ViewHandler`` can't
93
+ create platform views. The registration is kept so
94
+ ``handler_for`` can answer introspection questions and so the
95
+ SDK's install step doesn't fail, but it is never invoked.
96
+ """
97
+ self._handlers[type_name] = handler
98
+
99
+ def handler_for(self, type_name: str) -> Any:
100
+ """Return the diagnostic Python handler registered for ``type_name``."""
101
+ return self._handlers.get(type_name)
102
+
103
+ # ------------------------------------------------------------------
104
+ # Tag table
105
+ # ------------------------------------------------------------------
106
+
107
+ def resolve_view(self, tag: int) -> Optional[NativeViewRef]:
108
+ """Return the handle for ``tag`` (``None`` if the view is gone)."""
109
+ return self._refs.get(tag)
110
+
111
+ def type_of(self, tag: int) -> Optional[str]:
112
+ """Return the element type registered for ``tag``."""
113
+ return self._types.get(tag)
114
+
115
+ def live_view_count(self) -> int:
116
+ """Number of views currently alive on the native side."""
117
+ return len(self._types)
118
+
119
+ def python_props(self, tag: int) -> Dict[str, Any]:
120
+ """Props held Python-side for ``tag`` (callables never sent to native)."""
121
+ return self._python_props.get(tag, {})
122
+
123
+ # ------------------------------------------------------------------
124
+ # Commit channel
125
+ # ------------------------------------------------------------------
126
+
127
+ def apply_mutations(self, ops: Sequence[Mutation]) -> None:
128
+ """Serialize ``ops`` and apply them natively in one crossing."""
129
+ if not ops:
130
+ return
131
+ if self._failed:
132
+ raise CommitError("Native surface failed; remount the application with a new backend")
133
+ payload, sidecar = codec.encode_transaction(ops)
134
+ wire_ops = codec.loads(payload)
135
+ for op in wire_ops:
136
+ if op[0] == "u" and self._types.get(op[1]) == "TextInput" and "value" in op[2]:
137
+ op[2]["_pn_edit_revision"] = self._edit_revisions.get(op[1], 0)
138
+ envelope = {
139
+ "version": PROTOCOL_VERSION,
140
+ "application": self._commit.application,
141
+ "surface": self._commit.surface,
142
+ "revision": self._commit.revision + 1,
143
+ "ops": wire_ops,
144
+ }
145
+ from ..profiling import count
146
+
147
+ count("bridge.commits")
148
+ count("bridge.operations", len(ops))
149
+ count("bridge.bytes", len(payload.encode("utf-8")))
150
+ candidate = self._commit.prepare(envelope)
151
+ try:
152
+ ack = codec.loads(self.transport.apply(codec.dumps(envelope)))
153
+ if ack != candidate.acknowledgement():
154
+ raise CommitError(f"Native commit {candidate.revision} rejected: {ack!r}")
155
+ except Exception:
156
+ self._failed = True
157
+ raise
158
+ self._commit = candidate
159
+ destroyed: List[int] = []
160
+ for op in ops:
161
+ if isinstance(op, CreateOp):
162
+ self._types[op.tag] = op.type_name
163
+ self._births[op.tag] = candidate.revision
164
+ self._refs[op.tag] = NativeViewRef(op.tag, op.type_name)
165
+ elif isinstance(op, DestroyOp):
166
+ destroyed.append(op.tag)
167
+ for tag, props in sidecar:
168
+ self._python_props.setdefault(tag, {}).update(props)
169
+ for op in ops:
170
+ if isinstance(op, UpdateOp):
171
+ # A prop that changed from a callable to None arrives
172
+ # as None in the wire dict; drop the stale sidecar copy.
173
+ bucket = self._python_props.get(op.tag)
174
+ if bucket:
175
+ for key, value in op.changed_props.items():
176
+ if value is None:
177
+ bucket.pop(key, None)
178
+ if not bucket:
179
+ self._python_props.pop(op.tag, None)
180
+ for tag in destroyed:
181
+ self._forget(tag)
182
+
183
+ def accept_event(self, tag: int, name: str, envelope: Any) -> bool:
184
+ """Reject events from destroyed views, earlier applications, and replayed input."""
185
+ if self._failed or not isinstance(envelope, dict):
186
+ return False
187
+ if envelope.get("application") != self._commit.application or envelope.get("surface") != self._commit.surface:
188
+ return False
189
+ revision, sequence = envelope.get("revision"), envelope.get("sequence")
190
+ if type(revision) is not int or type(sequence) is not int or tag not in self._births:
191
+ return False
192
+ key = (tag, name)
193
+ if not self._births[tag] <= revision <= self._commit.revision or sequence <= self._event_sequences.get(key, 0):
194
+ return False
195
+ self._event_sequences[key] = sequence
196
+ if name == "on_change" and self._types.get(tag) == "TextInput":
197
+ edit = envelope.get("edit_revision")
198
+ if type(edit) is int:
199
+ self._edit_revisions[tag] = max(edit, self._edit_revisions.get(tag, 0))
200
+ return isinstance(envelope.get("args"), list)
201
+
202
+ def _forget(self, tag: int) -> None:
203
+ self._types.pop(tag, None)
204
+ self._births.pop(tag, None)
205
+ self._edit_revisions.pop(tag, None)
206
+ for key in tuple(self._event_sequences):
207
+ if key[0] == tag:
208
+ del self._event_sequences[key]
209
+ self._refs.pop(tag, None)
210
+ self._python_props.pop(tag, None)
211
+
212
+ # ------------------------------------------------------------------
213
+ # Imperative escape hatches
214
+ # ------------------------------------------------------------------
215
+
216
+ def measure_intrinsic(self, tag: int, max_width: float, max_height: float) -> Tuple[float, float]:
217
+ """Ask native for the natural size of ``tag`` under the constraints."""
218
+ if tag not in self._types:
219
+ return (0.0, 0.0)
220
+ w, h = self.transport.measure(tag, _bound(max_width), _bound(max_height))
221
+ return (max(0.0, float(w)), max(0.0, float(h)))
222
+
223
+ def command(self, tag: int, name: str, args: Optional[Dict[str, Any]] = None) -> Any:
224
+ """Run an imperative command on one view; returns its JSON result or ``None``."""
225
+ if tag not in self._types:
226
+ raise CommitError(f"Command {name!r} addressed stale view {tag}")
227
+ result = self.transport.command(tag, name, codec.dumps(codec.to_jsonable(args or {})))
228
+ return codec.loads(result)
229
+
230
+ def set_animated_property(self, tag: int, prop_name: str, value: Any) -> None:
231
+ """Write one animated property value without animating (a Python-driven frame)."""
232
+ if tag not in self._types:
233
+ return
234
+ self.transport.animate(tag, codec.dumps({"op": "set", "prop": prop_name, "value": codec.to_jsonable(value)}))
235
+
236
+ def install_animation_graph(self, tag: int, graph: dict[str, Any]) -> None:
237
+ """Install native expression nodes and view bindings in one crossing."""
238
+ if tag in self._types:
239
+ self.transport.animate(tag, codec.dumps({"op": "graph", "graph": graph}))
240
+
241
+ def start_animation(self, tag: int, anim_id: int, prop_name: str, spec: Dict[str, Any]) -> bool:
242
+ """Start a native-driven animation; returns whether native accepted it."""
243
+ if tag not in self._types:
244
+ return False
245
+ request = {"op": "start", "id": int(anim_id), "prop": prop_name, "spec": codec.to_jsonable(spec)}
246
+ result = codec.loads(self.transport.animate(tag, codec.dumps(request)))
247
+ return bool(isinstance(result, dict) and result.get("ok"))
248
+
249
+ def cancel_animation(self, tag: int, anim_id: int) -> Any:
250
+ """Cancel a native animation and return its presentation value, if known."""
251
+ if tag not in self._types:
252
+ return None
253
+ result = codec.loads(self.transport.animate(tag, codec.dumps({"op": "cancel", "id": int(anim_id)})))
254
+ if isinstance(result, dict):
255
+ return result.get("value")
256
+ return None
257
+
258
+ def reset(self) -> None:
259
+ """Forget a disconnected surface before the host remounts its tree."""
260
+ self._types.clear()
261
+ self._refs.clear()
262
+ self._python_props.clear()
263
+ self._commit = CommitState(str(uuid.uuid4()), 1)
264
+ self._births: dict[int, int] = {}
265
+ self._event_sequences: dict[tuple[int, str], int] = {}
266
+ self._failed = False
267
+
268
+
269
+ def _bound(value: float) -> float:
270
+ """Clamp ``math.inf`` to the wire's "unconstrained" sentinel."""
271
+ try:
272
+ f = float(value)
273
+ except (TypeError, ValueError):
274
+ return _MEASURE_UNBOUNDED
275
+ if not math.isfinite(f) or f > _MEASURE_UNBOUNDED:
276
+ return _MEASURE_UNBOUNDED
277
+ return max(0.0, f)
@@ -0,0 +1,103 @@
1
+ """Navigation: stack, tab, and drawer navigators with a React Navigation-style API.
2
+
3
+ ```python
4
+ import pythonnative as pn
5
+
6
+ Stack = pn.create_stack_navigator()
7
+
8
+ @pn.component
9
+ def HomeScreen():
10
+ nav = pn.use_navigation()
11
+ return pn.Button("Open 42", on_press=lambda: nav.navigate("Detail", id=42))
12
+
13
+ @pn.component
14
+ def DetailScreen():
15
+ route = pn.use_route()
16
+ return pn.Text(f"Item {route.params['id']}")
17
+
18
+ @pn.component
19
+ def App():
20
+ return pn.NavigationContainer(
21
+ Stack.Navigator(
22
+ Stack.Screen("Home", HomeScreen, title="Home"),
23
+ Stack.Screen("Detail", DetailScreen, options=lambda route: {"title": f"Item {route.params['id']}"}),
24
+ )
25
+ )
26
+ ```
27
+
28
+ Public surface (all re-exported from ``pythonnative``):
29
+
30
+ - Factories: [`create_stack_navigator`][pythonnative.create_stack_navigator],
31
+ [`create_tab_navigator`][pythonnative.create_tab_navigator],
32
+ [`create_drawer_navigator`][pythonnative.create_drawer_navigator],
33
+ [`NavigationContainer`][pythonnative.NavigationContainer].
34
+ - Hooks: [`use_navigation`][pythonnative.use_navigation],
35
+ [`use_route`][pythonnative.use_route],
36
+ [`use_is_focused`][pythonnative.use_is_focused],
37
+ [`use_focus_effect`][pythonnative.use_focus_effect].
38
+ - Types: [`Navigation`][pythonnative.Navigation],
39
+ [`Route`][pythonnative.navigation.Route],
40
+ [`NavigationState`][pythonnative.navigation.NavigationState],
41
+ [`ScreenOptions`][pythonnative.ScreenOptions],
42
+ [`LinkingConfig`][pythonnative.LinkingConfig].
43
+ """
44
+
45
+ from .container import ContainerContext, NavigationContainer
46
+ from .handle import (
47
+ DrawerNavigation,
48
+ EventName,
49
+ FocusContext,
50
+ HostNavigator,
51
+ Navigation,
52
+ NavigationContext,
53
+ NavigationEvent,
54
+ NavigatorCore,
55
+ TabNavigation,
56
+ )
57
+ from .hooks import use_focus_effect, use_is_focused, use_navigation, use_route
58
+ from .host import NAV_STATE_ARG, HostContext, HostRoot
59
+ from .linking import LinkingConfig
60
+ from .navigators import (
61
+ DrawerNavigator,
62
+ StackNavigator,
63
+ TabNavigator,
64
+ create_drawer_navigator,
65
+ create_stack_navigator,
66
+ create_tab_navigator,
67
+ )
68
+ from .screen import HeaderSlot, ScreenDef, ScreenOptions
69
+ from .state import NavigationState, Route, RouteParams
70
+
71
+ __all__ = [
72
+ "NAV_STATE_ARG",
73
+ "ContainerContext",
74
+ "DrawerNavigation",
75
+ "DrawerNavigator",
76
+ "EventName",
77
+ "FocusContext",
78
+ "HeaderSlot",
79
+ "HostContext",
80
+ "HostNavigator",
81
+ "HostRoot",
82
+ "LinkingConfig",
83
+ "Navigation",
84
+ "NavigationContainer",
85
+ "NavigationContext",
86
+ "NavigationEvent",
87
+ "NavigationState",
88
+ "NavigatorCore",
89
+ "Route",
90
+ "RouteParams",
91
+ "ScreenDef",
92
+ "ScreenOptions",
93
+ "StackNavigator",
94
+ "TabNavigation",
95
+ "TabNavigator",
96
+ "create_drawer_navigator",
97
+ "create_stack_navigator",
98
+ "create_tab_navigator",
99
+ "use_focus_effect",
100
+ "use_is_focused",
101
+ "use_navigation",
102
+ "use_route",
103
+ ]
@@ -0,0 +1,154 @@
1
+ """``NavigationContainer``: the root of a navigator tree.
2
+
3
+ The container wires the root navigator to the outside world: deep links
4
+ (via [`LinkingConfig`][pythonnative.LinkingConfig]), a caller-supplied
5
+ initial state, and ``on_state_change`` / ``on_ready`` callbacks. Every
6
+ app with navigation renders exactly one container at the top.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Any, Callable, Mapping, Optional, Union
12
+
13
+ from ..component import component
14
+ from ..element import Element, Node
15
+ from ..hooks import Context, create_context, use_effect, use_memo, use_ref
16
+ from .linking import LinkingConfig
17
+ from .state import NavigationState
18
+
19
+ __all__ = ["ContainerContext", "NavigationContainer"]
20
+
21
+ StateLike = Union[NavigationState, Mapping[str, Any]]
22
+
23
+
24
+ class ContainerConfig:
25
+ """What a root navigator reads from its enclosing container."""
26
+
27
+ __slots__ = ("initial_state", "on_state_change", "on_ready", "_root", "_ready")
28
+
29
+ def __init__(
30
+ self,
31
+ initial_state: Optional[NavigationState],
32
+ on_state_change: Optional[Callable[[NavigationState], None]],
33
+ on_ready: Optional[Callable[[], None]],
34
+ ) -> None:
35
+ self.initial_state = initial_state
36
+ self.on_state_change = on_state_change
37
+ self.on_ready = on_ready
38
+ self._root: Any = None
39
+ self._ready = False
40
+
41
+ def attach_root(self, core: Any) -> Callable[[], None]:
42
+ """Register the root navigator core; returns a detach callable."""
43
+ self._root = core
44
+ if not self._ready:
45
+ self._ready = True
46
+ if self.on_ready is not None:
47
+ self.on_ready()
48
+
49
+ def detach() -> None:
50
+ if self._root is core:
51
+ self._root = None
52
+
53
+ return detach
54
+
55
+ def dispatch_seed(self, seed: NavigationState) -> bool:
56
+ """Route a deep-link state to the root navigator (``False`` if none is mounted)."""
57
+ if self._root is None:
58
+ return False
59
+ target = seed.current
60
+ self._root.navigate(target.name, target.params, target.state)
61
+ return True
62
+
63
+
64
+ ContainerContext: Context[Optional[ContainerConfig]] = create_context(None, name="NavigationContainer")
65
+
66
+
67
+ def _coerce_state(value: Optional[StateLike]) -> Optional[NavigationState]:
68
+ if value is None or isinstance(value, NavigationState):
69
+ return value
70
+ try:
71
+ return NavigationState.from_dict(value)
72
+ except Exception:
73
+ return None
74
+
75
+
76
+ @component
77
+ def NavigationContainer(
78
+ *children: Node,
79
+ linking: Optional[LinkingConfig] = None,
80
+ initial_state: Optional[StateLike] = None,
81
+ on_state_change: Optional[Callable[[NavigationState], None]] = None,
82
+ on_ready: Optional[Callable[[], None]] = None,
83
+ ) -> Element:
84
+ """Root of a navigator tree.
85
+
86
+ Args:
87
+ *children: The root navigator (a ``Stack.Navigator``, ``Tab.Navigator``,
88
+ or ``Drawer.Navigator``) and anything rendered alongside it.
89
+ linking: Deep-link configuration. The URL the app was launched
90
+ with seeds the initial state; URLs that arrive later are
91
+ dispatched as ``navigate`` calls.
92
+ initial_state: Explicit initial state for the root navigator
93
+ (a ``NavigationState`` or its ``to_dict()`` form). Takes
94
+ precedence over the launch URL. State restored by a native
95
+ host (a pushed native screen re-entering Python) takes
96
+ precedence over both.
97
+ on_state_change: Called with the root navigator's state after
98
+ every change. Persist ``state.to_dict()`` to restore later.
99
+ on_ready: Called once the root navigator has mounted.
100
+
101
+ Example:
102
+ ```python
103
+ Stack = pn.create_stack_navigator()
104
+
105
+ @pn.component
106
+ def App():
107
+ return pn.NavigationContainer(
108
+ Stack.Navigator(
109
+ Stack.Screen("Home", HomeScreen),
110
+ Stack.Screen("Detail", DetailScreen, options={"title": "Detail"}),
111
+ ),
112
+ linking=linking,
113
+ )
114
+ ```
115
+ """
116
+ coerced = _coerce_state(initial_state)
117
+
118
+ def build() -> ContainerConfig:
119
+ seed = coerced
120
+ if seed is None and linking is not None:
121
+ from ..native_modules.linking import Linking
122
+
123
+ url = Linking.get_initial_url()
124
+ if url:
125
+ seed = linking.state_from_url(url)
126
+ return ContainerConfig(seed, on_state_change, on_ready)
127
+
128
+ config = use_memo(build, [])
129
+ config.on_state_change = on_state_change
130
+ config.on_ready = on_ready
131
+
132
+ initial_url: Any = use_ref(None)
133
+
134
+ def subscribe() -> Optional[Callable[[], None]]:
135
+ if linking is None:
136
+ return None
137
+ from ..native_modules.linking import Linking
138
+
139
+ initial_url.current = Linking.get_initial_url()
140
+
141
+ def on_url(url: str) -> None:
142
+ # The initial URL already seeded the state; don't navigate twice.
143
+ if url == initial_url.current:
144
+ initial_url.current = None
145
+ return
146
+ seed = linking.state_from_url(url)
147
+ if seed is not None:
148
+ config.dispatch_seed(seed)
149
+
150
+ return Linking.add_listener(on_url)
151
+
152
+ use_effect(subscribe, [linking])
153
+
154
+ return ContainerContext.Provider(config, *children)