82 lines
3.3 KiB
Swift
82 lines
3.3 KiB
Swift
import AppKit
|
|
|
|
/// SPEC §9 — page thumbnail sidebar. Thumbnails are low-resolution; the canvas
|
|
/// always uses the full-resolution `CGImage`.
|
|
|
|
final class ThumbnailSidebarView: NSView, NSTableViewDataSource, NSTableViewDelegate {
|
|
var pages: [TargetPage] = [] {
|
|
didSet { table.reloadData() }
|
|
}
|
|
var selectedIndex: Int = 0 {
|
|
didSet {
|
|
if selectedIndex >= 0, selectedIndex < pages.count {
|
|
table.selectRowIndexes(IndexSet(integer: selectedIndex), byExtendingSelection: false)
|
|
}
|
|
}
|
|
}
|
|
var onSelect: ((Int) -> Void)?
|
|
var onRemove: ((Int) -> Void)?
|
|
|
|
private let table = NSTableView()
|
|
private let scroll = NSScrollView()
|
|
|
|
override init(frame frameRect: NSRect) {
|
|
super.init(frame: frameRect)
|
|
let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("page"))
|
|
column.title = "Pages"
|
|
table.addTableColumn(column)
|
|
table.headerView = nil
|
|
table.rowHeight = 88
|
|
table.delegate = self
|
|
table.dataSource = self
|
|
table.selectionHighlightStyle = .regular
|
|
table.allowsEmptySelection = false
|
|
table.backgroundColor = NSColor.controlBackgroundColor
|
|
|
|
scroll.documentView = table
|
|
scroll.hasVerticalScroller = true
|
|
scroll.borderType = .noBorder
|
|
scroll.translatesAutoresizingMaskIntoConstraints = false
|
|
addSubview(scroll)
|
|
NSLayoutConstraint.activate([
|
|
scroll.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
scroll.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
scroll.topAnchor.constraint(equalTo: topAnchor),
|
|
scroll.bottomAnchor.constraint(equalTo: bottomAnchor),
|
|
])
|
|
}
|
|
|
|
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
|
|
|
func numberOfRows(in tableView: NSTableView) -> Int { pages.count }
|
|
|
|
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
|
let page = pages[row]
|
|
let cell = NSTableCellView()
|
|
let imageView = NSImageView(image: page.thumbnail)
|
|
imageView.imageScaling = .scaleProportionallyDown
|
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
|
let label = NSTextField(labelWithString: "\(row + 1) \(page.name)")
|
|
label.font = NSFont.systemFont(ofSize: 11)
|
|
label.lineBreakMode = .byTruncatingMiddle
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
cell.addSubview(imageView)
|
|
cell.addSubview(label)
|
|
NSLayoutConstraint.activate([
|
|
imageView.leadingAnchor.constraint(equalTo: cell.leadingAnchor, constant: 8),
|
|
imageView.centerYAnchor.constraint(equalTo: cell.centerYAnchor),
|
|
imageView.widthAnchor.constraint(equalToConstant: 56),
|
|
imageView.heightAnchor.constraint(equalToConstant: 72),
|
|
label.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: 8),
|
|
label.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: -8),
|
|
label.centerYAnchor.constraint(equalTo: cell.centerYAnchor),
|
|
])
|
|
return cell
|
|
}
|
|
|
|
func tableViewSelectionDidChange(_ notification: Notification) {
|
|
let row = table.selectedRow
|
|
if row >= 0 { onSelect?(row) }
|
|
}
|
|
}
|