Skip to content

Commit

Permalink
Implemented changable icons for AppleScriptTouchBarItem (#275)
Browse files Browse the repository at this point in the history
AppleScriptTouchBarItem now allow to specify any number of icons which can be changed from the script. You cannot change icon from touch event. To change icon, you need to return array from your script with 2 values - title and icn name. More info in readme
  • Loading branch information
FedorZaytsev committed Feb 28, 2020
1 parent 3864591 commit dbb2f16
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 6 deletions.
26 changes: 25 additions & 1 deletion MTMR/AppleScriptTouchBarItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ class AppleScriptTouchBarItem: CustomButtonTouchBarItem {
private var script: NSAppleScript!
private let interval: TimeInterval
private var forceHideConstraint: NSLayoutConstraint!
private let alternativeImages: [String: SourceProtocol]

init?(identifier: NSTouchBarItem.Identifier, source: SourceProtocol, interval: TimeInterval) {
init?(identifier: NSTouchBarItem.Identifier, source: SourceProtocol, interval: TimeInterval, alternativeImages: [String: SourceProtocol]) {
self.interval = interval
self.alternativeImages = alternativeImages
super.init(identifier: identifier, title: "")
forceHideConstraint = view.widthAnchor.constraint(equalToConstant: 0)
title = "scheduled"
Expand Down Expand Up @@ -57,13 +59,35 @@ class AppleScriptTouchBarItem: CustomButtonTouchBarItem {
}
}

func updateIcon(iconLabel: String) {
if alternativeImages[iconLabel] != nil {
DispatchQueue.main.async {
self.image = self.alternativeImages[iconLabel]!.image
}
} else {
print("Cannot find icon with label \"\(iconLabel)\"")
}
}

func execute() -> String {
var error: NSDictionary?
let output = script.executeAndReturnError(&error)
if let error = error {
print(error)
return "error"
}
if output.descriptorType == typeAEList {
let arr = Array(1...output.numberOfItems).compactMap({ output.atIndex($0)!.stringValue ?? "" })

if arr.count <= 0 {
return ""
} else if arr.count == 1 {
return arr[0]
} else {
updateIcon(iconLabel: arr[1])
return arr[0]
}
}
return output.stringValue ?? ""
}
}
Expand Down
6 changes: 4 additions & 2 deletions MTMR/ItemsParsing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class SupportedTypesHolder {

enum ItemType: Decodable {
case staticButton(title: String)
case appleScriptTitledButton(source: SourceProtocol, refreshInterval: Double)
case appleScriptTitledButton(source: SourceProtocol, refreshInterval: Double, alternativeImages: [String: SourceProtocol])
case shellScriptTitledButton(source: SourceProtocol, refreshInterval: Double)
case timeButton(formatTemplate: String, timeZone: String?, locale: String?)
case battery
Expand Down Expand Up @@ -251,6 +251,7 @@ enum ItemType: Decodable {
case autoResize
case filter
case disableMarquee
case alternativeImages
}

enum ItemTypeRaw: String, Decodable {
Expand Down Expand Up @@ -282,7 +283,8 @@ enum ItemType: Decodable {
case .appleScriptTitledButton:
let source = try container.decode(Source.self, forKey: .source)
let interval = try container.decodeIfPresent(Double.self, forKey: .refreshInterval) ?? 1800.0
self = .appleScriptTitledButton(source: source, refreshInterval: interval)
let alternativeImages = try container.decodeIfPresent([String: Source].self, forKey: .alternativeImages) ?? [:]
self = .appleScriptTitledButton(source: source, refreshInterval: interval, alternativeImages: alternativeImages)

case .shellScriptTitledButton:
let source = try container.decode(Source.self, forKey: .source)
Expand Down
4 changes: 2 additions & 2 deletions MTMR/TouchBarController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
switch item.type {
case let .staticButton(title: title):
barItem = CustomButtonTouchBarItem(identifier: identifier, title: title)
case let .appleScriptTitledButton(source: source, refreshInterval: interval):
barItem = AppleScriptTouchBarItem(identifier: identifier, source: source, interval: interval)
case let .appleScriptTitledButton(source: source, refreshInterval: interval, alternativeImages: alternativeImages):
barItem = AppleScriptTouchBarItem(identifier: identifier, source: source, interval: interval, alternativeImages: alternativeImages)
case let .shellScriptTitledButton(source: source, refreshInterval: interval):
barItem = ShellScriptTouchBarItem(identifier: identifier, source: source, interval: interval)
case let .timeButton(formatTemplate: template, timeZone: timeZone, locale: locale):
Expand Down
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,37 @@ The pre-installed configuration contains less or more than you'll probably want,
"inline": "tell application \"Finder\"\rif not (exists window 1) then\rmake new Finder window\rset target of front window to path to home folder as string\rend if\ractivate\rend tell",
// or
"base64": "StringInbase64"
}
},
}
```

> Note: appleScriptTitledButton can change its icon. To do it, you need to do the following things:
1. Declarate dictionary of icons in `alternativeImages` field
2. Make you script return array of two values - `{"TITLE", "IMAGE_LABEL"}`
3. Make sure that your `IMAGE_LABEL` is declared in `alternativeImages` field

Example:
```js
{
"type": "appleScriptTitledButton",
"source": {
"inline": "if (random number from 1 to 2) = 1 then\n\tset val to {\"title\", \"play\"}\nelse\n\tset val to {\"title\", \"pause\"}\nend if\nreturn val"
},
"refreshInterval": 1,
"image": {
"base64": "iVBORw0KGgoAAAANSUhEUgA..."
},
"alternativeImages": {
"play": {
"base64": "iVBORw0KGgoAAAANSUhEUgAAAAAA..."
},
"pause": {
"base64": "iVBORw0KGgoAAAANSUhEUgAAAIAA..."
}
}
},
```

#### `shellScriptTitledButton`
> Note: script may return also colors using escape sequences (read more here https://misc.flogisoft.com/bash/tip_colors_and_formatting)
> Only "16 Colors" mode supported atm. If background color returned, button will pick it up as own background color.
Expand Down

0 comments on commit dbb2f16

Please sign in to comment.