Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions apple/App/DraftCard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ final class DraftCard: NSView, NSTextViewDelegate, NSTextFieldDelegate {
private func refresh() {
let body = AppFont.native(.body)
// A task that does not exist yet has nothing to complete: the mark only says what the card is.
mark.image = .symbol("square", body)
mark.image = .symbol("circle", body)
title.font = body
titlePlaceholder.font = body
titlePlaceholder.isHidden = !title.string.isEmpty
Expand Down Expand Up @@ -487,7 +487,7 @@ final class DraftCard: NSView, NSTextViewDelegate, NSTextFieldDelegate {
subtaskLines.append((mark, field, remove))
}
for (index, line) in subtaskLines.enumerated() {
line.mark.image = .symbol("square", font, weight: .light)
line.mark.image = .symbol("circle", font, weight: .light)
line.field.font = font
if !editing(line.field), line.field.stringValue != draft.subtasks[index] { line.field.stringValue = draft.subtasks[index] }
line.remove.image = .symbol("xmark.circle.fill", font)
Expand Down Expand Up @@ -770,7 +770,7 @@ final class DraftCard: NSView, NSTextViewDelegate, NSTextFieldDelegate {
let markSize = mark.image?.size ?? .zero
f.mark = NSRect(x: insets.left, y: y + (line - markSize.height) / 2, width: markSize.width, height: markSize.height)
// In the list the title keeps the place a row gives it after the bar of the priority.
let titleX = f.mark.maxX + 8 + (footer ? 0 : 3 + 8)
let titleX = f.mark.maxX + (footer ? 8 : TaskTableMetrics.markGap + 3 + TaskTableMetrics.barGap)
let parsedWidth = parsed.stops.isEmpty ? 0 : min(parsed.stops.reduce(0) { $0 + $1.intrinsicContentSize.width + 6 }, (right - titleX) / 2)
let titleWidth = max(right - titleX - (parsedWidth > 0 ? parsedWidth + 8 : 0), 1)
let titleHeight = textHeight(title, width: titleWidth)
Expand Down
2 changes: 1 addition & 1 deletion apple/App/ListsApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ struct MenuBarView: View {
VStack(alignment: .leading, spacing: 6) {
ForEach(today.prefix(12), id: \.id) { task in
HStack(alignment: .firstTextBaseline, spacing: 8) {
Button { model.toggleDone(task) } label: { Image(systemName: "square") }
Button { model.toggleDone(task) } label: { Image(systemName: "circle") }
.buttonStyle(.plain)
.accessibilityLabel(L("Complete"))
Text(task.title).lineLimit(1)
Expand Down
4 changes: 2 additions & 2 deletions apple/App/TaskCard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -629,9 +629,9 @@ final class TaskCard: NSView, NSTextViewDelegate {
let headerTop = Self.margin + Self.padding.top + 6
let markSize = mark.fittingSize
frames.mark = NSRect(x: x, y: headerTop + (line - markSize.height) / 2, width: markSize.width, height: markSize.height)
x += markSize.width + 8
x += markSize.width + TaskTableMetrics.markGap
frames.bar = NSRect(x: x, y: headerTop + (line - 16) / 2, width: 3, height: 16)
x += 3 + 8
x += 3 + TaskTableMetrics.barGap
if !folder.isHidden {
let size = folder.image?.size ?? .zero
frames.folder = NSRect(x: x, y: headerTop + (line - size.height) / 2, width: size.width, height: size.height)
Expand Down
44 changes: 27 additions & 17 deletions apple/App/TaskRowCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ enum TaskTableMetrics {
/// How far a task of an open project stands to the right of the project (R30).
static let depthIndent: CGFloat = 22

/// R72: the space after the mark and after the bar of the priority, shared by the row and the open card, so the
/// title stays close to the mark (#427).
static let markGap: CGFloat = 3
static let barGap: CGFloat = 4

/// The field for a new task of an open project.
static func newChildRow() -> CGFloat { lineHeight(AppFont.native(.callout)) + 8 + 2 * rowInset }

Expand Down Expand Up @@ -78,7 +83,7 @@ extension NSImage {
}
}

/// The square mark of a task or of a subtask: a click completes it or takes it back into work.
/// The round mark of a task or of a subtask (#427): a click completes it or takes it back into work.
@MainActor
final class TaskMarkButton: NSButton {
private var task: TaskItem?
Expand All @@ -96,7 +101,7 @@ final class TaskMarkButton: NSButton {
self.task = task
// The mark of a record of a repeat takes its completion back while it can (R128, R133); after that it is a repeat icon.
let history = task.isLog && !task.undoable
let symbol = history ? "repeat" : task.wont ? "xmark.square.fill" : task.done != nil ? "checkmark.square.fill" : "square"
let symbol = history ? "repeat" : task.wont ? "xmark.circle.fill" : task.done != nil ? "checkmark.circle.fill" : "circle"
// R94: the mark is as quiet as the icons of the fields; R72: a little smaller than the text.
image = .symbol(symbol, AppFont.native(.callout), weight: .light)
contentTintColor = task.done != nil ? .secondaryLabelColor : .tertiaryLabelColor
Expand Down Expand Up @@ -254,17 +259,27 @@ final class TaskRowCell: NSTableCellView {
let inset: CGFloat = 6
let gap: CGFloat = 8
var x = inset + CGFloat(depth) * TaskTableMetrics.depthIndent
func center(_ view: NSView, width: CGFloat, height viewHeight: CGFloat) {
view.frame = NSRect(x: x, y: ((height - viewHeight) / 2).rounded(), width: width, height: viewHeight)
x += width + gap
}
let markSize = mark.fittingSize
center(mark, width: markSize.width, height: markSize.height)

// The title and the list under it stand as one block in the middle of the row; the mark, the project icon and
// the date stand at the middle of the title line, so in a row of two lines they go with the title (#427).
let titleHeight = TaskTableMetrics.lineHeight(AppFont.native(.body))
let originHeight = TaskTableMetrics.lineHeight(AppFont.native(.caption))
let twoLines = !origin.isHidden
center(bar, width: 3, height: twoLines ? 28 : 16)
let block = twoLines ? titleHeight + 2 + originHeight : titleHeight
let top = ((height + block) / 2).rounded()
let titleY = top - titleHeight
func onTitle(_ viewHeight: CGFloat) -> CGFloat { (titleY + (titleHeight - viewHeight) / 2).rounded() }

let markSize = mark.fittingSize
mark.frame = NSRect(x: x, y: onTitle(markSize.height), width: markSize.width, height: markSize.height)
x += markSize.width + TaskTableMetrics.markGap
let barHeight: CGFloat = twoLines ? 28 : 16
bar.frame = NSRect(x: x, y: ((height - barHeight) / 2).rounded(), width: 3, height: barHeight)
x += 3 + TaskTableMetrics.barGap
if !folder.isHidden {
let size = folder.image?.size ?? .zero
center(folder, width: size.width, height: size.height)
folder.frame = NSRect(x: x, y: onTitle(size.height), width: size.width, height: size.height)
x += size.width + gap
}

// From the right edge: the chevron, then the date.
Expand All @@ -274,25 +289,20 @@ final class TaskRowCell: NSTableCellView {
if !date.isHidden {
right -= gap
let size = date.fittingSize
date.frame = NSRect(x: right - size.width, y: ((height - size.height) / 2).rounded(), width: size.width, height: size.height)
date.frame = NSRect(x: right - size.width, y: onTitle(size.height), width: size.width, height: size.height)
right -= size.width
if !dateIcon.isHidden {
let icon = dateIcon.image?.size ?? .zero
right -= 3 + icon.width
dateIcon.frame = NSRect(x: right, y: ((height - icon.height) / 2).rounded(), width: icon.width, height: icon.height)
dateIcon.frame = NSRect(x: right, y: onTitle(icon.height), width: icon.width, height: icon.height)
}
}
right -= gap

// The title and its marks, and under them the list; each is cut at its own width.
let titleHeight = TaskTableMetrics.lineHeight(AppFont.native(.body))
let originHeight = TaskTableMetrics.lineHeight(AppFont.native(.caption))
let block = twoLines ? titleHeight + 2 + originHeight : titleHeight
let top = ((height + block) / 2).rounded()
let marksWidth = marks.arrangedSubviews.isEmpty ? 0 : marks.fittingSize.width
let room = max(right - x, 0)
let titleWidth = min(title.fittingSize.width, max(room - (marksWidth > 0 ? marksWidth + gap : 0), 0))
let titleY = top - titleHeight
title.frame = NSRect(x: x, y: titleY, width: titleWidth, height: titleHeight)
marks.frame = NSRect(x: x + titleWidth + gap, y: titleY, width: min(marksWidth, max(room - titleWidth - gap, 0)), height: titleHeight)
origin.frame = NSRect(x: x, y: titleY - 2 - originHeight, width: room, height: originHeight)
Expand Down
Binary file modified docs/screenshots/macos-quick-entry.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/macos-task.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/macos-today.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading