mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
87
Makefile
Normal file
87
Makefile
Normal file
@@ -0,0 +1,87 @@
|
||||
APP = Stats
|
||||
BUNDLE_ID = eu.exelban.Stats
|
||||
|
||||
ITC_USERNAME = $(AC_USERNAME)
|
||||
ITC_PASSWORD = @keychain:AC_PASSWORD
|
||||
ITC_PROVIDER = $(AC_PROVIDER)
|
||||
|
||||
RequestUUID = e6c7b954-d9fa-4c74-8927-ba2172c9526e
|
||||
|
||||
BUILD_PATH = $(PWD)/build
|
||||
ARCHIVE_PATH = $(BUILD_PATH)/$(APP).xcarchive
|
||||
APP_PATH = "$(BUILD_PATH)/$(APP).app"
|
||||
ZIP_PATH = "$(BUILD_PATH)/$(APP).zip"
|
||||
DMG_PATH = $(PWD)/$(APP).dmg
|
||||
|
||||
all: clean archive notarize sign build clean
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_PATH)
|
||||
|
||||
.PHONY: archive
|
||||
archive: clean
|
||||
xcodebuild \
|
||||
-scheme $(APP) \
|
||||
-destination 'platform=OS X,arch=x86_64' \
|
||||
-configuration AppStoreDistribution archive \
|
||||
-archivePath $(ARCHIVE_PATH)
|
||||
|
||||
xcodebuild \
|
||||
-exportArchive \
|
||||
-exportOptionsPlist "$(PWD)/exportOptions.plist" \
|
||||
-archivePath $(ARCHIVE_PATH) \
|
||||
-exportPath $(BUILD_PATH)
|
||||
|
||||
ditto -c -k --keepParent $(APP_PATH) $(ZIP_PATH)
|
||||
|
||||
.PHONY: notarize
|
||||
notarize:
|
||||
xcrun altool \
|
||||
--notarize-app \
|
||||
--primary-bundle-id $(BUNDLE_ID)\
|
||||
-itc_provider $(ITC_PROVIDER) \
|
||||
-u $(ITC_USERNAME) \
|
||||
-p $(ITC_PASSWORD) \
|
||||
--file $(ZIP_PATH)
|
||||
|
||||
sleep 380
|
||||
|
||||
.PHONY: sign
|
||||
sign:
|
||||
xcrun stapler staple $(APP_PATH)
|
||||
spctl -a -t exec -vvv $(APP_PATH)
|
||||
|
||||
.PHONY: build
|
||||
build: sign
|
||||
if [ ! -d $(PWD)/create-dmg ]; then \
|
||||
git clone https://github.com/andreyvit/create-dmg; \
|
||||
fi
|
||||
|
||||
./create-dmg/create-dmg \
|
||||
--volname $(APP) \
|
||||
--background "./resources/background.png" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 500 320 \
|
||||
--icon-size 80 \
|
||||
--icon "Stats.app" 125 175 \
|
||||
--hide-extension "Stats.app" \
|
||||
--app-drop-link 375 175 \
|
||||
$(DMG_PATH) \
|
||||
$(APP_PATH)
|
||||
|
||||
rm -rf ./create-dmg
|
||||
open $(PWD)
|
||||
|
||||
check:
|
||||
xcrun altool \
|
||||
--notarization-info $(RequestUUID) \
|
||||
-itc_provider $(ITC_PROVIDER) \
|
||||
-u $(ITC_USERNAME) \
|
||||
-p $(ITC_PASSWORD)
|
||||
|
||||
history:
|
||||
xcrun altool \
|
||||
--notarization-history 0 \
|
||||
-itc_provider $(ITC_PROVIDER) \
|
||||
-u $(ITC_USERNAME) \
|
||||
-p $(ITC_PASSWORD)
|
||||
10
README.md
10
README.md
@@ -49,6 +49,16 @@ You can download latest version [here](https://github.com/exelban/stats/releases
|
||||
|
||||
## What's new
|
||||
|
||||
### v1.2.2
|
||||
- fully automated build and sign app process
|
||||
- fixed update and about visibility window in dark mode
|
||||
- added name of the indicators in the Chart/Chart with value
|
||||
- added check for new version on start
|
||||
- removed charts and charts with value to Disk module
|
||||
- now module submenu is disabled if module is disabled
|
||||
- fixed bug when network module stop working after turn on/of
|
||||
- fixed few bugs
|
||||
|
||||
### v1.2.1
|
||||
- added charts and charts with value to Disk module
|
||||
- fixed bug when Chart with value does not shows
|
||||
|
||||
@@ -15,6 +15,9 @@ extension Notification.Name {
|
||||
|
||||
let modules: Observable<[Module]> = Observable([CPU(), Memory(), Disk(), Battery(), Network()])
|
||||
let colors: Observable<Bool> = Observable(true)
|
||||
let labelForChart: Observable<Bool> = Observable(true)
|
||||
|
||||
let updater = macAppUpdater(user: "exelban", repo: "stats")
|
||||
|
||||
@NSApplicationMain
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
@@ -27,7 +30,28 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
updater.check() { result, error in
|
||||
if error != nil && error as! String == "No internet connection" {
|
||||
return
|
||||
}
|
||||
|
||||
guard error == nil, let version: version = result else {
|
||||
print("Error: \(error ?? "check error")")
|
||||
return
|
||||
}
|
||||
|
||||
if version.newest {
|
||||
DispatchQueue.main.async(execute: {
|
||||
let updatesVC: NSWindowController? = NSStoryboard(name: "Updates", bundle: nil).instantiateController(withIdentifier: "UpdatesVC") as? NSWindowController
|
||||
updatesVC?.window?.center()
|
||||
updatesVC?.window?.level = .floating
|
||||
updatesVC!.showWindow(self)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
colors << (defaults.object(forKey: "colors") != nil ? defaults.bool(forKey: "colors") : false)
|
||||
labelForChart << (defaults.object(forKey: "labelForChart") != nil ? defaults.bool(forKey: "labelForChart") : false)
|
||||
_ = MenuBar(menuBarItem, menuBarButton: menuBarButton)
|
||||
|
||||
let launcherAppId = "eu.exelban.StatsLauncher"
|
||||
@@ -41,6 +65,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
self.defaults.set(true, forKey: "runAtLogin")
|
||||
}
|
||||
|
||||
if defaults.object(forKey: "labelForChart") == nil {
|
||||
self.defaults.set(true, forKey: "labelForChart")
|
||||
labelForChart << true
|
||||
}
|
||||
|
||||
if isRunning {
|
||||
DistributedNotificationCenter.default().post(name: .killLauncher, object: Bundle.main.bundleIdentifier!)
|
||||
}
|
||||
@@ -73,9 +102,7 @@ class AboutVC: NSViewController {
|
||||
|
||||
override func awakeFromNib() {
|
||||
if self.view.layer != nil {
|
||||
self.view.window?.backgroundColor = .white
|
||||
self.view.layer?.backgroundColor = .white
|
||||
|
||||
self.view.window?.backgroundColor = .windowBackgroundColor
|
||||
let versionNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
|
||||
versionLabel.stringValue = "Version \(versionNumber)"
|
||||
}
|
||||
@@ -92,7 +119,6 @@ class UpdatesVC: NSViewController {
|
||||
@IBOutlet weak var downloadButton: NSButton!
|
||||
@IBOutlet weak var spinner: NSProgressIndicator!
|
||||
|
||||
let updater = macAppUpdater(user: "exelban", repo: "stats")
|
||||
var url: String?
|
||||
|
||||
override func viewDidLoad() {
|
||||
@@ -133,8 +159,7 @@ class UpdatesVC: NSViewController {
|
||||
|
||||
override func awakeFromNib() {
|
||||
if self.view.layer != nil {
|
||||
self.view.window?.backgroundColor = .white
|
||||
self.view.layer?.backgroundColor = .white
|
||||
self.view.window?.backgroundColor = .windowBackgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,11 @@ class MenuBar {
|
||||
colorStatus.target = self
|
||||
preferencesMenu.addItem(colorStatus)
|
||||
|
||||
let chartLabels = NSMenuItem(title: "Label in chart", action: #selector(toggleMenu), keyEquivalent: "")
|
||||
chartLabels.state = defaults.bool(forKey: "labelForChart") || defaults.object(forKey: "labelForChart") == nil ? NSControl.StateValue.on : NSControl.StateValue.off
|
||||
chartLabels.target = self
|
||||
preferencesMenu.addItem(chartLabels)
|
||||
|
||||
let runAtLogin = NSMenuItem(title: "Run at login", action: #selector(toggleMenu), keyEquivalent: "")
|
||||
runAtLogin.state = defaults.bool(forKey: "runAtLogin") || defaults.object(forKey: "runAtLogin") == nil ? NSControl.StateValue.on : NSControl.StateValue.off
|
||||
runAtLogin.target = self
|
||||
@@ -115,6 +120,10 @@ class MenuBar {
|
||||
self.defaults.set(status, forKey: "colors")
|
||||
colors << status
|
||||
return
|
||||
case "Label in chart":
|
||||
self.defaults.set(status, forKey: "labelForChart")
|
||||
labelForChart << status
|
||||
return
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,15 @@ class CPU: Module {
|
||||
self.widgetType = defaults.object(forKey: "\(name)_widget") != nil ? defaults.float(forKey: "\(name)_widget") : Widgets.Mini
|
||||
initMenu()
|
||||
initWidget()
|
||||
|
||||
labelForChart.subscribe(observer: self) { (value, _) in
|
||||
guard let chartView: Chart = self.view as? Chart else {
|
||||
return
|
||||
}
|
||||
self.active << false
|
||||
chartView.toggleLabel(value: value)
|
||||
self.active << true
|
||||
}
|
||||
}
|
||||
|
||||
func initMenu() {
|
||||
|
||||
@@ -29,37 +29,21 @@ class Disk: Module {
|
||||
self.widgetType = defaults.object(forKey: "\(name)_widget") != nil ? defaults.float(forKey: "\(name)_widget") : Widgets.Mini
|
||||
|
||||
self.initMenu()
|
||||
initWidget()
|
||||
|
||||
let widget = Mini(frame: NSMakeRect(0, 0, MODULE_WIDTH, MODULE_HEIGHT))
|
||||
widget.label = self.shortName
|
||||
self.view = widget
|
||||
}
|
||||
|
||||
func initMenu() {
|
||||
menu = NSMenuItem(title: name, action: #selector(toggle), keyEquivalent: "")
|
||||
submenu = NSMenu()
|
||||
|
||||
if defaults.object(forKey: name) != nil {
|
||||
menu.state = defaults.bool(forKey: name) ? NSControl.StateValue.on : NSControl.StateValue.off
|
||||
} else {
|
||||
menu.state = NSControl.StateValue.on
|
||||
}
|
||||
menu.target = self
|
||||
|
||||
let mini = NSMenuItem(title: "Mini", action: #selector(toggleWidget), keyEquivalent: "")
|
||||
mini.state = self.widgetType == Widgets.Mini ? NSControl.StateValue.on : NSControl.StateValue.off
|
||||
mini.target = self
|
||||
|
||||
let chart = NSMenuItem(title: "Chart", action: #selector(toggleWidget), keyEquivalent: "")
|
||||
chart.state = self.widgetType == Widgets.Chart ? NSControl.StateValue.on : NSControl.StateValue.off
|
||||
chart.target = self
|
||||
|
||||
let chartWithValue = NSMenuItem(title: "Chart with value", action: #selector(toggleWidget), keyEquivalent: "")
|
||||
chartWithValue.state = self.widgetType == Widgets.ChartWithValue ? NSControl.StateValue.on : NSControl.StateValue.off
|
||||
chartWithValue.target = self
|
||||
|
||||
submenu.addItem(mini)
|
||||
submenu.addItem(chart)
|
||||
submenu.addItem(chartWithValue)
|
||||
|
||||
menu.submenu = submenu
|
||||
menu.isEnabled = true
|
||||
}
|
||||
|
||||
@objc func toggle(_ sender: NSMenuItem) {
|
||||
@@ -75,36 +59,4 @@ class Disk: Module {
|
||||
self.start()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func toggleWidget(_ sender: NSMenuItem) {
|
||||
var widgetCode: Float = 0.0
|
||||
|
||||
switch sender.title {
|
||||
case "Mini":
|
||||
widgetCode = Widgets.Mini
|
||||
case "Chart":
|
||||
widgetCode = Widgets.Chart
|
||||
case "Chart with value":
|
||||
widgetCode = Widgets.ChartWithValue
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if self.widgetType == widgetCode {
|
||||
return
|
||||
}
|
||||
|
||||
for item in self.submenu.items {
|
||||
if item.title == "Mini" || item.title == "Chart" || item.title == "Chart with value" {
|
||||
item.state = NSControl.StateValue.off
|
||||
}
|
||||
}
|
||||
|
||||
sender.state = sender.state == NSControl.StateValue.on ? NSControl.StateValue.off : NSControl.StateValue.on
|
||||
self.defaults.set(widgetCode, forKey: "\(name)_widget")
|
||||
self.widgetType = widgetCode
|
||||
self.active << false
|
||||
initWidget()
|
||||
self.active << true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,15 @@ class Memory: Module {
|
||||
self.widgetType = defaults.object(forKey: "\(name)_widget") != nil ? defaults.float(forKey: "\(name)_widget") : Widgets.Mini
|
||||
initMenu()
|
||||
initWidget()
|
||||
|
||||
labelForChart.subscribe(observer: self) { (value, _) in
|
||||
guard let chartView: Chart = self.view as? Chart else {
|
||||
return
|
||||
}
|
||||
self.active << false
|
||||
chartView.toggleLabel(value: value)
|
||||
self.active << true
|
||||
}
|
||||
}
|
||||
|
||||
func initMenu() {
|
||||
@@ -69,8 +78,10 @@ class Memory: Module {
|
||||
self.active << state
|
||||
|
||||
if !state {
|
||||
menu.submenu = nil
|
||||
self.stop()
|
||||
} else {
|
||||
menu.submenu = submenu
|
||||
self.start()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,8 +87,10 @@ class Network: Module {
|
||||
self.active << state
|
||||
|
||||
if !state {
|
||||
menu.submenu = nil
|
||||
self.stop()
|
||||
} else {
|
||||
menu.submenu = submenu
|
||||
self.start()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,33 +33,37 @@ class NetworkReader: Reader {
|
||||
defer {
|
||||
self.pipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
|
||||
}
|
||||
|
||||
|
||||
let output = self.pipe.fileHandleForReading.availableData
|
||||
if output.isEmpty {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let outputString = String(data: output, encoding: String.Encoding.utf8) ?? ""
|
||||
let arr = outputString.condenseWhitespace().split(separator: " ")
|
||||
|
||||
|
||||
if !arr.isEmpty && Int64(arr[0]) != nil {
|
||||
guard let download = Int64(arr[2]), let upload = Int64(arr[5]) else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
guard let value: Double = Double("\(download).\(upload)") else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
self.usage << value
|
||||
}
|
||||
}
|
||||
|
||||
netProcess.launch()
|
||||
do {
|
||||
try netProcess.run()
|
||||
} catch let error {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
func stop() {
|
||||
netProcess.interrupt()
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.NSFileHandleDataAvailable, object: nil)
|
||||
}
|
||||
|
||||
func read() {}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="QiE-cC-2Ak">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="QiE-cC-2Ak">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
@@ -85,7 +85,7 @@
|
||||
</customSpacing>
|
||||
</stackView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="hXC-tE-nSc">
|
||||
<rect key="frame" x="-2" y="41" width="256" height="34"/>
|
||||
<rect key="frame" x="-2" y="41" width="234" height="34"/>
|
||||
<textFieldCell key="cell" title="Simple macOS system monitor in your menu bar" id="w6j-75-PxU">
|
||||
<font key="font" metaFont="systemLight" size="13"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.2.1</string>
|
||||
<string>1.2.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<string>7</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
import Cocoa
|
||||
|
||||
class Chart: NSView, Widget {
|
||||
var labelPadding: CGFloat = 10.0
|
||||
var labelEnabled: Bool = false
|
||||
var label: String = ""
|
||||
|
||||
var height: CGFloat = 0.0
|
||||
var points: [Double] {
|
||||
didSet {
|
||||
@@ -21,6 +25,11 @@ class Chart: NSView, Widget {
|
||||
super.init(frame: frame)
|
||||
self.wantsLayer = true
|
||||
self.addSubview(NSView())
|
||||
self.labelEnabled = labelForChart.value
|
||||
|
||||
if self.labelEnabled {
|
||||
self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.frame.size.width + labelPadding, height: self.frame.size.height)
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder decoder: NSCoder) {
|
||||
@@ -34,12 +43,19 @@ class Chart: NSView, Widget {
|
||||
let gradientColor: NSColor = NSColor(red: (26/255.0), green: (126/255.0), blue: (252/255.0), alpha: 0.5)
|
||||
|
||||
let context = NSGraphicsContext.current!.cgContext
|
||||
let xOffset: CGFloat = 4.0
|
||||
var xOffset: CGFloat = 4.0
|
||||
if labelEnabled {
|
||||
xOffset = xOffset + labelPadding
|
||||
}
|
||||
let yOffset: CGFloat = 3.0
|
||||
if height == 0 {
|
||||
height = self.frame.size.height - CGFloat((yOffset * 2))
|
||||
}
|
||||
let xRatio = Double(self.frame.size.width - (xOffset * 2)) / (Double(self.points.count) - 1)
|
||||
|
||||
var xRatio = Double(self.frame.size.width - (xOffset * 2)) / (Double(self.points.count) - 1)
|
||||
if labelEnabled {
|
||||
xRatio = Double(self.frame.size.width - (xOffset * 2) + labelPadding) / (Double(self.points.count) - 1)
|
||||
}
|
||||
|
||||
let columnXPoint = { (point: Int) -> CGFloat in
|
||||
return CGFloat((Double(point) * xRatio)) + xOffset
|
||||
@@ -76,6 +92,30 @@ class Chart: NSView, Widget {
|
||||
|
||||
graphPath.lineWidth = 0.5
|
||||
graphPath.stroke()
|
||||
|
||||
if !self.labelEnabled {
|
||||
return
|
||||
}
|
||||
|
||||
let style = NSMutableParagraphStyle()
|
||||
style.alignment = .center
|
||||
let stringAttributes = [
|
||||
NSAttributedString.Key.font: NSFont.systemFont(ofSize: 7.2, weight: .bold),
|
||||
NSAttributedString.Key.foregroundColor: NSColor.labelColor,
|
||||
NSAttributedString.Key.paragraphStyle: style
|
||||
]
|
||||
|
||||
let letterHeight = (self.frame.size.height - (MODULE_MARGIN*2)) / 3
|
||||
let letterWidth: CGFloat = 10.0
|
||||
|
||||
var yMargin = MODULE_MARGIN
|
||||
for char in self.label.reversed() {
|
||||
let rect = CGRect(x: MODULE_MARGIN, y: yMargin, width: letterWidth, height: letterHeight)
|
||||
let str = NSAttributedString.init(string: "\(char)", attributes: stringAttributes)
|
||||
str.draw(with: rect)
|
||||
|
||||
yMargin += letterHeight
|
||||
}
|
||||
}
|
||||
|
||||
func redraw() {
|
||||
@@ -97,6 +137,15 @@ class Chart: NSView, Widget {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func toggleLabel(value: Bool) {
|
||||
labelEnabled = value
|
||||
if value {
|
||||
self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.frame.size.width + labelPadding, height: self.frame.size.height)
|
||||
} else {
|
||||
self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.frame.size.width - labelPadding, height: self.frame.size.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChartWithValue: Chart {
|
||||
@@ -104,10 +153,12 @@ class ChartWithValue: Chart {
|
||||
|
||||
override init(frame: NSRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.wantsLayer = true
|
||||
|
||||
valueLabel = NSTextField(frame: NSMakeRect(2, MODULE_HEIGHT - 11, self.frame.size.width, 10))
|
||||
if labelEnabled {
|
||||
valueLabel = NSTextField(frame: NSMakeRect(labelPadding + 2, MODULE_HEIGHT - 11, self.frame.size.width, 10))
|
||||
}
|
||||
valueLabel.textColor = NSColor.red
|
||||
valueLabel.isEditable = false
|
||||
valueLabel.isSelectable = false
|
||||
@@ -146,4 +197,15 @@ class ChartWithValue: Chart {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func toggleLabel(value: Bool) {
|
||||
labelEnabled = value
|
||||
if value {
|
||||
valueLabel.frame = NSMakeRect(labelPadding + 2, MODULE_HEIGHT - 11, self.frame.size.width, 10)
|
||||
self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.frame.size.width + labelPadding, height: self.frame.size.height)
|
||||
} else {
|
||||
valueLabel.frame = NSMakeRect(2, MODULE_HEIGHT - 11, self.frame.size.width, 10)
|
||||
self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.frame.size.width - labelPadding, height: self.frame.size.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,16 +141,3 @@ extension NSBezierPath {
|
||||
self.line(to: arrowLine2)
|
||||
}
|
||||
}
|
||||
|
||||
//extension NSView {
|
||||
// var backgroundColor: NSColor? {
|
||||
// get {
|
||||
// guard let color = layer?.backgroundColor else { return nil }
|
||||
// return NSColor(cgColor: color)
|
||||
// }
|
||||
// set {
|
||||
// wantsLayer = true
|
||||
// layer?.backgroundColor = newValue?.cgColor
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -13,6 +13,7 @@ protocol Module: class {
|
||||
var shortName: String { get }
|
||||
var view: NSView { get set }
|
||||
var menu: NSMenuItem { get }
|
||||
var submenu: NSMenu { get }
|
||||
var active: Observable<Bool> { get }
|
||||
var available: Observable<Bool> { get }
|
||||
var reader: Reader { get }
|
||||
@@ -31,10 +32,14 @@ extension Module {
|
||||
self.view = widget
|
||||
break
|
||||
case Widgets.Chart:
|
||||
self.view = Chart(frame: NSMakeRect(0, 0, MODULE_WIDTH + 7, MODULE_HEIGHT))
|
||||
let widget = Chart(frame: NSMakeRect(0, 0, MODULE_WIDTH + 7, MODULE_HEIGHT))
|
||||
widget.label = self.shortName
|
||||
self.view = widget
|
||||
break
|
||||
case Widgets.ChartWithValue:
|
||||
self.view = ChartWithValue(frame: NSMakeRect(0, 0, MODULE_WIDTH + 7, MODULE_HEIGHT))
|
||||
let widget = ChartWithValue(frame: NSMakeRect(0, 0, MODULE_WIDTH + 7, MODULE_HEIGHT))
|
||||
widget.label = self.shortName
|
||||
self.view = widget
|
||||
break
|
||||
case Widgets.Dots:
|
||||
self.view = NetworkDotsView(frame: NSMakeRect(0, 0, MODULE_WIDTH, MODULE_HEIGHT))
|
||||
|
||||
25
build.sh
25
build.sh
@@ -1,25 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ ! -d "./create-dmg" ]; then
|
||||
git clone https://github.com/andreyvit/create-dmg
|
||||
fi
|
||||
|
||||
# xcodebuild -configuration Distribution clean build
|
||||
|
||||
# cp -rf $PWD/build/Release/Stats.app ./
|
||||
# rm -rf echo $PWD/build
|
||||
|
||||
./create-dmg/create-dmg \
|
||||
--volname "Stats" \
|
||||
--background "./resources/background.png" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 500 320 \
|
||||
--icon-size 80 \
|
||||
--icon "Stats.app" 125 175 \
|
||||
--hide-extension "Stats.app" \
|
||||
--app-drop-link 375 175 \
|
||||
"Stats.dmg" \
|
||||
"Stats.app"
|
||||
|
||||
rm -rf ./create-dmg
|
||||
rm -rf Stats.app
|
||||
10
exportOptions.plist
Normal file
10
exportOptions.plist
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>method</key>
|
||||
<string>developer-id</string>
|
||||
<key>signingStyle</key>
|
||||
<string>automatic</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Reference in New Issue
Block a user