From ca5578970f74e6fafa4e7a3d152568aea1b88dfe Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Fri, 14 Jun 2019 16:51:16 +0200 Subject: [PATCH] moved view to file --- Stats.xcodeproj/project.pbxproj | 4 + Stats/Modules/Battery/Battery.swift | 79 -------------- Stats/Modules/Battery/BatteryReader.swift | 120 +++------------------- Stats/Modules/Battery/BatteryView.swift | 88 ++++++++++++++++ 4 files changed, 107 insertions(+), 184 deletions(-) create mode 100644 Stats/Modules/Battery/BatteryView.swift diff --git a/Stats.xcodeproj/project.pbxproj b/Stats.xcodeproj/project.pbxproj index 77daa7aa..7c9af989 100755 --- a/Stats.xcodeproj/project.pbxproj +++ b/Stats.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 9A09C89E22B3A7C90018426F /* Battery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A09C89D22B3A7C90018426F /* Battery.swift */; }; 9A09C8A022B3A7E20018426F /* BatteryReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A09C89F22B3A7E20018426F /* BatteryReader.swift */; }; + 9A09C8A222B3D94D0018426F /* BatteryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A09C8A122B3D94D0018426F /* BatteryView.swift */; }; 9A1410F9229E721100D29793 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1410F8229E721100D29793 /* AppDelegate.swift */; }; 9A141100229E721200D29793 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9A1410FE229E721200D29793 /* Main.storyboard */; }; 9A57A18522A1D26D0033E318 /* MenuBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A57A18422A1D26D0033E318 /* MenuBar.swift */; }; @@ -48,6 +49,7 @@ /* Begin PBXFileReference section */ 9A09C89D22B3A7C90018426F /* Battery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Battery.swift; sourceTree = ""; }; 9A09C89F22B3A7E20018426F /* BatteryReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryReader.swift; sourceTree = ""; }; + 9A09C8A122B3D94D0018426F /* BatteryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryView.swift; sourceTree = ""; }; 9A1410F5229E721100D29793 /* Stats.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Stats.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9A1410F8229E721100D29793 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 9A1410FF229E721200D29793 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -99,6 +101,7 @@ isa = PBXGroup; children = ( 9A09C89D22B3A7C90018426F /* Battery.swift */, + 9A09C8A122B3D94D0018426F /* BatteryView.swift */, 9A09C89F22B3A7E20018426F /* BatteryReader.swift */, ); path = Battery; @@ -322,6 +325,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9A09C8A222B3D94D0018426F /* BatteryView.swift in Sources */, 9A7B8F6F22A2C57000DEB352 /* DiskReader.swift in Sources */, 9A7B8F6922A2C3A100DEB352 /* Memory.swift in Sources */, 9A7B8F5E22A2A57600DEB352 /* CPUReader.swift in Sources */, diff --git a/Stats/Modules/Battery/Battery.swift b/Stats/Modules/Battery/Battery.swift index 19923b10..d07ca3c0 100644 --- a/Stats/Modules/Battery/Battery.swift +++ b/Stats/Modules/Battery/Battery.swift @@ -8,85 +8,6 @@ import Cocoa -class BatteryView: NSView { - var value: Float { - didSet { - self.needsDisplay = true - setNeedsDisplay(self.frame) - } - } - var charging: Bool { - didSet { - self.needsDisplay = true - setNeedsDisplay(self.frame) - } - } - - override init(frame: NSRect) { - self.value = 1.0 - self.charging = false - super.init(frame: frame) - self.wantsLayer = true - self.addSubview(NSView()) - } - - required init?(coder decoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func draw(_ dirtyRect: NSRect) { - super.draw(dirtyRect) - - let x: CGFloat = 4.0 - let w: CGFloat = dirtyRect.size.width - (x * 2) - let h: CGFloat = 11.0 - let y: CGFloat = (dirtyRect.size.height - h) / 2 - let r: CGFloat = 1.0 - - let battery = NSBezierPath(roundedRect: NSRect(x: x-1, y: y, width: w-1, height: h), xRadius: r, yRadius: r) - - let bPX: CGFloat = x+w-2 - let bPY: CGFloat = (dirtyRect.size.height / 2) - 2 - let batteryPoint = NSBezierPath(roundedRect: NSRect(x: bPX, y: bPY, width: 2, height: 4), xRadius: r, yRadius: r) - if self.charging { - NSColor.systemGreen.set() - } else { - NSColor.labelColor.set() - } - batteryPoint.lineWidth = 1.1 - batteryPoint.stroke() - batteryPoint.fill() - - let maxWidth = w-4.25 - let inner = NSBezierPath(roundedRect: NSRect(x: x+0.75, y: y+1.5, width: maxWidth*CGFloat(self.value), height: h-3), xRadius: 0.5, yRadius: 0.5) - self.value.batteryColor().set() - inner.lineWidth = 0 - inner.stroke() - inner.close() - inner.fill() - - if self.charging { - NSColor.systemGreen.set() - } else { - NSColor.labelColor.set() - } - battery.lineWidth = 0.8 - battery.stroke() - } - - func changeValue(value: Float) { - if self.value != value { - self.value = value - } - } - - func setCharging(value: Bool) { - if self.charging != value { - self.charging = value - } - } -} - class Battery: Module { let name: String = "Battery" var view: NSView = NSView() diff --git a/Stats/Modules/Battery/BatteryReader.swift b/Stats/Modules/Battery/BatteryReader.swift index a2a6eb94..8e493589 100644 --- a/Stats/Modules/Battery/BatteryReader.swift +++ b/Stats/Modules/Battery/BatteryReader.swift @@ -7,6 +7,7 @@ // import Foundation +import IOKit.ps class BatteryReader: Reader { var usage: Observable! @@ -38,7 +39,6 @@ class BatteryReader: Reader { } func start() { - _ = self.open() if updateTimer != nil { return } @@ -46,7 +46,6 @@ class BatteryReader: Reader { } func stop() { - _ = self.close() if updateTimer == nil { return } @@ -55,110 +54,21 @@ class BatteryReader: Reader { } @objc func read() { - var cap = charge() - let charging = isCharging() + let psInfo = IOPSCopyPowerSourcesInfo().takeRetainedValue() + let psList = IOPSCopyPowerSourcesList(psInfo).takeRetainedValue() as [CFTypeRef] - if !charging { - cap = 0 - cap + for ps in psList { + if let psDesc = IOPSGetPowerSourceDescription(psInfo, ps).takeUnretainedValue() as? [String: Any] { +// let type = psDesc[kIOPSTypeKey] as? String + let isCharging = (psDesc[kIOPSIsChargingKey] as? Bool) + var cap: Float = Float(psDesc[kIOPSCurrentCapacityKey] as! Int) / 100 + + if !isCharging! { + cap = 0 - cap + } + + self.usage << Float(cap) + } } - - self.usage << Float(cap) - } - - public func open() -> kern_return_t { - if (service != 0) { - #if DEBUG - print("WARNING - \(#file):\(#function) - connection already open") - #endif - return kIOReturnStillOpen - } - - service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceNameMatching("AppleSmartBattery")) - - if (service == 0) { - #if DEBUG - print("ERROR - \(#file):\(#function) - service not found") - #endif - return kIOReturnNotFound - } - - return kIOReturnSuccess - } - - public func close() -> kern_return_t { - let result = IOObjectRelease(service) - service = 0 - - #if DEBUG - if (result != kIOReturnSuccess) { - print("ERROR - \(#file):\(#function) - Failed to close") - } - #endif - - return result - } - - public func maxCapactiy() -> Int { - let prop = IORegistryEntryCreateCFProperty(service, Key.MaxCapacity.rawValue as CFString, kCFAllocatorDefault, 0) - - if prop != nil { - return prop!.takeUnretainedValue() as! Int - } - return 0 - } - - public func currentCapacity() -> Int { - let prop = IORegistryEntryCreateCFProperty(service, Key.CurrentCapacity.rawValue as CFString, kCFAllocatorDefault, 0) - - if prop != nil { - return prop!.takeUnretainedValue() as! Int - } - return 0 - } - - public func isACPowered() -> Bool { - let prop = IORegistryEntryCreateCFProperty(service, Key.ACPowered.rawValue as CFString, kCFAllocatorDefault, 0) - - if prop != nil { - return prop!.takeUnretainedValue() as! Bool - } - return false - } - - public func isCharging() -> Bool { - let prop = IORegistryEntryCreateCFProperty(service, Key.IsCharging.rawValue as CFString, kCFAllocatorDefault, 0) - - if prop != nil { - return prop!.takeUnretainedValue() as! Bool - } - return false - } - - public func isCharged() -> Bool { - let prop = IORegistryEntryCreateCFProperty(service, Key.FullyCharged.rawValue as CFString, kCFAllocatorDefault, 0) - - if prop != nil { - return prop!.takeUnretainedValue() as! Bool - } - return false - } - - public func charge() -> Double { - let ccap = Double(currentCapacity()) - let mcap = Double(maxCapactiy()) - - if ccap != 0 && mcap != 0 { - return ccap / mcap - } - return 0 - } - - public func timeRemaining() -> Int { - let prop = IORegistryEntryCreateCFProperty(service, Key.TimeRemaining.rawValue as CFString, kCFAllocatorDefault, 0) - - if prop != nil { - return prop!.takeUnretainedValue() as! Int - } - return 0 } } diff --git a/Stats/Modules/Battery/BatteryView.swift b/Stats/Modules/Battery/BatteryView.swift new file mode 100644 index 00000000..36a011e7 --- /dev/null +++ b/Stats/Modules/Battery/BatteryView.swift @@ -0,0 +1,88 @@ +// +// BatteryView.swift +// Stats +// +// Created by Serhiy Mytrovtsiy on 14/06/2019. +// Copyright © 2019 Serhiy Mytrovtsiy. All rights reserved. +// + +import Cocoa + +class BatteryView: NSView { + var value: Float { + didSet { + self.needsDisplay = true + setNeedsDisplay(self.frame) + } + } + var charging: Bool { + didSet { + self.needsDisplay = true + setNeedsDisplay(self.frame) + } + } + + override init(frame: NSRect) { + self.value = 1.0 + self.charging = false + super.init(frame: frame) + self.wantsLayer = true + self.addSubview(NSView()) + } + + required init?(coder decoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func draw(_ dirtyRect: NSRect) { + super.draw(dirtyRect) + + let x: CGFloat = 4.0 + let w: CGFloat = dirtyRect.size.width - (x * 2) + let h: CGFloat = 11.0 + let y: CGFloat = (dirtyRect.size.height - h) / 2 + let r: CGFloat = 1.0 + + let battery = NSBezierPath(roundedRect: NSRect(x: x-1, y: y, width: w-1, height: h), xRadius: r, yRadius: r) + + let bPX: CGFloat = x+w-2 + let bPY: CGFloat = (dirtyRect.size.height / 2) - 2 + let batteryPoint = NSBezierPath(roundedRect: NSRect(x: bPX, y: bPY, width: 2, height: 4), xRadius: r, yRadius: r) + if self.charging { + NSColor.systemGreen.set() + } else { + NSColor.labelColor.set() + } + batteryPoint.lineWidth = 1.1 + batteryPoint.stroke() + batteryPoint.fill() + + let maxWidth = w-4.25 + let inner = NSBezierPath(roundedRect: NSRect(x: x+0.75, y: y+1.5, width: maxWidth*CGFloat(self.value), height: h-3), xRadius: 0.5, yRadius: 0.5) + self.value.batteryColor().set() + inner.lineWidth = 0 + inner.stroke() + inner.close() + inner.fill() + + if self.charging { + NSColor.systemGreen.set() + } else { + NSColor.labelColor.set() + } + battery.lineWidth = 0.8 + battery.stroke() + } + + func changeValue(value: Float) { + if self.value != value { + self.value = value + } + } + + func setCharging(value: Bool) { + if self.charging != value { + self.charging = value + } + } +}