From 550cd7ad3523c2c06288686e7caf109cff03d264 Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Tue, 2 May 2023 17:56:14 +0200 Subject: [PATCH] feat: added a button to show/hide a fan control panel (#1416) --- .../tune.imageset/Contents.json | 26 +++ .../outline_tune_black_18pt_1x.png | Bin 0 -> 147 bytes .../outline_tune_black_18pt_2x.png | Bin 0 -> 170 bytes .../outline_tune_black_18pt_3x.png | Bin 0 -> 197 bytes Kit/helpers.swift | 1 - Kit/types.swift | 1 + Modules/Sensors/popup.swift | 155 ++++++++++++------ 7 files changed, 132 insertions(+), 51 deletions(-) create mode 100644 Kit/Supporting Files/Assets.xcassets/tune.imageset/Contents.json create mode 100644 Kit/Supporting Files/Assets.xcassets/tune.imageset/outline_tune_black_18pt_1x.png create mode 100644 Kit/Supporting Files/Assets.xcassets/tune.imageset/outline_tune_black_18pt_2x.png create mode 100644 Kit/Supporting Files/Assets.xcassets/tune.imageset/outline_tune_black_18pt_3x.png diff --git a/Kit/Supporting Files/Assets.xcassets/tune.imageset/Contents.json b/Kit/Supporting Files/Assets.xcassets/tune.imageset/Contents.json new file mode 100644 index 00000000..db1581b1 --- /dev/null +++ b/Kit/Supporting Files/Assets.xcassets/tune.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "outline_tune_black_18pt_1x.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "outline_tune_black_18pt_2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "outline_tune_black_18pt_3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Kit/Supporting Files/Assets.xcassets/tune.imageset/outline_tune_black_18pt_1x.png b/Kit/Supporting Files/Assets.xcassets/tune.imageset/outline_tune_black_18pt_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..2ebaa3f76a3ecc45d320cc52f18bc89798617d9c GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mqC8z3Lp07OCoC|1!R};|aNt1$ z3vYwcZ^?6qZw73b|Il9OPQS{g`7Vt4Ccc{w vE#~Gl9R19|k0wldT1B8K8p{I*uh{y4_A&y)J6nI`={~hOQ@x<=e8FzJN+;Lf?sHh~pF~D*0uU3Vvg7Tbm@26eyTM=_EKQ5VNXLF}h;y(=-$LDwg8?&p28mqxDV0_AFU#F;CD;b|v@AP182dk=Bz*{K&Iz U?_}m}K+73CUHx3vIVCg!0Gx3?+yDRo literal 0 HcmV?d00001 diff --git a/Kit/Supporting Files/Assets.xcassets/tune.imageset/outline_tune_black_18pt_3x.png b/Kit/Supporting Files/Assets.xcassets/tune.imageset/outline_tune_black_18pt_3x.png new file mode 100644 index 0000000000000000000000000000000000000000..4eaf2a189e0f27f800793e7561daf441583ad275 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL0wmRZ7KH(+9#0p?kch)?ryUeLpuoYR*%+kJ z*cY@&b;*(^$#Fh1iw`v4xf`B7*O9M7Va22wTV_8_^a|h3G>uO NSView { + let view: NSStackView = NSStackView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: 26)) + view.widthAnchor.constraint(equalToConstant: view.frame.width).isActive = true + view.heightAnchor.constraint(equalToConstant: view.bounds.height).isActive = true + view.orientation = .horizontal + view.spacing = 0 + view.distribution = .fillEqually + view.alignment = .top + + let labelView: NSTextField = TextView() + labelView.stringValue = localizedString("Fans") + labelView.alignment = .center + labelView.textColor = .secondaryLabelColor + labelView.font = NSFont.systemFont(ofSize: 12, weight: .medium) + + let btnContainer = NSView() + + let button = NSButton() + button.frame = CGRect(x: (self.frame.width/3)-20, y: 10, width: 15, height: 15) + button.bezelStyle = .regularSquare + button.isBordered = false + button.imageScaling = NSImageScaling.scaleAxesIndependently + button.contentTintColor = .lightGray + button.action = #selector(self.toggleFanControl) + button.target = self + button.toolTip = localizedString("Control") + button.image = Bundle(for: Module.self).image(forResource: "tune")! + + btnContainer.addSubview(button) + + view.addArrangedSubview(NSView()) + view.addArrangedSubview(labelView) + view.addArrangedSubview(btnContainer) + + return view + } + + @objc private func toggleSensor(_ sender: NSControl) { guard let id = sender.identifier else { return } Store.shared.set(key: "sensor_\(id.rawValue)_popup", value: controlState(sender)) self.setup(reload: true) } + + @objc private func toggleFanControl() { + self.fanControlState = !self.fanControlState + NotificationCenter.default.post(name: .toggleFanControl, object: nil, userInfo: ["state": self.fanControlState]) + } } // MARK: - Sensor view @@ -391,7 +444,7 @@ internal class FanView: NSStackView { private var speedState: Bool { Store.shared.bool(key: "Sensors_speed", defaultValue: false) } - private var fansSyncState: Bool { + private var syncState: Bool { Store.shared.bool(key: "Sensors_fansSync", defaultValue: false) } private var speed: Double { @@ -403,6 +456,7 @@ internal class FanView: NSStackView { } } private var resetModeAfterSleep: Bool = false + private var controlState: Bool private var horizontalMargin: CGFloat { self.edgeInsets.top + self.edgeInsets.bottom + (self.spacing*CGFloat(self.arrangedSubviews.count)) @@ -414,6 +468,7 @@ internal class FanView: NSStackView { public init(_ fan: Fan, width: CGFloat, callback: @escaping (() -> Void)) { self.fan = fan self.sizeCallback = callback + self.controlState = Store.shared.bool(key: "Sensors_fanControl", defaultValue: true) let inset: CGFloat = 5 super.init(frame: NSRect(x: 0, y: 0, width: width - (inset*2), height: 0)) @@ -432,28 +487,13 @@ internal class FanView: NSStackView { self.layer?.backgroundColor = NSColor.red.cgColor self.nameAndSpeed() - - if !SMCHelper.shared.isInstalled { - if let v = self.helperView { - self.addArrangedSubview(v) - } - } else { - if self.fan.maxSpeed != self.fan.minSpeed, let v = self.buttonsView { - self.addArrangedSubview(v) - } - if fan.mode == .forced, let view = self.controlView { - self.addArrangedSubview(view) - } - } - - let h = self.arrangedSubviews.map({ $0.bounds.height }).reduce(0, +) - self.setFrameSize(NSSize(width: self.frame.width, height: h + self.horizontalMargin)) - self.sizeCallback() + self.setupControls() NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.wakeListener), name: NSWorkspace.didWakeNotification, object: nil) NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.sleepListener), name: NSWorkspace.willSleepNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(syncFanSpeed), name: .syncFansControl, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(changeHelperState), name: .fanHelperState, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.syncFanSpeed), name: .syncFansControl, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.changeHelperState), name: .fanHelperState, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.controlCallback), name: .toggleFanControl, object: nil) if let fanMode = self.fan.customMode, self.speedState && fanMode != FanMode.automatic { SMCHelper.shared.setFanMode(fan.id, mode: fanMode.rawValue) @@ -473,7 +513,9 @@ internal class FanView: NSStackView { deinit { NSWorkspace.shared.notificationCenter.removeObserver(self) - NotificationCenter.default.removeObserver(self) + NotificationCenter.default.removeObserver(self, name: .syncFansControl, object: nil) + NotificationCenter.default.removeObserver(self, name: .fanHelperState, object: nil) + NotificationCenter.default.removeObserver(self, name: .toggleSettings, object: nil) } override func updateLayer() { @@ -496,7 +538,6 @@ internal class FanView: NSStackView { let value = self.fan.value let valueField: NSTextField = TextView() valueField.font = NSFont.systemFont(ofSize: 13, weight: .regular) - valueField.stringValue = self.fan.formattedValue valueField.alignment = .right valueField.stringValue = "\(self.fan.percentage)%" valueField.toolTip = "\(value)" @@ -766,7 +807,7 @@ internal class FanView: NSStackView { } @objc private func syncFanSpeed(_ notification: Notification) { - guard self.fansSyncState else { return } + guard self.syncState else { return } var speed = notification.userInfo?["speed"] as? Int if let percentage = notification.userInfo?["percentage"] as? Int { speed = ((Int(self.fan.maxSpeed - self.fan.minSpeed)*percentage)/100) + Int(self.fan.minSpeed) @@ -819,20 +860,28 @@ internal class FanView: NSStackView { } } - private func setupControls(_ state: Bool) { - if state { + private func setupControls(_ isInstalled: Bool? = nil) { + let helperState = isInstalled ?? SMCHelper.shared.isInstalled + + if !self.controlState { self.helperView?.removeFromSuperview() - if self.fan.maxSpeed != self.fan.minSpeed, let v = self.buttonsView { - self.addArrangedSubview(v) - } - if self.fan.mode == .forced, let v = self.controlView { - self.addArrangedSubview(v) - } - } else { - self.buttonsView?.removeFromSuperview() self.controlView?.removeFromSuperview() - if let v = self.helperView { - self.addArrangedSubview(v) + self.buttonsView?.removeFromSuperview() + } else { + if helperState { + self.helperView?.removeFromSuperview() + if self.fan.maxSpeed != self.fan.minSpeed, let v = self.buttonsView { + self.addArrangedSubview(v) + } + if self.fan.mode == .forced, let v = self.controlView { + self.addArrangedSubview(v) + } + } else { + self.buttonsView?.removeFromSuperview() + self.controlView?.removeFromSuperview() + if let v = self.helperView { + self.addArrangedSubview(v) + } } } @@ -845,6 +894,12 @@ internal class FanView: NSStackView { guard let state = notification.userInfo?["state"] as? Bool else { return } self.setupControls(state) } + + @objc private func controlCallback(_ notification: Notification) { + guard let state = notification.userInfo?["state"] as? Bool else { return } + self.controlState = state + self.setupControls() + } } private class ModeButtons: NSStackView {