예제 #1
0
 /// <summary>
 /// Create a VisualElement for this editable field's inline editor based on the field data type.
 ///
 /// This returns null if the type could not be resolved to a supported control element.
 /// </summary>
 public VisualElement GetControlElement(NodeView view)
 {
     return(ControlElementFactory.CreateControl(Field, view, Name));
 }
        public static VisualElement CreateControl(FieldInfo fieldInfo, NodeView view, string label = null)
        {
            // This mess is similar to what Unity is doing for ShaderGraph. It's not great.
            // But the automatic alternatives depend on SerializableObject which is a performance bottleneck.
            // Ref: https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/master/com.unity.shadergraph/Editor/Drawing/Controls/DefaultControl.cs

            Type type = fieldInfo.FieldType;

            // Builtin unity type editors
            if (type == typeof(bool))
            {
                return(BuildVal <Toggle, bool>(view, fieldInfo, label));
            }

            if (type == typeof(int))
            {
                return(BuildVal <IntegerField, int>(view, fieldInfo, label));
            }

            if (type == typeof(float))
            {
                return(BuildVal <FloatField, float>(view, fieldInfo, label));
            }

            if (type == typeof(string))
            {
                return(BuildVal <TextField, string>(view, fieldInfo, label));
            }

            if (type == typeof(Rect))
            {
                return(BuildVal <RectField, Rect>(view, fieldInfo, label));
            }

            if (type == typeof(Color))
            {
                return(BuildVal <ColorField, Color>(view, fieldInfo, label));
            }

            if (type == typeof(Vector2))
            {
                return(BuildVal <Vector2Field, Vector2>(view, fieldInfo, label));
            }

            if (type == typeof(Vector3))
            {
                return(BuildVal <Vector3Field, Vector3>(view, fieldInfo, label));
            }

            if (type == typeof(Vector4))
            {
                return(BuildVal <Vector4Field, Vector4>(view, fieldInfo, label));
            }

            if (type == typeof(Gradient))
            {
                return(BuildVal <GradientField, Gradient>(view, fieldInfo, label));
            }

            if (type == typeof(AnimationCurve))
            {
                return(BuildVal <CurveField, AnimationCurve>(view, fieldInfo, label));
            }

            if (type == typeof(LayerMask))
            {
                var value = ((LayerMask)fieldInfo.GetValue(view.Target)).value;
                var field = new LayerMaskField(label, value);

                field.RegisterValueChangedCallback((change) =>
                {
                    fieldInfo.SetValue(view.Target, (LayerMask)change.newValue);
                    view.Target.Validate();
                    view.OnPropertyChange();
                });

                return(field);
            }

            // Implementation (rather than just using EnumField) comes from:
            // https://github.com/Unity-Technologies/UnityCsReference/blob/1e8347ec4cbda9e8a4929e42a20f39df9bbab9d9/Editor/Mono/UIElements/Controls/PropertyField.cs#L306-L323

            if (typeof(Enum).IsAssignableFrom(type))
            {
                var choices      = new List <string>(type.GetEnumNames());
                var defaultIndex = (int)fieldInfo.GetValue(view.Target);

                if (type.IsDefined(typeof(FlagsAttribute), false))
                {
                    var field = new EnumFlagsField(label, (Enum)fieldInfo.GetValue(view.Target));

                    field.RegisterValueChangedCallback((change) =>
                    {
                        fieldInfo.SetValue(view.Target, change.newValue);
                        view.OnPropertyChange();
                    });

                    return(field);
                }
                else
                {
                    var field = new PopupField <string>(label, choices, defaultIndex);

                    field.RegisterValueChangedCallback((change) =>
                    {
                        fieldInfo.SetValue(view.Target, field.index);
                        view.OnPropertyChange();
                    });

                    return(field);
                }
            }

            // Specialized construct so I can set .objectType on the ObjectField
            if (typeof(UnityEngine.Object).IsAssignableFrom(type))
            {
                var field = BuildRef <ObjectField, UnityEngine.Object>(view, fieldInfo, label) as ObjectField;
                if (field != null)
                {
                    field.objectType = type;
                }

                return(field);
            }

            // TODO: EnumFlags/Masks (we have MaskField - how do we detect mask types?)

            // TODO: Specialized common types. Transform, Rotation, Texture2D, etc.

            // TODO: Custom plugin types

            return(null);
        }
예제 #3
0
 public void AddElement(NodeView node)
 {
     node.comment = this;
     containedNodes.Add(node);
 }