|
|
|
@ -3,16 +3,101 @@
|
|
|
|
|
|
|
|
|
|
using UnityEngine; |
|
|
|
|
using UnityEditor; |
|
|
|
|
using UnityEditorInternal; |
|
|
|
|
using System; |
|
|
|
|
using System.Linq; |
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
using System.Reflection; |
|
|
|
|
using Object = UnityEngine.Object; |
|
|
|
|
|
|
|
|
|
namespace Fungus.EditorUtils |
|
|
|
|
{ |
|
|
|
|
public class FlowchartWindow : EditorWindow |
|
|
|
|
{ |
|
|
|
|
protected class ClipboardObject |
|
|
|
|
{ |
|
|
|
|
internal SerializedObject serializedObject; |
|
|
|
|
internal Type type; |
|
|
|
|
|
|
|
|
|
internal ClipboardObject(Object obj) |
|
|
|
|
{ |
|
|
|
|
serializedObject = new SerializedObject(obj); |
|
|
|
|
type = obj.GetType(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected class BlockCopy |
|
|
|
|
{ |
|
|
|
|
private SerializedObject block = null; |
|
|
|
|
private List<ClipboardObject> commands = new List<ClipboardObject>(); |
|
|
|
|
private ClipboardObject eventHandler = null; |
|
|
|
|
|
|
|
|
|
internal BlockCopy(Block block) |
|
|
|
|
{ |
|
|
|
|
this.block = new SerializedObject(block); |
|
|
|
|
foreach (var command in block.CommandList) |
|
|
|
|
{ |
|
|
|
|
commands.Add(new ClipboardObject(command)); |
|
|
|
|
} |
|
|
|
|
if (block._EventHandler != null) |
|
|
|
|
{ |
|
|
|
|
eventHandler = new ClipboardObject(block._EventHandler); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void CopyProperties(SerializedObject source, Object dest, params SerializedPropertyType[] excludeTypes) |
|
|
|
|
{ |
|
|
|
|
var newSerializedObject = new SerializedObject(dest); |
|
|
|
|
var prop = source.GetIterator(); |
|
|
|
|
while (prop.NextVisible(true)) |
|
|
|
|
{ |
|
|
|
|
if (!excludeTypes.Contains(prop.propertyType)) |
|
|
|
|
{ |
|
|
|
|
newSerializedObject.CopyFromSerializedProperty(prop); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
newSerializedObject.ApplyModifiedProperties(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
internal Block PasteBlock(Flowchart flowchart) |
|
|
|
|
{ |
|
|
|
|
var newBlock = FlowchartWindow.CreateBlock(flowchart, Vector2.zero); |
|
|
|
|
|
|
|
|
|
// Copy all command serialized properties |
|
|
|
|
// Copy references to match duplication behavior |
|
|
|
|
foreach (var command in commands) |
|
|
|
|
{ |
|
|
|
|
var newCommand = Undo.AddComponent(flowchart.gameObject, command.type) as Command; |
|
|
|
|
CopyProperties(command.serializedObject, newCommand); |
|
|
|
|
newCommand.ItemId = flowchart.NextItemId(); |
|
|
|
|
newBlock.CommandList.Add(newCommand); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Copy event handler |
|
|
|
|
if (eventHandler != null) |
|
|
|
|
{ |
|
|
|
|
var newEventHandler = Undo.AddComponent(flowchart.gameObject, eventHandler.type) as EventHandler; |
|
|
|
|
CopyProperties(eventHandler.serializedObject, newEventHandler); |
|
|
|
|
newEventHandler.ParentBlock = newBlock; |
|
|
|
|
newBlock._EventHandler = newEventHandler; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Copy block properties, but do not copy references because those were just assigned |
|
|
|
|
CopyProperties( |
|
|
|
|
block, |
|
|
|
|
newBlock, |
|
|
|
|
SerializedPropertyType.ObjectReference, |
|
|
|
|
SerializedPropertyType.Generic, |
|
|
|
|
SerializedPropertyType.ArraySize |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
newBlock.BlockName = flowchart.GetUniqueBlockKey(block.FindProperty("blockName").stringValue + " (Copy)"); |
|
|
|
|
|
|
|
|
|
return newBlock; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected List<BlockCopy> copyList = new List<BlockCopy>(); |
|
|
|
|
public static List<Block> deleteList = new List<Block>(); |
|
|
|
|
|
|
|
|
|
protected List<Block> windowBlockMap = new List<Block>(); |
|
|
|
@ -34,11 +119,15 @@ namespace Fungus.EditorUtils
|
|
|
|
|
protected int forceRepaintCount; |
|
|
|
|
|
|
|
|
|
protected Texture2D addTexture; |
|
|
|
|
protected Texture2D connectionPointTexture; |
|
|
|
|
|
|
|
|
|
protected Rect selectionBox; |
|
|
|
|
protected Vector2 startSelectionBoxPosition = -Vector2.one; |
|
|
|
|
protected List<Block> mouseDownSelectionState = new List<Block>(); |
|
|
|
|
|
|
|
|
|
protected Color gridLineColor = Color.black; |
|
|
|
|
protected readonly Color connectionColor = new Color(0.65f, 0.65f, 0.65f, 1.0f); |
|
|
|
|
|
|
|
|
|
// Context Click occurs on MouseDown which interferes with panning |
|
|
|
|
// Track right click positions manually to show menus on MouseUp |
|
|
|
|
protected Vector2 rightClickDown = -Vector2.one; |
|
|
|
@ -66,6 +155,10 @@ namespace Fungus.EditorUtils
|
|
|
|
|
nodeStyle.wordWrap = true; |
|
|
|
|
|
|
|
|
|
addTexture = FungusEditorResources.AddSmall; |
|
|
|
|
connectionPointTexture = FungusEditorResources.ConnectionPoint; |
|
|
|
|
gridLineColor.a = EditorGUIUtility.isProSkin ? 0.5f : 0.25f; |
|
|
|
|
|
|
|
|
|
copyList.Clear(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected virtual void OnInspectorUpdate() |
|
|
|
@ -156,6 +249,11 @@ namespace Fungus.EditorUtils
|
|
|
|
|
Undo.DestroyObjectImmediate(command); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (deleteBlock._EventHandler != null) |
|
|
|
|
{ |
|
|
|
|
Undo.DestroyObjectImmediate(deleteBlock._EventHandler); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Undo.DestroyObjectImmediate((Block)deleteBlock); |
|
|
|
|
flowchart.ClearSelectedCommands(); |
|
|
|
|
|
|
|
|
@ -299,6 +397,13 @@ namespace Fungus.EditorUtils
|
|
|
|
|
flowchart.ScrollViewRect = newRect; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Draw background color / drop shadow |
|
|
|
|
if (Event.current.type == EventType.Repaint) |
|
|
|
|
{ |
|
|
|
|
UnityEditor.Graphs.Styles.graphBackground.Draw( |
|
|
|
|
new Rect(0, 17, position.width, position.height - 17), false, false, false, false |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
// Calc rect for script view |
|
|
|
|
Rect scriptViewRect = new Rect(0, 0, this.position.width / flowchart.Zoom, this.position.height / flowchart.Zoom); |
|
|
|
|
|
|
|
|
@ -320,9 +425,10 @@ namespace Fungus.EditorUtils
|
|
|
|
|
|
|
|
|
|
EditorZoomArea.Begin(flowchart.Zoom, scriptViewRect); |
|
|
|
|
|
|
|
|
|
DrawGrid(flowchart); |
|
|
|
|
|
|
|
|
|
GLDraw.BeginGroup(scriptViewRect); |
|
|
|
|
if (Event.current.type == EventType.Repaint) |
|
|
|
|
{ |
|
|
|
|
DrawGrid(flowchart); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// The center of the Flowchart depends on the block positions and window dimensions, so we calculate it |
|
|
|
|
// here in the FlowchartWindow class and store it on the Flowchart object for use later. |
|
|
|
@ -485,8 +591,6 @@ namespace Fungus.EditorUtils
|
|
|
|
|
|
|
|
|
|
PanAndZoom(flowchart); |
|
|
|
|
|
|
|
|
|
GLDraw.EndGroup(); |
|
|
|
|
|
|
|
|
|
EditorZoomArea.End(); |
|
|
|
|
|
|
|
|
|
// Handle right click up outside of EditorZoomArea to avoid strange offsets |
|
|
|
@ -512,14 +616,26 @@ namespace Fungus.EditorUtils
|
|
|
|
|
|
|
|
|
|
// Use a copy because flowchart.SelectedBlocks gets modified |
|
|
|
|
var blockList = new List<Block>(flowchart.SelectedBlocks); |
|
|
|
|
menu.AddItem(new GUIContent ("Duplicate"), false, DuplicateBlocks, blockList); |
|
|
|
|
menu.AddItem(new GUIContent ("Copy"), false, () => Copy(flowchart)); |
|
|
|
|
menu.AddItem(new GUIContent ("Cut"), false, () => Cut(flowchart)); |
|
|
|
|
menu.AddItem(new GUIContent ("Duplicate"), false, () => Duplicate(flowchart)); |
|
|
|
|
menu.AddItem(new GUIContent ("Delete"), false, DeleteBlocks, blockList); |
|
|
|
|
} |
|
|
|
|
// Clicked on empty space in grid |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
DeselectAll(flowchart); |
|
|
|
|
|
|
|
|
|
menu.AddItem(new GUIContent("Add Block"), false, () => CreateBlock(flowchart, mousePosition / flowchart.Zoom - flowchart.ScrollPos)); |
|
|
|
|
|
|
|
|
|
if (copyList.Count > 0) |
|
|
|
|
{ |
|
|
|
|
menu.AddItem(new GUIContent("Paste"), false, () => Paste(flowchart, mousePosition)); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
menu.AddDisabledItem(new GUIContent("Paste")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var menuRect = new Rect(); |
|
|
|
@ -720,26 +836,14 @@ namespace Fungus.EditorUtils
|
|
|
|
|
float width = this.position.width / flowchart.Zoom; |
|
|
|
|
float height = this.position.height / flowchart.Zoom; |
|
|
|
|
|
|
|
|
|
// Match background color of scene view |
|
|
|
|
if (EditorGUIUtility.isProSkin) |
|
|
|
|
{ |
|
|
|
|
GUI.color = new Color32(71, 71, 71, 255); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
GUI.color = new Color32(86, 86, 86, 255); |
|
|
|
|
} |
|
|
|
|
GUI.DrawTexture( new Rect(0,0, width, height), EditorGUIUtility.whiteTexture ); |
|
|
|
|
|
|
|
|
|
GUI.color = Color.white; |
|
|
|
|
Color color = new Color32(96, 96, 96, 255); |
|
|
|
|
Handles.color = gridLineColor; |
|
|
|
|
|
|
|
|
|
float gridSize = 128f; |
|
|
|
|
|
|
|
|
|
float x = flowchart.ScrollPos.x % gridSize; |
|
|
|
|
while (x < width) |
|
|
|
|
{ |
|
|
|
|
GLDraw.DrawLine(new Vector2(x, 0), new Vector2(x, height), color, 1f); |
|
|
|
|
Handles.DrawLine(new Vector2(x, 0), new Vector2(x, height)); |
|
|
|
|
x += gridSize; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -748,10 +852,12 @@ namespace Fungus.EditorUtils
|
|
|
|
|
{ |
|
|
|
|
if (y >= 0) |
|
|
|
|
{ |
|
|
|
|
GLDraw.DrawLine(new Vector2(0, y), new Vector2(width, y), color, 1f); |
|
|
|
|
Handles.DrawLine(new Vector2(0, y), new Vector2(width, y)); |
|
|
|
|
} |
|
|
|
|
y += gridSize; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Handles.color = Color.white; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected virtual void SelectBlock(Flowchart flowchart, Block block) |
|
|
|
@ -990,17 +1096,17 @@ namespace Fungus.EditorUtils
|
|
|
|
|
protected virtual void DrawRectConnection(Rect rectA, Rect rectB, bool highlight) |
|
|
|
|
{ |
|
|
|
|
Vector2[] pointsA = new Vector2[] { |
|
|
|
|
new Vector2(rectA.xMin + 5, rectA.center.y), |
|
|
|
|
new Vector2(rectA.xMin + rectA.width / 2, rectA.yMin + 2), |
|
|
|
|
new Vector2(rectA.xMin + rectA.width / 2, rectA.yMax - 2), |
|
|
|
|
new Vector2(rectA.xMax - 5, rectA.center.y) |
|
|
|
|
new Vector2(rectA.xMin, rectA.center.y), |
|
|
|
|
new Vector2(rectA.xMin + rectA.width / 2, rectA.yMin), |
|
|
|
|
new Vector2(rectA.xMin + rectA.width / 2, rectA.yMax), |
|
|
|
|
new Vector2(rectA.xMax, rectA.center.y) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
Vector2[] pointsB = new Vector2[] { |
|
|
|
|
new Vector2(rectB.xMin + 5, rectB.center.y), |
|
|
|
|
new Vector2(rectB.xMin + rectB.width / 2, rectB.yMin + 2), |
|
|
|
|
new Vector2(rectB.xMin + rectB.width / 2, rectB.yMax - 2), |
|
|
|
|
new Vector2(rectB.xMax - 5, rectB.center.y) |
|
|
|
|
new Vector2(rectB.xMin, rectB.center.y), |
|
|
|
|
new Vector2(rectB.xMin + rectB.width / 2, rectB.yMin), |
|
|
|
|
new Vector2(rectB.xMin + rectB.width / 2, rectB.yMax), |
|
|
|
|
new Vector2(rectB.xMax, rectB.center.y) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
Vector2 pointA = Vector2.zero; |
|
|
|
@ -1021,90 +1127,60 @@ namespace Fungus.EditorUtils
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Color color = Color.grey; |
|
|
|
|
Color color = connectionColor; |
|
|
|
|
if (highlight) |
|
|
|
|
{ |
|
|
|
|
color = Color.green; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GLDraw.DrawConnectingCurve(pointA, pointB, color, 1.025f); |
|
|
|
|
Handles.color = color; |
|
|
|
|
|
|
|
|
|
// Place control based on distance between points |
|
|
|
|
// Weight the min component more so things don't get overly curvy |
|
|
|
|
var diff = pointA - pointB; |
|
|
|
|
diff.x = Mathf.Abs(diff.x); |
|
|
|
|
diff.y = Mathf.Abs(diff.y); |
|
|
|
|
var min = Mathf.Min(diff.x, diff.y); |
|
|
|
|
var max = Mathf.Max(diff.x, diff.y); |
|
|
|
|
var mod = min * 0.75f + max * 0.25f; |
|
|
|
|
|
|
|
|
|
// Draw bezier curve connecting blocks |
|
|
|
|
var directionA = (rectA.center - pointA).normalized; |
|
|
|
|
var directionB = (rectB.center - pointB).normalized; |
|
|
|
|
var controlA = pointA - directionA * mod * 0.67f; |
|
|
|
|
var controlB = pointB - directionB * mod * 0.67f; |
|
|
|
|
Handles.DrawBezier(pointA, pointB, controlA, controlB, color, null, 3f); |
|
|
|
|
|
|
|
|
|
// Draw arrow on curve |
|
|
|
|
var point = GetPointOnCurve(pointA, controlA, pointB, controlB, 0.7f); |
|
|
|
|
var direction = (GetPointOnCurve(pointA, controlA, pointB, controlB, 0.6f) - point).normalized; |
|
|
|
|
var perp = new Vector2(direction.y, -direction.x); |
|
|
|
|
Handles.DrawAAConvexPolygon( |
|
|
|
|
point, point + direction * 10 + perp * 5, point + direction * 10 - perp * 5 |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
Rect dotARect = new Rect(pointA.x - 5, pointA.y - 5, 10, 10); |
|
|
|
|
GUI.Label(dotARect, "", new GUIStyle("U2D.dragDotActive")); |
|
|
|
|
var connectionPointA = pointA + directionA * 4f; |
|
|
|
|
var connectionRectA = new Rect(connectionPointA.x - 4f, connectionPointA.y - 4f, 8f, 8f); |
|
|
|
|
var connectionPointB = pointB + directionB * 4f; |
|
|
|
|
var connectionRectB = new Rect(connectionPointB.x - 4f, connectionPointB.y - 4f, 8f, 8f); |
|
|
|
|
|
|
|
|
|
Rect dotBRect = new Rect(pointB.x - 5, pointB.y - 5, 10, 10); |
|
|
|
|
GUI.Label(dotBRect, "", new GUIStyle("U2D.dragDotActive")); |
|
|
|
|
} |
|
|
|
|
GUI.DrawTexture(connectionRectA, connectionPointTexture, ScaleMode.ScaleToFit); |
|
|
|
|
GUI.DrawTexture(connectionRectB, connectionPointTexture, ScaleMode.ScaleToFit); |
|
|
|
|
|
|
|
|
|
public static void DeleteBlocks(object obj) |
|
|
|
|
{ |
|
|
|
|
var blocks = obj as List<Block>; |
|
|
|
|
blocks.ForEach(block => FlowchartWindow.deleteList.Add(block)); |
|
|
|
|
Handles.color = Color.white; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected static void DuplicateBlocks(object obj) |
|
|
|
|
private static Vector2 GetPointOnCurve(Vector2 s, Vector2 st, Vector2 e, Vector2 et, float t) |
|
|
|
|
{ |
|
|
|
|
DuplicateBlocks(obj, new Vector2(20, 0)); |
|
|
|
|
float rt = 1 - t; |
|
|
|
|
float rtt = rt * t; |
|
|
|
|
return rt * rt * rt * s + 3 * rt * rtt * st + 3 * rtt * t * et + t * t * t * e; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected static void DuplicateBlocks(object obj, Vector2 offset) |
|
|
|
|
public static void DeleteBlocks(object obj) |
|
|
|
|
{ |
|
|
|
|
var flowchart = GetFlowchart(); |
|
|
|
|
|
|
|
|
|
Undo.RecordObject(flowchart, "Select"); |
|
|
|
|
flowchart.ClearSelectedBlocks(); |
|
|
|
|
|
|
|
|
|
var blocks = obj as List<Block>; |
|
|
|
|
|
|
|
|
|
foreach (var block in blocks) |
|
|
|
|
{ |
|
|
|
|
Vector2 newPosition = block._NodeRect.position + offset; |
|
|
|
|
|
|
|
|
|
Block oldBlock = block; |
|
|
|
|
|
|
|
|
|
Block newBlock = FlowchartWindow.CreateBlock(flowchart, newPosition); |
|
|
|
|
newBlock.BlockName = flowchart.GetUniqueBlockKey(oldBlock.BlockName + " (Copy)"); |
|
|
|
|
|
|
|
|
|
Undo.RecordObject(newBlock, "Duplicate Block"); |
|
|
|
|
|
|
|
|
|
var commandList = oldBlock.CommandList; |
|
|
|
|
foreach (var command in commandList) |
|
|
|
|
{ |
|
|
|
|
if (ComponentUtility.CopyComponent(command)) |
|
|
|
|
{ |
|
|
|
|
if (ComponentUtility.PasteComponentAsNew(flowchart.gameObject)) |
|
|
|
|
{ |
|
|
|
|
Command[] commands = flowchart.GetComponents<Command>(); |
|
|
|
|
Command pastedCommand = commands.Last<Command>(); |
|
|
|
|
if (pastedCommand != null) |
|
|
|
|
{ |
|
|
|
|
pastedCommand.ItemId = flowchart.NextItemId(); |
|
|
|
|
newBlock.CommandList.Add(pastedCommand); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This stops the user pasting the command manually into another game object. |
|
|
|
|
ComponentUtility.CopyComponent(flowchart.transform); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (oldBlock._EventHandler != null) |
|
|
|
|
{ |
|
|
|
|
if (ComponentUtility.CopyComponent(oldBlock._EventHandler)) |
|
|
|
|
{ |
|
|
|
|
if (ComponentUtility.PasteComponentAsNew(flowchart.gameObject)) |
|
|
|
|
{ |
|
|
|
|
EventHandler[] eventHandlers = flowchart.GetComponents<EventHandler>(); |
|
|
|
|
EventHandler pastedEventHandler = eventHandlers.Last<EventHandler>(); |
|
|
|
|
if (pastedEventHandler != null) |
|
|
|
|
{ |
|
|
|
|
pastedEventHandler.ParentBlock = newBlock; |
|
|
|
|
newBlock._EventHandler = pastedEventHandler; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
blocks.ForEach(block => FlowchartWindow.deleteList.Add(block)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected static void ShowBlockInspector(Flowchart flowchart) |
|
|
|
@ -1149,18 +1225,74 @@ namespace Fungus.EditorUtils
|
|
|
|
|
return Event.current.shift || EditorGUI.actionKey; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected virtual void Copy(Flowchart flowchart) |
|
|
|
|
{ |
|
|
|
|
copyList.Clear(); |
|
|
|
|
|
|
|
|
|
foreach (var block in flowchart.SelectedBlocks) |
|
|
|
|
{ |
|
|
|
|
copyList.Add(new BlockCopy(block)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected virtual void Cut(Flowchart flowchart) |
|
|
|
|
{ |
|
|
|
|
Copy(flowchart); |
|
|
|
|
Undo.RecordObject(flowchart, "Cut"); |
|
|
|
|
DeleteBlocks(flowchart.SelectedBlocks); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Center is position in unscaled window space |
|
|
|
|
protected virtual void Paste(Flowchart flowchart, Vector2 center, bool relative = false) |
|
|
|
|
{ |
|
|
|
|
Undo.RecordObject(flowchart, "Deselect"); |
|
|
|
|
DeselectAll(flowchart); |
|
|
|
|
|
|
|
|
|
var pasteList = new List<Block>(); |
|
|
|
|
|
|
|
|
|
foreach (var copy in copyList) |
|
|
|
|
{ |
|
|
|
|
pasteList.Add(copy.PasteBlock(flowchart)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var copiedCenter = GetBlockCenter(flowchart, pasteList.ToArray()) + flowchart.ScrollPos; |
|
|
|
|
var delta = relative ? center : (center / flowchart.Zoom - copiedCenter); |
|
|
|
|
|
|
|
|
|
foreach (var block in pasteList) |
|
|
|
|
{ |
|
|
|
|
var tempRect = block._NodeRect; |
|
|
|
|
tempRect.position += delta; |
|
|
|
|
block._NodeRect = tempRect; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected virtual void Duplicate(Flowchart flowchart) |
|
|
|
|
{ |
|
|
|
|
var tempCopyList = new List<BlockCopy>(copyList); |
|
|
|
|
Copy(flowchart); |
|
|
|
|
Paste(flowchart, new Vector2(20, 0), true); |
|
|
|
|
copyList = tempCopyList; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected virtual void ValidateCommands(Flowchart flowchart) |
|
|
|
|
{ |
|
|
|
|
if (Event.current.type == EventType.ValidateCommand) |
|
|
|
|
{ |
|
|
|
|
var c = Event.current.commandName; |
|
|
|
|
if (c == "Delete" || c == "Duplicate") |
|
|
|
|
if (c == "Copy" || c == "Cut" || c == "Delete" || c == "Duplicate") |
|
|
|
|
{ |
|
|
|
|
if (flowchart.SelectedBlocks.Count > 0) |
|
|
|
|
{ |
|
|
|
|
Event.current.Use(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if (c == "Paste") |
|
|
|
|
{ |
|
|
|
|
if (copyList.Count > 0) |
|
|
|
|
{ |
|
|
|
|
Event.current.Use(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if (c == "SelectAll") |
|
|
|
|
{ |
|
|
|
|
Event.current.Use(); |
|
|
|
@ -1174,13 +1306,28 @@ namespace Fungus.EditorUtils
|
|
|
|
|
{ |
|
|
|
|
switch (Event.current.commandName) |
|
|
|
|
{ |
|
|
|
|
case "Copy": |
|
|
|
|
Copy(flowchart); |
|
|
|
|
Event.current.Use(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case "Cut": |
|
|
|
|
Cut(flowchart); |
|
|
|
|
Event.current.Use(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case "Paste": |
|
|
|
|
Paste(flowchart, position.center - position.position); |
|
|
|
|
Event.current.Use(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case "Delete": |
|
|
|
|
DeleteBlocks(flowchart.SelectedBlocks); |
|
|
|
|
Event.current.Use(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case "Duplicate": |
|
|
|
|
DuplicateBlocks(new List<Block>(flowchart.SelectedBlocks)); |
|
|
|
|
Duplicate(flowchart); |
|
|
|
|
Event.current.Use(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|