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.

120 lines
3.8 KiB

  1. //
  2. // AppDelegate.swift
  3. // Menubar RunCat
  4. //
  5. // Created by Takuto Nakamura on 2019/08/06.
  6. // Copyright © 2019 Takuto Nakamura. All rights reserved.
  7. //
  8. import Cocoa
  9. @NSApplicationMain
  10. class AppDelegate: NSObject, NSApplicationDelegate {
  11. @IBOutlet weak var menu: NSMenu!
  12. private let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
  13. private let nc = NSWorkspace.shared.notificationCenter
  14. private var anim = [(Double, [NSImage])]()
  15. private var cnt: Int = 0
  16. private var isRunning: Bool = false
  17. private var interval: Double = 1.0
  18. private let cpu = CPU()
  19. private var cpuTimer: Timer? = nil
  20. private var usage: (value: Double, description: String) = (0.0, "")
  21. private var isShowUsage: Bool = false
  22. private var animId: Int = 0
  23. func applicationDidFinishLaunching(_ aNotification: Notification) {
  24. for (name, len, rate) in [
  25. ("cat_page", 5, 1.0),
  26. ("dino", 2, 1.0),
  27. ("ablobcatbongo", 2, 0.5),
  28. ("ablobcatcoffee", 24, 0.2),
  29. ("ablobcatrave", 18, 0.2),
  30. ("ablobcatwave", 24, 0.4),
  31. ("ablobattention", 22, 0.2),
  32. ("ablobblewobble", 15, 0.2),
  33. ("annoyingdog", 2, 1.0),
  34. ] {
  35. let animFrames = (0..<len).map { NSImage(imageLiteralResourceName: "\(name)\($0)") }
  36. anim.append((rate, animFrames))
  37. }
  38. statusItem.menu = menu
  39. statusItem.button?.imagePosition = .imageRight
  40. statusItem.button?.image = anim[animId].1[cnt]
  41. startRunning()
  42. }
  43. func applicationWillTerminate(_ aNotification: Notification) {
  44. stopRunning()
  45. }
  46. func setNotifications() {
  47. nc.addObserver(self, selector: #selector(AppDelegate.receiveSleepNote),
  48. name: NSWorkspace.willSleepNotification, object: nil)
  49. nc.addObserver(self, selector: #selector(AppDelegate.receiveWakeNote),
  50. name: NSWorkspace.didWakeNotification, object: nil)
  51. }
  52. @objc func receiveSleepNote() {
  53. stopRunning()
  54. }
  55. @objc func receiveWakeNote() {
  56. startRunning()
  57. }
  58. func startRunning() {
  59. cpuTimer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true, block: { (t) in
  60. self.usage = self.cpu.usageCPU()
  61. self.interval = 0.02 * (100 - max(0.0, min(99.0, self.usage.value))) / 6 * self.anim[self.animId].0
  62. self.statusItem.button?.title = self.isShowUsage ? self.usage.description : ""
  63. })
  64. cpuTimer?.fire()
  65. isRunning = true
  66. animate()
  67. }
  68. func stopRunning() {
  69. isRunning = false
  70. cpuTimer?.invalidate()
  71. }
  72. func animate() {
  73. statusItem.button?.image = anim[animId].1[cnt]
  74. cnt = (cnt + 1) % anim[animId].1.count
  75. if !isRunning { return }
  76. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + interval) {
  77. self.animate()
  78. }
  79. }
  80. @IBAction func toggleShowUsage(_ sender: NSMenuItem) {
  81. isShowUsage = sender.state == .off
  82. sender.state = isShowUsage ? .on : .off
  83. statusItem.button?.title = isShowUsage ? usage.description : ""
  84. }
  85. @IBAction func changeAnimation(_ sender: NSMenuItem) {
  86. let animation = menu.item(withTag: 10)?.submenu
  87. for (index, item) in (animation?.items ?? []).enumerated() {
  88. if item == sender {
  89. NSLog("%d", index)
  90. animId = index
  91. cnt = 0
  92. item.state = NSControl.StateValue.on
  93. } else {
  94. item.state = NSControl.StateValue.off
  95. }
  96. }
  97. }
  98. @IBAction func showAbout(_ sender: Any) {
  99. NSApp.activate(ignoringOtherApps: true)
  100. NSApp.orderFrontStandardAboutPanel(nil)
  101. }
  102. }