Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions MeetingBar/Extensions/DefaultsKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ extension Defaults.Keys {
static let eventTimeFormat = Key<EventTimeFormat>("eventTimeFormat", default: .show)

static let eventTitleIconFormat = Key<EventTitleIconFormat>("eventTitleIconFormat", default: .none)
static let showDateOnIcon = Key<Bool>("showDateOnIcon", default: false)
static let statusbarEventTitleLength = Key<Int>("statusbarEventTitleLength", default: statusbarEventTitleLengthLimits.max)

static let hideMeetingTitle = Key<Bool>("hideMeetingTitle", default: false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"preferences_appearance_status_bar_icon_calendar_icon_value" = "\U00A0Calendar";
"preferences_appearance_status_bar_icon_specific_icon_value" = "\U00A0Event-specific icon (e.g. MS Teams)";
"preferences_appearance_status_bar_icon_no_icon_value" = "\U00A0No icon";
"preferences_appearance_status_bar_show_date_on_icon" = "Show today's date on icon";
"preferences_appearance_status_bar_title_title" = "Title";
"preferences_appearance_status_bar_title_event_title_value" = "event title";
"preferences_appearance_status_bar_title_dot_value" = "dot (•)";
Expand Down
44 changes: 41 additions & 3 deletions MeetingBar/UI/StatusBar/StatusBarItemController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ final class StatusBarItemController {
// For all these keys, just redraw:
Defaults.publisher(
keys: .statusbarEventTitleLength, .eventTimeFormat,
.eventTitleIconFormat, .showEventMaxTimeUntilEventThreshold,
.eventTitleIconFormat, .showDateOnIcon, .showEventMaxTimeUntilEventThreshold,
.showEventMaxTimeUntilEventEnabled, .showEventDetails,
.shortenEventTitle, .menuEventTitleLength,
.showEventEndTime, .showMeetingServiceIcon,
Expand Down Expand Up @@ -220,7 +220,7 @@ final class StatusBarItemController {
case .appicon:
button.image = NSImage(named: Defaults[.eventTitleIconFormat].rawValue)!
default:
button.image = NSImage(named: MenuStyleConstants.calendarCheckmarkIconName)
button.image = calendarIconWithOptionalDate(named: MenuStyleConstants.calendarCheckmarkIconName)
}
button.image?.size = MenuStyleConstants.iconSize
} else if title == "MeetingBar" {
Expand All @@ -231,7 +231,7 @@ final class StatusBarItemController {
case .appicon:
button.image = NSImage(named: Defaults[.eventTitleIconFormat].rawValue)!
default:
button.image = NSImage(named: MenuStyleConstants.calendarIconName)
button.image = calendarIconWithOptionalDate(named: MenuStyleConstants.calendarIconName)
}
}

Expand All @@ -240,6 +240,8 @@ final class StatusBarItemController {
let image: NSImage
if Defaults[.eventTitleIconFormat] == .eventtype {
image = getIconForMeetingService(nextEvent.meetingLink?.service)
} else if Defaults[.eventTitleIconFormat] == .calendar {
image = calendarIconWithOptionalDate(named: Defaults[.eventTitleIconFormat].rawValue)
} else {
image = NSImage(named: Defaults[.eventTitleIconFormat].rawValue)!
}
Expand Down Expand Up @@ -523,6 +525,42 @@ final class StatusBarItemController {
openInFantastical(startDate: event.startDate, title: event.title)
}
}

/// Returns the named calendar icon, optionally with the current day-of-month overlaid.
private func calendarIconWithOptionalDate(named name: String) -> NSImage {
let baseImage = NSImage(named: name)!
guard Defaults[.showDateOnIcon] else { return baseImage }

Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
let day = Calendar.current.component(.day, from: Date())
let dayString = String(day)

let size = MenuStyleConstants.iconSize
let composed = NSImage(size: size)
composed.lockFocus()

baseImage.draw(in: NSRect(origin: .zero, size: size),
from: .zero,
operation: .sourceOver,
fraction: 1.0)

// Pick a font size that fits one or two digits inside the calendar body.
let fontSize: CGFloat = dayString.count > 1 ? 8 : 9
let attributes: [NSAttributedString.Key: Any] = [
.font: NSFont.systemFont(ofSize: fontSize, weight: .bold),
.foregroundColor: NSColor.labelColor
]
let textSize = (dayString as NSString).size(withAttributes: attributes)
// Calendar icon has a header strip at the top; nudge text down into the body.
let textOrigin = NSPoint(
x: (size.width - textSize.width) / 2,
y: (size.height - textSize.height) / 2 - 1.5
)
(dayString as NSString).draw(at: textOrigin, withAttributes: attributes)

composed.unlockFocus()
composed.isTemplate = baseImage.isTemplate
return composed
}
}

func shortenTitle(title: String?, offset: Int) -> String {
Expand Down
9 changes: 9 additions & 0 deletions MeetingBar/UI/Views/Preferences/AppearanceTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ struct EventsSection: View {

struct StatusBarSection: View {
@Default(.eventTitleIconFormat) var eventTitleIconFormat
@Default(.showDateOnIcon) var showDateOnIcon
@Default(.eventTitleFormat) var eventTitleFormat
@Default(.eventTimeFormat) var eventTimeFormat
@Default(.statusbarEventTitleLength) var statusbarEventTitleLength
Expand Down Expand Up @@ -188,6 +189,14 @@ struct StatusBarSection: View {
}
}.frame(width: 325)

HStack {
Toggle(
"preferences_appearance_status_bar_show_date_on_icon".loco(),
isOn: $showDateOnIcon
)
.disabled(eventTitleIconFormat == .appicon || eventTitleIconFormat == .none)
}.frame(width: 325, alignment: .leading)

HStack {
Picker(
"preferences_appearance_status_bar_title_title".loco(),
Expand Down
Loading