123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647 |
- //
- // KMScreenShotMaskView.swift
- // PDF Reader Pro
- //
- // Created by liujiajie on 2024/1/24.
- //
- import Foundation
- typealias captureScreenCallBack = (_ ima: NSImage?) -> ()
- typealias updateFrameCallBack = (_ rect: NSRect) -> ()
- typealias detachEventInEditViewCallBack = (_ event: NSEvent) -> ()
- @objc enum KMScreenShotRectEditViewPositionType: Int {
- case None = 0
- case Top
- case Left
- case Bottom
- case Right
- case LeftUp
- case LeftLower
- case RightUp
- case RightLower
- }
- let KMScreenLineLength: CGFloat = 4//线长
- let KMScreenSpaceLength: CGFloat = 1//空格长
- let KMScreenLineWidth: CGFloat = 2//线宽
- let KMScreenSizeLableFont: CGFloat = 12//尺寸字体大小
- let KMScreenDetectLength: CGFloat = 4//选取rect之后边界线探测区域
- let KMScreenHoleMinWidthAndHeight: CGFloat = 40
- class KMScreenShotMaskView: NSView{
- var callBack: captureScreenCallBack?
- var frameCallBack: updateFrameCallBack?
- var detachCallBack: detachEventInEditViewCallBack?
- var holeDragMode = false
- var borderFrame: NSRect = .zero
- var iswindowCapture = false
-
- var topView: NSView!
- var leftView: NSView!
- var bottomView: NSView!
- var rightView: NSView!
- var windowMaskView: NSView!
- var sizeLabel: NSTextField!
-
- var localMonitor: Any?
- var globalMonitor: Any?
- var dragStartPoint: CGPoint = .zero
- var dragLastPoint: CGPoint = .zero
- var editingRect = false
- var positionType: KMScreenShotRectEditViewPositionType = .None
- var needborderFlag = false
- var pullXGap: Float = 0
- var pullYGap: Float = 0
-
- override func awakeFromNib() {
- super.awakeFromNib()
- topView = NSView(frame: CGRect.zero)
- leftView = NSView(frame: CGRect.zero)
- bottomView = NSView(frame: CGRect.zero)
- rightView = NSView(frame: CGRect.zero)
- windowMaskView = NSView(frame: CGRect.zero)
- sizeLabel = NSTextField(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
- sizeLabel.font = NSFont.systemFont(ofSize: CGFloat(KMScreenSizeLableFont))
- sizeLabel.textColor = NSColor.black
- sizeLabel.backgroundColor = NSColor.clear
- sizeLabel.isEnabled = false
- sizeLabel.isSelectable = false
- sizeLabel.isBordered = false
- sizeLabel.alignment = .right
-
- addSubview(topView)
- addSubview(leftView)
- addSubview(bottomView)
- addSubview(rightView)
- addSubview(sizeLabel)
- addSubview(windowMaskView)
-
- topView.wantsLayer = true
- leftView.wantsLayer = true
- bottomView.wantsLayer = true
- rightView.wantsLayer = true
- windowMaskView.wantsLayer = true
-
- topView.layer?.backgroundColor = NSColor.black.cgColor
- leftView.layer?.backgroundColor = NSColor.black.cgColor
- bottomView.layer?.backgroundColor = NSColor.black.cgColor
- rightView.layer?.backgroundColor = NSColor.black.cgColor
- windowMaskView.layer?.backgroundColor = NSColor.clear.cgColor
-
- topView.alphaValue = 0.3
- leftView.alphaValue = 0.3
- bottomView.alphaValue = 0.3
- rightView.alphaValue = 0.3
-
- needborderFlag = true
- }
-
- override func draw(_ dirtyRect: NSRect) {
- super.draw(dirtyRect)
- if !needborderFlag {
- return
- }
- if !editingRect {
- return
- }
-
- guard let myContext = NSGraphicsContext.current?.cgContext else {
- return
- }
-
- if iswindowCapture {
- return
- }
-
- myContext.setFillColor(NSColor.red.cgColor)
-
- myContext.addArc(center: CGPoint(x: borderFrame.minX, y: borderFrame.minY),
- radius: CGFloat(KMScreenDetectLength),
- startAngle: CGFloat(0),
- endAngle: CGFloat(Double.pi * 2),
- clockwise: true)
- myContext.drawPath(using: .fill)
-
- myContext.addArc(center: CGPoint(x: borderFrame.midX, y: borderFrame.minY),
- radius: CGFloat(KMScreenDetectLength),
- startAngle: CGFloat(0),
- endAngle: CGFloat(Double.pi * 2),
- clockwise: true)
- myContext.drawPath(using: .fill)
-
- myContext.addArc(center: CGPoint(x: borderFrame.maxX, y: borderFrame.minY),
- radius: CGFloat(KMScreenDetectLength),
- startAngle: CGFloat(0),
- endAngle: CGFloat(Double.pi * 2),
- clockwise: true)
- myContext.drawPath(using: .fill)
-
- myContext.addArc(center: CGPoint(x: borderFrame.maxX, y: borderFrame.midY),
- radius: CGFloat(KMScreenDetectLength),
- startAngle: CGFloat(0),
- endAngle: CGFloat(Double.pi * 2),
- clockwise: true)
- myContext.drawPath(using: .fill)
-
- myContext.addArc(center: CGPoint(x: borderFrame.maxX, y: borderFrame.maxY),
- radius: CGFloat(KMScreenDetectLength),
- startAngle: CGFloat(0),
- endAngle: CGFloat(Double.pi * 2),
- clockwise: true)
- myContext.drawPath(using: .fill)
-
- myContext.addArc(center: CGPoint(x: borderFrame.midX, y: borderFrame.maxY),
- radius: CGFloat(KMScreenDetectLength),
- startAngle: CGFloat(0),
- endAngle: CGFloat(Double.pi * 2),
- clockwise: true)
- myContext.drawPath(using: .fill)
-
- myContext.addArc(center: CGPoint(x: borderFrame.minX, y: borderFrame.maxY),
- radius: CGFloat(KMScreenDetectLength),
- startAngle: CGFloat(0),
- endAngle: CGFloat(Double.pi * 2),
- clockwise: true)
- myContext.drawPath(using: .fill)
-
- myContext.addArc(center: CGPoint(x: borderFrame.minX, y: borderFrame.midY),
- radius: CGFloat(KMScreenDetectLength),
- startAngle: CGFloat(0),
- endAngle: CGFloat(Double.pi * 2),
- clockwise: true)
- myContext.drawPath(using: .fill)
- }
- func updateSubViewFrame(withHoleRect holeRect: NSRect) {
- let topViewOriginalX: CGFloat = 0
- let topViewOriginalY: CGFloat = min(holeRect.maxY, frame.maxY)
- let topViewWidth = frame.size.width
- let topViewHeight = holeRect.maxY > frame.maxY ? 0 : frame.maxY - holeRect.maxY
- topView.frame = CGRect(x: topViewOriginalX, y: topViewOriginalY, width: topViewWidth, height: topViewHeight)
- let originalY = holeRect.origin.y
- var leftRightHeight: CGFloat
- if originalY > 0 {
- leftRightHeight = holeRect.size.height
- } else {
- leftRightHeight = holeRect.size.height - abs(holeRect.origin.y)
- }
- let leftViewOriginalX: CGFloat = 0
- let leftViewOriginalY: CGFloat = max(holeRect.minY, 0)
- let leftViewWidth = max(0, holeRect.minX)
- let leftViewHeight = leftRightHeight
- leftView.frame = CGRect(x: leftViewOriginalX, y: leftViewOriginalY, width: leftViewWidth, height: leftViewHeight)
-
- let bottomViewOriginalX: CGFloat = 0
- let bottomViewOriginalY: CGFloat = 0
- let bottomViewWidth = frame.size.width
- let bottomViewHeight = max(holeRect.minY, 0)
- bottomView.frame = CGRect(x: bottomViewOriginalX, y: bottomViewOriginalY, width: bottomViewWidth, height: bottomViewHeight)
-
- let rightViewOriginalX = min(holeRect.maxX, frame.maxX)
- let rightViewOriginalY = max(holeRect.minY, 0)
- let rightViewWidth = holeRect.maxX > frame.maxX ? 0 : frame.maxX - holeRect.maxX
- let rightViewHeight = leftRightHeight
- rightView.frame = CGRect(x: rightViewOriginalX, y: rightViewOriginalY, width: rightViewWidth, height: rightViewHeight)
- }
- func windowForEvent(_ event: NSEvent) -> CGWindowID {
- return CGWindowID(NSWindow.windowNumber(at: KMScreenShotHandler.screenPosition(for: event), belowWindowWithWindowNumber: self.window!.windowNumber))
- }
- func beginEditSelectArea(_ editFrame: NSRect) {
- self.editingRect = true
- }
-
- func changeCursorTypeWithEvent(_ result: NSEvent) {
- let point = KMScreenShotHandler.screenPosition(for: result)
- self.positionType = self.calulateCurrentPositionType(point)
- switch self.positionType {
- case .None:
- NSCursor.arrow.set()
- case .Top:
- NSCursor.resizeUpDown.set()
- case .Left:
- NSCursor.resizeLeftRight.set()
- case .Bottom:
- NSCursor.resizeUpDown.set()
- case .Right:
- NSCursor.resizeLeftRight.set()
- case .LeftUp:
- NSCursor.crosshair.set()
- case .LeftLower:
- NSCursor.crosshair.set()
- case .RightUp:
- NSCursor.crosshair.set()
- case .RightLower:
- NSCursor.crosshair.set()
- default:
- break
- }
- }
- func calulateCurrentPositionType(_ point: NSPoint) -> KMScreenShotRectEditViewPositionType {
- var type: KMScreenShotRectEditViewPositionType = .None
- let topYMin = NSMaxY(self.borderFrame) - CGFloat(KMScreenDetectLength)
- let topYMax = NSMaxY(self.borderFrame) + CGFloat(KMScreenDetectLength)
- let leftXMin = NSMinX(self.borderFrame) - CGFloat(KMScreenDetectLength)
- let leftXMax = NSMinX(self.borderFrame) + CGFloat(KMScreenDetectLength)
-
- let bottomYMin = NSMinY(self.borderFrame) - CGFloat(KMScreenDetectLength)
- let bottomYMax = NSMinY(self.borderFrame) + CGFloat(KMScreenDetectLength)
-
- let rightXMin = NSMaxX(self.borderFrame) - CGFloat(KMScreenDetectLength)
- let rightXMax = NSMaxX(self.borderFrame) + CGFloat(KMScreenDetectLength)
-
- if point.x <= leftXMax && point.x >= leftXMin {
- if point.y <= topYMax && point.y >= topYMin {
- type = .LeftUp
- } else if point.y <= bottomYMax && point.y >= bottomYMin {
- type = .LeftLower
- } else if point.y < topYMin && point.y > bottomYMax {
- type = .Left
- }
- } else if point.x <= rightXMax && point.x >= rightXMin {
- if point.y <= topYMax && point.y >= topYMin {
- type = .RightUp
- } else if point.y <= bottomYMax && point.y >= bottomYMin {
- type = .RightLower
- } else if point.y > bottomYMax && point.y < topYMin {
- type = .Right
- }
- } else if point.x > leftXMax && point.x < rightXMin {
- if point.y > bottomYMin && point.y < bottomYMax {
- type = .Bottom
- } else if point.y > topYMin && point.y < topYMax {
- type = .Top
- } else {
- type = .None
- }
- } else {
- type = .None
- }
- return type
- }
- func rectEditDrag(event: NSEvent) {
- let newPoint = KMScreenShotHandler.screenPosition(for: event)
- switch self.positionType {
- case .None:
- break
- case .Top:
- let changeTop = newPoint.y - self.borderFrame.maxY
- self.borderFrame = CGRect(x: self.borderFrame.origin.x, y: self.borderFrame.origin.y, width: self.borderFrame.size.width, height: CGFloat(self.borderFrame.size.height + CGFloat(changeTop) > CGFloat(KMScreenHoleMinWidthAndHeight) ? self.borderFrame.size.height + CGFloat(changeTop) : CGFloat(KMScreenHoleMinWidthAndHeight)))
- case .Left:
- let changeLeft = newPoint.x - self.borderFrame.minX
- self.borderFrame = CGRect(x: self.borderFrame.origin.x + changeLeft < self.borderFrame.maxX - CGFloat(KMScreenHoleMinWidthAndHeight) ? self.borderFrame.origin.x + changeLeft : self.borderFrame.maxX - CGFloat(KMScreenHoleMinWidthAndHeight), y: self.borderFrame.origin.y, width: self.borderFrame.size.width - changeLeft > CGFloat(KMScreenHoleMinWidthAndHeight) ? self.borderFrame.size.width - changeLeft : KMScreenHoleMinWidthAndHeight, height: self.borderFrame.size.height)
- case .Bottom:
- let changeBottom = newPoint.y - self.borderFrame.minY
- self.borderFrame = CGRect(x: self.borderFrame.origin.x, y: self.borderFrame.origin.y + changeBottom <= self.borderFrame.maxY - KMScreenHoleMinWidthAndHeight ? self.borderFrame.origin.y + changeBottom : self.borderFrame.maxY - KMScreenHoleMinWidthAndHeight, width: self.borderFrame.size.width, height: self.borderFrame.size.height - changeBottom > KMScreenHoleMinWidthAndHeight ? self.borderFrame.size.height - changeBottom : KMScreenHoleMinWidthAndHeight)
- case .Right:
- let changeRight = newPoint.x - self.borderFrame.maxX
- self.borderFrame = CGRect(x: self.borderFrame.origin.x, y: self.borderFrame.origin.y, width: self.borderFrame.size.width + changeRight > KMScreenHoleMinWidthAndHeight ? self.borderFrame.size.width + changeRight : KMScreenHoleMinWidthAndHeight, height: self.borderFrame.size.height)
- case .LeftUp:
- let changeX = newPoint.x - self.borderFrame.minX
- let changeY = newPoint.y - self.borderFrame.maxY
- self.borderFrame = CGRect(x: self.borderFrame.origin.x + changeX <= self.borderFrame.maxX - KMScreenHoleMinWidthAndHeight ? self.borderFrame.origin.x + changeX : self.borderFrame.maxX - KMScreenHoleMinWidthAndHeight, y: self.borderFrame.origin.y, width: self.borderFrame.size.width - changeX > KMScreenHoleMinWidthAndHeight ? self.borderFrame.size.width - changeX : KMScreenHoleMinWidthAndHeight, height: self.borderFrame.size.height + changeY > KMScreenHoleMinWidthAndHeight ? self.borderFrame.size.height + changeY : KMScreenHoleMinWidthAndHeight)
- case .LeftLower:
- let changeX = newPoint.x - self.borderFrame.minX
- let changeY = newPoint.y - self.borderFrame.minY
- self.borderFrame = CGRect(x: self.borderFrame.origin.x + changeX <= self.borderFrame.maxX - KMScreenHoleMinWidthAndHeight ? self.borderFrame.origin.x + changeX : self.borderFrame.maxX - KMScreenHoleMinWidthAndHeight, y: self.borderFrame.origin.y + changeY <= self.borderFrame.maxY - KMScreenHoleMinWidthAndHeight ? self.borderFrame.origin.y + changeY : self.borderFrame.maxY - KMScreenHoleMinWidthAndHeight, width: self.borderFrame.size.width - changeX > KMScreenHoleMinWidthAndHeight ? self.borderFrame.size.width - changeX : KMScreenHoleMinWidthAndHeight, height: self.borderFrame.size.height - changeY > KMScreenHoleMinWidthAndHeight ? self.borderFrame.size.height - changeY : KMScreenHoleMinWidthAndHeight)
- case .RightUp:
- let changeX = newPoint.x - self.borderFrame.maxX
- let changeY = newPoint.y - self.borderFrame.maxY
- self.borderFrame = CGRect(x: self.borderFrame.origin.x, y: self.borderFrame.origin.y, width: self.borderFrame.size.width + changeX > KMScreenHoleMinWidthAndHeight ? self.borderFrame.size.width + changeX : KMScreenHoleMinWidthAndHeight, height: self.borderFrame.size.height + changeY > KMScreenHoleMinWidthAndHeight ? self.borderFrame.size.height + changeY : KMScreenHoleMinWidthAndHeight)
- case .RightLower:
- let changeX = newPoint.x - self.borderFrame.maxX
- let changeY = newPoint.y - self.borderFrame.minY
- self.borderFrame = CGRect(x: self.borderFrame.origin.x, y: self.borderFrame.origin.y + changeY <= self.borderFrame.maxY - KMScreenHoleMinWidthAndHeight ? self.borderFrame.origin.y + changeY : self.borderFrame.maxY - KMScreenHoleMinWidthAndHeight, width: self.borderFrame.size.width + changeX > KMScreenHoleMinWidthAndHeight ? self.borderFrame.size.width + changeX : KMScreenHoleMinWidthAndHeight , height: self.borderFrame.size.height - changeY > KMScreenHoleMinWidthAndHeight ? self.borderFrame.size.height - changeY : KMScreenHoleMinWidthAndHeight)
- default:
- break
- }
- self.updateHoleWithRect(holeRect: self.borderFrame)
- self.updateSizeLabelWithRect(rect: self.borderFrame, dragPoint: CGPoint(x: self.borderFrame.maxX, y: self.borderFrame.minY))
- if let frameCallBack = self.frameCallBack {
- frameCallBack(self.borderFrame)
- }
- }
- func updateHoleWithRect(holeRect: CGRect) {
- self.borderFrame = holeRect
- self.updateSubViewFrameWithHoleRect(holeRect: holeRect)
- // self.setNeedsDisplay(true)
- self.needsDisplay = true
- }
- func updateSizeLabelWithRect(rect: CGRect, dragPoint: CGPoint) {
- let labelString = "\(Int(rect.size.width)) * \(Int(rect.size.height))"
- self.sizeLabel.stringValue = labelString
- self.sizeLabel.sizeToFit()
- if dragPoint.x == rect.maxX {
- self.sizeLabel.frame = CGRect(x: dragPoint.x, y: dragPoint.y - self.sizeLabel.frame.size.height, width: self.sizeLabel.frame.size.width, height: self.sizeLabel.frame.size.height)
- } else if dragPoint.x == rect.minX {
- self.sizeLabel.frame = CGRect(x: dragPoint.x - self.sizeLabel.frame.size.width, y: dragPoint.y - self.sizeLabel.frame.size.height, width: self.sizeLabel.frame.size.width, height: self.sizeLabel.frame.size.height)
- }
- }
- func updateSubViewFrameWithHoleRect(holeRect: NSRect) {
- let topViewOriginalX: CGFloat = 0
- let topViewOriginalY: CGFloat = min(holeRect.maxY, self.frame.maxY)
- let topViewWidth = self.frame.size.width
- let topViewHeight = holeRect.maxY > self.frame.maxY ? 0 : self.frame.maxY - holeRect.maxY
- self.topView.frame = CGRect(x: topViewOriginalX, y: topViewOriginalY, width: topViewWidth, height: topViewHeight)
- let originalY = holeRect.origin.y
- var leftRightHeight: CGFloat
- if originalY > 0 {
- leftRightHeight = holeRect.size.height
- } else {
- leftRightHeight = holeRect.size.height - abs(holeRect.origin.y)
- }
- let leftViewOriginalX: CGFloat = 0
- let leftViewOriginalY: CGFloat = max(holeRect.minY, 0)
- let leftViewWidth = max(0, holeRect.minX)
- let leftViewHeight = leftRightHeight
- self.leftView.frame = CGRect(x: leftViewOriginalX, y: leftViewOriginalY, width: leftViewWidth, height: leftViewHeight)
-
- let bottomViewOriginalX: CGFloat = 0
- let bottomViewOriginalY: CGFloat = 0
- let bottomViewWidth = self.frame.size.width
- let bottomViewHeight = max(holeRect.minY, 0)
- self.bottomView.frame = CGRect(x: bottomViewOriginalX, y: bottomViewOriginalY, width: bottomViewWidth, height: bottomViewHeight)
-
- let rightViewOriginalX = min(holeRect.maxX, self.frame.maxX)
- let rightViewOriginalY = max(holeRect.minY, 0)
- let rightViewWidth = holeRect.maxX > self.frame.maxX ? 0 : self.frame.maxX - holeRect.maxX
- let rightViewHeight = leftRightHeight
- self.rightView.frame = CGRect(x: rightViewOriginalX, y: rightViewOriginalY, width: rightViewWidth, height: rightViewHeight)
- }
- func updateholeSize(newSize: CGSize) {
- updateHoleWithRect(holeRect: NSRect(x: self.borderFrame.origin.x, y: self.borderFrame.origin.y, width: newSize.width, height: newSize.height))
- updateSizeLabelWithRect(rect: NSRect(x: self.borderFrame.origin.x, y: self.borderFrame.origin.y, width: newSize.width, height: newSize.height), dragPoint: CGPoint(x: self.borderFrame.maxX, y: self.borderFrame.minY))
- }
- func beginImageCapture(isCaptureWindow: Bool) {
- self.window?.setIsVisible(true)
- self.sizeLabel.isHidden = isCaptureWindow
- initMonitor(isCaptureWindow: isCaptureWindow)
- }
-
-
- func setUIPrepare(isWindowCapture: Bool) {
- if isWindowCapture {
- topView.layer?.backgroundColor = NSColor.clear.cgColor
- leftView.layer?.backgroundColor = NSColor.clear.cgColor
- bottomView.layer?.backgroundColor = NSColor.clear.cgColor
- rightView.layer?.backgroundColor = NSColor.clear.cgColor
- windowMaskView.layer?.backgroundColor = NSColor.black.cgColor
- windowMaskView.alphaValue = 0.3
- } else {
- topView.layer?.backgroundColor = NSColor.black.cgColor
- topView.alphaValue = 0.3
- leftView.layer?.backgroundColor = NSColor.black.cgColor
- leftView.alphaValue = 0.3
-
- bottomView.layer?.backgroundColor = NSColor.black.cgColor
- bottomView.alphaValue = 0.3
-
- rightView.layer?.backgroundColor = NSColor.black.cgColor
- rightView.alphaValue = 0.3
- }
- }
-
- func endImageCapture() {
- resignMonitor()
- borderFrame = CGRect.zero
- updateHoleWithRect(holeRect: CGRect.zero)
- self.needsDisplay = true
- editingRect = false
- holeDragMode = false
-
- if NSApp.windows.contains(self.window!) {
- self.window?.setIsVisible(false)
- }
-
- sizeLabel.isHidden = true
- needborderFlag = true
- NSCursor.arrow.set()
- }
-
- func resignMonitor() {
- NSEvent.removeMonitor(localMonitor as Any)
- NSEvent.removeMonitor(globalMonitor as Any)
- localMonitor = nil
- globalMonitor = nil
- }
-
- func initMonitor(isCaptureWindow: Bool) {
- self.iswindowCapture = isCaptureWindow
- var mask: NSEvent.EventTypeMask
- if isCaptureWindow {
- mask = [NSEvent.EventTypeMask.mouseMoved, NSEvent.EventTypeMask.leftMouseDown, NSEvent.EventTypeMask.keyDown]
- } else {
- mask = [NSEvent.EventTypeMask.mouseMoved, NSEvent.EventTypeMask.leftMouseDown, NSEvent.EventTypeMask.leftMouseDragged, NSEvent.EventTypeMask.leftMouseUp, NSEvent.EventTypeMask.keyDown]
- self.updateHoleWithRect(holeRect: .zero)
- }
- self.setUIPrepare(isWindowCapture: isCaptureWindow)
- if self.localMonitor == nil {
- self.localMonitor = NSEvent.addLocalMonitorForEvents(matching: mask) { (result) -> NSEvent? in
- if isCaptureWindow {
- let windowID: CGWindowID = self.windowForEvent(result)
- if result.type == .leftMouseDown {
- let image = KMScreenShotHandler.appointWindowScreenShot(withWindowID: windowID)
- self.callBack?(image ?? NSImage())
- self.endImageCapture()
- } else if result.type == .mouseMoved {
- let rect = KMOCTool.localCropRect(forWindow: windowID, withBounds: self.bounds)
- self.updateWindowSelectUI(withWindowRect: rect)
- let cursor = NSCursor(image: NSImage(named: "cameraCursor") ?? NSImage(), hotSpot: NSPoint(x: 0, y: 0))
- cursor.set()
- } else if result.type == .keyDown {
- if result.keyCode == 53 {
- self.endImageCapture()
- }
- }
- return nil
- } else {
- var newFrame = CGRect.zero
- if result.type == .leftMouseDown {
- if self.editingRect {
- if self.holeDragMode {
- let downPoint = KMScreenShotHandler.screenPosition(for: result)
- self.pullXGap = Float(downPoint.x - self.borderFrame.origin.x)
- self.pullYGap = Float(downPoint.y - self.borderFrame.origin.y)
- }
- } else {
- self.dragStartPoint = KMScreenShotHandler.screenPosition(for: result)
- }
- } else if result.type == .leftMouseDragged {
- if self.editingRect{
- if self.holeDragMode {
- self.dragholeImageView(result)
- } else {
- self.rectEditDrag(event: result)
- }
- } else {
- self.dragLastPoint = KMScreenShotHandler.screenPosition(for: result)
- newFrame = NSMakeRect(min(self.dragStartPoint.x, self.dragLastPoint.x), min(self.dragStartPoint.y, self.dragLastPoint.y), abs(self.dragStartPoint.x - self.dragLastPoint.x), abs(self.dragStartPoint.y - self.dragLastPoint.y))
- self.updateSizeLabelWithRect(rect: newFrame, dragPoint: self.dragLastPoint)
- self.updateHoleWithRect(holeRect: newFrame)
- NSCursor.crosshair.set()
- }
- } else if result.type == .leftMouseUp {
- if self.editingRect {
-
- } else {
- self.dragLastPoint = KMScreenShotHandler.screenPosition(for: result)
- newFrame = NSMakeRect(min(self.dragStartPoint.x, self.dragLastPoint.x), min(self.dragStartPoint.y, self.dragLastPoint.y), abs(self.dragStartPoint.x - self.dragLastPoint.x) <= KMScreenHoleMinWidthAndHeight ? KMScreenHoleMinWidthAndHeight : abs(self.dragStartPoint.x - self.dragLastPoint.x), abs(self.dragStartPoint.y - self.dragLastPoint.y) <= KMScreenHoleMinWidthAndHeight ? KMScreenHoleMinWidthAndHeight : abs(self.dragStartPoint.y - self.dragLastPoint.y))
- self.updateHoleWithRect(holeRect: newFrame)
- self.beginEditSelectArea(newFrame)
- self.frameCallBack?(newFrame)
- }
- } else if result.type == .keyDown {
- if result.keyCode == 53 {
- self.endImageCapture()
- }
- } else if result.type == .mouseMoved {
- if self.detachCallBack != nil {
- self.detachCallBack?(result)
- }
- if self.editingRect{
- self.changeCursorTypeWithEvent(result)
- return nil
- } else {
-
- }
- }
- return result
- }
- }
- }
- if self.globalMonitor == nil {
- self.globalMonitor = NSEvent.addGlobalMonitorForEvents(matching: mask) { (result) in
- if isCaptureWindow {
- let windowID = self.windowForEvent(result)
- if result.type == .leftMouseDown {
- let image = KMScreenShotHandler.appointWindowScreenShot(withWindowID: windowID)
- self.callBack?(image ?? NSImage())
- self.endImageCapture()
- } else if result.type == .mouseMoved {
- let rect = KMOCTool.localCropRect(forWindow: windowID, withBounds: self.bounds)
- self.updateWindowSelectUI(withWindowRect: rect)
- let cursor = NSCursor(image: NSImage(named: "cameraCursor") ?? NSImage(), hotSpot: NSPoint(x: 0, y: 0))
- cursor.set()
- print("全局移动")
- } else if result.type == .keyDown {
- if result.keyCode == 53 {
- self.endImageCapture()
- }
- } else if result.type == .rightMouseDown {
- self.endImageCapture()
- }
- } else {
- var newFrame = CGRect.zero
- if result.type == .leftMouseDown {
- if self.editingRect{
- if self.holeDragMode {
- let downPoint = KMScreenShotHandler.screenPosition(for: result)
- self.pullXGap = Float(downPoint.x - self.borderFrame.origin.x)
- self.pullYGap = Float(downPoint.y - self.borderFrame.origin.y)
- }
- } else {
- self.dragStartPoint = KMScreenShotHandler.screenPosition(for: result)
- }
- } else if result.type == .leftMouseDragged {
- if self.editingRect{
- if self.holeDragMode {
- self.dragholeImageView(result)
- } else {
- self.rectEditDrag(event: result)
- }
- } else {
- self.dragLastPoint = KMScreenShotHandler.screenPosition(for: result)
- newFrame = NSMakeRect(min(self.dragStartPoint.x, self.dragLastPoint.x), min(self.dragStartPoint.y, self.dragLastPoint.y), abs(self.dragStartPoint.x - self.dragLastPoint.x), abs(self.dragStartPoint.y - self.dragLastPoint.y))
- self.updateHoleWithRect(holeRect: newFrame)
- }
- } else if result.type == .leftMouseUp {
- if self.editingRect{
-
- } else {
- self.dragLastPoint = KMScreenShotHandler.screenPosition(for: result)
- newFrame = NSMakeRect(min(self.dragStartPoint.x, self.dragLastPoint.x), min(self.dragStartPoint.y, self.dragLastPoint.y), abs(self.dragStartPoint.x - self.dragLastPoint.x) <= KMScreenHoleMinWidthAndHeight ? KMScreenHoleMinWidthAndHeight : abs(self.dragStartPoint.x - self.dragLastPoint.x), abs(self.dragStartPoint.y - self.dragLastPoint.y) <= KMScreenHoleMinWidthAndHeight ? KMScreenHoleMinWidthAndHeight : abs(self.dragStartPoint.y - self.dragLastPoint.y))
- self.updateHoleWithRect(holeRect: newFrame)
- self.beginEditSelectArea(newFrame)
- self.frameCallBack?(newFrame)
- }
- } else if result.type == .keyDown {
- if result.keyCode == 53 {
- self.endImageCapture()
- }
- } else if result.type == .mouseMoved {
- if self.detachCallBack != nil {
- self.detachCallBack?(result)
- }
- if self.editingRect {
- self.changeCursorTypeWithEvent(result)
- } else {
-
- }
- }
- }
-
- }
- }
- }
- func updateWindowSelectUI(withWindowRect rect: CGRect) {
- topView.layer?.backgroundColor = NSColor.clear.cgColor
- leftView.layer?.backgroundColor = NSColor.clear.cgColor
- bottomView.layer?.backgroundColor = NSColor.clear.cgColor
- rightView.layer?.backgroundColor = NSColor.clear.cgColor
- windowMaskView.frame = rect
- windowMaskView.layer?.backgroundColor = NSColor.black.cgColor
- windowMaskView.alphaValue = 0.3
- }
- func dragholeImageView(_ event: NSEvent) {
- guard let screen = NSScreen.screens.first else { return }
- let xMax = screen.frame.size.width
- let yMax = screen.frame.size.height
- let newPoint = KMScreenShotHandler.screenPosition(for: event)
- var newOriginalX = newPoint.x - CGFloat(pullXGap)
- var newOriginalY = newPoint.y - CGFloat(pullYGap)
-
- if newOriginalX < 0 {
- newOriginalX = 0
- }
-
- if newOriginalX + borderFrame.size.width > xMax {
- newOriginalX = xMax - borderFrame.size.width
- }
-
- if newOriginalY < 0 {
- newOriginalY = 0
- }
-
- if newOriginalY + borderFrame.size.height > yMax {
- newOriginalY = yMax - borderFrame.size.height
- }
-
- borderFrame = NSMakeRect(newOriginalX, newOriginalY, borderFrame.size.width, borderFrame.size.height)
- updateHoleWithRect(holeRect: borderFrame)
- updateSizeLabelWithRect(rect: borderFrame, dragPoint: NSMakePoint(NSMaxX(borderFrame), NSMinY(borderFrame)))
-
- if let callback = frameCallBack {
- callback(borderFrame)
- }
- }
- func captureImage() {
- guard let screen = NSScreen.screens.first else { return }
- let screenHeight = screen.frame.size.height
- let actualFrame = NSMakeRect(borderFrame.origin.x, screenHeight - borderFrame.origin.y - borderFrame.size.height, borderFrame.size.width, borderFrame.size.height)
- needborderFlag = false
- self.needsDisplay = true
-
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { [weak self] in
- guard let self = self else { return }
- if let windowImage = CGWindowListCreateImage(actualFrame, .optionOnScreenOnly, kCGNullWindowID, []) {
- let image = KMScreenShotHandler.imageFromCGImageRef(windowImage)
- self.updateHoleWithRect(holeRect: NSRect.zero)
- if let callback = self.callBack {
- callback(image ?? NSImage())
- }
- }
- self.endImageCapture()
- }
- }
- }
|