确定了高亮区域的渲染方式后,我们在ClipWindowController中添加对鼠标事件的监听,用于获取高亮区域。

在ClipWindowController中设置一些变量,用来记录用户操作过程中的一些NSPoint和NSRect:

class ClipWindowController: NSWindowController {
    
    
    var clipView: ClipView?
		var screenImage: NSImage?
    
    var lastRect: NSRect?        // 上一个完整的区域,用于保存拖拽或调整前的区域
    var highlightRect: NSRect?   // 当前高亮的区域,通过鼠标操作动态更新
		var startPoint: NSPoint?     // 上一个完整区域的origin
    var lastPoint: NSPoint?      // 上一次更新区域时鼠标的位置
    
		// functions ....
}

实现思路:

其中用到mouseDownmouseUpmouseDrag这三个事件监听:

override func mouseDown(with event: NSEvent) {
      let location = event.locationInWindow
      switch ClipManager.shared.status {
      case .ready:
          ClipManager.shared.status = .start
          self.startPoint = location
      case .select:
          // 暂不实现
					break
      default:
          return
      }
  }
override func mouseUp(with event: NSEvent) {
    switch ClipManager.shared.status {
    case .start:
        guard let rect = self.highlightRect, let view = self.clipView else {
						// 没有形成高亮区域
            ClipManager.shared.status = .ready
            return
        }
        ClipManager.shared.status = .select
        self.lastRect = rect
        self.highlight()
    case .drag, .adjust:
				// 暂不实现
				break
    default:
        return
    }
}
override func mouseDragged(with event: NSEvent) {
    let location = event.locationInWindow
    switch ClipManager.shared.status {
    case .start:
        guard let start = self.startPoint else { return }
				// 根据 startPoint和当前位置构建新的rect并更新highlightRect
        self.highlightRect = RectUtil.getRect(aPoint: start, bPoint: location)
				// 重新渲染
        self.highlight()
    case .adjust:
        // 暂不实现
				break
    case .drag:
         // 暂不实现
				break
    default:
        break
    }
}

其中RectUtil.getRect是在工具类中的一个静态方法,根据两个Point获取对应的Rect:

Utils/RectUtil.swift

class RectUtil: NSObject {
	  static func getRect(aPoint: NSPoint, bPoint:NSPoint) -> NSRect{
	      return NSIntegralRect(NSRect(
	          x: min(aPoint.x, bPoint.x),
	          y: min(aPoint.y, bPoint.y),
	          width: abs(aPoint.x-bPoint.x),
	          height: abs(aPoint.y-bPoint.y)
	      ))
	  }
	  // ... other functions
}

高亮区域的拖拽移动 ➡️