KMTextField.swift 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // KMTextField.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2023/6/7.
  6. //
  7. import Cocoa
  8. protocol KMTextFieldDelegate: AnyObject {
  9. func km_controlTextShouldBeginEditing(textField: AnyObject) -> Bool
  10. func km_controlTextDidBeginEditing(textField: AnyObject)
  11. func km_controlTextDidChange(textField: AnyObject)
  12. func km_controlTextShouldEndEditing(textField: AnyObject) -> Bool
  13. func km_controlTextDidEndEditing(textField: AnyObject)
  14. func km_didBecomeFirstResponder(textField: AnyObject)
  15. }
  16. extension KMTextFieldDelegate {
  17. func km_controlTextShouldBeginEditing(textField: AnyObject) -> Bool { return true }
  18. func km_controlTextDidBeginEditing(textField: AnyObject) {}
  19. func km_controlTextDidChange(textField: AnyObject) {}
  20. func km_controlTextShouldEndEditing(textField: AnyObject) -> Bool { return true }
  21. func km_controlTextDidEndEditing(textField: AnyObject) {}
  22. func km_didBecomeFirstResponder(textField: AnyObject) {}
  23. }
  24. class KMTextField: NSTextField {
  25. private class _KMTextFieldCell: NSTextFieldCell {
  26. // 边框粗细
  27. var borderThickness: CGFloat = 1
  28. // 左右两边缩进
  29. var offset: CGFloat = 8.0
  30. override func draw(withFrame cellFrame: NSRect, in controlView: NSView) {
  31. // Area that covers the NSTextField itself. That is the total height minus our custom border size.
  32. let interiorFrame = NSRect(x: 0, y: 0, width: cellFrame.width, height: cellFrame.height - self.borderThickness)
  33. let path = NSBezierPath()
  34. path.lineWidth = self.borderThickness
  35. // Line width is at the center of the line.
  36. path.move(to: NSPoint(x: 0, y: cellFrame.height))
  37. path.line(to: NSPoint(x: cellFrame.width, y: cellFrame.height))
  38. path.line(to: NSPoint(x: cellFrame.width, y: 0))
  39. path.line(to: NSPoint(x: 0, y: 0))
  40. NSColor.clear.setStroke()
  41. path.stroke()
  42. // Pass in area minus the border thickness in the height
  43. drawInterior(withFrame: interiorFrame, in: controlView)
  44. }
  45. }
  46. var borderThickness: CGFloat = 1 {
  47. didSet {
  48. if let _cell = self.cell as? _KMTextFieldCell {
  49. _cell.borderThickness = self.borderThickness
  50. }
  51. self.needsDisplay = true
  52. }
  53. }
  54. var offset: CGFloat = 8.0 {
  55. didSet {
  56. if let _cell = self.cell as? _KMTextFieldCell {
  57. _cell.offset = self.offset
  58. }
  59. self.needsDisplay = true
  60. }
  61. }
  62. var enterKeyEndEdit = false
  63. override init(frame frameRect: NSRect) {
  64. super.init(frame: frameRect)
  65. }
  66. var firstResponderHandler: ((Bool)->Void)?
  67. required init?(coder: NSCoder) {
  68. super.init(coder: coder)
  69. }
  70. override class var cellClass: AnyClass? {
  71. set {
  72. super.cellClass = newValue
  73. }
  74. get {
  75. return _KMTextFieldCell.self
  76. }
  77. }
  78. override func becomeFirstResponder() -> Bool {
  79. let result = super.becomeFirstResponder()
  80. guard let callback = self.firstResponderHandler else {
  81. return result
  82. }
  83. callback(result)
  84. return result
  85. }
  86. }