work in progress on table indicators
This commit is contained in:
parent
de1b494189
commit
ee621b7993
|
|
@ -333,7 +333,7 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
|
|
||||||
private let indicatorRowHeight: CGFloat = 20
|
private let indicatorRowHeight: CGFloat = 20
|
||||||
private let indicatorColWidth: CGFloat = 30
|
private let indicatorColWidth: CGFloat = 30
|
||||||
private var indicatorsVisible = false
|
private var indicatorsVisible = true
|
||||||
private var indicatorContainer: NSView?
|
private var indicatorContainer: NSView?
|
||||||
private var focusMonitor: Any?
|
private var focusMonitor: Any?
|
||||||
|
|
||||||
|
|
@ -408,8 +408,8 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
let colCount = table.headers.count
|
let colCount = table.headers.count
|
||||||
guard colCount > 0 else { return }
|
guard colCount > 0 else { return }
|
||||||
let th = totalHeight
|
let th = totalHeight
|
||||||
let ox = indicatorOffset
|
let ox = indicatorColWidth
|
||||||
let oy = indicatorTopOffset
|
let oy = indicatorRowHeight
|
||||||
let gridWidth = columnX(for: colCount) + 1
|
let gridWidth = columnX(for: colCount) + 1
|
||||||
let fullWidth = gridWidth + ox
|
let fullWidth = gridWidth + ox
|
||||||
let fullHeight = th + oy
|
let fullHeight = th + oy
|
||||||
|
|
@ -467,10 +467,8 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
addSubview(line)
|
addSubview(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
if indicatorsVisible {
|
|
||||||
buildIndicators()
|
buildIndicators()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private func makeCell(text: String, frame: NSRect, isHeader: Bool, row: Int, col: Int) -> NSTextField {
|
private func makeCell(text: String, frame: NSRect, isHeader: Bool, row: Int, col: Int) -> NSTextField {
|
||||||
let field = NSTextField(frame: frame)
|
let field = NSTextField(frame: frame)
|
||||||
|
|
@ -510,14 +508,6 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
|
|
||||||
// MARK: - Indicators
|
// MARK: - Indicators
|
||||||
|
|
||||||
private var indicatorOffset: CGFloat {
|
|
||||||
indicatorsVisible ? indicatorColWidth : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
private var indicatorTopOffset: CGFloat {
|
|
||||||
indicatorsVisible ? indicatorRowHeight : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
private func buildIndicators() {
|
private func buildIndicators() {
|
||||||
indicatorContainer?.removeFromSuperview()
|
indicatorContainer?.removeFromSuperview()
|
||||||
|
|
||||||
|
|
@ -529,10 +519,10 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
|
|
||||||
let colCount = table.headers.count
|
let colCount = table.headers.count
|
||||||
let totalRows = 1 + table.rows.count
|
let totalRows = 1 + table.rows.count
|
||||||
let th = totalHeight + indicatorTopOffset
|
let topY = totalHeight + indicatorRowHeight
|
||||||
let indicatorBg = Theme.current.surface0
|
let indicatorBg = Theme.current.surface0
|
||||||
|
|
||||||
let corner = NSView(frame: NSRect(x: 0, y: th - indicatorRowHeight, width: indicatorColWidth, height: indicatorRowHeight))
|
let corner = NSView(frame: NSRect(x: 0, y: topY - indicatorRowHeight, width: indicatorColWidth, height: indicatorRowHeight))
|
||||||
corner.wantsLayer = true
|
corner.wantsLayer = true
|
||||||
corner.layer?.backgroundColor = indicatorBg.cgColor
|
corner.layer?.backgroundColor = indicatorBg.cgColor
|
||||||
container.addSubview(corner)
|
container.addSubview(corner)
|
||||||
|
|
@ -543,14 +533,14 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
label.font = NSFont.systemFont(ofSize: 10, weight: .medium)
|
label.font = NSFont.systemFont(ofSize: 10, weight: .medium)
|
||||||
label.textColor = Theme.current.overlay2
|
label.textColor = Theme.current.overlay2
|
||||||
label.alignment = .center
|
label.alignment = .center
|
||||||
label.frame = NSRect(x: x, y: th - indicatorRowHeight, width: columnWidths[col], height: indicatorRowHeight)
|
label.frame = NSRect(x: x, y: topY - indicatorRowHeight, width: columnWidths[col], height: indicatorRowHeight)
|
||||||
label.wantsLayer = true
|
label.wantsLayer = true
|
||||||
label.layer?.backgroundColor = indicatorBg.cgColor
|
label.layer?.backgroundColor = indicatorBg.cgColor
|
||||||
container.addSubview(label)
|
container.addSubview(label)
|
||||||
}
|
}
|
||||||
|
|
||||||
for row in 0..<totalRows {
|
for row in 0..<totalRows {
|
||||||
let y = rowY(for: row)
|
let y = rowY(for: row) + indicatorRowHeight
|
||||||
let label = NSTextField(labelWithString: "\(row + 1)")
|
let label = NSTextField(labelWithString: "\(row + 1)")
|
||||||
label.font = NSFont.systemFont(ofSize: 10, weight: .medium)
|
label.font = NSFont.systemFont(ofSize: 10, weight: .medium)
|
||||||
label.textColor = Theme.current.overlay2
|
label.textColor = Theme.current.overlay2
|
||||||
|
|
@ -565,7 +555,6 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
private func showIndicators() {
|
private func showIndicators() {
|
||||||
guard !indicatorsVisible else { return }
|
guard !indicatorsVisible else { return }
|
||||||
indicatorsVisible = true
|
indicatorsVisible = true
|
||||||
buildGrid()
|
|
||||||
NSAnimationContext.runAnimationGroup { ctx in
|
NSAnimationContext.runAnimationGroup { ctx in
|
||||||
ctx.duration = 0.2
|
ctx.duration = 0.2
|
||||||
self.indicatorContainer?.animator().alphaValue = 1
|
self.indicatorContainer?.animator().alphaValue = 1
|
||||||
|
|
@ -574,14 +563,11 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
|
|
||||||
private func hideIndicators() {
|
private func hideIndicators() {
|
||||||
guard indicatorsVisible else { return }
|
guard indicatorsVisible else { return }
|
||||||
NSAnimationContext.runAnimationGroup({ ctx in
|
indicatorsVisible = false
|
||||||
|
NSAnimationContext.runAnimationGroup { ctx in
|
||||||
ctx.duration = 0.2
|
ctx.duration = 0.2
|
||||||
self.indicatorContainer?.animator().alphaValue = 0
|
self.indicatorContainer?.animator().alphaValue = 0
|
||||||
}, completionHandler: { [weak self] in
|
}
|
||||||
guard let self = self else { return }
|
|
||||||
self.indicatorsVisible = false
|
|
||||||
self.buildGrid()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupFocusMonitoring() {
|
private func setupFocusMonitoring() {
|
||||||
|
|
@ -597,8 +583,12 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
private func checkFocusState() {
|
private func checkFocusState() {
|
||||||
guard let w = window else { return }
|
guard let w = window else { return }
|
||||||
let fr = w.firstResponder
|
let fr = w.firstResponder
|
||||||
let hasFocusedCell = cellFields.joined().contains { field in
|
var hasFocusedCell = false
|
||||||
fr === field || (fr as? NSTextView)?.delegate === field
|
if let fieldEditor = fr as? NSTextView,
|
||||||
|
let editedCell = fieldEditor.delegate as AnyObject? {
|
||||||
|
hasFocusedCell = cellFields.joined().contains { $0 === editedCell }
|
||||||
|
} else {
|
||||||
|
hasFocusedCell = cellFields.joined().contains { $0 === fr }
|
||||||
}
|
}
|
||||||
if hasFocusedCell && !indicatorsVisible {
|
if hasFocusedCell && !indicatorsVisible {
|
||||||
showIndicators()
|
showIndicators()
|
||||||
|
|
@ -612,15 +602,14 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
// MARK: - Resize hit detection
|
// MARK: - Resize hit detection
|
||||||
|
|
||||||
private func columnDivider(at point: NSPoint) -> Int? {
|
private func columnDivider(at point: NSPoint) -> Int? {
|
||||||
let ox = indicatorOffset
|
|
||||||
let colCount = table.headers.count
|
let colCount = table.headers.count
|
||||||
for i in 1..<colCount {
|
for i in 1..<colCount {
|
||||||
let divX = columnX(for: i) - 1 + ox
|
let divX = columnX(for: i) - 1 + indicatorColWidth
|
||||||
if abs(point.x - divX) <= dividerHitZone {
|
if abs(point.x - divX) <= dividerHitZone {
|
||||||
return i - 1
|
return i - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let lastX = columnX(for: colCount) + ox
|
let lastX = columnX(for: colCount) + indicatorColWidth
|
||||||
if abs(point.x - lastX) <= dividerHitZone {
|
if abs(point.x - lastX) <= dividerHitZone {
|
||||||
return colCount - 1
|
return colCount - 1
|
||||||
}
|
}
|
||||||
|
|
@ -628,14 +617,13 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func rowDivider(at point: NSPoint) -> Int? {
|
private func rowDivider(at point: NSPoint) -> Int? {
|
||||||
let oy = indicatorTopOffset
|
|
||||||
let totalRows = 1 + table.rows.count
|
let totalRows = 1 + table.rows.count
|
||||||
for i in 0..<totalRows {
|
for i in 0..<totalRows {
|
||||||
let divY: CGFloat
|
let divY: CGFloat
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
divY = totalHeight - rowHeights[0] + oy
|
divY = totalHeight - rowHeights[0] + indicatorRowHeight
|
||||||
} else {
|
} else {
|
||||||
divY = rowY(for: i) + oy
|
divY = rowY(for: i) + indicatorRowHeight
|
||||||
}
|
}
|
||||||
if abs(point.y - divY) <= dividerHitZone {
|
if abs(point.y - divY) <= dividerHitZone {
|
||||||
return i
|
return i
|
||||||
|
|
@ -680,6 +668,10 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func mouseDown(with event: NSEvent) {
|
override func mouseDown(with event: NSEvent) {
|
||||||
|
if !indicatorsVisible {
|
||||||
|
mouseInside = true
|
||||||
|
showIndicators()
|
||||||
|
}
|
||||||
let pt = convert(event.locationInWindow, from: nil)
|
let pt = convert(event.locationInWindow, from: nil)
|
||||||
if let col = columnDivider(at: pt) {
|
if let col = columnDivider(at: pt) {
|
||||||
if event.clickCount == 2 {
|
if event.clickCount == 2 {
|
||||||
|
|
@ -780,6 +772,12 @@ class MarkdownTableView: NSView, NSTextFieldDelegate {
|
||||||
|
|
||||||
// MARK: - Cell editing
|
// MARK: - Cell editing
|
||||||
|
|
||||||
|
func controlTextDidBeginEditing(_ obj: Notification) {
|
||||||
|
if !indicatorsVisible {
|
||||||
|
showIndicators()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func controlTextDidEndEditing(_ obj: Notification) {
|
func controlTextDidEndEditing(_ obj: Notification) {
|
||||||
guard let field = obj.object as? NSTextField else { return }
|
guard let field = obj.object as? NSTextField else { return }
|
||||||
let tag = field.tag
|
let tag = field.tag
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue