mirror of
https://github.com/Toxblh/MTMR.git
synced 2026-01-10 17:08:39 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
9abb17ee76
@ -21,6 +21,7 @@
|
||||
607EEA4B2087835F009DA5F0 /* WeatherBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607EEA4A2087835F009DA5F0 /* WeatherBarItem.swift */; };
|
||||
607EEA4D2087A8DA009DA5F0 /* CurrencyBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607EEA4C2087A8DA009DA5F0 /* CurrencyBarItem.swift */; };
|
||||
B0008E552080286C003AD4DD /* SupportHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0008E542080286C003AD4DD /* SupportHelpers.swift */; };
|
||||
B04B7BB72087398C00C835D0 /* BatteryBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B04B7BB62087398C00C835D0 /* BatteryBarItem.swift */; };
|
||||
B05600D32083E9BB00EB218D /* CustomSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B05600D22083E9BB00EB218D /* CustomSlider.swift */; };
|
||||
B059D622205E03F5006E6B86 /* TouchBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B059D621205E03F5006E6B86 /* TouchBarController.swift */; };
|
||||
B059D624205E04F3006E6B86 /* CustomButtonTouchBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B059D623205E04F3006E6B86 /* CustomButtonTouchBarItem.swift */; };
|
||||
@ -71,6 +72,7 @@
|
||||
607EEA4A2087835F009DA5F0 /* WeatherBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherBarItem.swift; sourceTree = "<group>"; };
|
||||
607EEA4C2087A8DA009DA5F0 /* CurrencyBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyBarItem.swift; sourceTree = "<group>"; };
|
||||
B0008E542080286C003AD4DD /* SupportHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportHelpers.swift; sourceTree = "<group>"; };
|
||||
B04B7BB62087398C00C835D0 /* BatteryBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryBarItem.swift; sourceTree = "<group>"; };
|
||||
B05600D22083E9BB00EB218D /* CustomSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomSlider.swift; sourceTree = "<group>"; };
|
||||
B059D621205E03F5006E6B86 /* TouchBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouchBarController.swift; sourceTree = "<group>"; };
|
||||
B059D623205E04F3006E6B86 /* CustomButtonTouchBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomButtonTouchBarItem.swift; sourceTree = "<group>"; };
|
||||
@ -176,6 +178,7 @@
|
||||
368EDDE620812A1D00E10953 /* ScrollViewItem.swift */,
|
||||
6042B6A62083E03A00C525C8 /* AppScrubberTouchBarItem.swift */,
|
||||
B05600D22083E9BB00EB218D /* CustomSlider.swift */,
|
||||
B04B7BB62087398C00C835D0 /* BatteryBarItem.swift */,
|
||||
607EEA4A2087835F009DA5F0 /* WeatherBarItem.swift */,
|
||||
607EEA4C2087A8DA009DA5F0 /* CurrencyBarItem.swift */,
|
||||
);
|
||||
@ -355,6 +358,7 @@
|
||||
607EEA4D2087A8DA009DA5F0 /* CurrencyBarItem.swift in Sources */,
|
||||
6027D1B92080E52A004FFDC7 /* BrightnessViewController.swift in Sources */,
|
||||
368EDDE720812A1D00E10953 /* ScrollViewItem.swift in Sources */,
|
||||
B04B7BB72087398C00C835D0 /* BatteryBarItem.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@ -13,7 +13,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
let statusItem = NSStatusBar.system.statusItem(withLength:NSStatusItem.squareLength)
|
||||
|
||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||
// Insert code here to initialize your application
|
||||
TouchBarController.shared.setupControlStripPresence()
|
||||
|
||||
if let button = statusItem.button {
|
||||
@ -23,7 +22,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ aNotification: Notification) {
|
||||
// Insert code here to tear down your application
|
||||
|
||||
}
|
||||
|
||||
@objc func openPrefereces(_ sender: Any?) {
|
||||
|
||||
@ -18,7 +18,9 @@ class AppleScriptTouchBarItem: CustomButtonTouchBarItem {
|
||||
DispatchQueue.main.async {
|
||||
var error: NSDictionary?
|
||||
guard script.compileAndReturnError(&error) else {
|
||||
// print(error?.description ?? "unknown error")
|
||||
#if DEBUG
|
||||
print(error?.description ?? "unknown error")
|
||||
#endif
|
||||
DispatchQueue.main.async {
|
||||
self.button.title = "error"
|
||||
}
|
||||
@ -33,7 +35,9 @@ class AppleScriptTouchBarItem: CustomButtonTouchBarItem {
|
||||
}
|
||||
|
||||
func refreshAndSchedule() {
|
||||
// print("refresh happened")
|
||||
#if DEBUG
|
||||
print("refresh happened")
|
||||
#endif
|
||||
let scriptResult = self.execute()
|
||||
DispatchQueue.main.async {
|
||||
self.button.title = scriptResult
|
||||
|
||||
137
MTMR/BatteryBarItem.swift
Normal file
137
MTMR/BatteryBarItem.swift
Normal file
@ -0,0 +1,137 @@
|
||||
//
|
||||
// BatteryBarItem.swift
|
||||
// MTMR
|
||||
//
|
||||
// Created by Anton Palgunov on 18/04/2018.
|
||||
// Copyright © 2018 Anton Palgunov. All rights reserved.
|
||||
//
|
||||
|
||||
import IOKit.ps
|
||||
import Foundation
|
||||
|
||||
class BatteryBarItem: NSCustomTouchBarItem {
|
||||
private var timer: Timer!
|
||||
private let button = NSButton(title: "", target: nil, action: nil)
|
||||
|
||||
override init(identifier: NSTouchBarItem.Identifier) {
|
||||
super.init(identifier: identifier)
|
||||
self.view = button
|
||||
button.bezelColor = .clear
|
||||
|
||||
let batteryInfo = BatteryInfo(button: button)
|
||||
batteryInfo.start()
|
||||
batteryInfo.updateInfo()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
class BatteryInfo: NSObject {
|
||||
var current: Int = 0
|
||||
var timeToEmpty: Int = 0
|
||||
var timeToFull: Int = 0
|
||||
var isCharged: Bool = false
|
||||
var isCharging: Bool = false
|
||||
var ACPower: String = ""
|
||||
var timeRemaining: String = ""
|
||||
|
||||
var button: NSButton?
|
||||
var loop:CFRunLoopSource?
|
||||
|
||||
init(button: NSButton) {
|
||||
super.init()
|
||||
|
||||
self.button = button
|
||||
self.start()
|
||||
}
|
||||
|
||||
func start() {
|
||||
let opaque = Unmanaged.passRetained(self).toOpaque()
|
||||
let context = UnsafeMutableRawPointer(opaque)
|
||||
loop = IOPSNotificationCreateRunLoopSource({ (context) in
|
||||
guard let ctx = context else {
|
||||
return
|
||||
}
|
||||
|
||||
let watcher = Unmanaged<BatteryInfo>.fromOpaque(ctx).takeUnretainedValue()
|
||||
watcher.updateInfo()
|
||||
}, context).takeRetainedValue() as CFRunLoopSource
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), loop, CFRunLoopMode.defaultMode)
|
||||
}
|
||||
|
||||
func stop() {
|
||||
if !(self.loop != nil) {
|
||||
return
|
||||
}
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), self.loop, CFRunLoopMode.defaultMode)
|
||||
self.loop = nil
|
||||
}
|
||||
|
||||
func getPSInfo() {
|
||||
let psInfo = IOPSCopyPowerSourcesInfo().takeRetainedValue()
|
||||
let psList = IOPSCopyPowerSourcesList(psInfo).takeRetainedValue() as [CFTypeRef]
|
||||
|
||||
for ps in psList {
|
||||
if let psDesc = IOPSGetPowerSourceDescription(psInfo, ps).takeUnretainedValue() as? [String: Any] {
|
||||
let current = psDesc[kIOPSCurrentCapacityKey]
|
||||
if (current != nil) {
|
||||
self.current = current as! Int
|
||||
}
|
||||
|
||||
let timeToEmpty = psDesc[kIOPSTimeToEmptyKey]
|
||||
if (timeToEmpty != nil) {
|
||||
self.timeToEmpty = timeToEmpty as! Int
|
||||
}
|
||||
|
||||
let timeToFull = psDesc[kIOPSTimeToFullChargeKey]
|
||||
if (timeToFull != nil) {
|
||||
self.timeToFull = timeToFull as! Int
|
||||
}
|
||||
|
||||
let isCharged = psDesc[kIOPSIsChargedKey]
|
||||
if (isCharged != nil) {
|
||||
self.isCharged = isCharged as! Bool
|
||||
}
|
||||
|
||||
let isCharging = psDesc[kIOPSIsChargingKey]
|
||||
if (isCharging != nil) {
|
||||
self.isCharging = isCharging as! Bool
|
||||
}
|
||||
|
||||
let ACPower = psDesc[kIOPSPowerSourceStateKey]
|
||||
if (ACPower != nil) {
|
||||
self.ACPower = ACPower as! String
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getFormattedTime(time: Int) -> String {
|
||||
if (time > 0) {
|
||||
let timeFormatted = NSString(format: " (%d:%02d)", time / 60, time % 60) as String
|
||||
return timeFormatted
|
||||
} else if (time == 0) {
|
||||
return ""
|
||||
}
|
||||
|
||||
return " (?)"
|
||||
}
|
||||
|
||||
public func updateInfo() {
|
||||
var title = ""
|
||||
self.getPSInfo()
|
||||
|
||||
if ACPower == "AC Power" {
|
||||
title += "⚡️"
|
||||
timeRemaining = getFormattedTime(time: timeToFull)
|
||||
} else {
|
||||
timeRemaining = getFormattedTime(time: timeToEmpty)
|
||||
}
|
||||
|
||||
title += String(current) + "%" + timeRemaining
|
||||
button?.title = title
|
||||
}
|
||||
|
||||
}
|
||||
@ -16,7 +16,7 @@ class CurrencyBarItem: CustomButtonTouchBarItem {
|
||||
private var from: String
|
||||
private var to: String
|
||||
private var oldValue: Float32!
|
||||
|
||||
|
||||
private let currencies = [
|
||||
"USD": "$",
|
||||
"EUR": "€",
|
||||
@ -31,44 +31,47 @@ class CurrencyBarItem: CustomButtonTouchBarItem {
|
||||
"IDR": "Rp",
|
||||
"MXN": "$",
|
||||
"SGD": "$",
|
||||
"CHF": "Fr."
|
||||
"CHF": "Fr.",
|
||||
"BTC": "฿",
|
||||
"LTC": "Ł",
|
||||
"ETH": "Ξ",
|
||||
]
|
||||
|
||||
|
||||
init(identifier: NSTouchBarItem.Identifier, interval: TimeInterval, from: String, to: String, onTap: @escaping () -> ()) {
|
||||
self.interval = interval
|
||||
self.from = from
|
||||
self.to = to
|
||||
|
||||
|
||||
if let prefix = currencies[from] {
|
||||
self.prefix = prefix
|
||||
} else {
|
||||
self.prefix = from
|
||||
}
|
||||
|
||||
|
||||
super.init(identifier: identifier, title: "⏳", onTap: onTap)
|
||||
|
||||
|
||||
button.bezelColor = .clear
|
||||
self.view = button
|
||||
|
||||
|
||||
timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(updateCurrency), userInfo: nil, repeats: true)
|
||||
|
||||
|
||||
updateCurrency()
|
||||
}
|
||||
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
@objc func updateCurrency() {
|
||||
let urlRequest = URLRequest(url: URL(string: "https://api.coinbase.com/v2/exchange-rates?currency=\(from)")!)
|
||||
|
||||
|
||||
let task = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
|
||||
if error == nil {
|
||||
do {
|
||||
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String : AnyObject]
|
||||
|
||||
|
||||
var value: Float32!
|
||||
|
||||
|
||||
if let data_array = json["data"] as? [String : AnyObject] {
|
||||
if let rates = data_array["rates"] as? [String : AnyObject] {
|
||||
if let item = rates["\(self.to)"] as? String {
|
||||
@ -89,21 +92,21 @@ class CurrencyBarItem: CustomButtonTouchBarItem {
|
||||
|
||||
task.resume()
|
||||
}
|
||||
|
||||
|
||||
func setCurrency(value: Float32) {
|
||||
var color = NSColor.white
|
||||
|
||||
|
||||
if let oldValue = self.oldValue {
|
||||
if oldValue < value {
|
||||
color = NSColor(red: 95.0/255.0, green: 185.0/255.0, blue: 50.0/255.0, alpha: 1.0)
|
||||
color = NSColor.green
|
||||
} else if oldValue > value {
|
||||
color = NSColor(red: 185.0/255.0, green: 95.0/255.0, blue: 50.0/255.0, alpha: 1.0)
|
||||
color = NSColor.red
|
||||
}
|
||||
}
|
||||
self.oldValue = value
|
||||
|
||||
|
||||
button.title = String(format: "%@%.2f", self.prefix, value)
|
||||
|
||||
|
||||
let textRange = NSRange(location: 0, length: button.title.count)
|
||||
let newTitle = NSMutableAttributedString(string: button.title)
|
||||
newTitle.addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: textRange)
|
||||
|
||||
@ -60,6 +60,10 @@ class SupportedTypesHolder {
|
||||
let imageParameter = GeneralParameter.image(source: NSImage(named: .touchBarVolumeUpTemplate)!)
|
||||
return (item: .staticButton(title: ""), action: .hidKey(keycode: NX_KEYTYPE_SOUND_UP), parameters: [.image: imageParameter])
|
||||
},
|
||||
"mute": { _ in
|
||||
let imageParameter = GeneralParameter.image(source: NSImage(named: .touchBarAudioOutputMuteTemplate)!)
|
||||
return (item: .staticButton(title: ""), action: .hidKey(keycode: NX_KEYTYPE_MUTE), parameters: [.image: imageParameter])
|
||||
},
|
||||
"previous": { _ in
|
||||
let imageParameter = GeneralParameter.image(source: NSImage(named: .touchBarRewindTemplate)!)
|
||||
return (item: .staticButton(title: ""), action: .hidKey(keycode: NX_KEYTYPE_PREVIOUS), parameters: [.image: imageParameter])
|
||||
@ -113,15 +117,6 @@ class SupportedTypesHolder {
|
||||
return (item: .brightness(refreshInterval: interval ?? 0.5), action: .none, parameters: [:])
|
||||
}
|
||||
},
|
||||
"battery": { decoder in
|
||||
enum CodingKeys: String, CodingKey { case refreshInterval }
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
let interval = try container.decodeIfPresent(Double.self, forKey: .refreshInterval)
|
||||
let scriptPath = Bundle.main.path(forResource: "Battery", ofType: "scpt")!
|
||||
let item = ItemType.appleScriptTitledButton(source: Source(filePath: scriptPath), refreshInterval: interval ?? 1800.0)
|
||||
let action = try ActionType(from: decoder)
|
||||
return (item: item, action: action, parameters: [:])
|
||||
},
|
||||
"sleep": { _ in return (item: .staticButton(title: "☕️"), action: .shellScript(executable: "/usr/bin/pmset", parameters: ["sleepnow"]), parameters: [:]) },
|
||||
"displaySleep": { _ in return (item: .staticButton(title: "☕️"), action: .shellScript(executable: "/usr/bin/pmset", parameters: ["displaysleepnow"]), parameters: [:]) },
|
||||
]
|
||||
@ -149,6 +144,7 @@ enum ItemType: Decodable {
|
||||
case staticButton(title: String)
|
||||
case appleScriptTitledButton(source: SourceProtocol, refreshInterval: Double)
|
||||
case timeButton(formatTemplate: String)
|
||||
case battery()
|
||||
case dock()
|
||||
case volume()
|
||||
case brightness(refreshInterval: Double)
|
||||
@ -174,6 +170,7 @@ enum ItemType: Decodable {
|
||||
case staticButton
|
||||
case appleScriptTitledButton
|
||||
case timeButton
|
||||
case battery
|
||||
case dock
|
||||
case volume
|
||||
case brightness
|
||||
@ -195,6 +192,8 @@ enum ItemType: Decodable {
|
||||
case .timeButton:
|
||||
let template = try container.decodeIfPresent(String.self, forKey: .formatTemplate) ?? "HH:mm"
|
||||
self = .timeButton(formatTemplate: template)
|
||||
case .battery:
|
||||
self = .battery()
|
||||
case .dock:
|
||||
self = .dock()
|
||||
case .volume:
|
||||
@ -209,7 +208,7 @@ enum ItemType: Decodable {
|
||||
let icon_type = try container.decodeIfPresent(String.self, forKey: .icon_type) ?? "text"
|
||||
self = .weather(interval: interval, units: units, api_key: api_key, icon_type: icon_type)
|
||||
case .currency:
|
||||
let interval = try container.decodeIfPresent(Double.self, forKey: .refreshInterval) ?? 1800.0
|
||||
let interval = try container.decodeIfPresent(Double.self, forKey: .refreshInterval) ?? 600.0
|
||||
let from = try container.decodeIfPresent(String.self, forKey: .from) ?? "RUB"
|
||||
let to = try container.decodeIfPresent(String.self, forKey: .to) ?? "USD"
|
||||
self = .currency(interval: interval, from: from, to: to)
|
||||
|
||||
@ -58,6 +58,7 @@ func HIDPostAuxKey(_ key: Int) {
|
||||
// hidsystem/ev_keymap.h
|
||||
let NX_KEYTYPE_SOUND_UP = 0
|
||||
let NX_KEYTYPE_SOUND_DOWN = 1
|
||||
let NX_KEYTYPE_MUTE = 7
|
||||
|
||||
let NX_KEYTYPE_BRIGHTNESS_UP = 2
|
||||
let NX_KEYTYPE_BRIGHTNESS_DOWN = 3
|
||||
@ -69,3 +70,4 @@ let NX_KEYTYPE_PREVIOUS = 18
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -23,6 +23,8 @@ extension ItemType {
|
||||
return "com.toxblh.mtmr.appleScriptButton."
|
||||
case .timeButton(formatTemplate: _):
|
||||
return "com.toxblh.mtmr.timeButton."
|
||||
case .battery():
|
||||
return "com.toxblh.mtmr.battery."
|
||||
case .dock():
|
||||
return "com.toxblh.mtmr.dock"
|
||||
case .volume():
|
||||
@ -40,7 +42,6 @@ extension ItemType {
|
||||
|
||||
extension NSTouchBarItem.Identifier {
|
||||
static let controlStripItem = NSTouchBarItem.Identifier("com.toxblh.mtmr.controlStrip")
|
||||
static let centerScrollArea = NSTouchBarItem.Identifier("com.toxblh.mtmr.scrollArea")
|
||||
}
|
||||
|
||||
class TouchBarController: NSObject, NSTouchBarDelegate {
|
||||
@ -54,6 +55,8 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
||||
var leftIdentifiers: [NSTouchBarItem.Identifier] = []
|
||||
var centerItems: [NSTouchBarItem] = []
|
||||
var rightIdentifiers: [NSTouchBarItem.Identifier] = []
|
||||
var scrollArea: NSCustomTouchBarItem?
|
||||
var centerScrollArea = NSTouchBarItem.Identifier("com.toxblh.mtmr.scrollArea.".appending(UUID().uuidString))
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
@ -81,8 +84,12 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
||||
return definition.align == .center ? items[identifier] : nil
|
||||
}
|
||||
|
||||
self.centerScrollArea = NSTouchBarItem.Identifier("com.toxblh.mtmr.scrollArea.".appending(UUID().uuidString))
|
||||
self.scrollArea = ScrollViewItem(identifier: centerScrollArea, items: centerItems)
|
||||
|
||||
touchBar.delegate = self
|
||||
touchBar.defaultItemIdentifiers = self.leftIdentifiers + [.centerScrollArea] + self.rightIdentifiers
|
||||
touchBar.defaultItemIdentifiers = []
|
||||
touchBar.defaultItemIdentifiers = self.leftIdentifiers + [centerScrollArea] + self.rightIdentifiers
|
||||
self.presentTouchBar()
|
||||
}
|
||||
|
||||
@ -141,8 +148,8 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
||||
}
|
||||
|
||||
func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? {
|
||||
if identifier == .centerScrollArea {
|
||||
return ScrollViewItem(identifier: identifier, items: centerItems)
|
||||
if identifier == centerScrollArea {
|
||||
return self.scrollArea
|
||||
}
|
||||
|
||||
guard let item = self.items[identifier],
|
||||
@ -164,6 +171,8 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
||||
barItem = AppleScriptTouchBarItem(identifier: identifier, source: source, interval: interval, onTap: action)
|
||||
case .timeButton(formatTemplate: let template):
|
||||
barItem = TimeTouchBarItem(identifier: identifier, formatTemplate: template)
|
||||
case .battery():
|
||||
barItem = BatteryBarItem(identifier: identifier)
|
||||
case .dock:
|
||||
barItem = AppScrubberTouchBarItem(identifier: identifier)
|
||||
case .volume:
|
||||
@ -225,7 +234,9 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
||||
case .openUrl(url: let url):
|
||||
return {
|
||||
if let url = URL(string: url), NSWorkspace.shared.open(url) {
|
||||
// print("URL was successfully opened")
|
||||
#if DEBUG
|
||||
print("URL was successfully opened")
|
||||
#endif
|
||||
} else {
|
||||
print("error", url)
|
||||
}
|
||||
|
||||
@ -33,6 +33,10 @@ class WeatherBarItem: CustomButtonTouchBarItem, CLLocationManagerDelegate {
|
||||
units_str = "°C"
|
||||
}
|
||||
|
||||
if self.units == "imperial" {
|
||||
units_str = "°F"
|
||||
}
|
||||
|
||||
if icon_type == "images" {
|
||||
iconsSource = iconsImages
|
||||
} else {
|
||||
|
||||
@ -66,8 +66,10 @@
|
||||
{ "type": "previous", "width": 44 },
|
||||
{ "type": "play", "width": 44 },
|
||||
{ "type": "next", "width": 44 },
|
||||
{ "type": "weather", "refreshInterval": 1800 },
|
||||
{ "type": "weather", "icon_type": "images", "units": "metric" },
|
||||
{ "type": "currency", "from": "BTC", "to": "USD" },
|
||||
{ "type": "sleep", "width": 44 },
|
||||
{ "type": "mute", "width": 40, "align": "right" },
|
||||
{ "type": "volumeDown", "width": 34, "align": "right" },
|
||||
{ "type": "volume", "width": 60, "align": "right" },
|
||||
{ "type": "volumeUp", "width": 34, "align": "right" },
|
||||
|
||||
39
README.md
39
README.md
@ -46,7 +46,6 @@ Maybe:
|
||||
|
||||
## Installation
|
||||
1. Download last release [Releases](https://github.com/Toxblh/MTMR/releases)
|
||||
2. Unzip
|
||||
3. Open MTMR
|
||||
4. Open preset `open ~/Library/Application\ Support/MTMR/items.json` and customize it. Restart MTMR to apply changes.
|
||||
|
||||
@ -62,16 +61,20 @@ File for customize your preset for MTMR: `open ~/Library/Application\ Support/MT
|
||||
- brightnessDown
|
||||
- volumeDown
|
||||
- volumeUp
|
||||
- mute
|
||||
- dock
|
||||
|
||||
> Native Plugins
|
||||
- battery
|
||||
- currency
|
||||
- weather
|
||||
|
||||
> Media Keys
|
||||
- previous
|
||||
- play
|
||||
- next
|
||||
|
||||
> AppleScript plugins
|
||||
- weather
|
||||
- battery
|
||||
- sleep
|
||||
- displaySleep
|
||||
|
||||
@ -106,8 +109,30 @@ File for customize your preset for MTMR: `open ~/Library/Application\ Support/MT
|
||||
"formatTemplate": "HH:mm" //optional
|
||||
```
|
||||
|
||||
## Native plugins
|
||||
- `weather`
|
||||
> Provider: https://openweathermap.org Need allowance location service
|
||||
```js
|
||||
"type": "weather",
|
||||
"refreshInterval": 600,
|
||||
"units": "metric", // or imperial
|
||||
"icon_type": "text" // or images
|
||||
"api_key": "" // you can get the key on openweather
|
||||
```
|
||||
|
||||
- `currency`
|
||||
> Provider: https://coinbase.com
|
||||
```js
|
||||
"type": "currency",
|
||||
"refreshInterval": 600,
|
||||
"align": "right",
|
||||
"from": "BTC",
|
||||
"to": "USD",
|
||||
```
|
||||
|
||||
## Actions:
|
||||
- `hidKey`
|
||||
> https://github.com/aosm/IOHIDFamily/blob/master/IOHIDSystem/IOKit/hidsystem/ev_keymap.h use only numbers
|
||||
```json
|
||||
"action": "hidKey",
|
||||
"keycode": 53,
|
||||
@ -132,10 +157,16 @@ File for customize your preset for MTMR: `open ~/Library/Application\ Support/MT
|
||||
```js
|
||||
"action": "shellScript",
|
||||
"executablePath": "/usr/bin/pmset",
|
||||
"shellArguments": "sleepnow", // optional
|
||||
"shellArguments": ["sleepnow"], // optional
|
||||
|
||||
```
|
||||
|
||||
- `openUrl`
|
||||
```js
|
||||
"action": "openUrl",
|
||||
"url": "https://google.com",
|
||||
```
|
||||
|
||||
## Additional paramaters:
|
||||
|
||||
- `width` allow to restrict how much room a particular button will take
|
||||
|
||||
Loading…
Reference in New Issue
Block a user