Merge "Simplify edit tile list state" into main
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt
index 73a0039..45262ca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt
@@ -40,21 +40,19 @@
TestEditTiles.forEach { assertThat(underTest.isMoving(it.tileSpec)).isFalse() }
// Start the drag movement
- val movingTileSpec = TestEditTiles[0].tileSpec
- underTest.onStarted(movingTileSpec)
+ underTest.onStarted(TestEditTiles[0])
// Assert that the correct tile is marked as moving
TestEditTiles.forEach {
- assertThat(underTest.isMoving(it.tileSpec)).isEqualTo(movingTileSpec == it.tileSpec)
+ assertThat(underTest.isMoving(it.tileSpec))
+ .isEqualTo(TestEditTiles[0].tileSpec == it.tileSpec)
}
}
@Test
fun onMoved_updatesList() {
- val movingTileSpec = TestEditTiles[0].tileSpec
-
// Start the drag movement
- underTest.onStarted(movingTileSpec)
+ underTest.onStarted(TestEditTiles[0])
// Move the tile to the end of the list
underTest.onMoved(listState.tiles[5].tileSpec)
@@ -67,10 +65,8 @@
@Test
fun onDrop_resetsMovingTile() {
- val movingTileSpec = TestEditTiles[0].tileSpec
-
// Start the drag movement
- underTest.onStarted(movingTileSpec)
+ underTest.onStarted(TestEditTiles[0])
// Move the tile to the end of the list
underTest.onMoved(listState.tiles[5].tileSpec)
@@ -84,16 +80,15 @@
@Test
fun onMoveOutOfBounds_removeMovingTileFromCurrentList() {
- val movingTileSpec = TestEditTiles[0].tileSpec
-
// Start the drag movement
- underTest.onStarted(movingTileSpec)
+ underTest.onStarted(TestEditTiles[0])
// Move the tile outside of the list
underTest.movedOutOfBounds()
// Asserts the moving tile is not current
- assertThat(listState.tiles.first { it.tileSpec == movingTileSpec }.isCurrent).isFalse()
+ assertThat(listState.tiles.firstOrNull { it.tileSpec == TestEditTiles[0].tileSpec })
+ .isNull()
}
companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
index 517b601..e76d389 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
@@ -33,22 +33,25 @@
val underTest = EditTileListState(TestEditTiles)
@Test
- fun movingNonExistentTile_listUnchanged() {
- underTest.move(TileSpec.create("other_tile"), TestEditTiles[0].tileSpec)
+ fun movingNonExistentTile_tileAdded() {
+ val newTile = createEditTile("other_tile", false)
+ underTest.move(newTile, TestEditTiles[0].tileSpec)
- assertThat(underTest.tiles).containsExactly(*TestEditTiles.toTypedArray())
+ assertThat(underTest.tiles[0]).isEqualTo(newTile)
+ assertThat(underTest.tiles.subList(1, underTest.tiles.size))
+ .containsExactly(*TestEditTiles.toTypedArray())
}
@Test
fun movingTileToNonExistentTarget_listUnchanged() {
- underTest.move(TestEditTiles[0].tileSpec, TileSpec.create("other_tile"))
+ underTest.move(TestEditTiles[0], TileSpec.create("other_tile"))
assertThat(underTest.tiles).containsExactly(*TestEditTiles.toTypedArray())
}
@Test
fun movingTileToItself_listUnchanged() {
- underTest.move(TestEditTiles[0].tileSpec, TestEditTiles[0].tileSpec)
+ underTest.move(TestEditTiles[0], TestEditTiles[0].tileSpec)
assertThat(underTest.tiles).containsExactly(*TestEditTiles.toTypedArray())
}
@@ -56,7 +59,7 @@
@Test
fun movingTileToSameSection_listUpdates() {
// Move tile at index 0 to index 1. Tile 0 should remain current.
- underTest.move(TestEditTiles[0].tileSpec, TestEditTiles[1].tileSpec)
+ underTest.move(TestEditTiles[0], TestEditTiles[1].tileSpec)
// Assert the tiles 0 and 1 have changed places.
assertThat(underTest.tiles[0]).isEqualTo(TestEditTiles[1])
@@ -67,22 +70,12 @@
.containsExactly(*TestEditTiles.subList(2, 5).toTypedArray())
}
- @Test
- fun movingTileToDifferentSection_listAndTileUpdates() {
- // Move tile at index 0 to index 3. Tile 0 should no longer be current.
- underTest.move(TestEditTiles[0].tileSpec, TestEditTiles[3].tileSpec)
+ fun removingTile_listUpdates() {
+ // Remove tile at index 0
+ underTest.remove(TestEditTiles[0].tileSpec)
- // Assert tile 0 is now at index 3 and is no longer current.
- assertThat(underTest.tiles[3]).isEqualTo(TestEditTiles[0].copy(isCurrent = false))
-
- // Assert previous tiles have shifted places
- assertThat(underTest.tiles[0]).isEqualTo(TestEditTiles[1])
- assertThat(underTest.tiles[1]).isEqualTo(TestEditTiles[2])
- assertThat(underTest.tiles[2]).isEqualTo(TestEditTiles[3])
-
- // Assert the rest of the list is unchanged
- assertThat(underTest.tiles.subList(4, 5))
- .containsExactly(*TestEditTiles.subList(4, 5).toTypedArray())
+ // Assert the tile was removed
+ assertThat(underTest.tiles).containsExactly(*TestEditTiles.subList(1, 6).toTypedArray())
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
index 782fb2a..71deeb6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
@@ -14,12 +14,9 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalFoundationApi::class)
-
package com.android.systemui.qs.panels.ui.compose
import android.content.ClipData
-import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.draganddrop.dragAndDropSource
import androidx.compose.foundation.draganddrop.dragAndDropTarget
import androidx.compose.foundation.gestures.detectTapGestures
@@ -32,11 +29,12 @@
import androidx.compose.ui.draganddrop.DragAndDropTarget
import androidx.compose.ui.draganddrop.DragAndDropTransferData
import androidx.compose.ui.draganddrop.mimeTypes
+import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
import com.android.systemui.qs.pipeline.shared.TileSpec
@Composable
fun rememberDragAndDropState(listState: EditTileListState): DragAndDropState {
- val sourceSpec: MutableState<TileSpec?> = remember { mutableStateOf(null) }
+ val sourceSpec: MutableState<EditTileViewModel?> = remember { mutableStateOf(null) }
return remember(listState) { DragAndDropState(sourceSpec, listState) }
}
@@ -45,7 +43,7 @@
* drop events.
*/
class DragAndDropState(
- val sourceSpec: MutableState<TileSpec?>,
+ val sourceSpec: MutableState<EditTileViewModel?>,
private val listState: EditTileListState
) {
val dragInProgress: Boolean
@@ -53,15 +51,15 @@
/** Returns index of the dragged tile if it's present in the list. Returns -1 if not. */
fun currentPosition(): Int {
- return sourceSpec.value?.let { listState.indexOf(it) } ?: -1
+ return sourceSpec.value?.let { listState.indexOf(it.tileSpec) } ?: -1
}
fun isMoving(tileSpec: TileSpec): Boolean {
- return sourceSpec.value?.let { it == tileSpec } ?: false
+ return sourceSpec.value?.let { it.tileSpec == tileSpec } ?: false
}
- fun onStarted(spec: TileSpec) {
- sourceSpec.value = spec
+ fun onStarted(tile: EditTileViewModel) {
+ sourceSpec.value = tile
}
fun onMoved(targetSpec: TileSpec) {
@@ -71,7 +69,7 @@
fun movedOutOfBounds() {
// Removing the tiles from the current tile grid if it moves out of bounds. This clears
// the spacer and makes it apparent that dropping the tile at that point would remove it.
- sourceSpec.value?.let { listState.removeFromCurrent(it) }
+ sourceSpec.value?.let { listState.remove(it.tileSpec) }
}
fun onDrop() {
@@ -100,7 +98,7 @@
object : DragAndDropTarget {
override fun onDrop(event: DragAndDropEvent): Boolean {
return dragAndDropState.sourceSpec.value?.let {
- onDrop(it, dragAndDropState.currentPosition())
+ onDrop(it.tileSpec, dragAndDropState.currentPosition())
dragAndDropState.onDrop()
true
} ?: false
@@ -114,7 +112,7 @@
return dragAndDropTarget(
shouldStartDragAndDrop = { event ->
event.mimeTypes().contains(QsDragAndDrop.TILESPEC_MIME_TYPE) &&
- dragAndDropState.sourceSpec.value?.let { acceptDrops(it) } ?: false
+ dragAndDropState.sourceSpec.value?.let { acceptDrops(it.tileSpec) } ?: false
},
target = target,
)
@@ -137,7 +135,7 @@
object : DragAndDropTarget {
override fun onDrop(event: DragAndDropEvent): Boolean {
return dragAndDropState.sourceSpec.value?.let {
- onDrop(it)
+ onDrop(it.tileSpec)
dragAndDropState.onDrop()
true
} ?: false
@@ -179,7 +177,7 @@
override fun onDrop(event: DragAndDropEvent): Boolean {
return dragAndDropState.sourceSpec.value?.let {
- onDrop(it, dragAndDropState.currentPosition())
+ onDrop(it.tileSpec, dragAndDropState.currentPosition())
dragAndDropState.onDrop()
true
} ?: false
@@ -190,23 +188,23 @@
target = target,
shouldStartDragAndDrop = { event ->
event.mimeTypes().contains(QsDragAndDrop.TILESPEC_MIME_TYPE) &&
- dragAndDropState.sourceSpec.value?.let { acceptDrops(it) } ?: false
+ dragAndDropState.sourceSpec.value?.let { acceptDrops(it.tileSpec) } ?: false
},
)
}
fun Modifier.dragAndDropTileSource(
- tileSpec: TileSpec,
+ tile: EditTileViewModel,
onTap: (TileSpec) -> Unit,
onDoubleTap: (TileSpec) -> Unit,
dragAndDropState: DragAndDropState
): Modifier {
return dragAndDropSource {
detectTapGestures(
- onTap = { onTap(tileSpec) },
- onDoubleTap = { onDoubleTap(tileSpec) },
+ onTap = { onTap(tile.tileSpec) },
+ onDoubleTap = { onDoubleTap(tile.tileSpec) },
onLongPress = {
- dragAndDropState.onStarted(tileSpec)
+ dragAndDropState.onStarted(tile)
// The tilespec from the ClipData transferred isn't actually needed as we're moving
// a tile within the same application. We're using a custom MIME type to limit the
@@ -216,7 +214,7 @@
ClipData(
QsDragAndDrop.CLIPDATA_LABEL,
arrayOf(QsDragAndDrop.TILESPEC_MIME_TYPE),
- ClipData.Item(tileSpec.spec)
+ ClipData.Item(tile.tileSpec.spec)
)
)
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
index 34876c4..e0fed28 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
@@ -34,28 +34,25 @@
class EditTileListState(tiles: List<EditTileViewModel>) {
val tiles: SnapshotStateList<EditTileViewModel> = tiles.toMutableStateList()
- fun move(tileSpec: TileSpec, target: TileSpec) {
- val fromIndex = indexOf(tileSpec)
+ fun move(tile: EditTileViewModel, target: TileSpec) {
+ val fromIndex = indexOf(tile.tileSpec)
val toIndex = indexOf(target)
- if (fromIndex == -1 || toIndex == -1 || fromIndex == toIndex) {
+ if (toIndex == -1 || fromIndex == toIndex) {
return
}
- val isMovingToCurrent = tiles[toIndex].isCurrent
- tiles.apply { add(toIndex, removeAt(fromIndex).copy(isCurrent = isMovingToCurrent)) }
+ if (fromIndex == -1) {
+ // If tile isn't in the list, simply insert it
+ tiles.add(toIndex, tile)
+ } else {
+ // If tile is present in the list, move it
+ tiles.apply { add(toIndex, removeAt(fromIndex)) }
+ }
}
- /**
- * Sets the [TileSpec] as a non-current tile. Use this when a tile is dragged out of the current
- * tile grid.
- */
- fun removeFromCurrent(tileSpec: TileSpec) {
- val fromIndex = indexOf(tileSpec)
- if (fromIndex >= 0 && fromIndex < tiles.size) {
- // Mark the moving tile as non-current
- tiles[fromIndex] = tiles[fromIndex].copy(isCurrent = false)
- }
+ fun remove(tileSpec: TileSpec) {
+ tiles.removeIf { it.tileSpec == tileSpec }
}
fun indexOf(tileSpec: TileSpec): Int {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
index bd7956d..cb9d0f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
@@ -294,9 +294,9 @@
onRemoveTile: (TileSpec) -> Unit,
onResize: (TileSpec, Boolean) -> Unit,
) {
- val currentListState = rememberEditListState(tiles)
+ val (currentTiles, otherTiles) = tiles.partition { it.isCurrent }
+ val currentListState = rememberEditListState(currentTiles)
val dragAndDropState = rememberDragAndDropState(currentListState)
- val (currentTiles, otherTiles) = currentListState.tiles.partition { it.isCurrent }
val addTileToEnd: (TileSpec) -> Unit by rememberUpdatedState {
onAddTile(it, CurrentTilesInteractor.POSITION_AT_END)
@@ -329,7 +329,7 @@
}
CurrentTilesGrid(
- currentTiles,
+ currentListState.tiles,
columns,
tilePadding,
isIconOnly,
@@ -480,16 +480,13 @@
onClick: (TileSpec) -> Unit,
dragAndDropState: DragAndDropState,
) {
- val (otherTilesStock, otherTilesCustom) =
- tiles.filter { !dragAndDropState.isMoving(it.tileSpec) }.partition { it.appName == null }
+ val (otherTilesStock, otherTilesCustom) = tiles.partition { it.appName == null }
val availableTileHeight = tileHeight(true)
val availableGridHeight = gridHeight(tiles.size, availableTileHeight, columns, tilePadding)
// Available tiles
TileLazyGrid(
- modifier =
- Modifier.height(availableGridHeight)
- .dragAndDropTileList(dragAndDropState, { false }, { _, _ -> }),
+ modifier = Modifier.height(availableGridHeight),
columns = GridCells.Fixed(columns)
) {
editTiles(
@@ -594,7 +591,7 @@
}
.dragAndDropTile(dragAndDropState, viewModel.tileSpec, acceptDrops, onDrop)
.dragAndDropTileSource(
- viewModel.tileSpec,
+ viewModel,
onClick,
onDoubleTap,
dragAndDropState,