/// <summary> /// Duplicates the selected objects. Supports undo/redo. /// </summary> public void Duplicate() { // Peek things that can be copied (copy all acctors) var objects = Selection.Where(x => x.CanCopyPaste).ToList().BuildAllNodes().Where(x => x.CanCopyPaste && x is ActorNode).ToList(); if (objects.Count == 0) { return; } // Serialize actors var actors = objects.ConvertAll(x => ((ActorNode)x).Actor); var data = Actor.ToBytes(actors.ToArray()); if (data == null) { Editor.LogError("Failed to copy actors data."); return; } // Create paste action (with selecting spawned objects) var pasteAction = PasteActorsAction.Duplicate(data, Guid.Empty); if (pasteAction != null) { OnPasteAcction(pasteAction); } }
/// <summary> /// Pastes the copied objects. Supports undo/redo. /// </summary> /// <param name="pasteTargetActor">The target actor to paste copied data.</param> public void Paste(Actor pasteTargetActor) { // Get clipboard data var data = Clipboard.RawData; // Set paste target if only one actor is selected and no target provided if (pasteTargetActor == null && SelectionCount == 1 && Selection[0] is ActorNode actorNode) { pasteTargetActor = actorNode.Actor; } // Create paste action var pasteAction = PasteActorsAction.Paste(data, pasteTargetActor?.ID ?? Guid.Empty); if (pasteAction != null) { pasteAction.Do(out _, out var nodeParents); // Select spawned objects (parents only) var selectAction = new SelectionChangeAction(Selection.ToArray(), nodeParents.Cast<SceneGraphNode>().ToArray(), OnSelectionUndo); selectAction.Do(); // Build single compound undo action that pastes the actors and selects the created objects (parents only) Undo.AddAction(new MultiUndoAction(pasteAction, selectAction)); OnSelectionChanged(); } }
private void OnPasteAcction(PasteActorsAction pasteAction) { pasteAction.Do(out _, out var nodeParents); // Select spawned objects var selectAction = new SelectionChangeAction(Selection.ToArray(), nodeParents.Cast <SceneGraphNode>().ToArray(), OnSelectionUndo); selectAction.Do(); Undo.AddAction(new MultiUndoAction(pasteAction, selectAction)); OnSelectionChanges(); }
/// <summary> /// Pastes the copied objects. Supports undo/redo. /// </summary> /// <param name="pasteTargetActor">The target actor to paste copied data.</param> public void Paste(Actor pasteTargetActor) { // Get clipboard data var data = Application.ClipboardRawData; // Ser aste target if only one actor is selected and no target provided if (pasteTargetActor == null && SelectionCount == 1 && Selection[0] is ActorNode actorNode) { pasteTargetActor = actorNode.Actor; } // Create paste action var pasteAction = PasteActorsAction.Paste(data, pasteTargetActor?.ID ?? Guid.Empty); if (pasteAction != null) { OnPasteAcction(pasteAction); } }
/// <summary> /// Duplicates the selected objects. Supports undo/redo. /// </summary> public void Duplicate() { // Peek things that can be copied (copy all actors) var nodes = Selection.Where(x => x.CanDuplicate).ToList().BuildAllNodes(); if (nodes.Count == 0) return; var actors = new List<Actor>(); var newSelection = new List<SceneGraphNode>(); List<IUndoAction> customUndoActions = null; foreach (var node in nodes) { if (node.CanDuplicate) { if (node is ActorNode actorNode) { actors.Add(actorNode.Actor); } else { var customDuplicatedObject = node.Duplicate(out var customUndoAction); if (customDuplicatedObject != null) newSelection.Add(customDuplicatedObject); if (customUndoAction != null) { if (customUndoActions == null) customUndoActions = new List<IUndoAction>(); customUndoActions.Add(customUndoAction); } } } } if (actors.Count == 0) { // Duplicate custom scene graph nodes only without actors if (newSelection.Count != 0) { // Select spawned objects (parents only) var selectAction = new SelectionChangeAction(Selection.ToArray(), newSelection.ToArray(), OnSelectionUndo); selectAction.Do(); // Build a single compound undo action that pastes the actors, pastes custom stuff (scene graph extension) and selects the created objects (parents only) var customUndoActionsCount = customUndoActions?.Count ?? 0; var undoActions = new IUndoAction[1 + customUndoActionsCount]; for (int i = 0; i < customUndoActionsCount; i++) undoActions[i] = customUndoActions[i]; undoActions[undoActions.Length - 1] = selectAction; Undo.AddAction(new MultiUndoAction(undoActions)); OnSelectionChanged(); } return; } // Serialize actors var data = Actor.ToBytes(actors.ToArray()); if (data == null) { Editor.LogError("Failed to copy actors data."); return; } // Create paste action (with selecting spawned objects) var pasteAction = PasteActorsAction.Duplicate(data, Guid.Empty); if (pasteAction != null) { pasteAction.Do(out _, out var nodeParents); // Select spawned objects (parents only) newSelection.AddRange(nodeParents); var selectAction = new SelectionChangeAction(Selection.ToArray(), newSelection.ToArray(), OnSelectionUndo); selectAction.Do(); // Build a single compound undo action that pastes the actors, pastes custom stuff (scene graph extension) and selects the created objects (parents only) var customUndoActionsCount = customUndoActions?.Count ?? 0; var undoActions = new IUndoAction[2 + customUndoActionsCount]; undoActions[0] = pasteAction; for (int i = 0; i < customUndoActionsCount; i++) undoActions[i + 1] = customUndoActions[i]; undoActions[undoActions.Length - 1] = selectAction; Undo.AddAction(new MultiUndoAction(undoActions)); OnSelectionChanged(); } }