From 435c335c443cef604826fcc9619196816528b7c2 Mon Sep 17 00:00:00 2001 From: Ellen Poe Date: Sat, 6 Dec 2025 17:24:53 -0800 Subject: [PATCH 1/2] feat: new navigation overlay views --- .../earth/maps/cardinal/ui/core/AppContent.kt | 2 +- .../ui/navigation/NavigationChrome.kt | 95 +++++++++++++++++++ .../TurnByTurnNavigationScreen.kt | 7 +- .../TurnByTurnNavigationViewModel.kt | 2 +- .../TurnByTurnNavigationViewModelTest.kt | 1 + 5 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/NavigationChrome.kt rename cardinal-android/app/src/main/java/earth/maps/cardinal/ui/{directions => navigation}/TurnByTurnNavigationScreen.kt (95%) rename cardinal-android/app/src/main/java/earth/maps/cardinal/ui/{directions => navigation}/TurnByTurnNavigationViewModel.kt (96%) diff --git a/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/core/AppContent.kt b/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/core/AppContent.kt index b6f893e..648024b 100644 --- a/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/core/AppContent.kt +++ b/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/core/AppContent.kt @@ -110,7 +110,7 @@ import earth.maps.cardinal.routing.RouteRepository import earth.maps.cardinal.ui.directions.DirectionsScreen import earth.maps.cardinal.ui.directions.DirectionsViewModel import earth.maps.cardinal.ui.directions.RouteDisplayHandler -import earth.maps.cardinal.ui.directions.TurnByTurnNavigationScreen +import earth.maps.cardinal.ui.navigation.TurnByTurnNavigationScreen import earth.maps.cardinal.ui.home.HomeScreen import earth.maps.cardinal.ui.home.HomeViewModel import earth.maps.cardinal.ui.home.NearbyScreenContent diff --git a/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/NavigationChrome.kt b/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/NavigationChrome.kt new file mode 100644 index 0000000..5a0797d --- /dev/null +++ b/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/NavigationChrome.kt @@ -0,0 +1,95 @@ +package earth.maps.cardinal.ui.navigation + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.stadiamaps.ferrostar.composeui.config.NavigationViewComponentBuilder +import com.stadiamaps.ferrostar.composeui.models.CameraControlState +import com.stadiamaps.ferrostar.composeui.theme.DefaultNavigationUITheme +import com.stadiamaps.ferrostar.composeui.views.components.CurrentRoadNameView +import com.stadiamaps.ferrostar.composeui.views.components.InstructionsView +import com.stadiamaps.ferrostar.composeui.views.components.TripProgressView +import com.stadiamaps.ferrostar.core.NavigationUiState +import kotlin.time.ExperimentalTime + +@Composable +fun CardinalInstructionsView(modifier: Modifier, uiState: NavigationUiState) { + uiState.visualInstruction?.let { instructions -> + InstructionsView( + modifier = modifier, + instructions = instructions, + theme = DefaultNavigationUITheme.instructionRowTheme, + remainingSteps = uiState.remainingSteps, + distanceToNextManeuver = uiState.progress?.distanceToNextManeuver) + } +} + +@OptIn(ExperimentalTime::class) +@Composable +fun CardinalProgressView( + modifier: Modifier, + uiState: NavigationUiState, + onTapExit: (() -> Unit)? +) { + uiState.progress?.let { progress -> + TripProgressView( + modifier = modifier, + theme = DefaultNavigationUITheme.tripProgressViewTheme, + progress = progress, + onTapExit = onTapExit) + } +} + +@Composable +fun CardinalRoadNameView( + modifier: Modifier, + roadName: String?, + cameraControlState: CameraControlState +) { + if (cameraControlState is CameraControlState.ShowRouteOverview) { + roadName?.let { roadName -> + Row( + modifier.fillMaxWidth(), + verticalAlignment = Alignment.Bottom, + horizontalArrangement = Arrangement.Center) { + CurrentRoadNameView( + modifier = modifier, + theme = DefaultNavigationUITheme.roadNameViewTheme, + currentRoadName = roadName) + + Spacer(modifier = Modifier.height(8.dp)) + } + } + } +} + +fun navigationViewComponentBuilder(): NavigationViewComponentBuilder { + return NavigationViewComponentBuilder( + instructionsView = @Composable { modifier, navigationUiState -> + CardinalInstructionsView( + modifier, + navigationUiState + ) + }, + progressView = @Composable { modifier, navigationUiState, onTapExit -> + CardinalProgressView( + modifier, + navigationUiState, + onTapExit + ) + }, + roadNameView = @Composable { modifier, roadName, cameraControlState -> + CardinalRoadNameView( + modifier, + roadName, + cameraControlState + ) + }, + ) +} diff --git a/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationScreen.kt b/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/TurnByTurnNavigationScreen.kt similarity index 95% rename from cardinal-android/app/src/main/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationScreen.kt rename to cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/TurnByTurnNavigationScreen.kt index 6c107ba..02b1ec0 100644 --- a/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationScreen.kt +++ b/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/TurnByTurnNavigationScreen.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package earth.maps.cardinal.ui.directions +package earth.maps.cardinal.ui.navigation import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box @@ -107,7 +107,10 @@ fun TurnByTurnNavigationScreen( // Only display the navigation view if we have a route if (route != null) { DynamicallyOrientingNavigationView( - styleUrl = styleUrl, modifier = Modifier, viewModel = viewModel + styleUrl = styleUrl, + modifier = Modifier, + viewModel = viewModel, + views = navigationViewComponentBuilder() ) } else { // Show a placeholder or loading state when no route is available diff --git a/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationViewModel.kt b/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/TurnByTurnNavigationViewModel.kt similarity index 96% rename from cardinal-android/app/src/main/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationViewModel.kt rename to cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/TurnByTurnNavigationViewModel.kt index 65462f6..5cb8f7b 100644 --- a/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationViewModel.kt +++ b/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/TurnByTurnNavigationViewModel.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package earth.maps.cardinal.ui.directions +package earth.maps.cardinal.ui.navigation import androidx.lifecycle.ViewModel import dagger.hilt.android.lifecycle.HiltViewModel diff --git a/cardinal-android/app/src/test/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationViewModelTest.kt b/cardinal-android/app/src/test/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationViewModelTest.kt index 962f027..265cc88 100644 --- a/cardinal-android/app/src/test/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationViewModelTest.kt +++ b/cardinal-android/app/src/test/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationViewModelTest.kt @@ -19,6 +19,7 @@ package earth.maps.cardinal.ui.directions import earth.maps.cardinal.routing.FerrostarWrapperRepository +import earth.maps.cardinal.ui.navigation.TurnByTurnNavigationViewModel import io.mockk.mockk import org.junit.Assert.assertEquals import org.junit.Before -- GitLab From 15d2f177469622e3a4ab717f77133948dc930a57 Mon Sep 17 00:00:00 2001 From: Ellen Poe Date: Sat, 6 Dec 2025 17:54:09 -0800 Subject: [PATCH 2/2] feat: larger text for route progress indicators --- .../ui/navigation/NavigationChrome.kt | 71 ++++++++++++++++--- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/NavigationChrome.kt b/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/NavigationChrome.kt index 5a0797d..27b2c8a 100644 --- a/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/NavigationChrome.kt +++ b/cardinal-android/app/src/main/java/earth/maps/cardinal/ui/navigation/NavigationChrome.kt @@ -5,28 +5,80 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import com.stadiamaps.ferrostar.composeui.config.NavigationViewComponentBuilder import com.stadiamaps.ferrostar.composeui.models.CameraControlState -import com.stadiamaps.ferrostar.composeui.theme.DefaultNavigationUITheme +import com.stadiamaps.ferrostar.composeui.theme.DefaultInstructionRowTheme +import com.stadiamaps.ferrostar.composeui.theme.DefaultRoadNameViewTheme +import com.stadiamaps.ferrostar.composeui.theme.InstructionRowTheme +import com.stadiamaps.ferrostar.composeui.theme.NavigationUITheme +import com.stadiamaps.ferrostar.composeui.theme.RoadNameViewTheme +import com.stadiamaps.ferrostar.composeui.theme.TripProgressViewStyle +import com.stadiamaps.ferrostar.composeui.theme.TripProgressViewTheme import com.stadiamaps.ferrostar.composeui.views.components.CurrentRoadNameView import com.stadiamaps.ferrostar.composeui.views.components.InstructionsView import com.stadiamaps.ferrostar.composeui.views.components.TripProgressView import com.stadiamaps.ferrostar.core.NavigationUiState import kotlin.time.ExperimentalTime +object CardinalNavigationUITheme : NavigationUITheme { + override val instructionRowTheme: InstructionRowTheme + @Composable get() = DefaultInstructionRowTheme + + override val roadNameViewTheme: RoadNameViewTheme + @Composable get() = DefaultRoadNameViewTheme + + override val tripProgressViewTheme: TripProgressViewTheme + @Composable get() = CardinalTripProgressViewTheme + + override val buttonSize: DpSize + @Composable get() = DpSize(56.dp, 56.dp) +} + +object CardinalTripProgressViewTheme : TripProgressViewTheme { + override val style: TripProgressViewStyle + @Composable get() = TripProgressViewStyle.SIMPLIFIED + + override val measurementTextStyle: TextStyle + @Composable + get() = + MaterialTheme.typography.titleLarge.copy( + color = MaterialTheme.colorScheme.onSurface, fontWeight = FontWeight.Normal) + + override val secondaryTextStyle: TextStyle + @Composable + get() = + MaterialTheme.typography.labelSmall.copy(color = MaterialTheme.colorScheme.onSurfaceVariant) + + override val exitIconColor: Color + @Composable get() = MaterialTheme.colorScheme.onSecondary + + override val exitButtonBackgroundColor: Color + @Composable get() = MaterialTheme.colorScheme.secondary + + override val backgroundColor: Color + @Composable get() = MaterialTheme.colorScheme.surface +} + + @Composable fun CardinalInstructionsView(modifier: Modifier, uiState: NavigationUiState) { uiState.visualInstruction?.let { instructions -> InstructionsView( modifier = modifier, instructions = instructions, - theme = DefaultNavigationUITheme.instructionRowTheme, + theme = CardinalNavigationUITheme.instructionRowTheme, remainingSteps = uiState.remainingSteps, - distanceToNextManeuver = uiState.progress?.distanceToNextManeuver) + distanceToNextManeuver = uiState.progress?.distanceToNextManeuver + ) } } @@ -40,9 +92,10 @@ fun CardinalProgressView( uiState.progress?.let { progress -> TripProgressView( modifier = modifier, - theme = DefaultNavigationUITheme.tripProgressViewTheme, + theme = CardinalNavigationUITheme.tripProgressViewTheme, progress = progress, - onTapExit = onTapExit) + onTapExit = onTapExit + ) } } @@ -57,11 +110,13 @@ fun CardinalRoadNameView( Row( modifier.fillMaxWidth(), verticalAlignment = Alignment.Bottom, - horizontalArrangement = Arrangement.Center) { + horizontalArrangement = Arrangement.Center + ) { CurrentRoadNameView( modifier = modifier, - theme = DefaultNavigationUITheme.roadNameViewTheme, - currentRoadName = roadName) + theme = CardinalNavigationUITheme.roadNameViewTheme, + currentRoadName = roadName + ) Spacer(modifier = Modifier.height(8.dp)) } -- GitLab