Skip to content

Commit 1e16d5e

Browse files
committed
Add Spatial layout for CameraScreen
1 parent cf4a1d4 commit 1e16d5e

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

feature/camera/src/main/java/com/android/developers/androidify/camera/CameraLayout.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import androidx.compose.ui.tooling.preview.Preview
5050
import androidx.compose.ui.tooling.preview.PreviewParameter
5151
import androidx.compose.ui.unit.dp
5252
import androidx.lifecycle.compose.LifecycleStartEffect
53+
import com.android.developers.androidify.camera.xr.CameraLayoutSpatial
5354
import com.android.developers.androidify.theme.AndroidifyTheme
5455
import com.android.developers.androidify.theme.TertiaryContainer
5556
import com.android.developers.androidify.util.FoldablePreviewParameters
@@ -58,6 +59,7 @@ import com.android.developers.androidify.util.allowsFullContent
5859
import com.android.developers.androidify.util.isAtLeastMedium
5960
import com.android.developers.androidify.util.shouldShowTabletopLayout
6061
import com.android.developers.androidify.util.supportsTabletop
62+
import com.android.developers.androidify.xr.LocalSpatialCapabilities
6163

6264
@Composable
6365
internal fun CameraLayout(
@@ -98,6 +100,15 @@ internal fun CameraLayout(
98100
.background(TertiaryContainer),
99101
) {
100102
when {
103+
xrEnabled && LocalSpatialCapabilities.current.isSpatialUiEnabled -> CameraLayoutSpatial(
104+
viewfinder,
105+
captureButton,
106+
flipCameraButton,
107+
zoomButton,
108+
guideText,
109+
guide,
110+
)
111+
101112
isAtLeastMedium() && shouldShowTabletopLayout(
102113
supportsTabletop = supportsTabletop,
103114
isTabletop = isTabletop,
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.android.developers.androidify.camera.xr
17+
18+
import androidx.compose.foundation.layout.Box
19+
import androidx.compose.foundation.layout.Column
20+
import androidx.compose.foundation.layout.fillMaxSize
21+
import androidx.compose.foundation.layout.padding
22+
import androidx.compose.foundation.layout.size
23+
import androidx.compose.material3.IconButtonDefaults
24+
import androidx.compose.material3.MaterialTheme
25+
import androidx.compose.runtime.Composable
26+
import androidx.compose.ui.Alignment
27+
import androidx.compose.ui.Modifier
28+
import androidx.compose.ui.unit.dp
29+
import androidx.xr.compose.spatial.ContentEdge
30+
import androidx.xr.compose.spatial.Orbiter
31+
import androidx.xr.compose.spatial.OrbiterOffsetType
32+
import androidx.xr.compose.spatial.Subspace
33+
import androidx.xr.compose.subspace.SpatialPanel
34+
import androidx.xr.compose.subspace.layout.SubspaceModifier
35+
import androidx.xr.compose.subspace.layout.aspectRatio
36+
import androidx.xr.compose.subspace.layout.fillMaxSize
37+
import com.android.developers.androidify.xr.MainPanelWorkaround
38+
import com.android.developers.androidify.xr.RequestHomeSpaceIconButton
39+
40+
@Composable
41+
fun CameraLayoutSpatial(
42+
viewfinder: @Composable (modifier: Modifier) -> Unit,
43+
captureButton: @Composable (modifier: Modifier) -> Unit,
44+
flipCameraButton: @Composable (modifier: Modifier) -> Unit,
45+
zoomButton: @Composable (modifier: Modifier) -> Unit,
46+
guideText: @Composable (modifier: Modifier) -> Unit,
47+
guide: @Composable (modifier: Modifier) -> Unit,
48+
surfaceAspectRatio: Float,
49+
) {
50+
Subspace {
51+
MainPanelWorkaround()
52+
SpatialPanel(
53+
SubspaceModifier
54+
.fillMaxSize(0.5f),
55+
) {
56+
Orbiter(
57+
position = ContentEdge.Top,
58+
offsetType = OrbiterOffsetType.InnerEdge,
59+
offset = 32.dp,
60+
alignment = Alignment.End,
61+
) {
62+
RequestHomeSpaceIconButton(
63+
modifier = Modifier
64+
.size(64.dp, 64.dp)
65+
.padding(8.dp),
66+
colors = IconButtonDefaults.iconButtonColors(
67+
containerColor = MaterialTheme.colorScheme.secondaryContainer,
68+
),
69+
)
70+
}
71+
Orbiter(ContentEdge.Start, offsetType = OrbiterOffsetType.InnerEdge, offset = 16.dp) {
72+
Column(horizontalAlignment = Alignment.CenterHorizontally) {
73+
captureButton(Modifier)
74+
flipCameraButton(Modifier)
75+
}
76+
}
77+
Orbiter(ContentEdge.Bottom, offsetType = OrbiterOffsetType.InnerEdge) {
78+
zoomButton(Modifier)
79+
}
80+
Box(Modifier.fillMaxSize()) {
81+
viewfinder(Modifier)
82+
guide(Modifier.fillMaxSize())
83+
guideText(
84+
Modifier
85+
.align(Alignment.BottomCenter)
86+
.padding(horizontal = 36.dp, vertical = 64.dp),
87+
)
88+
}
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)