protected void SelectNext() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); int lastSelectedIndex = -1; if (flowchart.selectedCommands.Count > 0) { for (int i = 0; i < flowchart.selectedBlock.commandList.Count; i++) { Command commandInBlock = flowchart.selectedBlock.commandList[i]; foreach (Command selectedCommand in flowchart.selectedCommands) { if (commandInBlock == selectedCommand) { lastSelectedIndex = i; } } } } if (lastSelectedIndex < flowchart.selectedBlock.commandList.Count - 1) { flowchart.ClearSelectedCommands(); flowchart.AddSelectedCommand(flowchart.selectedBlock.commandList[lastSelectedIndex + 1]); } Repaint(); }
//MIKEHACK public void AddCommandHack(Block bl, Type type, int index) { if (bl == null) { return; } Flowchart flowchart = bl.GetFlowchart(); flowchart.ClearSelectedCommands(); Command newCommand = Undo.AddComponent(bl.gameObject, type) as Command; bl.GetFlowchart().AddSelectedCommand(newCommand); newCommand.parentBlock = bl; newCommand.itemId = flowchart.NextItemId(); // Let command know it has just been added to the block newCommand.OnCommandAdded(bl); Undo.RecordObject(bl, "Set command type"); if (index < bl.commandList.Count - 1) { bl.commandList.Insert(index, newCommand); } else { bl.commandList.Add(newCommand); } // Because this is an async call, we need to force prefab instances to record changes PrefabUtility.RecordPrefabInstancePropertyModifications(bl); }
protected static void AddCommandCallback(object obj) { AddCommandOperation commandOperation = obj as AddCommandOperation; Block block = commandOperation.block; if (block == null) { return; } Flowchart flowchart = block.GetFlowchart(); flowchart.ClearSelectedCommands(); Command newCommand = Undo.AddComponent(block.gameObject, commandOperation.commandType) as Command; block.GetFlowchart().AddSelectedCommand(newCommand); newCommand.parentBlock = block; newCommand.itemId = flowchart.NextItemId(); // Let command know it has just been added to the block newCommand.OnCommandAdded(block); Undo.RecordObject(block, "Set command type"); if (commandOperation.index < block.commandList.Count - 1) { block.commandList.Insert(commandOperation.index, newCommand); } else { block.commandList.Add(newCommand); } }
protected virtual void DeleteBlock(Flowchart flowchart, Block block) { foreach (Command command in block.commandList) { Undo.DestroyObjectImmediate(command); } Undo.DestroyObjectImmediate(block); flowchart.ClearSelectedCommands(); }
public static Block CreateBlock(Flowchart flowchart, Vector2 position) { Block newBlock = flowchart.CreateBlock(position); Undo.RegisterCreatedObjectUndo(newBlock, "New Block"); ShowBlockInspector(flowchart); flowchart.selectedBlock = newBlock; flowchart.ClearSelectedCommands(); return(newBlock); }
protected virtual void SelectBlock(Flowchart flowchart, Block block) { // Select the block and also select currently executing command ShowBlockInspector(flowchart); flowchart.selectedBlock = block; flowchart.ClearSelectedCommands(); if (block.activeCommand != null) { flowchart.AddSelectedCommand(block.activeCommand); } }
protected void SelectNone() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); if (flowchart == null || flowchart.selectedBlock == null) { return; } Undo.RecordObject(flowchart, "Select None"); flowchart.ClearSelectedCommands(); Repaint(); }
protected void Delete() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); if (flowchart == null || flowchart.selectedBlock == null) { return; } int lastSelectedIndex = 0; for (int i = flowchart.selectedBlock.commandList.Count - 1; i >= 0; --i) { Command command = flowchart.selectedBlock.commandList[i]; foreach (Command selectedCommand in flowchart.selectedCommands) { if (command == selectedCommand) { command.OnCommandRemoved(block); // Order of destruction is important here for undo to work Undo.DestroyObjectImmediate(command); Undo.RecordObject(flowchart.selectedBlock, "Delete"); flowchart.selectedBlock.commandList.RemoveAt(i); lastSelectedIndex = i; break; } } } Undo.RecordObject(flowchart, "Delete"); flowchart.ClearSelectedCommands(); if (lastSelectedIndex < flowchart.selectedBlock.commandList.Count) { Command nextCommand = flowchart.selectedBlock.commandList[lastSelectedIndex]; block.GetFlowchart().AddSelectedCommand(nextCommand); } Repaint(); }
protected void SelectAll() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); if (flowchart == null || flowchart.selectedBlock == null) { return; } flowchart.ClearSelectedCommands(); Undo.RecordObject(flowchart, "Select All"); foreach (Command command in flowchart.selectedBlock.commandList) { flowchart.AddSelectedCommand(command); } Repaint(); }
protected void SelectPrevious() { Block block = target as Block; Flowchart flowchart = block.GetFlowchart(); int firstSelectedIndex = flowchart.selectedBlock.commandList.Count; bool firstSelectedCommandFound = false; if (flowchart.selectedCommands.Count > 0) { for (int i = 0; i < flowchart.selectedBlock.commandList.Count; i++) { Command commandInBlock = flowchart.selectedBlock.commandList[i]; foreach (Command selectedCommand in flowchart.selectedCommands) { if (commandInBlock == selectedCommand) { if (!firstSelectedCommandFound) { firstSelectedIndex = i; firstSelectedCommandFound = true; break; } } } if (firstSelectedCommandFound) { break; } } } if (firstSelectedIndex > 0) { flowchart.ClearSelectedCommands(); flowchart.AddSelectedCommand(flowchart.selectedBlock.commandList[firstSelectedIndex - 1]); } Repaint(); }
protected virtual void OnGUI() { Flowchart flowchart = GetFlowchart(); if (flowchart == null) { GUILayout.Label("No Flowchart scene object selected"); return; } // Delete any scheduled objects foreach (Block deleteBlock in deleteList) { bool isSelected = (flowchart.selectedBlock == deleteBlock); foreach (Command command in deleteBlock.commandList) { Undo.DestroyObjectImmediate(command); } Undo.DestroyObjectImmediate(deleteBlock); flowchart.ClearSelectedCommands(); if (isSelected) { // Revert to showing properties for the Flowchart Selection.activeGameObject = flowchart.gameObject; } } deleteList.Clear(); DrawFlowchartView(flowchart); DrawOverlay(flowchart); if (forceRepaintCount > 0) { // Redraw on next frame to get crisp refresh rate Repaint(); } }
protected static void AddCommandCallback(object obj) { AddCommandOperation commandOperation = obj as AddCommandOperation; Block block = commandOperation.block; if (block == null) { return; } Flowchart flowchart = block.GetFlowchart(); flowchart.ClearSelectedCommands(); Command newCommand = Undo.AddComponent(block.gameObject, commandOperation.commandType) as Command; block.GetFlowchart().AddSelectedCommand(newCommand); newCommand.parentBlock = block; newCommand.itemId = flowchart.NextItemId(); // Let command know it has just been added to the block newCommand.OnCommandAdded(block); Undo.RecordObject(block, "Set command type"); if (commandOperation.index < block.commandList.Count - 1) { block.commandList.Insert(commandOperation.index, newCommand); } else { block.commandList.Add(newCommand); } // Because this is an async call, we need to force prefab instances to record changes PrefabUtility.RecordPrefabInstancePropertyModifications(block); }
Command AddNewCommand() { Flowchart flowchart = FlowchartWindow.GetFlowchart(); if (flowchart == null) { return(null); } Block block = flowchart.selectedBlock; if (block == null) { return(null); } Command newCommand = Undo.AddComponent <Comment>(block.gameObject) as Command; newCommand.itemId = flowchart.NextItemId(); flowchart.ClearSelectedCommands(); flowchart.AddSelectedCommand(newCommand); return(newCommand); }
public void DrawItem(Rect position, int index) { Command command = this[index].objectReferenceValue as Command; if (command == null) { return; } CommandInfoAttribute commandInfoAttr = CommandEditor.GetCommandInfo(command.GetType()); if (commandInfoAttr == null) { return; } Flowchart flowchart = command.GetFlowchart(); if (flowchart == null) { return; } bool isComment = command.GetType() == typeof(Comment); bool isLabel = (command.GetType() == typeof(Label)); bool error = false; string summary = command.GetSummary(); if (summary == null) { summary = ""; } else { summary = summary.Replace("\n", "").Replace("\r", ""); } if (summary.StartsWith("Error:")) { error = true; } if (isComment || isLabel) { summary = "<b> " + summary + "</b>"; } else { summary = "<i>" + summary + "</i>"; } bool commandIsSelected = false; foreach (Command selectedCommand in flowchart.selectedCommands) { if (selectedCommand == command) { commandIsSelected = true; break; } } string commandName = commandInfoAttr.CommandName; GUIStyle commandLabelStyle = new GUIStyle(GUI.skin.box); commandLabelStyle.normal.background = FungusEditorResources.texCommandBackground; int borderSize = 5; commandLabelStyle.border.top = borderSize; commandLabelStyle.border.bottom = borderSize; commandLabelStyle.border.left = borderSize; commandLabelStyle.border.right = borderSize; commandLabelStyle.alignment = TextAnchor.MiddleLeft; commandLabelStyle.richText = true; commandLabelStyle.fontSize = 11; commandLabelStyle.padding.top -= 1; float indentSize = 20; for (int i = 0; i < command.indentLevel; ++i) { Rect indentRect = position; indentRect.x += i * indentSize - 21; indentRect.width = indentSize + 1; indentRect.y -= 2; indentRect.height += 5; GUI.backgroundColor = new Color(0.5f, 0.5f, 0.5f, 1f); GUI.Box(indentRect, "", commandLabelStyle); } float commandNameWidth = Mathf.Max(commandLabelStyle.CalcSize(new GUIContent(commandName)).x, 90f); float indentWidth = command.indentLevel * indentSize; Rect commandLabelRect = position; commandLabelRect.x += indentWidth - 21; commandLabelRect.y -= 2; commandLabelRect.width -= (indentSize * command.indentLevel - 22); commandLabelRect.height += 5; // There's a weird incompatibility between the Reorderable list control used for the command list and // the UnityEvent list control used in some commands. In play mode, if you click on the reordering grabber // for a command in the list it causes the UnityEvent list to spew null exception errors. // The workaround for now is to hide the reordering grabber from mouse clicks by extending the command // selection rectangle to cover it. We are planning to totally replace the command list display system. Rect clickRect = position; clickRect.x -= 20; clickRect.width += 20; // Select command via left click if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && clickRect.Contains(Event.current.mousePosition)) { if (flowchart.selectedCommands.Contains(command) && Event.current.button == 0) { // Left click on already selected command // Command key and shift key is not pressed if (!EditorGUI.actionKey && !Event.current.shift) { BlockEditor.actionList.Add(delegate { flowchart.selectedCommands.Remove(command); flowchart.ClearSelectedCommands(); }); } // Command key pressed if (EditorGUI.actionKey) { BlockEditor.actionList.Add(delegate { flowchart.selectedCommands.Remove(command); }); Event.current.Use(); } } else { bool shift = Event.current.shift; // Left click and no command key if (!shift && !EditorGUI.actionKey && Event.current.button == 0) { BlockEditor.actionList.Add(delegate { flowchart.ClearSelectedCommands(); }); Event.current.Use(); } BlockEditor.actionList.Add(delegate { flowchart.AddSelectedCommand(command); }); // Find first and last selected commands int firstSelectedIndex = -1; int lastSelectedIndex = -1; if (flowchart.selectedCommands.Count > 0) { if (flowchart.selectedBlock != null) { for (int i = 0; i < flowchart.selectedBlock.commandList.Count; i++) { Command commandInBlock = flowchart.selectedBlock.commandList[i]; foreach (Command selectedCommand in flowchart.selectedCommands) { if (commandInBlock == selectedCommand) { firstSelectedIndex = i; break; } } } for (int i = flowchart.selectedBlock.commandList.Count - 1; i >= 0; i--) { Command commandInBlock = flowchart.selectedBlock.commandList[i]; foreach (Command selectedCommand in flowchart.selectedCommands) { if (commandInBlock == selectedCommand) { lastSelectedIndex = i; break; } } } } } if (shift) { int currentIndex = command.commandIndex; if (firstSelectedIndex == -1 || lastSelectedIndex == -1) { // No selected command found - select entire list firstSelectedIndex = 0; lastSelectedIndex = currentIndex; } else { if (currentIndex < firstSelectedIndex) { firstSelectedIndex = currentIndex; } if (currentIndex > lastSelectedIndex) { lastSelectedIndex = currentIndex; } } for (int i = Math.Min(firstSelectedIndex, lastSelectedIndex); i < Math.Max(firstSelectedIndex, lastSelectedIndex); ++i) { Command selectedCommand = flowchart.selectedBlock.commandList[i]; BlockEditor.actionList.Add(delegate { flowchart.AddSelectedCommand(selectedCommand); }); } } Event.current.Use(); } GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus) } Color commandLabelColor = Color.white; if (flowchart.colorCommands) { commandLabelColor = command.GetButtonColor(); } if (commandIsSelected) { commandLabelColor = Color.green; } else if (!command.enabled) { commandLabelColor = Color.grey; } else if (error) { // TODO: Show warning icon } GUI.backgroundColor = commandLabelColor; if (isComment) { GUI.Label(commandLabelRect, "", commandLabelStyle); } else { string commandNameLabel; if (flowchart.showLineNumbers) { commandNameLabel = command.commandIndex.ToString() + ": " + commandName; } else { commandNameLabel = commandName; } GUI.Label(commandLabelRect, commandNameLabel, commandLabelStyle); } if (command.executingIconTimer > Time.realtimeSinceStartup) { Rect iconRect = new Rect(commandLabelRect); iconRect.x += iconRect.width - commandLabelRect.width - 20; iconRect.width = 20; iconRect.height = 20; Color storeColor = GUI.color; float alpha = (command.executingIconTimer - Time.realtimeSinceStartup) / Block.executingIconFadeTime; alpha = Mathf.Clamp01(alpha); GUI.color = new Color(1f, 1f, 1f, alpha); GUI.Label(iconRect, FungusEditorResources.texPlaySmall, new GUIStyle()); GUI.color = storeColor; } Rect summaryRect = new Rect(commandLabelRect); if (isComment) { summaryRect.x += 5; } else { summaryRect.x += commandNameWidth + 5; summaryRect.width -= commandNameWidth + 5; } GUIStyle summaryStyle = new GUIStyle(); summaryStyle.fontSize = 10; summaryStyle.padding.top += 5; summaryStyle.richText = true; summaryStyle.wordWrap = false; summaryStyle.clipping = TextClipping.Clip; commandLabelStyle.alignment = TextAnchor.MiddleLeft; GUI.Label(summaryRect, summary, summaryStyle); if (error) { GUISkin editorSkin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector); Rect errorRect = new Rect(summaryRect); errorRect.x += errorRect.width - 20; errorRect.y += 2; errorRect.width = 20; GUI.Label(errorRect, editorSkin.GetStyle("CN EntryError").normal.background); summaryRect.width -= 20; } GUI.backgroundColor = Color.white; }
protected virtual IEnumerator ExecuteBlock(Action onComplete = null) { Flowchart flowchart = GetFlowchart(); executionState = ExecutionState.Executing; #if UNITY_EDITOR // Select the executing block & the first command flowchart.selectedBlock = this; if (commandList.Count > 0) { flowchart.ClearSelectedCommands(); flowchart.AddSelectedCommand(commandList[0]); } #endif int i = 0; while (true) { // Executing commands specify the next command to skip to by setting jumpToCommandIndex using Command.Continue() if (jumpToCommandIndex > -1) { i = jumpToCommandIndex; jumpToCommandIndex = -1; } // Skip disabled commands, comments and labels while (i < commandList.Count && (!commandList[i].enabled || commandList[i].GetType() == typeof(Comment) || commandList[i].GetType() == typeof(Label))) { i = commandList[i].commandIndex + 1; } if (i >= commandList.Count) { break; } // The previous active command is needed for if / else / else if commands if (activeCommand == null) { previousActiveCommandIndex = -1; } else { previousActiveCommandIndex = activeCommand.commandIndex; } Command command = commandList[i]; activeCommand = command; if (flowchart.gameObject.activeInHierarchy) { // Auto select a command in some situations if ((flowchart.selectedCommands.Count == 0 && i == 0) || (flowchart.selectedCommands.Count == 1 && flowchart.selectedCommands[0].commandIndex == previousActiveCommandIndex)) { flowchart.ClearSelectedCommands(); flowchart.AddSelectedCommand(commandList[i]); } } command.isExecuting = true; // This icon timer is managed by the FlowchartWindow class, but we also need to // set it here in case a command starts and finishes execution before the next window update. command.executingIconTimer = Time.realtimeSinceStartup + executingIconFadeTime; command.Execute(); // Wait until the executing command sets another command to jump to via Command.Continue() while (jumpToCommandIndex == -1) { yield return(null); } #if UNITY_EDITOR if (flowchart.stepPause > 0f) { yield return(new WaitForSeconds(flowchart.stepPause)); } #endif command.isExecuting = false; } executionState = ExecutionState.Idle; activeCommand = null; if (onComplete != null) { onComplete(); } }
public void DrawItem(Rect position, int index) { Command command = this[index].objectReferenceValue as Command; if (command == null) { return; } CommandInfoAttribute commandInfoAttr = CommandEditor.GetCommandInfo(command.GetType()); if (commandInfoAttr == null) { return; } Flowchart flowchart = command.GetFlowchart(); if (flowchart == null) { return; } bool isComment = command.GetType() == typeof(Comment); bool isLabel = (command.GetType() == typeof(Label)); bool error = false; string summary = command.GetSummary(); if (summary == null) { summary = ""; } else { summary = summary.Replace("\n", "").Replace("\r", ""); } if (summary.StartsWith("Error:")) { error = true; } if (isComment || isLabel) { summary = "<b> " + summary + "</b>"; } else { summary = "<i>" + summary + "</i>"; } bool commandIsSelected = false; foreach (Command selectedCommand in flowchart.selectedCommands) { if (selectedCommand == command) { commandIsSelected = true; break; } } string commandName = commandInfoAttr.CommandName; GUIStyle commandLabelStyle = new GUIStyle(GUI.skin.box); commandLabelStyle.normal.background = FungusEditorResources.texCommandBackground; int borderSize = 5; commandLabelStyle.border.top = borderSize; commandLabelStyle.border.bottom = borderSize; commandLabelStyle.border.left = borderSize; commandLabelStyle.border.right = borderSize; commandLabelStyle.alignment = TextAnchor.MiddleLeft; commandLabelStyle.richText = true; commandLabelStyle.fontSize = 11; commandLabelStyle.padding.top -= 1; float indentSize = 20; for (int i = 0; i < command.indentLevel; ++i) { Rect indentRect = position; indentRect.x += i * indentSize - 21; indentRect.width = indentSize + 1; indentRect.y -= 2; indentRect.height += 5; GUI.backgroundColor = new Color(0.5f, 0.5f, 0.5f, 1f); GUI.Box(indentRect, "", commandLabelStyle); } float commandNameWidth = Mathf.Max(commandLabelStyle.CalcSize(new GUIContent(commandName)).x, 90f); float indentWidth = command.indentLevel * indentSize; Rect commandLabelRect = position; commandLabelRect.x += indentWidth - 21; commandLabelRect.y -= 2; commandLabelRect.width -= (indentSize * command.indentLevel - 22); commandLabelRect.height += 5; // Select command via left click if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && position.Contains(Event.current.mousePosition)) { if (flowchart.selectedCommands.Contains(command) && Event.current.button == 0) { // Left click on already selected command // Command key and shift key is not pressed if (!EditorGUI.actionKey && !Event.current.shift) { flowchart.selectedCommands.Remove(command); flowchart.ClearSelectedCommands(); } // Command key pressed if (EditorGUI.actionKey) { flowchart.selectedCommands.Remove(command); } // Shift key pressed if (Event.current.shift) { flowchart.ClearSelectedCommands(); if (pinShiftToTop) { for (int i = firstSelectedIndex; i < index + 1; ++i) { flowchart.AddSelectedCommand(flowchart.selectedBlock.commandList[i]); } } else { for (int i = index; i < lastSelectedIndex + 1; ++i) { flowchart.AddSelectedCommand(flowchart.selectedBlock.commandList[i]); } } } } else { // Left click and no command key if (!Event.current.shift && !EditorGUI.actionKey && Event.current.button == 0) { flowchart.ClearSelectedCommands(); } flowchart.AddSelectedCommand(command); bool firstSelectedCommandFound = false; if (flowchart.selectedCommands.Count > 0) { if (flowchart.selectedBlock != null) { for (int i = 0; i < flowchart.selectedBlock.commandList.Count; i++) { Command commandInBlock = flowchart.selectedBlock.commandList[i]; foreach (Command selectedCommand in flowchart.selectedCommands) { if (commandInBlock == selectedCommand) { if (!firstSelectedCommandFound) { firstSelectedIndex = i; firstSelectedCommandFound = true; } lastSelectedIndex = i; } } } } } if (Event.current.shift) { for (int i = firstSelectedIndex; i < lastSelectedIndex; ++i) { flowchart.AddSelectedCommand(flowchart.selectedBlock.commandList[i]); } } if (index == firstSelectedIndex) { pinShiftToTop = false; } else if (index == lastSelectedIndex) { pinShiftToTop = true; } } GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus) } Color commandLabelColor = Color.white; if (flowchart.colorCommands) { commandLabelColor = command.GetButtonColor(); } if (commandIsSelected) { commandLabelColor = Color.green; } else if (!command.enabled) { commandLabelColor = Color.grey; } else if (error) { // TODO: Show warning icon } GUI.backgroundColor = commandLabelColor; if (isComment) { GUI.Label(commandLabelRect, "", commandLabelStyle); } else { GUI.Label(commandLabelRect, commandName, commandLabelStyle); } if (command.executingIconTimer > Time.realtimeSinceStartup) { Rect iconRect = new Rect(commandLabelRect); iconRect.x += iconRect.width - commandLabelRect.width - 20; iconRect.width = 20; iconRect.height = 20; Color storeColor = GUI.color; float alpha = (command.executingIconTimer - Time.realtimeSinceStartup) / Block.executingIconFadeTime; alpha = Mathf.Clamp01(alpha); GUI.color = new Color(1f, 1f, 1f, alpha); GUI.Label(iconRect, FungusEditorResources.texPlaySmall, new GUIStyle()); GUI.color = storeColor; } Rect summaryRect = new Rect(commandLabelRect); if (isComment) { summaryRect.x += 5; } else { summaryRect.x += commandNameWidth; summaryRect.width -= commandNameWidth; summaryRect.width -= 5; } GUIStyle summaryStyle = new GUIStyle(); summaryStyle.fontSize = 10; summaryStyle.padding.top += 5; summaryStyle.richText = true; summaryStyle.wordWrap = false; summaryStyle.clipping = TextClipping.Clip; commandLabelStyle.alignment = TextAnchor.MiddleLeft; GUI.Label(summaryRect, summary, summaryStyle); if (error) { GUISkin editorSkin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector); Rect errorRect = new Rect(summaryRect); errorRect.x += errorRect.width - 20; errorRect.y += 2; errorRect.width = 20; GUI.Label(errorRect, editorSkin.GetStyle("CN EntryError").normal.background); summaryRect.width -= 20; } GUI.backgroundColor = Color.white; }
protected virtual void DrawFlowchartView(Flowchart flowchart) { Block[] blocks = flowchart.GetComponentsInChildren <Block>(true); foreach (Block block in blocks) { flowchart.scrollViewRect.xMin = Mathf.Min(flowchart.scrollViewRect.xMin, block.nodeRect.xMin - 400); flowchart.scrollViewRect.xMax = Mathf.Max(flowchart.scrollViewRect.xMax, block.nodeRect.xMax + 400); flowchart.scrollViewRect.yMin = Mathf.Min(flowchart.scrollViewRect.yMin, block.nodeRect.yMin - 400); flowchart.scrollViewRect.yMax = Mathf.Max(flowchart.scrollViewRect.yMax, block.nodeRect.yMax + 400); } // Calc rect for script view Rect scriptViewRect = new Rect(0, 0, this.position.width / flowchart.zoom, this.position.height / flowchart.zoom); EditorZoomArea.Begin(flowchart.zoom, scriptViewRect); DrawGrid(flowchart); GLDraw.BeginGroup(scriptViewRect); if (Event.current.button == 0 && Event.current.type == EventType.MouseDown && !mouseOverVariables) { flowchart.selectedBlock = null; if (!EditorGUI.actionKey) { flowchart.ClearSelectedCommands(); } Selection.activeGameObject = flowchart.gameObject; } // Draw connections foreach (Block block in blocks) { DrawConnections(flowchart, block, false); } foreach (Block block in blocks) { DrawConnections(flowchart, block, true); } GUIStyle windowStyle = new GUIStyle(); windowStyle.stretchHeight = true; BeginWindows(); windowBlockMap.Clear(); for (int i = 0; i < blocks.Length; ++i) { Block block = blocks[i]; float nodeWidthA = nodeStyle.CalcSize(new GUIContent(block.blockName)).x + 10; float nodeWidthB = 0f; if (block.eventHandler != null) { nodeWidthB = nodeStyle.CalcSize(new GUIContent(block.eventHandler.GetSummary())).x + 10; } block.nodeRect.width = Mathf.Max(Mathf.Max(nodeWidthA, nodeWidthB), 120); block.nodeRect.height = 40; if (Event.current.button == 0) { if (Event.current.type == EventType.MouseDrag && dragWindowId == i) { block.nodeRect.x += Event.current.delta.x; block.nodeRect.y += Event.current.delta.y; forceRepaintCount = 6; } else if (Event.current.type == EventType.MouseUp && dragWindowId == i) { Vector2 newPos = new Vector2(block.nodeRect.x, block.nodeRect.y); block.nodeRect.x = startDragPosition.x; block.nodeRect.y = startDragPosition.y; Undo.RecordObject(block, "Node Position"); block.nodeRect.x = newPos.x; block.nodeRect.y = newPos.y; dragWindowId = -1; forceRepaintCount = 6; } } Rect windowRect = new Rect(block.nodeRect); windowRect.x += flowchart.scrollPos.x; windowRect.y += flowchart.scrollPos.y; GUILayout.Window(i, windowRect, DrawWindow, "", windowStyle); GUI.backgroundColor = Color.white; windowBlockMap.Add(block); } EndWindows(); // Draw play icons beside all executing blocks if (Application.isPlaying) { foreach (Block b in blocks) { if (b.IsExecuting()) { b.executingIconTimer = Time.realtimeSinceStartup + Block.executingIconFadeTime; b.activeCommand.executingIconTimer = Time.realtimeSinceStartup + Block.executingIconFadeTime; forceRepaintCount = 6; } if (b.executingIconTimer > Time.realtimeSinceStartup) { Rect rect = new Rect(b.nodeRect); rect.x += flowchart.scrollPos.x - 37; rect.y += flowchart.scrollPos.y + 3; rect.width = 34; rect.height = 34; if (!b.IsExecuting()) { float alpha = (b.executingIconTimer - Time.realtimeSinceStartup) / Block.executingIconFadeTime; alpha = Mathf.Clamp01(alpha); GUI.color = new Color(1f, 1f, 1f, alpha); } if (GUI.Button(rect, FungusEditorResources.texPlayBig as Texture, new GUIStyle())) { SelectBlock(flowchart, b); } GUI.color = Color.white; } } } PanAndZoom(flowchart); GLDraw.EndGroup(); EditorZoomArea.End(); }