Skip to content
Draft
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 @@ -27,13 +27,18 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
Expand Down Expand Up @@ -80,22 +85,18 @@ import com.google.jetpackcamera.model.StreamConfig
import com.google.jetpackcamera.model.TestPattern
import com.google.jetpackcamera.model.VideoCaptureEvent
import com.google.jetpackcamera.ui.components.capture.AmplitudeToggleButton
import com.google.jetpackcamera.ui.components.capture.CAPTURE_MODE_TOGGLE_BUTTON
import com.google.jetpackcamera.ui.components.capture.CaptureButton
import com.google.jetpackcamera.ui.components.capture.CaptureLayout
import com.google.jetpackcamera.ui.components.capture.CaptureModeToggleButton
import com.google.jetpackcamera.ui.components.capture.ELAPSED_TIME_TAG
import com.google.jetpackcamera.ui.components.capture.ElapsedTimeText
import com.google.jetpackcamera.ui.components.capture.FLIP_CAMERA_BUTTON
import com.google.jetpackcamera.ui.components.capture.FlipCameraButton
import com.google.jetpackcamera.ui.components.capture.ImageWell
import com.google.jetpackcamera.ui.components.capture.PauseResumeToggleButton
import com.google.jetpackcamera.ui.components.capture.PreviewDisplay
import com.google.jetpackcamera.ui.components.capture.PreviewLayout
import com.google.jetpackcamera.ui.components.capture.R
import com.google.jetpackcamera.ui.components.capture.ScreenFlashScreen
import com.google.jetpackcamera.ui.components.capture.StabilizationIcon
import com.google.jetpackcamera.ui.components.capture.TestableSnackbar
import com.google.jetpackcamera.ui.components.capture.VIDEO_QUALITY_TAG
import com.google.jetpackcamera.ui.components.capture.VideoQualityIcon
import com.google.jetpackcamera.ui.components.capture.ZoomButtonRow
import com.google.jetpackcamera.ui.components.capture.ZoomState
Expand Down Expand Up @@ -185,7 +186,7 @@ fun PreviewScreen(
}

when (val currentUiState = captureUiState) {
is CaptureUiState.NotReady -> LoadingScreen()
is CaptureUiState.NotReady -> LoadingCaptureScreen()
is CaptureUiState.Ready -> {
var initialRecordingSettings by remember {
mutableStateOf<InitialRecordingSettings?>(
Expand Down Expand Up @@ -351,7 +352,7 @@ fun PreviewScreen(
}
}

@OptIn(ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
private fun ContentScreen(
captureUiState: CaptureUiState.Ready,
Expand Down Expand Up @@ -410,7 +411,7 @@ private fun ContentScreen(
}
}

LayoutWrapper(
CaptureLayoutWrapper(
modifier = modifier,
hdrIndicator = { HdrIndicator(modifier = it, hdrUiState = captureUiState.hdrUiState) },
flashModeIndicator = {
Expand All @@ -421,8 +422,8 @@ private fun ContentScreen(
},
videoQualityIndicator = {
VideoQualityIcon(
captureUiState.videoQuality,
Modifier.testTag(VIDEO_QUALITY_TAG)
modifier = it,
videoQuality = captureUiState.videoQuality
)
},
stabilizationIndicator = {
Expand All @@ -434,10 +435,14 @@ private fun ContentScreen(

viewfinder = {
PreviewDisplay(
modifier = it
.fillMaxSize()
.background(Color.Black),
clippedShape = RoundedCornerShape(16.dp),
previewDisplayUiState = captureUiState.previewDisplayUiState,
onFlipCamera = onFlipCamera,
onTapToFocus = onTapToFocus,
onScaleZoom = { onScaleZoom(it, LensToZoom.PRIMARY) },
onScaleZoom = { scaleFactor -> onScaleZoom(scaleFactor, LensToZoom.PRIMARY) },
surfaceRequest = surfaceRequest,
onRequestWindowColorMode = onRequestWindowColorMode,
focusMeteringUiState = captureUiState.focusMeteringUiState
Expand All @@ -453,6 +458,7 @@ private fun ContentScreen(
action()
}
CaptureButton(
modifier = it,
captureButtonUiState = captureUiState.captureButtonUiState,
isQuickSettingsOpen = (
captureUiState.quickSettingsUiState as?
Expand All @@ -479,7 +485,7 @@ private fun ContentScreen(
},
flipCameraButton = {
FlipCameraButton(
modifier = Modifier.testTag(FLIP_CAMERA_BUTTON),
modifier = it,
onClick = onFlipCamera,
flipLensUiState = captureUiState.flipLensUiState,
// enable only when phone has front and rear camera
Expand All @@ -490,14 +496,13 @@ private fun ContentScreen(
)
},
zoomLevelDisplay = {
Column(modifier = Modifier, horizontalAlignment = Alignment.CenterHorizontally) {
ZoomButtonRow(
zoomControlUiState = captureUiState.zoomControlUiState,
onChangeZoom = { targetZoom ->
onAnimateZoom(targetZoom, LensToZoom.PRIMARY)
}
)
}
ZoomButtonRow(
modifier = it,
zoomControlUiState = captureUiState.zoomControlUiState,
onChangeZoom = { targetZoom ->
onAnimateZoom(targetZoom, LensToZoom.PRIMARY)
}
)
},
elapsedTimeDisplay = {
AnimatedVisibility(
Expand All @@ -506,17 +511,13 @@ private fun ContentScreen(
exit = fadeOut(animationSpec = tween(delayMillis = 1_500))
) {
ElapsedTimeText(
modifier = Modifier.testTag(ELAPSED_TIME_TAG),
modifier = it,
elapsedTimeUiState = captureUiState.elapsedTimeUiState
)
}
},
quickSettingsButton = {
AnimatedVisibility(
visible = (captureUiState.videoRecordingState !is VideoRecordingState.Active),
enter = fadeIn(),
exit = fadeOut(animationSpec = tween(delayMillis = 1_500))
) {
if (captureUiState.videoRecordingState !is VideoRecordingState.Active) {
ToggleQuickSettingsButton(
modifier = it,
toggleBottomSheet = onToggleQuickSettings,
Expand All @@ -535,15 +536,21 @@ private fun ContentScreen(
)
},
captureModeToggle = {
if (captureUiState.captureModeToggleUiState is CaptureModeToggleUiState.Available) {
CaptureModeToggleButton(
uiState = captureUiState.captureModeToggleUiState
as CaptureModeToggleUiState.Available,

onChangeCaptureMode = onSetCaptureMode,
onToggleWhenDisabled = onDisabledCaptureMode,
modifier = it.testTag(CAPTURE_MODE_TOGGLE_BUTTON)
)
Box(
modifier = Modifier
.defaultMinSize(minHeight = IconButtonDefaults.largeContainerSize().height),
contentAlignment = Alignment.Center
) {
if (captureUiState.captureModeToggleUiState is CaptureModeToggleUiState.Available) {
CaptureModeToggleButton(
modifier = it,
uiState = captureUiState.captureModeToggleUiState
as CaptureModeToggleUiState.Available,

onChangeCaptureMode = onSetCaptureMode,
onToggleWhenDisabled = onDisabledCaptureMode
)
}
}
},
quickSettingsOverlay = {
Expand Down Expand Up @@ -631,7 +638,7 @@ private fun ContentScreen(
}

@Composable
private fun LoadingScreen(modifier: Modifier = Modifier) {
private fun LoadingCaptureScreen(modifier: Modifier = Modifier) {
Column(
modifier = modifier
.fillMaxSize()
Expand All @@ -645,7 +652,7 @@ private fun LoadingScreen(modifier: Modifier = Modifier) {
}

@Composable
private fun LayoutWrapper(
private fun CaptureLayoutWrapper(
modifier: Modifier = Modifier,
viewfinder: @Composable (modifier: Modifier) -> Unit,
captureButton: @Composable (modifier: Modifier) -> Unit,
Expand All @@ -670,7 +677,7 @@ private fun LayoutWrapper(
screenFlashOverlay: @Composable (modifier: Modifier) -> Unit,
snackBar: @Composable (modifier: Modifier, snackbarHostState: SnackbarHostState) -> Unit
) {
PreviewLayout(
CaptureLayout(
modifier = modifier,
viewfinder = viewfinder,
captureButton = captureButton,
Expand Down
Loading
Loading