Skip to content

Commit 264e99f

Browse files
committed
updated
1 parent a0849f7 commit 264e99f

File tree

13 files changed

+254
-82
lines changed

13 files changed

+254
-82
lines changed

Example/Example/Base.lproj/Main.storyboard

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ 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" id="Imv-nG-c4J">
908+
<scrollView 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"/>
910910
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
911911
<clipView key="contentView" drawsBackground="NO" id="Bv4-Kx-Cwg">

Example/Example/OutlineSidebarViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class OutlineSidebarViewController: NSViewController {
2121
}
2222

2323
lazy var cellRegistration = CellRegistration { tableCell, _, _, outlineItem in
24-
var configuration = tableCell.defaultContentConfiguration()
24+
var configuration = NSListContentConfiguration.sidebar()
2525
configuration.text = outlineItem.title
2626
tableCell.contentConfiguration = configuration
2727
}

Example/Example/TableSidebarViewController.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ class TableSidebarViewController: NSViewController {
4545

4646
/// Enables deleting selected rows via backspace key.
4747
dataSource.deletingHandlers.canDelete = { selectedItems in return selectedItems }
48-
dataSource.deletingHandlers.isDeletableByDraggingOutside = true
48+
49+
dataSource.draggingHandlers.canDrag = { items in return true }
50+
dataSource.draggingHandlers.pasteboardContent = { item in return ["Fun"] }
4951

5052
/// Swipe row actions for deleting and favoriting an item.
5153
dataSource.rowActionProvider = { swippedItem, edge in

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ extension NSTableCellView {
8585
translatesAutoresizingMaskIntoConstraints = false
8686
addSubview(withConstraint: contentView!)
8787
if let contentView = contentView as? NSListContentView {
88-
textField = contentView.textField
89-
imageView = contentView.imageView
88+
// textField = contentView.textField
89+
// imageView = contentView.imageView
9090
}
9191
}
9292
setNeedsDisplay()

Sources/AdvancedCollectionTableView/DiffableDataSource/NSOutlineView/CellOutlineVItem.swift

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,66 @@
55
// Created by Florian Zand on 20.01.25.
66
//
77

8+
import AppKit
9+
10+
/*
11+
public protocol OutlineItemObject: AnyObject, Hashable {
12+
/// The parent of the item.
13+
var parent: Self? { get set }
14+
15+
/// The children of the item.
16+
var children: [Self] { get set }
17+
18+
/**
19+
A Boolean value indicating whether the item is expanded.
20+
21+
The default value is `true`.
22+
*/
23+
var isExpanded: Bool { get set }
24+
25+
/**
26+
A Boolean value indicating whether the item can be expanded / collapsed by the user.
27+
28+
The default value is `true`.
29+
*/
30+
var isExpandable: Bool { get }
31+
32+
/**
33+
A Boolean value indicating whether the item can be selected.
34+
35+
The default value is `true`.
36+
*/
37+
var isSelectable: Bool { get }
38+
39+
/**
40+
A Boolean value indicating whether the item can be deleted by the user pressing `Backspace`.
41+
42+
The default value is `false`.
43+
*/
44+
var isDeletable: Bool { get }
45+
46+
/**
47+
A Boolean value indicating whether the item can be reorded.
48+
49+
The default value is `false`.
50+
*/
51+
var isReordable: Bool { get }
52+
}
53+
54+
55+
extension OutlineItemObject {
56+
public var isExpandable: Bool { !children.isEmpty }
57+
public var isSelectable: Bool { true }
58+
public var isDeletable: Bool { false }
59+
public var isReordable: Bool { false }
60+
61+
/// Checks if the specified item is a children of the items or the items children.
62+
public func contains(_ item: Self) -> Bool {
63+
children.contains(item) || children.contains(where: { $0.contains($0) })
64+
}
65+
}
66+
*/
67+
868
/*
969
import AppKit
1070

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

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,26 @@ extension OutlineViewDiffableDataSource {
5555
}
5656

5757
func outlineView(_ outlineView: NSOutlineView, rowViewForItem item: Any) -> NSTableRowView? {
58+
let isGroupItem = self.outlineView(dataSource.outlineView, isGroupItem: item)
5859
let rowView: NSTableRowView
5960
if let view = dataSource.rowViewProvider?(outlineView, dataSource.row(for: item as! ItemIdentifierType)!, item as! ItemIdentifierType) {
6061
rowView = view
6162
} else {
62-
rowView = outlineView.makeView(withIdentifier: "_RowView", owner: self) as? NSTableRowView ?? NSTableRowView()
63-
rowView.identifier = "_RowView"
63+
rowView = outlineView.makeView(withIdentifier: isGroupItem ? "_GroupRowView" : "_RowView", owner: self) as? NSTableRowView ?? NSTableRowView()
64+
rowView.identifier = isGroupItem ? "_GroupRowView" : "_RowView"
65+
/*
66+
if self.outlineView(dataSource.outlineView, isGroupItem: item) {
67+
let groupRowView = outlineView.makeView(withIdentifier: "GroupItemRowView", owner: nil) as? GroupItemRowView ?? GroupItemRowView()
68+
groupRowView.setup()
69+
rowView = groupRowView
70+
rowView.identifier = "GroupItemRowView"
71+
} else {
72+
rowView = outlineView.makeView(withIdentifier: "_RowView", owner: self) as? NSTableRowView ?? NSTableRowView()
73+
rowView.identifier = "_RowView"
74+
}
75+
*/
6476
}
65-
if !dataSource.currentSnapshot.groupItems.isAlwaysExpanded, self.outlineView(dataSource.outlineView, isGroupItem: item) {
77+
if !dataSource.currentSnapshot.groupItems.isAlwaysExpanded, isGroupItem {
6678
var isExpanded = false
6779
if let item = item as? ItemIdentifierType {
6880
isExpanded = dataSource.currentSnapshot.isExpanded(item)
@@ -76,23 +88,23 @@ extension OutlineViewDiffableDataSource {
7688
}
7789

7890
func outlineView(_ outlineView: NSOutlineView, shouldExpandItem item: Any) -> Bool {
79-
guard !dataSource.isExpandingItems else { return true }
91+
guard !dataSource.isApplyingSnapshot else { return true }
8092
return dataSource.expanionHandlers.shouldExpand?(item as! ItemIdentifierType) ?? true
8193
}
8294

8395
func outlineView(_ outlineView: NSOutlineView, shouldCollapseItem item: Any) -> Bool {
84-
guard !dataSource.isExpandingItems else { return true }
96+
guard !dataSource.isApplyingSnapshot else { return true }
8597
return dataSource.expanionHandlers.shouldCollapse?(item as! ItemIdentifierType) ?? true
8698
}
8799

88100
func outlineViewItemDidExpand(_ notification: Notification) {
89-
guard !dataSource.isExpandingItems, let item = notification.userInfo?["NSObject"] as? ItemIdentifierType else { return }
101+
guard !dataSource.isApplyingSnapshot, let item = notification.userInfo?["NSObject"] as? ItemIdentifierType else { return }
90102
dataSource.expanionHandlers.didExpand?(item)
91103
dataSource.currentSnapshot.expand([item])
92104
}
93105

94106
func outlineViewItemDidCollapse(_ notification: Notification) {
95-
guard !dataSource.isExpandingItems, let item = notification.userInfo?["NSObject"] as? ItemIdentifierType else { return }
107+
guard !dataSource.isApplyingSnapshot, let item = notification.userInfo?["NSObject"] as? ItemIdentifierType else { return }
96108
dataSource.expanionHandlers.didCollapse?(item)
97109
dataSource.currentSnapshot.collapse([item])
98110
}
@@ -139,9 +151,11 @@ extension OutlineViewDiffableDataSource {
139151
return cellView
140152
}
141153

154+
/*
142155
func outlineView(_ outlineView: NSOutlineView, shouldShowOutlineCellForItem item: Any) -> Bool {
143156
!self.outlineView(outlineView, isGroupItem: item)
144157
}
158+
*/
145159

146160
func outlineView(_ outlineView: NSOutlineView, isGroupItem item: Any) -> Bool {
147161
guard let item = item as? ItemIdentifierType, dataSource.currentSnapshot.groupItems.isEnabled else { return false }
@@ -228,3 +242,29 @@ extension OutlineViewDiffableDataSource {
228242
}
229243
}
230244
*/
245+
246+
/*
247+
class GroupItemRowView: NSTableRowView {
248+
var frameObservation: KeyValueObservation?
249+
func setup() {
250+
guard frameObservation == nil else { return }
251+
isGroupRowStyle = true
252+
frameObservation = observeChanges(for: \.superview?.frame) { [weak self] old, new in
253+
guard let self = self, let new = new else { return }
254+
Swift.print("heree", new)
255+
// self.frame.size.width = new.width
256+
}
257+
}
258+
259+
override var frame: NSRect {
260+
didSet {
261+
guard oldValue != frame else { return }
262+
Swift.print("row", frame)
263+
if let superview = superview {
264+
// frame.size.width = superview.bounds.width
265+
}
266+
267+
}
268+
}
269+
}
270+
*/

Sources/AdvancedCollectionTableView/DiffableDataSource/NSOutlineView/OutlineViewDiffableDataSource.swift

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public class OutlineViewDiffableDataSource<ItemIdentifierType: Hashable>: NSObje
5151
var draggedItems: [ItemIdentifierType] = []
5252
var draggedParent: ItemIdentifierType?
5353
var draggedIndexes: [Int] = []
54-
var isExpandingItems = false
54+
var isApplyingSnapshot = false
5555

5656
/// The closure that configures and returns the outline view’s row views from the diffable data source.
5757
open var rowViewProvider: RowViewProvider?
@@ -510,14 +510,14 @@ public class OutlineViewDiffableDataSource<ItemIdentifierType: Hashable>: NSObje
510510
- completion: An optional completion handler which gets called after applying the snapshot. The system calls this closure from the main queue.
511511
*/
512512
public func apply(_ snapshot: OutlineViewDiffableDataSourceSnapshot<ItemIdentifierType>, _ option: NSDiffableDataSourceSnapshotApplyOption = .animated, completion: (() -> Void)? = nil) {
513-
isExpandingItems = true
513+
isApplyingSnapshot = true
514514
let current = currentSnapshot
515515
let previousIsEmpty = currentSnapshot.items.isEmpty
516516
currentSnapshot = snapshot
517-
518-
outlineView.apply(snapshot, currentSnapshot: current, option: option, animation: defaultRowAnimation, completion: completion)
517+
outlineView.apply(snapshot, currentSnapshot: current, option: option, animation: defaultRowAnimation, completion: completion)
518+
updateEmptyView(previousIsEmpty: previousIsEmpty)
519519
updateEmptyView(previousIsEmpty: previousIsEmpty)
520-
isExpandingItems = false
520+
isApplyingSnapshot = false
521521
}
522522

523523
public func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
@@ -535,7 +535,7 @@ public class OutlineViewDiffableDataSource<ItemIdentifierType: Hashable>: NSObje
535535
}
536536

537537
public func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
538-
currentSnapshot.isExpandable(item as! ItemIdentifierType)
538+
!currentSnapshot.children(of: item as! ItemIdentifierType).isEmpty
539539
}
540540

541541
public func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItems draggedItems: [Any]) {
@@ -586,7 +586,7 @@ public class OutlineViewDiffableDataSource<ItemIdentifierType: Hashable>: NSObje
586586
public var groupItems: GroupItemOption = .none
587587

588588
func updateGroupItems(reload: Bool = false) {
589-
isExpandingItems = true
589+
isApplyingSnapshot = true
590590
if reload {
591591
reloadItems(currentSnapshot.rootItems)
592592
}
@@ -649,7 +649,7 @@ public class OutlineViewDiffableDataSource<ItemIdentifierType: Hashable>: NSObje
649649
Swift.print("CHECK", currentSnapshot.rootItems.filter({ outlineView.isItemExpanded($0) }))
650650
}
651651
}
652-
isExpandingItems = false
652+
isApplyingSnapshot = false
653653
}
654654
*/
655655

@@ -663,12 +663,16 @@ public class OutlineViewDiffableDataSource<ItemIdentifierType: Hashable>: NSObje
663663
if index == -1, delegate.outlineView(outlineView, isGroupItem: item) {
664664
return []
665665
}
666+
if let item = item as? ItemIdentifierType, draggedItems.contains(where: { currentSnapshot.isDescendant(item, of: $0) }) {
667+
return []
668+
}
669+
666670
/*
667671
if index == -1, !draggedIndexes.isEmpty, (draggedParent == item as? ItemIdentifierType) || (draggedParent == nil && item == nil) {
668672
return []
669673
}
670674
*/
671-
return reorderingHandlers.canReorder?(draggedItems, item as? ItemIdentifierType) == true ? .move : []
675+
return reorderingHandlers.canReorder?(draggedItems, item as? ItemIdentifierType) ?? true == true ? .move : []
672676
}
673677

674678
public func outlineView(_ outlineView: NSOutlineView, acceptDrop info: any NSDraggingInfo, item: Any?, childIndex index: Int) -> Bool {

Sources/AdvancedCollectionTableView/DiffableDataSource/NSOutlineView/Snapshot/OutlineChangeInstruction.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extension OutlineViewDiffableDataSourceSnapshot {
3333
func instructions(forMorphingTo newSnapshot: OutlineViewDiffableDataSourceSnapshot) -> [OutlineChangeInstruction] {
3434
var movedItems: Set<ItemIdentifierType> = []
3535
var work = self
36+
work.isCalculatingDiff = true
3637
func calculateSteps(from source: [ItemIdentifierType], to destination: [ItemIdentifierType], parent: ItemIdentifierType? = nil) -> [OutlineChangeInstruction] {
3738
var instructions: [OutlineChangeInstruction] = []
3839
for step in destination.difference(from: source).steps {
@@ -45,14 +46,15 @@ extension OutlineViewDiffableDataSourceSnapshot {
4546
work.move([item], toIndex: index, of: parent)
4647
} else {
4748
instructions.append(.insert(item, at: index, parent: parent))
48-
work.insert(item, newSnapshot.nodes[item]!, at: index, of: parent)
49+
work.insert(item, at: index, of: parent)
4950
}
5051
case .remove(let item, let index):
5152
if let toIndex = newSnapshot.childIndex(of: item) {
5253
guard !movedItems.contains(item) else { continue }
5354
movedItems.insert(item)
54-
instructions.append(.move(item, from: index, work.parent(of: item), to: toIndex, parent))
55-
work.move([item], toIndex: toIndex, of: parent)
55+
let newParent = newSnapshot.parent(of: item)
56+
instructions.append(.move(item, from: index, work.parent(of: item), to: toIndex, newParent))
57+
work.move([item], toIndex: toIndex, of: newParent)
5658
} else {
5759
instructions.append(.remove(item, at: index, parent: parent))
5860
work.delete([item])
@@ -68,6 +70,10 @@ extension OutlineViewDiffableDataSourceSnapshot {
6870
return instructions
6971
}
7072
let instructions = calculateSteps(from: rootItems, to: newSnapshot.rootItems)
73+
Swift.print("------")
74+
for step in instructions {
75+
Swift.print(step)
76+
}
7177
return instructions
7278
}
7379
}

Sources/AdvancedCollectionTableView/DiffableDataSource/NSOutlineView/Snapshot/OutlineViewDiffableDataSourceSnapshot+Node.swift

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,32 @@
77

88
import Foundation
99

10-
/// An outline view node.
10+
/**
11+
A outline node that can be used to construct the items of a `OutlineViewDiffableDataSourceSnapshot`.
12+
13+
Example usage:
14+
```swift
15+
var snapshot = OutlineViewDiffableDataSourceSnapshot<String> {
16+
OutlineNode("Food") {
17+
OutlineNode("Root 1 Child 1")
18+
OutlineNode("Root 1 Child 2")
19+
OutlineNode("Root 1 Child 3")
20+
}.isExpanded(true)
21+
OutlineNode("Root 2")
22+
OutlineNode("Root 3") {
23+
OutlineNode("Root 3 Child 1")
24+
OutlineNode("Root 3 Child 2")
25+
}
26+
}
27+
```
28+
*/
1129
public struct OutlineNode<ItemIdentifierType: Hashable> {
1230
/// The item of the node.
1331
public let item: ItemIdentifierType
1432

1533
/// The children of the node.
1634
public let children: [OutlineNode]
17-
35+
1836
/// A Boolean value indicating whether the item of the node is expanded.
1937
public let isExpanded: Bool
2038

@@ -23,6 +41,13 @@ public struct OutlineNode<ItemIdentifierType: Hashable> {
2341
.init(item, children: children, isExpanded: isExpanded)
2442
}
2543

44+
/*
45+
/// A Boolean value indicating whether the node contains the item.
46+
public func contains(_ item: ItemIdentifierType) -> Bool {
47+
children.contains(where: { $0.item == item || $0.contains(item) })
48+
}
49+
*/
50+
2651
/// Creates a node with the specified item.
2752
public init(_ item: ItemIdentifierType) {
2853
self.item = item

0 commit comments

Comments
 (0)