diff --git a/Sources/CodeEditTextView/TextLayoutManager/TextAttachments/TextAttachmentManager.swift b/Sources/CodeEditTextView/TextLayoutManager/TextAttachments/TextAttachmentManager.swift index dfa561d84..9eb1cde24 100644 --- a/Sources/CodeEditTextView/TextLayoutManager/TextAttachments/TextAttachmentManager.swift +++ b/Sources/CodeEditTextView/TextLayoutManager/TextAttachments/TextAttachmentManager.swift @@ -17,6 +17,8 @@ public final class TextAttachmentManager { weak var layoutManager: TextLayoutManager? private var selectionObserver: (any NSObjectProtocol)? + public weak var delegate: TextAttachmentManagerDelegate? + /// Adds a new attachment, keeping `orderedAttachments` sorted by range.location. /// If two attachments overlap, the layout phase will later ignore the one with the higher start. /// - Complexity: `O(n log(n))` due to array insertion. Could be improved with a binary tree. @@ -47,6 +49,8 @@ public final class TextAttachmentManager { } layoutManager?.setNeedsLayout() + + delegate?.textAttachmentDidAdd(attachment.attachment, for: range) } /// Removes an attachment and invalidates layout for the removed range. @@ -62,6 +66,9 @@ public final class TextAttachmentManager { let attachment = orderedAttachments.remove(at: index) layoutManager?.invalidateLayoutForRange(attachment.range) + + delegate?.textAttachmentDidRemove(attachment.attachment, for: attachment.range) + return attachment } diff --git a/Sources/CodeEditTextView/TextLayoutManager/TextAttachments/TextAttachmentManagerDelegate.swift b/Sources/CodeEditTextView/TextLayoutManager/TextAttachments/TextAttachmentManagerDelegate.swift new file mode 100644 index 000000000..c5b363b00 --- /dev/null +++ b/Sources/CodeEditTextView/TextLayoutManager/TextAttachments/TextAttachmentManagerDelegate.swift @@ -0,0 +1,13 @@ +// +// TextAttachmentManagerDelegate.swift +// CodeEditTextView +// +// Created by Khan Winter on 6/25/25. +// + +import Foundation + +public protocol TextAttachmentManagerDelegate: AnyObject { + func textAttachmentDidAdd(_ attachment: any TextAttachment, for range: NSRange) + func textAttachmentDidRemove(_ attachment: any TextAttachment, for range: NSRange) +} diff --git a/Sources/CodeEditTextView/TextLine/LineFragmentRenderer.swift b/Sources/CodeEditTextView/TextLine/LineFragmentRenderer.swift index 5225123d8..4824e010b 100644 --- a/Sources/CodeEditTextView/TextLine/LineFragmentRenderer.swift +++ b/Sources/CodeEditTextView/TextLine/LineFragmentRenderer.swift @@ -92,9 +92,9 @@ public final class LineFragmentRenderer { in: context, rect: NSRect( x: currentPosition, - y: yPos, + y: yPos + (lineFragment.heightDifference/2), width: attachment.width, - height: lineFragment.scaledHeight + height: lineFragment.height ) ) }