@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.
- package/ApexNavigation.podspec +2 -1
- package/CHANGELOG.md +128 -0
- package/README.md +147 -51
- package/android/CLAUDE.md +78 -25
- package/android/CORE.md +49 -25
- package/android/RECIPES.md +13 -6
- package/android/consumer-rules.pro +6 -0
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +85 -10
- package/android/src/main/java/dev/apexnative/navigation/NavigationApplication.kt +34 -13
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutChecks.kt +5 -1
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutNode.kt +6 -2
- package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenContext.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/AnimationsOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonMenuOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/options/HardwareBackButtonOptions.kt +9 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
- package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
- package/android/src/main/java/dev/apexnative/navigation/options/OptionsCache.kt +8 -4
- package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
- package/android/src/main/java/dev/apexnative/navigation/options/SideMenuOptions.kt +6 -1
- package/android/src/main/java/dev/apexnative/navigation/options/StackAnimationOptions.kt +40 -2
- package/android/src/main/java/dev/apexnative/navigation/options/StatusBarOptions.kt +7 -3
- package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/options/UserChoices.kt +159 -0
- package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +29 -36
- package/android/src/main/java/dev/apexnative/navigation/react/CommandContract.kt +59 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ErrorTexts.kt +75 -60
- package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +35 -23
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +12 -7
- package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +42 -4
- package/android/src/main/java/dev/apexnative/navigation/react/PendingCalls.kt +48 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +54 -20
- package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +7 -6
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +19 -50
- package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
- package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +50 -81
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventContract.kt +226 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +135 -94
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationState.kt +154 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/ScreenAppearance.kt +0 -6
- package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +12 -10
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotContainers.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +39 -19
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +16 -4
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotViews.kt +40 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageKey.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageLoader.kt +7 -89
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageRequests.kt +76 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
- package/android/src/main/java/dev/apexnative/navigation/utils/OptionImages.kt +262 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/UiUtils.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewController.kt +3 -1
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/SecondaryScreenPresenter.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/AppliedTabCalls.kt +49 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +108 -34
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +25 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +28 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +12 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +103 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalAnimations.kt +22 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +109 -21
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +21 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +476 -73
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +57 -25
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +83 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackCheck.kt +50 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +49 -14
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +71 -12
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +37 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +10 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +11 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +42 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +19 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +43 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +23 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +77 -17
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +315 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +30 -20
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +216 -18
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +26 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +149 -41
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +26 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +115 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +222 -48
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +3 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +30 -34
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +5 -51
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/MenuChecks.kt +13 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +219 -54
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarVisibility.kt +9 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +75 -21
- package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
- package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +9 -7
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStep.kt +31 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +143 -135
- package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +9 -6
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionViews.kt +100 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +112 -4
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +56 -41
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
- package/android/src/main/java/dev/apexnative/navigation/views/sidemenu/SideMenuView.kt +12 -3
- package/android/src/main/java/dev/apexnative/navigation/views/stack/ScreenEdge.kt +45 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +140 -1
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +14 -10
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -17
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +73 -34
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +125 -178
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
- package/android/src/main/jni/ANNContentHeights.cpp +82 -0
- package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
- package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
- package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
- package/android/src/main/res/values/styles.xml +1 -1
- package/android/src/main/res/values-night/styles.xml +1 -1
- package/cli/app.js +1 -1
- package/cli/doctor/checks/app.js +77 -14
- package/cli/doctor/checks/splash.js +4 -22
- package/cli/migrate/native.js +18 -0
- package/cli/project.js +10 -2
- package/cli/setup/index.js +18 -0
- package/cli/setup/source.js +2 -1
- package/cli/setup/steps/appDelegate.js +66 -11
- package/cli/setup/steps/mainApplication.js +134 -19
- package/cli/setup/steps/metro.js +46 -0
- package/cli/setup/steps/sceneDelegate.js +108 -0
- package/cli/splash/index.js +3 -1
- package/cli/upgrade/changelog.js +2 -2
- package/docs-md/architecture/native-screens.md +4 -0
- package/docs-md/architecture/theme-and-context.md +131 -12
- package/docs-md/architecture/transitions.md +58 -12
- package/docs-md/containers/modals.md +8 -4
- package/docs-md/containers/overlays.md +3 -1
- package/docs-md/containers/side-menu.md +19 -2
- package/docs-md/containers/tabs.md +5 -1
- package/docs-md/flows/bottom-sheets.md +4 -2
- package/docs-md/flows/forms-in-a-modal.md +1 -1
- package/docs-md/fundamentals/screens-and-props.md +9 -1
- package/docs-md/fundamentals/starting-the-app.md +1 -1
- package/docs-md/guides/cli.md +4 -3
- package/docs-md/guides/deep-links.md +15 -33
- package/docs-md/help/glossary.md +4 -4
- package/docs-md/help/troubleshooting.md +44 -6
- package/docs-md/index.json +57 -1
- package/docs-md/migration/from-expo-router.md +1 -1
- package/docs-md/migration/from-react-native-navigation.md +9 -3
- package/docs-md/migration/from-react-navigation.md +2 -2
- package/docs-md/screen-ui/back-and-gestures.md +46 -2
- package/docs-md/screen-ui/bar-buttons.md +5 -5
- package/docs-md/screen-ui/search.md +1 -1
- package/docs-md/screen-ui/system-ui.md +17 -12
- package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
- package/docs-md/screen-ui/top-bar.md +8 -4
- package/docs-md/start/installation.md +21 -3
- package/ios/Animations/ANNFrameDriver.h +55 -15
- package/ios/Animations/ANNFrameDriver.mm +216 -60
- package/ios/Animations/ANNTransitionAnimator.h +26 -5
- package/ios/Animations/ANNTransitionAnimator.mm +61 -13
- package/ios/Animations/ANNTransitionPlan.h +2 -2
- package/ios/Animations/ANNTransitionPlan.mm +10 -0
- package/ios/Animations/ANNTransitionWait.mm +6 -7
- package/ios/Animations/Elements/ANNElementFinder.h +57 -0
- package/ios/Animations/Elements/ANNElementFinder.mm +174 -2
- package/ios/Animations/Elements/ANNElementTransition.h +10 -8
- package/ios/Animations/Elements/ANNElementTransition.mm +19 -21
- package/ios/Animations/Elements/ANNSharedElementFlight.h +16 -11
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +308 -69
- package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
- package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
- package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
- package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
- package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
- package/ios/CLAUDE.md +60 -24
- package/ios/CORE.md +44 -34
- package/ios/Contract/ANNCommandAnswer.h +13 -5
- package/ios/Contract/ANNCommandAnswer.mm +40 -32
- package/ios/Contract/ANNCommandContract.h +15 -0
- package/ios/Contract/ANNCommandContract.mm +78 -0
- package/ios/Contract/ANNCommandRunner.h +10 -9
- package/ios/Contract/ANNCommandRunner.mm +22 -28
- package/ios/Contract/ANNErrorTexts.h +6 -2
- package/ios/Contract/ANNErrorTexts.mm +18 -10
- package/ios/Contract/ANNLayoutNode.h +3 -3
- package/ios/Contract/ANNLayoutReader.h +3 -3
- package/ios/Core/ANNAppDelegate.mm +0 -2
- package/ios/Core/ANNAppearanceDispatcher.h +5 -4
- package/ios/Core/ANNAppearanceDispatcher.mm +12 -1
- package/ios/Core/ANNDeepLinkQueue.h +22 -2
- package/ios/Core/ANNDeepLinkQueue.mm +121 -14
- package/ios/Core/ANNErrorHandler.h +9 -4
- package/ios/Core/ANNErrorHandler.mm +20 -2
- package/ios/Core/ANNEventContract.h +246 -0
- package/ios/Core/ANNEventContract.mm +225 -0
- package/ios/Core/ANNEventEmitter.h +6 -2
- package/ios/Core/ANNEventEmitter.mm +117 -80
- package/ios/Core/ANNHinge.h +6 -0
- package/ios/Core/ANNHinge.mm +15 -4
- package/ios/Core/ANNJavaScriptCalls.h +33 -0
- package/ios/Core/ANNJavaScriptCalls.mm +52 -0
- package/ios/Core/ANNLayoutProtocol.h +5 -5
- package/ios/Core/ANNNavigationState.h +7 -5
- package/ios/Core/ANNNavigationState.mm +8 -7
- package/ios/Core/ANNNodeHelper.h +32 -12
- package/ios/Core/ANNNodeHelper.mm +100 -3
- package/ios/Core/ANNParking.h +5 -4
- package/ios/Core/ANNReloadCoordinator.mm +5 -12
- package/ios/Core/ANNRenderWait.h +20 -6
- package/ios/Core/ANNRenderWait.mm +143 -56
- package/ios/Core/ANNSceneDelegate.mm +25 -15
- package/ios/Core/ANNSystemUI.h +3 -2
- package/ios/Core/ANNSystemUI.mm +7 -0
- package/ios/Core/ANNUtils.h +7 -0
- package/ios/Core/ANNUtils.mm +10 -0
- package/ios/Core/ApexNavigation+Internal.h +1 -1
- package/ios/Core/ApexNavigation.mm +7 -6
- package/ios/Core/UIViewController+LayoutProtocol.h +9 -2
- package/ios/Core/UIViewController+LayoutProtocol.mm +8 -0
- package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
- package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +10 -8
- package/ios/Layouts/Modal/ANNModalCoordinator.h +1 -1
- package/ios/Layouts/Modal/ANNModalCoordinator.mm +57 -16
- package/ios/Layouts/Modal/ANNModalPresentation.h +8 -5
- package/ios/Layouts/Modal/ANNModalPresentation.mm +12 -12
- package/ios/Layouts/Modal/ANNSheetPresenter.mm +83 -1
- package/ios/Layouts/Overlay/ANNOverlayCoordinator.mm +2 -8
- package/ios/Layouts/Root/ANNRootCoordinator.mm +58 -19
- package/ios/Layouts/Root/ANNSplashViewController.h +5 -3
- package/ios/Layouts/Root/ANNSplashViewController.mm +147 -0
- package/ios/Layouts/Screen/ANNComponentPresenter.h +11 -3
- package/ios/Layouts/Screen/ANNComponentPresenter.mm +34 -6
- package/ios/Layouts/Screen/ANNComponentViewController.h +15 -13
- package/ios/Layouts/Screen/ANNComponentViewController.mm +130 -75
- package/ios/Layouts/Screen/ANNNativeScreenContext.mm +7 -5
- package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
- package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
- package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
- package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
- package/ios/Layouts/Screen/ANNScreenPlace.h +53 -0
- package/ios/Layouts/Screen/ANNScreenPlace.mm +205 -0
- package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
- package/ios/Layouts/Screen/ANNScreenRegions.mm +9 -44
- package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
- package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
- package/ios/Layouts/Screen/ANNScreenSettling.h +32 -0
- package/ios/Layouts/Screen/ANNScreenSettling.mm +137 -0
- package/ios/Layouts/SideMenu/ANNSideMenuTypes.h +8 -0
- package/ios/Layouts/SideMenu/ANNSideMenuViewController.mm +83 -14
- package/ios/Layouts/SplitView/ANNSplitViewCommands.h +3 -2
- package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +105 -39
- package/ios/Layouts/SplitView/ANNSplitViewController.mm +7 -8
- package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
- package/ios/Layouts/Stack/ANNPreviewPush.mm +142 -27
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
- package/ios/Layouts/Stack/ANNStackCommands.mm +1 -0
- package/ios/Layouts/Stack/ANNStackController.h +8 -0
- package/ios/Layouts/Stack/ANNStackController.mm +184 -16
- package/ios/Layouts/Stack/ANNStackQueue.h +5 -2
- package/ios/Layouts/Stack/ANNStackQueue.mm +56 -43
- package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
- package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
- package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.h +4 -2
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +2 -3
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +11 -0
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.h +3 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +237 -57
- package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +6 -2
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +232 -43
- package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
- package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
- package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
- package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
- package/ios/Options/ANNAnimationOptions.h +2 -1
- package/ios/Options/ANNAnimationOptions.mm +1 -1
- package/ios/Options/ANNBottomTabsOptions.h +2 -0
- package/ios/Options/ANNBottomTabsOptions.mm +1 -0
- package/ios/Options/ANNOptions.h +25 -0
- package/ios/Options/ANNOptions.mm +157 -1
- package/ios/Options/ANNOptionsCache.h +7 -6
- package/ios/Options/ANNOptionsReader.mm +108 -0
- package/ios/Options/ANNSearchBarOptions.h +4 -3
- package/ios/Options/ANNSheetOptions.h +4 -1
- package/ios/Options/ANNSideMenuOptions.h +2 -0
- package/ios/Options/ANNSideMenuOptions.mm +2 -0
- package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
- package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
- package/ios/Options/ANNUserChoice.h +57 -0
- package/ios/Options/ANNUserChoice.mm +44 -0
- package/ios/Options/Params/ANNImageSource.h +61 -0
- package/ios/Options/Params/ANNImageSource.mm +101 -0
- package/ios/Options/Params/ANNOptionImages.h +37 -0
- package/ios/Options/Params/ANNOptionImages.mm +284 -0
- package/ios/Options/Params/ANNParam.h +15 -0
- package/ios/Options/Params/ANNParam.mm +61 -0
- package/ios/Options/Params/Color.h +3 -0
- package/ios/Options/Params/Color.mm +21 -0
- package/ios/Options/Params/ColorParser.h +4 -3
- package/ios/Options/Params/ColorParser.mm +22 -4
- package/ios/Options/Params/Image.h +15 -2
- package/ios/Options/Params/Image.mm +35 -2
- package/ios/Options/Params/ImageParser.h +5 -5
- package/ios/Options/Params/ImageParser.mm +28 -46
- package/ios/Public/ApexNavigation/ANNSceneDelegate.h +3 -0
- package/ios/Public/ApexNavigation/ApexNavigation.h +1 -1
- package/ios/RECIPES.md +13 -6
- package/ios/React/ANNReactView.mm +6 -25
- package/ios/React/ANNSafeAreaViewComponentView.mm +28 -17
- package/ios/React/ANNSurfaceHostingView.h +14 -0
- package/ios/React/ANNSurfaceHostingView.mm +144 -1
- package/ios/React/Slots/ANNSlotComponentView.mm +24 -17
- package/ios/React/Slots/ANNSlotContainers.h +14 -6
- package/ios/React/Slots/ANNSlotContainers.mm +75 -2
- package/ios/React/Slots/ANNSlotHost.mm +1 -3
- package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
- package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
- package/ios/TopBar/ANNBarAppearance.h +2 -1
- package/ios/TopBar/ANNBarAppearance.mm +111 -30
- package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
- package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
- package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
- package/ios/TopBar/ANNBarButtons.h +14 -8
- package/ios/TopBar/ANNBarButtons.mm +397 -80
- package/ios/TopBar/ANNIconButtonImage.h +1 -0
- package/ios/TopBar/ANNIconButtonImage.mm +34 -1
- package/ios/TopBar/ANNLargeTitlePresenter.h +13 -0
- package/ios/TopBar/ANNLargeTitlePresenter.mm +50 -7
- package/ios/TopBar/ANNMainList.h +3 -0
- package/ios/TopBar/ANNMainList.mm +4 -0
- package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
- package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
- package/ios/TopBar/ANNSearchPresenter.mm +172 -21
- package/ios/TopBar/ANNSearchResultsViewController.mm +29 -6
- package/ios/TopBar/ANNTopBarPresenter.h +8 -2
- package/ios/TopBar/ANNTopBarPresenter.mm +155 -33
- package/ios/TurboModules/ANNTurboEventEmitter.mm +4 -35
- package/ios/TurboModules/ANNTurboModule.mm +104 -33
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
- package/lib/module/ARCHITECTURE.md +40 -27
- package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
- package/lib/module/api/app/AppRegistry.js +14 -2
- package/lib/module/api/app/AppRegistry.js.map +1 -1
- package/lib/module/api/app/createNavigation.js +190 -66
- package/lib/module/api/app/createNavigation.js.map +1 -1
- package/lib/module/api/commands/commands.js +54 -6
- package/lib/module/api/commands/commands.js.map +1 -1
- package/lib/module/api/events/navigationEvents.js +6 -2
- package/lib/module/api/events/navigationEvents.js.map +1 -1
- package/lib/module/api/hooks/useNavigation.js +8 -3
- package/lib/module/api/hooks/useNavigation.js.map +1 -1
- package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
- package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
- package/lib/module/api/linking/dispatchedLinks.js +23 -0
- package/lib/module/api/linking/dispatchedLinks.js.map +1 -0
- package/lib/module/api/linking/linking.js +11 -0
- package/lib/module/api/linking/linking.js.map +1 -1
- package/lib/module/api/navigation.js.map +1 -1
- package/lib/module/api/options/OptionsChain.js +2 -2
- package/lib/module/api/screens/defineScreen.js +45 -3
- package/lib/module/api/screens/defineScreen.js.map +1 -1
- package/lib/module/api/screens/nativeScreens.js +31 -6
- package/lib/module/api/screens/nativeScreens.js.map +1 -1
- package/lib/module/api/screens/registerScreens.js +193 -35
- package/lib/module/api/screens/registerScreens.js.map +1 -1
- package/lib/module/api/theme/theme.js +5 -0
- package/lib/module/api/theme/theme.js.map +1 -1
- package/lib/module/engine/commands.js +51 -9
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +20 -11
- package/lib/module/engine/layout.js.map +1 -1
- package/lib/module/engine/nativeScreens.js +9 -0
- package/lib/module/engine/nativeScreens.js.map +1 -1
- package/lib/module/engine/options.js +49 -15
- package/lib/module/engine/options.js.map +1 -1
- package/lib/module/engine/optionsChange.js +102 -0
- package/lib/module/engine/optionsChange.js.map +1 -0
- package/lib/module/engine/places.js +52 -7
- package/lib/module/engine/places.js.map +1 -1
- package/lib/module/engine/props.js +30 -1
- package/lib/module/engine/props.js.map +1 -1
- package/lib/module/engine/refresh.js +85 -0
- package/lib/module/engine/refresh.js.map +1 -0
- package/lib/module/engine/rememberedOptions.js +61 -1
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +77 -16
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/module/interfaces/contract/commands.json +101 -0
- package/lib/module/interfaces/contract/errors.json +275 -0
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +12 -2
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
- package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
- package/lib/typescript/api/app/createNavigation.d.ts +8 -3
- package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
- package/lib/typescript/api/commands/commands.d.ts.map +1 -1
- package/lib/typescript/api/commands/presentation.d.ts +4 -3
- package/lib/typescript/api/commands/presentation.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +3 -3
- package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
- package/lib/typescript/api/index.d.ts +1 -1
- package/lib/typescript/api/index.d.ts.map +1 -1
- package/lib/typescript/api/linking/dispatchedLinks.d.ts +7 -0
- package/lib/typescript/api/linking/dispatchedLinks.d.ts.map +1 -0
- package/lib/typescript/api/linking/linking.d.ts +8 -0
- package/lib/typescript/api/linking/linking.d.ts.map +1 -1
- package/lib/typescript/api/navigation.d.ts +4 -1
- package/lib/typescript/api/navigation.d.ts.map +1 -1
- package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
- package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
- package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
- package/lib/typescript/api/theme/theme.d.ts +2 -0
- package/lib/typescript/api/theme/theme.d.ts.map +1 -1
- package/lib/typescript/engine/commands.d.ts +5 -0
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/layout.d.ts.map +1 -1
- package/lib/typescript/engine/nativeScreens.d.ts +5 -0
- package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/engine/options.d.ts +5 -2
- package/lib/typescript/engine/options.d.ts.map +1 -1
- package/lib/typescript/engine/optionsChange.d.ts +28 -0
- package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
- package/lib/typescript/engine/places.d.ts +7 -2
- package/lib/typescript/engine/places.d.ts.map +1 -1
- package/lib/typescript/engine/props.d.ts +8 -1
- package/lib/typescript/engine/props.d.ts.map +1 -1
- package/lib/typescript/engine/refresh.d.ts +35 -0
- package/lib/typescript/engine/refresh.d.ts.map +1 -0
- package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
- package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts +27 -6
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/ComponentEvents.d.ts +4 -4
- package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -1
- package/lib/typescript/interfaces/Events.d.ts +28 -10
- package/lib/typescript/interfaces/Events.d.ts.map +1 -1
- package/lib/typescript/interfaces/Options.d.ts +1 -1
- package/lib/typescript/interfaces/Options.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/animations.d.ts +80 -22
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +21 -7
- package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +23 -15
- package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/modals.d.ts +34 -26
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/sideMenu.d.ts +23 -6
- package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/stack.d.ts +17 -3
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +18 -11
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
- package/lib/typescript/interfaces/options/topBar.d.ts +68 -38
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/metro/acceptPlugin.js +57 -0
- package/metro/babelTransformer.js +45 -0
- package/metro/index.js +36 -0
- package/package.json +4 -25
- package/src/ARCHITECTURE.md +40 -27
- package/src/adapters/NativeANNTurboModule.ts +12 -2
- package/src/api/app/AppRegistry.ts +16 -2
- package/src/api/app/createNavigation.ts +203 -69
- package/src/api/commands/commands.ts +48 -7
- package/src/api/commands/presentation.ts +4 -3
- package/src/api/events/navigationEvents.ts +10 -4
- package/src/api/hooks/useNavigation.ts +9 -4
- package/src/api/hooks/useSafeAreaInsets.ts +4 -3
- package/src/api/index.ts +1 -0
- package/src/api/linking/dispatchedLinks.ts +18 -0
- package/src/api/linking/linking.ts +22 -1
- package/src/api/navigation.ts +4 -1
- package/src/api/options/OptionsChain.ts +2 -2
- package/src/api/screens/defineScreen.ts +49 -5
- package/src/api/screens/nativeScreens.ts +40 -4
- package/src/api/screens/registerScreens.tsx +185 -42
- package/src/api/theme/theme.ts +5 -0
- package/src/engine/commands.ts +70 -13
- package/src/engine/layout.ts +27 -11
- package/src/engine/nativeScreens.ts +10 -1
- package/src/engine/options.ts +45 -19
- package/src/engine/optionsChange.ts +107 -0
- package/src/engine/places.ts +65 -7
- package/src/engine/props.ts +30 -1
- package/src/engine/refresh.ts +97 -0
- package/src/engine/rememberedOptions.ts +74 -1
- package/src/engine/screens.tsx +76 -21
- package/src/interfaces/ComponentEvents.ts +4 -4
- package/src/interfaces/Events.ts +29 -10
- package/src/interfaces/Options.ts +1 -0
- package/src/interfaces/contract/commands.json +101 -0
- package/src/interfaces/contract/errors.json +275 -0
- package/src/interfaces/options/animations.ts +81 -22
- package/src/interfaces/options/bottomTabs.ts +21 -7
- package/src/interfaces/options/buttons.ts +23 -15
- package/src/interfaces/options/modals.ts +34 -26
- package/src/interfaces/options/sideMenu.ts +24 -6
- package/src/interfaces/options/stack.ts +17 -3
- package/src/interfaces/options/system.ts +18 -11
- package/src/interfaces/options/toolbar.ts +2 -2
- package/src/interfaces/options/topBar.ts +68 -38
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -41
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -69
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -138
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -88
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -66
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -179
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -139
- package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
- package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -68
- package/ios/Layouts/Tabs/ANNTabsPreloadWindow.h +0 -27
- package/ios/Layouts/Tabs/ANNTabsPreloadWindow.mm +0 -55
|
@@ -2,126 +2,78 @@ package dev.apexnative.navigation.views.element
|
|
|
2
2
|
|
|
3
3
|
import android.animation.Animator
|
|
4
4
|
import android.animation.AnimatorListenerAdapter
|
|
5
|
-
import android.graphics.Rect
|
|
6
5
|
import android.os.Build
|
|
7
6
|
import android.util.Log
|
|
8
7
|
import android.view.View
|
|
9
8
|
import android.view.ViewGroup
|
|
10
|
-
import com.facebook.react.uimanager.util.ReactFindViewUtil
|
|
11
|
-
import com.facebook.react.views.view.ReactViewGroup
|
|
12
9
|
import dev.apexnative.navigation.options.ElementTransitionOptions
|
|
13
10
|
import dev.apexnative.navigation.options.LayoutAnimation
|
|
14
11
|
import dev.apexnative.navigation.options.SharedElementTransitionOptions
|
|
15
12
|
import dev.apexnative.navigation.react.events.AppearanceDispatcher
|
|
16
13
|
import dev.apexnative.navigation.utils.DevelopmentLog
|
|
17
14
|
import dev.apexnative.navigation.utils.NavigationLog
|
|
15
|
+
import dev.apexnative.navigation.utils.SystemAnimations
|
|
18
16
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
17
|
+
import dev.apexnative.navigation.views.animations.AnimationLayer
|
|
19
18
|
import dev.apexnative.navigation.views.animations.SideAnimator
|
|
20
19
|
import dev.apexnative.navigation.views.element.animators.SharedAnimatorFactory
|
|
20
|
+
import java.util.Collections
|
|
21
|
+
import java.util.WeakHashMap
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
|
-
* The elements of one transition: the element transitions and the
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
24
|
+
* The elements of one transition: the element transitions and the shared pairs found by their `nativeID` (depth first,
|
|
25
|
+
* the first match) in the whole view of the screen each side shows — an element in the screen that goes first, then in
|
|
26
|
+
* the one that comes; a pair's `fromId` in the screen that goes, its `toId` in the one that comes; each screen is
|
|
27
|
+
* walked once for all of them ([TransitionViews]). What isn't found, what another transition plays now and an image
|
|
28
|
+
* that isn't loaded is skipped; so is an element whose start fails ([elementStep]): it gets its values back at once and
|
|
29
|
+
* the rest plays. No view leaves its parent, as on iOS. An element plays where it is, in its screen: its properties
|
|
30
|
+
* animate about its center and it moves with its screen. A pair flies as a copy drawn in a [TransitionLayer] over the
|
|
31
|
+
* screens, the copies in the order their targets are drawn; its `to` is hidden from the start, its `from` from the
|
|
32
|
+
* start of its flight. [finish] gives every element the values of its properties read before, shows the pairs' views
|
|
33
|
+
* again and takes the layer away. Main thread only.
|
|
32
34
|
*/
|
|
33
|
-
internal class ElementTransition private constructor(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
val pivotSet: Boolean,
|
|
42
|
-
// Where its parent's origin is in the layer: what `x` and `y` are counted from.
|
|
43
|
-
val originX: Int,
|
|
44
|
-
val originY: Int,
|
|
45
|
-
)
|
|
35
|
+
internal class ElementTransition private constructor(
|
|
36
|
+
private val layer: TransitionLayer?,
|
|
37
|
+
// The views of the screens, as far as the parents that cut a pair's views count.
|
|
38
|
+
private val fromRoot: View?,
|
|
39
|
+
private val toRoot: View?,
|
|
40
|
+
) {
|
|
41
|
+
// An element playing where it is: what it was.
|
|
42
|
+
private class InPlace(val view: View, val values: FloatArray, val pivotSet: Boolean)
|
|
46
43
|
|
|
47
|
-
private val
|
|
48
|
-
private val
|
|
44
|
+
private val inPlace = ArrayList<InPlace>()
|
|
45
|
+
private val taken = ArrayList<View>()
|
|
46
|
+
// The views of the pairs hidden while their copies fly, with the alpha each had.
|
|
47
|
+
private val hidden = LinkedHashMap<View, Float>()
|
|
49
48
|
private var finished = false
|
|
50
49
|
|
|
51
50
|
/** The animators of the elements and of the shared elements, each with its own time. */
|
|
52
51
|
val animators = ArrayList<Animator>()
|
|
53
52
|
|
|
54
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Every element's values back, the pairs' views seen, the layer gone; at the end of the transition and at any stop.
|
|
55
|
+
* Once.
|
|
56
|
+
*/
|
|
55
57
|
fun finish() {
|
|
56
58
|
if (finished) return
|
|
57
59
|
finished = true
|
|
58
|
-
for ((view, alpha) in hidden) view
|
|
60
|
+
for ((view, alpha) in hidden) show(view, alpha)
|
|
59
61
|
hidden.clear()
|
|
60
|
-
// Each
|
|
61
|
-
for (item in
|
|
62
|
+
// Each element on its own: one that can't get its values back doesn't keep the others from theirs.
|
|
63
|
+
for (item in inPlace.asReversed()) {
|
|
62
64
|
try {
|
|
63
|
-
|
|
65
|
+
restore(item.view, item.values, item.pivotSet)
|
|
64
66
|
} catch (e: RuntimeException) {
|
|
65
|
-
Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't
|
|
67
|
+
Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't get its values back", e)
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
inPlace.clear()
|
|
71
|
+
playing -= taken.toSet()
|
|
72
|
+
taken.clear()
|
|
73
|
+
layer?.detach()
|
|
70
74
|
}
|
|
71
75
|
|
|
72
|
-
private fun
|
|
73
|
-
val parent = view.parent as? ViewGroup ?: return null
|
|
74
|
-
// A parent that clips its subviews keeps its own list of children, which a stub swapped in would leave
|
|
75
|
-
// behind: its element stays where it is.
|
|
76
|
-
if ((parent as? ReactViewGroup)?.removeClippedSubviews == true) return null
|
|
77
|
-
val index = parent.indexOfChild(view)
|
|
78
|
-
if (index < 0) return null
|
|
79
|
-
val onScreen = IntArray(2)
|
|
80
|
-
parent.getLocationOnScreen(onScreen)
|
|
81
|
-
val origin = layer.originOnScreen
|
|
82
|
-
val originX = onScreen[0] - parent.scrollX - origin.x
|
|
83
|
-
val originY = onScreen[1] - parent.scrollY - origin.y
|
|
84
|
-
val frame = Rect(view.left, view.top, view.right, view.bottom)
|
|
85
|
-
val params = view.layoutParams ?: ViewGroup.LayoutParams(view.width, view.height)
|
|
86
|
-
val pivotSet = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && view.isPivotSet
|
|
87
|
-
val values = floatArrayOf(
|
|
88
|
-
view.alpha, view.translationX, view.translationY, view.scaleX, view.scaleY, view.rotation,
|
|
89
|
-
view.rotationX, view.rotationY, view.pivotX, view.pivotY,
|
|
90
|
-
)
|
|
91
|
-
val stub = ElementStub(view.context, view)
|
|
92
|
-
parent.removeViewAt(index)
|
|
93
|
-
parent.addView(stub, index, params)
|
|
94
|
-
stub.layout(frame.left, frame.top, frame.right, frame.bottom)
|
|
95
|
-
val left = originX + frame.left
|
|
96
|
-
val top = originY + frame.top
|
|
97
|
-
layer.put(view, left, top, frame.width(), frame.height())
|
|
98
|
-
// Scale and rotations turn about the center.
|
|
99
|
-
view.pivotX = frame.width() / 2f
|
|
100
|
-
view.pivotY = frame.height() / 2f
|
|
101
|
-
return Moved(view, stub, params, frame, values, pivotSet, originX, originY).also { moved += it }
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
private fun giveBack(item: Moved) {
|
|
105
|
-
val view = item.view
|
|
106
|
-
// A commit of Fabric meanwhile laid it out in its parent's coordinates: the newest such frame holds.
|
|
107
|
-
val reactFrame = if (view.parent === layer) layer.frameFromReact(view) else null
|
|
108
|
-
if (view.parent === layer) layer.removeView(view)
|
|
109
|
-
restore(view, item)
|
|
110
|
-
val parent = item.stub.parent as? ViewGroup ?: return
|
|
111
|
-
val index = parent.indexOfChild(item.stub)
|
|
112
|
-
if (index < 0) return
|
|
113
|
-
parent.removeViewAt(index)
|
|
114
|
-
parent.addView(view, index, item.params)
|
|
115
|
-
val frame = reactFrame ?: item.frame
|
|
116
|
-
view.measure(
|
|
117
|
-
View.MeasureSpec.makeMeasureSpec(frame.width(), View.MeasureSpec.EXACTLY),
|
|
118
|
-
View.MeasureSpec.makeMeasureSpec(frame.height(), View.MeasureSpec.EXACTLY),
|
|
119
|
-
)
|
|
120
|
-
view.layout(frame.left, frame.top, frame.right, frame.bottom)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
private fun restore(view: View, item: Moved) {
|
|
124
|
-
val values = item.values
|
|
76
|
+
private fun restore(view: View, values: FloatArray, pivotSet: Boolean) {
|
|
125
77
|
view.alpha = values[ALPHA]
|
|
126
78
|
view.translationX = values[TRANSLATION_X]
|
|
127
79
|
view.translationY = values[TRANSLATION_Y]
|
|
@@ -130,7 +82,7 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
130
82
|
view.rotation = values[ROTATION]
|
|
131
83
|
view.rotationX = values[ROTATION_X]
|
|
132
84
|
view.rotationY = values[ROTATION_Y]
|
|
133
|
-
if (!
|
|
85
|
+
if (!pivotSet && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
134
86
|
view.resetPivot()
|
|
135
87
|
} else {
|
|
136
88
|
view.pivotX = values[PIVOT_X]
|
|
@@ -138,34 +90,74 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
138
90
|
}
|
|
139
91
|
}
|
|
140
92
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
93
|
+
// An element with views in it fades through a hardware layer only where its alpha would draw it into an offscreen
|
|
94
|
+
// buffer at every frame (AnimationLayer: its rendering overlaps). React's views overlap only with
|
|
95
|
+
// `needsOffscreenAlphaCompositing`, so most elements fade without one and nothing they draw outside their bounds (a
|
|
96
|
+
// box shadow) is clipped. A view without children fades its own drawing at no extra cost. Scale and rotations turn
|
|
97
|
+
// about the element's center; `x` and `y` are its place in its own parent.
|
|
98
|
+
private fun addElement(options: ElementTransitionOptions, view: View) {
|
|
99
|
+
inPlace += InPlace(view, valuesOf(view), pivotSetOf(view))
|
|
100
|
+
view.pivotX = view.width / 2f
|
|
101
|
+
view.pivotY = view.height / 2f
|
|
102
|
+
val animator = SideAnimator.build(view, options, SideAnimator.Base()) ?: return
|
|
103
|
+
if (view is ViewGroup) AnimationLayer.during(view, animator)
|
|
104
|
+
animators += animator
|
|
144
105
|
}
|
|
145
106
|
|
|
146
|
-
//
|
|
107
|
+
// An element whose start failed gets its values back now.
|
|
108
|
+
private fun giveValuesBack(view: View) {
|
|
109
|
+
val item = inPlace.lastOrNull { it.view === view } ?: return
|
|
110
|
+
inPlace -= item
|
|
111
|
+
try {
|
|
112
|
+
restore(view, item.values, item.pivotSet)
|
|
113
|
+
} catch (e: RuntimeException) {
|
|
114
|
+
Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't get its values back", e)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// The pair's flight: `to` hidden from now, `from` from its start, both seen again when it stops or its copy can't
|
|
119
|
+
// be drawn. Nothing changes when it doesn't fly.
|
|
147
120
|
private fun addPair(
|
|
148
121
|
options: SharedElementTransitionOptions,
|
|
149
122
|
from: View,
|
|
150
|
-
|
|
151
|
-
|
|
123
|
+
to: View,
|
|
124
|
+
name: String,
|
|
152
125
|
fallbackDuration: Long,
|
|
153
|
-
)
|
|
154
|
-
val
|
|
126
|
+
) {
|
|
127
|
+
val layer = layer ?: return
|
|
155
128
|
val flight = SharedAnimatorFactory.create(
|
|
156
|
-
from, to,
|
|
157
|
-
) ?: return
|
|
158
|
-
val
|
|
159
|
-
|
|
160
|
-
|
|
129
|
+
from, to, fromRoot, toRoot, layer, options, fallbackDuration, DevelopmentLog::warn,
|
|
130
|
+
) ?: return
|
|
131
|
+
val fromAlpha = from.alpha
|
|
132
|
+
val seenAgain = {
|
|
133
|
+
flight.picture.shown = false
|
|
134
|
+
hidden.remove(from)?.let { show(from, it) }
|
|
135
|
+
hidden.remove(to)?.let { show(to, it) }
|
|
136
|
+
layer.invalidate()
|
|
137
|
+
}
|
|
138
|
+
flight.picture.onFailed = { e ->
|
|
139
|
+
elementSkipped(name, e.toString())
|
|
140
|
+
seenAgain()
|
|
141
|
+
}
|
|
161
142
|
flight.animator.addListener(object : AnimatorListenerAdapter() {
|
|
143
|
+
private var stopped = false
|
|
144
|
+
|
|
162
145
|
override fun onAnimationStart(animation: Animator) {
|
|
146
|
+
if (stopped || finished) return
|
|
147
|
+
hidden[from] = fromAlpha
|
|
163
148
|
from.alpha = 0f
|
|
164
|
-
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// A flight whose start or frame failed stops (`MoveAnimator`), maybe inside its own start.
|
|
152
|
+
override fun onAnimationCancel(animation: Animator) {
|
|
153
|
+
stopped = true
|
|
154
|
+
seenAgain()
|
|
165
155
|
}
|
|
166
156
|
})
|
|
157
|
+
layer.add(flight.picture)
|
|
158
|
+
hidden[to] = to.alpha
|
|
159
|
+
to.alpha = 0f
|
|
167
160
|
animators += flight.animator
|
|
168
|
-
return true
|
|
169
161
|
}
|
|
170
162
|
|
|
171
163
|
companion object {
|
|
@@ -180,10 +172,26 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
180
172
|
private const val PIVOT_X = 8
|
|
181
173
|
private const val PIVOT_Y = 9
|
|
182
174
|
|
|
175
|
+
// The views the transitions that run now play: another transition leaves them alone.
|
|
176
|
+
private val playing: MutableSet<View> = Collections.newSetFromMap(WeakHashMap())
|
|
177
|
+
|
|
178
|
+
private fun valuesOf(view: View) = floatArrayOf(
|
|
179
|
+
view.alpha, view.translationX, view.translationY, view.scaleX, view.scaleY, view.rotation,
|
|
180
|
+
view.rotationX, view.rotationY, view.pivotX, view.pivotY,
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
private fun pivotSetOf(view: View) = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && view.isPivotSet
|
|
184
|
+
|
|
185
|
+
// A view hidden for a flight shows again with its alpha, unless React gave it another one meanwhile. React
|
|
186
|
+
// writes the same alpha: an opacity it commits during the flight shows the view beside its copy until the end.
|
|
187
|
+
private fun show(view: View, alpha: Float) {
|
|
188
|
+
if (view.alpha == 0f) view.alpha = alpha
|
|
189
|
+
}
|
|
190
|
+
|
|
183
191
|
/**
|
|
184
|
-
* The elements of [animation] from [from] to [to]
|
|
185
|
-
* top without one)
|
|
186
|
-
* [fallbackDuration], the screen's fade.
|
|
192
|
+
* The elements of [animation] from [from] to [to]; the copies of the pairs in a layer that joins [host] at
|
|
193
|
+
* [layerIndex] (its top without one). None when none of them is found or the system's animations are off. A
|
|
194
|
+
* shared element without a duration takes [fallbackDuration], the screen's fade.
|
|
187
195
|
*/
|
|
188
196
|
fun start(
|
|
189
197
|
animation: LayoutAnimation,
|
|
@@ -193,33 +201,38 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
193
201
|
layerIndex: Int?,
|
|
194
202
|
fallbackDuration: Long,
|
|
195
203
|
): ElementTransition? {
|
|
204
|
+
if (SystemAnimations.areOff(host.context)) return null
|
|
196
205
|
val fromView = from?.let { AppearanceDispatcher.visibleNode(it).peekView() }
|
|
197
206
|
val toView = AppearanceDispatcher.visibleNode(to).peekView()
|
|
207
|
+
val transitions = animation.elementTransitions.transitions
|
|
208
|
+
val shared = animation.sharedElements.get()
|
|
209
|
+
val views = TransitionViews(shared, transitions, fromView, toView)
|
|
198
210
|
val taken = HashSet<View>()
|
|
199
211
|
val elements = ArrayList<Pair<ElementTransitionOptions, View>>()
|
|
200
|
-
for (element in
|
|
212
|
+
for (element in transitions) {
|
|
201
213
|
if (element.id.isEmpty()) continue
|
|
202
|
-
val view =
|
|
203
|
-
if (
|
|
214
|
+
val view = views.leaving(element.id) ?: views.arriving(element.id) ?: continue
|
|
215
|
+
if (view in playing || !taken.add(view)) continue
|
|
204
216
|
elements += element to view
|
|
205
217
|
}
|
|
206
218
|
val pairs = ArrayList<Triple<SharedElementTransitionOptions, View, View>>()
|
|
207
|
-
for (pair in
|
|
219
|
+
for (pair in shared) {
|
|
208
220
|
val fromId = pair.fromId.get(null) ?: continue
|
|
209
221
|
val toId = pair.toId.get(null) ?: continue
|
|
210
|
-
val source =
|
|
211
|
-
val target =
|
|
212
|
-
if (source === target ||
|
|
222
|
+
val source = views.leaving(fromId) ?: continue
|
|
223
|
+
val target = views.arriving(toId) ?: continue
|
|
224
|
+
if (source === target || source in playing || target in playing) continue
|
|
213
225
|
if (target in taken || source in taken) continue
|
|
214
226
|
if (!loaded(source, fromId) || !loaded(target, toId)) continue
|
|
227
|
+
taken += source
|
|
215
228
|
taken += target
|
|
216
229
|
pairs += Triple(pair, source, target)
|
|
217
230
|
}
|
|
218
231
|
if (elements.isEmpty() && pairs.isEmpty()) return null
|
|
219
|
-
val layer = TransitionLayer(host.context)
|
|
220
|
-
val transition = ElementTransition(layer)
|
|
232
|
+
val layer = if (pairs.isEmpty()) null else TransitionLayer(host.context)
|
|
233
|
+
val transition = ElementTransition(layer, fromView, toView)
|
|
221
234
|
try {
|
|
222
|
-
layer
|
|
235
|
+
layer?.attachTo(host, layerIndex ?: host.childCount)
|
|
223
236
|
transition.fill(host, elements, pairs, fallbackDuration)
|
|
224
237
|
} catch (e: RuntimeException) {
|
|
225
238
|
transition.finish()
|
|
@@ -229,8 +242,8 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
229
242
|
}
|
|
230
243
|
|
|
231
244
|
/**
|
|
232
|
-
* [start], and when that fails, a line in the log and none: the screens play without their elements; every
|
|
233
|
-
*
|
|
245
|
+
* [start], and when that fails, a line in the log and none: the screens play without their elements; every
|
|
246
|
+
* element has its values back already.
|
|
234
247
|
*/
|
|
235
248
|
fun startOrLog(
|
|
236
249
|
animation: LayoutAnimation,
|
|
@@ -246,9 +259,6 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
246
259
|
null
|
|
247
260
|
}
|
|
248
261
|
|
|
249
|
-
private fun find(root: View?, nativeId: String): View? =
|
|
250
|
-
root?.let { ReactFindViewUtil.findView(it, nativeId) }?.takeUnless { it is ElementStub }
|
|
251
|
-
|
|
252
262
|
// An image not loaded drops out of the transition; its wait logged it already, else it is logged now.
|
|
253
263
|
private fun loaded(view: View, id: String): Boolean {
|
|
254
264
|
if (ImageLoads.isLoaded(view)) return true
|
|
@@ -257,25 +267,23 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
257
267
|
}
|
|
258
268
|
}
|
|
259
269
|
|
|
260
|
-
// The
|
|
261
|
-
//
|
|
270
|
+
// The elements' animators where they are, then the pairs' flights, their copies in the order their targets are
|
|
271
|
+
// drawn. Each element's steps run on their own ([elementStep]): one that fails is left as it was, the others play.
|
|
262
272
|
private fun fill(
|
|
263
273
|
host: ViewGroup,
|
|
264
274
|
elements: List<Pair<ElementTransitionOptions, View>>,
|
|
265
275
|
pairs: List<Triple<SharedElementTransitionOptions, View, View>>,
|
|
266
276
|
fallbackDuration: Long,
|
|
267
277
|
) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
for (
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
giveBack(item)
|
|
278
|
-
}
|
|
278
|
+
for ((_, view) in elements) taken += view
|
|
279
|
+
for ((_, source, target) in pairs) taken += listOf(source, target)
|
|
280
|
+
playing += taken
|
|
281
|
+
for ((options, view) in elements) {
|
|
282
|
+
if (!elementStep(elementName(options.id)) { addElement(options, view) }) giveValuesBack(view)
|
|
283
|
+
}
|
|
284
|
+
for ((options, source, target) in DrawOrder.sorted(pairs, host) { it.third }) {
|
|
285
|
+
val name = pairName(options.fromId.get(""), options.toId.get(""))
|
|
286
|
+
elementStep(name) { addPair(options, source, target, name, fallbackDuration) }
|
|
279
287
|
}
|
|
280
288
|
}
|
|
281
289
|
}
|
|
@@ -3,11 +3,11 @@ package dev.apexnative.navigation.views.element
|
|
|
3
3
|
import android.util.Log
|
|
4
4
|
import android.view.Choreographer
|
|
5
5
|
import android.view.View
|
|
6
|
-
import com.facebook.react.uimanager.util.ReactFindViewUtil
|
|
7
6
|
import dev.apexnative.navigation.options.LayoutAnimation
|
|
8
7
|
import dev.apexnative.navigation.react.events.AppearanceDispatcher
|
|
9
8
|
import dev.apexnative.navigation.utils.DevelopmentLog
|
|
10
9
|
import dev.apexnative.navigation.utils.NavigationLog
|
|
10
|
+
import dev.apexnative.navigation.utils.SystemAnimations
|
|
11
11
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
12
12
|
import kotlinx.coroutines.CancellationException
|
|
13
13
|
import kotlinx.coroutines.CoroutineScope
|
|
@@ -18,7 +18,8 @@ import kotlinx.coroutines.launch
|
|
|
18
18
|
/**
|
|
19
19
|
* The wait of a forward transition with elements for its targets: the module's frames (`awaitTransitionTargets`, 0.5 s
|
|
20
20
|
* at most, then one frame more), then the images of the shared elements found ([ImageWait], 1 s at most each). It ends
|
|
21
|
-
* early when the screen that goes is destroyed
|
|
21
|
+
* early when the screen that goes is destroyed, and doesn't wait with the system's animations off. A failure in it is
|
|
22
|
+
* logged and the transition starts. Main thread only.
|
|
22
23
|
*/
|
|
23
24
|
internal object TargetsWait {
|
|
24
25
|
// The waits run on the main thread's frames; each is cancelled on its own.
|
|
@@ -32,6 +33,11 @@ internal object TargetsWait {
|
|
|
32
33
|
waiting: () -> Boolean,
|
|
33
34
|
done: () -> Unit,
|
|
34
35
|
): () -> Unit {
|
|
36
|
+
// With the system's animations off no element moves ([ElementTransition.start]): nothing to wait for.
|
|
37
|
+
if (SystemAnimations.areOff(to.peekView()?.context)) {
|
|
38
|
+
guarded { done() }
|
|
39
|
+
return NOTHING
|
|
40
|
+
}
|
|
35
41
|
var stopped = false
|
|
36
42
|
var stopImages: () -> Unit = NOTHING
|
|
37
43
|
val still = { !stopped && waiting() && from?.isDestroyed != true }
|
|
@@ -72,12 +78,14 @@ internal object TargetsWait {
|
|
|
72
78
|
): () -> Unit {
|
|
73
79
|
val fromView = from?.let { AppearanceDispatcher.visibleNode(it).peekView() }
|
|
74
80
|
val toView = AppearanceDispatcher.visibleNode(to).peekView()
|
|
81
|
+
val pairs = animation.sharedElements.get()
|
|
82
|
+
val views = TransitionViews(pairs, emptyList(), fromView, toView)
|
|
75
83
|
val images = ArrayList<ImageWait.Image?>()
|
|
76
|
-
for (pair in
|
|
84
|
+
for (pair in pairs) {
|
|
77
85
|
val fromId = pair.fromId.get(null) ?: continue
|
|
78
86
|
val toId = pair.toId.get(null) ?: continue
|
|
79
|
-
val source =
|
|
80
|
-
val target =
|
|
87
|
+
val source = views.leaving(fromId) ?: continue
|
|
88
|
+
val target = views.arriving(toId) ?: continue
|
|
81
89
|
images += imageOf(source, fromId)
|
|
82
90
|
images += imageOf(target, toId)
|
|
83
91
|
}
|
|
@@ -2,45 +2,35 @@ package dev.apexnative.navigation.views.element
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.Context
|
|
5
|
-
import android.graphics.
|
|
6
|
-
import android.graphics.Rect
|
|
5
|
+
import android.graphics.Canvas
|
|
7
6
|
import android.view.MotionEvent
|
|
8
7
|
import android.view.View
|
|
9
8
|
import android.view.ViewGroup
|
|
9
|
+
import dev.apexnative.navigation.views.element.animators.FlightPicture
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* The layer of a transition's elements: full size over the screens' common parent (a stack's
|
|
13
|
-
* the modals layer and the overlays layer), there only while the transition runs.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* accessibility doesn't see it. Main thread only.
|
|
12
|
+
* The layer the copies of a transition's shared elements fly in: full size over the screens' common parent (a stack's
|
|
13
|
+
* view; for a modal, between the modals layer and the overlays layer), there only while the transition runs. It holds
|
|
14
|
+
* no views: it draws the pictures of the flights ([FlightPicture]) in the order they are added, each while it is shown,
|
|
15
|
+
* on every frame while one of them is [FlightPicture.live]. A picture whose drawing fails draws no more, and its
|
|
16
|
+
* [FlightPicture.onFailed] runs after the frame. It takes no touches, accessibility doesn't see it. Main thread only.
|
|
17
17
|
*/
|
|
18
18
|
@SuppressLint("ViewConstructor")
|
|
19
|
-
internal class TransitionLayer(context: Context) :
|
|
20
|
-
|
|
21
|
-
private val reactFrames = HashMap<View, Rect>()
|
|
19
|
+
internal class TransitionLayer(context: Context) : View(context) {
|
|
20
|
+
private val pictures = ArrayList<FlightPicture>()
|
|
22
21
|
|
|
23
22
|
init {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
|
|
23
|
+
importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO
|
|
24
|
+
setWillNotDraw(false)
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
/** The layer's top left corner on the screen, in pixels: what the views in it are placed from. */
|
|
30
|
-
val originOnScreen: Point
|
|
31
|
-
get() {
|
|
32
|
-
val location = IntArray(2)
|
|
33
|
-
getLocationOnScreen(location)
|
|
34
|
-
return Point(location[0], location[1])
|
|
35
|
-
}
|
|
36
|
-
|
|
37
27
|
/**
|
|
38
|
-
* Joins [parent] at [index] (its top without one), laid out at once at the parent's size:
|
|
39
|
-
*
|
|
28
|
+
* Joins [parent] at [index] (its top without one), laid out at once at the parent's size: the places of the views
|
|
29
|
+
* are measured from it on the frame the transition starts.
|
|
40
30
|
*/
|
|
41
31
|
fun attachTo(parent: ViewGroup, index: Int = parent.childCount) {
|
|
42
32
|
// The parent turns these into its own kind of params.
|
|
43
|
-
parent.addView(this, index.coerceIn(0, parent.childCount), LayoutParams(MATCH, MATCH))
|
|
33
|
+
parent.addView(this, index.coerceIn(0, parent.childCount), ViewGroup.LayoutParams(MATCH, MATCH))
|
|
44
34
|
measure(
|
|
45
35
|
MeasureSpec.makeMeasureSpec(parent.width, MeasureSpec.EXACTLY),
|
|
46
36
|
MeasureSpec.makeMeasureSpec(parent.height, MeasureSpec.EXACTLY),
|
|
@@ -48,51 +38,10 @@ internal class TransitionLayer(context: Context) : ViewGroup(context) {
|
|
|
48
38
|
layout(0, 0, parent.width, parent.height)
|
|
49
39
|
}
|
|
50
40
|
|
|
51
|
-
/** [
|
|
52
|
-
fun
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
topMargin = top
|
|
56
|
-
}
|
|
57
|
-
addView(view, params)
|
|
58
|
-
layOut(view, left, top, width, height)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/** [view], in the layer, lies at [left], [top] at the size [width] × [height] from now on. */
|
|
62
|
-
fun place(view: View, left: Int, top: Int, width: Int, height: Int) {
|
|
63
|
-
noteReactFrame(view)
|
|
64
|
-
(view.layoutParams as? MarginLayoutParams)?.let {
|
|
65
|
-
it.leftMargin = left
|
|
66
|
-
it.topMargin = top
|
|
67
|
-
it.width = width
|
|
68
|
-
it.height = height
|
|
69
|
-
}
|
|
70
|
-
layOut(view, left, top, width, height)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
private fun layOut(view: View, left: Int, top: Int, width: Int, height: Int) {
|
|
74
|
-
view.measure(
|
|
75
|
-
MeasureSpec.makeMeasureSpec(width.coerceAtLeast(0), MeasureSpec.EXACTLY),
|
|
76
|
-
MeasureSpec.makeMeasureSpec(height.coerceAtLeast(0), MeasureSpec.EXACTLY),
|
|
77
|
-
)
|
|
78
|
-
view.layout(left, top, left + width, top + height)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* The newest frame React gave [view] while it was in the layer, in its parent's coordinates; none when React
|
|
83
|
-
* didn't lay it out meanwhile. A frame other than the one the layer gave it can only be React's.
|
|
84
|
-
*/
|
|
85
|
-
fun frameFromReact(view: View): Rect? {
|
|
86
|
-
noteReactFrame(view)
|
|
87
|
-
return reactFrames.remove(view)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// The view's frame isn't where the layer put it: React laid it out since.
|
|
91
|
-
private fun noteReactFrame(view: View) {
|
|
92
|
-
val params = view.layoutParams as? MarginLayoutParams ?: return
|
|
93
|
-
val placed = view.left == params.leftMargin && view.top == params.topMargin &&
|
|
94
|
-
view.width == params.width && view.height == params.height
|
|
95
|
-
if (!placed) reactFrames[view] = Rect(view.left, view.top, view.right, view.bottom)
|
|
41
|
+
/** [picture] is drawn over those added before it. */
|
|
42
|
+
fun add(picture: FlightPicture) {
|
|
43
|
+
pictures += picture
|
|
44
|
+
invalidate()
|
|
96
45
|
}
|
|
97
46
|
|
|
98
47
|
/** The layer leaves its parent. */
|
|
@@ -100,53 +49,29 @@ internal class TransitionLayer(context: Context) : ViewGroup(context) {
|
|
|
100
49
|
(parent as? ViewGroup)?.removeView(this)
|
|
101
50
|
}
|
|
102
51
|
|
|
103
|
-
override fun
|
|
104
|
-
|
|
105
|
-
for (
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
val child = getChildAt(index)
|
|
118
|
-
val params = child.layoutParams as? MarginLayoutParams ?: continue
|
|
119
|
-
noteReactFrame(child)
|
|
120
|
-
child.layout(
|
|
121
|
-
params.leftMargin,
|
|
122
|
-
params.topMargin,
|
|
123
|
-
params.leftMargin + child.measuredWidth,
|
|
124
|
-
params.topMargin + child.measuredHeight,
|
|
125
|
-
)
|
|
52
|
+
override fun onDraw(canvas: Canvas) {
|
|
53
|
+
var live = false
|
|
54
|
+
for (picture in pictures) {
|
|
55
|
+
if (!picture.shown) continue
|
|
56
|
+
live = live || picture.live
|
|
57
|
+
val count = canvas.save()
|
|
58
|
+
try {
|
|
59
|
+
picture.draw(canvas)
|
|
60
|
+
} catch (e: RuntimeException) {
|
|
61
|
+
picture.shown = false
|
|
62
|
+
post { picture.onFailed(e) }
|
|
63
|
+
} finally {
|
|
64
|
+
canvas.restoreToCount(count)
|
|
65
|
+
}
|
|
126
66
|
}
|
|
67
|
+
// A landed copy gets no more frames from its flight: one that changes by itself asks for them.
|
|
68
|
+
if (live) postInvalidateOnAnimation()
|
|
127
69
|
}
|
|
128
70
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
override fun generateDefaultLayoutParams(): LayoutParams = MarginLayoutParams(0, 0)
|
|
132
|
-
|
|
133
|
-
override fun generateLayoutParams(params: LayoutParams?): LayoutParams = MarginLayoutParams(params)
|
|
134
|
-
|
|
71
|
+
@SuppressLint("ClickableViewAccessibility")
|
|
135
72
|
override fun dispatchTouchEvent(event: MotionEvent?): Boolean = false
|
|
136
73
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
companion object {
|
|
140
|
-
private const val MATCH = LayoutParams.MATCH_PARENT
|
|
141
|
-
|
|
142
|
-
/** Whether [view] is in a transition's layer now (an element of another transition). */
|
|
143
|
-
fun holds(view: View): Boolean {
|
|
144
|
-
var parent = view.parent
|
|
145
|
-
while (parent != null) {
|
|
146
|
-
if (parent is TransitionLayer) return true
|
|
147
|
-
parent = parent.parent
|
|
148
|
-
}
|
|
149
|
-
return false
|
|
150
|
-
}
|
|
74
|
+
private companion object {
|
|
75
|
+
const val MATCH = ViewGroup.LayoutParams.MATCH_PARENT
|
|
151
76
|
}
|
|
152
77
|
}
|