Skip to content
Open
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
7 changes: 6 additions & 1 deletion Timer/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele

func applicationDidFinishLaunching(_ aNotification: Notification) {
let controller = MVTimerController()
controller.isMainController = true
controllers.append(controller)
self.addBadgeToDock(controller: controller)

Expand Down Expand Up @@ -81,6 +82,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
@objc func newDocument(_ sender: AnyObject?) {
let controller = MVTimerController(closeToWindow: NSApplication.shared.keyWindow)
controller.window?.level = self.windowLevel()
controller.isMainController = controllers.isEmpty
controllers.append(controller)
}

Expand Down Expand Up @@ -109,6 +111,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
}

private func registerDefaults() {
UserDefaults.standard.register(defaults: [MVUserDefaultsKeys.staysOnTop: false])
UserDefaults.standard.register(defaults: [
MVUserDefaultsKeys.staysOnTop: false,
MVUserDefaultsKeys.typicalTimeSuffixes: false
])
}
}
31 changes: 22 additions & 9 deletions Timer/MVClockView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ class MVClockView: NSControl {
}
}
}
var typicalSuffixes = false {
didSet {
self.updateLabels()
}
}

// MARK: -

Expand Down Expand Up @@ -342,28 +347,36 @@ class MVClockView: NSControl {
private func updateLabels() {
var suffixWidth: CGFloat = 0

let minutesSuffixFormat: NSString = typicalSuffixes ? "%im" : "%i'"
let secondsSuffixFormat: NSString = typicalSuffixes ? "%is" : "%i\""
if self.seconds < 60 {
minutesLabel.string = NSString(format: "%i\"", Int(self.seconds)) as String
minutesLabel.string = NSString(format: secondsSuffixFormat, Int(self.seconds)) as String
suffixWidth = minutesLabelSecondsSuffixWidth
} else {
minutesLabel.string = NSString(format: "%i'", Int(self.minutes)) as String
minutesLabel.string = NSString(format: minutesSuffixFormat, Int(self.minutes)) as String
suffixWidth = minutesLabelSuffixWidth
}
minutesLabel.sizeToFit()

var frame = minutesLabel.frame
frame.origin.x = round((self.bounds.width - (frame.size.width - suffixWidth)) / 2)
minutesLabel.frame = frame
// typical suffixes look better without frame adjustments
if !typicalSuffixes {
var frame = minutesLabel.frame
frame.origin.x = round((self.bounds.width - (frame.size.width - suffixWidth)) / 2)
minutesLabel.frame = frame
}

if self.seconds < 60 {
secondsLabel.string = ""
} else {
secondsLabel.string = NSString(format: "%i\"", Int(self.seconds.truncatingRemainder(dividingBy: 60))) as String
secondsLabel.string = NSString(format: secondsSuffixFormat, Int(self.seconds.truncatingRemainder(dividingBy: 60))) as String
secondsLabel.sizeToFit()

frame = secondsLabel.frame
frame.origin.x = round((self.bounds.width - (frame.size.width - secondsSuffixWidth)) / 2)
secondsLabel.frame = frame
// typical suffixes look better without frame adjustments
if !typicalSuffixes {
var frame = secondsLabel.frame
frame.origin.x = round((self.bounds.width - (frame.size.width - secondsSuffixWidth)) / 2)
secondsLabel.frame = frame
}
}
}

Expand Down
30 changes: 30 additions & 0 deletions Timer/MVMainView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class MVMainView: NSView {
private var contextMenu: NSMenu?
public var menuItem: NSMenuItem?
private var soundMenuItems: [NSMenuItem] = []
var typicalTimeSuffixMenuItem: NSMenuItem?

// swiftlint:disable unused_setter_value
override var menu: NSMenu? {
Expand Down Expand Up @@ -52,9 +53,27 @@ class MVMainView: NSView {
submenu.addItem(soundItem)
}
self.soundMenuItems.first?.state = .on

let menuItemViewConfig = NSMenuItem(
title: "View",
action: nil,
keyEquivalent: ""
)
let submenuViewConfig = NSMenu()
submenuViewConfig.autoenablesItems = false

typicalTimeSuffixMenuItem = NSMenuItem(
title: "Use typical minutes and seconds suffixes",
action: #selector(self.toggleViewItemState),
keyEquivalent: ""
)
submenuViewConfig.addItem(typicalTimeSuffixMenuItem!)

self.contextMenu?.addItem(menuItem!)
self.contextMenu?.addItem(menuItemSoundChoice)
self.contextMenu?.setSubmenu(submenu, for: menuItemSoundChoice)
self.contextMenu?.addItem(menuItemViewConfig)
self.contextMenu?.setSubmenu(submenuViewConfig, for: menuItemViewConfig)

let notificationCenter = NotificationCenter.default

Expand Down Expand Up @@ -102,6 +121,17 @@ class MVMainView: NSView {
}
}

@objc func toggleViewItemState(_ sender: NSMenuItem) {
var value = sender.state == .on ? true : false
value.toggle()
switch sender {
case typicalTimeSuffixMenuItem:
self.controller?.setViewState(value, forKey: MVUserDefaultsKeys.typicalTimeSuffixes)
default:
break
}
}

deinit {
NotificationCenter.default.removeObserver(self)
}
Expand Down
32 changes: 32 additions & 0 deletions Timer/MVTimerController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class MVTimerController: NSWindowController {
private var audioPlayer: AVAudioPlayer? // player must be kept in memory
private var soundURL = Bundle.main.url(forResource: "alert-sound", withExtension: "caf")

var isMainController: Bool = false

convenience init() {
let mainView = MVMainView(frame: NSRect.zero)

Expand All @@ -25,6 +27,8 @@ class MVTimerController: NSWindowController {
self.windowFrameAutosaveName = "TimerWindowAutosaveFrame"

window.makeKeyAndOrderFront(self)

loadViewStateFromUserDefaults()
}

convenience init(closeToWindow: NSWindow?) {
Expand Down Expand Up @@ -105,4 +109,32 @@ class MVTimerController: NSWindowController {
self.soundURL = nil
}
}

func setViewState(_ value: Bool, forKey viewConfigKey: String) {
setViewState(value, forKey: viewConfigKey, save: isMainController)
}

private func setViewState(_ value: Bool, forKey viewConfigKey: String, save: Bool) {
let state: NSControl.StateValue = value ? .on : .off
switch viewConfigKey {
case MVUserDefaultsKeys.typicalTimeSuffixes:
mainView.typicalTimeSuffixMenuItem?.state = state
clockView.typicalSuffixes = value
default:
break
}
if save {
UserDefaults.standard.set(value, forKey: viewConfigKey)
}
}

private func loadViewStateFromUserDefaults() {
let keys: [String] = [
MVUserDefaultsKeys.typicalTimeSuffixes
]
for key in keys {
let value = UserDefaults.standard.bool(forKey: key)
setViewState(value, forKey: key, save: false)
}
}
}
1 change: 1 addition & 0 deletions Timer/MVUserDefaultsKeys.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
struct MVUserDefaultsKeys {
static let staysOnTop = "staysOnTop"
static let typicalTimeSuffixes = "typicalTimeSuffixes"
}