@@ -115,342 +115,3 @@ extension NSOutlineView {
115
115
}
116
116
}
117
117
}
118
-
119
- /*
120
- fileprivate extension Array where Element: Hashable {
121
- func insertIndex(for element: Element, of other: [Element]) -> Int {
122
- let indexMap = Dictionary(uniqueKeysWithValues: other.enumerated().map { ($1, $0) })
123
- guard let targetIndex = indexMap[element] else { return 0 }
124
- for (i, item) in self.enumerated() {
125
- if let indexInOther = indexMap[item], indexInOther > targetIndex {
126
- return i
127
- }
128
- }
129
- return count
130
- }
131
- }
132
-
133
- func instructionsAlt1(forMorphingTo newSnapshot: OutlineViewDiffableDataSourceSnapshot) -> [OutlineChangeInstruction] {
134
- var work = self
135
- var result: [OutlineChangeInstruction] = []
136
- // let items = Set(items)
137
- // let newItems = Set(newSnapshot.items)
138
- let items = orderedItems
139
- let newItems = newSnapshot.orderedItems
140
- let added = newItems.subtracting(items)
141
- var removed = items.subtracting(newItems)
142
- var moved = newItems
143
-
144
- moved = moved.filter({
145
- guard let node = nodes[$0], let newNode = newSnapshot.nodes[$0] else { return false }
146
- return node.parent != newNode.parent || node.children.firstIndex(of: $0) != newNode.children.firstIndex(of: $0)
147
- })
148
-
149
-
150
-
151
- for remove in removed {
152
- if let parent = work.parent(of: remove), let index = work.childIndex(of: remove) {
153
- result.append(.remove(remove, at: index, parent: parent))
154
- } else if let index = work.rootItems.firstIndex(of: remove) {
155
- result.append(.remove(remove, at: index, parent: nil))
156
- }
157
- work.delete([remove])
158
- }
159
- for add in added {
160
- if let parent = newSnapshot.parent(of: add) {
161
- let index = work.children(of: parent).insertIndex(for: add, of: newSnapshot.children(of: parent))
162
- result.append(.insert(add, at: index, parent: parent))
163
- work.insert(add, newSnapshot.nodes[add]!, at: index, of: parent)
164
- } else {
165
- let index = work.rootItems.insertIndex(for: add, of: newSnapshot.rootItems)
166
- result.append(.insert(add, at: index, parent: nil))
167
- work.insert(add, newSnapshot.nodes[add]!, at: index, of: nil)
168
- }
169
- }
170
- for move in moved {
171
- func moveItem(_ fromIndex: Int, _ fromParent: ItemIdentifierType? = nil) {
172
- if let toParent = newSnapshot.parent(of: move) {
173
- let index = work.children(of: toParent).insertIndex(for: move, of: newSnapshot.children(of: toParent))
174
- result.append(.move(move, from: fromIndex, fromParent, to: index, toParent))
175
- work.move([move], toIndex: index, of: toParent)
176
- } else {
177
- let index = work.rootItems.insertIndex(for: move, of: newSnapshot.rootItems)
178
- result.append(.move(move, from: fromIndex, fromParent, to: index, nil))
179
- work.move([move], toIndex: index, of: nil)
180
- }
181
- }
182
- if let fromParent = work.parent(of: move), let fromIndex = work.childIndex(of: move) {
183
- moveItem(fromIndex, fromParent)
184
- } else if let fromIndex = work.rootItems.firstIndex(of: move) {
185
- moveItem(fromIndex)
186
- }
187
- }
188
- return result
189
- }
190
-
191
- func instructionsAlt3(forMorphingTo newSnapshot: OutlineViewDiffableDataSourceSnapshot) -> [OutlineChangeInstruction] {
192
- var work = self
193
- var result: [OutlineChangeInstruction] = []
194
- // let items = Set(items)
195
- // let newItems = Set(newSnapshot.items)
196
- let items = orderedItems
197
- let newItems = newSnapshot.orderedItems
198
- var added = newItems.filter({ !items.contains($0) })
199
- var removed = items.filter({ !newItems.contains($0) })
200
- var moved = newItems
201
-
202
- /*
203
- Swift.print("-----------")
204
- Swift.print("added")
205
- for item in added {
206
- Swift.print(item)
207
- }
208
- Swift.print("-----------")
209
- */
210
-
211
-
212
- moved = moved.filter({
213
- guard let node = nodes[$0], let newNode = newSnapshot.nodes[$0] else { return false }
214
- return node.parent != newNode.parent || node.children.firstIndex(of: $0) != newNode.children.firstIndex(of: $0)
215
- })
216
-
217
- func addItem(_ add: ItemIdentifierType) {
218
- if let parent = newSnapshot.parent(of: add) {
219
- let index = work.children(of: parent).insertIndex(for: add, of: newSnapshot.children(of: parent))
220
- result.append(.insert(add, at: index, parent: parent))
221
- work.insert(add, newSnapshot.nodes[add]!, at: index, of: parent)
222
- } else {
223
- let index = work.rootItems.insertIndex(for: add, of: newSnapshot.rootItems)
224
- result.append(.insert(add, at: index, parent: nil))
225
- work.insert(add, newSnapshot.nodes[add]!, at: index, of: nil)
226
- }
227
- }
228
-
229
- func removeItem(_ remove: ItemIdentifierType) {
230
- if let parent = work.parent(of: remove), let index = work.childIndex(of: remove) {
231
- result.append(.remove(remove, at: index, parent: parent))
232
- } else if let index = work.rootItems.firstIndex(of: remove) {
233
- result.append(.remove(remove, at: index, parent: nil))
234
- }
235
- work.delete([remove])
236
- }
237
-
238
- func _moveItem(_ move: ItemIdentifierType) {
239
- func moveItem(_ fromIndex: Int, _ fromParent: ItemIdentifierType? = nil) {
240
- if let toParent = newSnapshot.parent(of: move) {
241
- let index = work.children(of: toParent).insertIndex(for: move, of: newSnapshot.children(of: toParent))
242
- result.append(.move(move, from: fromIndex, fromParent, to: index, toParent))
243
- work.move([move], toIndex: index, of: toParent)
244
- } else {
245
- let index = work.rootItems.insertIndex(for: move, of: newSnapshot.rootItems)
246
- result.append(.move(move, from: fromIndex, fromParent, to: index, nil))
247
- work.move([move], toIndex: index, of: nil)
248
- }
249
- }
250
- if let fromParent = work.parent(of: move), let fromIndex = work.childIndex(of: move) {
251
- moveItem(fromIndex, fromParent)
252
- } else if let fromIndex = work.rootItems.firstIndex(of: move) {
253
- moveItem(fromIndex)
254
- }
255
- }
256
-
257
- func check(_ parent: ItemIdentifierType?) {
258
- var remove = removed.first
259
- while let toRemove = remove, work.parent(of: toRemove) == parent {
260
- removeItem(toRemove)
261
- removed.removeFirst()
262
- remove = removed.first
263
- }
264
- var add = added.first
265
- while let toAdd = add, newSnapshot.parent(of: toAdd) == parent {
266
- addItem(toAdd)
267
- added.removeFirst()
268
- add = added.first
269
- }
270
- var move = moved.first
271
- while let toMove = move, newSnapshot.parent(of: toMove) == parent {
272
- _moveItem(toMove)
273
- moved.removeFirst()
274
- move = moved.first
275
- }
276
- if let parent = parent {
277
- let childs = newSnapshot.children(of: parent)
278
- if !childs.isEmpty {
279
- childs.forEach({ check($0) })
280
- } else if !removed.isEmpty || !added.isEmpty || !moved.isEmpty {
281
- check(nil)
282
- }
283
- } else {
284
- let childs = newSnapshot.rootItems
285
- if !childs.isEmpty {
286
- childs.forEach({ check($0) })
287
- } else if !removed.isEmpty || !added.isEmpty || !moved.isEmpty {
288
- check(nil)
289
- }
290
- }
291
- }
292
-
293
- check(nil)
294
- return result
295
- }
296
-
297
- func diff(from oldSnapshot: OutlineViewDiffableDataSourceSnapshot) -> [OutlineChangeInstruction] {
298
- var instructions: [OutlineChangeInstruction] = []
299
- var processedItems: Set<ItemIdentifierType> = []
300
-
301
- // Helper function to compare children recursively
302
- func compareChildren(oldChildren: [ItemIdentifierType], newChildren: [ItemIdentifierType], parent: ItemIdentifierType?) {
303
-
304
- var oldIndexMap = Dictionary(uniqueKeysWithValues: oldChildren.enumerated().map { ($1, $0) })
305
- var newIndexMap = Dictionary(uniqueKeysWithValues: newChildren.enumerated().map { ($1, $0) })
306
-
307
- // let oldSet = oldChildren
308
- // let newSet = newChildren
309
-
310
- // Find removed items
311
- for oldItem in oldChildren.filter({ !newChildren.contains($0)}) {
312
- if let oldIndex = oldIndexMap[oldItem] {
313
- instructions.append(.remove(oldItem, at: oldIndex, parent: parent))
314
- processedItems.insert(oldItem)
315
- }
316
- }
317
-
318
- // Find inserted items
319
- for newItem in newChildren.filter({ !oldChildren.contains($0)}) {
320
- if let newIndex = newIndexMap[newItem] {
321
- instructions.append(.insert(newItem, at: newIndex, parent: parent))
322
- processedItems.insert(newItem)
323
- }
324
- compareChildren(
325
- oldChildren: oldSnapshot.nodes[newItem]?.children ?? [],
326
- newChildren: nodes[newItem]?.children ?? [],
327
- parent: newItem
328
- )
329
- }
330
-
331
- // Find moved or reordered items
332
- for newItem in newChildren.filter({ oldChildren.contains($0)}) {
333
- guard !processedItems.contains(newItem) else { continue }
334
- let oldIndex = oldIndexMap[newItem]!
335
- let newIndex = newIndexMap[newItem]!
336
- if oldIndex != newIndex || oldSnapshot.nodes[newItem]?.parent != nodes[newItem]?.parent {
337
- instructions.append(
338
- .move(
339
- newItem,
340
- from: oldIndex,
341
- oldSnapshot.nodes[newItem]?.parent,
342
- to: newIndex,
343
- nodes[newItem]?.parent
344
- )
345
- )
346
- }
347
- processedItems.insert(newItem)
348
- compareChildren(
349
- oldChildren: oldSnapshot.nodes[newItem]?.children ?? [],
350
- newChildren: nodes[newItem]?.children ?? [],
351
- parent: newItem
352
- )
353
- }
354
- }
355
-
356
- // Compare root items
357
- compareChildren(oldChildren: oldSnapshot.rootItems, newChildren: rootItems, parent: nil)
358
-
359
- return instructions
360
- }
361
-
362
- func diff1(from oldSnapshot: OutlineViewDiffableDataSourceSnapshot<ItemIdentifierType>) -> [OutlineChangeInstruction] {
363
- var instructions: [OutlineChangeInstruction] = []
364
- var processedItems: Set<ItemIdentifierType> = []
365
-
366
- // Helper function to compare children recursively
367
- func compareChildren(oldChildren: [ItemIdentifierType], newChildren: [ItemIdentifierType], parent: ItemIdentifierType?) {
368
- // Find removed items
369
- let removedItems = oldChildren.filter { !newChildren.contains($0) }
370
- for (index, item) in oldChildren.enumerated() where removedItems.contains(item) {
371
- instructions.append(.remove(item, at: index, parent: parent))
372
- processedItems.insert(item)
373
- }
374
-
375
- // Find inserted items
376
- let insertedItems = newChildren.filter { !oldChildren.contains($0) }
377
- for (index, item) in newChildren.enumerated() where insertedItems.contains(item) {
378
- instructions.append(.insert(item, at: index, parent: parent))
379
- processedItems.insert(item)
380
- }
381
-
382
- // Find moved items (including parent changes)
383
- for (newIndex, newItem) in newChildren.enumerated() {
384
- guard let oldIndex = oldChildren.firstIndex(of: newItem), !processedItems.contains(newItem) else { continue }
385
-
386
- let oldParent = oldSnapshot.nodes[newItem]?.parent
387
- let newParent = nodes[newItem]?.parent
388
-
389
- // Detect if item has moved (index or parent changed)
390
- if oldIndex != newIndex || oldParent != newParent {
391
- instructions.append(
392
- .move(
393
- newItem,
394
- from: oldIndex,
395
- oldParent,
396
- to: newIndex,
397
- newParent
398
- )
399
- )
400
- }
401
- processedItems.insert(newItem)
402
-
403
- // Recursively compare children
404
- compareChildren(
405
- oldChildren: oldSnapshot.nodes[newItem]?.children ?? [],
406
- newChildren: nodes[newItem]?.children ?? [],
407
- parent: newItem
408
- )
409
- }
410
- }
411
-
412
- // Compare root items
413
- compareChildren(oldChildren: oldSnapshot.rootItems, newChildren: rootItems, parent: nil)
414
-
415
- return instructions
416
- }
417
- */
418
-
419
- /*
420
- var description: String {
421
- switch self {
422
- case .insert(let item, let index, let parent):
423
- return "+ \"\(item)\" at \(index) in \"\(parent != nil ? "\(parent!)" : "Root")\""
424
- case .remove(let item, let index, let parent):
425
- return "- \"\(item)\" at \(index) from \"\(parent != nil ? "\(parent!)" : "Root")\""
426
- case .move(let item, let from, let fromParent, let to, let toParent):
427
- return "\"\(item)\" \"\(fromParent != nil ? "\(fromParent!)" : "Root")\" at \(from) → \"\(toParent != nil ? "\(toParent!)" : "Root")\" at \(to)"
428
- }
429
- }
430
- */
431
-
432
- /*
433
- var index: Int {
434
- switch self {
435
- case .insert(_, let index,_): return index
436
- case .remove(_, let index,_): return index
437
- default: return 0
438
- }
439
- }
440
-
441
- var parent: AnyHashable? {
442
- switch self {
443
- case .insert(_,_,let parent): return parent
444
- case .remove(_,_,let parent): return parent
445
- default: return nil
446
- }
447
- }
448
-
449
- var item: Any {
450
- switch self {
451
- case .insert(let item,_,_): return item
452
- case .remove(let item,_,_): return item
453
- case .move(let item,_,_,_,_): return item
454
- }
455
- }
456
- */
0 commit comments