public DataItemAttribute( bool writableName, ReorderableListFlags listFlags, bool autoGenerate, Type scriptBaseType) { _writableName = writableName; _listFlags = listFlags; _autoGenerate = autoGenerate; _scriptBaseType = scriptBaseType; }
/// <summary> /// Calculate height of list field for adapted collection. /// </summary> /// <param name="adaptor">Reorderable list adaptor.</param> /// <param name="flags">Optional flags to pass into list field.</param> /// <returns>Required list height in pixels.</returns> public static float CalculateListFieldHeight(IReorderableListAdaptor adaptor, ReorderableListFlags flags) { // We need to push/pop flags so that nested controls are properly // calculated. var restoreFlags = defaultListControl.flags; try { defaultListControl.flags = flags; return defaultListControl.CalculateListHeight(adaptor); } finally { defaultListControl.flags = restoreFlags; } }
/// <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); }
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(); }
/// <summary> /// Calculate height of list field for adapted collection. /// </summary> /// <param name="adaptor">Reorderable list adaptor.</param> /// <param name="flags">Optional flags to pass into list field.</param> /// <returns> /// Required list height in pixels. /// </returns> public static float CalculateListFieldHeight(IReorderableListAdaptor adaptor, ReorderableListFlags flags) { // We need to push/pop flags so that nested controls are properly calculated. var restoreFlags = DefaultListControl.Flags; try { DefaultListControl.Flags = flags; return(DefaultListControl.CalculateListHeight(adaptor)); } finally { DefaultListControl.Flags = restoreFlags; } }
private static void DrawIndentedList <T>(IList <T> list, ReorderableListFlags flags, Func <Rect, T, T> drawer) { if (list.Count == 0) { EditorGUILayout.HelpBox("No items in list", MessageType.Info); return; } var enableReordering = (flags & ReorderableListFlags.EnableReordering) != 0; var showIndices = (flags & ReorderableListFlags.ShowIndices) != 0; var indentLevel = EditorGUI.indentLevel; using (IndentLevelScope(-EditorGUI.indentLevel)) { for (var i = 0; i < list.Count; i++) { var item = list[i]; var controlRect = EditorGUILayout.GetControlRect(false); using (IndentLevelScope(indentLevel)) { controlRect = EditorGUI.IndentedRect(controlRect); } if (showIndices) { var indexContent = new GUIContent(i.ToString()); var indexRect = new Rect(controlRect); indexRect.width = GUI.skin.label.CalcSize(indexContent).x; GUI.Label(indexRect, indexContent); controlRect.x += indexRect.width + 5; controlRect.width -= indexRect.width + 5; } var drawerRect = new Rect(controlRect); if (enableReordering) { drawerRect.width -= 40; } drawer(drawerRect, item); if (enableReordering) { var buttonRect = new Rect(controlRect); buttonRect.x = buttonRect.xMax - 40; buttonRect.width = 20; using (new EditorGUI.DisabledScope(i == 0)) { if (GUI.Button(buttonRect, MoveUpButtonContents)) { SwapInList(list, i, i - 1); } } buttonRect.x += 20; using (new EditorGUI.DisabledScope(i == list.Count - 1)) { if (GUI.Button(buttonRect, MoveDownButtonContents)) { SwapInList(list, i, i + 1); } } } } } }
/// <summary> /// Generate and draw control from state object. /// </summary> /// <param name="position">Position of control.</param> /// <param name="adaptor">Reorderable list adaptor.</param> /// <param name="drawEmpty">Delegate for drawing empty list.</param> /// <param name="flags">Optional flags to pass into list field.</param> public static void DrawControlFromState(Rect position, IReorderableListAdaptor adaptor, DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) { int controlID = GUIUtility.GetControlID(FocusType.Passive); var control = GUIUtility.GetStateObject(typeof(ReorderableListControl), controlID) as ReorderableListControl; control.Flags = flags; control.Draw(position, controlID, adaptor, drawEmpty); }
/// <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); }
/// <inheritdoc cref="DoListField{T}(IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmpty, float, ReorderableListFlags)"/> public static void ListField <T>(IList <T> list, ReorderableListControl.ItemDrawer <T> drawItem, ReorderableListFlags flags) { DoListField <T>(list, drawItem, null, DefaultItemHeight, flags); }
/// <inheritdoc cref="DoListFieldAbsolute{T}(Rect, IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmptyAbsolute, float, ReorderableListFlags)"/> public static void ListFieldAbsolute <T>(Rect position, IList <T> list, ReorderableListControl.ItemDrawer <T> drawItem, ReorderableListControl.DrawEmptyAbsolute drawEmpty, float itemHeight, ReorderableListFlags flags) { DoListFieldAbsolute <T>(position, list, drawItem, drawEmpty, itemHeight, flags); }
/// <inheritdoc cref="DoListField{T}(IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmpty, float, ReorderableListFlags)"/> public static void ListField <T>(IList <T> list, ReorderableListControl.ItemDrawer <T> drawItem, ReorderableListControl.DrawEmpty drawEmpty, float itemHeight, ReorderableListFlags flags) { DoListField <T>(list, drawItem, drawEmpty, itemHeight, 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); }
/// <summary> /// Calculate height of list field for absolute positioning. /// </summary> /// <param name="itemCount">Count of items in list.</param> /// <param name="itemHeight">Fixed height of list item.</param> /// <param name="flags">Optional flags to pass into list field.</param> /// <returns> /// Required list height in pixels. /// </returns> public static float CalculateListFieldHeight(int itemCount, float itemHeight, ReorderableListFlags flags) { // We need to push/pop flags so that nested controls are properly calculated. var restoreFlags = defaultListControl.flags; try { defaultListControl.flags = flags; return(defaultListControl.CalculateListHeight(itemCount, itemHeight)); } finally { defaultListControl.flags = restoreFlags; } }
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(); }
private void DrawListField( string fieldName, Core.PropertyInfoType type, Type @enum, Type ptrType, IList list, Entity entity, bool isResizable) { ReorderableListGUI.Title(fieldName); ReorderableListFlags flags = ReorderableListFlags.ShowIndices; if (!isResizable) { flags = ReorderableListFlags.HideAddButton | ReorderableListFlags.HideRemoveButtons | ReorderableListFlags.ShowIndices; } switch (type) { case Core.PropertyInfoType.Int8: ReorderableListGUI.ListField( list as IList <sbyte>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.UInt8: ReorderableListGUI.ListField( list as IList <byte>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Int16: ReorderableListGUI.ListField( list as IList <short>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.UInt16: ReorderableListGUI.ListField( list as IList <ushort>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Int32: if (@enum != null) { // I'm sorry // I'll fix this later I swear var castList = new List <int>(list.Count); castList.AddRange(from object item in list select Convert.ToInt32(item)); ReorderableListGUI.ListField( castList, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); list.Clear(); foreach (var item in castList) { list.Add(Enum.ToObject(@enum, item)); } break; } ReorderableListGUI.ListField( list as IList <int>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.UInt32: ReorderableListGUI.ListField( list as IList <uint>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Int64: ReorderableListGUI.ListField( list as IList <long>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.UInt64: ReorderableListGUI.ListField( list as IList <ulong>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Float: ReorderableListGUI.ListField( list as IList <float>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Double: ReorderableListGUI.ListField( list as IList <double>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Bool: ReorderableListGUI.ListField( list as IList <bool>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.String: ReorderableListGUI.ListField( list as IList <string>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Path: ReorderableListGUI.ListField( list as IList <UnityEngine.Object>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.EntityPtr: var genericAdapterType = typeof(EntityPtrListAdapter <>).MakeGenericType(ptrType); var adapter = Activator.CreateInstance(genericAdapterType, list, ptrType, entity) as IReorderableListAdaptor; ReorderableListGUI.ListField(adapter); break; case Core.PropertyInfoType.Vector3: ReorderableListGUI.ListField( list as IList <UnityEngine.Vector3>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Vector4: ReorderableListGUI.ListField( list as IList <UnityEngine.Vector4>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Quat: ReorderableListGUI.ListField( list as IList <UnityEngine.Quaternion>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Matrix3: break; case Core.PropertyInfoType.Matrix4: ReorderableListGUI.ListField( list as IList <UnityEngine.Matrix4x4>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.Color: ReorderableListGUI.ListField( list as IList <Color>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.FilePtr: ReorderableListGUI.ListField( list as IList <UnityEngine.Object>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.EntityHandle: ReorderableListGUI.ListField( list as IList <Entity>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.EntityLink: ReorderableListGUI.ListField( list as IList <EntityLink>, (position, itemValue) => DrawListItem(position, itemValue, type, @enum, ptrType), DrawEmpty, flags); break; case Core.PropertyInfoType.PropertyInfo: break; case Core.PropertyInfoType.WideVector3: break; default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } }
/// <inheritdoc cref="DoListField(IReorderableListAdaptor, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> public static void ListField(IReorderableListAdaptor adaptor, ReorderableListFlags flags) { DoListField(adaptor, null, flags); }
/// <inheritdoc cref="DoListFieldAbsolute(Rect, IReorderableListAdaptor, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> public static void ListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor, ReorderableListFlags flags) { DoListFieldAbsolute(position, adaptor, null, flags); }
/// <inheritdoc cref="DoListFieldAbsolute{T}(Rect, IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmptyAbsolute, float, ReorderableListFlags)"/> public static void ListFieldAbsolute <T>(Rect position, IList <T> list, ReorderableListControl.ItemDrawer <T> drawItem, ReorderableListFlags flags) { DoListFieldAbsolute <T>(position, list, drawItem, null, DefaultItemHeight, flags); }
public DataItemAttribute() { _writableName = true; _listFlags = ReorderableListFlags.DisableReordering; }
/// <inheritdoc cref="CalculateListFieldHeight(int, float, ReorderableListFlags)"/> public static float CalculateListFieldHeight(int itemCount, ReorderableListFlags flags) { return(CalculateListFieldHeight(itemCount, DefaultItemHeight, flags)); }
private bool HasFlag(ReorderableListFlags flag) { return (Flags & flag) != 0; }
/// <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); }
/// <inheritdoc cref="DoListFieldAbsolute(Rect, SerializedProperty, float, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> public static void ListFieldAbsolute(Rect position, SerializedProperty arrayProperty, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) { DoListFieldAbsolute(position, arrayProperty, 0, drawEmpty, flags); }
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(); // Up Button Texture2D upIcon = Resources.Load("Icons/up") as Texture2D; if (GUILayout.Button(upIcon)) { SelectPrevious(); } // Down Button Texture2D downIcon = Resources.Load("Icons/down") as Texture2D; if (GUILayout.Button(downIcon)) { SelectNext(); } GUILayout.FlexibleSpace(); // Add Button Texture2D addIcon = Resources.Load("Icons/add") as Texture2D; if (GUILayout.Button(addIcon) || ((Event.current.type == EventType.KeyDown) && (Event.current.keyCode == KeyCode.A))) { ShowCommandMenu(); } // Duplicate Button Texture2D duplicateIcon = Resources.Load("Icons/duplicate") as Texture2D; if (GUILayout.Button(duplicateIcon)) { Copy(); Paste(); } // Delete Button Texture2D deleteIcon = Resources.Load("Icons/delete") as Texture2D; if (GUILayout.Button(deleteIcon) || ((Event.current.type == EventType.KeyDown) && (Event.current.keyCode == KeyCode.Delete))) { Delete(); } 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(); }
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> public static void ListField(SerializedProperty arrayProperty, ReorderableListFlags flags) { DoListField(arrayProperty, 0, null, flags); }
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(); } Block block = target as Block; SerializedProperty commandListProperty = serializedObject.FindProperty("commandList"); if (block == flowchart.selectedBlock) { SerializedProperty descriptionProp = serializedObject.FindProperty("description"); EditorGUILayout.PropertyField(descriptionProp); DrawEventHandlerGUI(flowchart); UpdateIndentLevels(block); // Make sure each command has a reference to its parent block foreach (Command 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> /// Calculate height of list field for absolute positioning. /// </summary> /// <param name="arrayProperty">Serializable property.</param> /// <param name="flags">Optional flags to pass into list field.</param> /// <returns> /// Required list height in pixels. /// </returns> public static float CalculateListFieldHeight(SerializedProperty arrayProperty, ReorderableListFlags flags) { // We need to push/pop flags so that nested controls are properly calculated. var restoreFlags = DefaultListControl.Flags; try { DefaultListControl.Flags = flags; return(DefaultListControl.CalculateListHeight(new SerializedPropertyAdaptor(arrayProperty))); } finally { DefaultListControl.Flags = restoreFlags; } }
public static void DrawControlFromState(IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags) { int controlID = GUIUtility.GetControlID(FocusType.Passive); ReorderableListControl reorderableListControl = GUIUtility.GetStateObject(typeof(ReorderableListControl), controlID) as ReorderableListControl; reorderableListControl.flags = flags; reorderableListControl.Draw(controlID, adaptor, drawEmpty); }
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> public static void ListField(SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags) { DoListField(arrayProperty, fixedItemHeight, drawEmpty, flags); }
/// <inheritdoc cref="DoListField(IReorderableListAdaptor, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> public static void ListField(IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags) { DoListField(adaptor, drawEmpty, flags); }
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> public static void ListField(SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListFlags flags) { DoListField(arrayProperty, fixedItemHeight, null, flags); }
/// <inheritdoc cref="DoListFieldAbsolute(Rect, IReorderableListAdaptor, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> public static void ListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) { DoListFieldAbsolute(position, adaptor, drawEmpty, flags); }
/// <inheritdoc cref="DoListFieldAbsolute(Rect, SerializedProperty, float, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> public static void ListFieldAbsolute(Rect position, SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListFlags flags) { DoListFieldAbsolute(position, arrayProperty, fixedItemHeight, null, 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 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 = 0) { ReorderableListControl.DrawControlFromState(adaptor, drawEmpty, flags); }
/// <summary> /// Generate and draw control from state object. /// </summary> /// <param name="adaptor">Reorderable list adaptor.</param> /// <param name="drawEmpty">Delegate for drawing empty list.</param> /// <param name="flags">Optional flags to pass into list field.</param> public static void DrawControlFromState(IReorderableListAdaptor adaptor, DrawEmpty drawEmpty, ReorderableListFlags flags) { int controlID = GetReorderableListControlID(); var control = GUIUtility.GetStateObject(typeof(ReorderableListControl), controlID) as ReorderableListControl; control.Flags = flags; control.Draw(controlID, adaptor, drawEmpty); }
/// <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 = 0) { ReorderableListControl.DrawControlFromState(position, adaptor, drawEmpty, flags); }
/// <summary> /// Initializes a new instance of <see cref="ReorderableListControl"/>. /// </summary> /// <param name="flags">Optional flags which affect behavior of control.</param> public ReorderableListControl(ReorderableListFlags flags) : this() { this.Flags = flags; }
private void UpdateFlag(bool shouldSet, ReorderableListFlags flag) { if (shouldSet) Flags |= flag; else Flags &= ~flag; }
/// <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); }