From df535b28934e92f4125621b7b3edf6bbbca4369e Mon Sep 17 00:00:00 2001 From: Anton Palgunov Date: Mon, 30 Apr 2018 11:29:42 +0100 Subject: [PATCH] Revert "tapAction and longTapAction in config now have nested values" --- MTMR/AppDelegate.swift | 2 +- MTMR/ItemsParsing.swift | 472 +++++++------------------- MTMR/KeyPress.swift | 32 +- MTMR/TouchBarController.swift | 105 ++---- MTMR/Widgets/InputSourceBarItem.swift | 4 +- 5 files changed, 161 insertions(+), 454 deletions(-) diff --git a/MTMR/AppDelegate.swift b/MTMR/AppDelegate.swift index 1923954..6c55260 100644 --- a/MTMR/AppDelegate.swift +++ b/MTMR/AppDelegate.swift @@ -59,7 +59,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { if (result != nil) { let path = result!.path let jsonData = path.fileData - let jsonItems = jsonData?.barItemDefinitions() ?? [BarItemDefinition(type: .staticButton(title: "bad preset"))] + let jsonItems = jsonData?.barItemDefinitions() ?? [BarItemDefinition(type: .staticButton(title: "bad preset"), action: .none, longAction: .none, additionalParameters: [:])] TouchBarController.shared.createAndUpdatePreset(jsonItems: jsonItems) } diff --git a/MTMR/ItemsParsing.swift b/MTMR/ItemsParsing.swift index 60699cd..b564cd3 100644 --- a/MTMR/ItemsParsing.swift +++ b/MTMR/ItemsParsing.swift @@ -3,261 +3,114 @@ import AppKit extension Data { func barItemDefinitions() -> [BarItemDefinition]? { - do { - return try JSONDecoder().decode([BarItemDefinition].self, from: self.utf8string!.stripComments().data(using: .utf8)!) - } catch { - print("\(error)") - } - return [BarItemDefinition(type: .staticButton(title: "bad preset"))] + return try? JSONDecoder().decode([BarItemDefinition].self, from: self.utf8string!.stripComments().data(using: .utf8)!) } } struct BarItemDefinition: Decodable { let type: ItemType let action: ActionType - let longTapAction: LongTapAction - let tapAction: TapAction + let longAction: LongActionType let additionalParameters: [GeneralParameters.CodingKeys: GeneralParameter] - + private enum CodingKeys: String, CodingKey { case type - case tapAction - case longTapAction } - init(type: ItemType, action: ActionType? = .none, tapAction: TapAction? = TapAction(actionType: TapActionType.none), longTapAction: LongTapAction? = LongTapAction(actionType: TapActionType.none), additionalParameters: [GeneralParameters.CodingKeys:GeneralParameter]? = [:]) { + init(type: ItemType, action: ActionType, longAction: LongActionType, additionalParameters: [GeneralParameters.CodingKeys:GeneralParameter]) { self.type = type - self.action = action! - self.longTapAction = longTapAction! - self.tapAction = tapAction! - self.additionalParameters = additionalParameters! + self.action = action + self.longAction = longAction + self.additionalParameters = additionalParameters } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let type = try container.decode(String.self, forKey: .type) let parametersDecoder = SupportedTypesHolder.sharedInstance.lookup(by: type) -// let tapAction = try container.decodeIfPresent(TapAction.self, forKey: .tapAction) -// let longTapAction = try container.decodeIfPresent(LongTapAction.self, forKey: .longTapAction) var additionalParameters = try GeneralParameters(from: decoder).parameters - do { - if let result = try? parametersDecoder(decoder), - case let (itemType, action, tapAction, longTapAction, parameters) = result { - parameters.forEach { additionalParameters[$0] = $1 } - self.init(type: itemType, action: action, tapAction: tapAction, longTapAction: longTapAction, additionalParameters: additionalParameters) - } else { - self.init(type: .staticButton(title: "unknown"), additionalParameters: additionalParameters) - } - } catch { - print("\(error)") + if let result = try? parametersDecoder(decoder), + case let (itemType, action, longAction, parameters) = result { + parameters.forEach { additionalParameters[$0] = $1 } + self.init(type: itemType, action: action, longAction: longAction, additionalParameters: additionalParameters) + } else { + self.init(type: .staticButton(title: "unknown"), action: .none, longAction: .none, additionalParameters: additionalParameters) } } } class SupportedTypesHolder { - typealias ParametersDecoder = (Decoder) throws -> (item: ItemType, action: ActionType, tapAction: TapAction, longTapAction: LongTapAction, parameters: [GeneralParameters.CodingKeys: GeneralParameter]) + typealias ParametersDecoder = (Decoder) throws ->(item: ItemType, action: ActionType, longAction: LongActionType, parameters: [GeneralParameters.CodingKeys: GeneralParameter]) private var supportedTypes: [String: ParametersDecoder] = [ - "escape": { _ in return ( - item: .staticButton(title: "esc"), - action: .keyPress(keycode: 53), - tapAction: TapAction(actionType: TapActionType.keyPress, keycode: 53), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.align: .align(.left)] - ) - }, - "delete": { _ in return ( - item: .staticButton(title: "del"), - action: .keyPress(keycode: 117), - tapAction: TapAction(actionType: TapActionType.keyPress, keycode: 117), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) - }, + "escape": { _ in return (item: .staticButton(title: "esc"), action: .keyPress(keycode: 53), longAction: .none, parameters: [.align: .align(.left)]) }, + "delete": { _ in return (item: .staticButton(title: "del"), action: .keyPress(keycode: 117), longAction: .none, parameters: [:])}, "brightnessUp": { _ in let imageParameter = GeneralParameter.image(source: #imageLiteral(resourceName: "brightnessUp")) - return ( - item: .staticButton(title: ""), - action: .hidKey(keycode: Int(NX_KEYTYPE_BRIGHTNESS_UP)), - tapAction: TapAction(actionType: TapActionType.hidKey, keycode: Int(NX_KEYTYPE_BRIGHTNESS_UP)), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.image: imageParameter] - ) + return (item: .staticButton(title: ""), action: .keyPress(keycode: 113), longAction: .none, parameters: [.image: imageParameter]) }, "brightnessDown": { _ in let imageParameter = GeneralParameter.image(source: #imageLiteral(resourceName: "brightnessDown")) - return ( - item: .staticButton(title: ""), - action: .hidKey(keycode: Int(NX_KEYTYPE_BRIGHTNESS_DOWN)), - tapAction: TapAction(actionType: TapActionType.hidKey, keycode: Int(NX_KEYTYPE_BRIGHTNESS_DOWN)), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.image: imageParameter] - ) + return (item: .staticButton(title: ""), action: .keyPress(keycode: 107), longAction: .none, parameters: [.image: imageParameter]) }, "volumeDown": { _ in let imageParameter = GeneralParameter.image(source: NSImage(named: .touchBarVolumeDownTemplate)!) - return ( - item: .staticButton(title: ""), - action: .hidKey(keycode: Int(NX_KEYTYPE_SOUND_DOWN)), - tapAction: TapAction(actionType: TapActionType.hidKey, keycode: Int(NX_KEYTYPE_SOUND_DOWN)), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.image: imageParameter] - ) + return (item: .staticButton(title: ""), action: .hidKey(keycode: NX_KEYTYPE_SOUND_DOWN), longAction: .none, parameters: [.image: imageParameter]) }, "volumeUp": { _ in let imageParameter = GeneralParameter.image(source: NSImage(named: .touchBarVolumeUpTemplate)!) - return ( - item: .staticButton(title: ""), - action: .hidKey(keycode: Int(NX_KEYTYPE_SOUND_UP)), - tapAction: TapAction(actionType: TapActionType.hidKey, keycode: Int(NX_KEYTYPE_SOUND_UP)), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.image: imageParameter] - ) + return (item: .staticButton(title: ""), action: .hidKey(keycode: NX_KEYTYPE_SOUND_UP), longAction: .none, parameters: [.image: imageParameter]) }, "mute": { _ in let imageParameter = GeneralParameter.image(source: NSImage(named: .touchBarAudioOutputMuteTemplate)!) - return ( - item: .staticButton(title: ""), - action: .hidKey(keycode: Int(NX_KEYTYPE_MUTE)), - tapAction: TapAction(actionType: TapActionType.hidKey, keycode: Int(NX_KEYTYPE_MUTE)), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.image: imageParameter] - ) + return (item: .staticButton(title: ""), action: .hidKey(keycode: NX_KEYTYPE_MUTE), longAction: .none, parameters: [.image: imageParameter]) }, "previous": { _ in let imageParameter = GeneralParameter.image(source: NSImage(named: .touchBarRewindTemplate)!) - return ( - item: .staticButton(title: ""), - action: .hidKey(keycode: Int(NX_KEYTYPE_PREVIOUS)), - tapAction: TapAction(actionType: TapActionType.hidKey, keycode: Int(NX_KEYTYPE_PREVIOUS)), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.image: imageParameter] - ) + return (item: .staticButton(title: ""), action: .hidKey(keycode: NX_KEYTYPE_PREVIOUS), longAction: .none, parameters: [.image: imageParameter]) }, "play": { _ in let imageParameter = GeneralParameter.image(source: NSImage(named: .touchBarPlayPauseTemplate)!) - return ( - item: .staticButton(title: ""), - action: .hidKey(keycode: Int(NX_KEYTYPE_PLAY)), - tapAction: TapAction(actionType: TapActionType.hidKey, keycode: Int(NX_KEYTYPE_PLAY)), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.image: imageParameter] - ) + return (item: .staticButton(title: ""), action: .hidKey(keycode: NX_KEYTYPE_PLAY), longAction: .none, parameters: [.image: imageParameter]) }, "next": { _ in let imageParameter = GeneralParameter.image(source: NSImage(named: .touchBarFastForwardTemplate)!) - return ( - item: .staticButton(title: ""), - action: .hidKey(keycode: Int(NX_KEYTYPE_NEXT)), - tapAction: TapAction(actionType: TapActionType.hidKey, keycode: Int(NX_KEYTYPE_NEXT)), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.image: imageParameter] - ) + return (item: .staticButton(title: ""), action: .hidKey(keycode: NX_KEYTYPE_NEXT), longAction: .none, parameters: [.image: imageParameter]) }, "weather": { decoder in - enum CodingKeys: String, CodingKey { case refreshInterval; case units; case api_key ; case icon_type; case tapAction; case longTapAction } + enum CodingKeys: String, CodingKey { case refreshInterval; case units; case api_key ; case icon_type } let container = try decoder.container(keyedBy: CodingKeys.self) let interval = try container.decodeIfPresent(Double.self, forKey: .refreshInterval) let units = try container.decodeIfPresent(String.self, forKey: .units) let api_key = try container.decodeIfPresent(String.self, forKey: .api_key) let icon_type = try container.decodeIfPresent(String.self, forKey: .icon_type) let action = try ActionType(from: decoder) - let tapAction = try container.decodeIfPresent(TapAction.self, forKey: .tapAction) - let longTapAction = try container.decodeIfPresent(LongTapAction.self, forKey: .longTapAction) - return ( - item: .weather(interval: interval ?? 1800.00,units: units ?? "metric", api_key: api_key ?? "32c4256d09a4c52b38aecddba7a078f6", icon_type: icon_type ?? "text"), - action: action, - tapAction: tapAction ?? TapAction(actionType: TapActionType.none), - longTapAction: longTapAction ?? LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) + let longAction = try LongActionType(from: decoder) + return (item: .weather(interval: interval ?? 1800.00, units: units ?? "metric", api_key: api_key ?? "32c4256d09a4c52b38aecddba7a078f6", icon_type: icon_type ?? "text"), action: action, longAction: longAction, parameters: [:]) }, "currency": { decoder in - enum CodingKeys: String, CodingKey { case refreshInterval; case from; case to; case tapAction; case longTapAction } + enum CodingKeys: String, CodingKey { case refreshInterval; case from; case to } let container = try decoder.container(keyedBy: CodingKeys.self) let interval = try container.decodeIfPresent(Double.self, forKey: .refreshInterval) let from = try container.decodeIfPresent(String.self, forKey: .from) let to = try container.decodeIfPresent(String.self, forKey: .to) let action = try ActionType(from: decoder) - let tapAction = try container.decodeIfPresent(TapAction.self, forKey: .tapAction) - let longTapAction = try container.decodeIfPresent(LongTapAction.self, forKey: .longTapAction) - return ( - item: .currency(interval: interval ?? 600.00, from: from ?? "RUB", to: to ?? "USD"), - action: action, - tapAction: tapAction ?? TapAction(actionType: TapActionType.none), - longTapAction: longTapAction ?? LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) + let longAction = try LongActionType(from: decoder) + return (item: .currency(interval: interval ?? 600.00, from: from ?? "RUB", to: to ?? "USD"), action: action, longAction: longAction, parameters: [:]) }, "dock": { decoder in - return ( - item: .dock(), - action: .none, - tapAction: TapAction(actionType: TapActionType.none), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) + return (item: .dock(), action: .none, longAction: .none, parameters: [:]) }, "inputsource": { decoder in - enum CodingKeys: String, CodingKey { case longTapAction } - let container = try decoder.container(keyedBy: CodingKeys.self) - let longTapAction = try container.decodeIfPresent(LongTapAction.self, forKey: .longTapAction) - return ( - item: .inputsource(), - action: .none, - tapAction: TapAction(actionType: TapActionType.none), - longTapAction: longTapAction ?? LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) - }, - "battery": { decoder in - enum CodingKeys: String, CodingKey { case tapAction; case longTapAction } - let container = try decoder.container(keyedBy: CodingKeys.self) - let action = try ActionType(from: decoder) - let tapAction = try container.decodeIfPresent(TapAction.self, forKey: .tapAction) - let longTapAction = try container.decodeIfPresent(LongTapAction.self, forKey: .longTapAction) - return ( - item: .battery(), - action: action, - tapAction: tapAction ?? TapAction(actionType: TapActionType.none), - longTapAction: longTapAction ?? LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) - }, - "timeButton": { decoder in - enum CodingKeys: String, CodingKey { case formatTemplate; case tapAction; case longTapAction } - let container = try decoder.container(keyedBy: CodingKeys.self) - let template = try container.decodeIfPresent(String.self, forKey: .formatTemplate) ?? "HH:mm" - let action = try ActionType(from: decoder) - let tapAction = try container.decodeIfPresent(TapAction.self, forKey: .tapAction) - let longTapAction = try container.decodeIfPresent(LongTapAction.self, forKey: .longTapAction) - return ( - item: .timeButton(formatTemplate: template), - action: action, - tapAction: tapAction ?? TapAction(actionType: TapActionType.none), - longTapAction: longTapAction ?? LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) + return (item: .inputsource(), action: .none, longAction: .none, parameters: [:]) }, "volume": { decoder in enum CodingKeys: String, CodingKey { case image } let container = try decoder.container(keyedBy: CodingKeys.self) if var img = try container.decodeIfPresent(Source.self, forKey: .image) { - return ( - item: .volume(), - action: .none, - tapAction: TapAction(actionType: TapActionType.none), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.image: .image(source: img)] - ) + return (item: .volume(), action: .none, longAction: .none, parameters: [.image: .image(source: img)]) } else { - return ( - item: .volume(), - action: .none, - tapAction: TapAction(actionType: TapActionType.none), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) + return (item: .volume(), action: .none, longAction: .none, parameters: [:]) } }, "brightness": { decoder in @@ -265,46 +118,20 @@ class SupportedTypesHolder { let container = try decoder.container(keyedBy: CodingKeys.self) let interval = try container.decodeIfPresent(Double.self, forKey: .refreshInterval) if var img = try container.decodeIfPresent(Source.self, forKey: .image) { - return ( - item: .brightness(refreshInterval: interval ?? 0.5), - action: .none, - tapAction: TapAction(actionType: TapActionType.none), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [.image: .image(source: img)] - ) + return (item: .brightness(refreshInterval: interval ?? 0.5), action: .none, longAction: .none, parameters: [.image: .image(source: img)]) } else { - return ( - item: .brightness(refreshInterval: interval ?? 0.5), - action: .none, - tapAction: TapAction(actionType: TapActionType.none), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) + return (item: .brightness(refreshInterval: interval ?? 0.5), action: .none, longAction: .none, parameters: [:]) } }, - "sleep": { _ in return ( - item: .staticButton(title: "☕️"), - action: .shellScript(executable: "/usr/bin/pmset", parameters: ["sleepnow"]), - tapAction: TapAction(actionType: TapActionType.shellScript, executablePath: "/usr/bin/pmset", shellArguments: ["sleepnow"]), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) - }, - "displaySleep": { _ in return ( - item: .staticButton(title: "☕️"), - action: .shellScript(executable: "/usr/bin/pmset",parameters: ["displaysleepnow"]), - tapAction: TapAction(actionType: TapActionType.shellScript, executablePath: "/usr/bin/pmset", shellArguments: ["displaysleepnow"]), - longTapAction: LongTapAction(actionType: TapActionType.none), - parameters: [:] - ) - }, + "sleep": { _ in return (item: .staticButton(title: "☕️"), action: .shellScript(executable: "/usr/bin/pmset", parameters: ["sleepnow"]), longAction: .none, parameters: [:]) }, + "displaySleep": { _ in return (item: .staticButton(title: "☕️"), action: .shellScript(executable: "/usr/bin/pmset", parameters: ["displaysleepnow"]), longAction: .none, parameters: [:])}, ] static let sharedInstance = SupportedTypesHolder() func lookup(by type: String) -> ParametersDecoder { return supportedTypes[type] ?? { decoder in - return (item: try ItemType(from: decoder), action: try ActionType(from: decoder), tapAction: try TapAction(from: decoder), longTapAction: try LongTapAction(from: decoder), parameters: [:]) + return (item: try ItemType(from: decoder), action: try ActionType(from: decoder), longAction: try LongActionType(from: decoder), parameters: [:]) } } @@ -312,14 +139,13 @@ class SupportedTypesHolder { supportedTypes[typename] = decoder } - func register(typename: String, item: ItemType, action: ActionType? = .none, tapAction: TapAction? = TapAction(actionType: TapActionType.none), longTapAction: LongTapAction? = LongTapAction(actionType: TapActionType.none)) { + func register(typename: String, item: ItemType, action: ActionType, longAction: LongActionType) { register(typename: typename) { _ in - return (item: item, action: action!, tapAction: tapAction!, longTapAction: longTapAction!, parameters: [:]) + return (item: item, action: action, longAction: longAction, parameters: [:]) } } } - enum ItemType: Decodable { case staticButton(title: String) case appleScriptTitledButton(source: SourceProtocol, refreshInterval: Double) @@ -453,6 +279,59 @@ enum ActionType: Decodable { } } + +enum LongActionType: Decodable { + case none + case hidKey(keycode: Int) + case keyPress(keycode: Int) + case appleSctipt(source: SourceProtocol) + case shellScript(executable: String, parameters: [String]) + case custom(closure: ()->()) + case openUrl(url: String) + + private enum CodingKeys: String, CodingKey { + case longAction + case keycode + case actionAppleScript + case executablePath + case shellArguments + case longUrl + } + + private enum LongActionTypeRaw: String, Decodable { + case hidKey + case keyPress + case appleScript + case shellScript + case openUrl + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let longType = try container.decodeIfPresent(LongActionTypeRaw.self, forKey: .longAction) + switch longType { + case .some(.hidKey): + let keycode = try container.decode(Int.self, forKey: .keycode) + self = .hidKey(keycode: keycode) + case .some(.keyPress): + let keycode = try container.decode(Int.self, forKey: .keycode) + self = .keyPress(keycode: keycode) + case .some(.appleScript): + let source = try container.decode(Source.self, forKey: .actionAppleScript) + self = .appleSctipt(source: source) + case .some(.shellScript): + let executable = try container.decode(String.self, forKey: .executablePath) + let parameters = try container.decodeIfPresent([String].self, forKey: .shellArguments) ?? [] + self = .shellScript(executable: executable, parameters: parameters) + case .some(.openUrl): + let longUrl = try container.decode(String.self, forKey: .longUrl) + self = .openUrl(url: longUrl) + case .none: + self = .none + } + } +} + extension ItemType: Equatable {} func ==(lhs: ItemType, rhs: ItemType) -> Bool { switch (lhs, rhs) { @@ -485,6 +364,26 @@ func ==(lhs: ActionType, rhs: ActionType) -> Bool { } } + +extension LongActionType: Equatable {} +func ==(lhs: LongActionType, rhs: LongActionType) -> Bool { + switch (lhs, rhs) { + case (.none, .none): + return true + case let (.hidKey(a), .hidKey(b)), + let (.keyPress(a), .keyPress(b)): + return a == b + case let (.appleSctipt(a), .appleSctipt(b)): + return a == b + case let (.shellScript(a, b), .shellScript(c, d)): + return a == c && b == d + case let (.openUrl(a), .openUrl(b)): + return a == b + default: + return false + } +} + enum GeneralParameter { case width(_: CGFloat) case image(source: SourceProtocol) @@ -586,146 +485,3 @@ enum Align: String, Decodable { case center case right } - -struct TapAction: Codable { - let actionType: TapActionType - let url: String? - let keycode: Int - let appleScript: String? - let executablePath: String? - let shellArguments: [String]? - let custom: () -> ()? - - enum CodingKeys: String, CodingKey { - case actionType = "type" - case url - case keycode - case appleScript - case executablePath - case shellArguments - } - - init(actionType: TapActionType, url: String? = "", keycode: Int? = -1, appleScript: String? = "", executablePath: String? = "", shellArguments: [String]? = [], custom: @escaping () -> Void? = {return}) { - self.actionType = actionType - self.url = url - self.keycode = keycode! - self.appleScript = appleScript - self.executablePath = executablePath - self.shellArguments = shellArguments - self.custom = custom - } - - init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let actionType = try container.decode(TapActionType.self, forKey: .actionType) - let url = try container.decodeIfPresent(String.self, forKey: .url) ?? "" - let keycode = try container.decodeIfPresent(Int.self, forKey: .keycode) ?? -1 - var appleScript = try container.decodeIfPresent(String.self, forKey: .appleScript) - do { - if let test = appleScript?.fileData?.utf8string { - appleScript = test - } else if let test = appleScript?.base64Data?.utf8string { - appleScript = test - } - } catch { - print("error") - } - let executablePath = try container.decodeIfPresent(String.self, forKey: .executablePath) ?? "" - let shellArguments = try container.decodeIfPresent([String].self, forKey: .shellArguments) ?? [] - self.init(actionType: actionType, url: url, keycode: keycode, appleScript: appleScript, executablePath: executablePath, shellArguments: shellArguments) - } -} - -struct LongTapAction: Codable { - let actionType: TapActionType - let url: String? - let keycode: Int - let appleScript: String? - let executablePath: String? - let shellArguments: [String]? - let custom: () -> ()? - - enum CodingKeys: String, CodingKey { - case actionType = "type" - case url - case keycode - case appleScript - case executablePath - case shellArguments - } - - init(actionType: TapActionType, url: String? = "", keycode: Int? = -1, appleScript: String? = "", executablePath: String? = "", shellArguments: [String]? = [], custom: @escaping () -> Void? = {return}) { - self.actionType = actionType - self.url = url - self.keycode = keycode! - self.appleScript = appleScript - self.executablePath = executablePath - self.shellArguments = shellArguments - self.custom = custom - } - - init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let actionType = try container.decode(TapActionType.self, forKey: .actionType) - let url = try container.decodeIfPresent(String.self, forKey: .url) ?? "" - let keycode = try container.decodeIfPresent(Int.self, forKey: .keycode) ?? -1 - var appleScript = try container.decodeIfPresent(String.self, forKey: .appleScript) - do { - if let test = appleScript?.fileData?.utf8string { - appleScript = test - } else if let test = appleScript?.base64Data?.utf8string { - appleScript = test - } - } catch { - print("error") - } - let executablePath = try container.decodeIfPresent(String.self, forKey: .executablePath) ?? "" - let shellArguments = try container.decodeIfPresent([String].self, forKey: .shellArguments) ?? [] - self.init(actionType: actionType, url: url, keycode: keycode, appleScript: appleScript, executablePath: executablePath, shellArguments: shellArguments) - } -} - -enum TapActionType: Codable { - func encode(to encoder: Encoder) throws { - - } - - case none - case hidKey - case keyPress - case appleScript - case shellScript - case custom - case openUrl - - private enum CodingKeys: String, CodingKey { - case type - } - - private enum ActionTypeRaw: String, Decodable { - case hidKey - case keyPress - case appleScript - case shellScript - case openUrl - } - - init(from decoder: Decoder) throws { - self = .none - - let container = try decoder.singleValueContainer() - let actionType = try container.decode(ActionTypeRaw.self) - switch actionType { - case .hidKey: - self = .hidKey - case .keyPress: - self = .keyPress - case .appleScript: - self = .appleScript - case .shellScript: - self = .shellScript - case .openUrl: - self = .openUrl - } - } -} diff --git a/MTMR/KeyPress.swift b/MTMR/KeyPress.swift index 02bbaab..fe0f109 100644 --- a/MTMR/KeyPress.swift +++ b/MTMR/KeyPress.swift @@ -56,30 +56,18 @@ func HIDPostAuxKey(_ key: Int) { // hidsystem/ev_keymap.h -let NX_KEYTYPE_SOUND_UP = 0 +let NX_KEYTYPE_SOUND_UP = 0 let NX_KEYTYPE_SOUND_DOWN = 1 -let NX_KEYTYPE_BRIGHTNESS_UP = 2 -let NX_KEYTYPE_BRIGHTNESS_DOWN = 3 -let NX_KEYTYPE_CAPS_LOCK = 4 -let NX_KEYTYPE_HELP = 5 -let NX_POWER_KEY = 6 let NX_KEYTYPE_MUTE = 7 -let NX_UP_ARROW_KEY = 8 -let NX_DOWN_ARROW_KEY = 9 -let NX_KEYTYPE_NUM_LOCK = 10 -let NX_KEYTYPE_CONTRAST_UP = 11 -let NX_KEYTYPE_CONTRAST_DOWN = 12 -let NX_KEYTYPE_LAUNCH_PANEL = 13 -let NX_KEYTYPE_EJECT = 14 -let NX_KEYTYPE_VIDMIRROR = 15 +let NX_KEYTYPE_BRIGHTNESS_UP = 2 +let NX_KEYTYPE_BRIGHTNESS_DOWN = 3 + +let NX_KEYTYPE_PLAY = 16 +let NX_KEYTYPE_NEXT = 17 +let NX_KEYTYPE_PREVIOUS = 18 + + + -let NX_KEYTYPE_PLAY = 16 -let NX_KEYTYPE_NEXT = 17 -let NX_KEYTYPE_PREVIOUS = 18 -let NX_KEYTYPE_FAST = 19 -let NX_KEYTYPE_REWIND = 20 -let NX_KEYTYPE_ILLUMINATION_UP = 21 -let NX_KEYTYPE_ILLUMINATION_DOWN = 22 -let NX_KEYTYPE_ILLUMINATION_TOGGLE = 23 diff --git a/MTMR/TouchBarController.swift b/MTMR/TouchBarController.swift index 50b2129..a3b28ca 100644 --- a/MTMR/TouchBarController.swift +++ b/MTMR/TouchBarController.swift @@ -63,7 +63,7 @@ class TouchBarController: NSObject, NSTouchBarDelegate { private override init() { super.init() - SupportedTypesHolder.sharedInstance.register(typename: "exitTouchbar", item: .staticButton(title: "exit"), action: .custom(closure: { [weak self] in self?.dismissTouchBar()})) + SupportedTypesHolder.sharedInstance.register(typename: "exitTouchbar", item: .staticButton(title: "exit"), action: .custom(closure: { [weak self] in self?.dismissTouchBar()}), longAction: .none) createAndUpdatePreset() } @@ -110,7 +110,7 @@ class TouchBarController: NSObject, NSTouchBarDelegate { let jsonData = presetPath.fileData - return jsonData?.barItemDefinitions() ?? [BarItemDefinition(type: .staticButton(title: "bad preset"))] + return jsonData?.barItemDefinitions() ?? [BarItemDefinition(type: .staticButton(title: "bad preset"), action: .none, longAction: .none, additionalParameters: [:])] } func loadItemDefinitions(jsonItems: [BarItemDefinition]) { @@ -173,24 +173,19 @@ class TouchBarController: NSObject, NSTouchBarDelegate { } func createItem(forIdentifier identifier: NSTouchBarItem.Identifier, definition item: BarItemDefinition) -> NSTouchBarItem? { - var action = self.action(forItem: item) - let longTapAction = self.longTapAction(forItem: item) - let tapAction = self.tapAction(forItem: item) - - if item.action == .none { - action = tapAction - } + 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: longTapAction, bezelColor: NSColor.controlColor) + barItem = CustomButtonTouchBarItem(identifier: identifier, title: title, onTap: action, onLongTap: longAction, bezelColor: NSColor.controlColor) case .appleScriptTitledButton(source: let source, refreshInterval: let interval): - barItem = AppleScriptTouchBarItem(identifier: identifier, source: source, interval: interval, onTap: action, onLongTap: longTapAction) + barItem = AppleScriptTouchBarItem(identifier: identifier, source: source, interval: interval, onTap: action, onLongTap: longAction) case .timeButton(formatTemplate: let template): - barItem = TimeTouchBarItem(identifier: identifier, formatTemplate: template, onTap: action, onLongTap: longTapAction) + barItem = TimeTouchBarItem(identifier: identifier, formatTemplate: template, onTap: action, onLongTap: longAction) case .battery(): - barItem = BatteryBarItem(identifier: identifier, onTap: action, onLongTap: longTapAction) + barItem = BatteryBarItem(identifier: identifier, onTap: action, onLongTap: longAction) case .dock: barItem = AppScrubberTouchBarItem(identifier: identifier) case .volume: @@ -206,11 +201,11 @@ 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: longTapAction) + barItem = WeatherBarItem(identifier: identifier, interval: interval, units: units, api_key: api_key, icon_type: icon_type, onTap: action, onLongTap: longAction) case .currency(interval: let interval, from: let from, to: let to): - barItem = CurrencyBarItem(identifier: identifier, interval: interval, from: from, to: to, onTap: action, onLongTap: longTapAction) + barItem = CurrencyBarItem(identifier: identifier, interval: interval, from: from, to: to, onTap: action, onLongTap: longAction) case .inputsource(): - barItem = InputSourceBarItem(identifier: identifier, onLongTap: longTapAction) + barItem = InputSourceBarItem(identifier: identifier, onTap: action, onLongTap: longAction) } if case .width(let value)? = item.additionalParameters[.width], let widthBarItem = barItem as? CanSetWidth { @@ -268,79 +263,47 @@ class TouchBarController: NSObject, NSTouchBarDelegate { return {} } } + - - func longTapAction(forItem item: BarItemDefinition) -> ()->() { - switch item.longTapAction.actionType { - case TapActionType.hidKey: - return { HIDPostAuxKey(item.longTapAction.keycode) } - case TapActionType.keyPress: - return { GenericKeyPress(keyCode: CGKeyCode(item.longTapAction.keycode)).send() } - case TapActionType.appleScript: + func longAction(forItem item: BarItemDefinition) -> ()->() { + switch item.longAction { + case .hidKey(keycode: let keycode): + return { HIDPostAuxKey(keycode) } + case .keyPress(keycode: let keycode): + return { GenericKeyPress(keyCode: CGKeyCode(keycode)).send() } + case .appleSctipt(source: let source): + guard let appleScript = source.appleScript else { + print("cannot create apple script for item \(item)") + return {} + } return { - let appleScriptSource = NSAppleScript(source: item.longTapAction.appleScript!) var error: NSDictionary? - appleScriptSource?.executeAndReturnError(&error) + appleScript.executeAndReturnError(&error) if let error = error { print("error \(error) when handling \(item) ") } } - case TapActionType.shellScript: + case .shellScript(executable: let executable, parameters: let parameters): return { let task = Process() - task.launchPath = item.longTapAction.executablePath - task.arguments = item.longTapAction.shellArguments + task.launchPath = executable + task.arguments = parameters task.launch() } - case TapActionType.openUrl: + case .openUrl(url: let url): return { - if let url = URL(string: item.longTapAction.url!), NSWorkspace.shared.open(url) { + if let url = URL(string: url), NSWorkspace.shared.open(url) { #if DEBUG print("URL was successfully opened") #endif + } else { + print("error", url) } } - case TapActionType.none: + case .custom(closure: let closure): + return closure + case .none: return {} - case TapActionType.custom: - return item.longTapAction.custom as! () -> () - } - } - - func tapAction(forItem item: BarItemDefinition) -> ()->() { - switch item.tapAction.actionType { - case TapActionType.hidKey: - return { HIDPostAuxKey(item.tapAction.keycode) } - case TapActionType.keyPress: - return { GenericKeyPress(keyCode: CGKeyCode(item.tapAction.keycode)).send() } - case TapActionType.appleScript: - return { - let appleScriptSource = NSAppleScript(source: item.tapAction.appleScript!) - var error: NSDictionary? - appleScriptSource?.executeAndReturnError(&error) - if let error = error { - print("error \(error) when handling \(item) ") - } - } - case TapActionType.shellScript: - return { - let task = Process() - task.launchPath = item.tapAction.executablePath - task.arguments = item.tapAction.shellArguments - task.launch() - } - case TapActionType.openUrl: - return { - if let url = URL(string: item.tapAction.url!), NSWorkspace.shared.open(url) { - #if DEBUG - print("URL was successfully opened") - #endif - } - } - case TapActionType.none: - return {} - case TapActionType.custom: - return item.tapAction.custom as! () -> () } } } diff --git a/MTMR/Widgets/InputSourceBarItem.swift b/MTMR/Widgets/InputSourceBarItem.swift index 0e208d0..f32abd0 100644 --- a/MTMR/Widgets/InputSourceBarItem.swift +++ b/MTMR/Widgets/InputSourceBarItem.swift @@ -13,9 +13,9 @@ class InputSourceBarItem: CustomButtonTouchBarItem { fileprivate var notificationCenter: CFNotificationCenter let buttonSize = NSSize(width: 21, height: 21) - init(identifier: NSTouchBarItem.Identifier, onLongTap: @escaping () -> ()) { + init(identifier: NSTouchBarItem.Identifier, onTap: @escaping () -> (), onLongTap: @escaping () -> ()) { notificationCenter = CFNotificationCenterGetDistributedCenter(); - super.init(identifier: identifier, title: "⏳", onTap: onLongTap, onLongTap: onLongTap) + super.init(identifier: identifier, title: "⏳", onTap: onTap, onLongTap: onLongTap) observeIputSourceChangedNotification(); textInputSourceDidChange()