public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); // The variable reference and data properties must follow the naming convention 'typeRef', 'typeVal' VariableInfoAttribute typeInfo = VariableEditor.GetVariableInfo(typeof(T)); if (typeInfo == null) { return; } string propNameBase = typeInfo.VariableType; propNameBase = Char.ToLowerInvariant(propNameBase[0]) + propNameBase.Substring(1); SerializedProperty referenceProp = property.FindPropertyRelative(propNameBase + "Ref"); SerializedProperty valueProp = property.FindPropertyRelative(propNameBase + "Val"); if (referenceProp == null || valueProp == null) { return; } Command command = property.serializedObject.targetObject as Command; if (command == null) { return; } Flowchart flowchart = command.GetFlowchart() as Flowchart; if (flowchart == null) { return; } if (EditorGUI.GetPropertyHeight(valueProp, label) > EditorGUIUtility.singleLineHeight) { DrawMultiLineProperty(position, label, referenceProp, valueProp, flowchart); } else { DrawSingleLineProperty(position, label, referenceProp, valueProp, flowchart); } EditorGUI.EndProperty(); }
public void Duplicate(int index) { Command command = _arrayProperty.GetArrayElementAtIndex(index).objectReferenceValue as Command; // Add the command as a new component Block parentBlock = command.GetComponent <Block>(); System.Type type = command.GetType(); Command newCommand = Undo.AddComponent(parentBlock.gameObject, type) as Command; newCommand.itemId = newCommand.GetFlowchart().NextItemId(); System.Reflection.FieldInfo[] fields = type.GetFields(); foreach (System.Reflection.FieldInfo field in fields) { field.SetValue(newCommand, field.GetValue(command)); } _arrayProperty.InsertArrayElementAtIndex(index); _arrayProperty.GetArrayElementAtIndex(index).objectReferenceValue = 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; }
public virtual void DrawCommandInspectorGUI() { Command t = target as Command; if (t == null) { return; } Flowchart flowchart = t.GetFlowchart(); if (flowchart == null) { return; } CommandInfoAttribute commandInfoAttr = CommandEditor.GetCommandInfo(t.GetType()); if (commandInfoAttr == null) { return; } GUILayout.BeginVertical(GUI.skin.box); if (t.enabled) { if (flowchart.colorCommands) { GUI.backgroundColor = t.GetButtonColor(); } else { GUI.backgroundColor = Color.white; } } else { GUI.backgroundColor = Color.grey; } GUILayout.BeginHorizontal(GUI.skin.button); string commandName = commandInfoAttr.CommandName; GUILayout.Label(commandName, GUILayout.MinWidth(80), GUILayout.ExpandWidth(true)); GUILayout.FlexibleSpace(); GUILayout.Label(new GUIContent("(" + t.itemId + ")")); GUILayout.Space(10); GUI.backgroundColor = Color.white; bool enabled = t.enabled; enabled = GUILayout.Toggle(enabled, new GUIContent()); if (t.enabled != enabled) { Undo.RecordObject(t, "Set Enabled"); t.enabled = enabled; } GUILayout.EndHorizontal(); GUI.backgroundColor = Color.white; EditorGUILayout.Separator(); DrawCommandGUI(); EditorGUILayout.Separator(); if (t.errorMessage.Length > 0) { GUIStyle style = new GUIStyle(GUI.skin.label); style.normal.textColor = new Color(1, 0, 0); EditorGUILayout.LabelField(new GUIContent("Error: " + t.errorMessage), style); } GUILayout.EndVertical(); // Display help text CommandInfoAttribute infoAttr = CommandEditor.GetCommandInfo(t.GetType()); if (infoAttr != null) { EditorGUILayout.HelpBox(infoAttr.HelpText, MessageType.Info, true); } }
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; }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); // The variable reference and data properties must follow the naming convention 'typeRef', 'typeVal' VariableInfoAttribute typeInfo = VariableEditor.GetVariableInfo(typeof(T)); if (typeInfo == null) { return; } string propNameBase = typeInfo.VariableType; propNameBase = Char.ToLowerInvariant(propNameBase[0]) + propNameBase.Substring(1); SerializedProperty referenceProp = property.FindPropertyRelative(propNameBase + "Ref"); SerializedProperty valueProp = property.FindPropertyRelative(propNameBase + "Val"); if (referenceProp == null || valueProp == null) { return; } const int popupWidth = 65; Rect controlRect = EditorGUI.PrefixLabel(position, label); Rect valueRect = controlRect; valueRect.width = controlRect.width - popupWidth - 5; Rect popupRect = controlRect; if (referenceProp.objectReferenceValue == null) { EditorGUI.PropertyField(valueRect, valueProp, new GUIContent("")); popupRect.x += valueRect.width + 5; popupRect.width = popupWidth; } Flowchart flowchart = property.serializedObject.targetObject as Flowchart; if (flowchart == null) { Command command = property.serializedObject.targetObject as Command; if (command != null) { flowchart = command.GetFlowchart(); } } if (flowchart != null) { T selectedVariable = referenceProp.objectReferenceValue as T; List <string> variableKeys = new List <string>(); List <Variable> variableObjects = new List <Variable>(); variableKeys.Add("<Value>"); variableObjects.Add(null); int index = 0; int selectedIndex = 0; foreach (Variable v in flowchart.variables) { if (v == null) { continue; } if (v.GetType() != typeof(T)) { continue; } variableKeys.Add(v.key); variableObjects.Add(v); index++; if (v == selectedVariable) { selectedIndex = index; } } selectedIndex = EditorGUI.Popup(popupRect, selectedIndex, variableKeys.ToArray()); referenceProp.objectReferenceValue = variableObjects[selectedIndex]; } EditorGUI.EndProperty(); }