Reduce cyclomatic complexity
This commit is contained in:
@@ -2,6 +2,7 @@ package ch.dissem.yaep.ui.common
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
@@ -61,74 +62,114 @@ private fun PuzzleRow(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.wrapContentHeight()
|
.wrapContentHeight()
|
||||||
) {
|
) {
|
||||||
val allOptions = row.options
|
|
||||||
for (cell in row) {
|
for (cell in row) {
|
||||||
var selection by remember(cell) { mutableStateOf(cell.selection) }
|
PuzzleCell(
|
||||||
val options = remember(cell) {
|
cell,
|
||||||
allOptions.map { Toggleable(it, cell.options.contains(it)) }
|
row,
|
||||||
}
|
onUpdate,
|
||||||
LaunchedEffect(cell) {
|
onSnapshot,
|
||||||
cell.optionsChangedListeners.add { enabled ->
|
onUndo,
|
||||||
options.forEach { it.enabled = enabled.contains(it.item) }
|
|
||||||
}
|
|
||||||
cell.selectionChangedListeners.add {
|
|
||||||
selection = it
|
|
||||||
onUpdate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val focusable = remember(cell, selectionManager) {
|
|
||||||
selectionManager.add { e ->
|
|
||||||
if (selection != null) {
|
|
||||||
when (e.key) {
|
|
||||||
Key.Spacebar, Key.Enter, Key.Delete, Key.Backspace -> {
|
|
||||||
onSelectItem(row, cell, options, null, onSnapshot, onUndo)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val i = getNumber(e)
|
|
||||||
if (i != null && i in 1..options.size) {
|
|
||||||
val selectedItem = options[i - 1].item
|
|
||||||
if (e.isShiftPressed) {
|
|
||||||
if (cell.options.contains(selectedItem)) {
|
|
||||||
onOptionRemoved(row, cell, selectedItem, onSnapshot)
|
|
||||||
} else {
|
|
||||||
cell.options.add(selectedItem)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
onSelectItem(row, cell, options, selectedItem, onSnapshot, onUndo)
|
|
||||||
}
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Selector(
|
|
||||||
modifier = Modifier
|
|
||||||
.focus(focusable)
|
|
||||||
.padding(spacing)
|
|
||||||
.weight(1f),
|
|
||||||
spacing,
|
spacing,
|
||||||
options = options,
|
selectionManager
|
||||||
onOptionRemoved = { selectedItem ->
|
|
||||||
onOptionRemoved(row, cell, selectedItem, onSnapshot)
|
|
||||||
},
|
|
||||||
onOptionAdded = {
|
|
||||||
cell.options.add(it)
|
|
||||||
},
|
|
||||||
selectedItem = selection,
|
|
||||||
onSelectItem = { selectedItem ->
|
|
||||||
onSelectItem(row, cell, options, selectedItem, onSnapshot, onUndo)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun RowScope.PuzzleCell(
|
||||||
|
cell: GameCell<ItemClass<*>>,
|
||||||
|
row: GameRow<ItemClass<*>>,
|
||||||
|
onUpdate: () -> Unit,
|
||||||
|
onSnapshot: () -> Unit,
|
||||||
|
onUndo: () -> Boolean,
|
||||||
|
spacing: Dp,
|
||||||
|
selectionManager: GridSelectionManager
|
||||||
|
) {
|
||||||
|
var selection by remember(cell) { mutableStateOf(cell.selection) }
|
||||||
|
val options = remember(cell) {
|
||||||
|
row.options.map { Toggleable(it, cell.options.contains(it)) }
|
||||||
|
}
|
||||||
|
LaunchedEffect(cell) {
|
||||||
|
cell.optionsChangedListeners.add { enabled ->
|
||||||
|
options.forEach { it.enabled = enabled.contains(it.item) }
|
||||||
|
}
|
||||||
|
cell.selectionChangedListeners.add {
|
||||||
|
selection = it
|
||||||
|
onUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val focusable = remember(cell, selectionManager) {
|
||||||
|
selectionManager.add { e ->
|
||||||
|
if (selection != null) {
|
||||||
|
handleClearSelection(e.key, row, cell, options, onSnapshot, onUndo)
|
||||||
|
} else {
|
||||||
|
handleSelection(e, options, cell, row, onSnapshot, onUndo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Selector(
|
||||||
|
modifier = Modifier
|
||||||
|
.focus(focusable)
|
||||||
|
.padding(spacing)
|
||||||
|
.weight(1f),
|
||||||
|
spacing,
|
||||||
|
options = options,
|
||||||
|
onOptionRemoved = { selectedItem ->
|
||||||
|
onOptionRemoved(row, cell, selectedItem, onSnapshot)
|
||||||
|
},
|
||||||
|
onOptionAdded = {
|
||||||
|
cell.options.add(it)
|
||||||
|
},
|
||||||
|
selectedItem = selection,
|
||||||
|
onSelectItem = { selectedItem ->
|
||||||
|
onSelectItem(row, cell, options, selectedItem, onSnapshot, onUndo)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleSelection(
|
||||||
|
e: KeyEvent,
|
||||||
|
options: List<Toggleable<Item<ItemClass<*>>>>,
|
||||||
|
cell: GameCell<ItemClass<*>>,
|
||||||
|
row: GameRow<ItemClass<*>>,
|
||||||
|
onSnapshot: () -> Unit,
|
||||||
|
onUndo: () -> Boolean
|
||||||
|
): Boolean {
|
||||||
|
val i = getNumber(e)
|
||||||
|
return if (i != null && i in 1..options.size) {
|
||||||
|
val selectedItem = options[i - 1].item
|
||||||
|
if (e.isShiftPressed) {
|
||||||
|
if (cell.options.contains(selectedItem)) {
|
||||||
|
onOptionRemoved(row, cell, selectedItem, onSnapshot)
|
||||||
|
} else {
|
||||||
|
cell.options.add(selectedItem)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onSelectItem(row, cell, options, selectedItem, onSnapshot, onUndo)
|
||||||
|
}
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleClearSelection(
|
||||||
|
key: Key,
|
||||||
|
row: GameRow<ItemClass<*>>,
|
||||||
|
cell: GameCell<ItemClass<*>>,
|
||||||
|
options: List<Toggleable<Item<ItemClass<*>>>>,
|
||||||
|
onSnapshot: () -> Unit,
|
||||||
|
onUndo: () -> Boolean
|
||||||
|
): Boolean = when (key) {
|
||||||
|
Key.Spacebar, Key.Enter, Key.Delete, Key.Backspace -> {
|
||||||
|
onSelectItem(row, cell, options, null, onSnapshot, onUndo)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
private fun onOptionRemoved(
|
private fun onOptionRemoved(
|
||||||
row: GameRow<ItemClass<*>>,
|
row: GameRow<ItemClass<*>>,
|
||||||
cell: GameCell<ItemClass<*>>,
|
cell: GameCell<ItemClass<*>>,
|
||||||
|
|||||||
Reference in New Issue
Block a user