- add an option to select a color for each module (from a predefined list)

- add a separator to select color menu
This commit is contained in:
Serhiy Mytrovtsiy
2020-07-08 17:50:40 +02:00
parent cb8ab6365c
commit 8b9698006f
10 changed files with 299 additions and 129 deletions

View File

@@ -15,10 +15,10 @@ import StatsKit
public class BarChart: Widget {
private var labelState: Bool = true
private var boxState: Bool = true
private var colorState: Bool = false
private var pressureState: Bool = false
private var colorState: widget_c = .systemAccent
private let store: UnsafePointer<Store>?
private var colors: [widget_c] = widget_c.allCases
private var value: [Double] = []
private var pressureLevel: Int = 0
@@ -49,8 +49,15 @@ public class BarChart: Widget {
if let box = configuration["Box"] as? Bool {
self.boxState = box
}
if let color = configuration["Color"] as? Bool {
self.colorState = color
if let colorsToDisable = configuration["Unsupported colors"] as? [String] {
self.colors = self.colors.filter { (color: widget_c) -> Bool in
return !colorsToDisable.contains("\(color.self)")
}
}
if let color = configuration["Color"] as? String {
if let defaultColor = colors.first(where: { "\($0.self)" == color }) {
self.colorState = defaultColor
}
}
}
super.init(frame: CGRect(x: 0, y: Constants.Widget.margin, width: Constants.Widget.width, height: Constants.Widget.height - (2*Constants.Widget.margin)))
@@ -62,8 +69,7 @@ public class BarChart: Widget {
if self.store != nil && !preview {
self.boxState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_box", defaultValue: self.boxState)
self.labelState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_label", defaultValue: self.labelState)
self.colorState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_color", defaultValue: self.colorState)
self.pressureState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_pressure", defaultValue: self.pressureState)
self.colorState = widget_c(rawValue: store!.pointee.string(key: "\(self.title)_\(self.type.rawValue)_color", defaultValue: self.colorState.rawValue)) ?? self.colorState
}
if preview {
@@ -72,7 +78,6 @@ public class BarChart: Widget {
}
self.setFrameSize(NSSize(width: 36, height: self.frame.size.height))
self.invalidateIntrinsicContentSize()
self.pressureState = false
}
}
@@ -146,6 +151,7 @@ public class BarChart: Widget {
box.stroke()
box.fill()
chartPadding = 1
x += 0.5
}
let widthForBarChart = box.bounds.width - chartPadding
@@ -154,19 +160,24 @@ public class BarChart: Widget {
let partitionWidth: CGFloat = (widthForBarChart / CGFloat(self.value.count)) - CGFloat(partitionsMargin.isNaN ? 0 : partitionsMargin)
let maxPartitionHeight: CGFloat = box.bounds.height - (chartPadding*2)
x += partitionMargin
for i in 0..<self.value.count {
let partitionValue = self.value[i]
let partitonHeight = maxPartitionHeight * CGFloat(partitionValue)
let partition = NSBezierPath(rect: NSRect(x: x, y: chartPadding, width: partitionWidth, height: partitonHeight))
if self.colorState {
partitionValue.usageColor().setFill()
} else if self.pressureState {
self.pressureLevel.pressureColor().setFill()
} else {
NSColor.controlAccentColor.set()
switch self.colorState {
case .systemAccent: NSColor.controlAccentColor.set()
case .utilization: partitionValue.usageColor().setFill()
case .pressure: self.pressureLevel.pressureColor().setFill()
case .monochrome:
if self.boxState {
(isDarkMode ? NSColor.black : NSColor.white).set()
} else {
(isDarkMode ? NSColor.white : NSColor.black).set()
}
default: colorFromString("\(self.colorState.self)").set()
}
partition.fill()
partition.close()
@@ -197,22 +208,12 @@ public class BarChart: Widget {
public override func settings(superview: NSView) {
let rowHeight: CGFloat = 30
let settingsNumber: CGFloat = self.title == "RAM" ? 4 : 3
let settingsNumber: CGFloat = 3
let height: CGFloat = ((rowHeight + Constants.Settings.margin) * settingsNumber) + Constants.Settings.margin
superview.setFrameSize(NSSize(width: superview.frame.width, height: height))
let view: NSView = NSView(frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin, width: superview.frame.width - (Constants.Settings.margin*2), height: superview.frame.height - (Constants.Settings.margin*2)))
if self.title == "RAM" {
self.pressureLevelSettingsView = ToggleTitleRow(
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 3, width: view.frame.width, height: rowHeight),
title: "Pressure level",
action: #selector(togglePressure),
state: self.pressureState
)
view.addSubview(self.pressureLevelSettingsView!)
}
view.addSubview(ToggleTitleRow(
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 2, width: view.frame.width, height: rowHeight),
title: "Label",
@@ -227,13 +228,13 @@ public class BarChart: Widget {
state: self.boxState
))
self.colorizeSettingsView = ToggleTitleRow(
view.addSubview(SelectColorRow(
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 0, width: view.frame.width, height: rowHeight),
title: "Colorize",
title: "Color",
action: #selector(toggleColor),
state: self.colorState
)
view.addSubview(self.colorizeSettingsView!)
items: self.colors.map{ $0.rawValue },
selected: self.colorState.rawValue
))
superview.addSubview(view)
}
@@ -262,41 +263,11 @@ public class BarChart: Widget {
self.display()
}
@objc private func toggleColor(_ sender: NSControl) {
var state: NSControl.StateValue? = nil
if #available(OSX 10.15, *) {
state = sender is NSSwitch ? (sender as! NSSwitch).state: nil
} else {
state = sender is NSButton ? (sender as! NSButton).state: nil
@objc private func toggleColor(_ sender: NSMenuItem) {
if let newColor = widget_c.allCases.first(where: { $0.rawValue == sender.title }) {
self.colorState = newColor
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_color", value: self.colorState.rawValue)
self.display()
}
self.colorState = state! == .on ? true : false
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_color", value: self.colorState)
if self.colorState {
self.pressureState = false
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_pressure", value: self.pressureState)
FindAndToggleNSControlState(self.pressureLevelSettingsView, state: .off)
}
self.display()
}
@objc private func togglePressure(_ sender: NSControl) {
var state: NSControl.StateValue? = nil
if #available(OSX 10.15, *) {
state = sender is NSSwitch ? (sender as! NSSwitch).state: nil
} else {
state = sender is NSButton ? (sender as! NSButton).state: nil
}
self.pressureState = state! == .on ? true : false
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_pressure", value: self.pressureState)
if self.pressureState {
self.colorState = false
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_color", value: self.colorState)
FindAndToggleNSControlState(self.colorizeSettingsView, state: .off)
}
self.display()
}
}

View File

@@ -16,11 +16,12 @@ public class LineChart: Widget {
private var labelState: Bool = true
private var boxState: Bool = true
private var valueState: Bool = false
private var colorState: Bool = false
private var pressureState: Bool = false
private var valueColorState: Bool = false
private var colorState: widget_c = .systemAccent
private let store: UnsafePointer<Store>?
private var chart: LineChartView
private var colors: [widget_c] = widget_c.allCases
private var value: Double = 0
private var pressureLevel: Int = 0
@@ -40,8 +41,15 @@ public class LineChart: Widget {
if let value = config!["Value"] as? Bool {
self.valueState = value
}
if let color = config!["Color"] as? Bool {
self.colorState = color
if let colorsToDisable = config!["Unsupported colors"] as? [String] {
self.colors = self.colors.filter { (color: widget_c) -> Bool in
return !colorsToDisable.contains("\(color.self)")
}
}
if let color = config!["Color"] as? String {
if let defaultColor = colors.first(where: { "\($0.self)" == color }) {
self.colorState = defaultColor
}
}
}
self.chart = LineChartView(frame: NSRect(x: 0, y: 0, width: Constants.Widget.width, height: Constants.Widget.height - (2*Constants.Widget.margin)), num: 60)
@@ -55,8 +63,8 @@ public class LineChart: Widget {
self.boxState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_box", defaultValue: self.boxState)
self.valueState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_value", defaultValue: self.valueState)
self.labelState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_label", defaultValue: self.labelState)
self.colorState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_color", defaultValue: self.colorState)
self.pressureState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_pressure", defaultValue: self.pressureState)
self.valueColorState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_valueColor", defaultValue: self.valueColorState)
self.colorState = widget_c(rawValue: store!.pointee.string(key: "\(self.title)_\(self.type.rawValue)_color", defaultValue: self.colorState.rawValue)) ?? self.colorState
}
if self.labelState {
@@ -70,7 +78,6 @@ public class LineChart: Widget {
}
self.chart.points = list
self.value = 0.38
self.pressureState = false
}
}
@@ -111,18 +118,32 @@ public class LineChart: Widget {
var boxRadius: CGFloat = 2
let boxWidth: CGFloat = Constants.Widget.width - (Constants.Widget.margin*2)
var color: NSColor = NSColor.controlAccentColor
switch self.colorState {
case .systemAccent: color = NSColor.controlAccentColor
case .utilization: color = value.usageColor()
case .pressure: color = self.pressureLevel.pressureColor()
case .monochrome:
if self.boxState {
color = (isDarkMode ? NSColor.black : NSColor.white)
} else {
color = (isDarkMode ? NSColor.white : NSColor.black)
}
default: color = colorFromString("\(self.colorState.self)")
}
if self.valueState {
let style = NSMutableParagraphStyle()
style.alignment = .right
var color = isDarkMode ? NSColor.white : NSColor.black
if self.colorState {
color = self.value.percentageColor(color: self.colorState)
var valueColor = isDarkMode ? NSColor.white : NSColor.black
if self.valueColorState {
valueColor = color
}
let stringAttributes = [
NSAttributedString.Key.font: NSFont.systemFont(ofSize: 8, weight: .regular),
NSAttributedString.Key.foregroundColor: color,
NSAttributedString.Key.foregroundColor: valueColor,
NSAttributedString.Key.paragraphStyle: style
]
@@ -146,11 +167,7 @@ public class LineChart: Widget {
}
chart.setFrameSize(NSSize(width: box.bounds.width - chartPadding, height: box.bounds.height - (chartPadding*2)))
if self.pressureState {
self.chart.color = self.pressureLevel.pressureColor()
} else {
self.chart.color = NSColor.controlAccentColor
}
self.chart.color = color
chart.draw(NSRect(x: box.bounds.origin.x + 1, y: chartPadding, width: chart.frame.width, height: chart.frame.height))
ctx.restoreGState()
@@ -163,47 +180,46 @@ public class LineChart: Widget {
public override func settings(superview: NSView) {
let rowHeight: CGFloat = 30
let settingsNumber: CGFloat = self.title == "RAM" ? 5 : 4
let settingsNumber: CGFloat = 5
let height: CGFloat = ((rowHeight + Constants.Settings.margin) * settingsNumber) + Constants.Settings.margin
superview.setFrameSize(NSSize(width: superview.frame.width, height: height))
let view: NSView = NSView(frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin, width: superview.frame.width - (Constants.Settings.margin*2), height: superview.frame.height - (Constants.Settings.margin*2)))
if self.title == "RAM" {
view.addSubview(ToggleTitleRow(
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 4, width: view.frame.width, height: rowHeight),
title: "Pressure level",
action: #selector(togglePressure),
state: self.pressureState
))
}
view.addSubview(ToggleTitleRow(
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 3, width: view.frame.width, height: rowHeight),
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 4, width: view.frame.width, height: rowHeight),
title: "Label",
action: #selector(toggleLabel),
state: self.labelState
))
view.addSubview(ToggleTitleRow(
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 2, width: view.frame.width, height: rowHeight),
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 3, width: view.frame.width, height: rowHeight),
title: "Box",
action: #selector(toggleBox),
state: self.boxState
))
view.addSubview(ToggleTitleRow(
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 1, width: view.frame.width, height: rowHeight),
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 2, width: view.frame.width, height: rowHeight),
title: "Value",
action: #selector(toggleValue),
state: self.valueState
))
view.addSubview(SelectColorRow(
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 1, width: view.frame.width, height: rowHeight),
title: "Color",
action: #selector(toggleColor),
items: self.colors.map{ $0.rawValue },
selected: self.colorState.rawValue
))
view.addSubview(ToggleTitleRow(
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 0, width: view.frame.width, height: rowHeight),
title: "Colorize value",
action: #selector(toggleColor),
state: self.colorState
action: #selector(toggleValueColor),
state: self.valueColorState
))
superview.addSubview(view)
@@ -271,27 +287,23 @@ public class LineChart: Widget {
self.display()
}
@objc private func toggleColor(_ sender: NSControl) {
var state: NSControl.StateValue? = nil
if #available(OSX 10.15, *) {
state = sender is NSSwitch ? (sender as! NSSwitch).state: nil
} else {
state = sender is NSButton ? (sender as! NSButton).state: nil
@objc private func toggleColor(_ sender: NSMenuItem) {
if let newColor = widget_c.allCases.first(where: { $0.rawValue == sender.title }) {
self.colorState = newColor
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_color", value: self.colorState.rawValue)
self.display()
}
self.colorState = state! == .on ? true : false
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_color", value: self.colorState)
self.display()
}
@objc private func togglePressure(_ sender: NSControl) {
@objc private func toggleValueColor(_ sender: NSControl) {
var state: NSControl.StateValue? = nil
if #available(OSX 10.15, *) {
state = sender is NSSwitch ? (sender as! NSSwitch).state: nil
} else {
state = sender is NSButton ? (sender as! NSButton).state: nil
}
self.pressureState = state! == .on ? true : false
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_pressure", value: self.pressureState)
self.valueColorState = state! == .on ? true : false
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_valueColor", value: self.valueColorState)
self.display()
}
}

View File

@@ -13,12 +13,14 @@ import Cocoa
import StatsKit
public class Mini: Widget {
public var colorState: Bool = false
public var labelState: Bool = true
private var colorState: widget_c = .monochrome
private let onlyValueWidth: CGFloat = 38
private var value: Double = 0
private let store: UnsafePointer<Store>?
private var colors: [widget_c] = widget_c.allCases
private var pressureLevel: Int = 0
public init(preview: Bool, title: String, config: NSDictionary?, store: UnsafePointer<Store>?) {
var widgetTitle: String = title
@@ -45,8 +47,15 @@ public class Mini: Widget {
if let label = configuration["Label"] as? Bool {
self.labelState = label
}
if let color = configuration["Color"] as? Bool {
self.colorState = color
if let colorsToDisable = configuration["Unsupported colors"] as? [String] {
self.colors = self.colors.filter { (color: widget_c) -> Bool in
return !colorsToDisable.contains("\(color.self)")
}
}
if let color = configuration["Color"] as? String {
if let defaultColor = colors.first(where: { "\($0.self)" == color }) {
self.colorState = defaultColor
}
}
}
super.init(frame: CGRect(x: 0, y: Constants.Widget.margin, width: Constants.Widget.width, height: Constants.Widget.height - (2*Constants.Widget.margin)))
@@ -56,7 +65,7 @@ public class Mini: Widget {
self.canDrawConcurrently = true
if self.store != nil {
self.colorState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_color", defaultValue: self.colorState)
self.colorState = widget_c(rawValue: store!.pointee.string(key: "\(self.title)_\(self.type.rawValue)_color", defaultValue: self.colorState.rawValue)) ?? self.colorState
self.labelState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_label", defaultValue: self.labelState)
}
}
@@ -87,9 +96,18 @@ public class Mini: Widget {
style.alignment = .left
}
var color: NSColor = NSColor.controlAccentColor
switch self.colorState {
case .systemAccent: color = NSColor.controlAccentColor
case .utilization: color = value.usageColor()
case .pressure: color = self.pressureLevel.pressureColor()
case .monochrome: color = (isDarkMode ? NSColor.white : NSColor.black)
default: color = colorFromString("\(self.colorState.self)")
}
let stringAttributes = [
NSAttributedString.Key.font: NSFont.systemFont(ofSize: valueSize, weight: .regular),
NSAttributedString.Key.foregroundColor: self.value.percentageColor(color: self.colorState),
NSAttributedString.Key.foregroundColor: color,
NSAttributedString.Key.paragraphStyle: style
]
let rect = CGRect(x: x, y: y, width: width - (Constants.Widget.margin*2), height: valueSize)
@@ -117,26 +135,23 @@ public class Mini: Widget {
state: self.labelState
))
view.addSubview(ToggleTitleRow(
frame: NSRect(x: 0, y: 0, width: view.frame.width, height: rowHeight),
title: "Colorize",
view.addSubview(SelectColorRow(
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 0, width: view.frame.width, height: rowHeight),
title: "Color",
action: #selector(toggleColor),
state: self.colorState
items: self.colors.map{ $0.rawValue },
selected: self.colorState.rawValue
))
superview.addSubview(view)
}
@objc private func toggleColor(_ sender: NSControl) {
var state: NSControl.StateValue? = nil
if #available(OSX 10.15, *) {
state = sender is NSSwitch ? (sender as! NSSwitch).state: nil
} else {
state = sender is NSButton ? (sender as! NSButton).state: nil
@objc private func toggleColor(_ sender: NSMenuItem) {
if let newColor = widget_c.allCases.first(where: { $0.rawValue == sender.title }) {
self.colorState = newColor
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_color", value: self.colorState.rawValue)
self.display()
}
self.colorState = state! == .on ? true : false
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_color", value: self.colorState)
self.display()
}
@objc private func toggleLabel(_ sender: NSControl) {
@@ -161,4 +176,15 @@ public class Mini: Widget {
self.display()
})
}
public func setPressure(_ level: Int) {
guard self.pressureLevel != level else {
return
}
self.pressureLevel = level
DispatchQueue.main.async(execute: {
self.display()
})
}
}

View File

@@ -41,6 +41,7 @@ public class SensorsWidget: Widget {
self.type = .sensors
self.preview = preview
self.canDrawConcurrently = true
self.layer?.backgroundColor = NSColor.clear.cgColor
if self.store != nil {
self.labelState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_label", defaultValue: self.labelState)

View File

@@ -12,6 +12,46 @@
import Cocoa
import StatsKit
public enum widget_c: String {
case utilization = "Based on utilization"
case pressure = "Based on pressure"
case separator_1 = "separator_1"
case systemAccent = "System accent"
case monochrome = "Monochrome accent"
case separator_2 = "separator_2"
case clear = "Clear"
case white = "White"
case black = "Black"
case gray = "Gray"
case secondGray = "Second gray"
case darkGray = "Dark gray"
case lightGray = "Light gray"
case red = "Red"
case secondRed = "Second red"
case green = "Green"
case secondGreen = "Second green"
case blue = "Blue"
case secondBlue = "Second blue"
case yellow = "Yellow"
case secondYellow = "Second yellow"
case orange = "Orange"
case secondOrange = "Second orange"
case purple = "Purple"
case secondPurple = "Second purple"
case brown = "Brown"
case secondBrown = "Second brown"
case cyan = "Cyan"
case magenta = "Magenta"
case pink = "Pink"
case teal = "Teal"
case indigo = "Indigo"
}
extension widget_c: CaseIterable {}
public enum widget_t: String {
case unknown = ""
case mini = "mini"

View File

@@ -17,11 +17,19 @@
<key>Value</key>
<string>0.08</string>
</dict>
<key>Unsupported colors</key>
<array>
<string>pressure</string>
</array>
</dict>
<key>line_chart</key>
<dict>
<key>Default</key>
<false/>
<key>Unsupported colors</key>
<array>
<string>pressure</string>
</array>
</dict>
<key>bar_chart</key>
<dict>
@@ -34,6 +42,10 @@
<key>Color</key>
<true/>
</dict>
<key>Unsupported colors</key>
<array>
<string>pressure</string>
</array>
</dict>
</dict>
</dict>

View File

@@ -21,6 +21,10 @@
<key>Value</key>
<string>0.36</string>
</dict>
<key>Unsupported colors</key>
<array>
<string>pressure</string>
</array>
</dict>
<key>bar_chart</key>
<dict>
@@ -40,11 +44,13 @@
<true/>
<key>Box</key>
<true/>
<key>Color</key>
<true/>
<key>Value</key>
<string>0.36</string>
</dict>
<key>Unsupported colors</key>
<array>
<string>pressure</string>
</array>
</dict>
<key>disk</key>
<dict>

View File

@@ -27,7 +27,9 @@ internal class Popup: NSView {
internal func usageCallback(_ value: DiskList) {
if self.list.count != value.list.count {
self.subviews.forEach{ $0.removeFromSuperview() }
DispatchQueue.main.async(execute: {
self.subviews.forEach{ $0.removeFromSuperview() }
})
self.list = [:]
}

View File

@@ -67,6 +67,7 @@ public class Memory: Module {
self.popupView.loadCallback(value!)
if let widget = self.widget as? Mini {
widget.setValue(value!.usage ?? 0, sufix: "%")
widget.setPressure(value?.pressureLevel ?? 0)
}
if let widget = self.widget as? LineChart {
widget.setValue(value!.usage ?? 0)

View File

@@ -366,6 +366,42 @@ public extension NSView {
return row
}
func SelectColorRow(frame: NSRect, title: String, action: Selector, items: [String], selected: String) -> NSView {
let row: NSView = NSView(frame: frame)
let rowTitle: NSTextField = LabelField(frame: NSRect(x: 0, y: (row.frame.height - 16)/2, width: row.frame.width - 52, height: 17), title)
rowTitle.font = NSFont.systemFont(ofSize: 13, weight: .light)
rowTitle.textColor = .textColor
let select: NSPopUpButton = NSPopUpButton(frame: NSRect(x: row.frame.width - 50, y: 0, width: 50, height: row.frame.height))
select.target = self
select.action = action
let menu = NSMenu()
items.forEach { (color: String) in
if color.contains("separator") {
menu.addItem(NSMenuItem.separator())
} else {
let interfaceMenu = NSMenuItem(title: color, action: nil, keyEquivalent: "")
menu.addItem(interfaceMenu)
if selected == color {
interfaceMenu.state = .on
}
}
}
select.menu = menu
select.sizeToFit()
rowTitle.setFrameSize(NSSize(width: row.frame.width - select.frame.width, height: rowTitle.frame.height))
select.setFrameOrigin(NSPoint(x: row.frame.width - select.frame.width, y: 0))
row.addSubview(select)
row.addSubview(rowTitle)
return row
}
}
public extension Notification.Name {
@@ -612,3 +648,66 @@ public func asyncShell(_ args: String) {
task.standardOutput = pipe
task.launch()
}
public func colorFromString(_ colorString: String) -> NSColor {
switch colorString {
case "black":
return NSColor.black
case "darkGray":
return NSColor.darkGray
case "lightGray":
return NSColor.lightGray
case "gray":
return NSColor.gray
case "secondGray":
return NSColor.systemGray
case "white":
return NSColor.white
case "red":
return NSColor.red
case "secondRed":
return NSColor.systemRed
case "green":
return NSColor.green
case "secondGreen":
return NSColor.systemGreen
case "blue":
return NSColor.blue
case "secondBlue":
return NSColor.systemBlue
case "yellow":
return NSColor.yellow
case "secondYellow":
return NSColor.systemYellow
case "orange":
return NSColor.orange
case "secondOrange":
return NSColor.systemOrange
case "purple":
return NSColor.purple
case "secondPurple":
return NSColor.systemPurple
case "brown":
return NSColor.brown
case "secondBrown":
return NSColor.systemBrown
case "cyan":
return NSColor.cyan
case "magenta":
return NSColor.magenta
case "clear":
return NSColor.clear
case "pink":
return NSColor.systemPink
case "teal":
return NSColor.systemTeal
case "indigo":
if #available(OSX 10.15, *) {
return NSColor.systemIndigo
} else {
return NSColor(hexString: "#4B0082")
}
default:
return NSColor.controlAccentColor
}
}