// // SKProgressController.swift // PDF Reader Pro // // Created by wanjun on 2023/10/7. // import Cocoa class SKProgressController_ProgressIndicator: NSProgressIndicator { override func draw(_ dirtyRect: NSRect) { let color = NSColor(red: 206/255.0, green: 208/255.0, blue: 212/255.0, alpha: 1.0) color.setStroke() color.setFill() let lineRect = NSRect(x: 1.5, y: (self.bounds.height - 2.4) * 0.5, width: self.bounds.width - 2, height: 2.4) let linePath = NSBezierPath(roundedRect: lineRect, xRadius: 0, yRadius: 0) linePath.fill() linePath.stroke() super.draw(dirtyRect) } } class SKProgressController: NSWindowController { @IBOutlet var progressBar: NSProgressIndicator! @IBOutlet var progressField: NSTextField! var _message: String? var _indeterminate: Bool = false var _maxValue: Double = 100.0 var _doubleValue: Double = 0.0 // 是否显示关闭按钮 [默认是显示] var showClose: Bool = true var closeBlock: (() -> Void)? override var windowNibName: NSNib.Name? { return NSNib.Name("ProgressSheet") } override func awakeFromNib() { super.awakeFromNib() KMPrint("") } override func windowDidLoad() { super.windowDidLoad() // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. progressBar.usesThreadedAnimation = true // self.window?.appearance = NSAppearance(named: .aqua) let button = NSButton() self.window?.contentView?.addSubview(button) let width = self.window?.contentView?.frame.width ?? 0 let height = self.window?.contentView?.frame.height ?? 0 let size = CGSize(width: 20, height: 20) let buttonY: CGFloat = 28 let buttonX = width - size.width - 10 button.frame = NSRect(x: buttonX, y: buttonY, width: size.width, height: size.height) button.autoresizingMask = [.minXMargin, .maxYMargin] button.isBordered = false button.image = NSImage(named: "KMImageNameWhiteClose") button.target = self button.action = #selector(buttonAction(_:)) button.isHidden = !self.showClose } //MARK: Get & Set var message: String? { get { return progressField?.stringValue ?? "" } set { progressField.stringValue = newValue! self.window?.title = newValue! } } var indeterminate: Bool { get { return self.progressBar.isIndeterminate } set { self.progressBar.isIndeterminate = newValue } } var maxValue: Double { get { return self.progressBar.maxValue } set { self.progressBar.maxValue = newValue self.progressBar.doubleValue = 0.0 } } var doubleValue: Double { get { return self.progressBar.doubleValue } set { DispatchQueue.main.async { self.progressBar.doubleValue = newValue self.progressBar.displayIfNeeded() } } } func increment(by delta: Double) { self.progressBar.increment(by: delta) self.progressBar.displayIfNeeded() } //MARK: Action @objc func buttonAction(_ sender: NSButton) { // Your button action code here if let closeBlock = self.closeBlock { closeBlock() } self.dismissSheet(sender) } //didEndSheet(returnCode:contextInfo:) // func beginSheetModal(for window: NSWindow, completionHandler handler: ((NSInteger) -> Void)?) { // progressBar.startAnimation(self) // // NSApp.beginSheet(window, // modalFor: window, // modalDelegate: self, // didEnd: #selector(didEndSheet(returnCode:contextInfo:)), // contextInfo: handler != nil ? Unmanaged.passRetained(handler as AnyObject).toOpaque() : nil) // } @IBAction func dismissSheet(_ sender: Any) { self.stopAnimation() if #available(macOS 10.13, *) { NSApp.endSheet(self.window!, returnCode: (sender as AnyObject).tag) } else { NSApp.endSheet(self.window!) } self.window!.orderOut(self) } func stopAnimation() { self.progressBar.stopAnimation(self) } }