@apexnative/navigation 1.0.0-alpha.1 → 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 +120 -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/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 +3 -1
- 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
|
@@ -7,17 +7,13 @@ import android.app.Activity
|
|
|
7
7
|
import android.content.Context
|
|
8
8
|
import android.content.pm.ApplicationInfo
|
|
9
9
|
import android.graphics.Color
|
|
10
|
-
import android.graphics.drawable.BitmapDrawable
|
|
11
10
|
import android.graphics.drawable.Drawable
|
|
12
|
-
import android.view.Menu
|
|
13
|
-
import android.view.MenuItem
|
|
14
11
|
import android.view.MotionEvent
|
|
15
12
|
import android.view.View
|
|
16
13
|
import android.view.ViewGroup
|
|
17
14
|
import android.view.animation.LinearInterpolator
|
|
18
15
|
import android.view.animation.PathInterpolator
|
|
19
16
|
import android.widget.FrameLayout
|
|
20
|
-
import android.widget.ImageView
|
|
21
17
|
import androidx.appcompat.content.res.AppCompatResources
|
|
22
18
|
import androidx.core.graphics.drawable.DrawableCompat
|
|
23
19
|
import androidx.core.view.WindowInsetsCompat
|
|
@@ -41,7 +37,6 @@ import dev.apexnative.navigation.utils.ImageLoader
|
|
|
41
37
|
import dev.apexnative.navigation.utils.ImageLoadingListenerAdapter
|
|
42
38
|
import dev.apexnative.navigation.utils.TestIds
|
|
43
39
|
import dev.apexnative.navigation.utils.UiUtils
|
|
44
|
-
import dev.apexnative.navigation.viewcontrollers.component.ScreenReadiness
|
|
45
40
|
import dev.apexnative.navigation.viewcontrollers.navigator.BackCallbackState
|
|
46
41
|
import dev.apexnative.navigation.viewcontrollers.stack.StackDisplay
|
|
47
42
|
import dev.apexnative.navigation.viewcontrollers.stack.StackDisplay.BarMotion
|
|
@@ -49,7 +44,9 @@ import dev.apexnative.navigation.viewcontrollers.stack.search.StackSearchPresent
|
|
|
49
44
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.IReactView
|
|
50
45
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ScrollEventListener
|
|
51
46
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
47
|
+
import dev.apexnative.navigation.views.animations.AnimationRules
|
|
52
48
|
import dev.apexnative.navigation.views.animations.SideAnimator
|
|
49
|
+
import dev.apexnative.navigation.views.animations.FadeThrough
|
|
53
50
|
import dev.apexnative.navigation.views.animations.SystemTransition
|
|
54
51
|
import dev.apexnative.navigation.views.component.ComponentLayout
|
|
55
52
|
import dev.apexnative.navigation.views.stack.StackLayout
|
|
@@ -58,8 +55,10 @@ import dev.apexnative.navigation.views.stack.topbar.TitleBar
|
|
|
58
55
|
import dev.apexnative.navigation.views.stack.topbar.TopBar
|
|
59
56
|
import dev.apexnative.navigation.views.stack.topbar.TopBarDefaults
|
|
60
57
|
import dev.apexnative.navigation.views.stack.topbar.titlebar.BarButtonComponentCell
|
|
58
|
+
import dev.apexnative.navigation.views.stack.topbar.titlebar.BarMenu
|
|
61
59
|
import dev.apexnative.navigation.views.stack.topbar.titlebar.ButtonBar
|
|
62
60
|
import dev.apexnative.navigation.views.stack.topbar.titlebar.IconBackgroundDrawable
|
|
61
|
+
import kotlin.math.roundToInt
|
|
63
62
|
|
|
64
63
|
/**
|
|
65
64
|
* What the bar of one stack shows: the options of the screen on top of the stack, resolved (a pair's options screen),
|
|
@@ -123,8 +122,15 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
123
122
|
private var largeTitleShown = false
|
|
124
123
|
private var followed: ScrollEventListener? = null
|
|
125
124
|
private var rowTarget: RowTarget? = null
|
|
125
|
+
// The large title opening with a push from a screen without one; none at rest.
|
|
126
|
+
private var largeTitleOpening: ValueAnimator? = null
|
|
126
127
|
// The picture of the part under the row in a leaving screen's overlay: the screen and the picture.
|
|
127
128
|
private var underRow: Pair<ViewController<*>, Drawable>? = null
|
|
129
|
+
// The bar goes with the screens of a transition of the stack's own, and the screen that leaves with its picture.
|
|
130
|
+
private var travelling = false
|
|
131
|
+
private var travelLeaving: ViewController<*>? = null
|
|
132
|
+
// The bar hides as it shows now, and the options of the screen it hides for wait until it is gone.
|
|
133
|
+
private var waitsForHide = false
|
|
128
134
|
|
|
129
135
|
private enum class Part { Look, Title, Left, Right, Back, LargeTitle, Visible, TestId }
|
|
130
136
|
|
|
@@ -135,9 +141,9 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
135
141
|
this.layout = layout
|
|
136
142
|
val bar = layout.topBar
|
|
137
143
|
this.bar = bar
|
|
138
|
-
leftButtons = ButtonBar(bar.leftButtonBar,
|
|
139
|
-
rightButtons = ButtonBar(bar.rightButtonBar,
|
|
140
|
-
visibility = TopBarVisibility(VisibilityTarget(bar) { collapse?.reset() })
|
|
144
|
+
leftButtons = ButtonBar(bar.leftButtonBar, ::loadIcon, Buttons())
|
|
145
|
+
rightButtons = ButtonBar(bar.rightButtonBar, ::loadIcon, Buttons())
|
|
146
|
+
visibility = TopBarVisibility(VisibilityTarget(bar) { collapse?.reset() }, ::hidden)
|
|
141
147
|
rowTransition = BarRowTransition(RowTarget(bar).also { rowTarget = it })
|
|
142
148
|
collapse = TopBarCollapseBehavior(bar)
|
|
143
149
|
bar.leftButtonBar.setNavigationOnClickListener { host.backPressed() }
|
|
@@ -160,12 +166,16 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
160
166
|
* The stack's current child changes to [incoming] ([motion]: the default transition that brings it, none at once):
|
|
161
167
|
* the row's picture is taken before the bar takes the new screen's options. A push from a large title to a screen
|
|
162
168
|
* without one makes the bar lower at once: the part under the row rides with the leaving screen as a picture in its
|
|
163
|
-
* overlay, and the row's picture holds the row only. So does a pop
|
|
169
|
+
* overlay, and the row's picture holds the row only. So does a pop or a fade through (`setStackRoot`) to a screen
|
|
170
|
+
* without a large title or with its large title collapsed: a picture as tall as the large title would hold the bar
|
|
171
|
+
* at its height to the end. With a transition of the stack's own ([travel]) the bar goes with the screens instead
|
|
172
|
+
* ([beginTravel]).
|
|
164
173
|
*/
|
|
165
174
|
fun beginRowTransition(
|
|
166
175
|
motion: BarMotion?,
|
|
167
176
|
incoming: ViewController<*>?,
|
|
168
177
|
visibility: StackDisplay.BarVisibility = StackDisplay.BarVisibility.AT_ONCE,
|
|
178
|
+
travel: StackDisplay.BarTravel? = null,
|
|
169
179
|
) {
|
|
170
180
|
this.motion = motion
|
|
171
181
|
this.visibilityChange = visibility
|
|
@@ -174,18 +184,82 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
174
184
|
val bar = bar
|
|
175
185
|
val leaving = shownEntry
|
|
176
186
|
val lowers = bar != null && bar.isLargeTitleShown && incoming != null && leaving != null &&
|
|
187
|
+
!hidesMoving(host.resolvedOf(incoming), visibility, travel != null) &&
|
|
177
188
|
lowersBar(motion, incoming, host.resolvedOf(incoming))
|
|
178
189
|
rowTarget?.withLargeTitle = !lowers
|
|
179
190
|
if (lowers) pictureUnderRow(bar, leaving)
|
|
180
191
|
rowTransition?.begin(motion)
|
|
192
|
+
endTravel()
|
|
193
|
+
if (travel != null && bar != null && incoming != null) beginTravel(bar, leaving, incoming, travel, visibility)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Whether a screen with [options] hides the bar, shown now, by a move of [change]: a slide, or the transition's
|
|
197
|
+
// side. The bar then leaves as it shows, its large title too (`applyAll`); while it goes with the screens of a
|
|
198
|
+
// transition of the stack's own ([travels]) only a side of its own moves it.
|
|
199
|
+
private fun hidesMoving(options: Options, change: StackDisplay.BarVisibility, travels: Boolean): Boolean {
|
|
200
|
+
val exit = change.side?.exit
|
|
201
|
+
return options.topBar.visible.isFalse && !options.topBar.animate.isFalse && change.animated &&
|
|
202
|
+
!AnimationRules.isTurnedOff(exit) && (!travels || AnimationRules.barSideGiven(exit))
|
|
181
203
|
}
|
|
182
204
|
|
|
183
205
|
/** The transition that brought the current child ended: the row at rest, the picture under it gone. */
|
|
184
206
|
fun endRowTransition() {
|
|
207
|
+
// A large title still opening is open now.
|
|
208
|
+
largeTitleOpening?.let {
|
|
209
|
+
largeTitleOpening = null
|
|
210
|
+
it.end()
|
|
211
|
+
}
|
|
185
212
|
motion = null
|
|
186
213
|
visibilityChange = StackDisplay.BarVisibility.AT_ONCE
|
|
187
214
|
rowTransition?.end()
|
|
188
215
|
dropPictureUnderRow()
|
|
216
|
+
endTravel()
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* The bar goes with the screens of a transition of the stack's own, as each screen's bar would: a picture of the
|
|
221
|
+
* bar as it is goes with [leaving], and the bar, which takes [incoming]'s options next, is drawn flat as [incoming]
|
|
222
|
+
* moves — under [leaving] on a pop ([StackDisplay.BarTravel.Back]) (`StackLayout.barTravels`). No picture when the
|
|
223
|
+
* bar doesn't show. Nothing travels when the new top hides the bar by a side of its own
|
|
224
|
+
* (`animations.*.topBar.exit`), which plays instead, or when the bar can't be recorded (a `HARDWARE` bitmap in it
|
|
225
|
+
* on Android 8): the bar takes the options in its place.
|
|
226
|
+
*/
|
|
227
|
+
private fun beginTravel(
|
|
228
|
+
bar: TopBar,
|
|
229
|
+
leaving: ViewController<*>?,
|
|
230
|
+
incoming: ViewController<*>,
|
|
231
|
+
direction: StackDisplay.BarTravel,
|
|
232
|
+
visibility: StackDisplay.BarVisibility,
|
|
233
|
+
) {
|
|
234
|
+
val layout = layout ?: return
|
|
235
|
+
val screen = incoming.peekView()?.takeIf(layout::holds) ?: return
|
|
236
|
+
val leavingView = leaving?.peekView()?.takeIf(layout::holds)
|
|
237
|
+
// The new top hides the bar by a side of its own: the side plays on the bar in its place instead.
|
|
238
|
+
if (host.resolvedOf(incoming).topBar.visible.isFalse && AnimationRules.barSideGiven(visibility.side?.exit)) return
|
|
239
|
+
val shows = bar.visibility == View.VISIBLE && this.visibility?.isHidden != true
|
|
240
|
+
val picture = if (shows && leavingView != null) pictureOfBar(bar) ?: return else null
|
|
241
|
+
travelling = true
|
|
242
|
+
travelLeaving = leaving.takeIf { picture != null }
|
|
243
|
+
// Flat: with an elevation the renderer would draw the bar over every screen and out of its alpha layer.
|
|
244
|
+
bar.isFlat = true
|
|
245
|
+
layout.barTravels(screen, leavingView, picture, direction == StackDisplay.BarTravel.Back)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// The bar's picture where the bar is in the stack, its moves counted.
|
|
249
|
+
private fun pictureOfBar(bar: TopBar): Drawable? {
|
|
250
|
+
val picture = bar.picture() ?: return null
|
|
251
|
+
val left = (bar.left + bar.translationX).roundToInt()
|
|
252
|
+
val top = (bar.top + bar.translationY).roundToInt()
|
|
253
|
+
return picture.apply { setBounds(left, top, left + intrinsicWidth, top + intrinsicHeight) }
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// The bar's travel ends: the picture goes, the bar is drawn in its place again with its shadow.
|
|
257
|
+
private fun endTravel() {
|
|
258
|
+
if (!travelling) return
|
|
259
|
+
travelling = false
|
|
260
|
+
travelLeaving = null
|
|
261
|
+
bar?.isFlat = false
|
|
262
|
+
layout?.endBarTravel()
|
|
189
263
|
}
|
|
190
264
|
|
|
191
265
|
/**
|
|
@@ -204,8 +278,9 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
204
278
|
keys.clear()
|
|
205
279
|
}
|
|
206
280
|
shownEntry = entry
|
|
207
|
-
// The screen that left with the picture under the row shows again: the picture goes.
|
|
281
|
+
// The screen that left with the picture under the row, or of the bar, shows again: the picture goes.
|
|
208
282
|
if (underRow?.first === entry) dropPictureUnderRow()
|
|
283
|
+
if (travelLeaving === entry) endTravel()
|
|
209
284
|
val options = host.resolvedOf(entry)
|
|
210
285
|
applyAll(bar, entry, screen, options, merge = false)
|
|
211
286
|
}
|
|
@@ -218,6 +293,8 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
218
293
|
val bar = bar ?: return
|
|
219
294
|
val screen = host.optionsScreen(entry)
|
|
220
295
|
if (screen !== shownScreen) return apply(entry)
|
|
296
|
+
// An open menu has the colors of before.
|
|
297
|
+
if (delta.topBar.menuBackgroundColor.hasValue() || delta.topBar.menuTextColor.hasValue()) closeMenus()
|
|
221
298
|
val options = host.resolvedOf(entry)
|
|
222
299
|
applyAll(bar, entry, screen, options, merge = true, delta = delta)
|
|
223
300
|
}
|
|
@@ -227,6 +304,8 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
227
304
|
* now.
|
|
228
305
|
*/
|
|
229
306
|
fun repaint(entry: ViewController<*>?) {
|
|
307
|
+
// An open menu has the old colors: it closes.
|
|
308
|
+
closeMenus()
|
|
230
309
|
keys.clear()
|
|
231
310
|
apply(entry)
|
|
232
311
|
val options = entry?.let(host::resolvedOf) ?: return
|
|
@@ -239,6 +318,7 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
239
318
|
* of the bar (the search) applies again.
|
|
240
319
|
*/
|
|
241
320
|
fun onInsets() {
|
|
321
|
+
if (waitsForHide) return
|
|
242
322
|
val bar = bar ?: return
|
|
243
323
|
val entry = shownEntry ?: return
|
|
244
324
|
val screen = shownScreen ?: return
|
|
@@ -313,6 +393,12 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
313
393
|
|
|
314
394
|
/** [screen] is destroyed: its components and its search go. */
|
|
315
395
|
fun screenDestroyed(screen: ViewController<*>, entryView: View?) {
|
|
396
|
+
// The bar may still show the components of the screen that goes: it is gone at once, with the options it held
|
|
397
|
+
// back, before they go; none when they are of the screen that goes.
|
|
398
|
+
if (waitsForHide) {
|
|
399
|
+
if (screen === shownScreen) waitsForHide = false
|
|
400
|
+
visibility?.hide(animated = false)
|
|
401
|
+
}
|
|
316
402
|
if (screen === shownScreen) {
|
|
317
403
|
shownScreen = null
|
|
318
404
|
shownEntry = null
|
|
@@ -333,7 +419,9 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
333
419
|
/** The stack is destroyed: every component stops. */
|
|
334
420
|
fun destroy() {
|
|
335
421
|
rowTransition?.end()
|
|
422
|
+
endTravel()
|
|
336
423
|
largeTitleFollower.stop()
|
|
424
|
+
stopLargeTitleOpening()
|
|
337
425
|
collapse?.disableCollapse()
|
|
338
426
|
components.destroyAll()
|
|
339
427
|
cells.clear()
|
|
@@ -369,6 +457,9 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
369
457
|
)
|
|
370
458
|
}
|
|
371
459
|
|
|
460
|
+
/** Whether the bar shows [entry]: its parts are applied, so its place in the layout is [entry]'s. */
|
|
461
|
+
fun shows(entry: ViewController<*>): Boolean = entry === shownEntry
|
|
462
|
+
|
|
372
463
|
/** The height of the search under the row of [entry] when it is the screen the bar shows; 0 otherwise. */
|
|
373
464
|
fun searchHeightOf(entry: ViewController<*>): Int =
|
|
374
465
|
if (entry === shownEntry) bar?.searchAreaHeight ?: 0 else 0
|
|
@@ -394,6 +485,26 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
394
485
|
merge: Boolean,
|
|
395
486
|
delta: Options? = null,
|
|
396
487
|
) {
|
|
488
|
+
// A screen that hides the bar: the bar leaves as it shows, its look, title and buttons those of the screen
|
|
489
|
+
// before, and takes this screen's options once it is gone. Taken first, they would paint the leaving bar (the
|
|
490
|
+
// default color over a bar that was transparent).
|
|
491
|
+
val waited = waitsForHide
|
|
492
|
+
waitsForHide = false
|
|
493
|
+
if (options.topBar.visible.isFalse && (!merge || waited)) {
|
|
494
|
+
applyVisibility(options, merge)
|
|
495
|
+
waitsForHide = visibility?.isHiding == true
|
|
496
|
+
if (waitsForHide) {
|
|
497
|
+
// The list of the screen before no longer moves the bar: a move of it would stop the hide.
|
|
498
|
+
collapse?.disableCollapse(reset = false)
|
|
499
|
+
return
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
// Shown again by a merge before it was gone: none of this screen's options are on the bar yet. It shows as a
|
|
503
|
+
// merge shows it, by `animate`, not by the transition's side.
|
|
504
|
+
if (merge && waited) {
|
|
505
|
+
visibilityChange = StackDisplay.BarVisibility(true, null)
|
|
506
|
+
return applyAll(bar, entry, screen, options, merge = false)
|
|
507
|
+
}
|
|
397
508
|
applyLook(bar, entry, options)
|
|
398
509
|
applyTitle(bar, screen, options)
|
|
399
510
|
// The search first: its magnifier takes a place among the right buttons. It gets a copy of the group: it
|
|
@@ -511,16 +622,15 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
511
622
|
keys[Part.Left] = leftKey
|
|
512
623
|
reportWithoutId(topBar.buttons.left, "leftButtons")
|
|
513
624
|
leftButtons?.set(
|
|
514
|
-
left.map { button(screen, it, roots) },
|
|
625
|
+
ButtonPlaces.line(left, left = true).map { button(screen, it, roots) },
|
|
515
626
|
emptyList(),
|
|
516
627
|
null,
|
|
517
628
|
merge && topBar.animateLeftButtons.isTrue,
|
|
518
629
|
)
|
|
519
630
|
}
|
|
520
631
|
val overflow = topBar.overflowMenu?.takeIf { it.items.isNotEmpty() }
|
|
521
|
-
val menu = bar.rightButtonBar.menu
|
|
522
632
|
search.applyMagnifier()
|
|
523
|
-
val taken =
|
|
633
|
+
val taken = if (bar.rightButtonBar.trailingView != null) 1 else 0
|
|
524
634
|
val configuration = context.resources.configuration
|
|
525
635
|
val plan = ButtonPlaces.plan(
|
|
526
636
|
right.map { ButtonPlaces.Button(ButtonPlaces.priorityOf(it.priority.get(null)), it.pinned.isTrue) },
|
|
@@ -541,12 +651,11 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
541
651
|
keys[Part.Right] = rightKey
|
|
542
652
|
reportWithoutId(topBar.buttons.right, "rightButtons")
|
|
543
653
|
rightButtons?.set(
|
|
544
|
-
plan.inBar.map { button(screen, right[it], roots) },
|
|
654
|
+
ButtonPlaces.line(plan.inBar, left = false).map { button(screen, right[it], roots) },
|
|
545
655
|
plan.inOverflow.map { button(screen, right[it], roots) },
|
|
546
656
|
overflow,
|
|
547
657
|
merge && topBar.animateRightButtons.isTrue,
|
|
548
658
|
)
|
|
549
|
-
search.applyMagnifier()
|
|
550
659
|
rightButtons?.setOverflowColor(overflowColor)
|
|
551
660
|
}
|
|
552
661
|
}
|
|
@@ -568,9 +677,9 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
568
677
|
).joinToString()
|
|
569
678
|
if (keys[Part.Back] == key) return
|
|
570
679
|
keys[Part.Back] = key
|
|
571
|
-
val
|
|
680
|
+
val row = bar.leftButtonBar
|
|
572
681
|
if (!shown) {
|
|
573
|
-
|
|
682
|
+
row.navigationIcon = null
|
|
574
683
|
return
|
|
575
684
|
}
|
|
576
685
|
val own = back.icon.get(null)?.let(::loadIcon)?.mutate()
|
|
@@ -597,19 +706,13 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
597
706
|
dp(background.height.get(0.0)),
|
|
598
707
|
)
|
|
599
708
|
} ?: icon
|
|
600
|
-
|
|
601
|
-
// Taking the icon, the
|
|
602
|
-
//
|
|
603
|
-
// gets the bar's direction at once
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
toolbar.navigationContentDescription = label
|
|
608
|
-
// The toolbar uses its navigation button again from screen to screen: its id is set every time.
|
|
609
|
-
for (index in 0 until toolbar.childCount) {
|
|
610
|
-
val child = toolbar.getChildAt(index)
|
|
611
|
-
if ((child as? ImageView)?.drawable === held) TestIds.apply(child, testId)
|
|
612
|
-
}
|
|
709
|
+
row.navigationIcon = drawable
|
|
710
|
+
// Taking the icon, the back button gives it its own direction, which is stale while the button is new or the
|
|
711
|
+
// bar's direction has just changed; the button corrects it only once its direction is resolved again. So the
|
|
712
|
+
// arrow gets the bar's direction at once; a background passes it to the arrow.
|
|
713
|
+
DrawableCompat.setLayoutDirection(drawable, arrowDirection)
|
|
714
|
+
row.navigationContentDescription = label
|
|
715
|
+
row.navigationButton?.let { TestIds.apply(it, testId) }
|
|
613
716
|
}
|
|
614
717
|
|
|
615
718
|
// The background (`topBar.background.component`).
|
|
@@ -632,11 +735,13 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
632
735
|
}
|
|
633
736
|
|
|
634
737
|
// Whether [incoming] shows less of the bar under the row than the large title now: a push to a screen without a
|
|
635
|
-
// large title, or a pop
|
|
738
|
+
// large title, or a pop or a fade through to one without a large title or with its large title collapsed. The lower
|
|
739
|
+
// bar would cut the row's picture.
|
|
636
740
|
private fun lowersBar(motion: BarMotion?, incoming: ViewController<*>, options: Options): Boolean = when (motion) {
|
|
637
741
|
BarMotion.Push -> !largeTitleShownFor(incoming, options)
|
|
638
|
-
BarMotion.Pop
|
|
639
|
-
|
|
742
|
+
BarMotion.Pop, BarMotion.FadeThrough ->
|
|
743
|
+
!largeTitleShownFor(incoming, options) || collapseOf(incoming, options) > 0f
|
|
744
|
+
null -> false
|
|
640
745
|
}
|
|
641
746
|
|
|
642
747
|
// How far [entry]'s large title is collapsed as it shows: by the offset its list had last, unless it doesn't follow
|
|
@@ -646,15 +751,14 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
646
751
|
|
|
647
752
|
private fun pictureUnderRow(bar: TopBar, leaving: ViewController<*>) {
|
|
648
753
|
val view = leaving.peekView() ?: return
|
|
649
|
-
val (
|
|
754
|
+
val (picture, top) = bar.pictureUnderRow() ?: return
|
|
650
755
|
val barPlace = IntArray(2)
|
|
651
756
|
val viewPlace = IntArray(2)
|
|
652
757
|
bar.getLocationInWindow(barPlace)
|
|
653
758
|
view.getLocationInWindow(viewPlace)
|
|
654
|
-
val picture = BitmapDrawable(bar.resources, bitmap)
|
|
655
759
|
val left = barPlace[0] - viewPlace[0]
|
|
656
760
|
val y = barPlace[1] + top - viewPlace[1]
|
|
657
|
-
picture.setBounds(left, y, left +
|
|
761
|
+
picture.setBounds(left, y, left + picture.intrinsicWidth, y + picture.intrinsicHeight)
|
|
658
762
|
view.overlay.add(picture)
|
|
659
763
|
underRow = leaving to picture
|
|
660
764
|
}
|
|
@@ -674,6 +778,11 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
674
778
|
large.fontSize.get(null), fontKey(large.font), large.collapseOnScroll.get(null), testId).joinToString()
|
|
675
779
|
if (keys[Part.LargeTitle] == key) return
|
|
676
780
|
keys[Part.LargeTitle] = key
|
|
781
|
+
// The default push or fade through from a screen without a large title opens it with the screens, on a bar that
|
|
782
|
+
// shows at rest: the bar's show and its hide on scroll move the same translation.
|
|
783
|
+
val opening = motion.takeIf { it == BarMotion.Push || it == BarMotion.FadeThrough }
|
|
784
|
+
val opens = shown && !largeTitleShown && bar.visibility == View.VISIBLE && bar.translationY == 0f
|
|
785
|
+
stopLargeTitleOpening()
|
|
677
786
|
largeTitleShown = shown
|
|
678
787
|
bar.setLargeTitleShown(shown)
|
|
679
788
|
largeTitleFollower.stop()
|
|
@@ -691,9 +800,49 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
691
800
|
// same frame: back to the screen, after light or dark changed, after a merge.
|
|
692
801
|
if (large.collapseOnScroll.isFalse) scrollOf(entry)?.forgetOffset()
|
|
693
802
|
largeTitleFollower.collapse(collapseOf(entry, options))
|
|
803
|
+
if (opens) opening?.let { openLargeTitle(bar, collapseOf(entry, options), it) }
|
|
694
804
|
if (!large.collapseOnScroll.isFalse) scrollOf(entry)?.let(largeTitleFollower::follow)
|
|
695
805
|
}
|
|
696
806
|
|
|
807
|
+
// The bar grows with the screens' [motion], on its curve and in its time, from the row's height to the large title
|
|
808
|
+
// as the screen's list left it: the large title comes out from under the row as it does when the list scrolls
|
|
809
|
+
// back. No frame shows the tall bar before the screens move.
|
|
810
|
+
private fun openLargeTitle(bar: TopBar, offset: Float, motion: BarMotion) {
|
|
811
|
+
val range = UiUtils.dpToPx(bar.context, LargeTitleView.HEIGHT)
|
|
812
|
+
val to = LargeTitleCollapse.shift(offset, range)
|
|
813
|
+
if (to >= range) return
|
|
814
|
+
bar.setLargeTitleCollapse(range.toInt())
|
|
815
|
+
largeTitleOpening = ValueAnimator.ofFloat(range, to).apply {
|
|
816
|
+
duration = if (motion == BarMotion.FadeThrough) FadeThrough.DURATION else SystemTransition.DURATION
|
|
817
|
+
interpolator = if (motion == BarMotion.FadeThrough) FadeThrough.CURVE else SystemTransition.CURVE
|
|
818
|
+
addUpdateListener { bar.setLargeTitleCollapse((it.animatedValue as Float).toInt()) }
|
|
819
|
+
addListener(object : AnimatorListenerAdapter() {
|
|
820
|
+
override fun onAnimationEnd(animation: Animator) {
|
|
821
|
+
if (largeTitleOpening === animation) largeTitleOpening = null
|
|
822
|
+
}
|
|
823
|
+
})
|
|
824
|
+
start()
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// Stopped where it is: what applies next sets the large title.
|
|
829
|
+
private fun stopLargeTitleOpening() {
|
|
830
|
+
val opening = largeTitleOpening ?: return
|
|
831
|
+
largeTitleOpening = null
|
|
832
|
+
opening.removeAllUpdateListeners()
|
|
833
|
+
opening.cancel()
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// A hide that held the options back ended: the bar, gone now, takes them.
|
|
837
|
+
private fun hidden() {
|
|
838
|
+
if (!waitsForHide) return
|
|
839
|
+
waitsForHide = false
|
|
840
|
+
val bar = bar ?: return
|
|
841
|
+
val entry = shownEntry ?: return
|
|
842
|
+
val screen = shownScreen ?: return
|
|
843
|
+
applyAll(bar, entry, screen, host.resolvedOf(entry), merge = false)
|
|
844
|
+
}
|
|
845
|
+
|
|
697
846
|
// Shown or hidden: with the transition by its side, or by `animate` in a merge.
|
|
698
847
|
private fun applyVisibility(options: Options, merge: Boolean) {
|
|
699
848
|
val visible = !options.topBar.visible.isFalse
|
|
@@ -701,7 +850,10 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
701
850
|
if (keys[Part.Visible] == key) return
|
|
702
851
|
keys[Part.Visible] = key
|
|
703
852
|
val change = visibilityChange
|
|
704
|
-
|
|
853
|
+
// While the bar goes with the screens it shows or hides at once, unless its side of its own plays.
|
|
854
|
+
val travels = !merge && travelling &&
|
|
855
|
+
!AnimationRules.barSideGiven(if (visible) change.side?.enter else change.side?.exit)
|
|
856
|
+
val animated = !options.topBar.animate.isFalse && (merge || change.animated) && !travels
|
|
705
857
|
visibility?.apply(visible, animated, if (merge) null else change.side)
|
|
706
858
|
}
|
|
707
859
|
|
|
@@ -824,14 +976,10 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
824
976
|
return resolved.component
|
|
825
977
|
}
|
|
826
978
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
// this root's, which answers by its own render.
|
|
832
|
-
if (BarComponents.isLive(componentId)) ScreenReadiness.forgetRender(componentId)
|
|
833
|
-
return ReactView(activity, componentId, name)
|
|
834
|
-
}
|
|
979
|
+
// A component of the bar renders at once, without waiting for its layout. Another live root may show the same id
|
|
980
|
+
// (a component of the stack's options on two screens): each answers by the render of its own surface.
|
|
981
|
+
private fun makeRoot(componentId: String, name: String): IReactView =
|
|
982
|
+
ReactView(activity, componentId, name, rendersAtOnce = true)
|
|
835
983
|
|
|
836
984
|
private fun loadIcon(uri: String): Drawable? {
|
|
837
985
|
var loaded: Drawable? = null
|
|
@@ -881,7 +1029,7 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
881
1029
|
else -> TitleBar.Alignment.Start
|
|
882
1030
|
}
|
|
883
1031
|
|
|
884
|
-
private fun dp(value: Double): Int = UiUtils.dpToPx(activity, value.toFloat()).
|
|
1032
|
+
private fun dp(value: Double): Int = UiUtils.dpToPx(activity, value.toFloat()).roundToInt()
|
|
885
1033
|
|
|
886
1034
|
// What makes a button's look, as a text: the parts that differ make it apply again.
|
|
887
1035
|
private fun buttonKey(context: Context, button: ButtonOptions): String = listOf(
|
|
@@ -896,8 +1044,16 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
896
1044
|
button.priority.get(null),
|
|
897
1045
|
).joinToString("|")
|
|
898
1046
|
|
|
899
|
-
|
|
900
|
-
|
|
1047
|
+
// What the overflow menu shows, its submenus and checks with it: a check the app moves, or one of the user layer
|
|
1048
|
+
// that leaves, fills the menu again.
|
|
1049
|
+
private fun menuKey(menu: ButtonMenuOptions): String = elementsKey(menu.items) + menu.testID
|
|
1050
|
+
|
|
1051
|
+
private fun elementsKey(elements: List<ButtonMenuOptions.Element>): String = elements.joinToString("|") {
|
|
1052
|
+
"${it.title}:${it.icon}:${it.testID}" + when (it) {
|
|
1053
|
+
is ButtonMenuOptions.Item -> ":${it.checked}:${it.disabled}"
|
|
1054
|
+
is ButtonMenuOptions.Submenu -> "[${elementsKey(it.items)}]"
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
901
1057
|
|
|
902
1058
|
private fun fontKey(font: FontOptions): String =
|
|
903
1059
|
listOf(font.fontFamily, font.fontStyle, font.fontWeight).joinToString { it.get(null).toString() }
|
|
@@ -922,11 +1078,16 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
922
1078
|
return (buttons.left.orEmpty() + buttons.right.orEmpty()).firstOrNull { it.id.get(null) == buttonId }?.menu
|
|
923
1079
|
}
|
|
924
1080
|
|
|
925
|
-
//
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1081
|
+
// Read as a menu opens, so they follow light and dark mode: `menuBackgroundColor`, else the bar's color as it
|
|
1082
|
+
// shows (none when it lets something through), and then `menuTextColor` or else the title's color, the pair
|
|
1083
|
+
// the bar shows; with neither, the theme's.
|
|
1084
|
+
override fun menuColors(): BarMenu.Colors {
|
|
1085
|
+
val topBar = shownEntry?.let(host::resolvedOf)?.topBar ?: return BarMenu.Colors(null, null)
|
|
1086
|
+
val context = bar?.context ?: activity
|
|
1087
|
+
val text = topBar.menuTextColor.get(context, null)
|
|
1088
|
+
topBar.menuBackgroundColor.get(context, null)?.let { return BarMenu.Colors(it, text) }
|
|
1089
|
+
val barColor = bar?.barColor?.takeIf { Color.alpha(it) == OPAQUE } ?: return BarMenu.Colors(null, text)
|
|
1090
|
+
return BarMenu.Colors(barColor, text ?: topBar.title.color.get(context, null))
|
|
930
1091
|
}
|
|
931
1092
|
}
|
|
932
1093
|
|
|
@@ -959,8 +1120,11 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
959
1120
|
if (large) View.IMPORTANT_FOR_ACCESSIBILITY_NO else View.IMPORTANT_FOR_ACCESSIBILITY_YES
|
|
960
1121
|
}
|
|
961
1122
|
|
|
1123
|
+
// The list scrolled while the large title opens: it follows the list from there.
|
|
962
1124
|
override fun onScrollOffset(offsetY: Float) {
|
|
963
|
-
if (largeTitleShown)
|
|
1125
|
+
if (!largeTitleShown) return
|
|
1126
|
+
stopLargeTitleOpening()
|
|
1127
|
+
collapse(offsetY)
|
|
964
1128
|
}
|
|
965
1129
|
|
|
966
1130
|
override fun onScrollUp(nextTranslation: Float) = Unit
|
|
@@ -1065,6 +1229,7 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
1065
1229
|
|
|
1066
1230
|
private companion object {
|
|
1067
1231
|
const val DEFAULT_HEIGHT_DP = 64.0
|
|
1232
|
+
const val OPAQUE = 255
|
|
1068
1233
|
const val DEFAULT_TITLE_SP = 22.0
|
|
1069
1234
|
const val DEFAULT_SUBTITLE_SP = 14.0
|
|
1070
1235
|
const val CENTER = "center"
|
|
@@ -10,9 +10,10 @@ import dev.apexnative.navigation.views.animations.AnimationRules
|
|
|
10
10
|
* stack its side (`animations.*.topBar`) plays instead — its `exit` hides, its `enter` shows; `enabled: false` shows or
|
|
11
11
|
* hides at once. A show cancels a running hide and a hide a running show, each with its own token, so `visible: false`
|
|
12
12
|
* then `true` leaves the bar shown; a motion cancelled leaves the bar at rest; a bar shown again stands in its place
|
|
13
|
-
* with its row seen (the hide on scroll's shift and fade reset).
|
|
13
|
+
* with its row seen (the hide on scroll's shift and fade reset). [onHidden] runs once a hide has made the bar `GONE`.
|
|
14
|
+
* Main thread only.
|
|
14
15
|
*/
|
|
15
|
-
internal class TopBarVisibility(private val target: Target) {
|
|
16
|
+
internal class TopBarVisibility(private val target: Target, private val onHidden: () -> Unit = {}) {
|
|
16
17
|
/** What moves: the bar's view, or the unit tests' fake. */
|
|
17
18
|
interface Target {
|
|
18
19
|
/** How far up the bar goes to hide: its height and the room over it, in pixels. */
|
|
@@ -45,6 +46,10 @@ internal class TopBarVisibility(private val target: Target) {
|
|
|
45
46
|
val isHidden: Boolean
|
|
46
47
|
get() = hidden
|
|
47
48
|
|
|
49
|
+
/** The bar is on its way out: a hide moves it and it still shows. */
|
|
50
|
+
val isHiding: Boolean
|
|
51
|
+
get() = hidden && sliding != null
|
|
52
|
+
|
|
48
53
|
/** Shows the bar: by [side] when it plays, sliding down when [animated], else at once. */
|
|
49
54
|
fun show(animated: Boolean, side: TopBarAnimationOptions? = null) {
|
|
50
55
|
val wasHidden = hidden
|
|
@@ -84,6 +89,7 @@ internal class TopBarVisibility(private val target: Target) {
|
|
|
84
89
|
if (!moves || target.isGone) {
|
|
85
90
|
target.translationY = 0f
|
|
86
91
|
target.isGone = true
|
|
92
|
+
onHidden()
|
|
87
93
|
return
|
|
88
94
|
}
|
|
89
95
|
val token = Any()
|
|
@@ -93,6 +99,7 @@ internal class TopBarVisibility(private val target: Target) {
|
|
|
93
99
|
settle()
|
|
94
100
|
target.isGone = true
|
|
95
101
|
target.translationY = 0f
|
|
102
|
+
onHidden()
|
|
96
103
|
}
|
|
97
104
|
}
|
|
98
105
|
val own = side?.takeIf { AnimationRules.sidePlays(it) }
|
|
@@ -13,8 +13,8 @@ import java.lang.ref.WeakReference
|
|
|
13
13
|
* tag) is in the screen, found once per tag —, not the horizontal ones, nor those of a modal, an overlay or another
|
|
14
14
|
* screen; a slot screen's lists are in its container too. While a list is dragged, each follower gets the drag as a
|
|
15
15
|
* translation to follow; when the drag ends, the way to settle; at every scroll event, the drags' and the inertia's,
|
|
16
|
-
* the offset. It listens to React Native's
|
|
17
|
-
*
|
|
16
|
+
* the offset. It listens to React Native's scroll views ([ScrollEvents]) only while it has followers and its screen's
|
|
17
|
+
* view. Released with the screen. Main thread only.
|
|
18
18
|
*/
|
|
19
19
|
class ScrollEventListener() {
|
|
20
20
|
/** Follows the content while it is dragged. */
|
|
@@ -105,15 +105,12 @@ class ScrollEventListener() {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
/**
|
|
108
|
-
* Listens to React Native's scroll
|
|
109
|
-
*
|
|
110
|
-
* window.
|
|
108
|
+
* Listens to React Native's scroll views when followers wait for them and it doesn't yet, once it has the screen's
|
|
109
|
+
* view to tell its own lists by; asked again as the screen joins a window.
|
|
111
110
|
*/
|
|
112
111
|
internal fun attachIfNeeded() {
|
|
113
|
-
if (released || stopListening != null || registrations.isEmpty()) return
|
|
114
|
-
|
|
115
|
-
stopListening = ScrollEvents.listen(context, ::onScrollEvent)
|
|
116
|
-
if (stopListening == null) ScrollEvents.waitForDispatcher(this)
|
|
112
|
+
if (released || stopListening != null || registrations.isEmpty() || scope?.get() == null) return
|
|
113
|
+
stopListening = ScrollEvents.listen(::onScrollEvent)
|
|
117
114
|
}
|
|
118
115
|
|
|
119
116
|
/** The screen is destroyed: no follower hears it any more. */
|