Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import com.stadiamaps.ferrostar.ui.DestinationSelectionCameraEffect
import kotlinx.serialization.json.buildJsonObject
import org.maplibre.compose.expressions.dsl.const
import org.maplibre.compose.layers.CircleLayer
import org.maplibre.compose.map.MapOptions
import org.maplibre.compose.map.OrnamentOptions
import org.maplibre.compose.sources.GeoJsonData
import org.maplibre.compose.sources.rememberGeoJsonSource
import org.maplibre.compose.style.BaseStyle
Expand Down Expand Up @@ -131,6 +133,14 @@ fun DemoNavigationScene(viewModel: DemoNavigationViewModel = AppModule.viewModel
viewModel.selectDestination(position)
NavigationMapClickResult.Consume
},
mapOptions =
MapOptions(
ornamentOptions =
OrnamentOptions(
isCompassEnabled = false,
isScaleBarEnabled = false,
),
),
) {
DemoDroppedPinOverlay(sceneState.droppedPin)
}
Expand Down Expand Up @@ -172,5 +182,5 @@ internal fun droppedPinFeatureCollection(pin: GeographicCoordinate) =
Feature(
geometry = Point(longitude = pin.lng, latitude = pin.lat),
properties = buildJsonObject {},
)
),
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import com.stadiamaps.ferrostar.composeui.runtime.paddingForGridView
import org.maplibre.compose.map.MapOptions
Expand All @@ -25,6 +26,7 @@ internal fun rememberMapOptionsForProgressViewHeight(
horizontalPadding: Dp = 16.dp,
verticalPadding: Dp = 8.dp,
contentPadding: PaddingValues = PaddingValues(0.dp),
baseMapOptions: MapOptions = defaultNavigationMapOptions(),
): MapOptions {
val layoutDirection = LocalLayoutDirection.current
val isLandscape = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE
Expand All @@ -35,39 +37,70 @@ internal fun rememberMapOptionsForProgressViewHeight(
horizontalPadding,
verticalPadding,
contentPadding,
baseMapOptions,
layoutDirection,
isLandscape,
gridPadding,
) {
val startPadding = contentPadding.calculateStartPadding(layoutDirection)
val endPadding =
contentPadding.calculateEndPadding(layoutDirection) +
gridPadding.calculateEndPadding(layoutDirection) +
horizontalPadding
val topPadding = contentPadding.calculateTopPadding() + verticalPadding
val bottomPadding =
contentPadding.calculateBottomPadding() +
gridPadding.calculateBottomPadding() +
if (isLandscape) {
verticalPadding
} else {
progressViewHeight + verticalPadding
}
mapOptionsForProgressViewHeight(
progressViewHeight = progressViewHeight,
horizontalPadding = horizontalPadding,
verticalPadding = verticalPadding,
contentPadding = contentPadding,
baseMapOptions = baseMapOptions,
layoutDirection = layoutDirection,
isLandscape = isLandscape,
gridPadding = gridPadding,
)
}
}

internal fun defaultNavigationMapOptions(): MapOptions =
MapOptions(
ornamentOptions =
OrnamentOptions(
padding =
PaddingValues(
start = startPadding,
end = endPadding,
top = topPadding,
bottom = bottomPadding,
),
isCompassEnabled = false,
isScaleBarEnabled = false,
logoAlignment = Alignment.BottomStart,
attributionAlignment = Alignment.BottomEnd,
),
)
}

internal fun mapOptionsForProgressViewHeight(
progressViewHeight: Dp,
horizontalPadding: Dp,
verticalPadding: Dp,
contentPadding: PaddingValues,
baseMapOptions: MapOptions,
layoutDirection: LayoutDirection,
isLandscape: Boolean,
gridPadding: PaddingValues,
): MapOptions {
val startPadding = contentPadding.calculateStartPadding(layoutDirection)
val endPadding =
contentPadding.calculateEndPadding(layoutDirection) +
gridPadding.calculateEndPadding(layoutDirection) +
horizontalPadding
val topPadding = contentPadding.calculateTopPadding() + verticalPadding
val bottomPadding =
contentPadding.calculateBottomPadding() +
gridPadding.calculateBottomPadding() +
if (isLandscape) {
verticalPadding
} else {
progressViewHeight + verticalPadding
}

return baseMapOptions.copy(
ornamentOptions =
baseMapOptions.ornamentOptions.copy(
padding =
PaddingValues(
start = startPadding,
end = endPadding,
top = topPadding,
bottom = bottomPadding,
),
),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ import com.stadiamaps.ferrostar.maplibreui.extensions.cameraControlState
import com.stadiamaps.ferrostar.maplibreui.routeline.RouteOverlayBuilder
import com.stadiamaps.ferrostar.maplibreui.runtime.NavigationCameraOptions
import com.stadiamaps.ferrostar.maplibreui.runtime.NavigationMapState
import com.stadiamaps.ferrostar.maplibreui.runtime.defaultNavigationMapOptions
import com.stadiamaps.ferrostar.maplibreui.runtime.navigationCameraOptions
import com.stadiamaps.ferrostar.maplibreui.runtime.rememberMapOptionsForProgressViewHeight
import com.stadiamaps.ferrostar.maplibreui.runtime.rememberNavigationMapState
import com.stadiamaps.ferrostar.maplibreui.runtime.withNavigationBottomInset
import org.maplibre.compose.map.MapOptions
import org.maplibre.compose.style.BaseStyle
import org.maplibre.compose.util.MaplibreComposable

Expand All @@ -52,6 +54,9 @@ import org.maplibre.compose.util.MaplibreComposable
* @param overlayPadding Optional padding applied to Ferrostar-owned overlay chrome such as
* instructions, controls, and custom overlays. Defaults to `WindowInsets.systemBars` when not
* provided.
* @param mapOptions MapLibre map options to use as the base configuration. The wrapper replaces
* `mapOptions.ornamentOptions.padding` with the computed padding needed to keep ornaments clear
* of navigation overlays.
*/
@Composable
fun DynamicallyOrientingNavigationView(
Expand All @@ -72,6 +77,7 @@ fun DynamicallyOrientingNavigationView(
onTapExit: (() -> Unit)? = null,
onMapClick: NavigationMapClickHandler = { _, _ -> NavigationMapClickResult.Pass },
onMapLongClick: NavigationMapClickHandler = { _, _ -> NavigationMapClickResult.Pass },
mapOptions: MapOptions = defaultNavigationMapOptions(),
mapContent: @Composable @MaplibreComposable ((NavigationUiState) -> Unit)? = null,
) {
val configuration = LocalConfiguration.current
Expand All @@ -85,10 +91,11 @@ fun DynamicallyOrientingNavigationView(
val systemBarsPadding = WindowInsets.systemBars.asPaddingValues()
val resolvedOrnamentPadding = ornamentPadding ?: systemBarsPadding
val resolvedOverlayPadding = overlayPadding ?: systemBarsPadding
val mapOptions =
val effectiveMapOptions =
rememberMapOptionsForProgressViewHeight(
progressViewHeight = if (uiState.isNavigating()) progressViewHeight else 0.dp,
contentPadding = resolvedOrnamentPadding,
baseMapOptions = mapOptions,
)
val effectiveNavigationCameraOptions =
if (uiState.isNavigating()) {
Expand All @@ -106,7 +113,7 @@ fun DynamicallyOrientingNavigationView(
baseStyle = baseStyle,
navigationMapState = navigationMapState,
uiState = uiState,
mapOptions = mapOptions,
mapOptions = effectiveMapOptions,
navigationCameraOptions = effectiveNavigationCameraOptions,
routeOverlayBuilder = routeOverlayBuilder,
locationPuckStyle = locationPuckStyle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,25 @@ import com.stadiamaps.ferrostar.maplibreui.extensions.cameraControlState
import com.stadiamaps.ferrostar.maplibreui.routeline.RouteOverlayBuilder
import com.stadiamaps.ferrostar.maplibreui.runtime.NavigationCameraOptions
import com.stadiamaps.ferrostar.maplibreui.runtime.NavigationMapState
import com.stadiamaps.ferrostar.maplibreui.runtime.defaultNavigationMapOptions
import com.stadiamaps.ferrostar.maplibreui.runtime.navigationCameraOptions
import com.stadiamaps.ferrostar.maplibreui.runtime.rememberMapOptionsForProgressViewHeight
import com.stadiamaps.ferrostar.maplibreui.runtime.rememberNavigationMapState
import com.stadiamaps.ferrostar.maplibreui.runtime.withNavigationBottomInset
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import org.maplibre.compose.map.MapOptions
import org.maplibre.compose.style.BaseStyle
import org.maplibre.compose.util.MaplibreComposable

/**
* A landscape orientation of the navigation view with instructions, default controls and the
* navigation map view.
*
* @param mapOptions MapLibre map options to use as the base configuration. The wrapper replaces
* `mapOptions.ornamentOptions.padding` with the computed padding needed to keep ornaments clear
* of navigation overlays.
*/
@Composable
fun LandscapeNavigationView(
modifier: Modifier,
Expand All @@ -62,13 +72,14 @@ fun LandscapeNavigationView(
onTapExit: (() -> Unit)? = null,
onMapClick: NavigationMapClickHandler = { _, _ -> NavigationMapClickResult.Pass },
onMapLongClick: NavigationMapClickHandler = { _, _ -> NavigationMapClickResult.Pass },
mapOptions: MapOptions = defaultNavigationMapOptions(),
mapContent: @Composable @MaplibreComposable ((NavigationUiState) -> Unit)? = null,
) {
val uiState by viewModel.navigationUiState.collectAsState()
val configuration = androidx.compose.ui.platform.LocalConfiguration.current
val layoutDirection = LocalLayoutDirection.current
val gridPadding = paddingForGridView()
val mapOptions = rememberMapOptionsForProgressViewHeight()
val effectiveMapOptions = rememberMapOptionsForProgressViewHeight(baseMapOptions = mapOptions)
val effectiveNavigationCameraOptions =
if (uiState.isNavigating()) {
navigationCameraOptions.withNavigationBottomInset(
Expand All @@ -85,7 +96,7 @@ fun LandscapeNavigationView(
baseStyle = baseStyle,
navigationMapState = navigationMapState,
uiState = uiState,
mapOptions = mapOptions,
mapOptions = effectiveMapOptions,
navigationCameraOptions = effectiveNavigationCameraOptions,
routeOverlayBuilder = routeOverlayBuilder,
showDefaultPuck = showDefaultPuck,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ import com.stadiamaps.ferrostar.maplibreui.extensions.cameraControlState
import com.stadiamaps.ferrostar.maplibreui.routeline.RouteOverlayBuilder
import com.stadiamaps.ferrostar.maplibreui.runtime.NavigationCameraOptions
import com.stadiamaps.ferrostar.maplibreui.runtime.NavigationMapState
import com.stadiamaps.ferrostar.maplibreui.runtime.defaultNavigationMapOptions
import com.stadiamaps.ferrostar.maplibreui.runtime.navigationCameraOptions
import com.stadiamaps.ferrostar.maplibreui.runtime.rememberMapOptionsForProgressViewHeight
import com.stadiamaps.ferrostar.maplibreui.runtime.rememberNavigationMapState
import com.stadiamaps.ferrostar.maplibreui.runtime.withNavigationBottomInset
import org.maplibre.compose.map.MapOptions
import org.maplibre.compose.style.BaseStyle
import org.maplibre.compose.util.MaplibreComposable

Expand All @@ -65,6 +67,9 @@ import org.maplibre.compose.util.MaplibreComposable
* position.
* @param onMapLongClick Callback invoked for long presses on the map with geographic coordinates
* and screen position.
* @param mapOptions MapLibre map options to use as the base configuration. The wrapper replaces
* `mapOptions.ornamentOptions.padding` with the computed padding needed to keep ornaments clear
* of navigation overlays.
* @param mapContent Any additional composable map symbol content to render.
*/
@Composable
Expand All @@ -84,13 +89,14 @@ fun PortraitNavigationView(
onTapExit: (() -> Unit)? = null,
onMapClick: NavigationMapClickHandler = { _, _ -> NavigationMapClickResult.Pass },
onMapLongClick: NavigationMapClickHandler = { _, _ -> NavigationMapClickResult.Pass },
mapOptions: MapOptions = defaultNavigationMapOptions(),
mapContent: @Composable @MaplibreComposable ((NavigationUiState) -> Unit)? = null,
) {
val uiState by viewModel.navigationUiState.collectAsState()
val configuration = androidx.compose.ui.platform.LocalConfiguration.current
val layoutDirection = LocalLayoutDirection.current
val gridPadding = paddingForGridView()
val mapOptions = rememberMapOptionsForProgressViewHeight()
val effectiveMapOptions = rememberMapOptionsForProgressViewHeight(baseMapOptions = mapOptions)
val effectiveNavigationCameraOptions =
if (uiState.isNavigating()) {
navigationCameraOptions.withNavigationBottomInset(
Expand All @@ -107,7 +113,7 @@ fun PortraitNavigationView(
baseStyle = baseStyle,
navigationMapState = navigationMapState,
uiState = uiState,
mapOptions = mapOptions,
mapOptions = effectiveMapOptions,
navigationCameraOptions = effectiveNavigationCameraOptions,
routeOverlayBuilder = routeOverlayBuilder,
locationPuckStyle = locationPuckStyle,
Expand Down
Loading
Loading