@@ -15,49 +15,35 @@ extension OutlineViewDiffableDataSource {
15
15
var previousSelectedItems : [ ItemIdentifierType ] = [ ]
16
16
17
17
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
35
25
}
36
26
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) } )
39
32
}
40
-
41
- return IndexSet ( selections . compactMap { outlineView . row ( for: $0 as! NSView ) } )
33
+
34
+ return IndexSet ( selected . compactMap ( { dataSource . row ( for: $0 ) } ) + diff . unchanged )
42
35
}
43
36
44
-
45
37
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)
49
43
}
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)
59
46
}
60
- previousSelectedItems = selectedItems
61
47
}
62
48
63
49
func outlineView( _ outlineView: NSOutlineView , userCanChangeVisibilityOf column: NSTableColumn ) -> Bool {
@@ -69,30 +55,45 @@ extension OutlineViewDiffableDataSource {
69
55
}
70
56
71
57
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 ( )
75
74
}
76
- */
77
- return dataSource. rowViewProvider ? ( outlineView, dataSource. row ( for: item as! ItemIdentifierType ) !, item as! ItemIdentifierType )
75
+ return rowView
78
76
}
79
77
80
78
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
82
81
}
83
82
84
83
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
86
86
}
87
87
88
88
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 " )
90
91
dataSource. expanionHandlers. didExpand ? ( item)
91
92
dataSource. currentSnapshot. expand ( [ item] )
92
93
}
93
94
94
95
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 }
96
97
dataSource. expanionHandlers. didCollapse ? ( item)
97
98
dataSource. currentSnapshot. collapse ( [ item] )
98
99
}
@@ -129,29 +130,63 @@ extension OutlineViewDiffableDataSource {
129
130
}
130
131
131
132
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 )
135
139
}
136
- */
137
- return dataSource. cellProvider ( outlineView, tableColumn, item as! ItemIdentifierType )
140
+ return cellView
138
141
}
139
-
140
- /*
142
+
143
+ func outlineView( _ outlineView: NSOutlineView , shouldShowOutlineCellForItem item: Any ) -> Bool {
144
+ !self . outlineView ( outlineView, isGroupItem: item)
145
+ }
146
+
141
147
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 }
143
149
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)
146
150
}
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
+ }
148
156
149
157
init ( _ dataSource: OutlineViewDiffableDataSource ! ) {
150
158
self . dataSource = dataSource
151
159
}
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
+ }
152
186
}
153
187
}
154
188
189
+
155
190
/*
156
191
extension OutlineViewDiffableDataSource {
157
192
class SectionRowView: NSTableRowView {
0 commit comments