96 lines
2.1 KiB
Swift
96 lines
2.1 KiB
Swift
//
|
|
// TaskList.swift
|
|
// Subtasks
|
|
//
|
|
|
|
import Adwaita
|
|
|
|
struct TaskList: View {
|
|
|
|
@Binding var tasks: [Task]
|
|
@State private var showAddDialog = false
|
|
@State private var addDialogText = ""
|
|
@State private var focusEntry: Signal = .init()
|
|
var app: AdwaitaApp
|
|
|
|
var view: Body {
|
|
ScrollView {
|
|
list
|
|
}
|
|
.topToolbar {
|
|
HeaderBar.start {
|
|
Button(icon: .default(icon: .listAdd)) {
|
|
showAddDialog = true
|
|
focusEntry.signal()
|
|
}
|
|
.keyboardShortcut("n".ctrl(), app: app)
|
|
}
|
|
}
|
|
.dialog(visible: $showAddDialog, id: "add") {
|
|
dialog
|
|
}
|
|
}
|
|
|
|
var list: AnyView {
|
|
List(tasks, selection: nil) { task in
|
|
taskRow(task: task)
|
|
}
|
|
.boxedList()
|
|
.valign(.start)
|
|
.padding(20)
|
|
.frame(maxWidth: 500)
|
|
}
|
|
|
|
var dialog: AnyView {
|
|
Form {
|
|
EntryRow("Label", text: $addDialogText)
|
|
.entryActivated {
|
|
add()
|
|
}
|
|
.frame(minWidth: 250)
|
|
.focus(focusEntry)
|
|
}
|
|
.padding(20)
|
|
.valign(.start)
|
|
.topToolbar {
|
|
HeaderBar {
|
|
Button("Cancel") {
|
|
cancel()
|
|
}
|
|
} end: {
|
|
Button("Add") {
|
|
add()
|
|
}
|
|
.suggested()
|
|
}
|
|
.showEndTitleButtons(false)
|
|
}
|
|
}
|
|
|
|
func taskRow(task: Task) -> AnyView {
|
|
ActionRow()
|
|
.title(task.label)
|
|
.prefix {
|
|
CheckButton()
|
|
.active($tasks[id: task.id, default: .init(label: "")].done)
|
|
.selectionMode()
|
|
.valign(.center)
|
|
}
|
|
.suffix {
|
|
ButtonContent()
|
|
.iconName(Icon.default(icon: .goNext).string)
|
|
}
|
|
}
|
|
|
|
func cancel() {
|
|
showAddDialog = false
|
|
addDialogText = ""
|
|
}
|
|
|
|
func add() {
|
|
tasks.append(.init(label: addDialogText))
|
|
cancel()
|
|
}
|
|
|
|
}
|