Skip to content

Commit

Permalink
move single/multi stream capture mode toggle to quick settings (#121)
Browse files Browse the repository at this point in the history
* remove temporary button and add single/multi stream capture toggle to quick settings menu
  • Loading branch information
Kimblebee committed Feb 29, 2024
1 parent eaf1e9c commit 600eeab
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import com.google.jetpackcamera.feature.preview.ui.ScreenFlashScreen
import com.google.jetpackcamera.feature.preview.ui.ShowTestableToast
import com.google.jetpackcamera.feature.quicksettings.QuickSettingsScreenOverlay
import com.google.jetpackcamera.settings.model.AspectRatio
import com.google.jetpackcamera.settings.model.CaptureMode
import com.google.jetpackcamera.settings.model.FlashMode

private const val TAG = "PreviewScreen"
Expand Down Expand Up @@ -93,12 +94,12 @@ fun PreviewScreen(
onChangeZoomScale = viewModel::setZoomScale,
onChangeFlash = viewModel::setFlash,
onChangeAspectRatio = viewModel::setAspectRatio,
onChangeCaptureMode = viewModel::setCaptureMode,
onToggleQuickSettings = viewModel::toggleQuickSettings,
onCaptureImage = viewModel::captureImage,
onCaptureImageWithUri = viewModel::captureImageWithUri,
onStartVideoRecording = viewModel::startVideoRecording,
onStopVideoRecording = viewModel::stopVideoRecording,
onToggleCaptureMode = viewModel::toggleCaptureMode,
onToastShown = viewModel::onToastShown
)
}
Expand All @@ -117,6 +118,7 @@ private fun ContentScreen(
onChangeZoomScale: (Float) -> Unit = {},
onChangeFlash: (FlashMode) -> Unit = {},
onChangeAspectRatio: (AspectRatio) -> Unit = {},
onChangeCaptureMode: (CaptureMode) -> Unit = {},
onToggleQuickSettings: () -> Unit = {},
onCaptureImage: () -> Unit = {},
onCaptureImageWithUri: (
Expand All @@ -126,7 +128,6 @@ private fun ContentScreen(
) -> Unit = { _, _, _ -> },
onStartVideoRecording: () -> Unit = {},
onStopVideoRecording: () -> Unit = {},
onToggleCaptureMode: () -> Unit = {},
onToastShown: () -> Unit = {}
) {
// display camera feed. this stays behind everything else
Expand All @@ -145,7 +146,8 @@ private fun ContentScreen(
currentCameraSettings = previewUiState.currentCameraSettings,
onLensFaceClick = { onFlipCamera() },
onFlashModeClick = onChangeFlash,
onAspectRatioClick = onChangeAspectRatio
onAspectRatioClick = onChangeAspectRatio,
onCaptureModeClick = onChangeCaptureMode
// onTimerClick = {}/*TODO*/
)
// relative-grid style overlay on top of preview display
Expand All @@ -159,8 +161,7 @@ private fun ContentScreen(
onCaptureImage = onCaptureImage,
onCaptureImageWithUri = onCaptureImageWithUri,
onStartVideoRecording = onStartVideoRecording,
onStopVideoRecording = onStopVideoRecording,
onToggleCaptureMode = onToggleCaptureMode
onStopVideoRecording = onStopVideoRecording
)

// displays toast when there is a message to show
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,24 +168,19 @@ class PreviewViewModel @Inject constructor(
)
}

fun toggleCaptureMode() {
val newCaptureMode = when (previewUiState.value.currentCameraSettings.captureMode) {
CaptureMode.MULTI_STREAM -> CaptureMode.SINGLE_STREAM
CaptureMode.SINGLE_STREAM -> CaptureMode.MULTI_STREAM
}

fun setCaptureMode(captureMode: CaptureMode) {
stopCamera()
runningCameraJob = viewModelScope.launch {
_previewUiState.emit(
previewUiState.value.copy(
currentCameraSettings =
previewUiState.value.currentCameraSettings.copy(
captureMode = newCaptureMode
captureMode = captureMode
)
)
)
// apply to cameraUseCase
cameraUseCase.setCaptureMode(newCaptureMode)
cameraUseCase.setCaptureMode(captureMode)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,16 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.google.jetpackcamera.feature.preview.MultipleEventsCutter
import com.google.jetpackcamera.feature.preview.PreviewMode
import com.google.jetpackcamera.feature.preview.PreviewUiState
import com.google.jetpackcamera.feature.preview.PreviewViewModel
import com.google.jetpackcamera.feature.preview.R
import com.google.jetpackcamera.feature.preview.VideoRecordingState
import com.google.jetpackcamera.feature.quicksettings.ui.QuickSettingsIndicators
import com.google.jetpackcamera.feature.quicksettings.ui.ToggleQuickSettingsButton
import com.google.jetpackcamera.settings.model.CameraAppSettings
import com.google.jetpackcamera.settings.model.CaptureMode
import com.google.jetpackcamera.settings.model.FlashMode
import com.google.jetpackcamera.settings.model.Stabilization
import com.google.jetpackcamera.settings.model.SupportedStabilizationMode
Expand Down Expand Up @@ -82,8 +79,7 @@ fun CameraControlsOverlay(
(PreviewViewModel.ImageCaptureEvent) -> Unit
) -> Unit = { _, _, _ -> },
onStartVideoRecording: () -> Unit = {},
onStopVideoRecording: () -> Unit = {},
onToggleCaptureMode: () -> Unit = {}
onStopVideoRecording: () -> Unit = {}
) {
// Show the current zoom level for a short period of time, only when the level changes.
var firstRun by remember { mutableStateOf(true) }
Expand All @@ -106,8 +102,7 @@ fun CameraControlsOverlay(
currentCameraSettings = previewUiState.currentCameraSettings,
onNavigateToSettings = onNavigateToSettings,
onChangeFlash = onChangeFlash,
onToggleQuickSettings = onToggleQuickSettings,
onToggleCaptureMode = onToggleCaptureMode
onToggleQuickSettings = onToggleQuickSettings
)
}

Expand Down Expand Up @@ -139,8 +134,7 @@ private fun ControlsTop(
modifier: Modifier = Modifier,
onNavigateToSettings: () -> Unit = {},
onChangeFlash: (FlashMode) -> Unit = {},
onToggleQuickSettings: () -> Unit = {},
onToggleCaptureMode: () -> Unit = {}
onToggleQuickSettings: () -> Unit = {}
) {
Row(modifier, verticalAlignment = Alignment.CenterVertically) {
Row(Modifier.weight(1f), verticalAlignment = Alignment.CenterVertically) {
Expand All @@ -162,17 +156,6 @@ private fun ControlsTop(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
) {
// For debug purposes, display whether the stream is in single/multi mode.
TestingButton(
modifier = Modifier.testTag("ToggleCaptureMode"),
onClick = onToggleCaptureMode,
text = stringResource(
when (currentCameraSettings.captureMode) {
CaptureMode.SINGLE_STREAM -> R.string.capture_mode_single_stream
CaptureMode.MULTI_STREAM -> R.string.capture_mode_multi_stream
}
)
)
StabilizationIcon(
supportedStabilizationMode = currentCameraSettings.supportedStabilizationModes,
videoStabilization = currentCameraSettings.videoCaptureStabilization,
Expand Down
2 changes: 0 additions & 2 deletions feature/preview/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
<resources>
<string name="camera_not_ready">Camera Loading…</string>
<string name="settings_content_description">Settings</string>
<string name="capture_mode_single_stream">Single Stream</string>
<string name="capture_mode_multi_stream">Multi Stream</string>
<string name="flip_camera_content_description">Flip Camera</string>

<string name="toast_image_capture_success">Image Capture Success</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,22 @@ enum class CameraAspectRatio : QuickSettingsEnum {
R.string.quick_settings_aspect_ratio_1_1_description
}
}

enum class CameraCaptureMode : QuickSettingsEnum {
MULTI_STREAM {
override fun getDrawableResId(): Int = R.drawable.multi_stream_icon

override fun getTextResId(): Int = R.string.quick_settings_capture_mode_multi

override fun getDescriptionResId(): Int =
R.string.quick_settings_capture_mode_multi_description
},
SINGLE_STREAM {
override fun getDrawableResId(): Int = R.drawable.single_stream_capture_icon

override fun getTextResId(): Int = R.string.quick_settings_capture_mode_single

override fun getDescriptionResId(): Int =
R.string.quick_settings_capture_mode_single_description
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.dimensionResource
import com.google.jetpackcamera.feature.quicksettings.ui.ExpandedQuickSetRatio
import com.google.jetpackcamera.feature.quicksettings.ui.QuickFlipCamera
import com.google.jetpackcamera.feature.quicksettings.ui.QuickSetCaptureMode
import com.google.jetpackcamera.feature.quicksettings.ui.QuickSetFlash
import com.google.jetpackcamera.feature.quicksettings.ui.QuickSetRatio
import com.google.jetpackcamera.feature.quicksettings.ui.QuickSettingsGrid
import com.google.jetpackcamera.quicksettings.R
import com.google.jetpackcamera.settings.model.AspectRatio
import com.google.jetpackcamera.settings.model.CameraAppSettings
import com.google.jetpackcamera.settings.model.CaptureMode
import com.google.jetpackcamera.settings.model.FlashMode

/**
Expand All @@ -58,7 +60,8 @@ fun QuickSettingsScreenOverlay(
toggleIsOpen: () -> Unit,
onLensFaceClick: (lensFace: Boolean) -> Unit,
onFlashModeClick: (flashMode: FlashMode) -> Unit,
onAspectRatioClick: (aspectRation: AspectRatio) -> Unit
onAspectRatioClick: (aspectRation: AspectRatio) -> Unit,
onCaptureModeClick: (captureMode: CaptureMode) -> Unit
) {
var shouldShowQuickSetting by remember {
mutableStateOf(IsExpandedQuickSetting.NONE)
Expand Down Expand Up @@ -103,7 +106,8 @@ fun QuickSettingsScreenOverlay(
},
onLensFaceClick = onLensFaceClick,
onFlashModeClick = onFlashModeClick,
onAspectRatioClick = onAspectRatioClick
onAspectRatioClick = onAspectRatioClick,
onCaptureModeClick = onCaptureModeClick
)
}
} else {
Expand All @@ -125,9 +129,10 @@ private fun ExpandedQuickSettingsUi(
currentCameraSettings: CameraAppSettings,
onLensFaceClick: (lensFacingFront: Boolean) -> Unit,
onFlashModeClick: (flashMode: FlashMode) -> Unit,
onAspectRatioClick: (aspectRation: AspectRatio) -> Unit,
onCaptureModeClick: (captureMode: CaptureMode) -> Unit,
shouldShowQuickSetting: IsExpandedQuickSetting,
setVisibleQuickSetting: (IsExpandedQuickSetting) -> Unit,
onAspectRatioClick: (aspectRation: AspectRatio) -> Unit
setVisibleQuickSetting: (IsExpandedQuickSetting) -> Unit
) {
Column(
modifier =
Expand Down Expand Up @@ -169,6 +174,13 @@ private fun ExpandedQuickSettingsUi(
ratio = currentCameraSettings.aspectRatio,
currentRatio = currentCameraSettings.aspectRatio
)
},
{
QuickSetCaptureMode(
modifier = Modifier.testTag(""),
setCaptureMode = { c: CaptureMode -> onCaptureModeClick(c) },
currentCaptureMode = currentCameraSettings.captureMode
)
}
)
QuickSettingsGrid(quickSettingsButtons = displayedQuickSettings)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,16 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.google.jetpackcamera.feature.quicksettings.CameraAspectRatio
import com.google.jetpackcamera.feature.quicksettings.CameraCaptureMode
import com.google.jetpackcamera.feature.quicksettings.CameraFlashMode
import com.google.jetpackcamera.feature.quicksettings.CameraLensFace
import com.google.jetpackcamera.feature.quicksettings.QuickSettingsEnum
import com.google.jetpackcamera.quicksettings.R
import com.google.jetpackcamera.settings.model.AspectRatio
import com.google.jetpackcamera.settings.model.CaptureMode
import com.google.jetpackcamera.settings.model.FlashMode
import kotlin.math.min

Expand Down Expand Up @@ -163,6 +166,29 @@ fun QuickFlipCamera(
)
}

@Composable
fun QuickSetCaptureMode(
modifier: Modifier = Modifier,
setCaptureMode: (CaptureMode) -> Unit,
currentCaptureMode: CaptureMode
) {
val enum: CameraCaptureMode =
when (currentCaptureMode) {
CaptureMode.MULTI_STREAM -> CameraCaptureMode.MULTI_STREAM
CaptureMode.SINGLE_STREAM -> CameraCaptureMode.SINGLE_STREAM
}
QuickSettingUiItem(
modifier = modifier,
enum = enum,
onClick = {
when (currentCaptureMode) {
CaptureMode.MULTI_STREAM -> setCaptureMode(CaptureMode.SINGLE_STREAM)
CaptureMode.SINGLE_STREAM -> setCaptureMode(CaptureMode.MULTI_STREAM)
}
}
)
}

/**
* Button to toggle quick settings
*/
Expand Down Expand Up @@ -239,7 +265,7 @@ fun QuickSettingUiItem(
.size(dimensionResource(id = R.dimen.quick_settings_ui_item_icon_size))
)

Text(text = text, color = tint)
Text(text = text, color = tint, textAlign = TextAlign.Center)
}
}

Expand Down
21 changes: 21 additions & 0 deletions feature/quicksettings/src/main/res/drawable/multi_stream_icon.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector android:height="72dp" android:tint="#000000"
android:viewportHeight="960" android:viewportWidth="960"
android:width="72dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M220,880Q162,880 121,839Q80,798 80,740Q80,682 121,641Q162,600 220,600Q238,600 255,604.5Q272,609 287,617L440,464L440,354Q396,341 368,304.5Q340,268 340,220Q340,162 381,121Q422,80 480,80Q538,80 579,121Q620,162 620,220Q620,268 592,304.5Q564,341 520,354L520,464L674,617Q689,609 705.5,604.5Q722,600 740,600Q798,600 839,641Q880,682 880,740Q880,798 839,839Q798,880 740,880Q682,880 641,839Q600,798 600,740Q600,722 604.5,705Q609,688 617,673L480,536L343,673Q351,688 355.5,705Q360,722 360,740Q360,798 319,839Q278,880 220,880ZM740,800Q765,800 782.5,782.5Q800,765 800,740Q800,715 782.5,697.5Q765,680 740,680Q715,680 697.5,697.5Q680,715 680,740Q680,765 697.5,782.5Q715,800 740,800ZM480,280Q505,280 522.5,262.5Q540,245 540,220Q540,195 522.5,177.5Q505,160 480,160Q455,160 437.5,177.5Q420,195 420,220Q420,245 437.5,262.5Q455,280 480,280ZM220,800Q245,800 262.5,782.5Q280,765 280,740Q280,715 262.5,697.5Q245,680 220,680Q195,680 177.5,697.5Q160,715 160,740Q160,765 177.5,782.5Q195,800 220,800Z"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector android:height="72dp" android:tint="#000000"
android:viewportHeight="960" android:viewportWidth="960"
android:width="72dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M320,640Q386,640 433,593Q480,546 480,480Q480,414 433,367Q386,320 320,320Q254,320 207,367Q160,414 160,480Q160,546 207,593Q254,640 320,640ZM320,720Q220,720 150,650Q80,580 80,480Q80,380 150,310Q220,240 320,240Q410,240 476.5,297Q543,354 557,440L880,440L880,520L557,520Q543,606 476.5,663Q410,720 320,720ZM320,480Q320,480 320,480Q320,480 320,480Q320,480 320,480Q320,480 320,480Q320,480 320,480Q320,480 320,480Q320,480 320,480Q320,480 320,480Z"/>
</vector>
28 changes: 11 additions & 17 deletions feature/quicksettings/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,27 @@
<resources>
<string name="quick_settings_front_camera_text">FRONT</string>
<string name="quick_settings_back_camera_text">BACK</string>
<string name="quick_settings_front_camera_description">Front Camera</string>
<string name="quick_settings_back_camera_description">Back Camera</string>

<string name="quick_settings_aspect_ratio_3_4">3:4</string>
<string name="quick_settings_aspect_ratio_9_16">9:16</string>
<string name="quick_settings_aspect_ratio_1_1">1:1</string>

<string name="quick_settings_flash_off">OFF</string>
<string name="quick_settings_flash_auto">AUTO</string>
<string name="quick_settings_flash_on">ON</string>

<string name="quick_settings_timer_off">OFF</string>
<string name="quick_settings_timer_3"></string>
<string name="quick_settings_timer_10"></string>

<string name="quick_settings_dropdown_description">Quick settings drop down</string>

<string name="quick_settings_front_camera_description">Front Camera</string>
<string name="quick_settings_back_camera_description">Back Camera</string>

<string name="quick_settings_aspect_ratio_3_4_description">3 to 4 aspect ratio</string>
<string name="quick_settings_aspect_ratio_9_16_description">9 to 16 aspect ratio</string>
<string name="quick_settings_aspect_ratio_1_1_description">1 to 1 aspect ratio</string>

<string name="quick_settings_flash_off">OFF</string>
<string name="quick_settings_flash_auto">AUTO</string>
<string name="quick_settings_flash_on">ON</string>
<string name="quick_settings_flash_off_description">Flash off</string>
<string name="quick_settings_flash_auto_description">Auto flash</string>
<string name="quick_settings_flash_on_description">Flash on</string>

<string name="quick_settings_timer_off_description">Timer off</string>
<string name="quick_settings_timer_3_description">3 seconds timer</string>
<string name="quick_settings_timer_10_description">10 seconds timer</string>
<string name="quick_settings_capture_mode_single">Single Stream</string>
<string name="quick_settings_capture_mode_multi">Multi Stream</string>
<string name="quick_settings_capture_mode_single_description">Single-stream capture mode on</string>
<string name="quick_settings_capture_mode_multi_description">Multi-stream capture mode on</string>

<string name="quick_settings_dropdown_description">Quick settings drop down</string>
</resources>

0 comments on commit 600eeab

Please sign in to comment.