Skip to content

Commit

Permalink
Separate gutter separator view from STGutterView
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
krzyzanowskim committed Jan 9, 2025
1 parent a85d9ed commit 773da40
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 20 deletions.
31 changes: 31 additions & 0 deletions Sources/STTextViewAppKit/Gutter/STGutterSeparatorView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Created by Marcin Krzyzanowski
// https://github.com/krzyzanowskim/STTextView/blob/main/LICENSE.md

import Cocoa

class STGutterSeparatorView: NSView {
@Invalidating(.display)
var drawSeparator: Bool = true

@Invalidating(.display)
var separatorColor = NSColor.separatorColor.withAlphaComponent(0.1)

override var isFlipped: Bool {
true
}

override func draw(_ rect: CGRect) {
super.draw(rect)

guard let context = NSGraphicsContext.current?.cgContext else {
return
}

if drawSeparator {
context.setLineWidth(1)
context.setStrokeColor(separatorColor.cgColor)
context.addLines(between: [CGPoint(x: frame.width - 0.5, y: 0), CGPoint(x: frame.width - 0.5, y: bounds.maxY) ])
context.strokePath()
}
}
}
45 changes: 25 additions & 20 deletions Sources/STTextViewAppKit/Gutter/STGutterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// https://github.com/krzyzanowskim/STTextView/blob/main/LICENSE.md
//
// STGutterView
// |- NSVisualEffectView
// |- STGutterContainerView
// |- STGutterSeparatorView
// |-STGutterLineNumberCell
// |- STGutterMarkerContainerView
// |-STGutterMarker.view
Expand All @@ -27,6 +29,7 @@ public extension STGutterViewDelegate {

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

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

/// A Boolean indicating whether to draw a separator or not. Default true.
@Invalidating(.display)
open var drawSeparator: Bool = true
open var drawSeparator: Bool {
get {
separatorView.drawSeparator
}
set {
separatorView.drawSeparator = newValue
}
}

/// A Boolean that controls whether the text view highlights the currently selected line. Default false.
@Invalidating(.display)
Expand All @@ -70,7 +79,8 @@ open class STGutterView: NSView, NSDraggingSource {
backgroundEffect.blendingMode = .withinWindow
backgroundEffect.material = .contentBackground
backgroundEffect.state = .followsWindowActiveState
addSubview(backgroundEffect, positioned: .below, relativeTo: self)
// insert subview to `self`. below other subviews.
self.subviews.insert(backgroundEffect, at: 0)
self._backgroundEffectView = backgroundEffect
} else if backgroundColor != nil, _backgroundEffectView != nil {
_backgroundEffectView?.removeFromSuperview()
Expand All @@ -90,8 +100,14 @@ open class STGutterView: NSView, NSDraggingSource {
/// The color of the separator.
///
/// Needs ``drawSeparator`` to be set to `true`.
@Invalidating(.display)
open var separatorColor = NSColor.separatorColor.withAlphaComponent(0.1)
open var separatorColor: NSColor {
get {
separatorView.separatorColor
}
set {
separatorView.separatorColor = newValue
}
}

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

override init(frame: CGRect) {
separatorView = STGutterSeparatorView(frame: frame)
separatorView.autoresizingMask = [.width, .height]

containerView = STGutterContainerView(frame: frame)
containerView.autoresizingMask = [.width, .height]

Expand All @@ -123,6 +142,7 @@ open class STGutterView: NSView, NSDraggingSource {
wantsLayer = true
clipsToBounds = true

addSubview(separatorView)
addSubview(containerView)
addSubview(markerContainerView)

Expand Down Expand Up @@ -185,21 +205,6 @@ open class STGutterView: NSView, NSDraggingSource {
}
}

open override func draw(_ rect: CGRect) {
super.draw(rect)

guard let context = NSGraphicsContext.current?.cgContext else {
return
}

if drawSeparator {
context.setLineWidth(1)
context.setStrokeColor(separatorColor.cgColor)
context.addLines(between: [CGPoint(x: frame.width - 0.5, y: 0), CGPoint(x: frame.width - 0.5, y: bounds.maxY) ])
context.strokePath()
}
}

open override func mouseDown(with event: NSEvent) {
if areMarkersEnabled, event.type == .leftMouseDown, event.clickCount == 1 {
let eventPoint = containerView.convert(event.locationInWindow, from: nil)
Expand Down

0 comments on commit 773da40

Please sign in to comment.