KMGuideTargetView.swift 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. //
  2. // KMGuideTargetView.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2024/6/25.
  6. //
  7. import Cocoa
  8. @objc enum KMGuideTargetStyle: UInt {
  9. case none = 0
  10. case ellipse
  11. case round
  12. }
  13. @objcMembers class KMGuideTargetView: NSView {
  14. var lineWidth: CGFloat = 2 {
  15. didSet {
  16. self.needsDisplay = true
  17. }
  18. }
  19. var strokeColor: NSColor = .black {
  20. didSet {
  21. self.needsDisplay = true
  22. }
  23. }
  24. var insets: NSEdgeInsets = .init(top: 0, left: 0, bottom: 0, right: 0) {
  25. didSet {
  26. self.needsDisplay = true
  27. }
  28. }
  29. var style: KMGuideTargetStyle = .ellipse {
  30. didSet {
  31. self.needsDisplay = true
  32. }
  33. }
  34. var xRadius: CGFloat = 0 {
  35. didSet {
  36. self.needsDisplay = true
  37. }
  38. }
  39. var yRadius: CGFloat = 0 {
  40. didSet {
  41. self.needsDisplay = true
  42. }
  43. }
  44. override func draw(_ dirtyRect: NSRect) {
  45. super.draw(dirtyRect)
  46. let rect = self.bounds
  47. let left = self.insets.left
  48. let top = self.insets.top
  49. let drawW = max(NSWidth(rect)-left-self.insets.right, 0)
  50. let drawH = max(NSHeight(rect)-top-self.insets.bottom, 0)
  51. let drawRect = NSMakeRect(left, top, drawW, drawH)
  52. let context = NSGraphicsContext.current?.cgContext
  53. context?.saveGState()
  54. context?.setLineWidth(self.lineWidth)
  55. context?.setStrokeColor(self.strokeColor.cgColor)
  56. let dxy = self.lineWidth * 0.5
  57. let outRect = drawRect.insetBy(dx: dxy, dy: dxy)
  58. if style == .ellipse {
  59. context?.addEllipse(in: outRect)
  60. } else if style == .round {
  61. let path = CGPath(roundedRect: outRect, cornerWidth: xRadius, cornerHeight: yRadius, transform: nil)
  62. context?.addPath(path)
  63. }
  64. let offset: CGFloat = 4
  65. let inRect = outRect.insetBy(dx: dxy+offset, dy: dxy+offset)
  66. if style == .ellipse {
  67. context?.addEllipse(in: inRect)
  68. } else if style == .round {
  69. let path = CGPath(roundedRect: inRect, cornerWidth: xRadius-offset, cornerHeight: yRadius-offset, transform: nil)
  70. context?.addPath(path)
  71. }
  72. context?.strokePath()
  73. context?.restoreGState()
  74. }
  75. // func _bezierPathToCGPath(_ bezierPath: NSBezierPath) -> CGPath? {
  76. // let mutablePath = CGMutablePath()
  77. // let numElements = bezierPath.elementCount
  78. // let points = UnsafeMutablePointer<NSPoint>.allocate(capacity: 3)
  79. //
  80. // for i in 0 ..< numElements {
  81. // switch bezierPath.element(at: i, associatedPoints: points) {
  82. // case .moveTo:
  83. // KMPathMoveToPoint(mutablePath, nil, points[0].x, points[0].y)
  84. // case .lineTo:
  85. // KMPathAddLineToPoint(mutablePath, nil, points[0].x, points[0].y)
  86. // case .curveTo:
  87. // KMPathAddCurveToPoint(mutablePath, nil, points[0].x, points[0].y,points[1].x, points[1].y, points[2].x, points[2].y)
  88. // case .closePath:
  89. // KMPathCloseSubpath(mutablePath)
  90. // default:
  91. // break
  92. // }
  93. // }
  94. //
  95. // return KMPathCreateCopy(mutablePath)
  96. // }
  97. }