diff options
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | menubar/main.swift | 12 | ||||
| -rw-r--r-- | menubar/model.swift | 33 |
3 files changed, 37 insertions, 13 deletions
@@ -99,8 +99,9 @@ than a poll is still a completion. - **Importance**: mark an agent high, normal (the default), or low. Within a status, more important agents are listed first, so a jump goes to them first; status still comes first (a blocked low agent before a done high - one). A high agent shows a bold `!` before its name; a low agent's name is - lightly dimmed, its second line says "low", and it makes no sound (it + one). A high agent shows a peach `!` before its name (in a column of its + own, so names line up); a low agent's name is dimmed, its second line + says "low", and it makes no sound (it still notifies, and waits in line like any other). In pi, type `/importance high|normal|low` (no argument: the current level); pi saves it with the session, so it comes back after `/reload`, a restart, or a diff --git a/menubar/main.swift b/menubar/main.swift index 135c099..2230817 100644 --- a/menubar/main.swift +++ b/menubar/main.swift @@ -424,6 +424,18 @@ if arguments.contains("--selftest") { if rowTitle(high).string != "✓ ! Fix it" || rowTitlePrefix(high) != "✓ ! " { failures.append("title: a high agent is marked: \(rowTitle(high).string)") } + let markColor = rowTitle(high).attribute(.foregroundColor, at: rowTitlePrefix(high).utf16.count - 2, + effectiveRange: nil) as? NSColor + if markColor != herdrPeach { failures.append("title: the ! is peach") } + let normal = Row(paneId: "%2", agent: "pi", name: "Fix it", status: .done, session: "s", window: "w", since: 1) + if rowTitle(normal).string != "✓ Fix it" || rowTitlePrefix(normal).count != rowTitlePrefix(high).count { + failures.append("title: names line up with or without the mark: '\(rowTitle(normal).string)'") + } + let low = Row(paneId: "%3", agent: "pi", name: "Fix it", status: .done, session: "s", window: "w", since: 1, + importance: .low) + let lowColor = rowTitle(low).attribute(.foregroundColor, at: rowTitlePrefix(low).utf16.count, + effectiveRange: nil) as? NSColor + if lowColor?.alphaComponent != lowImportanceAlpha { failures.append("title: a low agent's name is dimmed") } failures.forEach { print("FAIL \($0)") } print(failures.isEmpty ? "selftest ok" : "selftest: \(failures.count) failed") exit(failures.isEmpty ? 0 : 1) diff --git a/menubar/model.swift b/menubar/model.swift index 513f9fb..f0f977e 100644 --- a/menubar/model.swift +++ b/menubar/model.swift @@ -18,6 +18,8 @@ let herdrTeal = herdrColor(dark: (148, 226, 213), light: (23, 146, 153)) let herdrYellow = herdrColor(dark: (249, 226, 175), light: (223, 142, 29)) let herdrGreen = herdrColor(dark: (166, 227, 161), light: (64, 160, 43)) let herdrGray = herdrColor(dark: (108, 112, 134), light: (156, 160, 176)) +/// Not a status color: marks a high-importance agent. +let herdrPeach = herdrColor(dark: (250, 179, 135), light: (254, 100, 11)) /// herdr's mocha text colors, fixed (not appearance-dependent) for the /// always-dark floating panel. @@ -324,15 +326,23 @@ func plainTitle(for rows: [Row]) -> String { title(for: rows).string } -/// The title's characters before the name: the status symbol, and `!` for a -/// high agent. +/// The title's characters before the name: the status symbol and the +/// importance column. func rowTitlePrefix(_ row: Row) -> String { - "\(row.status.symbol) " + (row.importance == .high ? "! " : "") + "\(row.status.symbol) " + importanceMark(row) + " " } -/// Row title: the colored status symbol, a bold `!` for a high agent, then -/// the agent's name. Unnamed agents show their harness, dimmed, so it never -/// competes with real names; a low agent's name is lightly dimmed. +/// The importance column: `!` for a high agent, a blank otherwise, so every +/// name starts in the same place. +private func importanceMark(_ row: Row) -> String { row.importance == .high ? "!" : " " } + +/// How much a low agent's name is dimmed: enough to recede, still legible. +let lowImportanceAlpha: CGFloat = 0.5 + +/// Row title: the colored status symbol, the importance column (a peach `!` +/// for a high agent), then the agent's name. Unnamed agents show their +/// harness, dimmed, so it never competes with real names; a low agent's name +/// is dimmed. func rowTitle(_ row: Row, primary: NSColor = .labelColor, secondary: NSColor = .secondaryLabelColor) -> NSAttributedString { let font = NSFont.menuFont(ofSize: 0) @@ -340,11 +350,12 @@ func rowTitle(_ row: Row, primary: NSColor = .labelColor, let text = NSMutableAttributedString() text.append(NSAttributedString( string: "\(row.status.symbol) ", attributes: [.font: mono, .foregroundColor: row.status.color])) - if row.importance == .high { - text.append(NSAttributedString( - string: "! ", attributes: [.font: NSFont.boldSystemFont(ofSize: font.pointSize), .foregroundColor: primary])) - } - let labelColor = row.name.isEmpty ? secondary : row.importance == .low ? primary.withAlphaComponent(0.7) : primary + text.append(NSAttributedString( + string: importanceMark(row) + " ", + attributes: [.font: NSFont.monospacedSystemFont(ofSize: font.pointSize, weight: .heavy), + .foregroundColor: herdrPeach])) + let labelColor = row.name.isEmpty ? secondary + : row.importance == .low ? primary.withAlphaComponent(lowImportanceAlpha) : primary text.append(NSAttributedString( string: row.label, attributes: [.font: font, .foregroundColor: labelColor])) return text |
