You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
5.6 KiB
193 lines
5.6 KiB
// |
|
// AppDelegate.swift |
|
// LunaMac |
|
// |
|
// Created by Claire Davis on 9/21/22. |
|
// Copyright © 2022 A Better Geek. All rights reserved. |
|
// |
|
|
|
import Cocoa |
|
import Foundation |
|
import CoreFoundation |
|
|
|
@NSApplicationMain |
|
class AppDelegate: NSObject, NSApplicationDelegate { |
|
|
|
// make sure applet stays in memory |
|
var statusBarItem: NSStatusItem? |
|
|
|
// static array of possible lunar values |
|
let phaseArray:[String:[String:NSString]] = [ |
|
"new" : [ |
|
"nice" : "New Moon", |
|
"start" : "0", |
|
"end" : "1", |
|
"icon" : "🌑" |
|
], |
|
"waxc" : [ |
|
"nice" : "Waxing Crescent", |
|
"start" : "1", |
|
"end" : "6.38264692644", |
|
"icon" : "🌒" |
|
], |
|
"firstq" : [ |
|
"nice" : "First Quarter", |
|
"start" : "6.38264692644", |
|
"end" : "8.38264692644", |
|
"icon" : "🌓" |
|
], |
|
"waxg" : [ |
|
"nice" : "Waxing Gibbous", |
|
"start" : "8.38264692644", |
|
"end" : "13.76529385288", |
|
"icon" : "🌔" |
|
], |
|
"full" : [ |
|
"nice" : "Full Moon", |
|
"start" : "13.76529385288", |
|
"end" : "15.76529385288", |
|
"icon" : "🌕" |
|
], |
|
"wang" : [ |
|
"nice" : "Waning Gibbous", |
|
"start" : "15.76529385288", |
|
"end" : "21.14794077932", |
|
"icon" : "🌖" |
|
], |
|
"lastq" : [ |
|
"nice" : "Last Quarter", |
|
"start" : "21.14794077932", |
|
"end" : "23.14794077932", |
|
"icon" : "🌗" |
|
], |
|
"wanc" : [ |
|
"nice" : "Waning Crescent", |
|
"start" : "23.14794077932", |
|
"end" : "28.53058770576", |
|
"icon" : "🌘" |
|
], |
|
"new2" : [ |
|
"nice" : "New Moon", |
|
"start" : "28.53058770576", |
|
"end" : "29.53058770576", |
|
"icon" : "🌑" |
|
], |
|
"default" : [ |
|
"nice" : "Failed to calculate.", |
|
"icon" : "🌙" |
|
] |
|
] |
|
|
|
func applicationDidFinishLaunching(_ aNotification: Notification) { |
|
updateIcon() |
|
} |
|
|
|
@objc func buildMenu(key: String = "default") { |
|
// get system-wide menu bar |
|
let statusBar = NSStatusBar.system |
|
|
|
// set icon size to square |
|
statusBarItem = statusBar.statusItem(withLength: NSStatusItem.squareLength) |
|
|
|
// set icon using emoji |
|
statusBarItem?.button?.title = phaseArray[key]?["icon"] as String? ?? "🌙" |
|
|
|
// create a menu for the icon |
|
let statusBarMenu = NSMenu(title: "LunaMac Menu") |
|
|
|
// add the menu to the menu bar icon |
|
statusBarItem?.menu = statusBarMenu |
|
|
|
let topTxt = phaseArray["default"]?["nice"] as String? ?? "" |
|
|
|
// add menu items to the menu |
|
if (!topTxt.isEmpty) { |
|
statusBarMenu.addItem( |
|
withTitle: phaseArray[key]?["nice"] as String? ?? topTxt, |
|
action: nil, |
|
keyEquivalent: "" |
|
) |
|
} |
|
|
|
statusBarMenu.addItem( |
|
withTitle: "Update moon phase", |
|
action: #selector(AppDelegate.updateIcon), |
|
keyEquivalent: "" |
|
) |
|
|
|
statusBarMenu.addItem( |
|
withTitle: "Quit LunaMac", |
|
action: #selector(AppDelegate.quitApp), |
|
keyEquivalent: "" |
|
) |
|
} |
|
|
|
// update menu bar icon |
|
@objc func updateIcon() { |
|
// current system time in UTC |
|
let sysDate = Date() |
|
// get baseline date |
|
// let baseDateStr = "2000-01-06 18:14:00 +0000" |
|
|
|
// create date object from baseDate |
|
// date components |
|
var bdc = DateComponents() |
|
bdc.year = 2000 |
|
bdc.month = 1 |
|
bdc.day = 6 |
|
bdc.hour = 18 |
|
bdc.minute = 14 |
|
// create date object |
|
let ucal = Calendar(identifier: .gregorian) |
|
let baseDate = ucal.date(from: bdc) |
|
|
|
// days in a lunar cycle |
|
let lunarDays = 29.53058770576 |
|
// seconds in a lunar cycle |
|
let lunarSecs = lunarDays * (24 * 60 * 60) |
|
|
|
// calculate seconds between sysDate and baseDate |
|
// if baseDate is nil, default to current system time |
|
let totalSecs = sysDate.timeIntervalSince(baseDate ?? Date()) |
|
|
|
if (totalSecs.sign != .minus) { |
|
// a positive number is valid |
|
// % calculates seconds of current cycle |
|
let currSecs = totalSecs.truncatingRemainder(dividingBy: lunarSecs) |
|
let currFrac = currSecs / lunarSecs |
|
let currDays = currFrac * lunarDays |
|
|
|
var newArr = [String:[String:NSString]]() |
|
|
|
newArr = phaseArray.filter{findPhase(key: $0.key, val: $0.value, start: $0.value["start"]?.doubleValue ?? 0, end: $0.value["end"]?.doubleValue ?? 0, curr: currDays)} |
|
|
|
// we want newArr[0].value which is [String:NSString] |
|
let theKey = newArr.first!.key |
|
buildMenu(key: theKey) |
|
} else { |
|
// if dateDiff is negative, something went wrong. |
|
buildMenu() |
|
} |
|
} |
|
|
|
@objc func findPhase(key: String, val: [String:NSString], start: Double, end: Double, curr: Double) -> Bool { |
|
|
|
if ((curr >= start) && (curr <= end)) { |
|
return true |
|
} else { |
|
return false |
|
} |
|
} |
|
|
|
// quit application |
|
@objc func quitApp() { |
|
NSApp.terminate(self) |
|
} |
|
|
|
func applicationWillTerminate(_ aNotification: Notification) { |
|
// Insert code here to tear down your application |
|
} |
|
|
|
|
|
} |
|
|
|
|