Skip to content

Commit

Permalink
implemented redo (to be tested)
Browse files Browse the repository at this point in the history
  • Loading branch information
pier-bezuhoff committed Jan 24, 2024
1 parent a785ea9 commit 397853c
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 7 deletions.
3 changes: 3 additions & 0 deletions composeApp/src/commonMain/kotlin/ui/EditClusterScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ fun EditClusterTopBar(
IconButton(onClick = viewModel::undo) {
Icon(painterResource("icons/undo.xml"), contentDescription = "Undo")
}
IconButton(onClick = viewModel::redo) {
Icon(painterResource("icons/redo.xml"), contentDescription = "Redo")
}
// IconButton(onClick = viewModel::cancelAndGoBack) {
// Icon(Icons.Default.Close, contentDescription = "Cancel")
// }
Expand Down
34 changes: 28 additions & 6 deletions composeApp/src/commonMain/kotlin/ui/EditClusterViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ class EditClusterViewModel(
val handleIsDown = mutableStateOf(false)
val grabbedCircleIx = mutableStateOf<Int?>(null)

// tagged & grouped gap buffer
private val commands = ArrayDeque<Command>(HISTORY_SIZE)
private val redoCommands = ArrayDeque<Command>(HISTORY_SIZE)
// we group history by commands and record it only when the new command differs from the previous one
// NOTE: history doesn't survive background app kill
// TODO: redo stack
private val history = ArrayDeque<UiState>(HISTORY_SIZE)
private val redoHistory = ArrayDeque<UiState>(HISTORY_SIZE)

private val _decayingCircles = MutableSharedFlow<DecayingCircles>()
val decayingCircles = _decayingCircles.asSharedFlow()
Expand Down Expand Up @@ -94,14 +96,32 @@ class EditClusterViewModel(
fun undo() {
if (history.size > 1) {
val previousState = history.removeLast()
val previousCommand = commands.removeLast()
selection.clear()
parts.clear()
circles.clear()
circles.addAll(previousState.circles)
parts.addAll(previousState.parts)
switchSelectionMode(previousState.selectionMode)
selection.addAll(previousState.selection)
commands.removeLast()
redoCommands.addFirst(previousCommand)
redoHistory.addFirst(previousState)
}
}

fun redo() {
if (redoHistory.isNotEmpty()) {
val nextState = redoHistory.removeFirst()
val nextCommand = redoCommands.removeFirst()
selection.clear()
parts.clear()
circles.clear()
circles.addAll(nextState.circles)
parts.addAll(nextState.parts)
switchSelectionMode(nextState.selectionMode)
selection.addAll(nextState.selection)
commands.addLast(nextCommand)
history.addLast(nextState)
}
}

Expand All @@ -111,9 +131,11 @@ class EditClusterViewModel(
history.removeFirst()
commands.removeFirst()
}
history.add(UiState.save(this))
commands.add(command)
history.addLast(UiState.save(this))
commands.addLast(command)
}
redoCommands.clear()
redoHistory.clear()
}

suspend fun createNewCircle() {
Expand Down Expand Up @@ -198,11 +220,11 @@ class EditClusterViewModel(
selection.clear()
} else if (selectionMode.value == SelectionMode.SelectRegion && newMode == SelectionMode.SelectRegion) {
if (parts.isEmpty()) {
recordCommand(Command.SELECT_PART)
// recordCommand(Command.SELECT_PART)
// select interlacing, todo: proper 2^n -> even # of 1's -> {0101001} -> parts
parts.add(Cluster.Part(emptySet(), circles.indices.toSet()))
} else {
recordCommand(Command.SELECT_PART)
// recordCommand(Command.SELECT_PART)
parts.clear()
}
}
Expand Down
3 changes: 2 additions & 1 deletion composeApp/src/wasmJsMain/kotlin/data/io/OpenFile.wasmJs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ actual fun OpenFileButton(
fun queryFile(callback: (file: File?) -> Unit) {
val input = document.createElement("input") as HTMLInputElement
input.type = "file"
input.accept = "text/plain"
// input.accept = "text/plain" // doesnt detect custom formats
// input.accept = "*/*"
input.onchange = { event ->
val file = input.files?.get(0)
// val file = extractFileFromEvent(event)
Expand Down
2 changes: 2 additions & 0 deletions composeApp/src/wasmJsMain/kotlin/data/io/SaveFile.wasmJs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ actual fun SaveFileButton(
}
}

// showSaveFilePicker() is still experimental, cmon js bros...

// global js function
external fun encodeURIComponent(str: String): String

Expand Down
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ kotlinx-serialization = "1.6.2"
compose = "1.5.4"
compose-compiler = "1.5.6"
compose-plugin = "1.6.0-alpha01"
material3 = "1.1.2"
junit = "4.13.2"
#noinspection GradleDependency
kotlin = "1.9.21"
Expand All @@ -34,6 +35,8 @@ compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref =
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" }
compose-material = { module = "androidx.compose.material:material", version.ref = "compose" }
compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
compose-material3-window-size-klass = { module = "androidx.compose.material3:material3-window-size-class", version.ref = "material3" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization"}

[plugins]
Expand Down

0 comments on commit 397853c

Please sign in to comment.