diff --git a/selector/common/src/commonMain/kotlin/dev/inmo/micro_utils/selector/Selector.kt b/selector/common/src/commonMain/kotlin/dev/inmo/micro_utils/selector/Selector.kt index ed0366096e5..ae55738447e 100644 --- a/selector/common/src/commonMain/kotlin/dev/inmo/micro_utils/selector/Selector.kt +++ b/selector/common/src/commonMain/kotlin/dev/inmo/micro_utils/selector/Selector.kt @@ -12,12 +12,21 @@ interface Selector { val itemUnselected: SharedFlow suspend fun toggleSelection(element: T) + suspend fun forceSelect(element: T) + suspend fun forceDeselect(element: T) + suspend fun clearSelection() } @Suppress("NOTHING_TO_INLINE") inline operator fun Selector.contains(element: T) = selectedItems.contains(element) @Suppress("NOTHING_TO_INLINE") inline fun Selector.nothingSelected(): Boolean = selectedItems.isEmpty() +suspend inline fun Selector.toggleSelection(elements: List) = elements.forEach { toggleSelection(it) } +suspend inline fun Selector.forceSelect(elements: List) = elements.forEach { forceSelect(it) } +suspend inline fun Selector.forceDeselect(elements: List) = elements.forEach { forceDeselect(it) } +suspend inline fun Selector.toggleSelection(firstElement: T, vararg elements: T) = toggleSelection(listOf(firstElement) + elements.toList()) +suspend inline fun Selector.forceSelect(firstElement: T, vararg elements: T) = forceSelect(listOf(firstElement) + elements.toList()) +suspend inline fun Selector.forceDeselect(firstElement: T, vararg elements: T) = forceDeselect(listOf(firstElement) + elements.toList()) /** * Realization of [Selector] with one or without selected element. This realization will always have empty @@ -48,6 +57,24 @@ class SingleSelector( null } + override suspend fun forceDeselect(element: T) { + mutex ?.lock() + if (selectedItem == element) { + selectedItem = null + _itemUnselected.emit(element) + } + mutex ?.unlock() + } + + override suspend fun forceSelect(element: T) { + mutex ?.lock() + if (selectedItem != element) { + selectedItem = element + _itemSelected.emit(element) + } + mutex ?.unlock() + } + override suspend fun toggleSelection(element: T) { mutex ?.lock() if (selectedItem == element) { @@ -64,6 +91,10 @@ class SingleSelector( } mutex ?.unlock() } + + override suspend fun clearSelection() { + selectedItem ?.let { forceDeselect(it) } + } } /** @@ -90,6 +121,22 @@ class MultipleSelector( null } + override suspend fun forceDeselect(element: T) { + mutex ?.lock() + if (_selectedItems.remove(element)) { + _itemUnselected.emit(element) + } + mutex ?.unlock() + } + + override suspend fun forceSelect(element: T) { + mutex ?.lock() + if (element !in _selectedItems && _selectedItems.add(element)) { + _itemSelected.emit(element) + } + mutex ?.unlock() + } + override suspend fun toggleSelection(element: T) { mutex ?.lock() if (_selectedItems.remove(element)) { @@ -100,6 +147,14 @@ class MultipleSelector( } mutex ?.unlock() } + + override suspend fun clearSelection() { + mutex ?.lock() + val preSelectedItems = _selectedItems.toList() + _selectedItems.clear() + preSelectedItems.forEach { _itemUnselected.emit(it) } + mutex ?.unlock() + } } @Suppress("FunctionName", "NOTHING_TO_INLINE")