Skip to content

Commit aece402

Browse files
committed
Create Spatial layout for Edit Screen
1 parent c2459f4 commit aece402

File tree

12 files changed

+421
-53
lines changed

12 files changed

+421
-53
lines changed

feature/creation/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ dependencies {
9898
androidTestImplementation(libs.androidx.espresso.core)
9999
androidTestImplementation(libs.hilt.android.testing)
100100
androidTestImplementation(projects.core.testing)
101+
implementation(projects.core.network)
101102
kspAndroidTest(libs.hilt.compiler)
102103

103104
debugImplementation(libs.androidx.ui.test.manifest)

feature/creation/src/androidTest/java/com/android/developers/androidify/creation/CreationScreenTest.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class CreationScreenTest {
4747
EditScreen(
4848
snackbarHostState = SnackbarHostState(),
4949
dropBehaviourFactory = FakeDropImageFactory(),
50-
isExpanded = false,
50+
layoutType = EditScreenLayoutType.Compact,
5151
onCameraPressed = {},
5252
onBackPressed = {},
5353
onAboutPressed = {},
@@ -76,7 +76,7 @@ class CreationScreenTest {
7676
EditScreen(
7777
snackbarHostState = SnackbarHostState(),
7878
dropBehaviourFactory = FakeDropImageFactory(),
79-
isExpanded = false,
79+
layoutType = EditScreenLayoutType.Compact,
8080
onCameraPressed = {},
8181
onBackPressed = {},
8282
onAboutPressed = {},
@@ -106,7 +106,7 @@ class CreationScreenTest {
106106
EditScreen(
107107
snackbarHostState = SnackbarHostState(),
108108
dropBehaviourFactory = FakeDropImageFactory(),
109-
isExpanded = false,
109+
layoutType = EditScreenLayoutType.Compact,
110110
onCameraPressed = {},
111111
onBackPressed = {},
112112
onAboutPressed = {},
@@ -141,7 +141,7 @@ class CreationScreenTest {
141141
EditScreen(
142142
snackbarHostState = SnackbarHostState(),
143143
dropBehaviourFactory = FakeDropImageFactory(),
144-
isExpanded = false,
144+
layoutType = EditScreenLayoutType.Compact,
145145
onCameraPressed = {},
146146
onBackPressed = {},
147147
onAboutPressed = {},
@@ -175,7 +175,7 @@ class CreationScreenTest {
175175
EditScreen(
176176
snackbarHostState = SnackbarHostState(),
177177
dropBehaviourFactory = FakeDropImageFactory(),
178-
isExpanded = false,
178+
layoutType = EditScreenLayoutType.Compact,
179179
onCameraPressed = {},
180180
onBackPressed = {},
181181
onAboutPressed = {},
@@ -210,7 +210,7 @@ class CreationScreenTest {
210210
EditScreen(
211211
snackbarHostState = SnackbarHostState(),
212212
dropBehaviourFactory = FakeDropImageFactory(),
213-
isExpanded = false,
213+
layoutType = EditScreenLayoutType.Compact,
214214
onCameraPressed = {},
215215
onBackPressed = {},
216216
onAboutPressed = {},
@@ -244,7 +244,7 @@ class CreationScreenTest {
244244
EditScreen(
245245
snackbarHostState = SnackbarHostState(),
246246
dropBehaviourFactory = FakeDropImageFactory(),
247-
isExpanded = false,
247+
layoutType = EditScreenLayoutType.Compact,
248248
onCameraPressed = {},
249249
onBackPressed = {},
250250
onAboutPressed = {},
@@ -274,7 +274,7 @@ class CreationScreenTest {
274274
EditScreen(
275275
snackbarHostState = SnackbarHostState(),
276276
dropBehaviourFactory = FakeDropImageFactory(),
277-
isExpanded = true, // Expanded mode
277+
layoutType = EditScreenLayoutType.Medium,
278278
onCameraPressed = {},
279279
onBackPressed = {},
280280
onAboutPressed = {},

feature/creation/src/main/java/com/android/developers/androidify/creation/CreationScreen.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,17 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
3939
import com.android.developers.androidify.customize.CustomizeAndExportScreen
4040
import com.android.developers.androidify.customize.CustomizeExportViewModel
4141
import com.android.developers.androidify.results.ResultsScreen
42-
import com.android.developers.androidify.util.isAtLeastMedium
4342

4443
@Composable
4544
fun CreationScreen(
4645
fileName: String? = null,
4746
creationViewModel: CreationViewModel = hiltViewModel(),
48-
isMedium: Boolean = isAtLeastMedium(),
4947
onCameraPressed: () -> Unit = {},
5048
onBackPressed: () -> Unit,
5149
onAboutPressed: () -> Unit,
5250
) {
5351
val uiState by creationViewModel.uiState.collectAsStateWithLifecycle()
52+
val layoutType = calculateLayoutType(uiState.xrEnabled)
5453
BackHandler(
5554
enabled = uiState.screenState != ScreenState.EDIT,
5655
) {
@@ -74,7 +73,7 @@ fun CreationScreen(
7473
EditScreen(
7574
snackbarHostState = snackbarHostState,
7675
dropBehaviourFactory = creationViewModel.dropBehaviourFactory,
77-
isExpanded = isMedium,
76+
layoutType = layoutType,
7877
onCameraPressed = onCameraPressed,
7978
onBackPressed = onBackPressed,
8079
onAboutPressed = onAboutPressed,

feature/creation/src/main/java/com/android/developers/androidify/creation/CreationViewModel.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import androidx.compose.material3.SnackbarHostState
2424
import androidx.compose.ui.graphics.Color
2525
import androidx.lifecycle.ViewModel
2626
import androidx.lifecycle.viewModelScope
27+
import com.android.developers.androidify.data.ConfigProvider
2728
import com.android.developers.androidify.data.DropBehaviourFactory
2829
import com.android.developers.androidify.data.ImageDescriptionFailedGenerationException
2930
import com.android.developers.androidify.data.ImageGenerationRepository
@@ -52,6 +53,7 @@ class CreationViewModel @Inject constructor(
5253
val dropBehaviourFactory: DropBehaviourFactory,
5354
@ApplicationContext
5455
val context: Context,
56+
configProvider: ConfigProvider,
5557
) : ViewModel() {
5658

5759
init {
@@ -61,7 +63,7 @@ class CreationViewModel @Inject constructor(
6163
}
6264
}
6365

64-
private var _uiState = MutableStateFlow(CreationState())
66+
private var _uiState = MutableStateFlow(CreationState(xrEnabled = configProvider.isXrEnabled()))
6567

6668
val uiState: StateFlow<CreationState>
6769
get() = _uiState
@@ -253,6 +255,7 @@ data class CreationState(
253255
val promptGenerationInProgress: Boolean = false,
254256
val screenState: ScreenState = ScreenState.EDIT,
255257
val resultBitmap: Bitmap? = null,
258+
val xrEnabled: Boolean = false,
256259
)
257260

258261
enum class ScreenState {

feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreen.kt

Lines changed: 98 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,23 @@ import androidx.compose.ui.Modifier
4646
import androidx.compose.ui.draganddrop.DragAndDropEvent
4747
import androidx.compose.ui.draganddrop.DragAndDropTarget
4848
import androidx.compose.ui.unit.dp
49+
import com.android.developers.androidify.creation.xr.EditScreenSpatial
4950
import com.android.developers.androidify.data.DropBehaviourFactory
5051
import com.android.developers.androidify.theme.AndroidifyTheme
5152
import com.android.developers.androidify.theme.SharedElementContextPreview
5253
import com.android.developers.androidify.theme.components.AboutButton
5354
import com.android.developers.androidify.theme.components.AndroidifyTopAppBar
5455
import com.android.developers.androidify.theme.components.SquiggleBackground
55-
import com.android.developers.androidify.util.AdaptivePreview
56-
import com.android.developers.androidify.util.isAtLeastMedium
56+
import com.android.developers.androidify.util.LargeScreensPreview
57+
import com.android.developers.androidify.util.PhonePreview
58+
import com.android.developers.androidify.xr.RequestFullSpaceIconButton
59+
import com.android.developers.androidify.xr.couldRequestFullSpace
5760

5861
@Composable
5962
fun EditScreen(
6063
snackbarHostState: SnackbarHostState,
6164
dropBehaviourFactory: DropBehaviourFactory,
62-
isExpanded: Boolean = isAtLeastMedium(),
65+
layoutType: EditScreenLayoutType,
6366
onCameraPressed: () -> Unit,
6467
onBackPressed: () -> Unit,
6568
onAboutPressed: () -> Unit,
@@ -71,13 +74,73 @@ fun EditScreen(
7174
onBotColorSelected: (BotColor) -> Unit,
7275
onStartClicked: () -> Unit,
7376
onDropCallback: (Uri) -> Unit = {},
77+
) {
78+
when (layoutType) {
79+
EditScreenLayoutType.Compact ->
80+
EditScreenScaffoldWithAppBar(snackbarHostState, layoutType, onBackPressed, onAboutPressed, uiState, onPromptOptionSelected) {
81+
EditScreenContentsCompact(
82+
dropBehaviourFactory,
83+
onCameraPressed,
84+
uiState,
85+
onChooseImageClicked,
86+
onPromptOptionSelected,
87+
onUndoPressed,
88+
onPromptGenerationPressed,
89+
onBotColorSelected,
90+
onStartClicked,
91+
onDropCallback,
92+
)
93+
}
94+
EditScreenLayoutType.Medium ->
95+
EditScreenScaffoldWithAppBar(snackbarHostState, layoutType, onBackPressed, onAboutPressed, uiState, onPromptOptionSelected) {
96+
EditScreenContentsMedium(
97+
dropBehaviourFactory,
98+
onCameraPressed,
99+
uiState,
100+
onChooseImageClicked,
101+
onPromptOptionSelected,
102+
onUndoPressed,
103+
onPromptGenerationPressed,
104+
onBotColorSelected,
105+
onStartClicked,
106+
onDropCallback,
107+
)
108+
}
109+
EditScreenLayoutType.Spatial ->
110+
EditScreenSpatial(
111+
dropBehaviourFactory,
112+
onCameraPressed,
113+
onBackPressed,
114+
onAboutPressed,
115+
uiState,
116+
snackbarHostState,
117+
onChooseImageClicked,
118+
onPromptOptionSelected,
119+
onUndoPressed,
120+
onPromptGenerationPressed,
121+
onBotColorSelected,
122+
onStartClicked,
123+
onDropCallback,
124+
)
125+
}
126+
}
127+
128+
@Composable
129+
fun EditScreenScaffoldWithAppBar(
130+
snackbarHostState: SnackbarHostState,
131+
layoutType: EditScreenLayoutType,
132+
onBackPressed: () -> Unit,
133+
onAboutPressed: () -> Unit,
134+
uiState: CreationState,
135+
onPromptOptionSelected: (PromptType) -> Unit,
136+
contents: @Composable () -> Unit,
74137
) {
75138
EditScreenScaffold(
76139
snackbarHostState,
77140
topBar = {
78141
AndroidifyTopAppBar(
79142
backEnabled = true,
80-
isMediumWindowSize = isExpanded,
143+
isMediumWindowSize = layoutType == EditScreenLayoutType.Medium,
81144
onBackPressed = onBackPressed,
82145
expandedCenterButtons = {
83146
PromptTypeToolbar(
@@ -88,7 +151,10 @@ fun EditScreen(
88151
},
89152
actions = {
90153
AboutButton { onAboutPressed() }
91-
}
154+
if (couldRequestFullSpace()) {
155+
RequestFullSpaceIconButton()
156+
}
157+
},
92158
)
93159
},
94160
) { contentPadding ->
@@ -99,33 +165,7 @@ fun EditScreen(
99165
.padding(contentPadding)
100166
.imePadding(),
101167
) {
102-
if (isExpanded) {
103-
EditScreenContentsMedium(
104-
dropBehaviourFactory,
105-
onCameraPressed,
106-
uiState,
107-
onChooseImageClicked,
108-
onPromptOptionSelected,
109-
onUndoPressed,
110-
onPromptGenerationPressed,
111-
onBotColorSelected,
112-
onStartClicked,
113-
onDropCallback,
114-
)
115-
} else {
116-
EditScreenContentsCompact(
117-
dropBehaviourFactory,
118-
onCameraPressed,
119-
uiState,
120-
onChooseImageClicked,
121-
onPromptOptionSelected,
122-
onUndoPressed,
123-
onPromptGenerationPressed,
124-
onBotColorSelected,
125-
onStartClicked,
126-
onDropCallback,
127-
)
128-
}
168+
contents()
129169
}
130170
}
131171
}
@@ -156,9 +196,9 @@ fun EditScreenScaffold(
156196
)
157197
}
158198

199+
@PhonePreview
159200
@Composable
160-
@AdaptivePreview
161-
private fun EditScreenPreview() {
201+
private fun HomeScreenPhonePreview() {
162202
AndroidifyTheme {
163203
SharedElementContextPreview {
164204
EditScreen(
@@ -175,11 +215,35 @@ private fun EditScreenPreview() {
175215
onDropCallback = {},
176216
onBackPressed = {},
177217
onAboutPressed = {},
218+
layoutType = EditScreenLayoutType.Compact,
178219
)
179220
}
180221
}
181222
}
182223

224+
@LargeScreensPreview
225+
@Composable
226+
private fun HomeScreenLargeScreensPreview() {
227+
SharedElementContextPreview {
228+
EditScreen(
229+
snackbarHostState = SnackbarHostState(),
230+
dropBehaviourFactory = fakeDropBehaviourFactory,
231+
onCameraPressed = { },
232+
uiState = CreationState(),
233+
onChooseImageClicked = {},
234+
onPromptOptionSelected = {},
235+
onUndoPressed = {},
236+
onPromptGenerationPressed = {},
237+
onBotColorSelected = {},
238+
onStartClicked = {},
239+
onDropCallback = {},
240+
onBackPressed = {},
241+
onAboutPressed = {},
242+
layoutType = EditScreenLayoutType.Medium,
243+
)
244+
}
245+
}
246+
183247
val fakeDropBehaviourFactory = object : DropBehaviourFactory {
184248
override fun shouldStartDragAndDrop(event: DragAndDropEvent): Boolean {
185249
TODO("Stub")

feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreenCompact.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ private fun EditScreenPreview() {
237237
onDropCallback = {},
238238
onBackPressed = {},
239239
onAboutPressed = {},
240-
isExpanded = false,
240+
layoutType = EditScreenLayoutType.Compact,
241241
)
242242
}
243243
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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.creation
17+
18+
import androidx.compose.runtime.Composable
19+
import com.android.developers.androidify.util.isAtLeastMedium
20+
import com.android.developers.androidify.xr.LocalSpatialCapabilities
21+
22+
enum class EditScreenLayoutType {
23+
Compact,
24+
Medium,
25+
Spatial,
26+
}
27+
28+
@Composable
29+
fun calculateLayoutType(enableXr: Boolean = false): EditScreenLayoutType {
30+
return when {
31+
LocalSpatialCapabilities.current.isSpatialUiEnabled && enableXr -> EditScreenLayoutType.Spatial
32+
isAtLeastMedium() -> EditScreenLayoutType.Medium
33+
else -> EditScreenLayoutType.Compact
34+
}
35+
}

0 commit comments

Comments
 (0)