public virtual void DrawInspectorGUI() { // Users should not be able to change the MonoScript for the command using the usual Script field. // Doing so could cause block.commandList to contain null entries. // To avoid this we manually display all properties, except for m_Script. serializedObject.Update(); SerializedProperty iterator = serializedObject.GetIterator(); bool enterChildren = true; while (iterator.NextVisible(enterChildren)) { enterChildren = false; if (iterator.name == "m_Script") { continue; } EditorGUILayout.PropertyField(iterator, true, new GUILayoutOption[0]); } EventHandler t = target as EventHandler; EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(t.GetType()); if (info != null && info.HelpText.Length > 0) { EditorGUILayout.HelpBox(info.HelpText, MessageType.Info); } serializedObject.ApplyModifiedProperties(); }
protected static void ExportEventHandlerInfo(string path) { List <System.Type> eventHandlerTypes = EditorExtensions.FindDerivedTypes(typeof(EventHandler)).ToList(); List <string> eventHandlerCategories = new List <string>(); eventHandlerCategories.Add("Core"); foreach (System.Type type in eventHandlerTypes) { EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(type); if (info != null && info.Category != "" && !eventHandlerCategories.Contains(info.Category)) { eventHandlerCategories.Add(info.Category); } } eventHandlerCategories.Sort(); // Output the commands in each category foreach (string category in eventHandlerCategories) { string markdown = ""; foreach (System.Type type in eventHandlerTypes) { EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(type); if (info != null && info.Category == category || info.Category == "" && category == "Core") { markdown += "## " + info.EventHandlerName + "\n"; markdown += info.HelpText + "\n"; markdown += GetPropertyInfo(type); } } string filePath = path + "/event_handlers/" + category.ToLower() + "_events.md"; Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllText(filePath, markdown); } }
protected virtual void DrawWindow(int windowId) { Block block = windowBlockMap[windowId]; Flowchart flowchart = block.GetFlowchart(); // Select block when node is clicked if (Event.current.button == 0 && Event.current.type == EventType.MouseDown && !mouseOverVariables) { // Check if might be start of a window drag if (Event.current.button == 0 && Event.current.alt == false) { dragWindowId = windowId; startDragPosition.x = block.nodeRect.x; startDragPosition.y = block.nodeRect.y; } if (windowId < windowBlockMap.Count) { Undo.RecordObject(flowchart, "Select"); SelectBlock(flowchart, block); GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus) } } bool selected = (flowchart.selectedBlock == block); GUIStyle nodeStyleCopy = new GUIStyle(nodeStyle); if (block.eventHandler != null) { nodeStyleCopy.normal.background = selected ? FungusEditorResources.texEventNodeOn : FungusEditorResources.texEventNodeOff; } else { // Count the number of unique connections (excluding self references) List <Block> uniqueList = new List <Block>(); List <Block> connectedBlocks = block.GetConnectedBlocks(); foreach (Block connectedBlock in connectedBlocks) { if (connectedBlock == block || uniqueList.Contains(connectedBlock)) { continue; } uniqueList.Add(connectedBlock); } if (uniqueList.Count > 1) { nodeStyleCopy.normal.background = selected ? FungusEditorResources.texChoiceNodeOn : FungusEditorResources.texChoiceNodeOff; } else { nodeStyleCopy.normal.background = selected ? FungusEditorResources.texProcessNodeOn : FungusEditorResources.texProcessNodeOff; } } nodeStyleCopy.normal.textColor = Color.black; // Make sure node is wide enough to fit the node name text float width = nodeStyleCopy.CalcSize(new GUIContent(block.blockName)).x; block.nodeRect.width = Mathf.Max(block.nodeRect.width, width); GUI.backgroundColor = Color.white; GUILayout.Box(block.blockName, nodeStyleCopy, GUILayout.Width(block.nodeRect.width), GUILayout.Height(block.nodeRect.height)); if (block.eventHandler != null) { string handlerLabel = ""; EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(block.eventHandler.GetType()); if (info != null) { handlerLabel = "<" + info.EventHandlerName + "> "; } string handlerSummary = block.eventHandler.GetSummary(); if (handlerSummary.Length > 0) { handlerLabel += handlerSummary; } GUIStyle handlerStyle = new GUIStyle(EditorStyles.helpBox); handlerStyle.wordWrap = true; handlerStyle.margin.top = 0; handlerStyle.margin.bottom = 0; GUILayout.Label(handlerLabel, handlerStyle); // Move connection marker down below handler description float height = 44 + handlerStyle.CalcHeight(new GUIContent(handlerLabel), block.nodeRect.width); block.nodeRect.height = height; } if (block.description.Length > 0) { GUIStyle descriptionStyle = new GUIStyle(EditorStyles.whiteLabel); descriptionStyle.wordWrap = true; GUILayout.Label(block.description, descriptionStyle); } if (Event.current.type == EventType.ContextClick) { GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Duplicate"), false, DuplicateBlock, block); menu.AddItem(new GUIContent("Delete"), false, DeleteBlock, block); menu.ShowAsContext(); } }
protected virtual void DrawEventHandlerGUI(Flowchart flowchart) { // Show available Event Handlers in a drop down list with type of current // event handler selected. List <System.Type> eventHandlerTypes = EditorExtensions.FindDerivedTypes(typeof(EventHandler)).ToList(); Block block = target as Block; System.Type currentType = null; if (block.eventHandler != null) { currentType = block.eventHandler.GetType(); } string currentHandlerName = "<None>"; if (currentType != null) { EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(currentType); if (info != null) { currentHandlerName = info.EventHandlerName; } } EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(new GUIContent("Execute On Event")); if (GUILayout.Button(new GUIContent(currentHandlerName), EditorStyles.popup)) { SetEventHandlerOperation noneOperation = new SetEventHandlerOperation(); noneOperation.block = block; noneOperation.eventHandlerType = null; GenericMenu eventHandlerMenu = new GenericMenu(); eventHandlerMenu.AddItem(new GUIContent("None"), false, OnSelectEventHandler, noneOperation); // Add event handlers with no category first foreach (System.Type type in eventHandlerTypes) { EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(type); if (info.Category.Length == 0) { SetEventHandlerOperation operation = new SetEventHandlerOperation(); operation.block = block; operation.eventHandlerType = type; eventHandlerMenu.AddItem(new GUIContent(info.EventHandlerName), false, OnSelectEventHandler, operation); } } // Add event handlers with a category afterwards foreach (System.Type type in eventHandlerTypes) { EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(type); if (info.Category.Length > 0) { SetEventHandlerOperation operation = new SetEventHandlerOperation(); operation.block = block; operation.eventHandlerType = type; string typeName = info.Category + "/" + info.EventHandlerName; eventHandlerMenu.AddItem(new GUIContent(typeName), false, OnSelectEventHandler, operation); } } eventHandlerMenu.ShowAsContext(); } EditorGUILayout.EndHorizontal(); if (block.eventHandler != null) { EventHandlerEditor eventHandlerEditor = Editor.CreateEditor(block.eventHandler) as EventHandlerEditor; if (eventHandlerEditor != null) { eventHandlerEditor.DrawInspectorGUI(); DestroyImmediate(eventHandlerEditor); } } }
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; } // 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. CalcFlowchartCenter(flowchart, blocks); // 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 Event Handler labels foreach (Block block in blocks) { if (block.eventHandler != null) { string handlerLabel = ""; EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(block.eventHandler.GetType()); if (info != null) { handlerLabel = "<" + info.EventHandlerName + "> "; } GUIStyle handlerStyle = new GUIStyle(EditorStyles.whiteLabel); handlerStyle.wordWrap = true; handlerStyle.margin.top = 0; handlerStyle.margin.bottom = 0; handlerStyle.alignment = TextAnchor.MiddleCenter; Rect rect = new Rect(block.nodeRect); rect.height = handlerStyle.CalcHeight(new GUIContent(handlerLabel), block.nodeRect.width); rect.x += flowchart.scrollPos.x; rect.y += flowchart.scrollPos.y - rect.height; GUI.Label(rect, handlerLabel, handlerStyle); } } // 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(); }
protected virtual void DrawWindow(int windowId) { Sequence sequence = windowSequenceMap[windowId]; FungusScript fungusScript = sequence.GetFungusScript(); // Select sequence when node is clicked if (Event.current.button == 0 && Event.current.type == EventType.MouseDown && !mouseOverVariables) { // Check if might be start of a window drag if (Event.current.button == 0) { dragWindowId = windowId; startDragPosition.x = sequence.nodeRect.x; startDragPosition.y = sequence.nodeRect.y; } if (windowId < windowSequenceMap.Count) { Undo.RecordObject(fungusScript, "Select"); SelectSequence(fungusScript, sequence); GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus) } } bool selected = (fungusScript.selectedSequence == sequence); GUIStyle nodeStyleCopy = new GUIStyle(nodeStyle); if (sequence.eventHandler != null) { nodeStyleCopy.normal.background = selected ? FungusEditorResources.texEventNodeOn : FungusEditorResources.texEventNodeOff; } else { // Count the number of unique connections (excluding self references) List <Sequence> uniqueList = new List <Sequence>(); List <Sequence> connectedSequences = sequence.GetConnectedSequences(); foreach (Sequence connectedSequence in connectedSequences) { if (connectedSequence == sequence || uniqueList.Contains(connectedSequence)) { continue; } uniqueList.Add(connectedSequence); } if (uniqueList.Count > 1) { nodeStyleCopy.normal.background = selected ? FungusEditorResources.texChoiceNodeOn : FungusEditorResources.texChoiceNodeOff; } else { nodeStyleCopy.normal.background = selected ? FungusEditorResources.texProcessNodeOn : FungusEditorResources.texProcessNodeOff; } } // Show event handler name, or a custom summary if one is provided string nodeName = ""; if (sequence.eventHandler != null) { string handlerSummary = sequence.eventHandler.GetSummary(); if (handlerSummary == "") { EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(sequence.eventHandler.GetType()); if (info != null) { handlerSummary = info.EventHandlerName; } } nodeName = "(" + handlerSummary + ")\n"; } nodeName += sequence.sequenceName; // Make sure node is wide enough to fit the node name text float width = nodeStyleCopy.CalcSize(new GUIContent(nodeName)).x; sequence.nodeRect.width = Mathf.Max(sequence.nodeRect.width, width); GUILayout.Box(nodeName, nodeStyleCopy, GUILayout.Width(sequence.nodeRect.width), GUILayout.Height(sequence.nodeRect.height)); if (sequence.description.Length > 0) { GUILayout.Label(sequence.description, EditorStyles.whiteLabel); } if (Event.current.type == EventType.ContextClick) { GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Duplicate"), false, DuplicateSequence, sequence); menu.AddItem(new GUIContent("Delete"), false, DeleteSequence, sequence); menu.ShowAsContext(); } }