@apexnative/navigation 1.0.0-alpha.0 → 1.0.0-alpha.10

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 (574) hide show
  1. package/ApexNavigation.podspec +2 -1
  2. package/CHANGELOG.md +128 -0
  3. package/README.md +147 -51
  4. package/android/CLAUDE.md +78 -25
  5. package/android/CORE.md +49 -25
  6. package/android/RECIPES.md +13 -6
  7. package/android/consumer-rules.pro +6 -0
  8. package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +85 -10
  9. package/android/src/main/java/dev/apexnative/navigation/NavigationApplication.kt +34 -13
  10. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutChecks.kt +5 -1
  11. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutNode.kt +6 -2
  12. package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenContext.kt +2 -2
  13. package/android/src/main/java/dev/apexnative/navigation/options/AnimationsOptions.kt +2 -2
  14. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
  15. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
  16. package/android/src/main/java/dev/apexnative/navigation/options/ButtonMenuOptions.kt +2 -2
  17. package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +3 -3
  18. package/android/src/main/java/dev/apexnative/navigation/options/HardwareBackButtonOptions.kt +9 -1
  19. package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
  20. package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
  21. package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
  22. package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
  23. package/android/src/main/java/dev/apexnative/navigation/options/OptionsCache.kt +8 -4
  24. package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
  25. package/android/src/main/java/dev/apexnative/navigation/options/SideMenuOptions.kt +6 -1
  26. package/android/src/main/java/dev/apexnative/navigation/options/StackAnimationOptions.kt +40 -2
  27. package/android/src/main/java/dev/apexnative/navigation/options/StatusBarOptions.kt +7 -3
  28. package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
  29. package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
  30. package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
  31. package/android/src/main/java/dev/apexnative/navigation/options/UserChoices.kt +159 -0
  32. package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +29 -36
  33. package/android/src/main/java/dev/apexnative/navigation/react/CommandContract.kt +59 -0
  34. package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
  35. package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
  36. package/android/src/main/java/dev/apexnative/navigation/react/ErrorTexts.kt +75 -60
  37. package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +35 -23
  38. package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +12 -7
  39. package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +42 -4
  40. package/android/src/main/java/dev/apexnative/navigation/react/PendingCalls.kt +48 -0
  41. package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +54 -20
  42. package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +7 -6
  43. package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
  44. package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +19 -50
  45. package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
  46. package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +50 -81
  47. package/android/src/main/java/dev/apexnative/navigation/react/events/EventContract.kt +226 -0
  48. package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +135 -94
  49. package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationState.kt +154 -0
  50. package/android/src/main/java/dev/apexnative/navigation/react/events/ScreenAppearance.kt +0 -6
  51. package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +12 -10
  52. package/android/src/main/java/dev/apexnative/navigation/slots/SlotContainers.kt +10 -7
  53. package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +39 -19
  54. package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +16 -4
  55. package/android/src/main/java/dev/apexnative/navigation/slots/SlotViews.kt +40 -0
  56. package/android/src/main/java/dev/apexnative/navigation/utils/ImageKey.kt +66 -0
  57. package/android/src/main/java/dev/apexnative/navigation/utils/ImageLoader.kt +7 -89
  58. package/android/src/main/java/dev/apexnative/navigation/utils/ImageRequests.kt +76 -0
  59. package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
  60. package/android/src/main/java/dev/apexnative/navigation/utils/OptionImages.kt +262 -0
  61. package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
  62. package/android/src/main/java/dev/apexnative/navigation/utils/UiUtils.kt +3 -3
  63. package/android/src/main/java/dev/apexnative/navigation/utils/ViewController.kt +3 -1
  64. package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
  65. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +10 -7
  66. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/SecondaryScreenPresenter.kt +13 -5
  67. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/AppliedTabCalls.kt +49 -0
  68. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
  69. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +108 -34
  70. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +25 -24
  71. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
  72. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +3 -3
  73. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
  74. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +28 -7
  75. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +12 -9
  76. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +2 -2
  77. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +27 -7
  78. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +1 -1
  79. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +103 -56
  80. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
  81. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
  82. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalAnimations.kt +22 -24
  83. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +109 -21
  84. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +21 -6
  85. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +476 -73
  86. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +57 -25
  87. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
  88. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +83 -0
  89. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackCheck.kt +50 -0
  90. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +49 -14
  91. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +71 -12
  92. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +37 -11
  93. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +10 -8
  94. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +11 -4
  95. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +3 -3
  96. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +6 -6
  97. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +42 -9
  98. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +19 -8
  99. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +16 -7
  100. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +43 -4
  101. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +23 -0
  102. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +77 -17
  103. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +315 -0
  104. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
  105. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +30 -20
  106. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +216 -18
  107. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +26 -1
  108. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +149 -41
  109. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +26 -8
  110. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +115 -6
  111. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
  112. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +222 -48
  113. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +3 -5
  114. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +30 -34
  115. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +5 -51
  116. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
  117. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
  118. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/MenuChecks.kt +13 -56
  119. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +219 -54
  120. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarVisibility.kt +9 -2
  121. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
  122. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +75 -21
  123. package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
  124. package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +29 -11
  125. package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
  126. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +9 -7
  127. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
  128. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +0 -5
  129. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
  130. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStep.kt +31 -0
  131. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +143 -135
  132. package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +13 -5
  133. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
  134. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +9 -6
  135. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionViews.kt +100 -0
  136. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +112 -4
  137. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
  138. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
  139. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +56 -41
  140. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
  141. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
  142. package/android/src/main/java/dev/apexnative/navigation/views/sidemenu/SideMenuView.kt +12 -3
  143. package/android/src/main/java/dev/apexnative/navigation/views/stack/ScreenEdge.kt +45 -0
  144. package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +140 -1
  145. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +14 -10
  146. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
  147. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
  148. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -17
  149. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +73 -34
  150. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
  151. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
  152. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
  153. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +125 -178
  154. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
  155. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
  156. package/android/src/main/jni/ANNContentHeights.cpp +82 -0
  157. package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
  158. package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
  159. package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
  160. package/android/src/main/res/values/styles.xml +1 -1
  161. package/android/src/main/res/values-night/styles.xml +1 -1
  162. package/cli/app.js +1 -1
  163. package/cli/doctor/checks/app.js +77 -14
  164. package/cli/doctor/checks/splash.js +4 -22
  165. package/cli/migrate/native.js +18 -0
  166. package/cli/project.js +10 -2
  167. package/cli/setup/index.js +18 -0
  168. package/cli/setup/source.js +2 -1
  169. package/cli/setup/steps/appDelegate.js +66 -11
  170. package/cli/setup/steps/mainApplication.js +134 -19
  171. package/cli/setup/steps/metro.js +46 -0
  172. package/cli/setup/steps/sceneDelegate.js +108 -0
  173. package/cli/splash/index.js +3 -1
  174. package/cli/upgrade/changelog.js +2 -2
  175. package/docs-md/architecture/native-screens.md +4 -0
  176. package/docs-md/architecture/theme-and-context.md +131 -12
  177. package/docs-md/architecture/transitions.md +58 -12
  178. package/docs-md/containers/modals.md +8 -4
  179. package/docs-md/containers/overlays.md +3 -1
  180. package/docs-md/containers/side-menu.md +19 -2
  181. package/docs-md/containers/tabs.md +5 -1
  182. package/docs-md/flows/bottom-sheets.md +4 -2
  183. package/docs-md/flows/forms-in-a-modal.md +1 -1
  184. package/docs-md/fundamentals/screens-and-props.md +9 -1
  185. package/docs-md/fundamentals/starting-the-app.md +1 -1
  186. package/docs-md/guides/cli.md +4 -3
  187. package/docs-md/guides/deep-links.md +15 -33
  188. package/docs-md/help/glossary.md +4 -4
  189. package/docs-md/help/troubleshooting.md +44 -6
  190. package/docs-md/index.json +57 -1
  191. package/docs-md/migration/from-expo-router.md +1 -1
  192. package/docs-md/migration/from-react-native-navigation.md +9 -3
  193. package/docs-md/migration/from-react-navigation.md +2 -2
  194. package/docs-md/screen-ui/back-and-gestures.md +46 -2
  195. package/docs-md/screen-ui/bar-buttons.md +5 -5
  196. package/docs-md/screen-ui/search.md +1 -1
  197. package/docs-md/screen-ui/system-ui.md +17 -12
  198. package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
  199. package/docs-md/screen-ui/top-bar.md +8 -4
  200. package/docs-md/start/installation.md +21 -3
  201. package/ios/Animations/ANNFrameDriver.h +55 -15
  202. package/ios/Animations/ANNFrameDriver.mm +216 -60
  203. package/ios/Animations/ANNTransitionAnimator.h +26 -5
  204. package/ios/Animations/ANNTransitionAnimator.mm +61 -13
  205. package/ios/Animations/ANNTransitionPlan.h +2 -2
  206. package/ios/Animations/ANNTransitionPlan.mm +10 -0
  207. package/ios/Animations/ANNTransitionWait.mm +6 -7
  208. package/ios/Animations/Elements/ANNElementFinder.h +57 -0
  209. package/ios/Animations/Elements/ANNElementFinder.mm +174 -2
  210. package/ios/Animations/Elements/ANNElementTransition.h +10 -8
  211. package/ios/Animations/Elements/ANNElementTransition.mm +19 -21
  212. package/ios/Animations/Elements/ANNSharedElementFlight.h +16 -11
  213. package/ios/Animations/Elements/ANNSharedElementFlight.mm +308 -69
  214. package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
  215. package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
  216. package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
  217. package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
  218. package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
  219. package/ios/CLAUDE.md +60 -24
  220. package/ios/CORE.md +44 -34
  221. package/ios/Contract/ANNCommandAnswer.h +13 -5
  222. package/ios/Contract/ANNCommandAnswer.mm +40 -32
  223. package/ios/Contract/ANNCommandContract.h +15 -0
  224. package/ios/Contract/ANNCommandContract.mm +78 -0
  225. package/ios/Contract/ANNCommandRunner.h +10 -9
  226. package/ios/Contract/ANNCommandRunner.mm +22 -28
  227. package/ios/Contract/ANNErrorTexts.h +6 -2
  228. package/ios/Contract/ANNErrorTexts.mm +18 -10
  229. package/ios/Contract/ANNLayoutNode.h +3 -3
  230. package/ios/Contract/ANNLayoutReader.h +3 -3
  231. package/ios/Core/ANNAppDelegate.mm +0 -2
  232. package/ios/Core/ANNAppearanceDispatcher.h +5 -4
  233. package/ios/Core/ANNAppearanceDispatcher.mm +12 -1
  234. package/ios/Core/ANNDeepLinkQueue.h +22 -2
  235. package/ios/Core/ANNDeepLinkQueue.mm +121 -14
  236. package/ios/Core/ANNErrorHandler.h +9 -4
  237. package/ios/Core/ANNErrorHandler.mm +20 -2
  238. package/ios/Core/ANNEventContract.h +246 -0
  239. package/ios/Core/ANNEventContract.mm +225 -0
  240. package/ios/Core/ANNEventEmitter.h +6 -2
  241. package/ios/Core/ANNEventEmitter.mm +117 -80
  242. package/ios/Core/ANNHinge.h +6 -0
  243. package/ios/Core/ANNHinge.mm +15 -4
  244. package/ios/Core/ANNJavaScriptCalls.h +33 -0
  245. package/ios/Core/ANNJavaScriptCalls.mm +52 -0
  246. package/ios/Core/ANNLayoutProtocol.h +5 -5
  247. package/ios/Core/ANNNavigationState.h +7 -5
  248. package/ios/Core/ANNNavigationState.mm +8 -7
  249. package/ios/Core/ANNNodeHelper.h +32 -12
  250. package/ios/Core/ANNNodeHelper.mm +100 -3
  251. package/ios/Core/ANNParking.h +5 -4
  252. package/ios/Core/ANNReloadCoordinator.mm +5 -12
  253. package/ios/Core/ANNRenderWait.h +20 -6
  254. package/ios/Core/ANNRenderWait.mm +143 -56
  255. package/ios/Core/ANNSceneDelegate.mm +25 -15
  256. package/ios/Core/ANNSystemUI.h +3 -2
  257. package/ios/Core/ANNSystemUI.mm +7 -0
  258. package/ios/Core/ANNUtils.h +7 -0
  259. package/ios/Core/ANNUtils.mm +10 -0
  260. package/ios/Core/ApexNavigation+Internal.h +1 -1
  261. package/ios/Core/ApexNavigation.mm +7 -6
  262. package/ios/Core/UIViewController+LayoutProtocol.h +9 -2
  263. package/ios/Core/UIViewController+LayoutProtocol.mm +8 -0
  264. package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
  265. package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
  266. package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +10 -8
  267. package/ios/Layouts/Modal/ANNModalCoordinator.h +1 -1
  268. package/ios/Layouts/Modal/ANNModalCoordinator.mm +57 -16
  269. package/ios/Layouts/Modal/ANNModalPresentation.h +8 -5
  270. package/ios/Layouts/Modal/ANNModalPresentation.mm +12 -12
  271. package/ios/Layouts/Modal/ANNSheetPresenter.mm +83 -1
  272. package/ios/Layouts/Overlay/ANNOverlayCoordinator.mm +2 -8
  273. package/ios/Layouts/Root/ANNRootCoordinator.mm +58 -19
  274. package/ios/Layouts/Root/ANNSplashViewController.h +5 -3
  275. package/ios/Layouts/Root/ANNSplashViewController.mm +147 -0
  276. package/ios/Layouts/Screen/ANNComponentPresenter.h +11 -3
  277. package/ios/Layouts/Screen/ANNComponentPresenter.mm +34 -6
  278. package/ios/Layouts/Screen/ANNComponentViewController.h +15 -13
  279. package/ios/Layouts/Screen/ANNComponentViewController.mm +130 -75
  280. package/ios/Layouts/Screen/ANNNativeScreenContext.mm +7 -5
  281. package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
  282. package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
  283. package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
  284. package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
  285. package/ios/Layouts/Screen/ANNScreenPlace.h +53 -0
  286. package/ios/Layouts/Screen/ANNScreenPlace.mm +205 -0
  287. package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
  288. package/ios/Layouts/Screen/ANNScreenRegions.mm +9 -44
  289. package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
  290. package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
  291. package/ios/Layouts/Screen/ANNScreenSettling.h +32 -0
  292. package/ios/Layouts/Screen/ANNScreenSettling.mm +137 -0
  293. package/ios/Layouts/SideMenu/ANNSideMenuTypes.h +8 -0
  294. package/ios/Layouts/SideMenu/ANNSideMenuViewController.mm +83 -14
  295. package/ios/Layouts/SplitView/ANNSplitViewCommands.h +3 -2
  296. package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +105 -39
  297. package/ios/Layouts/SplitView/ANNSplitViewController.mm +7 -8
  298. package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
  299. package/ios/Layouts/Stack/ANNPreviewPush.mm +142 -27
  300. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
  301. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
  302. package/ios/Layouts/Stack/ANNStackCommands.mm +1 -0
  303. package/ios/Layouts/Stack/ANNStackController.h +8 -0
  304. package/ios/Layouts/Stack/ANNStackController.mm +184 -16
  305. package/ios/Layouts/Stack/ANNStackQueue.h +5 -2
  306. package/ios/Layouts/Stack/ANNStackQueue.mm +56 -43
  307. package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
  308. package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
  309. package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
  310. package/ios/Layouts/Stack/UINavigationController+ANNCommands.h +4 -2
  311. package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +2 -3
  312. package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +4 -0
  313. package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +11 -0
  314. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
  315. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
  316. package/ios/Layouts/Tabs/ANNBottomTabsController.h +3 -0
  317. package/ios/Layouts/Tabs/ANNBottomTabsController.mm +237 -57
  318. package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
  319. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +6 -2
  320. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +232 -43
  321. package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
  322. package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
  323. package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
  324. package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
  325. package/ios/Options/ANNAnimationOptions.h +2 -1
  326. package/ios/Options/ANNAnimationOptions.mm +1 -1
  327. package/ios/Options/ANNBottomTabsOptions.h +2 -0
  328. package/ios/Options/ANNBottomTabsOptions.mm +1 -0
  329. package/ios/Options/ANNOptions.h +25 -0
  330. package/ios/Options/ANNOptions.mm +157 -1
  331. package/ios/Options/ANNOptionsCache.h +7 -6
  332. package/ios/Options/ANNOptionsReader.mm +108 -0
  333. package/ios/Options/ANNSearchBarOptions.h +4 -3
  334. package/ios/Options/ANNSheetOptions.h +4 -1
  335. package/ios/Options/ANNSideMenuOptions.h +2 -0
  336. package/ios/Options/ANNSideMenuOptions.mm +2 -0
  337. package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
  338. package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
  339. package/ios/Options/ANNUserChoice.h +57 -0
  340. package/ios/Options/ANNUserChoice.mm +44 -0
  341. package/ios/Options/Params/ANNImageSource.h +61 -0
  342. package/ios/Options/Params/ANNImageSource.mm +101 -0
  343. package/ios/Options/Params/ANNOptionImages.h +37 -0
  344. package/ios/Options/Params/ANNOptionImages.mm +284 -0
  345. package/ios/Options/Params/ANNParam.h +15 -0
  346. package/ios/Options/Params/ANNParam.mm +61 -0
  347. package/ios/Options/Params/Color.h +3 -0
  348. package/ios/Options/Params/Color.mm +21 -0
  349. package/ios/Options/Params/ColorParser.h +4 -3
  350. package/ios/Options/Params/ColorParser.mm +22 -4
  351. package/ios/Options/Params/Image.h +15 -2
  352. package/ios/Options/Params/Image.mm +35 -2
  353. package/ios/Options/Params/ImageParser.h +5 -5
  354. package/ios/Options/Params/ImageParser.mm +28 -46
  355. package/ios/Public/ApexNavigation/ANNSceneDelegate.h +3 -0
  356. package/ios/Public/ApexNavigation/ApexNavigation.h +1 -1
  357. package/ios/RECIPES.md +13 -6
  358. package/ios/React/ANNReactView.mm +6 -25
  359. package/ios/React/ANNSafeAreaViewComponentView.mm +28 -17
  360. package/ios/React/ANNSurfaceHostingView.h +14 -0
  361. package/ios/React/ANNSurfaceHostingView.mm +144 -1
  362. package/ios/React/Slots/ANNSlotComponentView.mm +24 -17
  363. package/ios/React/Slots/ANNSlotContainers.h +14 -6
  364. package/ios/React/Slots/ANNSlotContainers.mm +75 -2
  365. package/ios/React/Slots/ANNSlotHost.mm +1 -3
  366. package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
  367. package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
  368. package/ios/TopBar/ANNBarAppearance.h +2 -1
  369. package/ios/TopBar/ANNBarAppearance.mm +111 -30
  370. package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
  371. package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
  372. package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
  373. package/ios/TopBar/ANNBarButtons.h +14 -8
  374. package/ios/TopBar/ANNBarButtons.mm +397 -80
  375. package/ios/TopBar/ANNIconButtonImage.h +1 -0
  376. package/ios/TopBar/ANNIconButtonImage.mm +34 -1
  377. package/ios/TopBar/ANNLargeTitlePresenter.h +13 -0
  378. package/ios/TopBar/ANNLargeTitlePresenter.mm +50 -7
  379. package/ios/TopBar/ANNMainList.h +3 -0
  380. package/ios/TopBar/ANNMainList.mm +4 -0
  381. package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
  382. package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
  383. package/ios/TopBar/ANNSearchPresenter.mm +172 -21
  384. package/ios/TopBar/ANNSearchResultsViewController.mm +29 -6
  385. package/ios/TopBar/ANNTopBarPresenter.h +8 -2
  386. package/ios/TopBar/ANNTopBarPresenter.mm +155 -33
  387. package/ios/TurboModules/ANNTurboEventEmitter.mm +4 -35
  388. package/ios/TurboModules/ANNTurboModule.mm +104 -33
  389. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
  390. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
  391. package/lib/module/ARCHITECTURE.md +40 -27
  392. package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
  393. package/lib/module/api/app/AppRegistry.js +14 -2
  394. package/lib/module/api/app/AppRegistry.js.map +1 -1
  395. package/lib/module/api/app/createNavigation.js +190 -66
  396. package/lib/module/api/app/createNavigation.js.map +1 -1
  397. package/lib/module/api/commands/commands.js +54 -6
  398. package/lib/module/api/commands/commands.js.map +1 -1
  399. package/lib/module/api/events/navigationEvents.js +6 -2
  400. package/lib/module/api/events/navigationEvents.js.map +1 -1
  401. package/lib/module/api/hooks/useNavigation.js +8 -3
  402. package/lib/module/api/hooks/useNavigation.js.map +1 -1
  403. package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
  404. package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
  405. package/lib/module/api/linking/dispatchedLinks.js +23 -0
  406. package/lib/module/api/linking/dispatchedLinks.js.map +1 -0
  407. package/lib/module/api/linking/linking.js +11 -0
  408. package/lib/module/api/linking/linking.js.map +1 -1
  409. package/lib/module/api/navigation.js.map +1 -1
  410. package/lib/module/api/options/OptionsChain.js +2 -2
  411. package/lib/module/api/screens/defineScreen.js +45 -3
  412. package/lib/module/api/screens/defineScreen.js.map +1 -1
  413. package/lib/module/api/screens/nativeScreens.js +31 -6
  414. package/lib/module/api/screens/nativeScreens.js.map +1 -1
  415. package/lib/module/api/screens/registerScreens.js +193 -35
  416. package/lib/module/api/screens/registerScreens.js.map +1 -1
  417. package/lib/module/api/theme/theme.js +5 -0
  418. package/lib/module/api/theme/theme.js.map +1 -1
  419. package/lib/module/engine/commands.js +51 -9
  420. package/lib/module/engine/commands.js.map +1 -1
  421. package/lib/module/engine/layout.js +20 -11
  422. package/lib/module/engine/layout.js.map +1 -1
  423. package/lib/module/engine/nativeScreens.js +9 -0
  424. package/lib/module/engine/nativeScreens.js.map +1 -1
  425. package/lib/module/engine/options.js +49 -15
  426. package/lib/module/engine/options.js.map +1 -1
  427. package/lib/module/engine/optionsChange.js +102 -0
  428. package/lib/module/engine/optionsChange.js.map +1 -0
  429. package/lib/module/engine/places.js +52 -7
  430. package/lib/module/engine/places.js.map +1 -1
  431. package/lib/module/engine/props.js +30 -1
  432. package/lib/module/engine/props.js.map +1 -1
  433. package/lib/module/engine/refresh.js +85 -0
  434. package/lib/module/engine/refresh.js.map +1 -0
  435. package/lib/module/engine/rememberedOptions.js +61 -1
  436. package/lib/module/engine/rememberedOptions.js.map +1 -1
  437. package/lib/module/engine/screens.js +77 -16
  438. package/lib/module/engine/screens.js.map +1 -1
  439. package/lib/module/interfaces/contract/commands.json +101 -0
  440. package/lib/module/interfaces/contract/errors.json +275 -0
  441. package/lib/typescript/adapters/NativeANNTurboModule.d.ts +12 -2
  442. package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
  443. package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
  444. package/lib/typescript/api/app/createNavigation.d.ts +8 -3
  445. package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
  446. package/lib/typescript/api/commands/commands.d.ts.map +1 -1
  447. package/lib/typescript/api/commands/presentation.d.ts +4 -3
  448. package/lib/typescript/api/commands/presentation.d.ts.map +1 -1
  449. package/lib/typescript/api/events/navigationEvents.d.ts +3 -3
  450. package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
  451. package/lib/typescript/api/hooks/useNavigation.d.ts +1 -1
  452. package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -1
  453. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
  454. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
  455. package/lib/typescript/api/index.d.ts +1 -1
  456. package/lib/typescript/api/index.d.ts.map +1 -1
  457. package/lib/typescript/api/linking/dispatchedLinks.d.ts +7 -0
  458. package/lib/typescript/api/linking/dispatchedLinks.d.ts.map +1 -0
  459. package/lib/typescript/api/linking/linking.d.ts +8 -0
  460. package/lib/typescript/api/linking/linking.d.ts.map +1 -1
  461. package/lib/typescript/api/navigation.d.ts +4 -1
  462. package/lib/typescript/api/navigation.d.ts.map +1 -1
  463. package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
  464. package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
  465. package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
  466. package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
  467. package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
  468. package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
  469. package/lib/typescript/api/theme/theme.d.ts +2 -0
  470. package/lib/typescript/api/theme/theme.d.ts.map +1 -1
  471. package/lib/typescript/engine/commands.d.ts +5 -0
  472. package/lib/typescript/engine/commands.d.ts.map +1 -1
  473. package/lib/typescript/engine/layout.d.ts.map +1 -1
  474. package/lib/typescript/engine/nativeScreens.d.ts +5 -0
  475. package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
  476. package/lib/typescript/engine/options.d.ts +5 -2
  477. package/lib/typescript/engine/options.d.ts.map +1 -1
  478. package/lib/typescript/engine/optionsChange.d.ts +28 -0
  479. package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
  480. package/lib/typescript/engine/places.d.ts +7 -2
  481. package/lib/typescript/engine/places.d.ts.map +1 -1
  482. package/lib/typescript/engine/props.d.ts +8 -1
  483. package/lib/typescript/engine/props.d.ts.map +1 -1
  484. package/lib/typescript/engine/refresh.d.ts +35 -0
  485. package/lib/typescript/engine/refresh.d.ts.map +1 -0
  486. package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
  487. package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
  488. package/lib/typescript/engine/screens.d.ts +27 -6
  489. package/lib/typescript/engine/screens.d.ts.map +1 -1
  490. package/lib/typescript/interfaces/ComponentEvents.d.ts +4 -4
  491. package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -1
  492. package/lib/typescript/interfaces/Events.d.ts +28 -10
  493. package/lib/typescript/interfaces/Events.d.ts.map +1 -1
  494. package/lib/typescript/interfaces/Options.d.ts +1 -1
  495. package/lib/typescript/interfaces/Options.d.ts.map +1 -1
  496. package/lib/typescript/interfaces/options/animations.d.ts +80 -22
  497. package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
  498. package/lib/typescript/interfaces/options/bottomTabs.d.ts +21 -7
  499. package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
  500. package/lib/typescript/interfaces/options/buttons.d.ts +23 -15
  501. package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -1
  502. package/lib/typescript/interfaces/options/modals.d.ts +34 -26
  503. package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
  504. package/lib/typescript/interfaces/options/sideMenu.d.ts +23 -6
  505. package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -1
  506. package/lib/typescript/interfaces/options/stack.d.ts +17 -3
  507. package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
  508. package/lib/typescript/interfaces/options/system.d.ts +18 -11
  509. package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
  510. package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
  511. package/lib/typescript/interfaces/options/topBar.d.ts +68 -38
  512. package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
  513. package/metro/acceptPlugin.js +57 -0
  514. package/metro/babelTransformer.js +45 -0
  515. package/metro/index.js +36 -0
  516. package/package.json +4 -25
  517. package/src/ARCHITECTURE.md +40 -27
  518. package/src/adapters/NativeANNTurboModule.ts +12 -2
  519. package/src/api/app/AppRegistry.ts +16 -2
  520. package/src/api/app/createNavigation.ts +203 -69
  521. package/src/api/commands/commands.ts +48 -7
  522. package/src/api/commands/presentation.ts +4 -3
  523. package/src/api/events/navigationEvents.ts +10 -4
  524. package/src/api/hooks/useNavigation.ts +9 -4
  525. package/src/api/hooks/useSafeAreaInsets.ts +4 -3
  526. package/src/api/index.ts +1 -0
  527. package/src/api/linking/dispatchedLinks.ts +18 -0
  528. package/src/api/linking/linking.ts +22 -1
  529. package/src/api/navigation.ts +4 -1
  530. package/src/api/options/OptionsChain.ts +2 -2
  531. package/src/api/screens/defineScreen.ts +49 -5
  532. package/src/api/screens/nativeScreens.ts +40 -4
  533. package/src/api/screens/registerScreens.tsx +185 -42
  534. package/src/api/theme/theme.ts +5 -0
  535. package/src/engine/commands.ts +70 -13
  536. package/src/engine/layout.ts +27 -11
  537. package/src/engine/nativeScreens.ts +10 -1
  538. package/src/engine/options.ts +45 -19
  539. package/src/engine/optionsChange.ts +107 -0
  540. package/src/engine/places.ts +65 -7
  541. package/src/engine/props.ts +30 -1
  542. package/src/engine/refresh.ts +97 -0
  543. package/src/engine/rememberedOptions.ts +74 -1
  544. package/src/engine/screens.tsx +76 -21
  545. package/src/interfaces/ComponentEvents.ts +4 -4
  546. package/src/interfaces/Events.ts +29 -10
  547. package/src/interfaces/Options.ts +1 -0
  548. package/src/interfaces/contract/commands.json +101 -0
  549. package/src/interfaces/contract/errors.json +275 -0
  550. package/src/interfaces/options/animations.ts +81 -22
  551. package/src/interfaces/options/bottomTabs.ts +21 -7
  552. package/src/interfaces/options/buttons.ts +23 -15
  553. package/src/interfaces/options/modals.ts +34 -26
  554. package/src/interfaces/options/sideMenu.ts +24 -6
  555. package/src/interfaces/options/stack.ts +17 -3
  556. package/src/interfaces/options/system.ts +18 -11
  557. package/src/interfaces/options/toolbar.ts +2 -2
  558. package/src/interfaces/options/topBar.ts +68 -38
  559. package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -41
  560. package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -69
  561. package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +0 -62
  562. package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +0 -62
  563. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
  564. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
  565. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -138
  566. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -88
  567. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
  568. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -66
  569. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -179
  570. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -139
  571. package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
  572. package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -68
  573. package/ios/Layouts/Tabs/ANNTabsPreloadWindow.h +0 -27
  574. package/ios/Layouts/Tabs/ANNTabsPreloadWindow.mm +0 -55
@@ -0,0 +1,507 @@
1
+ #import "ANNTransformParts.h"
2
+ #import <React/RCTLog.h>
3
+ #include <algorithm>
4
+ #include <cmath>
5
+
6
+ // The math works on m[i][j] = m(i+1)(j+1) of `CATransform3D`: a row is what a point's coordinate multiplies (row
7
+ // vectors), the layout of the decomposition's own pseudo-code (its matrix[3][0..2] is the translation).
8
+ typedef double ANNMatrix[4][4];
9
+
10
+ static void ANNMatrixOf(CATransform3D t, ANNMatrix m) {
11
+ const CGFloat values[16] = {t.m11, t.m12, t.m13, t.m14, t.m21, t.m22, t.m23, t.m24,
12
+ t.m31, t.m32, t.m33, t.m34, t.m41, t.m42, t.m43, t.m44};
13
+ for (int i = 0; i < 16; i++) {
14
+ m[i / 4][i % 4] = values[i];
15
+ }
16
+ }
17
+
18
+ static CATransform3D ANNTransformOfMatrix(const ANNMatrix m) {
19
+ CATransform3D t;
20
+ t.m11 = m[0][0];
21
+ t.m12 = m[0][1];
22
+ t.m13 = m[0][2];
23
+ t.m14 = m[0][3];
24
+ t.m21 = m[1][0];
25
+ t.m22 = m[1][1];
26
+ t.m23 = m[1][2];
27
+ t.m24 = m[1][3];
28
+ t.m31 = m[2][0];
29
+ t.m32 = m[2][1];
30
+ t.m33 = m[2][2];
31
+ t.m34 = m[2][3];
32
+ t.m41 = m[3][0];
33
+ t.m42 = m[3][1];
34
+ t.m43 = m[3][2];
35
+ t.m44 = m[3][3];
36
+ return t;
37
+ }
38
+
39
+ static void ANNMatrixIdentity(ANNMatrix m) {
40
+ for (int i = 0; i < 4; i++) {
41
+ for (int j = 0; j < 4; j++) {
42
+ m[i][j] = i == j ? 1 : 0;
43
+ }
44
+ }
45
+ }
46
+
47
+ // a · b: the point goes through a, then through b.
48
+ static void ANNMatrixMultiply(const ANNMatrix a, const ANNMatrix b, ANNMatrix out) {
49
+ ANNMatrix product;
50
+ for (int i = 0; i < 4; i++) {
51
+ for (int j = 0; j < 4; j++) {
52
+ double sum = 0;
53
+ for (int k = 0; k < 4; k++) {
54
+ sum += a[i][k] * b[k][j];
55
+ }
56
+ product[i][j] = sum;
57
+ }
58
+ }
59
+ memcpy(out, product, sizeof(ANNMatrix));
60
+ }
61
+
62
+ // The inverse of m into `out`; NO when m has none.
63
+ static BOOL ANNMatrixInvert(const ANNMatrix m, ANNMatrix out) {
64
+ const double *a = &m[0][0];
65
+ double inv[16];
66
+ inv[0] = a[5] * a[10] * a[15] - a[5] * a[11] * a[14] - a[9] * a[6] * a[15] +
67
+ a[9] * a[7] * a[14] + a[13] * a[6] * a[11] - a[13] * a[7] * a[10];
68
+ inv[4] = -a[4] * a[10] * a[15] + a[4] * a[11] * a[14] + a[8] * a[6] * a[15] -
69
+ a[8] * a[7] * a[14] - a[12] * a[6] * a[11] + a[12] * a[7] * a[10];
70
+ inv[8] = a[4] * a[9] * a[15] - a[4] * a[11] * a[13] - a[8] * a[5] * a[15] +
71
+ a[8] * a[7] * a[13] + a[12] * a[5] * a[11] - a[12] * a[7] * a[9];
72
+ inv[12] = -a[4] * a[9] * a[14] + a[4] * a[10] * a[13] + a[8] * a[5] * a[14] -
73
+ a[8] * a[6] * a[13] - a[12] * a[5] * a[10] + a[12] * a[6] * a[9];
74
+ inv[1] = -a[1] * a[10] * a[15] + a[1] * a[11] * a[14] + a[9] * a[2] * a[15] -
75
+ a[9] * a[3] * a[14] - a[13] * a[2] * a[11] + a[13] * a[3] * a[10];
76
+ inv[5] = a[0] * a[10] * a[15] - a[0] * a[11] * a[14] - a[8] * a[2] * a[15] +
77
+ a[8] * a[3] * a[14] + a[12] * a[2] * a[11] - a[12] * a[3] * a[10];
78
+ inv[9] = -a[0] * a[9] * a[15] + a[0] * a[11] * a[13] + a[8] * a[1] * a[15] -
79
+ a[8] * a[3] * a[13] - a[12] * a[1] * a[11] + a[12] * a[3] * a[9];
80
+ inv[13] = a[0] * a[9] * a[14] - a[0] * a[10] * a[13] - a[8] * a[1] * a[14] +
81
+ a[8] * a[2] * a[13] + a[12] * a[1] * a[10] - a[12] * a[2] * a[9];
82
+ inv[2] = a[1] * a[6] * a[15] - a[1] * a[7] * a[14] - a[5] * a[2] * a[15] +
83
+ a[5] * a[3] * a[14] + a[13] * a[2] * a[7] - a[13] * a[3] * a[6];
84
+ inv[6] = -a[0] * a[6] * a[15] + a[0] * a[7] * a[14] + a[4] * a[2] * a[15] -
85
+ a[4] * a[3] * a[14] - a[12] * a[2] * a[7] + a[12] * a[3] * a[6];
86
+ inv[10] = a[0] * a[5] * a[15] - a[0] * a[7] * a[13] - a[4] * a[1] * a[15] +
87
+ a[4] * a[3] * a[13] + a[12] * a[1] * a[7] - a[12] * a[3] * a[5];
88
+ inv[14] = -a[0] * a[5] * a[14] + a[0] * a[6] * a[13] + a[4] * a[1] * a[14] -
89
+ a[4] * a[2] * a[13] - a[12] * a[1] * a[6] + a[12] * a[2] * a[5];
90
+ inv[3] = -a[1] * a[6] * a[11] + a[1] * a[7] * a[10] + a[5] * a[2] * a[11] -
91
+ a[5] * a[3] * a[10] - a[9] * a[2] * a[7] + a[9] * a[3] * a[6];
92
+ inv[7] = a[0] * a[6] * a[11] - a[0] * a[7] * a[10] - a[4] * a[2] * a[11] +
93
+ a[4] * a[3] * a[10] + a[8] * a[2] * a[7] - a[8] * a[3] * a[6];
94
+ inv[11] = -a[0] * a[5] * a[11] + a[0] * a[7] * a[9] + a[4] * a[1] * a[11] -
95
+ a[4] * a[3] * a[9] - a[8] * a[1] * a[7] + a[8] * a[3] * a[5];
96
+ inv[15] = a[0] * a[5] * a[10] - a[0] * a[6] * a[9] - a[4] * a[1] * a[10] +
97
+ a[4] * a[2] * a[9] + a[8] * a[1] * a[6] - a[8] * a[2] * a[5];
98
+ double determinant = a[0] * inv[0] + a[1] * inv[4] + a[2] * inv[8] + a[3] * inv[12];
99
+ if (determinant == 0 || !std::isfinite(determinant)) {
100
+ return NO;
101
+ }
102
+ for (int i = 0; i < 16; i++) {
103
+ out[i / 4][i % 4] = inv[i] / determinant;
104
+ }
105
+ return YES;
106
+ }
107
+
108
+ static double ANNLength(const double v[3]) {
109
+ return std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
110
+ }
111
+
112
+ static double ANNDot(const double a[3], const double b[3]) {
113
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
114
+ }
115
+
116
+ // a·sa + b·sb into a.
117
+ static void ANNCombine(double a[3], const double b[3], double sa, double sb) {
118
+ for (int i = 0; i < 3; i++) {
119
+ a[i] = a[i] * sa + b[i] * sb;
120
+ }
121
+ }
122
+
123
+ ANNTransformParts ANNTransformPartsIdentity(void) {
124
+ ANNTransformParts parts = {};
125
+ parts.scale[0] = parts.scale[1] = parts.scale[2] = 1;
126
+ parts.perspective[3] = 1;
127
+ parts.quaternion[3] = 1;
128
+ return parts;
129
+ }
130
+
131
+ BOOL ANNTransformPartsOf(CATransform3D transform, ANNTransformParts *parts) {
132
+ ANNMatrix m;
133
+ ANNMatrixOf(transform, m);
134
+ if (m[3][3] == 0) {
135
+ return NO;
136
+ }
137
+ double w = m[3][3];
138
+ for (int i = 0; i < 4; i++) {
139
+ for (int j = 0; j < 4; j++) {
140
+ m[i][j] /= w;
141
+ }
142
+ }
143
+ // The perspective's own matrix: the rest without the perspective column; it also tells a flat transform.
144
+ ANNMatrix perspectiveMatrix;
145
+ memcpy(perspectiveMatrix, m, sizeof(ANNMatrix));
146
+ for (int i = 0; i < 3; i++) {
147
+ perspectiveMatrix[i][3] = 0;
148
+ }
149
+ perspectiveMatrix[3][3] = 1;
150
+ ANNMatrix inverse;
151
+ if (!ANNMatrixInvert(perspectiveMatrix, inverse)) {
152
+ return NO;
153
+ }
154
+ ANNTransformParts result = {};
155
+ if (m[0][3] != 0 || m[1][3] != 0 || m[2][3] != 0) {
156
+ const double right[4] = {m[0][3], m[1][3], m[2][3], m[3][3]};
157
+ // right · (inverse transposed): each component is a row of the inverse dotted with `right`.
158
+ for (int i = 0; i < 4; i++) {
159
+ double sum = 0;
160
+ for (int j = 0; j < 4; j++) {
161
+ sum += right[j] * inverse[i][j];
162
+ }
163
+ result.perspective[i] = sum;
164
+ }
165
+ } else {
166
+ result.perspective[3] = 1;
167
+ }
168
+ for (int i = 0; i < 3; i++) {
169
+ result.translate[i] = m[3][i];
170
+ }
171
+ double row[3][3];
172
+ for (int i = 0; i < 3; i++) {
173
+ for (int j = 0; j < 3; j++) {
174
+ row[i][j] = m[i][j];
175
+ }
176
+ }
177
+ result.scale[0] = ANNLength(row[0]);
178
+ if (result.scale[0] == 0) {
179
+ return NO;
180
+ }
181
+ ANNCombine(row[0], row[0], 1 / result.scale[0], 0);
182
+ result.skew[0] = ANNDot(row[0], row[1]);
183
+ ANNCombine(row[1], row[0], 1, -result.skew[0]);
184
+ result.scale[1] = ANNLength(row[1]);
185
+ if (result.scale[1] == 0) {
186
+ return NO;
187
+ }
188
+ ANNCombine(row[1], row[1], 1 / result.scale[1], 0);
189
+ result.skew[0] /= result.scale[1];
190
+ result.skew[1] = ANNDot(row[0], row[2]);
191
+ ANNCombine(row[2], row[0], 1, -result.skew[1]);
192
+ result.skew[2] = ANNDot(row[1], row[2]);
193
+ ANNCombine(row[2], row[1], 1, -result.skew[2]);
194
+ result.scale[2] = ANNLength(row[2]);
195
+ if (result.scale[2] == 0) {
196
+ return NO;
197
+ }
198
+ ANNCombine(row[2], row[2], 1 / result.scale[2], 0);
199
+ result.skew[1] /= result.scale[2];
200
+ result.skew[2] /= result.scale[2];
201
+ // The rows are orthonormal now; a mirrored system turns into a rotation with every scale negated. A flat transform
202
+ // (nothing out of the screen's plane) negates only x and keeps its rotation in the plane, as Android's views hold a
203
+ // mirror: it then flips across the element's own axis on the way, on both platforms, rather than through 3D.
204
+ const double cross[3] = {row[1][1] * row[2][2] - row[1][2] * row[2][1],
205
+ row[1][2] * row[2][0] - row[1][0] * row[2][2],
206
+ row[1][0] * row[2][1] - row[1][1] * row[2][0]};
207
+ if (ANNDot(row[0], cross) < 0) {
208
+ const double flatness = std::fabs(m[0][2]) + std::fabs(m[1][2]) + std::fabs(m[2][0]) +
209
+ std::fabs(m[2][1]) + std::fabs(m[0][3]) + std::fabs(m[1][3]) +
210
+ std::fabs(m[2][3]);
211
+ const int negated = flatness < 1e-9 ? 1 : 3;
212
+ for (int i = 0; i < negated; i++) {
213
+ result.scale[i] = -result.scale[i];
214
+ ANNCombine(row[i], row[i], -1, 0);
215
+ }
216
+ }
217
+ // The quaternion by Shepperd's method, from the largest of its four terms: the signs of the others follow from
218
+ // the off-diagonal terms, also for half a turn (w = 0), where the comparisons of the pseudo-code lose them. `r` is
219
+ // the rotation for column vectors, the transpose of the rows.
220
+ auto r = [&row](int i, int j) {
221
+ return row[j][i];
222
+ };
223
+ double *q = result.quaternion;
224
+ double trace = r(0, 0) + r(1, 1) + r(2, 2);
225
+ if (trace > 0) {
226
+ double s = 2 * std::sqrt(trace + 1);
227
+ q[3] = s / 4;
228
+ q[0] = (r(2, 1) - r(1, 2)) / s;
229
+ q[1] = (r(0, 2) - r(2, 0)) / s;
230
+ q[2] = (r(1, 0) - r(0, 1)) / s;
231
+ } else if (r(0, 0) > r(1, 1) && r(0, 0) > r(2, 2)) {
232
+ double s = 2 * std::sqrt(1 + r(0, 0) - r(1, 1) - r(2, 2));
233
+ q[3] = (r(2, 1) - r(1, 2)) / s;
234
+ q[0] = s / 4;
235
+ q[1] = (r(0, 1) + r(1, 0)) / s;
236
+ q[2] = (r(0, 2) + r(2, 0)) / s;
237
+ } else if (r(1, 1) > r(2, 2)) {
238
+ double s = 2 * std::sqrt(1 + r(1, 1) - r(0, 0) - r(2, 2));
239
+ q[3] = (r(0, 2) - r(2, 0)) / s;
240
+ q[0] = (r(0, 1) + r(1, 0)) / s;
241
+ q[1] = s / 4;
242
+ q[2] = (r(1, 2) + r(2, 1)) / s;
243
+ } else {
244
+ double s = 2 * std::sqrt(1 + r(2, 2) - r(0, 0) - r(1, 1));
245
+ q[3] = (r(1, 0) - r(0, 1)) / s;
246
+ q[0] = (r(0, 2) + r(2, 0)) / s;
247
+ q[1] = (r(1, 2) + r(2, 1)) / s;
248
+ q[2] = s / 4;
249
+ }
250
+ *parts = result;
251
+ return YES;
252
+ }
253
+
254
+ // The rotation of a unit quaternion as a matrix of row vectors: the transpose of the decomposition's pseudo-code,
255
+ // whose matrix is written for column vectors there.
256
+ static void ANNRotationMatrixOf(const double q[4], ANNMatrix m) {
257
+ double x = q[0], y = q[1], z = q[2], w = q[3];
258
+ ANNMatrixIdentity(m);
259
+ m[0][0] = 1 - 2 * (y * y + z * z);
260
+ m[0][1] = 2 * (x * y + z * w);
261
+ m[0][2] = 2 * (x * z - y * w);
262
+ m[1][0] = 2 * (x * y - z * w);
263
+ m[1][1] = 1 - 2 * (x * x + z * z);
264
+ m[1][2] = 2 * (y * z + x * w);
265
+ m[2][0] = 2 * (x * z + y * w);
266
+ m[2][1] = 2 * (y * z - x * w);
267
+ m[2][2] = 1 - 2 * (x * x + y * y);
268
+ }
269
+
270
+ // The shears as the decomposition took them off the rows: row 1 gains xy of row 0, row 2 xz of row 0 and yz of row 1.
271
+ static void ANNSkewMatrixOf(const double skew[3], ANNMatrix m) {
272
+ ANNMatrixIdentity(m);
273
+ m[1][0] = skew[0];
274
+ m[2][0] = skew[1];
275
+ m[2][1] = skew[2];
276
+ }
277
+
278
+ CATransform3D ANNTransformOfParts(ANNTransformParts parts) {
279
+ // Built from the last step back: perspective, translation, rotation, skew, then the scale goes first.
280
+ ANNMatrix m;
281
+ ANNMatrixIdentity(m);
282
+ for (int i = 0; i < 4; i++) {
283
+ m[i][3] = parts.perspective[i];
284
+ }
285
+ for (int i = 0; i < 4; i++) {
286
+ for (int j = 0; j < 3; j++) {
287
+ m[3][i] += parts.translate[j] * m[j][i];
288
+ }
289
+ }
290
+ ANNMatrix rotation;
291
+ ANNRotationMatrixOf(parts.quaternion, rotation);
292
+ ANNMatrixMultiply(rotation, m, m);
293
+ ANNMatrix skew;
294
+ ANNSkewMatrixOf(parts.skew, skew);
295
+ ANNMatrixMultiply(skew, m, m);
296
+ for (int i = 0; i < 3; i++) {
297
+ for (int j = 0; j < 4; j++) {
298
+ m[i][j] *= parts.scale[i];
299
+ }
300
+ }
301
+ return ANNTransformOfMatrix(m);
302
+ }
303
+
304
+ static double ANNLerp(double from, double to, double f) {
305
+ return from + f * (to - from);
306
+ }
307
+
308
+ ANNTransformParts ANNInterpolateTransformParts(ANNTransformParts from, ANNTransformParts to,
309
+ double f) {
310
+ if (f == 0) {
311
+ return from;
312
+ }
313
+ if (f == 1) {
314
+ return to;
315
+ }
316
+ ANNTransformParts parts;
317
+ for (int i = 0; i < 3; i++) {
318
+ parts.translate[i] = ANNLerp(from.translate[i], to.translate[i], f);
319
+ parts.scale[i] = ANNLerp(from.scale[i], to.scale[i], f);
320
+ parts.skew[i] = ANNLerp(from.skew[i], to.skew[i], f);
321
+ }
322
+ for (int i = 0; i < 4; i++) {
323
+ parts.perspective[i] = ANNLerp(from.perspective[i], to.perspective[i], f);
324
+ }
325
+ // The slerp, along the shorter arc: q and −q are the same rotation.
326
+ const double *a = from.quaternion;
327
+ double b[4] = {to.quaternion[0], to.quaternion[1], to.quaternion[2], to.quaternion[3]};
328
+ double product = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
329
+ if (product < 0) {
330
+ for (int i = 0; i < 4; i++) {
331
+ b[i] = -b[i];
332
+ }
333
+ product = -product;
334
+ }
335
+ product = std::min(product, 1.0);
336
+ if (product >= 1.0 - 1e-12) {
337
+ for (int i = 0; i < 4; i++) {
338
+ parts.quaternion[i] = ANNLerp(a[i], b[i], f);
339
+ }
340
+ return parts;
341
+ }
342
+ double theta = std::acos(product);
343
+ double sinTheta = std::sqrt(1 - product * product);
344
+ double wa = std::sin((1 - f) * theta) / sinTheta;
345
+ double wb = std::sin(f * theta) / sinTheta;
346
+ for (int i = 0; i < 4; i++) {
347
+ parts.quaternion[i] = a[i] * wa + b[i] * wb;
348
+ }
349
+ return parts;
350
+ }
351
+
352
+ void ANNRotationDegreesOf(ANNTransformParts parts, double *x, double *y, double *z) {
353
+ ANNMatrix r;
354
+ ANNRotationMatrixOf(parts.quaternion, r);
355
+ // r = Rx(a)·Ry(b)·Rz(c) in row vectors: r[0][2] = −sin b, r[1][2] = sin a·cos b, r[2][2] = cos a·cos b,
356
+ // r[0][1] = cos b·sin c, r[0][0] = cos b·cos c.
357
+ double sinB = std::max(-1.0, std::min(1.0, -r[0][2]));
358
+ double b = std::asin(sinB);
359
+ double a;
360
+ double c;
361
+ if (std::fabs(std::cos(b)) > 1e-6) {
362
+ a = std::atan2(r[1][2], r[2][2]);
363
+ c = std::atan2(r[0][1], r[0][0]);
364
+ } else {
365
+ // Turned a quarter about y: x and z turn about one axis, all of it goes to x.
366
+ c = 0;
367
+ a = std::atan2(sinB * r[1][0], r[1][1]);
368
+ }
369
+ const double degrees = 180.0 / M_PI;
370
+ *x = a * degrees;
371
+ *y = b * degrees;
372
+ *z = c * degrees;
373
+ }
374
+
375
+ CATransform3D ANNSkewTransformOf(ANNTransformParts parts) {
376
+ ANNMatrix m;
377
+ ANNSkewMatrixOf(parts.skew, m);
378
+ return ANNTransformOfMatrix(m);
379
+ }
380
+
381
+ #if DEBUG
382
+
383
+ static BOOL ANNSameTransform(CATransform3D a, CATransform3D b, double tolerance) {
384
+ ANNMatrix ma;
385
+ ANNMatrix mb;
386
+ ANNMatrixOf(a, ma);
387
+ ANNMatrixOf(b, mb);
388
+ for (int i = 0; i < 4; i++) {
389
+ for (int j = 0; j < 4; j++) {
390
+ if (!(std::fabs(ma[i][j] - mb[i][j]) <= tolerance)) {
391
+ return NO;
392
+ }
393
+ }
394
+ }
395
+ return YES;
396
+ }
397
+
398
+ static void ANNExpectTransform(const char *what, CATransform3D value, CATransform3D expected) {
399
+ if (!ANNSameTransform(value, expected, 1e-6)) {
400
+ RCTLogWarn(@"[ApexNavigation] transform self-check: %s is off", what);
401
+ }
402
+ }
403
+
404
+ static CATransform3D ANNRotationZ(double degrees) {
405
+ return CATransform3DMakeRotation(degrees * M_PI / 180.0, 0, 0, 1);
406
+ }
407
+
408
+ // The transform at f of the way from `from` to `to`, split and rebuilt.
409
+ static CATransform3D ANNTransformBetween(CATransform3D from, CATransform3D to, double f) {
410
+ ANNTransformParts a;
411
+ ANNTransformParts b;
412
+ if (!ANNTransformPartsOf(from, &a) || !ANNTransformPartsOf(to, &b)) {
413
+ return CATransform3DIdentity;
414
+ }
415
+ return ANNTransformOfParts(ANNInterpolateTransformParts(a, b, f));
416
+ }
417
+
418
+ void ANNTransformPartsSelfCheck(void) {
419
+ static dispatch_once_t once;
420
+ dispatch_once(&once, ^{
421
+ CATransform3D tilt = CATransform3DMakeRotation(40 * M_PI / 180.0, 1, 0, 0);
422
+ tilt.m34 = -1.0 / 500;
423
+ CATransform3D shear = CATransform3DIdentity;
424
+ shear.m21 = 0.3;
425
+ const struct {
426
+ const char *name;
427
+ CATransform3D transform;
428
+ } splits[] = {
429
+ {"a rotation of 90", ANNRotationZ(90)},
430
+ {"a rotation of 180", ANNRotationZ(180)},
431
+ {"a scale, a rotation and a translation",
432
+ CATransform3DConcat(CATransform3DConcat(CATransform3DMakeScale(2, 0.5, 1),
433
+ ANNRotationZ(30)),
434
+ CATransform3DMakeTranslation(12, -7, 0))},
435
+ {"a skew", CATransform3DConcat(shear, ANNRotationZ(-20))},
436
+ {"a tilt with perspective", tilt},
437
+ {"a mirror", CATransform3DMakeScale(-1, 1, 1)},
438
+ {"a mirror and a turn of 30",
439
+ CATransform3DConcat(ANNRotationZ(30), CATransform3DMakeScale(-1, 1, 1))},
440
+ {"a turn of -90 and a mirror",
441
+ CATransform3DConcat(CATransform3DMakeScale(-1, 1, 1), ANNRotationZ(-90))},
442
+ {"a mirror upside down and a turn of -30",
443
+ CATransform3DConcat(ANNRotationZ(-30), CATransform3DMakeScale(1, -1, 1))},
444
+ {"half a turn and a tilt",
445
+ CATransform3DConcat(ANNRotationZ(180),
446
+ CATransform3DMakeRotation(20 * M_PI / 180.0, 1, 0, 0))},
447
+ };
448
+ for (const auto &split : splits) {
449
+ ANNTransformParts parts;
450
+ if (!ANNTransformPartsOf(split.transform, &parts)) {
451
+ RCTLogWarn(@"[ApexNavigation] transform self-check: %s can't be split", split.name);
452
+ continue;
453
+ }
454
+ ANNExpectTransform(split.name, ANNTransformOfParts(parts), split.transform);
455
+ }
456
+ ANNExpectTransform("0 to 90 half way",
457
+ ANNTransformBetween(ANNRotationZ(0), ANNRotationZ(90), 0.5),
458
+ ANNRotationZ(45));
459
+ ANNExpectTransform("45 to -45 half way",
460
+ ANNTransformBetween(ANNRotationZ(45), ANNRotationZ(-45), 0.5),
461
+ CATransform3DIdentity);
462
+ ANNExpectTransform("0 to 270 half way, the shorter arc",
463
+ ANNTransformBetween(ANNRotationZ(0), ANNRotationZ(270), 0.5),
464
+ ANNRotationZ(-45));
465
+ ANNExpectTransform("170 to -170 half way, the shorter arc",
466
+ ANNTransformBetween(ANNRotationZ(170), ANNRotationZ(-170), 0.5),
467
+ ANNRotationZ(180));
468
+ ANNExpectTransform("a scale half way",
469
+ ANNTransformBetween(CATransform3DIdentity,
470
+ CATransform3DMakeScale(3, 2, 1), 0.5),
471
+ CATransform3DMakeScale(2, 1.5, 1));
472
+ // Half a turn keeps its size on the way: a quarter turn, either way, half way.
473
+ CATransform3D half = ANNTransformBetween(ANNRotationZ(0), ANNRotationZ(180), 0.5);
474
+ if (!ANNSameTransform(half, ANNRotationZ(90), 1e-6) &&
475
+ !ANNSameTransform(half, ANNRotationZ(-90), 1e-6)) {
476
+ RCTLogWarn(@"[ApexNavigation] transform self-check: 0 to 180 half way is off");
477
+ }
478
+ // A flat mirror turned keeps its rotation in the plane, the mirror in x, as Android's views hold it.
479
+ ANNTransformParts mirrored;
480
+ CATransform3D mirror =
481
+ CATransform3DConcat(ANNRotationZ(30), CATransform3DMakeScale(-1, 1, 1));
482
+ if (ANNTransformPartsOf(mirror, &mirrored)) {
483
+ BOOL flat = std::fabs(mirrored.quaternion[0]) < 1e-9 &&
484
+ std::fabs(mirrored.quaternion[1]) < 1e-9;
485
+ if (!(mirrored.scale[0] < 0 && mirrored.scale[1] > 0 && flat)) {
486
+ RCTLogWarn(@"[ApexNavigation] transform self-check: a flat mirror leaves the plane");
487
+ }
488
+ }
489
+ // The turns about x, y and z rebuild the rotation in the order of a view's tracks.
490
+ CATransform3D turned = CATransform3DConcat(
491
+ CATransform3DConcat(CATransform3DMakeRotation(25 * M_PI / 180.0, 1, 0, 0),
492
+ CATransform3DMakeRotation(-35 * M_PI / 180.0, 0, 1, 0)),
493
+ ANNRotationZ(120));
494
+ ANNTransformParts turnedParts;
495
+ if (ANNTransformPartsOf(turned, &turnedParts)) {
496
+ double x = 0, y = 0, z = 0;
497
+ ANNRotationDegreesOf(turnedParts, &x, &y, &z);
498
+ CATransform3D rebuilt = CATransform3DConcat(
499
+ CATransform3DConcat(CATransform3DMakeRotation(x * M_PI / 180.0, 1, 0, 0),
500
+ CATransform3DMakeRotation(y * M_PI / 180.0, 0, 1, 0)),
501
+ ANNRotationZ(z));
502
+ ANNExpectTransform("the turns about x, y and z", rebuilt, turned);
503
+ }
504
+ });
505
+ }
506
+
507
+ #endif
@@ -17,14 +17,17 @@ FOUNDATION_EXPORT CGFloat ANNCameraDistance(void);
17
17
  /// `rotationY`, `rotation` (clockwise, degrees), the perspective, the translation.
18
18
  ///
19
19
  /// A missing end is the view's value when the tracks are made: `x`, `y` its place in its parent (from its layer's
20
- /// position and bounds, never its frame), the translations 0, `alpha` its alpha before any hide, the scales 1, the
21
- /// rotations 0. Each frame writes only what plays: `alpha` only with an `alpha` track, `layer.transform` only when a
22
- /// property of the transform plays; with `translationX` and `x` on one side the translation wins. The frame is never
23
- /// changed (React keeps the layout). `restore` puts back the alpha and the transform as they were read.
20
+ /// position and bounds, never its frame) moved by its own translation, `alpha` its alpha before any hide, the
21
+ /// translations, scales and rotations those of its own transform (React Native's `transform`, split into its parts as
22
+ /// Android's views hold it: the shorter angle, −180…180). A property that doesn't play keeps the view's own value, its
23
+ /// skew and perspective stay. Only what plays animates, in Core Animation (`ANNKeyframes`): `opacity` only with an
24
+ /// `alpha` track, `transform` only when a property of the transform plays; with `translationX` and `x` on one side the
25
+ /// translation wins. The view's own values (its frame, alpha and transform) are never written: the animations show
26
+ /// over them, and `restore` removes the animations.
24
27
  @interface ANNViewTracks : NSObject <ANNFrameClient>
25
28
 
26
29
  /// The playing properties of `side` on `view`. `alphaBefore`: the view's alpha before the core hid it for the
27
- /// transition (the arriving screen), else its alpha now; it is also what `restore` puts back.
30
+ /// transition (the arriving screen), else its alpha now.
28
31
  - (instancetype)initWithView:(UIView *)view
29
32
  side:(ANNViewAnimationOptions *)side
30
33
  alphaBefore:(CGFloat)alphaBefore;
@@ -33,7 +36,7 @@ FOUNDATION_EXPORT CGFloat ANNCameraDistance(void);
33
36
  /// disappearing from it to `to`, or both ends given.
34
37
  - (instancetype)initWithView:(UIView *)view element:(ANNElementTransitionOptions *)element;
35
38
 
36
- /// A linear fade of `view`'s alpha (a dismissed popover with nothing to play); `restore` puts back `alphaBefore`.
39
+ /// A linear fade of `view`'s alpha (a dismissed popover with nothing to play, a transition under Reduce Motion).
37
40
  - (instancetype)initWithView:(UIView *)view
38
41
  fadeFrom:(CGFloat)from
39
42
  to:(CGFloat)to