Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combine cpu temp and fan speed in one item #243

Open
wants to merge 3 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions iGlance/iGlance/iGlance/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@
</connections>
</button>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="5" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uK4-wT-QAk">
<rect key="frame" x="20" y="435" width="256" height="21"/>
<rect key="frame" x="20" y="411" width="256" height="21"/>
<subviews>
<button horizontalHuggingPriority="249" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Kpt-VS-dwb">
<rect key="frame" x="-2" y="2" width="126" height="18"/>
Expand Down Expand Up @@ -680,7 +680,7 @@
</customSpacing>
</stackView>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ET5-It-2lY">
<rect key="frame" x="50" y="405" width="103" height="20"/>
<rect key="frame" x="50" y="381" width="103" height="20"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hvq-Z6-w6F">
<rect key="frame" x="-2" y="2" width="79" height="16"/>
Expand Down Expand Up @@ -712,7 +712,7 @@
</customSpacing>
</stackView>
<stackView hidden="YES" distribution="fill" orientation="horizontal" alignment="bottom" spacing="10" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DUt-WU-a5o">
<rect key="frame" x="296" y="438" width="264" height="16"/>
<rect key="frame" x="296" y="414" width="264" height="16"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="58k-mq-i3p">
<rect key="frame" x="-2" y="0.0" width="82" height="16"/>
Expand Down Expand Up @@ -784,7 +784,7 @@
</customSpacing>
</stackView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7uy-pD-grI">
<rect key="frame" x="48" y="379" width="139" height="18"/>
<rect key="frame" x="48" y="355" width="139" height="18"/>
<buttonCell key="cell" type="check" title="Show graph border" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="bIW-9G-JM9">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
Expand All @@ -794,7 +794,7 @@
</connections>
</button>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="15" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3OR-d7-zts">
<rect key="frame" x="50" y="351" width="257" height="20"/>
<rect key="frame" x="50" y="327" width="257" height="20"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="u2P-Ah-WZf">
<rect key="frame" x="-2" y="1" width="134" height="18"/>
Expand Down Expand Up @@ -848,18 +848,30 @@
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sUp-UF-DGC">
<rect key="frame" x="48" y="440" width="122" height="18"/>
<buttonCell key="cell" type="check" title="Show Fan speed" bezelStyle="regularSquare" imagePosition="left" inset="2" id="4IS-AH-4Is">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="cpuFanCheckboxChanged:" target="uGw-Yr-sBC" id="CF7-wQ-usY"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="uK4-wT-QAk" firstAttribute="top" secondItem="Xe1-Jt-TNX" secondAttribute="bottom" constant="10" id="8rY-i8-XqG"/>
<constraint firstItem="DUt-WU-a5o" firstAttribute="top" secondItem="q0i-aM-agG" secondAttribute="top" constant="46" id="9YC-Bf-KUj"/>
<constraint firstItem="sUp-UF-DGC" firstAttribute="leading" secondItem="q0i-aM-agG" secondAttribute="leading" constant="50" id="4HC-RJ-oe7"/>
<constraint firstItem="Xe1-Jt-TNX" firstAttribute="leading" secondItem="q0i-aM-agG" secondAttribute="leading" constant="20" id="DRs-Qt-17T"/>
<constraint firstItem="Xe1-Jt-TNX" firstAttribute="top" secondItem="q0i-aM-agG" secondAttribute="top" constant="20" id="HAU-Hs-nVB"/>
<constraint firstItem="3OR-d7-zts" firstAttribute="top" secondItem="7uy-pD-grI" secondAttribute="bottom" constant="10" id="MPB-uW-Lzv"/>
<constraint firstItem="DUt-WU-a5o" firstAttribute="leading" secondItem="uK4-wT-QAk" secondAttribute="trailing" constant="20" id="Mh9-HG-5iZ"/>
<constraint firstItem="uK4-wT-QAk" firstAttribute="top" secondItem="sUp-UF-DGC" secondAttribute="bottom" constant="10" id="WsY-SW-l8Y"/>
<constraint firstItem="3OR-d7-zts" firstAttribute="leading" secondItem="q0i-aM-agG" secondAttribute="leading" constant="50" id="aHf-xA-42J"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Xe1-Jt-TNX" secondAttribute="trailing" constant="20" symbolic="YES" id="bbW-le-fNL"/>
<constraint firstItem="ET5-It-2lY" firstAttribute="top" secondItem="uK4-wT-QAk" secondAttribute="bottom" constant="10" id="gib-kn-MgW"/>
<constraint firstItem="sUp-UF-DGC" firstAttribute="top" secondItem="Xe1-Jt-TNX" secondAttribute="bottom" constant="10" id="gqz-hS-hge"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="7uy-pD-grI" secondAttribute="trailing" constant="20" symbolic="YES" id="gsz-Yc-sCZ"/>
<constraint firstItem="DUt-WU-a5o" firstAttribute="centerY" secondItem="uK4-wT-QAk" secondAttribute="centerY" id="ihy-o4-lGk"/>
<constraint firstItem="7uy-pD-grI" firstAttribute="top" secondItem="ET5-It-2lY" secondAttribute="bottom" constant="10" id="jJj-ps-sQl"/>
<constraint firstItem="uK4-wT-QAk" firstAttribute="leading" secondItem="q0i-aM-agG" secondAttribute="leading" constant="20" id="k9M-eE-vxB"/>
<constraint firstItem="ET5-It-2lY" firstAttribute="leading" secondItem="q0i-aM-agG" secondAttribute="leading" constant="50" id="w9C-V5-6Y8"/>
Expand All @@ -869,6 +881,7 @@
</view>
<connections>
<outlet property="colorGradientCheckbox" destination="u2P-Ah-WZf" id="c1t-W1-odS"/>
<outlet property="cpuFanCheckbox" destination="sUp-UF-DGC" id="sNA-U6-CA6"/>
<outlet property="cpuTempCheckbox" destination="Xe1-Jt-TNX" id="QS5-Xf-9a3"/>
<outlet property="cpuUsageCheckbox" destination="Kpt-VS-dwb" id="Iyq-Nt-2xy"/>
<outlet property="graphColorStackView" destination="ET5-It-2lY" id="PTE-qE-dn2"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ class CpuViewController: MainViewViewController {
cpuTempCheckbox.state = AppDelegate.userSettings.settings.cpu.showTemperature ? NSButton.StateValue.on : NSButton.StateValue.off
}
}
@IBOutlet private var cpuFanCheckbox: NSButton! {
didSet {
cpuFanCheckbox.state = AppDelegate.userSettings.settings.cpu.showFanSpeed ? NSButton.StateValue.on : NSButton.StateValue.off
}
}
@IBOutlet private var cpuUsageCheckbox: NSButton! {
didSet {
cpuUsageCheckbox.state = AppDelegate.userSettings.settings.cpu.showUsage ? NSButton.StateValue.on : NSButton.StateValue.off
Expand Down Expand Up @@ -136,6 +141,7 @@ class CpuViewController: MainViewViewController {
override func updateGUIComponents() {
// Call didSet methods of all GUI components
self.cpuTempCheckbox = { self.cpuTempCheckbox }()
self.cpuFanCheckbox = { self.cpuFanCheckbox }()
self.cpuUsageCheckbox = { self.cpuUsageCheckbox }()
self.graphSelector = { self.graphSelector }()
self.graphWidthStackView = { self.graphWidthStackView }()
Expand Down Expand Up @@ -170,6 +176,20 @@ class CpuViewController: MainViewViewController {
DDLogInfo("Did set cpu temp checkbox value to (\(activated))")
}

@IBAction private func cpuFanCheckboxChanged(_ sender: NSButton) {
// get the boolean to the current state of the checkbox
let activated = sender.state == NSButton.StateValue.on

// set the user settings
AppDelegate.userSettings.settings.cpu.showFanSpeed = activated
if activated && !AppDelegate.userSettings.settings.cpu.showTemperature {
cpuTempCheckbox.state = .on
cpuTempCheckboxChanged(cpuTempCheckbox)
}

DDLogInfo("Did set cpu temp checkbox value to (\(activated))")
}

@IBAction private func cpuUsageCheckboxChanged(_ sender: NSButton) {
// get the boolean to the current state of the checkbox
let activated = sender.state == NSButton.StateValue.on
Expand Down
101 changes: 90 additions & 11 deletions iGlance/iGlance/iGlance/MenuBarItems/Cpu/CpuTempMenuBarItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ class CpuTempMenuBarItem: MenuBarItem {
// MARK: -
// MARK: Protocol Implementations

/// the number of fans of the machine
private let fanCount: Int

override init() {
// initially get the number of fans
fanCount = AppDelegate.systemInfo.fan.getNumberOfFans()
super.init()
}

func update() {
self.statusItem.isVisible = AppDelegate.userSettings.settings.cpu.showTemperature
if !self.statusItem.isVisible {
Expand All @@ -38,10 +47,26 @@ class CpuTempMenuBarItem: MenuBarItem {
DDLogError("Could not retrieve the button of the 'CpuTempMenuBarItem'")
return
}
if AppDelegate.userSettings.settings.cpu.showFanSpeed {
// get the info for every fan
var fanInfo: [(currentFanSpeed: Int, maxFanSpeed: Int, minFanSpeed: Int)] = []
for id in 0..<fanCount {
// get the fan speed for the current fan
let currentFanSpeed = AppDelegate.systemInfo.fan.getCurrentFanSpeed(id: id)
let maxFanSpeed = AppDelegate.systemInfo.fan.getMaxFanSpeed(id: id)
let minFanSpeed = AppDelegate.systemInfo.fan.getMinFanSpeed(id: id)

fanInfo.append((currentFanSpeed: currentFanSpeed, maxFanSpeed: maxFanSpeed, minFanSpeed: minFanSpeed))
}
button.image = createFanTempMenuBarImage(fanInfo: fanInfo, temp: temp)
} else {
button.image = createTempMenuBarImage(temp: temp)
}
}

private func createTempMenuBarImage(temp: Int) -> NSImage? {
// get the string that is going to be rendered
let buttonString = createAttributedTempString(value: temp)

// create an image for the menu bar item
let imageWidth = CGFloat(30)
let image = NSImage(size: NSSize(width: imageWidth, height: self.menubarHeightWithMargin))
Expand All @@ -55,26 +80,80 @@ class CpuTempMenuBarItem: MenuBarItem {
// unlock the focus of the image
image.unlockFocus()

button.image = image
return image
}

private func createFanTempMenuBarImage(fanInfo: [(currentFanSpeed: Int, maxFanSpeed: Int, minFanSpeed: Int)], temp: Int) -> NSImage? {
var curMaxFanSpeed = 0
for info in fanInfo {
// get the fan speed for the current fan
let fanSpeed = info.currentFanSpeed

// if the rpm of the current fan is higher than the saved fan speed update it
if curMaxFanSpeed < fanSpeed {
curMaxFanSpeed = fanSpeed
}
}

// get the string that is going to be rendered
let tempString = createAttributedTempString(value: temp, isSingleLine: false)
let fanString = createAttributedFanString(value: Int(curMaxFanSpeed))

let tempStringSize = tempString.size()
let fanStringSize = fanString.size()

// create an image for the menu bar item
let imageWidth = max(tempStringSize.width, fanStringSize.width)
let image = NSImage(size: NSSize(width: imageWidth, height: self.menubarHeightWithMargin))

// lock the image to render the string
image.lockFocus()

// render the string
tempString.draw(at: NSPoint(x: 0, y: image.size.height - 9))
fanString.draw(at: NSPoint(x: 0, y: -1))

// unlock the focus of the image
image.unlockFocus()

return image
}

/**
* Returns the attributed string of the current cpu temperature that can be rendered on an image.
*
* - Parameter value: The given cpu temperature
*/
private func createAttributedTempString(value: Int) -> NSAttributedString {
private func createAttributedTempString(value: Int, isSingleLine: Bool = true) -> NSAttributedString {
// create the attributed string
let string = String(value) + "°"
let attribString = NSMutableAttributedString(string: string)

// define the font
let font = NSFont.systemFont(ofSize: 13)

attribString.addAttribute(.font, value: font, range: NSRange(location: 0, length: string.count))
let fontColor = ThemeManager.isDarkTheme() ? NSColor.white : NSColor.black
attribString.addAttribute(.foregroundColor, value: fontColor, range: NSRange(location: 0, length: string.count))
let attributes = createAttributes(isForSingleLine: isSingleLine)
let attribString = NSMutableAttributedString(string: string, attributes: attributes)
return attribString
}

/**
* Returns the attributed string of the current cpu fan speed that can be rendered on an image.
*
* - Parameter value: The given cpu fan speed
*/
private func createAttributedFanString(value: Int) -> NSAttributedString {
// create the attributed string
let unit = AppDelegate.userSettings.settings.fan.showFanSpeedUnit ? "RMP" : ""
let string = String(value) + unit
let attributes = createAttributes(isForSingleLine: false)
let attribString = NSMutableAttributedString(string: string, attributes: attributes)
return attribString
}

private func createAttributes(isForSingleLine: Bool) -> [NSAttributedString.Key: Any] {
var attributes: [NSAttributedString.Key: Any] = [.foregroundColor: ThemeManager.isDarkTheme() ? NSColor.white : NSColor.black]
if isForSingleLine {
attributes[.font] = NSFont.systemFont(ofSize: 13)
} else {
attributes[.font] = NSFont.systemFont(ofSize: 9)
attributes[.kern] = 1.2
}
return attributes
}
}
5 changes: 5 additions & 0 deletions iGlance/iGlance/iGlance/UserSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct ColorGradientSettings: Codable, Equatable {

struct CpuSettings: Codable, Equatable {
var showTemperature: Bool = true
var showFanSpeed: Bool = false
var showUsage: Bool = true
var usageGraphColor = CodableColor(nsColor: NSColor.green)
var usageGraphKind: GraphKind = .bar
Expand All @@ -50,6 +51,9 @@ struct CpuSettings: Codable, Equatable {
if let decodedShowTemperature = try? container.decodeIfPresent(Bool.self, forKey: .showTemperature) {
self.showTemperature = decodedShowTemperature
}
if let decodedShowFanSpeed = try? container.decodeIfPresent(Bool.self, forKey: .showFanSpeed) {
self.showFanSpeed = decodedShowFanSpeed
}
if let decodedShowUsage = try? container.decodeIfPresent(Bool.self, forKey: .showUsage) {
self.showUsage = decodedShowUsage
}
Expand All @@ -72,6 +76,7 @@ struct CpuSettings: Codable, Equatable {

static func == (lhs: CpuSettings, rhs: CpuSettings) -> Bool {
lhs.showTemperature == rhs.showTemperature
&& lhs.showFanSpeed == rhs.showFanSpeed
&& lhs.showUsage == rhs.showUsage
&& lhs.usageGraphColor == rhs.usageGraphColor
&& lhs.usageGraphKind == rhs.usageGraphKind
Expand Down