123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- //
- // KMScreenShotMaskWindowController.swift
- // PDF Reader Pro
- //
- // Created by liujiajie on 2024/1/24.
- //
- import Cocoa
- let ktimeLabelWidthAndHeight: CGFloat = 100
- let kdefauletDelaytime: CGFloat = 5
- class KMScreenShotMaskWindowController: NSWindowController{
- var maskViewController: KMScreenShotMaskViewController!
- @IBOutlet var timeLabel: NSTextField!
- var fullScreenCallBack: captureScreenCallBack?
- var countDownTimer: Timer?
-
- var countDownSurplusTime: Int = 0
- var localMonitor: Any?
- var globalMonitor: Any?
-
- deinit {
- NotificationCenter.default.removeObserver(self)
- if (countDownTimer != nil){
- countDownTimer?.invalidate()
- countDownTimer = nil
- }
- }
- convenience init( handler: @escaping captureScreenCallBack) {
- self.init(windowNibName: "KMScreenShotMaskWindowController")
- self.window?.backgroundColor = .clear
- self.window?.isOpaque = false
- let screen = NSScreen.screens.first
- self.window?.setFrame(screen?.frame ?? .zero, display: false)
- self.window?.level = NSWindow.Level(Int(kCGOverlayWindowLevel)) //NSWindow.Level(rawValue: Int(kCGOverlayWindowLevel))
- self.maskViewController = KMScreenShotMaskViewController(callB: handler)
- self.maskViewController.view.frame = self.window?.frame ?? .zero
- self.window?.contentView!.addSubview(self.maskViewController.view)
- self.timeLabel.isHidden = true
- }
-
- convenience init(fullScreenShot delayTime: Int, completeHandler: @escaping captureScreenCallBack) {
- self.init(windowNibName: "KMScreenShotMaskWindowController")
- self.countDownSurplusTime = delayTime
- self.window?.backgroundColor = NSColor.black
- if let screen = NSScreen.screens.first {
- self.window?.setFrame(NSRect(x: screen.frame.size.width/2 - ktimeLabelWidthAndHeight/2, y: screen.frame.size.height/2 - ktimeLabelWidthAndHeight/2, width: ktimeLabelWidthAndHeight, height: ktimeLabelWidthAndHeight), display: false)
- }
- self.window?.level = NSWindow.Level(Int(kCGOverlayWindowLevel))
- self.timeLabel.font = NSFont.systemFont(ofSize: 100)
- self.timeLabel.textColor = NSColor.white
- self.window?.alphaValue = 0.3
- self.timeLabel.integerValue = self.countDownSurplusTime
- self.timeLabel.sizeToFit()
- self.timeLabel.frame = NSRect(x: (ktimeLabelWidthAndHeight - self.timeLabel.frame.size.width)/2, y: (ktimeLabelWidthAndHeight - self.timeLabel.frame.size.height)/2, width: self.timeLabel.frame.size.width, height: self.timeLabel.frame.size.height)
- if delayTime == 0 {
- self.window?.setIsVisible(false)
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
- let ima = KMScreenShotHandler.fullScreenShot()
- completeHandler(ima)
- }
- } else {
- self.timeLabel.isHidden = false
- let sel = NSSelectorFromString("countTimer_Method:")
- self.countDownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: sel, userInfo: nil, repeats: true)
-
- RunLoop.current.add(self.countDownTimer!, forMode: .common)
- self.fullScreenCallBack = completeHandler
- if self.localMonitor == nil {
- let mask: NSEvent.EventTypeMask = [.leftMouseDown, .keyDown]
- self.localMonitor = NSEvent.addLocalMonitorForEvents(matching: mask, handler: { (event) -> NSEvent? in
- if event.type == .keyDown {
- if event.keyCode == 53 {
- self.endFullScreenShot()
- self.fullScreenCallBack?(nil)
- }
- }
- return nil
- })
- }
- if self.globalMonitor == nil {
- self.globalMonitor = NSEvent.addGlobalMonitorForEvents(matching: .keyDown, handler: { (event) in
- if event.type == .keyDown {
- if event.keyCode == 53 {
- self.endFullScreenShot()
- self.fullScreenCallBack?(nil)
- }
- }
- })
- }
- }
- NotificationCenter.default.addObserver(self, selector: #selector(cancelCurrentCapturingAction(notification:)), name: NSNotification.Name(KMCancelCurrentCapturingActionNotification), object: nil)
- }
- @objc func cancelCurrentCapturingAction(notification: Notification) {
- DispatchQueue.main.async {
- self.endFullScreenShot()
- }
- }
- func endFullScreenShot() {
- self.countDownTimer?.invalidate()
- self.window?.setIsVisible(false)
- NSEvent.removeMonitor(self.localMonitor as Any)
- self.localMonitor = nil
- NSEvent.removeMonitor(self.globalMonitor as Any)
- self.globalMonitor = nil
- }
- @objc func countTimer_Method(_ sender: Any) {
- self.countDownSurplusTime -= 1
- self.timeLabel.integerValue = self.countDownSurplusTime
- if self.countDownSurplusTime == 0 {
- self.endFullScreenShot()
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
- let ima = KMScreenShotHandler.fullScreenShot()
- self.fullScreenCallBack?(ima)
- }
- }
- }
- override func windowDidLoad() {
- super.windowDidLoad()
- }
-
- func beginImageCapture(_ isCaptureWindow: Bool) { self.maskViewController.beginImageCapture(isCaptureWindow)
- if isCaptureWindow {
- let cursor = NSCursor(image: NSImage(named: "cameraCursor") ?? NSImage(), hotSpot: NSPoint(x: 0, y: 0))
- cursor.set()
- self.showScreenShotHint(NSLocalizedString("Move the camera over the window you want to capture.", comment: ""))
- } else {
- NSCursor.crosshair.set()
- self.showScreenShotHint(NSLocalizedString("Drag the crosshair over the area you want to capture.", comment: ""))
- }
- }
-
- func showScreenShotHint(_ hintMsg: String) {
- let topBottomGap: CGFloat = 10
- let texfield = NSTextField()
- texfield.isBordered = false
- texfield.font = NSFont.systemFont(ofSize: 20)
- texfield.textColor = NSColor.white
- texfield.backgroundColor = NSColor.clear
- texfield.stringValue = hintMsg
- texfield.sizeToFit()
- let hintContainer = NSView()
- hintContainer.wantsLayer = true
- hintContainer.layer?.backgroundColor = NSColor.black.cgColor
- hintContainer.addSubview(texfield)
-
- var containerFrame = hintContainer.frame
- containerFrame.size.height = texfield.frame.size.height + topBottomGap * 2
- containerFrame.size.width = texfield.frame.size.width + containerFrame.size.height
- containerFrame.origin.x = ((self.window?.contentView?.frame.size.width ?? 0) - containerFrame.size.width) / 2
- containerFrame.origin.y = ((self.window?.contentView?.frame.size.height ?? 0) - containerFrame.size.height) / 2
- hintContainer.frame = containerFrame
-
- var textfieldFrame = texfield.frame
- textfieldFrame.origin.x = (containerFrame.size.width - texfield.frame.size.width) / 2
- textfieldFrame.origin.y = topBottomGap
- texfield.frame = textfieldFrame
-
- hintContainer.layer?.cornerRadius = containerFrame.size.height / 2
- self.window?.contentView?.addSubview(hintContainer)
-
- NSAnimationContext.runAnimationGroup({ (context) in
- context.duration = 3
- hintContainer.animator().alphaValue = 0.0
- }, completionHandler: {
-
- })
- }
- }
|