@apexnative/navigation 1.0.0-alpha.6 → 1.0.0-alpha.8
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 +15 -0
- package/android/CLAUDE.md +19 -10
- package/android/CORE.md +3 -2
- package/android/consumer-rules.pro +6 -0
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +1 -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/SheetOptions.kt +7 -4
- 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/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/NavigationTurboModule.kt +4 -0
- package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +41 -3
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +16 -1
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +12 -1
- package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
- package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +329 -55
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +26 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +60 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +8 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +32 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +46 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +15 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +7 -4
- 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 +215 -43
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +25 -26
- 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/TopBarPresenter.kt +86 -39
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarVisibility.kt +9 -2
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +124 -181
- package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +8 -1
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +56 -3
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +170 -153
- 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 +55 -45
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/{TextChangeAnimator.kt → TextMorph.kt} +79 -129
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
- 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 -24
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +51 -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 +121 -175
- 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/doctor/checks/app.js +16 -1
- package/cli/project.js +4 -0
- package/cli/setup/index.js +5 -0
- package/cli/setup/steps/metro.js +46 -0
- 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 +43 -4
- package/docs-md/flows/bottom-sheets.md +4 -2
- package/docs-md/fundamentals/screens-and-props.md +9 -1
- package/docs-md/guides/cli.md +3 -1
- package/docs-md/help/troubleshooting.md +1 -1
- package/docs-md/index.json +29 -1
- package/docs-md/screen-ui/back-and-gestures.md +3 -1
- package/docs-md/screen-ui/bar-buttons.md +1 -1
- package/docs-md/screen-ui/toolbar-and-fab.md +2 -0
- package/docs-md/start/installation.md +16 -1
- package/ios/Animations/ANNFrameDriver.h +55 -15
- package/ios/Animations/ANNFrameDriver.mm +214 -60
- package/ios/Animations/ANNTransitionAnimator.h +26 -5
- package/ios/Animations/ANNTransitionAnimator.mm +49 -3
- package/ios/Animations/ANNTransitionPlan.h +2 -2
- package/ios/Animations/ANNTransitionPlan.mm +10 -0
- package/ios/Animations/Elements/ANNElementFinder.h +2 -2
- package/ios/Animations/Elements/ANNElementFinder.mm +2 -2
- package/ios/Animations/Elements/ANNElementTransition.h +3 -3
- package/ios/Animations/Elements/ANNElementTransition.mm +2 -2
- package/ios/Animations/Elements/ANNSharedElementFlight.h +3 -3
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +181 -43
- package/ios/Animations/Interpolators/ANNViewTracks.h +6 -5
- package/ios/Animations/Interpolators/ANNViewTracks.mm +51 -21
- package/ios/CLAUDE.md +19 -8
- package/ios/CORE.md +1 -1
- package/ios/Core/ANNAppDelegate.mm +0 -2
- package/ios/Core/ANNDeepLinkQueue.h +6 -5
- package/ios/Core/ANNDeepLinkQueue.mm +22 -10
- package/ios/Core/ANNSceneDelegate.mm +2 -2
- package/ios/Core/ANNUtils.h +7 -0
- package/ios/Core/ANNUtils.mm +10 -0
- package/ios/Core/ApexNavigation.mm +6 -2
- package/ios/Layouts/Overlay/ANNOverlayCoordinator.mm +1 -7
- package/ios/Layouts/Root/ANNRootCoordinator.mm +45 -15
- package/ios/Layouts/Screen/ANNComponentViewController.mm +4 -1
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
- package/ios/Layouts/Stack/ANNStackController.h +8 -0
- package/ios/Layouts/Stack/ANNStackController.mm +153 -11
- 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/Tabs/ANNTabsPreloadWindow.mm +2 -4
- package/ios/Options/ANNAnimationOptions.h +2 -1
- package/ios/Options/ANNAnimationOptions.mm +1 -1
- package/ios/Options/ANNOptions.h +7 -0
- package/ios/Options/ANNOptions.mm +45 -0
- package/ios/Options/ANNOptionsReader.mm +2 -4
- package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
- package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
- package/ios/Options/Params/ColorParser.h +4 -3
- package/ios/Options/Params/ColorParser.mm +22 -4
- package/ios/React/ANNSurfaceHostingView.h +8 -0
- package/ios/React/ANNSurfaceHostingView.mm +28 -1
- package/ios/React/Slots/ANNSlotHost.mm +1 -3
- package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
- package/ios/TurboModules/ANNTurboModule.mm +46 -0
- 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 +9 -3
- 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 +188 -66
- package/lib/module/api/app/createNavigation.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/linking/linking.js +11 -0
- package/lib/module/api/linking/linking.js.map +1 -1
- 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 +21 -1
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +7 -2
- 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 +5 -4
- 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/refresh.js +85 -0
- package/lib/module/engine/refresh.js.map +1 -0
- package/lib/module/engine/rememberedOptions.js +60 -0
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +26 -0
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +7 -0
- 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 +5 -0
- package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +2 -2
- package/lib/typescript/api/events/navigationEvents.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/linking.d.ts +8 -0
- package/lib/typescript/api/linking/linking.d.ts.map +1 -1
- 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/optionsChange.d.ts +28 -0
- package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
- 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 +7 -0
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/ComponentEvents.d.ts +2 -2
- package/lib/typescript/interfaces/options/animations.d.ts +40 -15
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +2 -2
- package/lib/typescript/interfaces/options/buttons.d.ts +2 -2
- package/lib/typescript/interfaces/options/modals.d.ts +6 -7
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/stack.d.ts +8 -3
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/topBar.d.ts +14 -0
- 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 +9 -3
- package/src/adapters/NativeANNTurboModule.ts +7 -0
- package/src/api/app/AppRegistry.ts +16 -2
- package/src/api/app/createNavigation.ts +198 -66
- package/src/api/events/navigationEvents.ts +9 -3
- package/src/api/index.ts +1 -0
- package/src/api/linking/linking.ts +22 -1
- 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 +21 -0
- package/src/engine/layout.ts +11 -2
- package/src/engine/nativeScreens.ts +10 -1
- package/src/engine/options.ts +6 -8
- package/src/engine/optionsChange.ts +107 -0
- package/src/engine/refresh.ts +97 -0
- package/src/engine/rememberedOptions.ts +70 -0
- package/src/engine/screens.tsx +24 -0
- package/src/interfaces/ComponentEvents.ts +2 -2
- package/src/interfaces/options/animations.ts +40 -15
- package/src/interfaces/options/bottomTabs.ts +2 -2
- package/src/interfaces/options/buttons.ts +2 -2
- package/src/interfaces/options/modals.ts +6 -7
- package/src/interfaces/options/stack.ts +8 -3
- package/src/interfaces/options/topBar.ts +14 -0
- 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 -134
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -78
- 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 -57
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -146
|
@@ -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
|
|
@@ -59,6 +55,7 @@ import dev.apexnative.navigation.views.stack.topbar.TitleBar
|
|
|
59
55
|
import dev.apexnative.navigation.views.stack.topbar.TopBar
|
|
60
56
|
import dev.apexnative.navigation.views.stack.topbar.TopBarDefaults
|
|
61
57
|
import dev.apexnative.navigation.views.stack.topbar.titlebar.BarButtonComponentCell
|
|
58
|
+
import dev.apexnative.navigation.views.stack.topbar.titlebar.BarMenu
|
|
62
59
|
import dev.apexnative.navigation.views.stack.topbar.titlebar.ButtonBar
|
|
63
60
|
import dev.apexnative.navigation.views.stack.topbar.titlebar.IconBackgroundDrawable
|
|
64
61
|
import kotlin.math.roundToInt
|
|
@@ -132,6 +129,8 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
132
129
|
// The bar goes with the screens of a transition of the stack's own, and the screen that leaves with its picture.
|
|
133
130
|
private var travelling = false
|
|
134
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
|
|
135
134
|
|
|
136
135
|
private enum class Part { Look, Title, Left, Right, Back, LargeTitle, Visible, TestId }
|
|
137
136
|
|
|
@@ -142,9 +141,9 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
142
141
|
this.layout = layout
|
|
143
142
|
val bar = layout.topBar
|
|
144
143
|
this.bar = bar
|
|
145
|
-
leftButtons = ButtonBar(bar.leftButtonBar,
|
|
146
|
-
rightButtons = ButtonBar(bar.rightButtonBar,
|
|
147
|
-
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)
|
|
148
147
|
rowTransition = BarRowTransition(RowTarget(bar).also { rowTarget = it })
|
|
149
148
|
collapse = TopBarCollapseBehavior(bar)
|
|
150
149
|
bar.leftButtonBar.setNavigationOnClickListener { host.backPressed() }
|
|
@@ -185,6 +184,7 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
185
184
|
val bar = bar
|
|
186
185
|
val leaving = shownEntry
|
|
187
186
|
val lowers = bar != null && bar.isLargeTitleShown && incoming != null && leaving != null &&
|
|
187
|
+
!hidesMoving(host.resolvedOf(incoming), visibility, travel != null) &&
|
|
188
188
|
lowersBar(motion, incoming, host.resolvedOf(incoming))
|
|
189
189
|
rowTarget?.withLargeTitle = !lowers
|
|
190
190
|
if (lowers) pictureUnderRow(bar, leaving)
|
|
@@ -193,6 +193,15 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
193
193
|
if (travel != null && bar != null && incoming != null) beginTravel(bar, leaving, incoming, travel, visibility)
|
|
194
194
|
}
|
|
195
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))
|
|
203
|
+
}
|
|
204
|
+
|
|
196
205
|
/** The transition that brought the current child ended: the row at rest, the picture under it gone. */
|
|
197
206
|
fun endRowTransition() {
|
|
198
207
|
// A large title still opening is open now.
|
|
@@ -212,8 +221,8 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
212
221
|
* bar as it is goes with [leaving], and the bar, which takes [incoming]'s options next, is drawn flat as [incoming]
|
|
213
222
|
* moves — under [leaving] on a pop ([StackDisplay.BarTravel.Back]) (`StackLayout.barTravels`). No picture when the
|
|
214
223
|
* bar doesn't show. Nothing travels when the new top hides the bar by a side of its own
|
|
215
|
-
* (`animations.*.topBar.exit`), which plays instead, or when the bar can't be
|
|
216
|
-
*
|
|
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.
|
|
217
226
|
*/
|
|
218
227
|
private fun beginTravel(
|
|
219
228
|
bar: TopBar,
|
|
@@ -238,10 +247,10 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
238
247
|
|
|
239
248
|
// The bar's picture where the bar is in the stack, its moves counted.
|
|
240
249
|
private fun pictureOfBar(bar: TopBar): Drawable? {
|
|
241
|
-
val
|
|
250
|
+
val picture = bar.picture() ?: return null
|
|
242
251
|
val left = (bar.left + bar.translationX).roundToInt()
|
|
243
252
|
val top = (bar.top + bar.translationY).roundToInt()
|
|
244
|
-
return
|
|
253
|
+
return picture.apply { setBounds(left, top, left + intrinsicWidth, top + intrinsicHeight) }
|
|
245
254
|
}
|
|
246
255
|
|
|
247
256
|
// The bar's travel ends: the picture goes, the bar is drawn in its place again with its shadow.
|
|
@@ -284,6 +293,8 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
284
293
|
val bar = bar ?: return
|
|
285
294
|
val screen = host.optionsScreen(entry)
|
|
286
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()
|
|
287
298
|
val options = host.resolvedOf(entry)
|
|
288
299
|
applyAll(bar, entry, screen, options, merge = true, delta = delta)
|
|
289
300
|
}
|
|
@@ -293,6 +304,8 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
293
304
|
* now.
|
|
294
305
|
*/
|
|
295
306
|
fun repaint(entry: ViewController<*>?) {
|
|
307
|
+
// An open menu has the old colors: it closes.
|
|
308
|
+
closeMenus()
|
|
296
309
|
keys.clear()
|
|
297
310
|
apply(entry)
|
|
298
311
|
val options = entry?.let(host::resolvedOf) ?: return
|
|
@@ -305,6 +318,7 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
305
318
|
* of the bar (the search) applies again.
|
|
306
319
|
*/
|
|
307
320
|
fun onInsets() {
|
|
321
|
+
if (waitsForHide) return
|
|
308
322
|
val bar = bar ?: return
|
|
309
323
|
val entry = shownEntry ?: return
|
|
310
324
|
val screen = shownScreen ?: return
|
|
@@ -379,6 +393,12 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
379
393
|
|
|
380
394
|
/** [screen] is destroyed: its components and its search go. */
|
|
381
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
|
+
}
|
|
382
402
|
if (screen === shownScreen) {
|
|
383
403
|
shownScreen = null
|
|
384
404
|
shownEntry = null
|
|
@@ -465,6 +485,26 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
465
485
|
merge: Boolean,
|
|
466
486
|
delta: Options? = null,
|
|
467
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
|
+
}
|
|
468
508
|
applyLook(bar, entry, options)
|
|
469
509
|
applyTitle(bar, screen, options)
|
|
470
510
|
// The search first: its magnifier takes a place among the right buttons. It gets a copy of the group: it
|
|
@@ -582,16 +622,15 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
582
622
|
keys[Part.Left] = leftKey
|
|
583
623
|
reportWithoutId(topBar.buttons.left, "leftButtons")
|
|
584
624
|
leftButtons?.set(
|
|
585
|
-
left.map { button(screen, it, roots) },
|
|
625
|
+
ButtonPlaces.line(left, left = true).map { button(screen, it, roots) },
|
|
586
626
|
emptyList(),
|
|
587
627
|
null,
|
|
588
628
|
merge && topBar.animateLeftButtons.isTrue,
|
|
589
629
|
)
|
|
590
630
|
}
|
|
591
631
|
val overflow = topBar.overflowMenu?.takeIf { it.items.isNotEmpty() }
|
|
592
|
-
val menu = bar.rightButtonBar.menu
|
|
593
632
|
search.applyMagnifier()
|
|
594
|
-
val taken =
|
|
633
|
+
val taken = if (bar.rightButtonBar.trailingView != null) 1 else 0
|
|
595
634
|
val configuration = context.resources.configuration
|
|
596
635
|
val plan = ButtonPlaces.plan(
|
|
597
636
|
right.map { ButtonPlaces.Button(ButtonPlaces.priorityOf(it.priority.get(null)), it.pinned.isTrue) },
|
|
@@ -612,12 +651,11 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
612
651
|
keys[Part.Right] = rightKey
|
|
613
652
|
reportWithoutId(topBar.buttons.right, "rightButtons")
|
|
614
653
|
rightButtons?.set(
|
|
615
|
-
plan.inBar.map { button(screen, right[it], roots) },
|
|
654
|
+
ButtonPlaces.line(plan.inBar, left = false).map { button(screen, right[it], roots) },
|
|
616
655
|
plan.inOverflow.map { button(screen, right[it], roots) },
|
|
617
656
|
overflow,
|
|
618
657
|
merge && topBar.animateRightButtons.isTrue,
|
|
619
658
|
)
|
|
620
|
-
search.applyMagnifier()
|
|
621
659
|
rightButtons?.setOverflowColor(overflowColor)
|
|
622
660
|
}
|
|
623
661
|
}
|
|
@@ -639,9 +677,9 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
639
677
|
).joinToString()
|
|
640
678
|
if (keys[Part.Back] == key) return
|
|
641
679
|
keys[Part.Back] = key
|
|
642
|
-
val
|
|
680
|
+
val row = bar.leftButtonBar
|
|
643
681
|
if (!shown) {
|
|
644
|
-
|
|
682
|
+
row.navigationIcon = null
|
|
645
683
|
return
|
|
646
684
|
}
|
|
647
685
|
val own = back.icon.get(null)?.let(::loadIcon)?.mutate()
|
|
@@ -668,19 +706,13 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
668
706
|
dp(background.height.get(0.0)),
|
|
669
707
|
)
|
|
670
708
|
} ?: icon
|
|
671
|
-
|
|
672
|
-
// Taking the icon, the
|
|
673
|
-
//
|
|
674
|
-
// gets the bar's direction at once
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
toolbar.navigationContentDescription = label
|
|
679
|
-
// The toolbar uses its navigation button again from screen to screen: its id is set every time.
|
|
680
|
-
for (index in 0 until toolbar.childCount) {
|
|
681
|
-
val child = toolbar.getChildAt(index)
|
|
682
|
-
if ((child as? ImageView)?.drawable === held) TestIds.apply(child, testId)
|
|
683
|
-
}
|
|
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) }
|
|
684
716
|
}
|
|
685
717
|
|
|
686
718
|
// The background (`topBar.background.component`).
|
|
@@ -719,15 +751,14 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
719
751
|
|
|
720
752
|
private fun pictureUnderRow(bar: TopBar, leaving: ViewController<*>) {
|
|
721
753
|
val view = leaving.peekView() ?: return
|
|
722
|
-
val (
|
|
754
|
+
val (picture, top) = bar.pictureUnderRow() ?: return
|
|
723
755
|
val barPlace = IntArray(2)
|
|
724
756
|
val viewPlace = IntArray(2)
|
|
725
757
|
bar.getLocationInWindow(barPlace)
|
|
726
758
|
view.getLocationInWindow(viewPlace)
|
|
727
|
-
val picture = BitmapDrawable(bar.resources, bitmap)
|
|
728
759
|
val left = barPlace[0] - viewPlace[0]
|
|
729
760
|
val y = barPlace[1] + top - viewPlace[1]
|
|
730
|
-
picture.setBounds(left, y, left +
|
|
761
|
+
picture.setBounds(left, y, left + picture.intrinsicWidth, y + picture.intrinsicHeight)
|
|
731
762
|
view.overlay.add(picture)
|
|
732
763
|
underRow = leaving to picture
|
|
733
764
|
}
|
|
@@ -802,6 +833,16 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
802
833
|
opening.cancel()
|
|
803
834
|
}
|
|
804
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
|
+
|
|
805
846
|
// Shown or hidden: with the transition by its side, or by `animate` in a merge.
|
|
806
847
|
private fun applyVisibility(options: Options, merge: Boolean) {
|
|
807
848
|
val visible = !options.topBar.visible.isFalse
|
|
@@ -1037,11 +1078,16 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
1037
1078
|
return (buttons.left.orEmpty() + buttons.right.orEmpty()).firstOrNull { it.id.get(null) == buttonId }?.menu
|
|
1038
1079
|
}
|
|
1039
1080
|
|
|
1040
|
-
//
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
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))
|
|
1045
1091
|
}
|
|
1046
1092
|
}
|
|
1047
1093
|
|
|
@@ -1183,6 +1229,7 @@ internal class TopBarPresenter(private val activity: Activity, private val host:
|
|
|
1183
1229
|
|
|
1184
1230
|
private companion object {
|
|
1185
1231
|
const val DEFAULT_HEIGHT_DP = 64.0
|
|
1232
|
+
const val OPAQUE = 255
|
|
1186
1233
|
const val DEFAULT_TITLE_SP = 22.0
|
|
1187
1234
|
const val DEFAULT_SUBTITLE_SP = 14.0
|
|
1188
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) }
|