Make the row checkbox select items instead of ticking them off
The checkbox was marking items done, but the intent was to gather items and act on them: tick several, then right-click to copy, copy as a list, move, merge or delete them all at once. Done is still available from the same menu, it is just no longer what the checkbox does.
This commit is contained in:
@@ -193,20 +193,20 @@ struct PanelView: View {
|
||||
.padding(.vertical, 48)
|
||||
}
|
||||
|
||||
/// Rows are checklists by default: a checkbox to tick an item off, with the
|
||||
/// rest of the row copying on click. The row cannot be a Button because the
|
||||
/// checkbox is one, and nested buttons do not receive clicks.
|
||||
/// Rows carry a checkbox that *selects* the item, so a selection can be
|
||||
/// copied or deleted from the context menu. The row cannot be a Button
|
||||
/// because the checkbox is one, and nested buttons do not receive clicks.
|
||||
private func row(for item: PromptItem, sectionName: String) -> some View {
|
||||
HStack(alignment: .top, spacing: 8) {
|
||||
Button {
|
||||
store.toggleDone(item.id)
|
||||
toggleSelection(item.id)
|
||||
} label: {
|
||||
Image(systemName: item.done ? "checkmark.circle.fill" : "circle")
|
||||
Image(systemName: selection.contains(item.id) ? "checkmark.circle.fill" : "circle")
|
||||
.font(.system(size: 15))
|
||||
.foregroundStyle(item.done ? Color.accentColor : Color.secondary.opacity(0.55))
|
||||
.foregroundStyle(selection.contains(item.id) ? Color.accentColor : Color.secondary.opacity(0.55))
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help(item.done ? "Mark as not done" : "Mark as done")
|
||||
.help(selection.contains(item.id) ? "Deselect" : "Select for copy or delete")
|
||||
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
if !sectionName.isEmpty {
|
||||
@@ -278,43 +278,51 @@ struct PanelView: View {
|
||||
}
|
||||
|
||||
private func contextMenu(for item: PromptItem) -> some View {
|
||||
Group {
|
||||
let ids = effectiveIDs(for: item)
|
||||
let multiple = ids.count > 1
|
||||
return Group {
|
||||
Button("Copy") { copy(item) }
|
||||
Button("Copy as List") {
|
||||
store.copyAsList(ids: effectiveIDs(for: item))
|
||||
Button(multiple ? "Copy \(ids.count) as List" : "Copy as List") {
|
||||
store.copyAsList(ids: ids)
|
||||
flashCopied(item.id)
|
||||
}
|
||||
Button("Copy as Lines") {
|
||||
store.copyAsLines(ids: effectiveIDs(for: item))
|
||||
Button(multiple ? "Copy \(ids.count) as Lines" : "Copy as Lines") {
|
||||
store.copyAsLines(ids: ids)
|
||||
flashCopied(item.id)
|
||||
}
|
||||
Divider()
|
||||
Button(item.done ? "Mark as Not Done" : "Mark as Done") { store.toggleDone(item.id) }
|
||||
if case .text(let text) = item.content {
|
||||
Button(item.done ? "Mark as Not Done" : "Mark as Done") {
|
||||
store.setDone(!item.done, ids: ids)
|
||||
}
|
||||
if case .text(let text) = item.content, !multiple {
|
||||
Button("Edit…") {
|
||||
PanelController.shared.editController.edit(itemID: item.id, text: text)
|
||||
}
|
||||
}
|
||||
if case .image(let filename) = item.content {
|
||||
if case .image(let filename) = item.content, !multiple {
|
||||
Button("Open") {
|
||||
NSWorkspace.shared.open(store.imageURL(for: filename))
|
||||
}
|
||||
}
|
||||
if selection.count > 1, selection.contains(item.id) {
|
||||
if multiple {
|
||||
Button("Merge Notes") {
|
||||
store.merge(ids: selection)
|
||||
store.merge(ids: ids)
|
||||
clearSelection()
|
||||
}
|
||||
}
|
||||
Menu("Move To") {
|
||||
ForEach(store.sections.filter { $0.id != store.sectionID(of: item.id) }) { section in
|
||||
Button(section.name) { store.move(item.id, to: section.id) }
|
||||
Button(section.name) {
|
||||
store.move(ids: ids, to: section.id)
|
||||
if multiple { clearSelection() }
|
||||
}
|
||||
}
|
||||
}
|
||||
Divider()
|
||||
Button("Delete", role: .destructive) {
|
||||
selection.remove(item.id)
|
||||
store.delete(item.id)
|
||||
Button(multiple ? "Delete \(ids.count) Items" : "Delete", role: .destructive) {
|
||||
store.delete(ids: ids)
|
||||
selection.subtract(ids)
|
||||
lastSelectedID = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -664,12 +672,7 @@ struct PanelView: View {
|
||||
private func handleClick(_ item: PromptItem) {
|
||||
let modifiers = NSApp.currentEvent?.modifierFlags ?? []
|
||||
if modifiers.contains(.command) {
|
||||
if selection.contains(item.id) {
|
||||
selection.remove(item.id)
|
||||
} else {
|
||||
selection.insert(item.id)
|
||||
}
|
||||
lastSelectedID = item.id
|
||||
toggleSelection(item.id)
|
||||
return
|
||||
}
|
||||
if modifiers.contains(.shift), let anchor = lastSelectedID, anchor != item.id {
|
||||
@@ -679,6 +682,15 @@ struct PanelView: View {
|
||||
copy(item)
|
||||
}
|
||||
|
||||
private func toggleSelection(_ id: UUID) {
|
||||
if selection.contains(id) {
|
||||
selection.remove(id)
|
||||
} else {
|
||||
selection.insert(id)
|
||||
}
|
||||
lastSelectedID = id
|
||||
}
|
||||
|
||||
private func selectRange(from anchor: UUID, to target: UUID) {
|
||||
let ids = displayedItems.map(\.item.id)
|
||||
guard let start = ids.firstIndex(of: anchor), let end = ids.firstIndex(of: target) else { return }
|
||||
|
||||
Reference in New Issue
Block a user