Skip to content

Commit 91764ef

Browse files
committed
updated
1 parent 2096909 commit 91764ef

File tree

10 files changed

+278
-105
lines changed

10 files changed

+278
-105
lines changed

Example/Example/Base.lproj/Main.storyboard

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,9 +905,9 @@ Quicklook collection items via spacebar and favorite them by right-clicking them
905905
<rect key="frame" x="0.0" y="0.0" width="220" height="556"/>
906906
<autoresizingMask key="autoresizingMask"/>
907907
<subviews>
908-
<scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="5" horizontalPageScroll="10" verticalLineScroll="5" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Imv-nG-c4J">
908+
<scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="5" horizontalPageScroll="10" verticalLineScroll="5" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="Imv-nG-c4J">
909909
<rect key="frame" x="0.0" y="253" width="220" height="245"/>
910-
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
910+
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
911911
<clipView key="contentView" drawsBackground="NO" id="Bv4-Kx-Cwg">
912912
<rect key="frame" x="0.0" y="0.0" width="220" height="245"/>
913913
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>

Example/Example/Model/OutlineItem.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@
77

88
import Foundation
99

10-
struct OutlineItem: Hashable, ExpressibleByStringLiteral {
10+
struct OutlineItem: Hashable, ExpressibleByStringLiteral, CustomStringConvertible {
1111
let title: String
1212

1313
init(_ title: String) {
1414
self.title = title
1515
}
1616

17+
var description: String {
18+
title
19+
}
20+
1721
init(stringLiteral value: String) {
1822
self.title = value
1923
}

Example/Example/OutlineSidebarViewController.swift

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,38 +21,16 @@ class OutlineSidebarViewController: NSViewController {
2121
}
2222

2323
lazy var cellRegistration = CellRegistration { tableCell, _, _, outlineItem in
24-
var configuration = NSListContentConfiguration.plain()
24+
var configuration = tableCell.defaultContentConfiguration()
2525
configuration.text = outlineItem.title
26-
27-
/// Check if the outline item is a root item and change it's font.
28-
if self.currentSnapshot.rootItems.contains(outlineItem) {
29-
configuration.textProperties.font = .body.bold
30-
}
3126
tableCell.contentConfiguration = configuration
3227
}
33-
34-
lazy var headerRegistration = CellRegistration { tableCell, _, _, outlineItem in
35-
36-
if let rowView = tableCell.rowView, rowView.isGroupRowStyle {
37-
Swift.print("groupRow", rowView.frame, rowView.subviews, rowView.backgroundColor == .controlAccentColor)
3828

39-
rowView.backgroundColor = .controlAccentColor
40-
41-
}
42-
var configuration = NSListContentConfiguration.plain()
43-
configuration.text = outlineItem.title
44-
configuration.textProperties.font = .body.bold
45-
tableCell.contentConfiguration = configuration
46-
}
47-
4829
override func viewDidLoad() {
4930
super.viewDidLoad()
5031

5132
outlineView.dataSource = dataSource
52-
outlineView.floatsGroupRows = false
53-
54-
dataSource.applyHeaderRegistration(headerRegistration)
55-
33+
5634
/// Enables reordering selected rows by dragging them.
5735
dataSource.reorderingHandlers.canReorder = { _, _ in return true }
5836

@@ -64,10 +42,9 @@ class OutlineSidebarViewController: NSViewController {
6442

6543
func applySnapshot() {
6644
var snapshot = dataSource.emptySnapshot()
67-
45+
6846
let rootItems: [OutlineItem] = ["Root 1", "Root 2", "Root 3", "Root 4", "Root 5"]
6947
snapshot.append(rootItems)
70-
7148
rootItems.forEach { rootItem in
7249
let childItems = (1...5).map { OutlineItem("\(rootItem.title).\($0)") }
7350
snapshot.append(childItems, to: rootItem)

Sources/AdvancedCollectionTableView/Configuration/Extensions/NSTableView+/NSTableCellVew+.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ extension NSTableCellView {
8484
contentView = contentConfiguration.makeContentView()
8585
translatesAutoresizingMaskIntoConstraints = false
8686
addSubview(withConstraint: contentView!)
87+
if let contentView = contentView as? NSListContentView {
88+
textField = contentView.textField
89+
imageView = contentView.imageView
90+
}
8791
}
8892
setNeedsDisplay()
8993
contentView?.setNeedsDisplay()

Sources/AdvancedCollectionTableView/DiffableDataSource/NSOutlineView/OutlineViewDiffableDataSource+Delegate.swift

Lines changed: 90 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,49 +15,35 @@ extension OutlineViewDiffableDataSource {
1515
var previousSelectedItems: [ItemIdentifierType] = []
1616

1717
func outlineView(_ outlineView: NSOutlineView, selectionIndexesForProposedSelection proposedSelectionIndexes: IndexSet) -> IndexSet {
18-
let isEmpty = proposedSelectionIndexes.isEmpty
19-
if !isEmpty, proposedSelectionIndexes.isEmpty {
20-
return outlineView.selectedRowIndexes
21-
}
22-
guard dataSource.selectionHandlers.shouldSelect != nil || dataSource.selectionHandlers.shouldDeselect != nil else {
23-
return proposedSelectionIndexes
24-
}
25-
let selectedRows = Array(outlineView.selectedRowIndexes)
26-
let proposedRows = Array(proposedSelectionIndexes)
27-
28-
let diff = selectedRows.difference(to: proposedRows)
29-
let selectedItems = diff.added.compactMap { outlineView.item(atRow: $0) } as! [ItemIdentifierType]
30-
let deselectedItems = diff.removed.compactMap { outlineView.item(atRow: $0) } as! [ItemIdentifierType]
31-
32-
var selections: [ItemIdentifierType] = selectedItems
33-
if !selectedItems.isEmpty, let shouldSelectRows = dataSource.selectionHandlers.shouldSelect?(selectedItems) {
34-
selections = selectedItems.filter({ shouldSelectRows.contains($0) })
18+
previousSelectedItems = outlineView.selectedRowIndexes.compactMap({ outlineView.item(atRow: $0) as? ItemIdentifierType })
19+
let diff = outlineView.selectedRowIndexes.difference(to: proposedSelectionIndexes)
20+
21+
var selected = diff.added.compactMap({ outlineView.item(atRow: $0) as? ItemIdentifierType })
22+
selected = selected.filter({ !self.outlineView(outlineView, isGroupItem: $0) })
23+
if !selected.isEmpty {
24+
selected = dataSource.selectionHandlers.shouldSelect?(selected) ?? selected
3525
}
3626

37-
if !deselectedItems.isEmpty, let shouldDeselectRows = dataSource.selectionHandlers.shouldDeselect?(deselectedItems) {
38-
selections += deselectedItems.filter({ !shouldDeselectRows.contains($0) })
27+
var deselected = diff.removed.compactMap({ outlineView.item(atRow: $0) as? ItemIdentifierType })
28+
if !deselected.isEmpty {
29+
let should = dataSource.selectionHandlers.shouldDeselect?(deselected) ?? deselected
30+
selected += deselected.filter({ !should.contains($0) })
31+
deselected = deselected.filter({ should.contains($0) })
3932
}
40-
41-
return IndexSet(selections.compactMap { outlineView.row(for: $0 as! NSView) })
33+
34+
return IndexSet(selected.compactMap({dataSource.row(for:$0)}) + diff.unchanged)
4235
}
4336

44-
4537
func outlineViewSelectionDidChange(_: Notification) {
46-
guard dataSource.selectionHandlers.didSelect != nil || dataSource.selectionHandlers.didDeselect != nil else {
47-
previousSelectedItems = (dataSource.outlineView.selectedItems) as! [ItemIdentifierType]
48-
return
38+
guard dataSource.selectionHandlers.didSelect != nil || dataSource.selectionHandlers.didDeselect != nil else { return }
39+
40+
let diff = previousSelectedItems.difference(to: dataSource.selectedItems)
41+
if !diff.added.isEmpty {
42+
dataSource.selectionHandlers.didSelect?(diff.added)
4943
}
50-
let selectedItems = (dataSource.outlineView.selectedItems) as! [ItemIdentifierType]
51-
let diff = previousSelectedItems.difference(to: selectedItems)
52-
53-
if !diff.added.isEmpty, let didSelect = dataSource.selectionHandlers.didSelect {
54-
didSelect(diff.added)
55-
}
56-
57-
if !diff.removed.isEmpty, let didDeselect = dataSource.selectionHandlers.didDeselect {
58-
didDeselect(diff.removed)
44+
if !diff.removed.isEmpty {
45+
dataSource.selectionHandlers.didDeselect?(diff.removed)
5946
}
60-
previousSelectedItems = selectedItems
6147
}
6248

6349
func outlineView(_ outlineView: NSOutlineView, userCanChangeVisibilityOf column: NSTableColumn) -> Bool {
@@ -69,30 +55,45 @@ extension OutlineViewDiffableDataSource {
6955
}
7056

7157
func outlineView(_ outlineView: NSOutlineView, rowViewForItem item: Any) -> NSTableRowView? {
72-
/*
73-
if self.outlineView(outlineView, isGroupItem: item) {
74-
return SectionRowView()
58+
let rowView: NSTableRowView
59+
if let view = dataSource.rowViewProvider?(outlineView, dataSource.row(for: item as! ItemIdentifierType)!, item as! ItemIdentifierType) {
60+
rowView = view
61+
} else {
62+
rowView = outlineView.makeView(withIdentifier: "_RowView", owner: self) as? NSTableRowView ?? NSTableRowView()
63+
rowView.identifier = "_RowView"
64+
}
65+
if dataSource.currentSnapshot.groupItemsAreExpandable, self.outlineView(dataSource.outlineView, isGroupItem: item) {
66+
var isExpanded = false
67+
if let item = item as? ItemIdentifierType {
68+
isExpanded = dataSource.currentSnapshot.isExpanded(item)
69+
}
70+
let button = rowView.viewWithTag(OutlineButton.tag) as? OutlineButton ?? OutlineButton(for: rowView, dataSource.outlineView)
71+
button.state = isExpanded ? .on : .off
72+
} else {
73+
rowView.viewWithTag(OutlineButton.tag)?.removeFromSuperview()
7574
}
76-
*/
77-
return dataSource.rowViewProvider?(outlineView, dataSource.row(for: item as! ItemIdentifierType)!, item as! ItemIdentifierType)
75+
return rowView
7876
}
7977

8078
func outlineView(_ outlineView: NSOutlineView, shouldExpandItem item: Any) -> Bool {
81-
dataSource.expanionHandlers.shouldExpand?(item as! ItemIdentifierType) ?? true
79+
guard !dataSource.isExpandingItems else { return true }
80+
return dataSource.expanionHandlers.shouldExpand?(item as! ItemIdentifierType) ?? true
8281
}
8382

8483
func outlineView(_ outlineView: NSOutlineView, shouldCollapseItem item: Any) -> Bool {
85-
dataSource.expanionHandlers.shouldCollapse?(item as! ItemIdentifierType) ?? true
84+
guard !dataSource.isExpandingItems else { return true }
85+
return dataSource.expanionHandlers.shouldCollapse?(item as! ItemIdentifierType) ?? true
8686
}
8787

8888
func outlineViewItemDidExpand(_ notification: Notification) {
89-
guard let item = notification.userInfo?["NSObject"] as? ItemIdentifierType else { return }
89+
guard !dataSource.isExpandingItems, let item = notification.userInfo?["NSObject"] as? ItemIdentifierType else { return }
90+
Swift.print("outlineViewItemDidExpand")
9091
dataSource.expanionHandlers.didExpand?(item)
9192
dataSource.currentSnapshot.expand([item])
9293
}
9394

9495
func outlineViewItemDidCollapse(_ notification: Notification) {
95-
guard let item = notification.userInfo?["NSObject"] as? ItemIdentifierType else { return }
96+
guard !dataSource.isExpandingItems, let item = notification.userInfo?["NSObject"] as? ItemIdentifierType else { return }
9697
dataSource.expanionHandlers.didCollapse?(item)
9798
dataSource.currentSnapshot.collapse([item])
9899
}
@@ -129,29 +130,63 @@ extension OutlineViewDiffableDataSource {
129130
}
130131

131132
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
132-
/*
133-
if self.outlineView(outlineView, isGroupItem: item), let headerCellProvider = dataSource.headerCellProvider {
134-
return headerCellProvider(outlineView, tableColumn, item as! ItemIdentifierType)
133+
let isGroupItem = self.outlineView(outlineView, isGroupItem: item)
134+
let cellView: NSView
135+
if isGroupItem, let groupRowCellProvider = dataSource.groupRowCellProvider {
136+
cellView = groupRowCellProvider(outlineView, tableColumn, item as! ItemIdentifierType)
137+
} else {
138+
cellView = dataSource.cellProvider(outlineView, tableColumn, item as! ItemIdentifierType)
135139
}
136-
*/
137-
return dataSource.cellProvider(outlineView, tableColumn, item as! ItemIdentifierType)
140+
return cellView
138141
}
139-
140-
/*
142+
143+
func outlineView(_ outlineView: NSOutlineView, shouldShowOutlineCellForItem item: Any) -> Bool {
144+
!self.outlineView(outlineView, isGroupItem: item)
145+
}
146+
141147
func outlineView(_ outlineView: NSOutlineView, isGroupItem item: Any) -> Bool {
142-
guard let item = item as? ItemIdentifierType else { return false }
148+
guard let item = item as? ItemIdentifierType, dataSource.currentSnapshot.usesGroupItems else { return false }
143149
return dataSource.currentSnapshot.rootItems.contains(item)
144-
guard let item = item as? ItemIdentifierType, dataSource.headerCellProvider != nil else { return false }
145-
return dataSource.currentSnapshot.groupItems.contains(item)
146150
}
147-
*/
151+
152+
func outlineView(_ outlineView: NSOutlineView, tintConfigurationForItem item: Any) -> NSTintConfiguration? {
153+
guard let item = item as? ItemIdentifierType else { return nil }
154+
return dataSource.tintConfigurationProvider?(item)
155+
}
148156

149157
init(_ dataSource: OutlineViewDiffableDataSource!) {
150158
self.dataSource = dataSource
151159
}
160+
161+
class OutlineButton: NSButton {
162+
init(for view: NSView, _ outlineView: NSOutlineView) {
163+
super.init(frame: .zero)
164+
title = ""
165+
bezelStyle = .disclosure
166+
sizeToFit()
167+
frame.origin = .init(x: view.bounds.width - 20, y: (view.bounds.height/2.0)-(bounds.height/2.0))
168+
target = outlineView
169+
action = NSSelectorFromString("_outlineControlClicked:")
170+
tag = Self.tag
171+
view.addSubview(self)
172+
frameObservation = observeChanges(for: \.superview?.frame) { [weak self] old, new in
173+
guard let self = self, old?.size != new?.size, let new = new?.size else { return }
174+
self.frame.origin = CGPoint(x: new.width - 20, y: (new.height/2.0)-(self.bounds.height/2.0))
175+
}
176+
}
177+
178+
static var tag: Int { 3345665333 }
179+
180+
required init?(coder: NSCoder) {
181+
fatalError("init(coder:) has not been implemented")
182+
}
183+
184+
var frameObservation: KeyValueObservation?
185+
}
152186
}
153187
}
154188

189+
155190
/*
156191
extension OutlineViewDiffableDataSource {
157192
class SectionRowView: NSTableRowView {

0 commit comments

Comments
 (0)