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,82 @@
1
+ package com.pythonnative.runtime.bridge
2
+
3
+ import android.util.Log
4
+ import com.pythonnative.runtime.components.BuiltinComponents
5
+ import com.pythonnative.runtime.components.ComponentManager
6
+ import com.pythonnative.runtime.modules.BuiltinModules
7
+ import com.pythonnative.runtime.modules.NativeModule
8
+ import com.pythonnative.runtime.plugins.GeneratedPlugins
9
+
10
+ /**
11
+ * A native extension: registers component managers and native modules.
12
+ *
13
+ * `pn build` generates a call to each plugin entry's `register` in
14
+ * `plugins/GeneratedPlugins.kt`.
15
+ */
16
+ interface PNPlugin {
17
+ fun register(registry: PNRegistry)
18
+ }
19
+
20
+ /**
21
+ * Registry of component managers (by element type) and native modules
22
+ * (by module name). Built-ins are registered on first use, followed by
23
+ * the generated plugin registrations.
24
+ */
25
+ object PNRegistry {
26
+ private val componentFactories = HashMap<String, () -> ComponentManager>()
27
+ private val managers = HashMap<String, ComponentManager>()
28
+ private val moduleFactories = HashMap<String, () -> NativeModule>()
29
+ private val modules = HashMap<String, NativeModule>()
30
+ private var builtinsRegistered = false
31
+
32
+ /** Register (or override) the manager factory for element type `name`. */
33
+ fun registerComponent(name: String, factory: () -> ComponentManager) {
34
+ componentFactories[name] = factory
35
+ managers.remove(name)
36
+ }
37
+
38
+ /**
39
+ * Register a native module. The factory is invoked once to read the
40
+ * module's `name`; the same instance then serves every call.
41
+ */
42
+ fun registerModule(factory: () -> NativeModule) {
43
+ val module = factory()
44
+ moduleFactories[module.name] = factory
45
+ modules[module.name] = module
46
+ }
47
+
48
+ /** The manager for element type `name`, or `null` when unknown. */
49
+ fun managerFor(name: String): ComponentManager? {
50
+ ensureBuiltins()
51
+ managers[name]?.let { return it }
52
+ val factory = componentFactories[name] ?: return null
53
+ val manager = factory()
54
+ managers[name] = manager
55
+ return manager
56
+ }
57
+
58
+ /** The module named `name`, or `null`. */
59
+ fun module(name: String): NativeModule? {
60
+ ensureBuiltins()
61
+ return modules[name]
62
+ }
63
+
64
+ /** Registered element type names. */
65
+ fun componentNames(): Set<String> {
66
+ ensureBuiltins()
67
+ return componentFactories.keys
68
+ }
69
+
70
+ /** Register built-in components and modules plus generated plugins (idempotent). */
71
+ fun ensureBuiltins() {
72
+ if (builtinsRegistered) return
73
+ builtinsRegistered = true
74
+ BuiltinComponents.register(this)
75
+ BuiltinModules.register(this)
76
+ try {
77
+ GeneratedPlugins.registerAll(this)
78
+ } catch (e: Exception) {
79
+ Log.e(PNLog.TAG, "plugin registration failed", e)
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,80 @@
1
+ package com.pythonnative.runtime.bridge
2
+
3
+ import org.json.JSONArray
4
+ import org.json.JSONException
5
+ import org.json.JSONObject
6
+
7
+ /** One decoded mutation op. Geometry is in dp (points). */
8
+ sealed class Op {
9
+ /** `["c", tag, "Type", {props}]` */
10
+ data class Create(val tag: Long, val typeName: String, val props: JSONObject) : Op()
11
+
12
+ /** `["u", tag, {changed}]` (a `null` value means the prop was removed) */
13
+ data class Update(val tag: Long, val changed: JSONObject) : Op()
14
+
15
+ /** `["i", parent, child, index]` (move-aware) */
16
+ data class Insert(val parent: Long, val child: Long, val index: Int) : Op()
17
+
18
+ /** `["d", tag]` */
19
+ data class Destroy(val tag: Long) : Op()
20
+
21
+ /** `["f", tag, x, y, w, h]` relative to the parent's content origin */
22
+ data class Frame(val tag: Long, val x: Double, val y: Double, val width: Double, val height: Double) : Op()
23
+ }
24
+
25
+ /**
26
+ * Decoder for the transaction wire format: a JSON array of ops, each an
27
+ * array whose first element is a one-letter opcode.
28
+ *
29
+ * Decoding is isolated per op: a malformed entry is reported through
30
+ * `onError` and skipped so the rest of the commit still applies.
31
+ */
32
+ object PNTransaction {
33
+ /** Decode `json`; invalid ops are skipped after `onError(index, error)`. */
34
+ fun decode(json: String, onError: (Int, Throwable) -> Unit = { _, _ -> }): List<Op> {
35
+ val array = JSONArray(json)
36
+ val ops = ArrayList<Op>(array.length())
37
+ for (i in 0 until array.length()) {
38
+ try {
39
+ val raw = array.get(i) as? JSONArray
40
+ ?: throw JSONException("op $i is not an array")
41
+ ops.add(decodeOp(raw))
42
+ } catch (e: Exception) {
43
+ onError(i, e)
44
+ }
45
+ }
46
+ return ops
47
+ }
48
+
49
+ /** Decode a single op array. */
50
+ fun decodeOp(raw: JSONArray): Op {
51
+ val code = raw.optString(0, "")
52
+ return when (code) {
53
+ "c" -> Op.Create(
54
+ tag(raw, 1),
55
+ raw.optString(2, ""),
56
+ raw.optJSONObject(3) ?: JSONObject(),
57
+ )
58
+ "u" -> Op.Update(tag(raw, 1), raw.optJSONObject(2) ?: JSONObject())
59
+ "i" -> Op.Insert(tag(raw, 1), tag(raw, 2), JsonUtil.toInt(raw.opt(3), 0))
60
+ "d" -> Op.Destroy(tag(raw, 1))
61
+ "f" -> Op.Frame(
62
+ tag(raw, 1),
63
+ JsonUtil.toDouble(raw.opt(2)),
64
+ JsonUtil.toDouble(raw.opt(3)),
65
+ JsonUtil.toDouble(raw.opt(4)),
66
+ JsonUtil.toDouble(raw.opt(5)),
67
+ )
68
+ else -> throw JSONException("unknown opcode '$code'")
69
+ }
70
+ }
71
+
72
+ private fun tag(raw: JSONArray, index: Int): Long {
73
+ val v = raw.opt(index) ?: throw JSONException("missing tag at $index")
74
+ return when (v) {
75
+ is Number -> v.toLong()
76
+ is String -> v.toLongOrNull() ?: throw JSONException("bad tag '$v'")
77
+ else -> throw JSONException("bad tag $v")
78
+ }
79
+ }
80
+ }
@@ -0,0 +1,117 @@
1
+ package com.pythonnative.runtime.bridge
2
+
3
+ import android.view.View
4
+ import com.pythonnative.runtime.PNBridge
5
+ import com.pythonnative.runtime.components.ComponentManager
6
+ import com.pythonnative.runtime.components.PlaceholderManager
7
+ import com.pythonnative.runtime.gestures.GestureCoordinator
8
+ import org.json.JSONObject
9
+
10
+ /**
11
+ * Applies decoded transactions to the view tree, in order, with per-op
12
+ * error isolation. Unknown element types create a placeholder view and
13
+ * log once.
14
+ */
15
+ class TransactionApplier(private val registry: ViewRegistry) {
16
+ private val placeholder = PlaceholderManager()
17
+
18
+ /** Decode and apply `transactionJson`. */
19
+ fun apply(transactionJson: String) {
20
+ val ops = try {
21
+ PNTransaction.decode(transactionJson) { index, error ->
22
+ PNLog.rateLimited("decode", "transaction op $index could not be decoded", error)
23
+ }
24
+ } catch (e: Exception) {
25
+ PNLog.rateLimited("decode-top", "transaction is not a JSON array", e)
26
+ return
27
+ }
28
+ for (op in ops) {
29
+ try {
30
+ applyOp(op)
31
+ } catch (e: Exception) {
32
+ PNLog.rateLimited("op:" + op.javaClass.simpleName, "failed to apply $op", e)
33
+ }
34
+ }
35
+ }
36
+
37
+ /** Apply a single op. */
38
+ fun applyOp(op: Op) {
39
+ when (op) {
40
+ is Op.Create -> create(op)
41
+ is Op.Update -> update(op)
42
+ is Op.Insert -> insert(op)
43
+ is Op.Destroy -> destroy(op)
44
+ is Op.Frame -> frame(op)
45
+ }
46
+ }
47
+
48
+ private fun create(op: Op.Create) {
49
+ registry.get(op.tag)?.let {
50
+ PNLog.rateLimited("dup-create", "tag ${op.tag} already exists (${it.typeName}); replacing")
51
+ destroyRecord(it)
52
+ }
53
+ val manager = PNRegistry.managerFor(op.typeName) ?: run {
54
+ PNLog.once("unknown-type:" + op.typeName, "unknown element type '${op.typeName}'; using a placeholder view")
55
+ placeholder
56
+ }
57
+ val view = manager.createView(PNBridge.context(), op.tag, op.props)
58
+ val record = ViewRecord(op.tag, op.typeName, view, manager)
59
+ JsonUtil.merge(record.props, op.props)
60
+ registry.register(record)
61
+ try {
62
+ manager.applyProps(view, op.props, true)
63
+ } finally {
64
+ record.initialized = true
65
+ }
66
+ if (op.props.has("gestures")) {
67
+ GestureCoordinator.bind(record, op.props.opt("gestures"))
68
+ }
69
+ }
70
+
71
+ private fun update(op: Op.Update) {
72
+ val record = registry.get(op.tag) ?: throw IllegalStateException("update: unknown tag ${op.tag}")
73
+ JsonUtil.merge(record.props, op.changed)
74
+ record.manager.update(record.view, op.changed)
75
+ if (op.changed.has("gestures")) {
76
+ GestureCoordinator.bind(record, op.changed.opt("gestures"))
77
+ }
78
+ }
79
+
80
+ private fun insert(op: Op.Insert) {
81
+ val parent = registry.get(op.parent) ?: throw IllegalStateException("insert: unknown parent ${op.parent}")
82
+ val child = registry.get(op.child) ?: throw IllegalStateException("insert: unknown child ${op.child}")
83
+ parent.manager.insertChild(parent.view, child.view, op.index)
84
+ }
85
+
86
+ private fun destroy(op: Op.Destroy) {
87
+ val record = registry.get(op.tag) ?: return
88
+ destroyRecord(record)
89
+ }
90
+
91
+ private fun destroyRecord(record: ViewRecord) {
92
+ com.pythonnative.runtime.animation.AnimationGraph.forget(record.tag)
93
+ GestureCoordinator.unbind(record)
94
+ try {
95
+ val parentRecord = com.pythonnative.runtime.layout.NativeLayout.parent(record.tag)?.let { registry.get(it) }
96
+ ?: (record.view.parent as? View)?.let { registry.recordFor(it) }
97
+ if (parentRecord != null) {
98
+ parentRecord.manager.removeChild(parentRecord.view, record.view)
99
+ }
100
+ record.manager.destroy(record.view)
101
+ } finally {
102
+ registry.unregister(record.tag)
103
+ }
104
+ }
105
+
106
+ private fun frame(op: Op.Frame) {
107
+ val record = registry.get(op.tag) ?: throw IllegalStateException("frame: unknown tag ${op.tag}")
108
+ record.frame = doubleArrayOf(op.x, op.y, op.width, op.height)
109
+ record.manager.setFrame(record.view, op.x, op.y, op.width, op.height)
110
+ }
111
+
112
+ /** Whether `manager` is the fallback placeholder manager. */
113
+ fun isPlaceholder(manager: ComponentManager): Boolean = manager === placeholder
114
+
115
+ /** The props recorded for `tag`, mainly for diagnostics. */
116
+ fun propsOf(tag: Long): JSONObject? = registry.get(tag)?.props
117
+ }
@@ -0,0 +1,74 @@
1
+ package com.pythonnative.runtime.bridge
2
+
3
+ import android.view.View
4
+ import com.pythonnative.runtime.components.ComponentManager
5
+ import org.json.JSONArray
6
+ import org.json.JSONObject
7
+ import java.util.IdentityHashMap
8
+
9
+ /**
10
+ * Per-view bookkeeping: the reconciler tag, the element type, the
11
+ * manager that owns it, the merged props, and free-form manager state.
12
+ */
13
+ class ViewRecord(
14
+ val tag: Long,
15
+ val typeName: String,
16
+ val view: View,
17
+ val manager: ComponentManager,
18
+ ) {
19
+ /** Every prop applied so far (removed props stay as JSON null). */
20
+ val props = JSONObject()
21
+
22
+ /** Manager-private state (suppress flags, wrapped widgets, etc.). */
23
+ val state = HashMap<String, Any?>()
24
+
25
+ /** Last frame applied by `setFrame`, in dp (`x, y, w, h`). */
26
+ var frame: DoubleArray? = null
27
+
28
+ /** Whether the initial props have been applied. */
29
+ var initialized = false
30
+
31
+ /** Whether the element wired a callback named `name` this render. */
32
+ fun hasEvent(name: String): Boolean {
33
+ val events = props.opt("_pn_events") as? JSONArray ?: return false
34
+ for (i in 0 until events.length()) {
35
+ if (events.optString(i) == name) return true
36
+ }
37
+ return false
38
+ }
39
+ }
40
+
41
+ /** Tag to [ViewRecord] map with a reverse index by view identity. */
42
+ class ViewRegistry {
43
+ private val byTag = HashMap<Long, ViewRecord>()
44
+ private val byView = IdentityHashMap<View, ViewRecord>()
45
+
46
+ /** Number of live records. */
47
+ val size: Int get() = byTag.size
48
+
49
+ /** Register `record`; replaces any earlier record with the same tag. */
50
+ fun register(record: ViewRecord) {
51
+ byTag.remove(record.tag)?.let { byView.remove(it.view) }
52
+ byTag[record.tag] = record
53
+ byView[record.view] = record
54
+ }
55
+
56
+ /** Remove and return the record for `tag`. */
57
+ fun unregister(tag: Long): ViewRecord? {
58
+ val record = byTag.remove(tag) ?: return null
59
+ byView.remove(record.view)
60
+ return record
61
+ }
62
+
63
+ /** The record for `tag`, or `null`. */
64
+ fun get(tag: Long): ViewRecord? = byTag[tag]
65
+
66
+ /** The record whose view is `view`, or `null`. */
67
+ fun recordFor(view: View): ViewRecord? = byView[view]
68
+
69
+ /** The tag of `view`, or `null` when it is not a PythonNative view. */
70
+ fun tagOf(view: View): Long? = byView[view]?.tag
71
+
72
+ /** Snapshot of all records. */
73
+ fun all(): List<ViewRecord> = ArrayList(byTag.values)
74
+ }
@@ -0,0 +1,37 @@
1
+ package com.pythonnative.runtime.components
2
+
3
+ import com.pythonnative.runtime.bridge.PNRegistry
4
+
5
+ /** Registers the built-in element types with the registry. */
6
+ object BuiltinComponents {
7
+ fun register(registry: PNRegistry) {
8
+ registry.registerComponent("View") { ViewManager() }
9
+ registry.registerComponent("Screen") { ScreenManager() }
10
+ registry.registerComponent("ScreenStack") { ScreenStackManager() }
11
+ registry.registerComponent("Column") { ViewManager() }
12
+ registry.registerComponent("Row") { ViewManager() }
13
+ registry.registerComponent("Text") { TextManager() }
14
+ registry.registerComponent("Button") { ButtonManager() }
15
+ registry.registerComponent("TextInput") { TextInputManager() }
16
+ registry.registerComponent("Image") { ImageManager() }
17
+ registry.registerComponent("Switch") { SwitchManager() }
18
+ registry.registerComponent("Checkbox") { CheckboxManager() }
19
+ registry.registerComponent("ProgressBar") { ProgressBarManager() }
20
+ registry.registerComponent("ActivityIndicator") { ActivityIndicatorManager() }
21
+ registry.registerComponent("Slider") { SliderManager() }
22
+ registry.registerComponent("WebView") { WebViewManager() }
23
+ registry.registerComponent("Spacer") { SpacerManager() }
24
+ registry.registerComponent("ScrollView") { ScrollViewManager() }
25
+ registry.registerComponent("SafeAreaView") { SafeAreaViewManager() }
26
+ registry.registerComponent("KeyboardAvoidingView") { KeyboardAvoidingViewManager() }
27
+ registry.registerComponent("Modal") { ModalManager() }
28
+ registry.registerComponent("Portal") { PortalManager() }
29
+ registry.registerComponent("TabBar") { TabBarManager() }
30
+ registry.registerComponent("Pressable") { PressableManager() }
31
+ registry.registerComponent("StatusBar") { StatusBarManager() }
32
+ registry.registerComponent("Picker") { PickerManager() }
33
+ registry.registerComponent("SegmentedControl") { SegmentedControlManager() }
34
+ registry.registerComponent("DatePicker") { DatePickerManager() }
35
+ registry.registerComponent("VirtualList") { VirtualListManager() }
36
+ }
37
+ }
@@ -0,0 +1,32 @@
1
+ package com.pythonnative.runtime.components
2
+
3
+ import android.content.Context
4
+ import android.view.View
5
+ import android.widget.Button
6
+ import com.pythonnative.runtime.bridge.JsonUtil
7
+ import com.pythonnative.runtime.bridge.num
8
+ import com.pythonnative.runtime.bridge.str
9
+ import com.pythonnative.runtime.bridge.value
10
+ import org.json.JSONObject
11
+
12
+ /** `Button` element: a platform `Button` firing `on_press`. */
13
+ class ButtonManager : ComponentManager() {
14
+ override fun createView(context: Context, tag: Long, props: JSONObject): View {
15
+ val button = Button(context)
16
+ button.setOnClickListener { fire(it, "on_press") }
17
+ return button
18
+ }
19
+
20
+ override fun applyProps(view: View, props: JSONObject, initial: Boolean) {
21
+ val button = view as Button
22
+ if (props.has("title")) button.text = props.str("title") ?: ""
23
+ props.num("font_size")?.let { button.textSize = it.toFloat() }
24
+ PNColor.parse(props.value("color"))?.let { button.setTextColor(it) }
25
+ if (props.has("disabled")) button.isEnabled = !JsonUtil.truthy(props.value("disabled"))
26
+ if (props.has("all_caps")) button.isAllCaps = JsonUtil.truthy(props.value("all_caps"))
27
+ if (listOf("font_family", "font_weight", "italic", "bold").any { props.has(it) }) {
28
+ TextStyle.applyTypeface(button, propsOf(button))
29
+ }
30
+ ViewStyler.apply(button, props)
31
+ }
32
+ }
@@ -0,0 +1,213 @@
1
+ package com.pythonnative.runtime.components
2
+
3
+ import android.content.Context
4
+ import android.util.Log
5
+ import android.view.View
6
+ import android.view.ViewGroup
7
+ import android.widget.FrameLayout
8
+ import com.pythonnative.runtime.PNBridge
9
+ import com.pythonnative.runtime.animation.PNAnimator
10
+ import com.pythonnative.runtime.bridge.JsonUtil
11
+ import com.pythonnative.runtime.bridge.ViewRecord
12
+ import com.pythonnative.runtime.bridge.present
13
+ import org.json.JSONArray
14
+ import org.json.JSONObject
15
+ import kotlin.math.max
16
+ import kotlin.math.min
17
+ import kotlin.math.roundToInt
18
+
19
+ /**
20
+ * Base class for one element type's native implementation.
21
+ *
22
+ * Subclasses implement [createView] (construct the widget) and
23
+ * [applyProps] (apply visual props); the base class owns frame
24
+ * application, intrinsic measurement, child management, and the
25
+ * animation hooks. All geometry crossing this API is in dp.
26
+ */
27
+ abstract class ComponentManager {
28
+ /** Construct the widget for `tag`; `props` may be consulted for creation-time choices. */
29
+ abstract fun createView(context: Context, tag: Long, props: JSONObject): View
30
+
31
+ /**
32
+ * Apply `props` to `view`. `initial` is `true` for the create op;
33
+ * on updates `props` holds only the changed keys (JSON null means
34
+ * removed). The merged props are always available via [propsOf].
35
+ */
36
+ open fun applyProps(view: View, props: JSONObject, initial: Boolean) {
37
+ ViewStyler.apply(view, props)
38
+ }
39
+
40
+ /** Apply changed props (the `u` op). */
41
+ fun update(view: View, changed: JSONObject) = applyProps(view, changed, false)
42
+
43
+ /** Ensure `child` sits at `index` under `parent` (move-aware, clamped). */
44
+ open fun insertChild(parent: View, child: View, index: Int) {
45
+ val group = parent as? ViewGroup ?: return
46
+ ViewChildren.insert(group, child, index)
47
+ }
48
+
49
+ /** Detach `child` from `parent` without destroying it. */
50
+ open fun removeChild(parent: View, child: View) {
51
+ (parent as? ViewGroup)?.removeView(child)
52
+ }
53
+
54
+ /** Release resources and detach from the parent. */
55
+ open fun destroy(view: View) {
56
+ try {
57
+ teardown(view)
58
+ } catch (e: Exception) {
59
+ Log.d(PNBridge.TAG, "teardown failed for ${view.javaClass.simpleName}", e)
60
+ }
61
+ (view.parent as? ViewGroup)?.removeView(view)
62
+ }
63
+
64
+ /** Subclass hook for extra cleanup before the view is released. */
65
+ protected open fun teardown(view: View) {}
66
+
67
+ /**
68
+ * Position `view` inside its parent's `FrameLayout` via margin layout
69
+ * params. Non-finite values are clamped; sizes are never negative.
70
+ */
71
+ open fun setFrame(view: View, x: Double, y: Double, width: Double, height: Double) {
72
+ val pxX = px(finite(x))
73
+ val pxY = px(finite(y))
74
+ val pxW = max(0, px(finite(width)))
75
+ val pxH = max(0, px(finite(height)))
76
+ val lp = view.layoutParams
77
+ val params: ViewGroup.LayoutParams = if (lp == null) {
78
+ FrameLayout.LayoutParams(pxW, pxH)
79
+ } else {
80
+ lp.width = pxW
81
+ lp.height = pxH
82
+ lp
83
+ }
84
+ if (params is ViewGroup.MarginLayoutParams) {
85
+ params.leftMargin = pxX
86
+ params.topMargin = pxY
87
+ params.rightMargin = 0
88
+ params.bottomMargin = 0
89
+ }
90
+ view.layoutParams = params
91
+ val record = recordOf(view)
92
+ if (record != null) {
93
+ record.frame = doubleArrayOf(x, y, width, height)
94
+ if (record.props.present("hit_slop") || record.state["hit_slop_active"] == true) {
95
+ ViewStyler.updateHitSlop(view)
96
+ }
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Natural size of `view` under the constraints, in dp. Either
102
+ * constraint may be `1e6` or infinite meaning unconstrained.
103
+ */
104
+ open fun measure(view: View, maxWidth: Double, maxHeight: Double): FloatArray {
105
+ val density = PNBridge.density()
106
+ val wSpec = measureSpec(maxWidth, density)
107
+ val hSpec = measureSpec(maxHeight, density)
108
+ view.measure(wSpec, hSpec)
109
+ return floatArrayOf(view.measuredWidth / density, view.measuredHeight / density)
110
+ }
111
+
112
+ /** Run an imperative command; unknown names return `null`. */
113
+ open fun command(view: View, name: String, args: JSONObject): Any? = null
114
+
115
+ /** Apply one Python-driven animation frame immediately. */
116
+ open fun setAnimatedProperty(view: View, prop: String, value: Any?) {
117
+ PNAnimator.setProperty(view, prop, value)
118
+ }
119
+
120
+ /** Start a natively driven animation; `false` asks Python to tick it instead. */
121
+ open fun startAnimation(view: View, id: Long, prop: String, spec: JSONObject): Boolean =
122
+ PNAnimator.start(view, id, prop, spec)
123
+
124
+ /** Cancel a native animation and return the presentation value, if readable. */
125
+ open fun cancelAnimation(view: View, id: Long): Any? = PNAnimator.cancel(id)
126
+
127
+ // ------------------------------------------------------------------
128
+ // Helpers for subclasses
129
+ // ------------------------------------------------------------------
130
+
131
+ /** The registry record for `view`, or `null` for foreign views. */
132
+ protected fun recordOf(view: View): ViewRecord? = PNBridge.registry.recordFor(view)
133
+
134
+ /** Merged props for `view` (empty for foreign views). */
135
+ protected fun propsOf(view: View): JSONObject = recordOf(view)?.props ?: JSONObject()
136
+
137
+ /** Manager-private state map for `view`. */
138
+ protected fun stateOf(view: View): MutableMap<String, Any?> = recordOf(view)?.state ?: HashMap()
139
+
140
+ /** Dispatch event `name` with positional `args` for `view`'s tag. */
141
+ protected fun fire(view: View, name: String, vararg args: Any?): Boolean = PNEvents.fire(view, name, *args)
142
+
143
+ /** Dispatch event `name` and return Python's (JSON) reply. */
144
+ protected fun fireForResult(view: View, name: String, vararg args: Any?): String? =
145
+ PNEvents.fireForResult(view, name, *args)
146
+
147
+ /** Whether the element wired a callback named `name`. */
148
+ protected fun hasEvent(view: View, name: String): Boolean = recordOf(view)?.hasEvent(name) ?: false
149
+
150
+ /** dp to whole pixels. */
151
+ protected fun px(dp: Double): Int = (dp * PNBridge.density()).roundToInt()
152
+
153
+ /** dp to pixels as a float. */
154
+ protected fun pxF(dp: Double): Float = (dp * PNBridge.density()).toFloat()
155
+
156
+ /** pixels to dp. */
157
+ protected fun dp(px: Number): Double = px.toDouble() / PNBridge.density()
158
+
159
+ private fun finite(v: Double): Double = if (v.isNaN() || v.isInfinite()) 0.0 else v
160
+
161
+ private fun measureSpec(limit: Double, density: Float): Int {
162
+ if (limit.isNaN() || limit.isInfinite() || limit >= 1e6) {
163
+ return View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
164
+ }
165
+ val px = min((max(0.0, limit) * density).toInt(), (1 shl 29))
166
+ return View.MeasureSpec.makeMeasureSpec(px, View.MeasureSpec.AT_MOST)
167
+ }
168
+ }
169
+
170
+ /** Move-aware indexed insertion into any `ViewGroup`. */
171
+ object ViewChildren {
172
+ fun insert(parent: ViewGroup, child: View, index: Int) {
173
+ val current = child.parent as? ViewGroup
174
+ if (current === parent) {
175
+ val currentIndex = parent.indexOfChild(child)
176
+ val target = max(0, min(index, parent.childCount - 1))
177
+ if (currentIndex == target) return
178
+ parent.removeView(child)
179
+ parent.addView(child, max(0, min(target, parent.childCount)))
180
+ return
181
+ }
182
+ current?.removeView(child)
183
+ if (child.layoutParams == null) {
184
+ child.layoutParams = FrameLayout.LayoutParams(0, 0)
185
+ }
186
+ parent.addView(child, max(0, min(index, parent.childCount)))
187
+ }
188
+ }
189
+
190
+ /** Event dispatch keyed by view identity. */
191
+ object PNEvents {
192
+ /** Dispatch `name` for `view` with positional `args`; `false` when the view is unknown. */
193
+ fun fire(view: View, name: String, vararg args: Any?): Boolean {
194
+ val tag = PNBridge.registry.tagOf(view) ?: return false
195
+ fireTag(tag, name, JsonUtil.args(*args))
196
+ return true
197
+ }
198
+
199
+ /** Dispatch `name` for `view` and return Python's JSON reply. */
200
+ fun fireForResult(view: View, name: String, vararg args: Any?): String? {
201
+ val tag = PNBridge.registry.tagOf(view) ?: return null
202
+ return fireTag(tag, name, JsonUtil.args(*args))
203
+ }
204
+
205
+ /** Dispatch `name` for `tag` with an already built argument array. */
206
+ fun fireTag(tag: Long, name: String, args: JSONArray): String? =
207
+ PNBridge.callPython("event", tag, name, args.toString())
208
+ }
209
+
210
+ /** Fallback for unknown element types: an empty container that hosts children. */
211
+ class PlaceholderManager : ComponentManager() {
212
+ override fun createView(context: Context, tag: Long, props: JSONObject): View = FrameLayout(context)
213
+ }