Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorTest.kt +3 −3 Original line number Diff line number Diff line Loading @@ -85,12 +85,12 @@ class IconTilesInteractorTest : SysuiTestCase() { runCurrent() // Assert that the tile is removed from the large tiles after resizing underTest.resize(largeTile) underTest.resize(largeTile, toIcon = true) runCurrent() assertThat(latest).doesNotContain(largeTile) // Assert that the tile is added to the large tiles after resizing underTest.resize(largeTile) underTest.resize(largeTile, toIcon = false) runCurrent() assertThat(latest).contains(largeTile) } Loading Loading @@ -122,7 +122,7 @@ class IconTilesInteractorTest : SysuiTestCase() { val newTile = TileSpec.create("newTile") // Remove the large tile from the current tiles underTest.resize(newTile) underTest.resize(newTile, toIcon = false) runCurrent() // Assert that it's still small Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt +0 −18 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import com.android.systemui.common.shared.model.Icon import com.android.systemui.qs.panels.shared.model.SizedTile import com.android.systemui.qs.panels.shared.model.SizedTileImpl import com.android.systemui.qs.panels.ui.model.GridCell import com.android.systemui.qs.panels.ui.model.SpacerGridCell import com.android.systemui.qs.panels.ui.model.TileGridCell import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel import com.android.systemui.qs.pipeline.shared.TileSpec Loading @@ -38,13 +37,6 @@ import org.junit.runner.RunWith class EditTileListStateTest : SysuiTestCase() { private val underTest = EditTileListState(TestEditTiles, 4) @Test fun noDrag_listUnchanged() { underTest.tiles.forEach { assertThat(it).isNotInstanceOf(SpacerGridCell::class.java) } assertThat(underTest.tiles.map { (it as TileGridCell).tile.tileSpec }) .containsExactly(*TestEditTiles.map { it.tile.tileSpec }.toTypedArray()) } @Test fun startDrag_listHasSpacers() { underTest.onStarted(TestEditTiles[0]) Loading Loading @@ -108,16 +100,6 @@ class EditTileListStateTest : SysuiTestCase() { ) } @Test fun droppedNewTile_spacersDisappear() { underTest.onStarted(TestEditTiles[0]) underTest.onDrop() assertThat(underTest.tiles.toStrings()).isEqualTo(listOf("a", "b", "c", "d", "e")) assertThat(underTest.isMoving(TestEditTiles[0].tile.tileSpec)).isFalse() assertThat(underTest.dragInProgress).isFalse() } @Test fun movedTileOutOfBounds_tileDisappears() { underTest.onStarted(TestEditTiles[0]) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt +58 −21 Original line number Diff line number Diff line Loading @@ -27,23 +27,25 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class MutableSelectionStateTest : SysuiTestCase() { private val underTest = MutableSelectionState() private val underTest = MutableSelectionState({}, {}) @Test fun selectTile_isCorrectlySelected() { assertThat(underTest.isSelected(TEST_SPEC)).isFalse() assertThat(underTest.selection?.tileSpec).isNotEqualTo(TEST_SPEC) underTest.select(TEST_SPEC) assertThat(underTest.isSelected(TEST_SPEC)).isTrue() underTest.select(TEST_SPEC, manual = true) assertThat(underTest.selection?.tileSpec).isEqualTo(TEST_SPEC) assertThat(underTest.selection?.manual).isTrue() underTest.unSelect() assertThat(underTest.isSelected(TEST_SPEC)).isFalse() assertThat(underTest.selection).isNull() val newSpec = TileSpec.create("newSpec") underTest.select(TEST_SPEC) underTest.select(newSpec) assertThat(underTest.isSelected(TEST_SPEC)).isFalse() assertThat(underTest.isSelected(newSpec)).isTrue() underTest.select(TEST_SPEC, manual = true) underTest.select(newSpec, manual = false) assertThat(underTest.selection?.tileSpec).isNotEqualTo(TEST_SPEC) assertThat(underTest.selection?.tileSpec).isEqualTo(newSpec) assertThat(underTest.selection?.manual).isFalse() } @Test Loading @@ -51,12 +53,12 @@ class MutableSelectionStateTest : SysuiTestCase() { assertThat(underTest.resizingState).isNull() // Resizing starts but no tile is selected underTest.onResizingDragStart(TileWidths(0, 0, 1)) {} underTest.onResizingDragStart(TileWidths(0, 0, 1)) assertThat(underTest.resizingState).isNull() // Resizing starts with a selected tile underTest.select(TEST_SPEC) underTest.onResizingDragStart(TileWidths(0, 0, 1)) {} underTest.select(TEST_SPEC, manual = true) underTest.onResizingDragStart(TileWidths(0, 0, 1)) assertThat(underTest.resizingState).isNotNull() } Loading @@ -66,8 +68,8 @@ class MutableSelectionStateTest : SysuiTestCase() { val spec = TileSpec.create("testSpec") // Resizing starts with a selected tile underTest.select(spec) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) {} underTest.select(spec, manual = true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) assertThat(underTest.resizingState).isNotNull() underTest.onResizingDragEnd() Loading @@ -77,8 +79,8 @@ class MutableSelectionStateTest : SysuiTestCase() { @Test fun unselect_clearsResizingState() { // Resizing starts with a selected tile underTest.select(TEST_SPEC) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) {} underTest.select(TEST_SPEC, manual = true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) assertThat(underTest.resizingState).isNotNull() underTest.unSelect() Loading @@ -88,8 +90,8 @@ class MutableSelectionStateTest : SysuiTestCase() { @Test fun onResizingDrag_updatesResizingState() { // Resizing starts with a selected tile underTest.select(TEST_SPEC) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) {} underTest.select(TEST_SPEC, manual = true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) assertThat(underTest.resizingState).isNotNull() underTest.onResizingDrag(5f) Loading @@ -105,11 +107,15 @@ class MutableSelectionStateTest : SysuiTestCase() { @Test fun onResizingDrag_receivesResizeCallback() { var resized = false val onResize: () -> Unit = { resized = !resized } val onResize: (TileSpec) -> Unit = { assertThat(it).isEqualTo(TEST_SPEC) resized = !resized } val underTest = MutableSelectionState(onResize = onResize, {}) // Resizing starts with a selected tile underTest.select(TEST_SPEC) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10), onResize) underTest.select(TEST_SPEC, true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) assertThat(underTest.resizingState).isNotNull() // Drag under the threshold Loading @@ -125,6 +131,37 @@ class MutableSelectionStateTest : SysuiTestCase() { assertThat(resized).isFalse() } @Test fun onResizingEnded_receivesResizeEndCallback() { var resizeEnded = false val onResizeEnd: (TileSpec) -> Unit = { resizeEnded = true } val underTest = MutableSelectionState({}, onResizeEnd = onResizeEnd) // Resizing starts with a selected tile underTest.select(TEST_SPEC, true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) underTest.onResizingDragEnd() assertThat(resizeEnded).isTrue() } @Test fun onResizingEnded_setsSelectionAutomatically() { val underTest = MutableSelectionState({}, {}) // Resizing starts with a selected tile underTest.select(TEST_SPEC, manual = true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) // Assert the selection was manual assertThat(underTest.selection?.manual).isTrue() underTest.onResizingDragEnd() // Assert the selection is no longer manual due to the resizing assertThat(underTest.selection?.manual).isFalse() } companion object { private val TEST_SPEC = TileSpec.create("testSpec") } Loading packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt +6 −5 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ constructor( private val currentTilesInteractor: CurrentTilesInteractor, private val preferencesInteractor: QSPreferencesInteractor, @PanelsLog private val logBuffer: LogBuffer, @Application private val applicationScope: CoroutineScope @Application private val applicationScope: CoroutineScope, ) { val largeTilesSpecs = Loading @@ -64,14 +64,15 @@ constructor( fun isIconTile(spec: TileSpec): Boolean = !largeTilesSpecs.value.contains(spec) fun resize(spec: TileSpec) { fun resize(spec: TileSpec, toIcon: Boolean) { if (!isCurrent(spec)) { return } if (largeTilesSpecs.value.contains(spec)) { val isIcon = !largeTilesSpecs.value.contains(spec) if (toIcon && !isIcon) { preferencesInteractor.setLargeTilesSpecs(largeTilesSpecs.value - spec) } else { } else if (!toIcon && isIcon) { preferencesInteractor.setLargeTilesSpecs(largeTilesSpecs.value + spec) } } Loading @@ -85,7 +86,7 @@ constructor( LOG_BUFFER_LARGE_TILES_SPECS_CHANGE_TAG, LogLevel.DEBUG, { str1 = specs.toString() }, { "Large tiles change: $str1" } { "Large tiles change: $str1" }, ) } Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt +50 −8 Original line number Diff line number Diff line Loading @@ -60,10 +60,37 @@ class EditTileListState(tiles: List<SizedTile<EditTileViewModel>>, private val c return _tiles.filterIsInstance<TileGridCell>().map { it.tile.tileSpec } } fun indexOf(tileSpec: TileSpec): Int { private fun indexOf(tileSpec: TileSpec): Int { return _tiles.indexOfFirst { it is TileGridCell && it.tile.tileSpec == tileSpec } } /** * Whether the tile with this [TileSpec] is currently an icon in the [EditTileListState] * * @return true if the tile is an icon, false if it's large, null if the tile isn't in the list */ fun isIcon(tileSpec: TileSpec): Boolean? { val index = indexOf(tileSpec) return if (index != -1) { val cell = _tiles[index] cell as TileGridCell return cell.isIcon } else { null } } /** Toggle the size of the tile corresponding to the [TileSpec] */ fun toggleSize(tileSpec: TileSpec) { val fromIndex = indexOf(tileSpec) if (fromIndex != -1) { val cell = _tiles.removeAt(fromIndex) cell as TileGridCell _tiles.add(fromIndex, cell.copy(width = if (cell.isIcon) 2 else 1)) regenerateGrid(fromIndex) } } override fun isMoving(tileSpec: TileSpec): Boolean { return _draggedCell.value?.let { it.tile.tileSpec == tileSpec } ?: false } Loading @@ -71,8 +98,8 @@ class EditTileListState(tiles: List<SizedTile<EditTileViewModel>>, private val c override fun onStarted(cell: SizedTile<EditTileViewModel>) { _draggedCell.value = cell // Add visible spacers to the grid to indicate where the user can move a tile regenerateGrid(includeSpacers = true) // Add spacers to the grid to indicate where the user can move a tile regenerateGrid() } override fun onMoved(target: Int, insertAfter: Boolean) { Loading @@ -86,7 +113,7 @@ class EditTileListState(tiles: List<SizedTile<EditTileViewModel>>, private val c val insertionIndex = if (insertAfter) target + 1 else target if (fromIndex != -1) { val cell = _tiles.removeAt(fromIndex) regenerateGrid(includeSpacers = true) regenerateGrid() _tiles.add(insertionIndex.coerceIn(0, _tiles.size), cell) } else { // Add the tile with a temporary row which will get reassigned when Loading @@ -94,7 +121,7 @@ class EditTileListState(tiles: List<SizedTile<EditTileViewModel>>, private val c _tiles.add(insertionIndex.coerceIn(0, _tiles.size), TileGridCell(draggedTile, 0)) } regenerateGrid(includeSpacers = true) regenerateGrid() } override fun movedOutOfBounds() { Loading @@ -109,12 +136,27 @@ class EditTileListState(tiles: List<SizedTile<EditTileViewModel>>, private val c _draggedCell.value = null // Remove the spacers regenerateGrid(includeSpacers = false) regenerateGrid() } private fun regenerateGrid(includeSpacers: Boolean) { _tiles.filterIsInstance<TileGridCell>().toGridCells(columns, includeSpacers).let { /** Regenerate the list of [GridCell] with their new potential rows */ private fun regenerateGrid() { _tiles.filterIsInstance<TileGridCell>().toGridCells(columns).let { _tiles.clear() _tiles.addAll(it) } } /** * Regenerate the list of [GridCell] with their new potential rows from [fromIndex], leaving * cells before that untouched. */ private fun regenerateGrid(fromIndex: Int) { val fromRow = _tiles[fromIndex].row val (pre, post) = _tiles.partition { it.row < fromRow } post.filterIsInstance<TileGridCell>().toGridCells(columns, startingRow = fromRow).let { _tiles.clear() _tiles.addAll(pre) _tiles.addAll(it) } } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorTest.kt +3 −3 Original line number Diff line number Diff line Loading @@ -85,12 +85,12 @@ class IconTilesInteractorTest : SysuiTestCase() { runCurrent() // Assert that the tile is removed from the large tiles after resizing underTest.resize(largeTile) underTest.resize(largeTile, toIcon = true) runCurrent() assertThat(latest).doesNotContain(largeTile) // Assert that the tile is added to the large tiles after resizing underTest.resize(largeTile) underTest.resize(largeTile, toIcon = false) runCurrent() assertThat(latest).contains(largeTile) } Loading Loading @@ -122,7 +122,7 @@ class IconTilesInteractorTest : SysuiTestCase() { val newTile = TileSpec.create("newTile") // Remove the large tile from the current tiles underTest.resize(newTile) underTest.resize(newTile, toIcon = false) runCurrent() // Assert that it's still small Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt +0 −18 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import com.android.systemui.common.shared.model.Icon import com.android.systemui.qs.panels.shared.model.SizedTile import com.android.systemui.qs.panels.shared.model.SizedTileImpl import com.android.systemui.qs.panels.ui.model.GridCell import com.android.systemui.qs.panels.ui.model.SpacerGridCell import com.android.systemui.qs.panels.ui.model.TileGridCell import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel import com.android.systemui.qs.pipeline.shared.TileSpec Loading @@ -38,13 +37,6 @@ import org.junit.runner.RunWith class EditTileListStateTest : SysuiTestCase() { private val underTest = EditTileListState(TestEditTiles, 4) @Test fun noDrag_listUnchanged() { underTest.tiles.forEach { assertThat(it).isNotInstanceOf(SpacerGridCell::class.java) } assertThat(underTest.tiles.map { (it as TileGridCell).tile.tileSpec }) .containsExactly(*TestEditTiles.map { it.tile.tileSpec }.toTypedArray()) } @Test fun startDrag_listHasSpacers() { underTest.onStarted(TestEditTiles[0]) Loading Loading @@ -108,16 +100,6 @@ class EditTileListStateTest : SysuiTestCase() { ) } @Test fun droppedNewTile_spacersDisappear() { underTest.onStarted(TestEditTiles[0]) underTest.onDrop() assertThat(underTest.tiles.toStrings()).isEqualTo(listOf("a", "b", "c", "d", "e")) assertThat(underTest.isMoving(TestEditTiles[0].tile.tileSpec)).isFalse() assertThat(underTest.dragInProgress).isFalse() } @Test fun movedTileOutOfBounds_tileDisappears() { underTest.onStarted(TestEditTiles[0]) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt +58 −21 Original line number Diff line number Diff line Loading @@ -27,23 +27,25 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class MutableSelectionStateTest : SysuiTestCase() { private val underTest = MutableSelectionState() private val underTest = MutableSelectionState({}, {}) @Test fun selectTile_isCorrectlySelected() { assertThat(underTest.isSelected(TEST_SPEC)).isFalse() assertThat(underTest.selection?.tileSpec).isNotEqualTo(TEST_SPEC) underTest.select(TEST_SPEC) assertThat(underTest.isSelected(TEST_SPEC)).isTrue() underTest.select(TEST_SPEC, manual = true) assertThat(underTest.selection?.tileSpec).isEqualTo(TEST_SPEC) assertThat(underTest.selection?.manual).isTrue() underTest.unSelect() assertThat(underTest.isSelected(TEST_SPEC)).isFalse() assertThat(underTest.selection).isNull() val newSpec = TileSpec.create("newSpec") underTest.select(TEST_SPEC) underTest.select(newSpec) assertThat(underTest.isSelected(TEST_SPEC)).isFalse() assertThat(underTest.isSelected(newSpec)).isTrue() underTest.select(TEST_SPEC, manual = true) underTest.select(newSpec, manual = false) assertThat(underTest.selection?.tileSpec).isNotEqualTo(TEST_SPEC) assertThat(underTest.selection?.tileSpec).isEqualTo(newSpec) assertThat(underTest.selection?.manual).isFalse() } @Test Loading @@ -51,12 +53,12 @@ class MutableSelectionStateTest : SysuiTestCase() { assertThat(underTest.resizingState).isNull() // Resizing starts but no tile is selected underTest.onResizingDragStart(TileWidths(0, 0, 1)) {} underTest.onResizingDragStart(TileWidths(0, 0, 1)) assertThat(underTest.resizingState).isNull() // Resizing starts with a selected tile underTest.select(TEST_SPEC) underTest.onResizingDragStart(TileWidths(0, 0, 1)) {} underTest.select(TEST_SPEC, manual = true) underTest.onResizingDragStart(TileWidths(0, 0, 1)) assertThat(underTest.resizingState).isNotNull() } Loading @@ -66,8 +68,8 @@ class MutableSelectionStateTest : SysuiTestCase() { val spec = TileSpec.create("testSpec") // Resizing starts with a selected tile underTest.select(spec) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) {} underTest.select(spec, manual = true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) assertThat(underTest.resizingState).isNotNull() underTest.onResizingDragEnd() Loading @@ -77,8 +79,8 @@ class MutableSelectionStateTest : SysuiTestCase() { @Test fun unselect_clearsResizingState() { // Resizing starts with a selected tile underTest.select(TEST_SPEC) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) {} underTest.select(TEST_SPEC, manual = true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) assertThat(underTest.resizingState).isNotNull() underTest.unSelect() Loading @@ -88,8 +90,8 @@ class MutableSelectionStateTest : SysuiTestCase() { @Test fun onResizingDrag_updatesResizingState() { // Resizing starts with a selected tile underTest.select(TEST_SPEC) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) {} underTest.select(TEST_SPEC, manual = true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) assertThat(underTest.resizingState).isNotNull() underTest.onResizingDrag(5f) Loading @@ -105,11 +107,15 @@ class MutableSelectionStateTest : SysuiTestCase() { @Test fun onResizingDrag_receivesResizeCallback() { var resized = false val onResize: () -> Unit = { resized = !resized } val onResize: (TileSpec) -> Unit = { assertThat(it).isEqualTo(TEST_SPEC) resized = !resized } val underTest = MutableSelectionState(onResize = onResize, {}) // Resizing starts with a selected tile underTest.select(TEST_SPEC) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10), onResize) underTest.select(TEST_SPEC, true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) assertThat(underTest.resizingState).isNotNull() // Drag under the threshold Loading @@ -125,6 +131,37 @@ class MutableSelectionStateTest : SysuiTestCase() { assertThat(resized).isFalse() } @Test fun onResizingEnded_receivesResizeEndCallback() { var resizeEnded = false val onResizeEnd: (TileSpec) -> Unit = { resizeEnded = true } val underTest = MutableSelectionState({}, onResizeEnd = onResizeEnd) // Resizing starts with a selected tile underTest.select(TEST_SPEC, true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) underTest.onResizingDragEnd() assertThat(resizeEnded).isTrue() } @Test fun onResizingEnded_setsSelectionAutomatically() { val underTest = MutableSelectionState({}, {}) // Resizing starts with a selected tile underTest.select(TEST_SPEC, manual = true) underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10)) // Assert the selection was manual assertThat(underTest.selection?.manual).isTrue() underTest.onResizingDragEnd() // Assert the selection is no longer manual due to the resizing assertThat(underTest.selection?.manual).isFalse() } companion object { private val TEST_SPEC = TileSpec.create("testSpec") } Loading
packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractor.kt +6 −5 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ constructor( private val currentTilesInteractor: CurrentTilesInteractor, private val preferencesInteractor: QSPreferencesInteractor, @PanelsLog private val logBuffer: LogBuffer, @Application private val applicationScope: CoroutineScope @Application private val applicationScope: CoroutineScope, ) { val largeTilesSpecs = Loading @@ -64,14 +64,15 @@ constructor( fun isIconTile(spec: TileSpec): Boolean = !largeTilesSpecs.value.contains(spec) fun resize(spec: TileSpec) { fun resize(spec: TileSpec, toIcon: Boolean) { if (!isCurrent(spec)) { return } if (largeTilesSpecs.value.contains(spec)) { val isIcon = !largeTilesSpecs.value.contains(spec) if (toIcon && !isIcon) { preferencesInteractor.setLargeTilesSpecs(largeTilesSpecs.value - spec) } else { } else if (!toIcon && isIcon) { preferencesInteractor.setLargeTilesSpecs(largeTilesSpecs.value + spec) } } Loading @@ -85,7 +86,7 @@ constructor( LOG_BUFFER_LARGE_TILES_SPECS_CHANGE_TAG, LogLevel.DEBUG, { str1 = specs.toString() }, { "Large tiles change: $str1" } { "Large tiles change: $str1" }, ) } Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt +50 −8 Original line number Diff line number Diff line Loading @@ -60,10 +60,37 @@ class EditTileListState(tiles: List<SizedTile<EditTileViewModel>>, private val c return _tiles.filterIsInstance<TileGridCell>().map { it.tile.tileSpec } } fun indexOf(tileSpec: TileSpec): Int { private fun indexOf(tileSpec: TileSpec): Int { return _tiles.indexOfFirst { it is TileGridCell && it.tile.tileSpec == tileSpec } } /** * Whether the tile with this [TileSpec] is currently an icon in the [EditTileListState] * * @return true if the tile is an icon, false if it's large, null if the tile isn't in the list */ fun isIcon(tileSpec: TileSpec): Boolean? { val index = indexOf(tileSpec) return if (index != -1) { val cell = _tiles[index] cell as TileGridCell return cell.isIcon } else { null } } /** Toggle the size of the tile corresponding to the [TileSpec] */ fun toggleSize(tileSpec: TileSpec) { val fromIndex = indexOf(tileSpec) if (fromIndex != -1) { val cell = _tiles.removeAt(fromIndex) cell as TileGridCell _tiles.add(fromIndex, cell.copy(width = if (cell.isIcon) 2 else 1)) regenerateGrid(fromIndex) } } override fun isMoving(tileSpec: TileSpec): Boolean { return _draggedCell.value?.let { it.tile.tileSpec == tileSpec } ?: false } Loading @@ -71,8 +98,8 @@ class EditTileListState(tiles: List<SizedTile<EditTileViewModel>>, private val c override fun onStarted(cell: SizedTile<EditTileViewModel>) { _draggedCell.value = cell // Add visible spacers to the grid to indicate where the user can move a tile regenerateGrid(includeSpacers = true) // Add spacers to the grid to indicate where the user can move a tile regenerateGrid() } override fun onMoved(target: Int, insertAfter: Boolean) { Loading @@ -86,7 +113,7 @@ class EditTileListState(tiles: List<SizedTile<EditTileViewModel>>, private val c val insertionIndex = if (insertAfter) target + 1 else target if (fromIndex != -1) { val cell = _tiles.removeAt(fromIndex) regenerateGrid(includeSpacers = true) regenerateGrid() _tiles.add(insertionIndex.coerceIn(0, _tiles.size), cell) } else { // Add the tile with a temporary row which will get reassigned when Loading @@ -94,7 +121,7 @@ class EditTileListState(tiles: List<SizedTile<EditTileViewModel>>, private val c _tiles.add(insertionIndex.coerceIn(0, _tiles.size), TileGridCell(draggedTile, 0)) } regenerateGrid(includeSpacers = true) regenerateGrid() } override fun movedOutOfBounds() { Loading @@ -109,12 +136,27 @@ class EditTileListState(tiles: List<SizedTile<EditTileViewModel>>, private val c _draggedCell.value = null // Remove the spacers regenerateGrid(includeSpacers = false) regenerateGrid() } private fun regenerateGrid(includeSpacers: Boolean) { _tiles.filterIsInstance<TileGridCell>().toGridCells(columns, includeSpacers).let { /** Regenerate the list of [GridCell] with their new potential rows */ private fun regenerateGrid() { _tiles.filterIsInstance<TileGridCell>().toGridCells(columns).let { _tiles.clear() _tiles.addAll(it) } } /** * Regenerate the list of [GridCell] with their new potential rows from [fromIndex], leaving * cells before that untouched. */ private fun regenerateGrid(fromIndex: Int) { val fromRow = _tiles[fromIndex].row val (pre, post) = _tiles.partition { it.row < fromRow } post.filterIsInstance<TileGridCell>().toGridCells(columns, startingRow = fromRow).let { _tiles.clear() _tiles.addAll(pre) _tiles.addAll(it) } } Loading