/// <summary> /// Draw list field control for adapted collection. /// </summary> /// <param name="position">Position of control.</param> /// <param name="adaptor">Reorderable list adaptor.</param> /// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> /// <param name="flags">Optional flags to pass into list field.</param> private static void DoListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) { ReorderableListControl.DrawControlFromState(position, adaptor, drawEmpty, flags); }
/// <summary> /// Draw list field control for serializable property array. /// </summary> /// <param name="position">Position of control.</param> /// <param name="arrayProperty">Serializable property.</param> /// <param name="fixedItemHeight">Use fixed height for items rather than <see cref="UnityEditor.EditorGUI.GetPropertyHeight(SerializedProperty)"/>.</param> /// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> /// <param name="flags">Optional flags to pass into list field.</param> private static void DoListFieldAbsolute(Rect position, SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) { var adaptor = new SerializedPropertyAdaptor(arrayProperty, fixedItemHeight); ReorderableListControl.DrawControlFromState(position, adaptor, drawEmpty, flags); }
/// <summary> /// Draw list field control for adapted collection. /// </summary> /// <param name="adaptor">Reorderable list adaptor.</param> /// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> /// <param name="flags">Optional flags to pass into list field.</param> private static void DoListField(IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags) { ReorderableListControl.DrawControlFromState(adaptor, drawEmpty, flags); }
/// <summary> /// Draw list field control. /// </summary> /// <param name="list">The list which can be reordered.</param> /// <param name="drawItem">Callback to draw list item.</param> /// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> /// <param name="itemHeight">Height of a single list item.</param> /// <param name="flags">Optional flags to pass into list field.</param> /// <typeparam name="T">Type of list item.</typeparam> private static void DoListField <T>(IList <T> list, ReorderableListControl.ItemDrawer <T> drawItem, ReorderableListControl.DrawEmpty drawEmpty, float itemHeight, ReorderableListFlags flags) { var adaptor = new GenericListAdaptor <T>(list, drawItem, itemHeight); ReorderableListControl.DrawControlFromState(adaptor, drawEmpty, flags); }
/// <summary> /// Draw list field control with absolute positioning. /// </summary> /// <param name="position">Position of control.</param> /// <param name="list">The list which can be reordered.</param> /// <param name="drawItem">Callback to draw list item.</param> /// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> /// <param name="itemHeight">Height of a single list item.</param> /// <param name="flags">Optional flags to pass into list field.</param> /// <typeparam name="T">Type of list item.</typeparam> private static void DoListFieldAbsolute <T>(Rect position, IList <T> list, ReorderableListControl.ItemDrawer <T> drawItem, ReorderableListControl.DrawEmptyAbsolute drawEmpty, float itemHeight, ReorderableListFlags flags) { var adaptor = new GenericListAdaptor <T>(list, drawItem, itemHeight); ReorderableListControl.DrawControlFromState(position, adaptor, drawEmpty, flags); }
public virtual void DrawVariablesGUI() { serializedObject.Update(); FungusScript t = target as FungusScript; if (t.variables.Count == 0) { t.variablesExpanded = true; } if (!t.variablesExpanded) { if (GUILayout.Button("Variables (" + t.variables.Count + ")", GUILayout.Height(24))) { t.variablesExpanded = true; } } else { Rect listRect = new Rect(); if (t.variables.Count > 0) { ReorderableListGUI.Title("Variables"); VariableListAdaptor adaptor = new VariableListAdaptor(variablesProp, 0); ReorderableListFlags flags = ReorderableListFlags.DisableContextMenu | ReorderableListFlags.HideAddButton; ReorderableListControl.DrawControlFromState(adaptor, null, flags); listRect = GUILayoutUtility.GetLastRect(); } else { GUILayoutUtility.GetRect(300, 24); listRect = GUILayoutUtility.GetLastRect(); listRect.y += 20; } float plusWidth = 32; float plusHeight = 24; Rect buttonRect = listRect; float buttonHeight = 24; buttonRect.x = 4; buttonRect.y -= buttonHeight - 1; buttonRect.height = buttonHeight; if (!Application.isPlaying) { buttonRect.width -= 30; } if (GUI.Button(buttonRect, "Variables")) { t.variablesExpanded = false; } Rect plusRect = listRect; plusRect.x += plusRect.width - plusWidth; plusRect.y -= plusHeight - 1; plusRect.width = plusWidth; plusRect.height = plusHeight; if (!Application.isPlaying && GUI.Button(plusRect, FungusEditorResources.texAddButton)) { GenericMenu menu = new GenericMenu(); List <System.Type> types = FindAllDerivedTypes <Variable>(); // Add variable types without a category foreach (System.Type type in types) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(type); if (variableInfo == null || variableInfo.Category != "") { continue; } AddVariableInfo addVariableInfo = new AddVariableInfo(); addVariableInfo.fungusScript = t; addVariableInfo.variableType = type; GUIContent typeName = new GUIContent(variableInfo.VariableType); menu.AddItem(typeName, false, AddVariable, addVariableInfo); } // Add types with a category foreach (System.Type type in types) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(type); if (variableInfo == null || variableInfo.Category == "") { continue; } AddVariableInfo info = new AddVariableInfo(); info.fungusScript = t; info.variableType = type; GUIContent typeName = new GUIContent(variableInfo.Category + "/" + variableInfo.VariableType); menu.AddItem(typeName, false, AddVariable, info); } menu.ShowAsContext(); } } serializedObject.ApplyModifiedProperties(); }
public virtual void DrawSequenceGUI(FungusScript fungusScript) { serializedObject.Update(); Sequence sequence = target as Sequence; SerializedProperty descriptionProp = serializedObject.FindProperty("description"); EditorGUILayout.PropertyField(descriptionProp); SerializedProperty runSlowInEditorProp = serializedObject.FindProperty("runSlowInEditor"); EditorGUILayout.PropertyField(runSlowInEditorProp); DrawEventHandlerGUI(fungusScript); UpdateIndentLevels(sequence); SerializedProperty sequenceNameProperty = serializedObject.FindProperty("sequenceName"); Rect sequenceLabelRect = new Rect(45, 5, 120, 16); EditorGUI.LabelField(sequenceLabelRect, new GUIContent("Sequence Name")); Rect sequenceNameRect = new Rect(45, 21, 180, 16); EditorGUI.PropertyField(sequenceNameRect, sequenceNameProperty, new GUIContent("")); // Ensure sequence name is unique for this Fungus Script string uniqueName = fungusScript.GetUniqueSequenceKey(sequenceNameProperty.stringValue, sequence); if (uniqueName != sequence.sequenceName) { sequenceNameProperty.stringValue = uniqueName; } // Make sure each command has a reference to its parent sequence foreach (Command command in sequence.commandList) { if (command == null) // Will be deleted from the list later on { continue; } command.parentSequence = sequence; } SerializedProperty commandListProperty = serializedObject.FindProperty("commandList"); ReorderableListGUI.Title("Commands"); CommandListAdaptor adaptor = new CommandListAdaptor(commandListProperty, 0); adaptor.nodeRect = sequence.nodeRect; ReorderableListFlags flags = ReorderableListFlags.HideAddButton | ReorderableListFlags.HideRemoveButtons | ReorderableListFlags.DisableContextMenu; ReorderableListControl.DrawControlFromState(adaptor, null, flags); if (Event.current.type == EventType.ContextClick) { ShowContextMenu(); } if (sequence == fungusScript.selectedSequence) { // Show add command button { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button(FungusEditorResources.texAddButton)) { ShowCommandMenu(); } GUILayout.EndHorizontal(); } } // Remove any null entries in the command list. // This can happen when a command class is deleted or renamed. for (int i = commandListProperty.arraySize - 1; i >= 0; --i) { SerializedProperty commandProperty = commandListProperty.GetArrayElementAtIndex(i); if (commandProperty.objectReferenceValue == null) { commandListProperty.DeleteArrayElementAtIndex(i); } } serializedObject.ApplyModifiedProperties(); }
public virtual void DrawVariablesGUI() { serializedObject.Update(); Flowchart t = target as Flowchart; if (t.variables.Count == 0) { t.variablesExpanded = true; } if (!t.variablesExpanded) { if (GUILayout.Button("Variables (" + t.variables.Count + ")", GUILayout.Height(24))) { t.variablesExpanded = true; } // Draw disclosure triangle Rect lastRect = GUILayoutUtility.GetLastRect(); lastRect.x += 5; lastRect.y += 5; EditorGUI.Foldout(lastRect, false, ""); } else { Rect listRect = new Rect(); if (t.variables.Count > 0) { // Remove any null variables from the list // Can sometimes happen when upgrading to a new version of Fungus (if .meta GUID changes for a variable class) for (int i = t.variables.Count - 1; i >= 0; i--) { if (t.variables[i] == null) { t.variables.RemoveAt(i); } } ReorderableListGUI.Title("Variables"); VariableListAdaptor adaptor = new VariableListAdaptor(variablesProp, 0); ReorderableListFlags flags = ReorderableListFlags.DisableContextMenu | ReorderableListFlags.HideAddButton; ReorderableListControl.DrawControlFromState(adaptor, null, flags); listRect = GUILayoutUtility.GetLastRect(); } else { GUILayoutUtility.GetRect(300, 24); listRect = GUILayoutUtility.GetLastRect(); listRect.y += 20; } float plusWidth = 32; float plusHeight = 24; Rect buttonRect = listRect; float buttonHeight = 24; buttonRect.x = 4; buttonRect.y -= buttonHeight - 1; buttonRect.height = buttonHeight; if (!Application.isPlaying) { buttonRect.width -= 30; } if (GUI.Button(buttonRect, "Variables")) { t.variablesExpanded = false; } // Draw disclosure triangle Rect lastRect = buttonRect; lastRect.x += 5; lastRect.y += 5; EditorGUI.Foldout(lastRect, true, ""); Rect plusRect = listRect; plusRect.x += plusRect.width - plusWidth; plusRect.y -= plusHeight - 1; plusRect.width = plusWidth; plusRect.height = plusHeight; if (!Application.isPlaying && GUI.Button(plusRect, addTexture)) { GenericMenu menu = new GenericMenu(); List <System.Type> types = FindAllDerivedTypes <Variable>(); // Add variable types without a category foreach (System.Type type in types) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(type); if (variableInfo == null || variableInfo.Category != "") { continue; } AddVariableInfo addVariableInfo = new AddVariableInfo(); addVariableInfo.flowchart = t; addVariableInfo.variableType = type; GUIContent typeName = new GUIContent(variableInfo.VariableType); menu.AddItem(typeName, false, AddVariable, addVariableInfo); } // Add types with a category foreach (System.Type type in types) { VariableInfoAttribute variableInfo = VariableEditor.GetVariableInfo(type); if (variableInfo == null || variableInfo.Category == "") { continue; } AddVariableInfo info = new AddVariableInfo(); info.flowchart = t; info.variableType = type; GUIContent typeName = new GUIContent(variableInfo.Category + "/" + variableInfo.VariableType); menu.AddItem(typeName, false, AddVariable, info); } menu.ShowAsContext(); } } serializedObject.ApplyModifiedProperties(); }
public virtual void DrawBlockGUI(Flowchart flowchart) { serializedObject.Update(); // Execute any queued cut, copy, paste, etc. operations from the prevous GUI update // We need to defer applying these operations until the following update because // the ReorderableList control emits GUI errors if you clear the list in the same frame // as drawing the control (e.g. select all and then delete) if (Event.current.type == EventType.Layout) { foreach (Action action in actionList) { if (action != null) { action(); } } actionList.Clear(); } var block = target as Block; SerializedProperty commandListProperty = serializedObject.FindProperty("commandList"); if (block == flowchart.SelectedBlock) { // Custom tinting SerializedProperty useCustomTintProp = serializedObject.FindProperty("useCustomTint"); SerializedProperty tintProp = serializedObject.FindProperty("tint"); EditorGUILayout.BeginHorizontal(); useCustomTintProp.boolValue = GUILayout.Toggle(useCustomTintProp.boolValue, " Custom Tint"); if (useCustomTintProp.boolValue) { EditorGUILayout.PropertyField(tintProp, GUIContent.none); } EditorGUILayout.EndHorizontal(); SerializedProperty descriptionProp = serializedObject.FindProperty("description"); EditorGUILayout.PropertyField(descriptionProp); DrawEventHandlerGUI(flowchart); block.UpdateIndentLevels(); // Make sure each command has a reference to its parent block foreach (var command in block.CommandList) { if (command == null) // Will be deleted from the list later on { continue; } command.ParentBlock = block; } ReorderableListGUI.Title("Commands"); CommandListAdaptor adaptor = new CommandListAdaptor(commandListProperty, 0); adaptor.nodeRect = block._NodeRect; ReorderableListFlags flags = ReorderableListFlags.HideAddButton | ReorderableListFlags.HideRemoveButtons | ReorderableListFlags.DisableContextMenu; if (block.CommandList.Count == 0) { EditorGUILayout.HelpBox("Press the + button below to add a command to the list.", MessageType.Info); } else { ReorderableListControl.DrawControlFromState(adaptor, null, flags); } // EventType.contextClick doesn't register since we moved the Block Editor to be inside // a GUI Area, no idea why. As a workaround we just check for right click instead. if (Event.current.type == EventType.MouseUp && Event.current.button == 1) { ShowContextMenu(); Event.current.Use(); } if (GUIUtility.keyboardControl == 0) //Only call keyboard shortcuts when not typing in a text field { Event e = Event.current; // Copy keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "Copy") { if (flowchart.SelectedCommands.Count > 0) { e.Use(); } } if (e.type == EventType.ExecuteCommand && e.commandName == "Copy") { actionList.Add(Copy); e.Use(); } // Cut keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "Cut") { if (flowchart.SelectedCommands.Count > 0) { e.Use(); } } if (e.type == EventType.ExecuteCommand && e.commandName == "Cut") { actionList.Add(Cut); e.Use(); } // Paste keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "Paste") { CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance(); if (commandCopyBuffer.HasCommands()) { e.Use(); } } if (e.type == EventType.ExecuteCommand && e.commandName == "Paste") { actionList.Add(Paste); e.Use(); } // Duplicate keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "Duplicate") { if (flowchart.SelectedCommands.Count > 0) { e.Use(); } } if (e.type == EventType.ExecuteCommand && e.commandName == "Duplicate") { actionList.Add(Copy); actionList.Add(Paste); e.Use(); } // Delete keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "Delete") { if (flowchart.SelectedCommands.Count > 0) { e.Use(); } } if (e.type == EventType.ExecuteCommand && e.commandName == "Delete") { actionList.Add(Delete); e.Use(); } // SelectAll keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "SelectAll") { e.Use(); } if (e.type == EventType.ExecuteCommand && e.commandName == "SelectAll") { actionList.Add(SelectAll); e.Use(); } } } // Remove any null entries in the command list. // This can happen when a command class is deleted or renamed. for (int i = commandListProperty.arraySize - 1; i >= 0; --i) { SerializedProperty commandProperty = commandListProperty.GetArrayElementAtIndex(i); if (commandProperty.objectReferenceValue == null) { commandListProperty.DeleteArrayElementAtIndex(i); } } serializedObject.ApplyModifiedProperties(); }
/// <summary> /// Draw list field control for serializable property array. /// </summary> /// <param name="arrayProperty">Serializable property.</param> /// <param name="fixedItemHeight">Use fixed height for items rather than <see cref="UnityEditor.EditorGUI.GetPropertyHeight(SerializedProperty)"/>.</param> /// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> /// <param name="flags">Optional flags to pass into list field.</param> static void DoListField(SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags) { var adaptor = new SerializedPropertyAdaptor(arrayProperty, fixedItemHeight); ReorderableListControl.DrawControlFromState(adaptor, drawEmpty, flags); }