ClashX.Meta/ClashX/Views/StatusItemView.swift

125 lines
4.0 KiB
Swift
Raw Normal View History

2018-06-23 20:17:05 +08:00
//
// StatusItemView.swift
// ClashX
//
2018-08-08 13:47:38 +08:00
// Created by CYC on 2018/6/23.
// Copyright © 2018 yichengchen. All rights reserved.
2018-06-23 20:17:05 +08:00
//
import AppKit
2019-10-20 13:40:50 +08:00
import Foundation
import RxCocoa
import RxSwift
2018-06-23 20:17:05 +08:00
class StatusItemView: NSView {
@IBOutlet var imageView: NSImageView!
2019-10-20 13:40:50 +08:00
2018-06-23 21:43:33 +08:00
@IBOutlet var uploadSpeedLabel: NSTextField!
2018-06-23 20:17:05 +08:00
@IBOutlet var downloadSpeedLabel: NSTextField!
2019-10-20 13:40:50 +08:00
@IBOutlet var speedContainerView: NSView!
weak var statusItem: NSStatusItem?
2019-10-15 22:40:02 +08:00
lazy var menuImage: NSImage = {
let customImagePath = (NSHomeDirectory() as NSString).appendingPathComponent("/.config/clash/menuImage.png")
if let image = NSImage(contentsOfFile: customImagePath) {
return image
}
if let imagePath = Bundle.main.path(forResource: "menu_icon@2x", ofType: "png"),
let image = NSImage(contentsOfFile: imagePath) {
return image
}
return NSImage()
2019-10-15 22:40:02 +08:00
}()
2019-10-20 13:40:50 +08:00
static func create(statusItem: NSStatusItem?) -> StatusItemView {
var topLevelObjects: NSArray?
2018-09-27 23:07:05 +08:00
if Bundle.main.loadNibNamed("StatusItemView", owner: self, topLevelObjects: &topLevelObjects) {
2018-06-23 20:17:05 +08:00
let view = (topLevelObjects!.first(where: { $0 is NSView }) as? StatusItemView)!
view.statusItem = statusItem
view.setupView()
2018-06-23 20:17:05 +08:00
return view
}
return NSView() as! StatusItemView
}
2019-10-20 13:40:50 +08:00
func setupView() {
2019-11-21 22:39:10 +08:00
let fontSize: CGFloat = 9
let font: NSFont
if let fontName = UserDefaults.standard.string(forKey: "kStatusMenuFontName"),
let f = NSFont(name: fontName, size: fontSize) {
font = f
} else {
font = NSFont.menuBarFont(ofSize: fontSize)
}
2019-11-21 22:39:10 +08:00
uploadSpeedLabel.font = font
downloadSpeedLabel.font = font
}
2019-10-20 13:40:50 +08:00
2019-10-15 22:40:02 +08:00
func updateViewStatus(enableProxy: Bool) {
2019-10-20 13:40:50 +08:00
let selectedColor = NSColor.red
let unselectedColor: NSColor
if #available(OSX 10.14, *) {
unselectedColor = selectedColor.withSystemEffect(.disabled)
} else {
unselectedColor = selectedColor.withAlphaComponent(0.5)
}
2022-08-19 18:08:11 +08:00
uploadSpeedLabel.textColor = enableProxy ? NSColor.black : NSColor.init(white: 1.0, alpha: 0.5)
downloadSpeedLabel.textColor = enableProxy ? NSColor.black : NSColor.init(white: 1.0, alpha: 0.5)
2019-10-20 13:40:50 +08:00
imageView.image = menuImage.tint(color: enableProxy ? selectedColor : unselectedColor)
updateStatusItemView()
2019-10-15 22:40:02 +08:00
}
2021-12-05 22:21:12 +08:00
func getSpeedString(for byte: Int) -> String {
let kb = byte / 1024
if kb < 1024 {
return "\(kb)KB/s"
2018-06-23 21:43:33 +08:00
} else {
2021-12-05 22:21:12 +08:00
let mb = Double(kb) / 1024.0
if mb >= 100 {
if mb >= 1000 {
return String(format: "%.1fGB/s", mb/1024)
}
return String(format: "%.1fMB/s", mb)
} else {
return String(format: "%.2fMB/s", mb)
}
2018-06-23 21:43:33 +08:00
}
2021-12-05 22:21:12 +08:00
}
2019-10-20 13:40:50 +08:00
2021-12-05 22:21:12 +08:00
func updateSpeedLabel(up: Int, down: Int) {
guard !speedContainerView.isHidden else { return }
let finalUpStr = getSpeedString(for: up)
let finalDownStr = getSpeedString(for: down)
2019-11-21 22:39:36 +08:00
2019-11-21 22:39:10 +08:00
if downloadSpeedLabel.stringValue == finalDownStr && uploadSpeedLabel.stringValue == finalUpStr {
return
2018-06-23 21:43:33 +08:00
}
2019-11-21 22:39:10 +08:00
downloadSpeedLabel.stringValue = finalDownStr
uploadSpeedLabel.stringValue = finalUpStr
updateStatusItemView()
2018-06-23 21:43:33 +08:00
}
2019-10-20 13:40:50 +08:00
func showSpeedContainer(show: Bool) {
speedContainerView.isHidden = !show
updateStatusItemView()
}
2019-10-20 13:40:50 +08:00
func updateStatusItemView() {
statusItem?.updateImage(withView: self)
2018-06-23 20:17:05 +08:00
}
}
extension NSStatusItem {
2019-11-21 22:39:10 +08:00
func updateImage(withView view: NSView) {
if let rep = view.bitmapImageRepForCachingDisplay(in: view.bounds) {
view.cacheDisplay(in: view.bounds, to: rep)
let img = NSImage(size: view.bounds.size)
img.addRepresentation(rep)
img.isTemplate = true
image = img
}
2018-06-23 20:17:05 +08:00
}
}