aboutsummaryrefslogtreecommitdiffstats
path: root/WireGuard/WireGuard/UI/macOS/StatusItemController.swift
diff options
context:
space:
mode:
authorRoopesh Chander <roop@roopc.net>2019-01-16 01:00:42 +0530
committerRoopesh Chander <roop@roopc.net>2019-01-16 01:26:10 +0530
commite29cf19fddc6878f7e24c442f83d6ff0d23fa6b8 (patch)
tree6b7a098cd40dda417d1827af5245669bc883fa88 /WireGuard/WireGuard/UI/macOS/StatusItemController.swift
parentmacOS: Add About dialog (diff)
downloadwireguard-apple-e29cf19fddc6878f7e24c442f83d6ff0d23fa6b8.tar.xz
wireguard-apple-e29cf19fddc6878f7e24c442f83d6ff0d23fa6b8.zip
macOS: Different status bar icon looks for different states
- Looks dimmed when no tunnel is active - Looks normal when a tunnel is active - Animates when a tunnel is activating Signed-off-by: Roopesh Chander <roop@roopc.net>
Diffstat (limited to '')
-rw-r--r--WireGuard/WireGuard/UI/macOS/StatusItemController.swift66
1 files changed, 66 insertions, 0 deletions
diff --git a/WireGuard/WireGuard/UI/macOS/StatusItemController.swift b/WireGuard/WireGuard/UI/macOS/StatusItemController.swift
new file mode 100644
index 00000000..2568c153
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/StatusItemController.swift
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: MIT
+// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
+
+import Cocoa
+
+class StatusItemController {
+ var currentTunnel: TunnelContainer? {
+ didSet {
+ updateStatusItemImage()
+ }
+ }
+
+ let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
+ private let statusBarImageWhenActive = NSImage(named: "StatusBarIcon")!
+ private let statusBarImageWhenInactive = NSImage(named: "StatusBarIconDimmed")!
+
+ private let animationImages = [
+ NSImage(named: "StatusBarIconDot1")!,
+ NSImage(named: "StatusBarIconDot2")!,
+ NSImage(named: "StatusBarIconDot3")!
+ ]
+ private var animationImageIndex: Int = 0
+ private var animationTimer: Timer?
+
+ init() {
+ updateStatusItemImage()
+ }
+
+ func updateStatusItemImage() {
+ guard let currentTunnel = currentTunnel else {
+ stopActivatingAnimation()
+ statusItem.button?.image = statusBarImageWhenInactive
+ return
+ }
+ switch currentTunnel.status {
+ case .inactive:
+ stopActivatingAnimation()
+ statusItem.button?.image = statusBarImageWhenInactive
+ case .active:
+ stopActivatingAnimation()
+ statusItem.button?.image = statusBarImageWhenActive
+ case .activating, .waiting, .reasserting, .restarting:
+ startActivatingAnimation()
+ case .deactivating:
+ break
+ }
+ }
+
+ func startActivatingAnimation() {
+ guard animationTimer == nil else { return }
+ let timer = Timer(timeInterval: 0.3, repeats: true) { [weak self] _ in
+ guard let self = self else { return }
+ self.statusItem.button?.image = self.animationImages[self.animationImageIndex]
+ self.animationImageIndex = (self.animationImageIndex + 1) % self.animationImages.count
+ }
+ RunLoop.main.add(timer, forMode: .default)
+ animationTimer = timer
+ }
+
+ func stopActivatingAnimation() {
+ guard let timer = self.animationTimer else { return }
+ timer.invalidate()
+ animationTimer = nil
+ animationImageIndex = 0
+ }
+}