Skip to content

Commit 773da40

Browse files
committed
Separate gutter separator view from STGutterView
- Extract logic for drawing the gutter separator into a dedicated STGutterSeparatorView class. This allows the separator view to handle its own drawing and configuration. - Make the gutter separator view a subview of STGutterView, similar to the existing container view and marker container view. - Update properties on STGutterView to pass through to the underlying STGutterSeparatorView instance. - Insert the background effect view as the first subview of STGutterView, below the other subviews, instead of relative to self.
1 parent a85d9ed commit 773da40

File tree

2 files changed

+56
-20
lines changed

2 files changed

+56
-20
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Created by Marcin Krzyzanowski
2+
// https://github.com/krzyzanowskim/STTextView/blob/main/LICENSE.md
3+
4+
import Cocoa
5+
6+
class STGutterSeparatorView: NSView {
7+
@Invalidating(.display)
8+
var drawSeparator: Bool = true
9+
10+
@Invalidating(.display)
11+
var separatorColor = NSColor.separatorColor.withAlphaComponent(0.1)
12+
13+
override var isFlipped: Bool {
14+
true
15+
}
16+
17+
override func draw(_ rect: CGRect) {
18+
super.draw(rect)
19+
20+
guard let context = NSGraphicsContext.current?.cgContext else {
21+
return
22+
}
23+
24+
if drawSeparator {
25+
context.setLineWidth(1)
26+
context.setStrokeColor(separatorColor.cgColor)
27+
context.addLines(between: [CGPoint(x: frame.width - 0.5, y: 0), CGPoint(x: frame.width - 0.5, y: bounds.maxY) ])
28+
context.strokePath()
29+
}
30+
}
31+
}

Sources/STTextViewAppKit/Gutter/STGutterView.swift

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// https://github.com/krzyzanowskim/STTextView/blob/main/LICENSE.md
33
//
44
// STGutterView
5+
// |- NSVisualEffectView
56
// |- STGutterContainerView
7+
// |- STGutterSeparatorView
68
// |-STGutterLineNumberCell
79
// |- STGutterMarkerContainerView
810
// |-STGutterMarker.view
@@ -27,6 +29,7 @@ public extension STGutterViewDelegate {
2729

2830
/// A gutter to the side of a scroll view’s document view.
2931
open class STGutterView: NSView, NSDraggingSource {
32+
internal let separatorView: STGutterSeparatorView
3033
internal let containerView: STGutterContainerView
3134
internal let markerContainerView: STGutterMarkerContainerView
3235

@@ -53,8 +56,14 @@ open class STGutterView: NSView, NSDraggingSource {
5356
open var textColor = NSColor.secondaryLabelColor
5457

5558
/// A Boolean indicating whether to draw a separator or not. Default true.
56-
@Invalidating(.display)
57-
open var drawSeparator: Bool = true
59+
open var drawSeparator: Bool {
60+
get {
61+
separatorView.drawSeparator
62+
}
63+
set {
64+
separatorView.drawSeparator = newValue
65+
}
66+
}
5867

5968
/// A Boolean that controls whether the text view highlights the currently selected line. Default false.
6069
@Invalidating(.display)
@@ -70,7 +79,8 @@ open class STGutterView: NSView, NSDraggingSource {
7079
backgroundEffect.blendingMode = .withinWindow
7180
backgroundEffect.material = .contentBackground
7281
backgroundEffect.state = .followsWindowActiveState
73-
addSubview(backgroundEffect, positioned: .below, relativeTo: self)
82+
// insert subview to `self`. below other subviews.
83+
self.subviews.insert(backgroundEffect, at: 0)
7484
self._backgroundEffectView = backgroundEffect
7585
} else if backgroundColor != nil, _backgroundEffectView != nil {
7686
_backgroundEffectView?.removeFromSuperview()
@@ -90,8 +100,14 @@ open class STGutterView: NSView, NSDraggingSource {
90100
/// The color of the separator.
91101
///
92102
/// Needs ``drawSeparator`` to be set to `true`.
93-
@Invalidating(.display)
94-
open var separatorColor = NSColor.separatorColor.withAlphaComponent(0.1)
103+
open var separatorColor: NSColor {
104+
get {
105+
separatorView.separatorColor
106+
}
107+
set {
108+
separatorView.separatorColor = newValue
109+
}
110+
}
95111

96112
/// The receiver’s gutter markers to markers, removing any existing ruler markers and not consulting with the client view about the new markers.
97113
@Invalidating(.markers)
@@ -113,6 +129,9 @@ open class STGutterView: NSView, NSDraggingSource {
113129
}
114130

115131
override init(frame: CGRect) {
132+
separatorView = STGutterSeparatorView(frame: frame)
133+
separatorView.autoresizingMask = [.width, .height]
134+
116135
containerView = STGutterContainerView(frame: frame)
117136
containerView.autoresizingMask = [.width, .height]
118137

@@ -123,6 +142,7 @@ open class STGutterView: NSView, NSDraggingSource {
123142
wantsLayer = true
124143
clipsToBounds = true
125144

145+
addSubview(separatorView)
126146
addSubview(containerView)
127147
addSubview(markerContainerView)
128148

@@ -185,21 +205,6 @@ open class STGutterView: NSView, NSDraggingSource {
185205
}
186206
}
187207

188-
open override func draw(_ rect: CGRect) {
189-
super.draw(rect)
190-
191-
guard let context = NSGraphicsContext.current?.cgContext else {
192-
return
193-
}
194-
195-
if drawSeparator {
196-
context.setLineWidth(1)
197-
context.setStrokeColor(separatorColor.cgColor)
198-
context.addLines(between: [CGPoint(x: frame.width - 0.5, y: 0), CGPoint(x: frame.width - 0.5, y: bounds.maxY) ])
199-
context.strokePath()
200-
}
201-
}
202-
203208
open override func mouseDown(with event: NSEvent) {
204209
if areMarkersEnabled, event.type == .leftMouseDown, event.clickCount == 1 {
205210
let eventPoint = containerView.convert(event.locationInWindow, from: nil)

0 commit comments

Comments
 (0)