KMTextWithIconCell.swift 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //
  2. // KMTextWithIconCell.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by lizhe on 2024/2/21.
  6. //
  7. import Cocoa
  8. let SKTextWithIconStringKey = "string"
  9. let SKTextWithIconImageKey = "image"
  10. let BORDER_BETWEEN_EDGE_AND_IMAGE: CGFloat = 2.0
  11. let BORDER_BETWEEN_IMAGE_AND_TEXT: CGFloat = 2.0
  12. let IMAGE_OFFSET: CGFloat = 1.0
  13. class KMTextWithIconCell: NSTextFieldCell {
  14. var imageCell: NSImageCell = NSImageCell()
  15. override init(textCell string: String) {
  16. super.init(textCell: string)
  17. commonInit()
  18. }
  19. required init(coder: NSCoder) {
  20. super.init(coder: coder)
  21. commonInit()
  22. }
  23. private func commonInit() {
  24. imageCell.imageScaling = .scaleProportionallyUpOrDown
  25. // if formatter == nil {
  26. // formatter = DictionaryFormatter(key: SKTextWithIconStringKey)
  27. // }
  28. }
  29. override func cellSize(forBounds rect: NSRect) -> NSSize {
  30. var cellSize = super.cellSize(forBounds: rect)
  31. cellSize.width += cellSize.height - 1 + BORDER_BETWEEN_EDGE_AND_IMAGE + BORDER_BETWEEN_IMAGE_AND_TEXT
  32. cellSize.width = min(cellSize.width, rect.width)
  33. return cellSize
  34. }
  35. private func textRect(forBounds rect: NSRect) -> NSRect {
  36. return KMShrinkRect(rect, NSHeight(rect) - 1 + BORDER_BETWEEN_EDGE_AND_IMAGE + BORDER_BETWEEN_IMAGE_AND_TEXT, .minX)
  37. }
  38. private func iconRect(forBounds rect: NSRect) -> NSRect {
  39. return KMSliceRect(KMShrinkRect(rect, BORDER_BETWEEN_EDGE_AND_IMAGE, .minX), NSHeight(rect) - 1, .minX)
  40. }
  41. override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
  42. // let super draw the text
  43. let textRect = textRect(forBounds: cellFrame)
  44. super.drawInterior(withFrame: textRect, in: controlView)
  45. // Draw the image
  46. var imageRect = iconRect(forBounds: cellFrame)
  47. imageRect = KMCenterRectVertically(rect: imageRect, height: NSWidth(imageRect), offset: IMAGE_OFFSET, flipped: controlView.isFlipped)
  48. imageCell.drawInterior(withFrame: imageRect, in: controlView)
  49. }
  50. override func edit(withFrame cellFrame: NSRect, in controlView: NSView, editor textObj: NSText, delegate anObject: Any?, event: NSEvent?) {
  51. super.edit(withFrame: textRect(forBounds: cellFrame), in: controlView, editor: textObj, delegate: anObject, event: event)
  52. }
  53. override func select(withFrame cellFrame: NSRect, in controlView: NSView, editor textObj: NSText, delegate anObject: Any?, start selStart: Int, length selLength: Int) {
  54. super.select(withFrame: textRect(forBounds: cellFrame), in: controlView, editor: textObj, delegate: anObject, start: selStart, length: selLength)
  55. }
  56. override func hitTest(for event: NSEvent, in rect: NSRect, of controlView: NSView) -> NSCell.HitResult {
  57. let textRect = textRect(forBounds: rect)
  58. let mouseLoc = event.location(inPDFListView: controlView)
  59. var hit: NSCell.HitResult = []
  60. if NSMouseInRect(mouseLoc, textRect, controlView.isFlipped) {
  61. hit = super.hitTest(for: event, in: textRect, of: controlView)
  62. } else if NSMouseInRect(mouseLoc, iconRect(forBounds: rect), controlView.isFlipped) {
  63. hit = .contentArea
  64. }
  65. return hit
  66. }
  67. override var objectValue: Any? {
  68. didSet {
  69. if let obj = objectValue as? NSDictionary {
  70. // imageCell.image = obj[SKTextWithIconImageKey] as? NSImage
  71. self.stringValue = obj[SKTextWithIconStringKey] as! String
  72. }
  73. }
  74. }
  75. var icon: NSImage? {
  76. return imageCell.image
  77. }
  78. }
  79. extension KMTextWithIconCell {
  80. func KMSliceRect(_ rect: NSRect, _ amount: CGFloat, _ edge: NSRectEdge) -> NSRect {
  81. var rect = rect
  82. var ignored = NSRect.zero
  83. NSDivideRect(rect, &rect, &ignored, amount, edge);
  84. return rect
  85. }
  86. func KMShrinkRect(_ rect: NSRect, _ amount: CGFloat, _ edge: NSRectEdge) -> NSRect {
  87. var rect = rect
  88. var ignored = NSRect.zero
  89. NSDivideRect(rect, &ignored, &rect, amount, edge);
  90. return rect
  91. }
  92. func KMCenterRectVertically(rect: NSRect, height: CGFloat , offset: CGFloat, flipped: Bool) -> NSRect {
  93. var rect = rect
  94. rect.origin.y += 0.5 * (NSHeight(rect) - height);
  95. rect.origin.y = flipped ? ceil(rect.origin.y) - offset : floor(rect.origin.y) + offset;
  96. rect.size.height = height;
  97. return rect;
  98. }
  99. }