diff --git a/MTMR/AppleScriptTouchBarItem.swift b/MTMR/AppleScriptTouchBarItem.swift index 9659a9b..82b54b6 100644 --- a/MTMR/AppleScriptTouchBarItem.swift +++ b/MTMR/AppleScriptTouchBarItem.swift @@ -5,16 +5,16 @@ class AppleScriptTouchBarItem: CustomButtonTouchBarItem { private let interval: TimeInterval private var forceHideConstraint: NSLayoutConstraint! - init?(identifier: NSTouchBarItem.Identifier, source: SourceProtocol, interval: TimeInterval, onTap: @escaping ()->(), onLongTap: @escaping ()->()) { + init?(identifier: NSTouchBarItem.Identifier, source: SourceProtocol, interval: TimeInterval) { self.interval = interval - super.init(identifier: identifier, title: "⏳", onTap: onTap, onLongTap: onLongTap) + super.init(identifier: identifier, title: "⏳") self.forceHideConstraint = self.view.widthAnchor.constraint(equalToConstant: 0) guard let script = source.appleScript else { self.title = "no script" return } self.script = script - button.bezelColor = .clear + self.isBordered = false DispatchQueue.main.async { var error: NSDictionary? guard script.compileAndReturnError(&error) else { diff --git a/MTMR/CustomButtonTouchBarItem.swift b/MTMR/CustomButtonTouchBarItem.swift index 95de37f..a181668 100644 --- a/MTMR/CustomButtonTouchBarItem.swift +++ b/MTMR/CustomButtonTouchBarItem.swift @@ -11,14 +11,12 @@ import Cocoa class CustomButtonTouchBarItem: NSCustomTouchBarItem, NSGestureRecognizerDelegate { var tapClosure: (() -> ())? var longTapClosure: (() -> ())? - private(set) var button: NSButton! //todo hide completely + private var button: NSButton! private var singleClick: NSClickGestureRecognizer! private var longClick: NSPressGestureRecognizer! - init(identifier: NSTouchBarItem.Identifier, title: String, onTap callback: @escaping () -> (), onLongTap callbackLong: @escaping () -> (), bezelColor: NSColor? = .clear) { - self.tapClosure = callback - self.longTapClosure = callbackLong + init(identifier: NSTouchBarItem.Identifier, title: String) { self.attributedTitle = title.defaultTouchbarAttributedString super.init(identifier: identifier) @@ -63,10 +61,17 @@ class CustomButtonTouchBarItem: NSCustomTouchBarItem, NSGestureRecognizerDelegat var attributedTitle: NSAttributedString { didSet { + self.button?.imagePosition = attributedTitle.length > 0 ? .imageLeading : .imageOnly self.button?.attributedTitle = attributedTitle } } + var image: NSImage? { + didSet { + button.image = image + } + } + private func reinstallButton() { let title = button.attributedTitle let image = button.image @@ -80,7 +85,10 @@ class CustomButtonTouchBarItem: NSCustomTouchBarItem, NSGestureRecognizerDelegat button.isBordered = isBordered button.bezelStyle = isBordered ? .rounded : .inline } + button.imageScaling = .scaleProportionallyDown + button.imageHugsTitle = true button.attributedTitle = title + self.button?.imagePosition = title.length > 0 ? .imageLeading : .imageOnly button.image = image self.view = button diff --git a/MTMR/GeneralExtensions.swift b/MTMR/GeneralExtensions.swift index fe8d36f..be4bf2c 100644 --- a/MTMR/GeneralExtensions.swift +++ b/MTMR/GeneralExtensions.swift @@ -9,3 +9,11 @@ import Foundation } } #endif + +extension String { + + var ifNotEmpty: String? { + return self.count > 0 ? self : nil + } + +} diff --git a/MTMR/ScrollViewItem.swift b/MTMR/ScrollViewItem.swift index c4fc12c..7fe49ea 100644 --- a/MTMR/ScrollViewItem.swift +++ b/MTMR/ScrollViewItem.swift @@ -10,7 +10,6 @@ class ScrollViewItem: NSCustomTouchBarItem { stackView.orientation = .horizontal let scrollView = NSScrollView(frame: CGRect(origin: .zero, size: stackView.fittingSize)) scrollView.documentView = stackView -// scrollView.documentView?.bounds.origin = CGPoint(x: 0.0, y: -2.5) self.view = scrollView } diff --git a/MTMR/TouchBarController.swift b/MTMR/TouchBarController.swift index 91a41ff..4de66ac 100644 --- a/MTMR/TouchBarController.swift +++ b/MTMR/TouchBarController.swift @@ -193,19 +193,17 @@ class TouchBarController: NSObject, NSTouchBarDelegate { } func createItem(forIdentifier identifier: NSTouchBarItem.Identifier, definition item: BarItemDefinition) -> NSTouchBarItem? { - let action = self.action(forItem: item) - let longAction = self.longAction(forItem: item) var barItem: NSTouchBarItem! switch item.type { case .staticButton(title: let title): - barItem = CustomButtonTouchBarItem(identifier: identifier, title: title, onTap: action, onLongTap: longAction, bezelColor: NSColor.controlColor) + barItem = CustomButtonTouchBarItem(identifier: identifier, title: title) case .appleScriptTitledButton(source: let source, refreshInterval: let interval): - barItem = AppleScriptTouchBarItem(identifier: identifier, source: source, interval: interval, onTap: action, onLongTap: longAction) + barItem = AppleScriptTouchBarItem(identifier: identifier, source: source, interval: interval) case .timeButton(formatTemplate: let template): - barItem = TimeTouchBarItem(identifier: identifier, formatTemplate: template, onTap: action, onLongTap: longAction) + barItem = TimeTouchBarItem(identifier: identifier, formatTemplate: template) case .battery(): - barItem = BatteryBarItem(identifier: identifier, onTap: action, onLongTap: longAction) + barItem = BatteryBarItem(identifier: identifier) case .dock: barItem = AppScrubberTouchBarItem(identifier: identifier) case .volume: @@ -221,15 +219,21 @@ class TouchBarController: NSObject, NSTouchBarDelegate { barItem = BrightnessViewController(identifier: identifier, refreshInterval: interval) } case .weather(interval: let interval, units: let units, api_key: let api_key, icon_type: let icon_type): - barItem = WeatherBarItem(identifier: identifier, interval: interval, units: units, api_key: api_key, icon_type: icon_type, onTap: action, onLongTap: longAction) + barItem = WeatherBarItem(identifier: identifier, interval: interval, units: units, api_key: api_key, icon_type: icon_type) case .currency(interval: let interval, from: let from, to: let to): - barItem = CurrencyBarItem(identifier: identifier, interval: interval, from: from, to: to, onTap: action, onLongTap: longAction) + barItem = CurrencyBarItem(identifier: identifier, interval: interval, from: from, to: to) case .inputsource(): - barItem = InputSourceBarItem(identifier: identifier, onTap: action, onLongTap: longAction) + barItem = InputSourceBarItem(identifier: identifier) case .music(interval: let interval): - barItem = MusicBarItem(identifier: identifier, interval: interval, onLongTap: longAction) + barItem = MusicBarItem(identifier: identifier, interval: interval) } + if let action = self.action(forItem: item), let item = barItem as? CustomButtonTouchBarItem { + item.tapClosure = action + } + if let longAction = self.longAction(forItem: item), let item = barItem as? CustomButtonTouchBarItem { + item.longTapClosure = longAction + } if case .bordered(let bordered)? = item.additionalParameters[.bordered], let item = barItem as? CustomButtonTouchBarItem { item.isBordered = bordered } @@ -240,21 +244,12 @@ class TouchBarController: NSObject, NSTouchBarDelegate { widthBarItem.setWidth(value: value) } if case .image(let source)? = item.additionalParameters[.image], let item = barItem as? CustomButtonTouchBarItem { - let button = item.button! - button.imageScaling = .scaleProportionallyDown - button.imagePosition = .imageLeading - - if (item.title == "") { - button.imagePosition = .imageOnly - } - - button.imageHugsTitle = true - button.image = source.image + item.image = source.image } return barItem } - func action(forItem item: BarItemDefinition) -> ()->() { + func action(forItem item: BarItemDefinition) -> (()->())? { switch item.action { case .hidKey(keycode: let keycode): return { HIDPostAuxKey(keycode) } @@ -292,12 +287,12 @@ class TouchBarController: NSObject, NSTouchBarDelegate { case .custom(closure: let closure): return closure case .none: - return {} + return nil } } - func longAction(forItem item: BarItemDefinition) -> ()->() { + func longAction(forItem item: BarItemDefinition) -> (()->())? { switch item.longAction { case .hidKey(keycode: let keycode): return { HIDPostAuxKey(keycode) } @@ -335,7 +330,7 @@ class TouchBarController: NSObject, NSTouchBarDelegate { case .custom(closure: let closure): return closure case .none: - return {} + return nil } } } diff --git a/MTMR/Widgets/BatteryBarItem.swift b/MTMR/Widgets/BatteryBarItem.swift index 02cd2c7..008813a 100644 --- a/MTMR/Widgets/BatteryBarItem.swift +++ b/MTMR/Widgets/BatteryBarItem.swift @@ -12,8 +12,8 @@ import Foundation class BatteryBarItem: CustomButtonTouchBarItem { private let batteryInfo = BatteryInfo() - init(identifier: NSTouchBarItem.Identifier, onTap: @escaping () -> (), onLongTap: @escaping () -> ()) { - super.init(identifier: identifier, title: " ", onTap: onTap, onLongTap: onLongTap) + init(identifier: NSTouchBarItem.Identifier) { + super.init(identifier: identifier, title: " ") batteryInfo.start { [weak self] in self?.refresh() diff --git a/MTMR/Widgets/CurrencyBarItem.swift b/MTMR/Widgets/CurrencyBarItem.swift index eddff4f..f7d05a0 100644 --- a/MTMR/Widgets/CurrencyBarItem.swift +++ b/MTMR/Widgets/CurrencyBarItem.swift @@ -36,7 +36,7 @@ class CurrencyBarItem: CustomButtonTouchBarItem { "ETH": "Ξ", ] - init(identifier: NSTouchBarItem.Identifier, interval: TimeInterval, from: String, to: String, onTap: @escaping () -> (), onLongTap: @escaping () -> ()) { + init(identifier: NSTouchBarItem.Identifier, interval: TimeInterval, from: String, to: String) { activity = NSBackgroundActivityScheduler(identifier: "\(identifier.rawValue).updatecheck") activity.interval = interval self.from = from @@ -48,9 +48,7 @@ class CurrencyBarItem: CustomButtonTouchBarItem { self.prefix = from } - super.init(identifier: identifier, title: "⏳", onTap: onTap, onLongTap: onLongTap) - - self.view = button + super.init(identifier: identifier, title: "⏳") activity.repeats = true activity.qualityOfService = .utility diff --git a/MTMR/Widgets/InputSourceBarItem.swift b/MTMR/Widgets/InputSourceBarItem.swift index 1d9f49d..e543303 100644 --- a/MTMR/Widgets/InputSourceBarItem.swift +++ b/MTMR/Widgets/InputSourceBarItem.swift @@ -13,18 +13,15 @@ class InputSourceBarItem: CustomButtonTouchBarItem { fileprivate var notificationCenter: CFNotificationCenter let buttonSize = NSSize(width: 21, height: 21) - init(identifier: NSTouchBarItem.Identifier, onTap: @escaping () -> (), onLongTap: @escaping () -> ()) { + init(identifier: NSTouchBarItem.Identifier) { notificationCenter = CFNotificationCenterGetDistributedCenter(); - super.init(identifier: identifier, title: "⏳", onTap: onTap, onLongTap: onLongTap) + super.init(identifier: identifier, title: "⏳") observeIputSourceChangedNotification(); textInputSourceDidChange() - - self.button.cell?.action = #selector(switchInputSource) - self.button.action = #selector(switchInputSource) - - self.button.frame.size = buttonSize - self.button.bounds.size = buttonSize + self.tapClosure = { [weak self] in + self?.switchInputSource() + } } required init?(coder: NSCoder) { @@ -35,29 +32,21 @@ class InputSourceBarItem: CustomButtonTouchBarItem { CFNotificationCenterRemoveEveryObserver(notificationCenter, UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())); } - @objc override func handleGestureSingle(gr: NSClickGestureRecognizer) { - super.handleGestureSingle(gr: gr) - switchInputSource() - } - @objc public func textInputSourceDidChange() { let currentSource = TISCopyCurrentKeyboardInputSource().takeUnretainedValue() var iconImage: NSImage? = nil - if let imageURL = currentSource.iconImageURL { - if let image = NSImage(contentsOf: imageURL) { - iconImage = image - } - } - - if iconImage == nil, let iconRef = currentSource.iconRef { + if let imageURL = currentSource.iconImageURL, + let image = NSImage(contentsOf: imageURL) { + iconImage = image + } else if let iconRef = currentSource.iconRef { iconImage = NSImage(iconRef: iconRef) } - if (iconImage != nil) { - self.button.cell?.image = iconImage - self.button.cell?.image?.size = buttonSize + if let iconImage = iconImage { + iconImage.size = buttonSize + self.image = iconImage self.title = "" } else { self.title = currentSource.name diff --git a/MTMR/Widgets/MusicBarItem.swift b/MTMR/Widgets/MusicBarItem.swift index 2b83ba9..b15c13d 100644 --- a/MTMR/Widgets/MusicBarItem.swift +++ b/MTMR/Widgets/MusicBarItem.swift @@ -23,15 +23,11 @@ class MusicBarItem: CustomButtonTouchBarItem { "com.apple.Safari" ] - init(identifier: NSTouchBarItem.Identifier, interval: TimeInterval, onLongTap: @escaping () -> ()) { + init(identifier: NSTouchBarItem.Identifier, interval: TimeInterval) { self.interval = interval - super.init(identifier: identifier, title: "⏳", onTap: onLongTap, onLongTap: onLongTap) - - button.bezelColor = .clear - button.imageScaling = .scaleProportionallyDown - button.imagePosition = .imageLeading - button.image?.size = NSSize(width: 24, height: 24) + super.init(identifier: identifier, title: "⏳") + self.isBordered = false self.tapClosure = { [weak self] in self?.playPause() } self.longTapClosure = { [weak self] in self?.nextTrack() } @@ -42,11 +38,11 @@ class MusicBarItem: CustomButtonTouchBarItem { } @objc func marquee(){ - let str = self.button.title + let str = self.title if (str.count > 10) { let indexFirst = str.index(str.startIndex, offsetBy: 0) let indexSecond = str.index(str.startIndex, offsetBy: 1) - self.button.title = String(str.suffix(from: indexSecond)) + String(str[indexFirst]) + self.title = String(str.suffix(from: indexSecond)) + String(str[indexFirst]) } } @@ -222,20 +218,19 @@ class MusicBarItem: CustomButtonTouchBarItem { self.songTitle = tempTitle } - if (self.songTitle != "") { - self.button.cell?.title = " " + self.songTitle! + " " + if let songTitle = self.songTitle?.ifNotEmpty { + self.title = " " + songTitle + " " titleUpdated = true self.timer?.invalidate() self.timer = nil self.timer = Timer.scheduledTimer(timeInterval: 0.25, target: self, selector: #selector(self.marquee), userInfo: nil, repeats: true) } - if ident != "" { - if let appPath = NSWorkspace.shared.absolutePathForApplication(withBundleIdentifier: ident) { - self.button.image = NSWorkspace.shared.icon(forFile: appPath) - self.button.image?.size = self.buttonSize - self.button.imagePosition = .imageLeft - iconUpdated = true - } + if let ident = ident.ifNotEmpty, + let appPath = NSWorkspace.shared.absolutePathForApplication(withBundleIdentifier: ident) { + let image = NSWorkspace.shared.icon(forFile: appPath) + image.size = self.buttonSize + self.image = image + iconUpdated = true } break } @@ -244,11 +239,11 @@ class MusicBarItem: CustomButtonTouchBarItem { DispatchQueue.main.async { if !iconUpdated { - self.button.cell?.image = nil + self.image = nil } if !titleUpdated { - self.button.cell?.title = "" + self.title = "" } } DispatchQueue.main.asyncAfter(deadline: .now() + self.interval) { [weak self] in diff --git a/MTMR/Widgets/TimeTouchBarItem.swift b/MTMR/Widgets/TimeTouchBarItem.swift index 5785c52..5f7810a 100644 --- a/MTMR/Widgets/TimeTouchBarItem.swift +++ b/MTMR/Widgets/TimeTouchBarItem.swift @@ -3,14 +3,12 @@ import Cocoa class TimeTouchBarItem: CustomButtonTouchBarItem { private let dateFormatter = DateFormatter() private var timer: Timer! -// private let button = NSButton(title: "", target: nil, action: nil) - init(identifier: NSTouchBarItem.Identifier, formatTemplate: String, onTap: @escaping () -> (), onLongTap: @escaping () -> ()) { + init(identifier: NSTouchBarItem.Identifier, formatTemplate: String) { dateFormatter.setLocalizedDateFormatFromTemplate(formatTemplate) - super.init(identifier: identifier, title: " ", onTap: onTap, onLongTap: onLongTap) + super.init(identifier: identifier, title: " ") timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true) - self.view = button - button.bezelColor = .clear + self.isBordered = false updateTime() } diff --git a/MTMR/Widgets/WeatherBarItem.swift b/MTMR/Widgets/WeatherBarItem.swift index 257febc..8d1e242 100644 --- a/MTMR/Widgets/WeatherBarItem.swift +++ b/MTMR/Widgets/WeatherBarItem.swift @@ -22,7 +22,7 @@ class WeatherBarItem: CustomButtonTouchBarItem, CLLocationManagerDelegate { private var manager:CLLocationManager! - init(identifier: NSTouchBarItem.Identifier, interval: TimeInterval, units: String, api_key: String, icon_type: String? = "text", onTap: @escaping () -> (), onLongTap: @escaping () -> ()) { + init(identifier: NSTouchBarItem.Identifier, interval: TimeInterval, units: String, api_key: String, icon_type: String? = "text") { activity = NSBackgroundActivityScheduler(identifier: "\(identifier.rawValue).updatecheck") activity.interval = interval self.units = units @@ -42,9 +42,7 @@ class WeatherBarItem: CustomButtonTouchBarItem, CLLocationManagerDelegate { iconsSource = iconsText } - super.init(identifier: identifier, title: "⏳", onTap: onTap, onLongTap: onLongTap) - - self.view = button + super.init(identifier: identifier, title: "⏳") let status = CLLocationManager.authorizationStatus() if status == .restricted || status == .denied {