-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Android route overview #345
Changes from 13 commits
7e77c8c
ce94b79
794d2de
5063fc7
060e839
6ab8f7e
584bb74
8318660
bc096e3
3e99c47
dd73e99
8fc0ce8
cf15dd8
742a5ca
cee5ffd
aee4461
6819739
c12f3c8
6545310
06843fe
1d8d8db
df63897
5c03f41
cc83bbd
28dd2cc
9cfff25
98effcf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.stadiamaps.ferrostar.composeui.config | ||
|
||
import androidx.compose.ui.unit.DpSize | ||
import androidx.compose.ui.unit.dp | ||
|
||
sealed class CameraControlState { | ||
data object Hidden : CameraControlState() | ||
|
||
data class ShowRecenter(val updateCamera: () -> Unit) : CameraControlState() | ||
|
||
data class ShowRouteOverview(val updateCamera: () -> Unit) : CameraControlState() | ||
} | ||
|
||
data class VisualNavigationViewConfig( | ||
var showMute: Boolean = false, | ||
var showZoom: Boolean = false, | ||
var buttonSize: DpSize = DpSize(56.dp, 56.dp) | ||
) { | ||
companion object { | ||
fun Default() = VisualNavigationViewConfig(showMute = true, showZoom = true) | ||
} | ||
} | ||
|
||
/** Enables the mute button in the navigation view. */ | ||
fun VisualNavigationViewConfig.useMuteButton(): VisualNavigationViewConfig { | ||
showMute = true | ||
return this | ||
} | ||
|
||
/** Enables the zoom button in the navigation view. */ | ||
fun VisualNavigationViewConfig.useZoomButton(): VisualNavigationViewConfig { | ||
showZoom = true | ||
return this | ||
} | ||
|
||
/** Changes the size of navigation buttons. */ | ||
fun VisualNavigationViewConfig.buttonSize(size: DpSize): VisualNavigationViewConfig { | ||
buttonSize = size | ||
return this | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,26 @@ | ||
package com.stadiamaps.ferrostar.composeui.views.gridviews | ||
|
||
import androidx.compose.foundation.layout.Arrangement | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.Spacer | ||
import androidx.compose.foundation.layout.fillMaxSize | ||
import androidx.compose.foundation.layout.width | ||
import androidx.compose.material.icons.Icons | ||
import androidx.compose.material.icons.automirrored.filled.VolumeOff | ||
import androidx.compose.material.icons.automirrored.filled.VolumeUp | ||
import androidx.compose.material.icons.filled.Navigation | ||
import androidx.compose.material.icons.filled.VolumeOff | ||
import androidx.compose.material.icons.filled.Route | ||
import androidx.compose.material3.Icon | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.draw.rotate | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.tooling.preview.Devices | ||
import androidx.compose.ui.tooling.preview.Preview | ||
import androidx.compose.ui.unit.DpSize | ||
import androidx.compose.ui.unit.dp | ||
import com.stadiamaps.ferrostar.composeui.R | ||
import com.stadiamaps.ferrostar.composeui.config.CameraControlState | ||
import com.stadiamaps.ferrostar.composeui.views.controls.NavigationUIButton | ||
import com.stadiamaps.ferrostar.composeui.views.controls.NavigationUIZoomButton | ||
|
||
|
@@ -25,11 +30,11 @@ fun NavigatingInnerGridView( | |
showMute: Boolean = true, | ||
isMuted: Boolean?, | ||
onClickMute: () -> Unit = {}, | ||
buttonSize: DpSize, | ||
cameraControlState: CameraControlState = CameraControlState.Hidden, | ||
showZoom: Boolean = true, | ||
onClickZoomIn: () -> Unit = {}, | ||
onClickZoomOut: () -> Unit = {}, | ||
showCentering: Boolean = true, | ||
onClickCenter: () -> Unit = {}, | ||
topCenter: @Composable () -> Unit = { Spacer(Modifier.width(12.dp)) }, | ||
centerStart: @Composable () -> Unit = { Spacer(Modifier.width(12.dp)) }, | ||
bottomEnd: @Composable () -> Unit = { Spacer(Modifier.width(12.dp)) } | ||
|
@@ -41,29 +46,52 @@ fun NavigatingInnerGridView( | |
}, | ||
topCenter = topCenter, | ||
topEnd = { | ||
if (showMute && isMuted != null) { | ||
NavigationUIButton(onClick = onClickMute) { | ||
if (isMuted) { | ||
Icon( | ||
Icons.AutoMirrored.Filled.VolumeOff, | ||
contentDescription = stringResource(id = R.string.unmute_description)) | ||
} else { | ||
Icon( | ||
Icons.AutoMirrored.Filled.VolumeUp, | ||
contentDescription = stringResource(id = R.string.mute_description)) | ||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { | ||
when (cameraControlState) { | ||
CameraControlState.Hidden -> { | ||
// Nothing to draw here :) | ||
} | ||
is CameraControlState.ShowRecenter -> { | ||
// We decided to put this in the bottom corner for now | ||
} | ||
is CameraControlState.ShowRouteOverview -> { | ||
NavigationUIButton( | ||
onClick = cameraControlState.updateCamera, buttonSize = buttonSize) { | ||
Icon( | ||
Icons.Default.Route, | ||
modifier = Modifier.rotate(90.0f), | ||
contentDescription = stringResource(id = R.string.route_overview)) | ||
} | ||
} | ||
} | ||
|
||
// NOTE: Some controls hidden when the camera is not following the user | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me know if my memory of this is incorrect, but I believe your request on the call was to hide the mute button but leave zoom (if present), progress, and instructions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks correct (as per matching inspired by Apple Maps): |
||
if (showMute && | ||
isMuted != null && | ||
cameraControlState !is CameraControlState.ShowRecenter) { | ||
NavigationUIButton(onClick = onClickMute, buttonSize = buttonSize) { | ||
if (isMuted) { | ||
Icon( | ||
Icons.AutoMirrored.Filled.VolumeOff, | ||
contentDescription = stringResource(id = R.string.unmute_description)) | ||
} else { | ||
Icon( | ||
Icons.AutoMirrored.Filled.VolumeUp, | ||
contentDescription = stringResource(id = R.string.mute_description)) | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
centerStart = centerStart, | ||
centerEnd = { | ||
if (showZoom) { | ||
NavigationUIZoomButton(onClickZoomIn, onClickZoomOut) | ||
NavigationUIZoomButton(buttonSize, onClickZoomIn, onClickZoomOut) | ||
} | ||
}, | ||
bottomStart = { | ||
if (showCentering) { | ||
NavigationUIButton(onClick = onClickCenter) { | ||
if (cameraControlState is CameraControlState.ShowRecenter) { | ||
NavigationUIButton(onClick = cameraControlState.updateCamera, buttonSize = buttonSize) { | ||
Icon( | ||
Icons.Filled.Navigation, | ||
contentDescription = stringResource(id = R.string.recenter)) | ||
|
@@ -75,14 +103,56 @@ fun NavigatingInnerGridView( | |
|
||
@Preview(device = Devices.PIXEL_5) | ||
@Composable | ||
fun NavigatingInnerGridViewPreview() { | ||
NavigatingInnerGridView(modifier = Modifier.fillMaxSize(), isMuted = false) | ||
fun NavigatingInnerGridViewNonTrackingPreview() { | ||
NavigatingInnerGridView( | ||
modifier = Modifier.fillMaxSize(), | ||
isMuted = false, | ||
buttonSize = DpSize(56.dp, 56.dp), | ||
cameraControlState = | ||
CameraControlState.ShowRecenter { | ||
// Do nothing | ||
}) | ||
} | ||
|
||
@Preview(device = Devices.PIXEL_5) | ||
@Composable | ||
fun NavigatingInnerGridViewTrackingPreview() { | ||
NavigatingInnerGridView( | ||
modifier = Modifier.fillMaxSize(), | ||
isMuted = false, | ||
buttonSize = DpSize(56.dp, 56.dp), | ||
cameraControlState = | ||
CameraControlState.ShowRouteOverview { | ||
// Do nothing | ||
}) | ||
} | ||
|
||
@Preview( | ||
device = | ||
"spec:height=411dp,width=891dp,dpi=420,isRound=false,chinSize=0dp,orientation=landscape") | ||
@Composable | ||
fun NavigatingInnerGridViewLandscapeNonTrackingPreview() { | ||
NavigatingInnerGridView( | ||
modifier = Modifier.fillMaxSize(), | ||
isMuted = true, | ||
buttonSize = DpSize(56.dp, 56.dp), | ||
cameraControlState = | ||
CameraControlState.ShowRecenter { | ||
// Do nothing | ||
}) | ||
} | ||
|
||
@Preview( | ||
device = | ||
"spec:width=411dp,height=891dp,dpi=420,isRound=false,chinSize=0dp,orientation=landscape") | ||
"spec:height=411dp,width=891dp,dpi=420,isRound=false,chinSize=0dp,orientation=landscape") | ||
@Composable | ||
fun NavigatingInnerGridViewLandscapePreview() { | ||
NavigatingInnerGridView(modifier = Modifier.fillMaxSize(), isMuted = true) | ||
fun NavigatingInnerGridViewLandscapeTrackingPreview() { | ||
NavigatingInnerGridView( | ||
modifier = Modifier.fillMaxSize(), | ||
isMuted = true, | ||
buttonSize = DpSize(56.dp, 56.dp), | ||
cameraControlState = | ||
CameraControlState.ShowRouteOverview { | ||
// Do nothing | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was previously an informal constant that was copied everywhere. This at least gives it a place to live, and opens the path for button scaling enhancements if needed.