Skip to content

Commit

Permalink
Merge pull request #1 from exelban/dev
Browse files Browse the repository at this point in the history
v1.1.0
  • Loading branch information
exelban authored Jun 17, 2019
2 parents e89997f + 5fd3fc1 commit e1fc6de
Show file tree
Hide file tree
Showing 23 changed files with 1,109 additions and 303 deletions.
40 changes: 30 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
# Stats
Application for macos that shows CPU, Memory and Disk usage on the menu bar
Simple macOS system monitor in your menu bar

[<img src="https://serhiy.s3.eu-central-1.amazonaws.com/Github_repo/stats/widgets%3Fv1.0.0.png" width="500">](https://github.com/exelban/stats/releases)
[<img src="https://serhiy.s3.eu-central-1.amazonaws.com/Github_repo/stats/widgets%3Fv1.1.0.1.png">](https://github.com/exelban/stats/releases)

## Why
Stats is a application which allows you to monitor your macOS system.
Also its:

- free
- easy to use
- no advertisement
- no tracking
- few types of widgets
- black theme compatible

## Installation
You can download latest version [here](https://github.com/exelban/stats/releases).

## Widgets
Each widget can be disabled in menu.
## Modules

| Name | Type | Description |
| Name | Available widgets | Description |
| --- | --- | --- |
| **CPU** | Percentage | Shows CPU usage |
| **Memory** | Percentage | Shows RAM usage |
| **CPU** | Percentage / Chart / Chart with value | Shows CPU usage |
| **Memory** | Percentage / Chart / Chart with value | Shows RAM usage |
| **Disk** | Percentage | Shows disk filling |
| **Battery** | Graphic / Percentage | Shows battery level and charging status |

## Compatibility
| macOS | Compatible |
Expand All @@ -22,18 +33,27 @@ Each widget can be disabled in menu.
| 10.14.1 *(Mojave)* | **true** |

## Todo
- [ ] Battery percentage
- [ ] Create new logo
- [ ] Window with preferences
- [ ] Save last modules values
- [ ] Colors toggle for each module
- [ ] temperature module
- [ ] battery module
- [X] battery module
- [X] move to module system (CPU, RAM, DISK)
- [ ] network module
- [X] save settings
- [ ] tests
- [ ] OTA updates
- [ ] charts
- [X] charts
- [X] autostart on boot

## What's new

### v1.1.0
- added battery module
- added chart widget for CPU and Memory
- added About Stats window

### v1.0.0
- first release

Expand Down
52 changes: 40 additions & 12 deletions Stats.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
objects = {

/* 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 */; };
Expand All @@ -15,10 +18,9 @@
9A5B1CBF229E78F0008B9D3C /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A5B1CBE229E78F0008B9D3C /* Observable.swift */; };
9A5B1CC5229E7B40008B9D3C /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A5B1CC4229E7B40008B9D3C /* Extensions.swift */; };
9A6CFC0122A1C9F5001E782D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9A6CFC0022A1C9F5001E782D /* Assets.xcassets */; };
9A7B8F5B22A290A200DEB352 /* CPU.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9A7B8F5A22A290A200DEB352 /* CPU.xib */; };
9A74D59422B4315C004FE1FA /* Chart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A74D59322B4315C004FE1FA /* Chart.swift */; };
9A74D59722B44498004FE1FA /* Mini.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A74D59622B44498004FE1FA /* Mini.swift */; };
9A7B8F5E22A2A57600DEB352 /* CPUReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A7B8F5D22A2A57600DEB352 /* CPUReader.swift */; };
9A7B8F6522A2C19D00DEB352 /* Memory.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9A7B8F6422A2C19D00DEB352 /* Memory.xib */; };
9A7B8F6722A2C1B900DEB352 /* Disk.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9A7B8F6622A2C1B900DEB352 /* Disk.xib */; };
9A7B8F6922A2C3A100DEB352 /* Memory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A7B8F6822A2C3A100DEB352 /* Memory.swift */; };
9A7B8F6B22A2C3A700DEB352 /* Disk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A7B8F6A22A2C3A700DEB352 /* Disk.swift */; };
9A7B8F6D22A2C3D600DEB352 /* MemoryReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A7B8F6C22A2C3D600DEB352 /* MemoryReader.swift */; };
Expand All @@ -27,6 +29,7 @@
9AFA402822AE49A200FE90BC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9AFA402622AE49A200FE90BC /* Main.storyboard */; };
9AFA402F22AE49AE00FE90BC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AFA402E22AE49AE00FE90BC /* AppDelegate.swift */; };
9AFA403022AE49DD00FE90BC /* StatsLauncher.app in Copy Files */ = {isa = PBXBuildFile; fileRef = 9AFA401E22AE49A100FE90BC /* StatsLauncher.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
9AFFCB3B22B3FD0500B0E6D8 /* About.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9AFFCB3A22B3FD0500B0E6D8 /* About.storyboard */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand All @@ -44,6 +47,9 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
9A09C89D22B3A7C90018426F /* Battery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Battery.swift; sourceTree = "<group>"; };
9A09C89F22B3A7E20018426F /* BatteryReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryReader.swift; sourceTree = "<group>"; };
9A09C8A122B3D94D0018426F /* BatteryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryView.swift; sourceTree = "<group>"; };
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 = "<group>"; };
9A1410FF229E721200D29793 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
Expand All @@ -55,10 +61,9 @@
9A5B1CBE229E78F0008B9D3C /* Observable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = "<group>"; };
9A5B1CC4229E7B40008B9D3C /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
9A6CFC0022A1C9F5001E782D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
9A7B8F5A22A290A200DEB352 /* CPU.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CPU.xib; sourceTree = "<group>"; };
9A74D59322B4315C004FE1FA /* Chart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Chart.swift; sourceTree = "<group>"; };
9A74D59622B44498004FE1FA /* Mini.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mini.swift; sourceTree = "<group>"; };
9A7B8F5D22A2A57600DEB352 /* CPUReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPUReader.swift; sourceTree = "<group>"; };
9A7B8F6422A2C19D00DEB352 /* Memory.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Memory.xib; sourceTree = "<group>"; };
9A7B8F6622A2C1B900DEB352 /* Disk.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Disk.xib; sourceTree = "<group>"; };
9A7B8F6822A2C3A100DEB352 /* Memory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Memory.swift; sourceTree = "<group>"; };
9A7B8F6A22A2C3A700DEB352 /* Disk.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Disk.swift; sourceTree = "<group>"; };
9A7B8F6C22A2C3D600DEB352 /* MemoryReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryReader.swift; sourceTree = "<group>"; };
Expand All @@ -71,6 +76,7 @@
9AFA402922AE49A200FE90BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9AFA402A22AE49A200FE90BC /* StatsLauncher.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = StatsLauncher.entitlements; sourceTree = "<group>"; };
9AFA402E22AE49AE00FE90BC /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
9AFFCB3A22B3FD0500B0E6D8 /* About.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = About.storyboard; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -91,6 +97,15 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
9A09C89C22B3A7BB0018426F /* Battery */ = {
isa = PBXGroup;
children = (
9A09C89D22B3A7C90018426F /* Battery.swift */,
9A09C89F22B3A7E20018426F /* BatteryReader.swift */,
);
path = Battery;
sourceTree = "<group>";
};
9A1410EC229E721100D29793 = {
isa = PBXGroup;
children = (
Expand All @@ -113,6 +128,7 @@
9A1410F7229E721100D29793 /* Stats */ = {
isa = PBXGroup;
children = (
9A74D59522B440D4004FE1FA /* Widgets */,
9A5B1CB3229E72A7008B9D3C /* Supporting Files */,
9A5B1CBA229E7892008B9D3C /* Modules */,
9A5B1CBD229E78D2008B9D3C /* libs */,
Expand All @@ -126,6 +142,7 @@
isa = PBXGroup;
children = (
9A6CFC0022A1C9F5001E782D /* Assets.xcassets */,
9AFFCB3A22B3FD0500B0E6D8 /* About.storyboard */,
9A1410FE229E721200D29793 /* Main.storyboard */,
9A141101229E721200D29793 /* Info.plist */,
9A141102229E721200D29793 /* Stats.entitlements */,
Expand All @@ -136,6 +153,7 @@
9A5B1CBA229E7892008B9D3C /* Modules */ = {
isa = PBXGroup;
children = (
9A09C89C22B3A7BB0018426F /* Battery */,
9A7B8F5C22A2926500DEB352 /* CPU */,
9A7B8F6222A2C17000DEB352 /* Memory */,
9A7B8F6322A2C17500DEB352 /* Disk */,
Expand All @@ -153,10 +171,19 @@
path = libs;
sourceTree = "<group>";
};
9A74D59522B440D4004FE1FA /* Widgets */ = {
isa = PBXGroup;
children = (
9A09C8A122B3D94D0018426F /* BatteryView.swift */,
9A74D59322B4315C004FE1FA /* Chart.swift */,
9A74D59622B44498004FE1FA /* Mini.swift */,
);
path = Widgets;
sourceTree = "<group>";
};
9A7B8F5C22A2926500DEB352 /* CPU */ = {
isa = PBXGroup;
children = (
9A7B8F5A22A290A200DEB352 /* CPU.xib */,
9A57A19C22A1E3270033E318 /* CPU.swift */,
9A7B8F5D22A2A57600DEB352 /* CPUReader.swift */,
);
Expand All @@ -166,7 +193,6 @@
9A7B8F6222A2C17000DEB352 /* Memory */ = {
isa = PBXGroup;
children = (
9A7B8F6422A2C19D00DEB352 /* Memory.xib */,
9A7B8F6822A2C3A100DEB352 /* Memory.swift */,
9A7B8F6C22A2C3D600DEB352 /* MemoryReader.swift */,
);
Expand All @@ -176,7 +202,6 @@
9A7B8F6322A2C17500DEB352 /* Disk */ = {
isa = PBXGroup;
children = (
9A7B8F6622A2C1B900DEB352 /* Disk.xib */,
9A7B8F6A22A2C3A700DEB352 /* Disk.swift */,
9A7B8F6E22A2C57000DEB352 /* DiskReader.swift */,
);
Expand Down Expand Up @@ -284,10 +309,8 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9A7B8F5B22A290A200DEB352 /* CPU.xib in Resources */,
9A6CFC0122A1C9F5001E782D /* Assets.xcassets in Resources */,
9A7B8F6722A2C1B900DEB352 /* Disk.xib in Resources */,
9A7B8F6522A2C19D00DEB352 /* Memory.xib in Resources */,
9AFFCB3B22B3FD0500B0E6D8 /* About.storyboard in Resources */,
9A141100229E721200D29793 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -308,16 +331,21 @@
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 */,
9A74D59422B4315C004FE1FA /* Chart.swift in Sources */,
9A09C89E22B3A7C90018426F /* Battery.swift in Sources */,
9A7B8F6D22A2C3D600DEB352 /* MemoryReader.swift in Sources */,
9A57A18522A1D26D0033E318 /* MenuBar.swift in Sources */,
9A57A19D22A1E3270033E318 /* CPU.swift in Sources */,
9A09C8A022B3A7E20018426F /* BatteryReader.swift in Sources */,
9A57A19B22A1E1C50033E318 /* Module.swift in Sources */,
9A5B1CBF229E78F0008B9D3C /* Observable.swift in Sources */,
9A7B8F6B22A2C3A700DEB352 /* Disk.swift in Sources */,
9A1410F9229E721100D29793 /* AppDelegate.swift in Sources */,
9A74D59722B44498004FE1FA /* Mini.swift in Sources */,
9A5B1CC5229E7B40008B9D3C /* Extensions.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
29 changes: 28 additions & 1 deletion Stats/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extension Notification.Name {
static let killLauncher = Notification.Name("killLauncher")
}

let modules: Observable<[Module]> = Observable([CPU(), Memory(), Disk()])
let modules: Observable<[Module]> = Observable([CPU(), Memory(), Disk(), Battery()])
let colors: Observable<Bool> = Observable(true)

@NSApplicationMain
Expand Down Expand Up @@ -54,3 +54,30 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}
}

class AboutVC: NSViewController {
@IBOutlet weak var versionLabel: NSTextField!

override func viewDidLoad() {
super.viewDidLoad()
self.view.wantsLayer = true
}

@IBAction func openLink(_ sender: Any) {
NSWorkspace.shared.open(URL(string: "https://github.com/exelban/stats")!)
}

@IBAction func exit(_ sender: Any) {
self.view.window?.close()
}

override func awakeFromNib() {
if self.view.layer != nil {
self.view.window?.backgroundColor = .white
self.view.layer?.backgroundColor = .white

let versionNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
versionLabel.stringValue = "Version \(versionNumber)"
}
}
}
55 changes: 37 additions & 18 deletions Stats/MenuBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Cocoa
import ServiceManagement

let MODULE_HEIGHT = CGFloat(NSApplication.shared.mainMenu?.menuBarHeight ?? 22)
let MODULE_WIDTH = CGFloat(28)
let MODULE_WIDTH = CGFloat(32)

class MenuBar {
let defaults = UserDefaults.standard
Expand All @@ -34,6 +34,13 @@ class MenuBar {
for module in modules.value {
module.active.subscribe(observer: self) { (value, _) in
self.buildModulesView()
self.menuBarItem.menu?.removeAllItems()
self.menuBarItem.menu = self.buildMenu()
}
module.available.subscribe(observer: self) { (value, _) in
self.buildModulesView()
self.menuBarItem.menu?.removeAllItems()
self.menuBarItem.menu = self.buildMenu()
}
}
}
Expand All @@ -42,7 +49,9 @@ class MenuBar {
let menu = NSMenu()

for module in modules.value {
menu.addItem(module.menu())
if module.available.value {
menu.addItem(module.menu)
}
}

menu.addItem(NSMenuItem.separator())
Expand All @@ -64,11 +73,21 @@ class MenuBar {
menu.addItem(preferences)

menu.addItem(NSMenuItem.separator())
let aboutMenu = NSMenuItem(title: "About Stats", action: #selector(openAbout), keyEquivalent: "")
aboutMenu.target = self
menu.addItem(aboutMenu)
menu.addItem(NSMenuItem(title: "Quit Stats", action: #selector(NSApplication.terminate(_:)), keyEquivalent: ""))

return menu
}

@objc func openAbout(_ sender : NSMenuItem) {
let aboutVC: NSWindowController? = NSStoryboard(name: "About", bundle: nil).instantiateController(withIdentifier: "AboutVC") as? NSWindowController
aboutVC?.window?.center()
aboutVC?.window?.level = .floating
aboutVC!.showWindow(self)
}

@objc func toggleMenu(_ sender : NSMenuItem) {
let launcherId = "eu.exelban.StatsLauncher"
let status = sender.state != NSControl.StateValue.on
Expand All @@ -92,32 +111,32 @@ class MenuBar {
}

self.menuBarButton.image = NSImage(named:NSImage.Name("tray_icon"))
var WIDTH = CGFloat(modules.value.count * 28)

let view: NSView = NSView(frame: NSMakeRect(0, 0, WIDTH, MODULE_HEIGHT))

let stack: NSStackView = NSStackView(frame: NSMakeRect(0, 0, WIDTH, MODULE_HEIGHT))
stack.orientation = NSUserInterfaceLayoutOrientation.horizontal
stack.distribution = NSStackView.Distribution.fillEqually
stack.spacing = 0
self.menuBarItem.length = MODULE_WIDTH
var WIDTH = CGFloat(modules.value.count) * MODULE_WIDTH

WIDTH = 0
for module in modules.value {
if module.active.value {
if module.active.value && module.available.value {
module.start()
WIDTH = WIDTH + module.view.frame.size.width
stack.addView(module.view, in: NSStackView.Gravity.center)
}
}

if stack.subviews.count != 0 {
let view: NSView = NSView(frame: NSMakeRect(0, 0, WIDTH, MODULE_HEIGHT))

var x: CGFloat = 0
for module in modules.value {
if module.active.value && module.available.value {
module.view.frame = CGRect(x: x, y: 0, width: module.view.frame.size.width, height: module.view.frame.size.height)
view.addSubview(module.view)
x = x + module.view.frame.size.width
}
}

if view.subviews.count != 0 {
view.frame.size.width = WIDTH
stack.frame.size.width = WIDTH
self.menuBarItem.length = WIDTH

view.addSubview(stack)

self.menuBarButton.image = nil
self.menuBarItem.length = WIDTH
self.menuBarButton.addSubview(view)
}
}
Expand Down
Loading

0 comments on commit e1fc6de

Please sign in to comment.