Exemplo n.º 1
0
        private void RenderArray(SerializedProperty prop, string changedCallback)
        {
            var formatted = Regex.Split(prop.name, @"(?<!^)(?=[A-Z])");

            formatted[0] = formatted[0].Substring(0, 1).ToUpper() + formatted[0].Substring(1);
            var disabledString = propDisabled ? "[Read Only]" : "";

            prop.isExpanded = UTStyles.FoldoutHeader($"{String.Join(" ", formatted)} [{prop.arraySize}] {disabledString}", prop.isExpanded);
            var foldoutRect = GUILayoutUtility.GetLastRect();

            if (!propDisabled)
            {
                HandleDragAndDrop(foldoutRect, prop);
                if (droppedObjects)
                {
                    return;
                }
            }
            if (!prop.isExpanded)
            {
                return;
            }
            EditorGUI.BeginDisabledGroup(propDisabled);
            var popup = UTUtils.GetPropertyAttribute <PopupAttribute>(prop);

            for (int i = 0; i < prop.arraySize; i++)
            {
                EditorGUILayout.BeginHorizontal();
                if (RenderPositionControls(i, new[] { prop }))
                {
                    break;
                }
                EditorGUI.BeginChangeCheck();
                if (popup == null)
                {
                    EditorGUILayout.PropertyField(prop.GetArrayElementAtIndex(i), new GUIContent());
                }
                else
                {
                    var options = UTUtils.GetPopupOptions(prop.GetArrayElementAtIndex(i), null, popup, out var selectedIndex);
                    selectedIndex = EditorGUILayout.Popup(selectedIndex, options);
                    prop.GetArrayElementAtIndex(i).stringValue = options[selectedIndex];
                }
                if (EditorGUI.EndChangeCheck())
                {
                    HandleChangeCallback(t, changedCallback, prop, null, new object[] { prop.GetArrayElementAtIndex(i), i });
                }

                if (RenderRemoveControls(i, new[] { prop }))
                {
                    HandleChangeCallback(t, changedCallback, prop, null, new object[] { null, i });
                    break;
                }
                EditorGUILayout.EndHorizontal();
            }

            if (!propDisabled)
            {
                EditorGUILayout.BeginHorizontal();
                if (RenderAddControls(new[] { prop }, "Add Element", null))
                {
                    HandleChangeCallback(t, changedCallback, prop, null, new object[] { prop.GetArrayElementAtIndex(prop.arraySize - 1), prop.arraySize - 1 });
                }
                if (GUILayout.Button("Clear", GUILayout.MaxWidth(60)))
                {
                    prop.arraySize = 0;
                    HandleChangeCallback(t, changedCallback, prop, null, new object[] { null, 0 });
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUI.EndDisabledGroup();
        }
Exemplo n.º 2
0
        private void RenderStackedArray(string name, SerializedProperty prop, SerializedProperty otherProp, PopupAttribute leftPopup,
                                        PopupAttribute rightPopup,
                                        string addMethod, string addText, string changedCallback)
        {
            var disabledString = propDisabled ? "[Read Only]" : "";

            prop.isExpanded = UTStyles.FoldoutHeader($"{name} [{prop.arraySize}] {disabledString}", prop.isExpanded);
            var foldoutRect = GUILayoutUtility.GetLastRect();

            if (!propDisabled)
            {
                HandleDragAndDrop(foldoutRect, prop, otherProp);
                if (droppedObjects)
                {
                    return;
                }
            }
            if (!prop.isExpanded)
            {
                return;
            }
            EditorGUI.BeginDisabledGroup(propDisabled);
            for (int i = 0; i < prop.arraySize; i++)
            {
                EditorGUILayout.BeginHorizontal();
                if (RenderPositionControls(i, new[] { prop, otherProp }))
                {
                    break;
                }

                // this code is very similar to PopupAttribute itself
                // but we have to handle it here directly because we are connecting two different props together
                // should probably refactor at some point
                EditorGUI.BeginChangeCheck();
                // handle arrays of different lengths
                var lLength = prop.arraySize;
                var rLength = otherProp.arraySize;
                if (lLength != rLength)
                {
                    prop.arraySize      = Math.Max(lLength, rLength);
                    otherProp.arraySize = Math.Max(lLength, rLength);
                }
                // Left Field
                if (leftPopup == null)
                {
                    EditorGUILayout.PropertyField(prop.GetArrayElementAtIndex(i), new GUIContent());
                }
                else
                {
                    var source  = otherProp.GetArrayElementAtIndex(i);
                    var options = UTUtils.GetPopupOptions(prop.GetArrayElementAtIndex(i), source, leftPopup, out var selectedIndex);

                    selectedIndex = EditorGUILayout.Popup(selectedIndex, options);
                    prop.GetArrayElementAtIndex(i).stringValue = options[selectedIndex];
                }

                if (rightPopup == null)
                {
                    EditorGUILayout.PropertyField(otherProp.GetArrayElementAtIndex(i), new GUIContent());
                }
                else
                {
                    var source  = prop.GetArrayElementAtIndex(i);
                    var options = UTUtils.GetPopupOptions(otherProp.GetArrayElementAtIndex(i), source, rightPopup, out var selectedIndex);

                    selectedIndex = EditorGUILayout.Popup(selectedIndex, options);
                    otherProp.GetArrayElementAtIndex(i).stringValue = options[selectedIndex];
                }

                if (EditorGUI.EndChangeCheck())
                {
                    HandleChangeCallback(t, changedCallback, prop, otherProp, new object[] { prop.GetArrayElementAtIndex(i), otherProp.GetArrayElementAtIndex(i), i });
                }

                if (RenderRemoveControls(i, new[] { prop, otherProp }))
                {
                    HandleChangeCallback(t, changedCallback, prop, otherProp, new object[] { null, null, i });
                    break;
                }

                EditorGUILayout.EndHorizontal();
            }

            if (!propDisabled)
            {
                EditorGUILayout.BeginHorizontal();
                if (RenderAddControls(new[] { prop, otherProp }, addText, addMethod))
                {
                    HandleChangeCallback(t, changedCallback, prop, otherProp, new object[] { prop.GetArrayElementAtIndex(prop.arraySize - 1), otherProp.GetArrayElementAtIndex(otherProp.arraySize - 1), prop.arraySize - 1 });
                }
                if (GUILayout.Button("Clear", GUILayout.MaxWidth(60)))
                {
                    prop.arraySize      = 0;
                    otherProp.arraySize = 0;
                    HandleChangeCallback(t, changedCallback, prop, otherProp, new object[] { null, null, 0 });
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUI.EndDisabledGroup();
        }
Exemplo n.º 3
0
        private void DrawFieldElement(UTField field, SerializedProperty prop)
        {
            var propPath = prop.propertyPath;
            var arrIndex = Convert.ToInt32(field.isArray
        ? propPath.Substring(propPath.LastIndexOf("[") + 1, propPath.LastIndexOf("]") - propPath.LastIndexOf("[") - 1)
        : null);
            var customLabel = field.attributes.Find(i => i is ShowLabelAttribute) as ShowLabelAttribute;
            var uiAttrs     = field.uiAttrs;
            var uiOverride  = uiAttrs.Where(i => i.GetType().GetMethod("OnGUI")?.DeclaringType == i.GetType()).ToArray();

            EditorGUI.BeginChangeCheck();
            switch (prop.type)
            {
            case "bool":
                if (uiOverride.Any())
                {
                    uiOverride.First().OnGUI(prop);
                    break;
                }

                if (customLabel == null)
                {
                    EditorGUILayout.PropertyField(prop, new GUIContent(), GUILayout.MaxWidth(30));
                }
                else
                {
                    EditorGUILayout.PropertyField(prop, new GUIContent(customLabel.label ?? prop.displayName));
                }

                break;

            default:
                // for list views we handle the UI separately due to how popup targeting works
                if (uiOverride.Any() && !field.isInListView)
                {
                    uiOverride.First().OnGUI(prop);
                    break;
                }

                var popupAttr = field.attributes.Find(i => i is PopupAttribute) as PopupAttribute;
                if (popupAttr != null)
                {
                    var sourceProp = UTUtils.GetPropThroughAttribute(serializedObject, popupAttr.methodName);
                    // I do not like this handling
                    // need a way to determine if target is a part of the list view or not without breaking the bank
                    var source = sourceProp == null ? null : !field.isInListView
              ? sourceProp
              : sourceProp.isArray && sourceProp.arraySize > arrIndex
                ? sourceProp.GetArrayElementAtIndex(arrIndex)
                : null;

                    var options = UTUtils.GetPopupOptions(prop, source, popupAttr, out var selectedIndex);
                    selectedIndex = EditorGUILayout.Popup(selectedIndex, options);
                    // we force reserialize for cases of default values
                    if (prop.type == "int")
                    {
                        if (prop.intValue != selectedIndex)
                        {
                            shouldReserialize = true;
                        }
                        prop.intValue = selectedIndex;
                    }
                    else
                    {
                        if (prop.stringValue != options[selectedIndex])
                        {
                            shouldReserialize = true;
                        }
                        prop.stringValue = options[selectedIndex];
                    }
                    break;
                }

                // if there are no popup attributes - still allow gui override
                if (uiOverride.Any(i => !(i is PopupAttribute)))
                {
                    uiOverride.First(i => !(i is PopupAttribute)).OnGUI(prop);
                    break;
                }

                if (customLabel == null)
                {
                    EditorGUILayout.PropertyField(prop, new GUIContent());
                }
                else
                {
                    EditorGUILayout.PropertyField(prop, new GUIContent(customLabel.label ?? prop.displayName));
                }

                break;
            }

            if (EditorGUI.EndChangeCheck() && field.onValueChaged != null)
            {
                if (!field.isInListView)
                {
                    field.onValueChaged.Invoke(t, new object[] { prop });
                    return;
                }
                HandleFieldChangeArray(field, prop, arrIndex);
            }
        }