Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ extension TextViewController {
delegate: self
)
gutterView.updateWidthIfNeeded()
scrollView.addFloatingSubview(
gutterView,
for: .horizontal
)
scrollView.addFloatingSubview(gutterView, for: .horizontal)

minimapView = MinimapView(textView: textView, theme: theme)
scrollView.addFloatingSubview(minimapView, for: .vertical)
Expand Down Expand Up @@ -89,7 +86,7 @@ extension TextViewController {
minimapView.bottomAnchor.constraint(equalTo: scrollView.contentView.bottomAnchor),
minimapXConstraint,
maxWidthConstraint,
relativeWidthConstraint,
relativeWidthConstraint
])
}

Expand Down Expand Up @@ -124,7 +121,11 @@ extension TextViewController {
queue: .main
) { [weak self] _ in
self?.gutterView.frame.size.height = (self?.textView.frame.height ?? 0) + 10
self?.gutterView.frame.origin.y = (self?.textView.frame.origin.y ?? 0.0)
- (self?.scrollView.contentInsets.top ?? 0)

self?.gutterView.needsDisplay = true
self?.scrollView.needsLayout = true
}

NotificationCenter.default.addObserver(
Expand All @@ -146,7 +147,7 @@ extension TextViewController {

// Reset content insets and gutter position when appearance changes
self.styleScrollView()
self.gutterView.frame.origin.y = -self.scrollView.contentInsets.top
self.gutterView.frame.origin.y = self.textView.frame.origin.y - self.scrollView.contentInsets.top
}
}
.store(in: &cancellables)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ extension TextViewController {

findViewController?.topPadding = contentInsets?.top

gutterView.frame.origin.y = -scrollView.contentInsets.top
gutterView.frame.origin.y = textView.frame.origin.y - scrollView.contentInsets.top

// Update scrollview tiling
scrollView.reflectScrolledClipView(scrollView.contentView)
Expand Down
29 changes: 25 additions & 4 deletions Sources/CodeEditSourceEditor/Gutter/GutterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ public class GutterView: NSView {
var textColor: NSColor = .secondaryLabelColor

@Invalidating(.display)
var font: NSFont = .systemFont(ofSize: 13)
var font: NSFont = .systemFont(ofSize: 13) {
didSet {
updateFontLineHeight()
}
}

@Invalidating(.display)
var edgeInsets: EdgeInsets = EdgeInsets(leading: 20, trailing: 12)
Expand Down Expand Up @@ -74,6 +78,19 @@ public class GutterView: NSView {
/// The maximum number of digits found for a line number.
private var maxLineLength: Int = 0

private var fontLineHeight = 1.0

private func updateFontLineHeight() {
let string = NSAttributedString(string: "0", attributes: [.font: font])
let typesetter = CTTypesetterCreateWithAttributedString(string)
let ctLine = CTTypesetterCreateLine(typesetter, CFRangeMake(0, 1))
var ascent: CGFloat = 0
var descent: CGFloat = 0
var leading: CGFloat = 0
CTLineGetTypographicBounds(ctLine, &ascent, &descent, &leading)
fontLineHeight = (ascent + descent + leading)
}

override public var isFlipped: Bool {
true
}
Expand Down Expand Up @@ -181,7 +198,7 @@ public class GutterView: NSView {
y: line.yPos,
width: width,
height: line.height
)
).pixelAligned
)
}

Expand Down Expand Up @@ -217,12 +234,16 @@ public class GutterView: NSView {
let fragment: LineFragment? = linePosition.data.lineFragments.first?.data
var ascent: CGFloat = 0
let lineNumberWidth = CTLineGetTypographicBounds(ctLine, &ascent, nil, nil)
let fontHeightDifference = ((fragment?.height ?? 0) - fontLineHeight) / 4

let yPos = linePosition.yPos + ascent + (fragment?.heightDifference ?? 0)/2
let yPos = linePosition.yPos + ascent + (fragment?.heightDifference ?? 0)/2 + fontHeightDifference
// Leading padding + (width - linewidth)
let xPos = edgeInsets.leading + (maxWidth - lineNumberWidth)

context.textPosition = CGPoint(x: xPos, y: yPos).pixelAligned
ContextSetHiddenSmoothingStyle(context, 16)

context.textPosition = CGPoint(x: xPos, y: yPos)

CTLineDraw(ctLine, context)
}
context.restoreGState()
Expand Down