mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: added tooltips to the missing elements and enabled accessibility on some not natively supported (#2321)
This commit is contained in:
@@ -418,7 +418,7 @@ internal class HeaderView: NSStackView {
|
||||
fileprivate func setCloseButton(_ state: Bool) {
|
||||
if state && !self.isCloseAction {
|
||||
self.activityButton?.image = Bundle(for: type(of: self)).image(forResource: "close")!
|
||||
self.activityButton?.toolTip = localizedString("Close popup")
|
||||
self.activityButton?.toolTip = localizedString("Close")
|
||||
self.activityButton?.action = #selector(self.closePopup)
|
||||
self.isCloseAction = true
|
||||
} else if !state && self.isCloseAction {
|
||||
|
||||
@@ -496,7 +496,8 @@ private class WidgetPreview: NSStackView {
|
||||
self.layer?.backgroundColor = NSColor.white.cgColor
|
||||
|
||||
self.identifier = NSUserInterfaceItemIdentifier(rawValue: type.rawValue)
|
||||
self.toolTip = localizedString("Move widget", type.name())
|
||||
self.setAccessibilityElement(true)
|
||||
self.toolTip = type.name()
|
||||
|
||||
self.orientation = .vertical
|
||||
self.distribution = .fill
|
||||
|
||||
@@ -486,6 +486,8 @@ public class PieChartView: NSView {
|
||||
self.segments = segments
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.setAccessibilityElement(true)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
@@ -575,6 +577,15 @@ public class HalfCircleGraphView: NSView {
|
||||
|
||||
public var color: NSColor = NSColor.systemBlue
|
||||
|
||||
public override init(frame: NSRect) {
|
||||
super.init(frame: frame)
|
||||
self.setAccessibilityElement(true)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public override func draw(_ rect: CGRect) {
|
||||
let arcWidth: CGFloat = 7.0
|
||||
let radius = (min(self.frame.width, self.frame.height) - arcWidth) / 2
|
||||
|
||||
@@ -131,6 +131,8 @@ internal class Popup: PopupWrapper {
|
||||
|
||||
self.spacing = 0
|
||||
self.orientation = .vertical
|
||||
// self.setAccessibilityElement(true)
|
||||
// self.toolTip = self.title
|
||||
|
||||
self.systemColorState = SColor.fromString(Store.shared.string(key: "\(self.title)_systemColor", defaultValue: self.systemColorState.key))
|
||||
self.userColorState = SColor.fromString(Store.shared.string(key: "\(self.title)_userColor", defaultValue: self.userColorState.key))
|
||||
@@ -375,6 +377,7 @@ internal class Popup: PopupWrapper {
|
||||
self.userField?.stringValue = "\(Int(value.userLoad.rounded(toPlaces: 2) * 100))%"
|
||||
self.idleField?.stringValue = "\(Int(value.idleLoad.rounded(toPlaces: 2) * 100))%"
|
||||
|
||||
self.circle?.toolTip = "\(localizedString("CPU usage")): \(Int(value.totalUsage.rounded(toPlaces: 2) * 100))%"
|
||||
self.circle?.setValue(value.totalUsage)
|
||||
self.circle?.setSegments([
|
||||
circle_segment(value: value.systemLoad, color: self.systemColor),
|
||||
@@ -416,6 +419,7 @@ internal class Popup: PopupWrapper {
|
||||
view.isHidden = false
|
||||
}
|
||||
|
||||
self.temperatureCircle?.toolTip = "\(localizedString("CPU temperature")): \(temperature(value))"
|
||||
self.temperatureCircle?.setValue(value)
|
||||
self.temperatureCircle?.setText(temperature(value))
|
||||
self.initializedTemperature = true
|
||||
@@ -447,6 +451,7 @@ internal class Popup: PopupWrapper {
|
||||
if let circle = self.frequencyCircle {
|
||||
circle.setValue((100*freq)/self.maxFreq)
|
||||
circle.setText("\((freq/1000).rounded(toPlaces: 2))")
|
||||
circle.toolTip = "\(localizedString("CPU frequency")): \(Int(freq)) MHz - \(((100*freq)/self.maxFreq).rounded(toPlaces: 2))%"
|
||||
}
|
||||
} else if value.count == 2 {
|
||||
let e = value.first ?? 0
|
||||
@@ -463,6 +468,7 @@ internal class Popup: PopupWrapper {
|
||||
if let circle = self.frequencyCircle {
|
||||
circle.setValue((100*freq)/self.maxFreq)
|
||||
circle.setText("\((freq/1000).rounded(toPlaces: 2))")
|
||||
circle.toolTip = "\(localizedString("CPU frequency")): \(Int(freq)) MHz - \(((100*freq)/self.maxFreq).rounded(toPlaces: 2))%"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,7 @@ public class Portal: PortalWrapper {
|
||||
self.userField?.stringValue = "\(Int(value.userLoad.rounded(toPlaces: 2) * 100))%"
|
||||
self.idleField?.stringValue = "\(Int(value.idleLoad.rounded(toPlaces: 2) * 100))%"
|
||||
|
||||
self.circle?.toolTip = "\(localizedString("CPU usage")): \(Int(value.totalUsage.rounded(toPlaces: 2) * 100))%"
|
||||
self.circle?.setValue(value.totalUsage)
|
||||
self.circle?.setSegments([
|
||||
circle_segment(value: value.systemLoad, color: self.systemColor),
|
||||
|
||||
@@ -165,6 +165,8 @@ private class CalendarView: NSStackView {
|
||||
self.day = Calendar.current.component(.day, from: Date())
|
||||
|
||||
super.init(frame: NSRect(x: 0, y: 0, width: width, height: width - 32))
|
||||
self.setAccessibilityElement(true)
|
||||
self.toolTip = localizedString("Calendar")
|
||||
|
||||
self.spacing = 0
|
||||
self.orientation = .vertical
|
||||
@@ -442,6 +444,8 @@ private class ClockView: NSStackView {
|
||||
)
|
||||
self.wantsLayer = true
|
||||
self.layer?.cornerRadius = 2
|
||||
self.setAccessibilityElement(true)
|
||||
self.toolTip = "\(clock.name): \(clock.formatted())"
|
||||
|
||||
self.clockView.widthAnchor.constraint(equalToConstant: 34).isActive = true
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ public class Portal: PortalWrapper {
|
||||
self.usedField?.stringValue = DiskSize(value.size - value.free).getReadableMemory()
|
||||
self.freeField?.stringValue = DiskSize(value.free).getReadableMemory()
|
||||
|
||||
self.circle?.toolTip = "\(localizedString("Disk usage")): \(Int(value.percentage*100))%"
|
||||
self.circle?.setValue(value.percentage)
|
||||
self.circle?.setSegments([
|
||||
circle_segment(value: value.percentage, color: self.valueColor)
|
||||
|
||||
@@ -161,8 +161,8 @@ private class GPUView: NSStackView {
|
||||
charts.distribution = .fillEqually
|
||||
self.chartRow = charts
|
||||
|
||||
self.addStats(id: "temperature", self.value.temperature)
|
||||
self.addStats(id: "utilization", self.value.utilization)
|
||||
self.addStats(id: "GPU temperature", self.value.temperature)
|
||||
self.addStats(id: "GPU utilization", self.value.utilization)
|
||||
self.addStats(id: "Render utilization", self.value.renderUtilization)
|
||||
self.addStats(id: "Tiler utilization", self.value.tilerUtilization)
|
||||
|
||||
@@ -191,7 +191,7 @@ private class GPUView: NSStackView {
|
||||
} else {
|
||||
circle = HalfCircleGraphView(frame: NSRect(x: 0, y: 0, width: circleSize, height: circleSize))
|
||||
circle.id = id
|
||||
circle.toolTip = localizedString("GPU \(id)")
|
||||
circle.toolTip = localizedString(id)
|
||||
if let row = self.circleRow {
|
||||
row.setFrameSize(NSSize(width: row.frame.width, height: self.circleSize + 20))
|
||||
row.edgeInsets = NSEdgeInsets(top: 10, left: 10, bottom: 0, right: 10)
|
||||
@@ -208,7 +208,7 @@ private class GPUView: NSStackView {
|
||||
chart.layer?.backgroundColor = NSColor.lightGray.withAlphaComponent(0.1).cgColor
|
||||
chart.layer?.cornerRadius = 3
|
||||
chart.id = id
|
||||
chart.toolTip = localizedString("GPU \(id)")
|
||||
chart.toolTip = localizedString(id)
|
||||
if let row = self.chartRow {
|
||||
row.setFrameSize(NSSize(width: row.frame.width, height: self.chartSize + 20))
|
||||
row.spacing = Constants.Popup.margins
|
||||
@@ -223,17 +223,19 @@ private class GPUView: NSStackView {
|
||||
}
|
||||
}
|
||||
|
||||
if id == "temperature" {
|
||||
if id == "GPU temperature" {
|
||||
circle.setValue(value)
|
||||
circle.setText(temperature(value))
|
||||
circle.toolTip = "\(localizedString(id)): \(temperature(value))"
|
||||
chart.suffix = UnitTemperature.current.symbol
|
||||
|
||||
if self.temperatureChart == nil {
|
||||
self.temperatureChart = chart
|
||||
}
|
||||
} else if id == "utilization" {
|
||||
} else if id == "GPU utilization" {
|
||||
circle.setValue(value)
|
||||
circle.setText("\(Int(value*100))%")
|
||||
circle.toolTip = "\(localizedString(id)): \(Int(value*100))%"
|
||||
|
||||
if self.utilizationChart == nil {
|
||||
self.utilizationChart = chart
|
||||
@@ -241,6 +243,7 @@ private class GPUView: NSStackView {
|
||||
} else if id == "Render utilization" {
|
||||
circle.setValue(value)
|
||||
circle.setText("\(Int(value*100))%")
|
||||
circle.toolTip = "\(localizedString(id)): \(Int(value*100))%"
|
||||
|
||||
if self.renderUtilizationChart == nil {
|
||||
self.renderUtilizationChart = chart
|
||||
@@ -248,6 +251,7 @@ private class GPUView: NSStackView {
|
||||
} else if id == "Tiler utilization" {
|
||||
circle.setValue(value)
|
||||
circle.setText("\(Int(value*100))%")
|
||||
circle.toolTip = "\(localizedString(id)): \(Int(value*100))%"
|
||||
|
||||
if self.tilerUtilizationChart == nil {
|
||||
self.tilerUtilizationChart = chart
|
||||
@@ -262,8 +266,8 @@ private class GPUView: NSStackView {
|
||||
self.stateView?.layer?.backgroundColor = (gpu.state ? NSColor.systemGreen : NSColor.systemRed).cgColor
|
||||
self.stateView?.toolTip = localizedString("GPU \(gpu.state ? "enabled" : "disabled")")
|
||||
|
||||
self.addStats(id: "temperature", gpu.temperature)
|
||||
self.addStats(id: "utilization", gpu.utilization)
|
||||
self.addStats(id: "GPU temperature", gpu.temperature)
|
||||
self.addStats(id: "GPU utilization", gpu.utilization)
|
||||
self.addStats(id: "Render utilization", gpu.renderUtilization)
|
||||
self.addStats(id: "Tiler utilization", gpu.tilerUtilization)
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ public class Portal: PortalWrapper {
|
||||
self.tilerField?.stringValue = "\(Int(value*100))%"
|
||||
}
|
||||
|
||||
self.circle?.toolTip = "\(localizedString("GPU usage")): \(Int(value.utilization!*100))%"
|
||||
self.circle?.setValue(value.utilization!)
|
||||
self.circle?.setText("\(Int(value.utilization!*100))%")
|
||||
self.initialized = true
|
||||
|
||||
@@ -15,12 +15,14 @@ import Kit
|
||||
internal class Popup: PopupWrapper {
|
||||
private var title: String
|
||||
|
||||
private var uploadContainerView: NSView? = nil
|
||||
private var uploadView: NSView? = nil
|
||||
private var uploadValue: Int64 = 0
|
||||
private var uploadValueField: NSTextField? = nil
|
||||
private var uploadUnitField: NSTextField? = nil
|
||||
private var uploadStateView: ColorView? = nil
|
||||
|
||||
private var downloadContainerView: NSView? = nil
|
||||
private var downloadView: NSView? = nil
|
||||
private var downloadValue: Int64 = 0
|
||||
private var downloadValueField: NSTextField? = nil
|
||||
@@ -166,6 +168,7 @@ internal class Popup: PopupWrapper {
|
||||
|
||||
let leftPart: NSView = NSView(frame: NSRect(x: 0, y: 0, width: view.frame.width / 2, height: view.frame.height))
|
||||
let downloadFields = self.topValueView(leftPart, title: localizedString("Downloading"), color: self.downloadColor)
|
||||
self.downloadContainerView = leftPart
|
||||
self.downloadView = downloadFields.0
|
||||
self.downloadValueField = downloadFields.1
|
||||
self.downloadUnitField = downloadFields.2
|
||||
@@ -173,6 +176,7 @@ internal class Popup: PopupWrapper {
|
||||
|
||||
let rightPart: NSView = NSView(frame: NSRect(x: view.frame.width / 2, y: 0, width: view.frame.width / 2, height: view.frame.height))
|
||||
let uploadFields = self.topValueView(rightPart, title: localizedString("Uploading"), color: self.uploadColor)
|
||||
self.uploadContainerView = rightPart
|
||||
self.uploadView = uploadFields.0
|
||||
self.uploadValueField = uploadFields.1
|
||||
self.uploadUnitField = uploadFields.2
|
||||
@@ -688,6 +692,9 @@ internal class Popup: PopupWrapper {
|
||||
let topHeight: CGFloat = 30
|
||||
let titleHeight: CGFloat = 15
|
||||
|
||||
view.setAccessibilityElement(true)
|
||||
view.toolTip = title
|
||||
|
||||
let valueWidth = "0".widthOfString(usingFont: .systemFont(ofSize: 26, weight: .light)) + 5
|
||||
let unitWidth = "KB/s".widthOfString(usingFont: .systemFont(ofSize: 13, weight: .light)) + 5
|
||||
let topPartWidth = valueWidth + unitWidth
|
||||
@@ -739,6 +746,9 @@ internal class Popup: PopupWrapper {
|
||||
let upload = Units(bytes: self.uploadValue).getReadableTuple(base: self.base)
|
||||
let download = Units(bytes: self.downloadValue).getReadableTuple(base: self.base)
|
||||
|
||||
self.uploadContainerView?.toolTip = "\(localizedString("Uploading")): \(upload.0)\(upload.1)"
|
||||
self.downloadContainerView?.toolTip = "\(localizedString("Downloading")): \(download.0)\(download.1)"
|
||||
|
||||
var valueWidth = "\(upload.0)".widthOfString(usingFont: .systemFont(ofSize: 26, weight: .light)) + 5
|
||||
var unitWidth = upload.1.widthOfString(usingFont: .systemFont(ofSize: 13, weight: .light)) + 5
|
||||
var topPartWidth = valueWidth + unitWidth
|
||||
|
||||
@@ -250,6 +250,7 @@ internal class Popup: PopupWrapper {
|
||||
self.usedField?.stringValue = Units(bytes: Int64(value.used)).getReadableMemory(style: .memory)
|
||||
self.freeField?.stringValue = Units(bytes: Int64(value.free)).getReadableMemory(style: .memory)
|
||||
|
||||
self.circle?.toolTip = "\(localizedString("Memory usage")): \(Int(value.usage*100))%"
|
||||
self.circle?.setValue(value.usage)
|
||||
self.circle?.setSegments([
|
||||
circle_segment(value: value.app/value.total, color: self.appColor),
|
||||
@@ -258,6 +259,7 @@ internal class Popup: PopupWrapper {
|
||||
])
|
||||
self.circle?.setNonActiveSegmentColor(self.freeColor)
|
||||
self.level?.setValue(value.pressure)
|
||||
self.level?.toolTip = "\(localizedString("Memory pressure")): \(value.pressure.value.rawValue)"
|
||||
|
||||
self.initialized = true
|
||||
}
|
||||
@@ -431,6 +433,15 @@ public class PressureView: NSView {
|
||||
|
||||
private var value: Pressure = Pressure(level: 1, value: .normal)
|
||||
|
||||
public override init(frame: NSRect) {
|
||||
super.init(frame: frame)
|
||||
self.setAccessibilityElement(true)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public override func draw(_ rect: CGRect) {
|
||||
let arcWidth: CGFloat = 7.0
|
||||
let centerPoint = CGPoint(x: self.frame.width/2, y: self.frame.height/2)
|
||||
|
||||
@@ -111,6 +111,7 @@ public class Portal: PortalWrapper {
|
||||
self.pressureLevelField?.toolTip = localizedString(level.value)
|
||||
}
|
||||
|
||||
self.circle?.toolTip = "\(localizedString("Memory usage")): \(Int(value.usage*100))%"
|
||||
self.circle?.setValue(value.usage)
|
||||
self.circle?.setSegments([
|
||||
circle_segment(value: value.app/value.total, color: self.appColor),
|
||||
|
||||
@@ -513,7 +513,8 @@ private class ModulePreview: NSStackView {
|
||||
self.layer?.backgroundColor = NSColor.white.cgColor
|
||||
|
||||
self.identifier = NSUserInterfaceItemIdentifier(rawValue: id)
|
||||
self.toolTip = localizedString("Move module", id)
|
||||
self.setAccessibilityElement(true)
|
||||
self.toolTip = id
|
||||
|
||||
self.orientation = .vertical
|
||||
self.distribution = .fill
|
||||
|
||||
Reference in New Issue
Block a user