Skip to content

Commit

Permalink
Improve gutter line number cell layout and marker positioning
Browse files Browse the repository at this point in the history
- Store text size in `STGutterLineNumberCell` for more efficient layout
- Add `firstBaselineOffsetFromTop` to `STGutterLineNumberCell` for proper vertical alignment
- Position gutter markers based on the text size and baseline of the corresponding line number cell
- Ensure marker views don't exceed the height of the line number cell
  • Loading branch information
krzyzanowskim committed Jan 2, 2025
1 parent fc3a733 commit 5c0e0fe
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
12 changes: 8 additions & 4 deletions Sources/STTextViewAppKit/Gutter/STGutterLineNumberCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ final class STGutterLineNumberCell: NSView {
let lineNumber: Int
private let firstBaseline: CGFloat
private let ctLine: CTLine
private let textWidth: CGFloat
let textSize: CGSize
var insets: STRulerInsets = STRulerInsets()

override func animation(forKey key: NSAnimatablePropertyKey) -> Any? {
Expand All @@ -20,13 +20,17 @@ final class STGutterLineNumberCell: NSView {
"\(super.debugDescription) (number: \(lineNumber))"
}

override var firstBaselineOffsetFromTop: CGFloat {
firstBaseline
}

init(firstBaseline: CGFloat, attributes: [NSAttributedString.Key: Any], number: Int) {
self.lineNumber = number
self.firstBaseline = firstBaseline

let attributedString = NSAttributedString(string: "\(number)", attributes: attributes)
self.ctLine = CTLineCreateWithAttributedString(attributedString)
self.textWidth = ceil(CTLineGetTypographicBounds(ctLine, nil, nil, nil))
self.textSize = CGSize(width: ceil(CTLineGetTypographicBounds(ctLine, nil, nil, nil)), height: ctLine.height())

super.init(frame: .zero)
wantsLayer = true
Expand All @@ -49,7 +53,7 @@ final class STGutterLineNumberCell: NSView {
}

override var intrinsicContentSize: NSSize {
NSSize(width: textWidth + insets.trailing + insets.leading, height: 14)
NSSize(width: textSize.width + insets.trailing + insets.leading, height: textSize.height)
}

override func draw(_ rect: CGRect) {
Expand All @@ -63,7 +67,7 @@ final class STGutterLineNumberCell: NSView {
ctx.textMatrix = CGAffineTransform(scaleX: 1, y: isFlipped ? -1 : 1)

// align to right
ctx.textPosition = CGPoint(x: frame.width - (textWidth + insets.trailing), y: firstBaseline)
ctx.textPosition = CGPoint(x: frame.width - (textSize.width + insets.trailing), y: firstBaseline)
CTLineDraw(ctLine, ctx)
ctx.restoreGState()
}
Expand Down
5 changes: 3 additions & 2 deletions Sources/STTextViewAppKit/Gutter/STGutterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,10 @@ open class STGutterView: NSView, NSDraggingSource {
}

if let cellView {
markerContainerView.addSubview(marker.view)
marker.view.frame.size = cellView.frame.size
marker.view.frame.origin = cellView.frame.origin
marker.view.frame.size = cellView.frame.size
marker.view.frame.size.height = min(cellView.textSize.height + cellView.firstBaselineOffsetFromTop, cellView.frame.size.height)
markerContainerView.addSubview(marker.view)
}
}
}
Expand Down

0 comments on commit 5c0e0fe

Please sign in to comment.