Created
December 28, 2019 18:42
-
-
Save Ceylo/c66b10a9bd908448a7842ad5ae111387 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
private func rowIndexForLayer(at rowIndex: Int, in layers: [Layer]) -> Int { | |
return layers.count - 1 - rowIndex | |
} | |
private func outlineViewRowIndex(for path: IndexPath, parent: LayerContainer) -> Int { | |
let layerIndex = path.last! | |
return rowIndexForLayer(at: layerIndex, in: parent.layers) | |
} | |
func rowIndexesForMoving(_ layer: Layer, from: IndexPath, below: IndexPath, | |
sourceContainer: LayerContainer, destinationContainer: LayerContainer) | |
-> (fromRow: Int, fromParent: LayerContainer?, toRow: Int, toParent: LayerContainer?)? | |
{ | |
guard from.next != below else { return nil } | |
guard from != below else { return nil } | |
let updatedFrom = from.parent == below.parent ? from.havingInserted(below) : from | |
var fromRow = outlineViewRowIndex(for: updatedFrom, | |
parent: sourceContainer) | |
let updatedBelow = from.parent == below.parent ? below.havingRemoved(from) : below | |
let toRow = outlineViewRowIndex(for: updatedBelow, | |
parent: destinationContainer) | |
if sourceContainer === destinationContainer && toRow > fromRow { | |
fromRow += 1 | |
} | |
if sourceContainer !== destinationContainer { | |
fromRow += 1 | |
} | |
guard fromRow != toRow || sourceContainer !== destinationContainer else { return nil } | |
let fromParent = from.count > 1 ? sourceContainer : nil | |
let toParent = below.count > 1 ? destinationContainer : nil | |
return (fromRow, fromParent, toRow, toParent) | |
} | |
extension NSOutlineView { | |
/// Convenience API for the similar `NSOutlineView.moveItem(at:inParent:to:inParent:)`, but in Canvas | |
/// coordinates. | |
/// | |
/// Canvas coordinates refer to the fact that the first layer (index 0) in canvas is the background one (ie. below other layers), | |
/// although it is displayed as the last one in the outline view (ie. the bottom layer is the background). | |
/// | |
/// - Parameters: | |
/// - layer: The layer being moved. | |
/// - canvas: The canvas to which the layer belongs. | |
/// - sourcePath: The original path to the layer, in Canvas coordinates. | |
/// - destinationPath: The destination path at which the layer is inserted, in Canvas coordinates. | |
func move(_ layer: Layer, in canvas: Canvas, at sourcePath: IndexPath, below destinationPath: IndexPath, | |
sourceContainer: LayerContainer, destinationContainer: LayerContainer) { | |
if let (fromRow, fromParent, toRow, toParent) | |
= rowIndexesForMoving(layer, from: sourcePath, below: destinationPath, | |
sourceContainer: sourceContainer, | |
destinationContainer: destinationContainer) { | |
moveItem(at: fromRow, inParent: fromParent, to: toRow, inParent: toParent) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment