Example #1
0
        /// <summary>
        /// Draws the property.
        /// </summary>
        protected override void DrawPropertyLayout(IPropertyValueEntry <T> entry, ValueDropdownAttribute attribute, GUIContent label)
        {
            // We invoke a strongly typed method of the base value type, so polymorphism doesn't break
            PropertyContext <Action <IPropertyValueEntry, ValueDropdownAttribute, GUIContent> > invoker;

            if (entry.Context.Get(this, "invoker", out invoker))
            {
                MethodInfo method = this.GetType().GetMethod("DoProperty", Flags.InstanceAnyVisibility);
                method        = method.MakeGenericMethod(entry.BaseValueType);
                invoker.Value = (Action <IPropertyValueEntry, ValueDropdownAttribute, GUIContent>)Delegate.CreateDelegate(typeof(Action <IPropertyValueEntry, ValueDropdownAttribute, GUIContent>), this, method);
            }

            invoker.Value(entry.Property.BaseValueEntry, attribute, label);
        }
Example #2
0
        private void DoProperty <TBase>(IPropertyValueEntry weakEntry, ValueDropdownAttribute attribute, GUIContent label)
        {
            var entry  = (IPropertyValueEntry <TBase>)weakEntry;
            var config = entry.Property.Context.Get(this, "Config", (PropertyConfig <TBase>)null);

            if (config.Value == null)
            {
                config.Value = new PropertyConfig <TBase>();

                Type parentType;

                if (entry.ValueCategory == PropertyValueCategory.Member)
                {
                    parentType = entry.ParentType;
                    config.Value.GetParentValuesFromProperty = entry.Property;
                }
                else
                {
                    parentType = entry.Property.Parent.ParentType;
                    config.Value.GetParentValuesFromProperty = entry.Property.Parent;
                }

                MemberInfo memberInfo = parentType.FindMember()
                                        .HasReturnType <IList <TBase> >(true)
                                        .HasNoParameters()
                                        .IsNamed(attribute.MemberName)
                                        .GetMember <MemberInfo>(out config.Value.ErrorMessage);

                if (config.Value.ErrorMessage == null)
                {
                    string memberName = attribute.MemberName + ((memberInfo is MethodInfo) ? "()" : "");
                    if (memberInfo.IsStatic())
                    {
                        config.Value.StaticValueDropdownGetter = DeepReflection.CreateValueGetter <IList <TBase> >(parentType, memberName);
                    }
                    else
                    {
                        config.Value.InstanceValueDropdownGetter = DeepReflection.CreateWeakInstanceValueGetter <IList <TBase> >(parentType, memberName);
                    }
                    config.Value.IsValueDropdown = false;
                }
                else
                {
                    string errorMessage;

                    memberInfo = parentType.FindMember()
                                 .HasReturnType <IList <ValueDropdownItem <TBase> > >(true)
                                 .HasNoParameters()
                                 .IsNamed(attribute.MemberName)
                                 .GetMember <MemberInfo>(out errorMessage);

                    if (errorMessage == null)
                    {
                        string memberName = attribute.MemberName + ((memberInfo is MethodInfo) ? "()" : "");
                        if (memberInfo.IsStatic())
                        {
                            config.Value.ValueDropdownStaticValueDropdownGetter = DeepReflection.CreateValueGetter <IList <ValueDropdownItem <TBase> > >(parentType, memberName);
                        }
                        else
                        {
                            config.Value.ValueDropdownInstanceValueDropdownGetter = DeepReflection.CreateWeakInstanceValueGetter <IList <ValueDropdownItem <TBase> > >(parentType, memberName);
                        }
                        config.Value.ErrorMessage    = null;
                        config.Value.IsValueDropdown = true;
                    }
                    else
                    {
                        if (config.Value.ErrorMessage != errorMessage)
                        {
                            config.Value.ErrorMessage += " or\n" + errorMessage;
                        }

                        if (IsStrongList)
                        {
                            memberInfo = parentType.FindMember()
                                         .HasReturnType(typeof(IList <>).MakeGenericType(StrongListElementType), true)
                                         .HasNoParameters()
                                         .IsNamed(attribute.MemberName)
                                         .GetMember <MemberInfo>(out errorMessage);

                            if (errorMessage != null)
                            {
                                config.Value.ErrorMessage += " or\n" + errorMessage;

                                Type valueDropdown = typeof(ValueDropdownItem <>).MakeGenericType(StrongListElementType);

                                memberInfo = parentType.FindMember()
                                             .HasReturnType(typeof(IList <>).MakeGenericType(valueDropdown), true)
                                             .HasNoParameters()
                                             .IsNamed(attribute.MemberName)
                                             .GetMember <MemberInfo>(out errorMessage);

                                if (errorMessage != null)
                                {
                                    config.Value.ErrorMessage += " or\n" + errorMessage;
                                }
                                else
                                {
                                    config.Value.ErrorMessage   = null;
                                    config.Value.CallNextDrawer = true;
                                }
                            }
                            else
                            {
                                config.Value.ErrorMessage   = null;
                                config.Value.CallNextDrawer = true;
                            }
                        }
                    }
                }
            }

            if (config.Value.ErrorMessage != null)
            {
                if (entry.ValueCategory == PropertyValueCategory.Member)
                {
                    AllEditorGUI.ErrorMessageBox(config.Value.ErrorMessage);
                }

                this.CallNextDrawer(entry, label);
            }
            else if (config.Value.CallNextDrawer)
            {
                this.CallNextDrawer(entry, label);
            }
            else
            {
                if (config.Value.IsValueDropdown)
                {
                    IList <ValueDropdownItem <TBase> > selectList = config.Value.ValueDropdownStaticValueDropdownGetter != null?
                                                                    config.Value.ValueDropdownStaticValueDropdownGetter() :
                                                                        config.Value.ValueDropdownInstanceValueDropdownGetter(config.Value.GetParentValuesFromProperty.ParentValues[0]);

                    selectedValuesBuffer.Clear();

                    if (selectList != null && selectList.Count > 0)
                    {
                        for (int i = 0; i < entry.Values.Count; i++)
                        {
                            var val = entry.Values[i];
                            for (int j = 0; j < selectList.Count; j++)
                            {
                                if (EqualityComparer <TBase> .Default.Equals((TBase)val, selectList[j].Value))
                                {
                                    selectedValuesBuffer.Add(j);
                                }
                            }
                        }

                        //if (Event.current.type == EventType.Repaint && selectList.Count > 0 && selectedValuesBuffer.Count == 0 && entry.Values.Count == 1)
                        //{
                        //    entry.SmartValue = selectList[0].Value;
                        //}
                    }

                    if (SirenixEditorFields.Dropdown <ValueDropdownItem <TBase> >(label, selectedValuesBuffer, selectList, false))
                    {
                        if (selectedValuesBuffer.Count > 0)
                        {
                            entry.SmartValue = selectList[selectedValuesBuffer[0]].Value;
                        }
                    }

                    //IList<ValueDropdownItem<TBase>> selectList = config.Value.ValueDropdownStaticValueDropdownGetter != null ?
                    //    config.Value.ValueDropdownStaticValueDropdownGetter() :
                    //    config.Value.ValueDropdownInstanceValueDropdownGetter(config.Value.GetParentValuesFromProperty.ParentValues[0]);

                    //ValueDropdownItem<TBase> selected = new ValueDropdownItem<TBase>(null, entry.SmartValue);
                    //entry.SmartValue = SirenixEditorFields.Dropdown(label, selected, selectList).Value;
                }
                else
                {
                    IList <TBase> selectList = config.Value.StaticValueDropdownGetter != null?
                                               config.Value.StaticValueDropdownGetter() :
                                                   config.Value.InstanceValueDropdownGetter(config.Value.GetParentValuesFromProperty.ParentValues[0]);

                    entry.SmartValue = SirenixEditorFields.Dropdown(label, entry.SmartValue, selectList);
                }
            }
        }
Example #3
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            //获取对应的脚本
            if (target == null)
            {
                target = property.serializedObject.targetObject;
            }
            //获取对应脚本的类型
            if (targetType == null)
            {
                targetType = target.GetType();
            }
            //获取源数据数组数据
            IList targetValue = null;
            ValueDropdownAttribute valueDropdownAttribute = attribute as ValueDropdownAttribute;

            MemberInfo[] memberInfos = targetType.GetMember(valueDropdownAttribute.MemberName, mMemberTypes, mBindingFlags);
            for (int i = 0, len = memberInfos.Length; i < len; i++)
            {
                try
                {
                    switch (memberInfos[i].MemberType)
                    {
                    case MemberTypes.Field:
                        targetValue = (IList)(memberInfos[i] as FieldInfo)?.GetValue(target);
                        break;

                    case MemberTypes.Property:
                        targetValue = (IList)(memberInfos[i] as PropertyInfo)?.GetValue(target);
                        break;

                    case MemberTypes.Method:
                        targetValue = (IList)(memberInfos[i] as MethodInfo)?.Invoke(target, valueDropdownAttribute.Objs);
                        break;
                    }
                }
                catch (Exception e)
                {
                    Debug.LogError(e);
                }
            }
            if (targetValue == null)
            {
                Debug.LogError(string.Format("{0}使用出错!", attribute.GetType().ToString()), target);
                EditorGUILayout.PropertyField(property, label, true);
                return;
            }

            //目标值
            string targetFieldValue = (fieldInfo.GetValue(target) ?? string.Empty).ToString();

            GUIContent[] displayedOptions = new GUIContent[targetValue.Count];
            for (int i = 0; i < displayedOptions.Length; i++)
            {
                displayedOptions[i] = new GUIContent(targetValue[i].ToString());
                if (displayedOptions[i].text == targetFieldValue)
                {
                    selectedIndex = i;
                }
            }
            bool needInit = selectedIndex == -1;

            if (needInit)
            {
                selectedIndex = 0;
            }
            EditorGUI.BeginChangeCheck();
            selectedIndex = EditorGUILayout.Popup(label, selectedIndex, displayedOptions);
            if (needInit || EditorGUI.EndChangeCheck())
            {
                try
                {
                    Undo.RecordObject(target, target.name);
                    fieldInfo.SetValue(target, targetValue[selectedIndex]);
                }
                catch (Exception e)
                {
                    Debug.LogError(string.Format("{0}使用出错!", attribute.GetType().ToString()), target);
                    Debug.LogError(e.Message, target);
                }
            }
        }
        private void DoProperty <TBase>(IPropertyValueEntry weakEntry, ValueDropdownAttribute attribute, GUIContent label)
        {
            var entry  = (IPropertyValueEntry <TBase>)weakEntry;
            var config = entry.Property.Context.Get(this, "Config", (PropertyConfig <TBase>)null);

            if (config.Value == null)
            {
                config.Value = new PropertyConfig <TBase>();

                Type parentType;

                if (entry.ValueCategory == PropertyValueCategory.Member)
                {
                    parentType = entry.ParentType;
                    config.Value.GetParentValuesFromProperty = entry.Property;
                }
                else
                {
                    parentType = entry.Property.Parent.ParentType;
                    config.Value.GetParentValuesFromProperty = entry.Property.Parent;
                }

                MemberInfo memberInfo = parentType.FindMember()
                                        .HasReturnType <IList <TBase> >(true)
                                        .HasNoParameters()
                                        .IsNamed(attribute.MemberName)
                                        .GetMember <MemberInfo>(out config.Value.ErrorMessage);

                if (config.Value.ErrorMessage == null)
                {
                    string memberName = attribute.MemberName + ((memberInfo is MethodInfo) ? "()" : "");
                    if (memberInfo.IsStatic())
                    {
                        config.Value.StaticValueDropdownGetter = DeepReflection.CreateValueGetter <IList <TBase> >(parentType, memberName);
                    }
                    else
                    {
                        config.Value.InstanceValueDropdownGetter = DeepReflection.CreateWeakInstanceValueGetter <IList <TBase> >(parentType, memberName);
                    }
                    config.Value.IsValueDropdown = false;
                }
                else
                {
                    string errorMessage;

                    memberInfo = parentType.FindMember()
                                 .HasReturnType <IList <ValueDropdownItem <TBase> > >(true)
                                 .HasNoParameters()
                                 .IsNamed(attribute.MemberName)
                                 .GetMember <MemberInfo>(out errorMessage);

                    if (errorMessage == null)
                    {
                        string memberName = attribute.MemberName + ((memberInfo is MethodInfo) ? "()" : "");
                        if (memberInfo.IsStatic())
                        {
                            config.Value.ValueDropdownStaticValueDropdownGetter = DeepReflection.CreateValueGetter <IList <ValueDropdownItem <TBase> > >(parentType, memberName);
                        }
                        else
                        {
                            config.Value.ValueDropdownInstanceValueDropdownGetter = DeepReflection.CreateWeakInstanceValueGetter <IList <ValueDropdownItem <TBase> > >(parentType, memberName);
                        }
                        config.Value.ErrorMessage    = null;
                        config.Value.IsValueDropdown = true;
                    }
                    else
                    {
                        if (config.Value.ErrorMessage != errorMessage)
                        {
                            config.Value.ErrorMessage += " or\n" + errorMessage;
                        }

                        if (IsStrongList)
                        {
                            memberInfo = parentType.FindMember()
                                         .HasReturnType(typeof(IList <>).MakeGenericType(StrongListElementType), true)
                                         .HasNoParameters()
                                         .IsNamed(attribute.MemberName)
                                         .GetMember <MemberInfo>(out errorMessage);

                            if (errorMessage != null)
                            {
                                config.Value.ErrorMessage += " or\n" + errorMessage;

                                Type valueDropdown = typeof(ValueDropdownItem <>).MakeGenericType(StrongListElementType);

                                memberInfo = parentType.FindMember()
                                             .HasReturnType(typeof(IList <>).MakeGenericType(valueDropdown), true)
                                             .HasNoParameters()
                                             .IsNamed(attribute.MemberName)
                                             .GetMember <MemberInfo>(out errorMessage);

                                if (errorMessage != null)
                                {
                                    config.Value.ErrorMessage += " or\n" + errorMessage;
                                }
                                else
                                {
                                    config.Value.ErrorMessage   = null;
                                    config.Value.CallNextDrawer = true;
                                }
                            }
                            else
                            {
                                config.Value.ErrorMessage   = null;
                                config.Value.CallNextDrawer = true;
                            }
                        }
                    }
                }
            }

            if (config.Value.ErrorMessage != null)
            {
                if (entry.ValueCategory == PropertyValueCategory.Member)
                {
                    SirenixEditorGUI.ErrorMessageBox(config.Value.ErrorMessage);
                }

                this.CallNextDrawer(entry, label);
            }
            else if (config.Value.CallNextDrawer)
            {
                this.CallNextDrawer(entry, label);
            }
            else
            {
                if (config.Value.IsValueDropdown)
                {
                    IList <ValueDropdownItem <TBase> > selectList = config.Value.ValueDropdownStaticValueDropdownGetter != null?
                                                                    config.Value.ValueDropdownStaticValueDropdownGetter() :
                                                                        config.Value.ValueDropdownInstanceValueDropdownGetter(config.Value.GetParentValuesFromProperty.ParentValues[0]);

                    selectedValuesBuffer.Clear();

                    if (selectList != null && selectList.Count > 0)
                    {
                        for (int i = 0; i < entry.Values.Count; i++)
                        {
                            var val = entry.Values[i];
                            for (int j = 0; j < selectList.Count; j++)
                            {
                                if (EqualityComparer <TBase> .Default.Equals((TBase)val, selectList[j].Value))
                                {
                                    selectedValuesBuffer.Add(j);
                                }
                            }
                        }
                    }

                    if (SirenixEditorFields.Dropdown <ValueDropdownItem <TBase> >(label, selectedValuesBuffer, selectList, false))
                    {
                        if (selectedValuesBuffer.Count > 0)
                        {
                            entry.SmartValue = selectList[selectedValuesBuffer[0]].Value;
                        }
                    }
                }
                else
                {
                    IList <TBase> selectList = config.Value.StaticValueDropdownGetter != null?
                                               config.Value.StaticValueDropdownGetter() :
                                                   config.Value.InstanceValueDropdownGetter(config.Value.GetParentValuesFromProperty.ParentValues[0]);

                    if (GeneralDrawerConfig.Instance.UseImprovedEnumDropDown)
                    {
                        int  id;
                        bool hasFocus;
                        Rect rect;
                        Action <OdinSelector <TBase> > bindSelector;
                        Func <IEnumerable <TBase> >    getResult;

                        TempFeatureRichControlRect(label, out id, out hasFocus, out rect);

                        if (GenericSelector <TBase> .DrawSelectorButton(rect, entry.SmartValue + "", EditorStyles.popup, id, out bindSelector, out getResult))
                        {
                            var selector = new GenericSelector <TBase>(selectList);
                            selector.SetSelection(entry.SmartValue);
                            selector.ShowInPopup(new Vector2(rect.xMin, rect.yMax));
                            bindSelector(selector);
                        }

                        if (getResult != null)
                        {
                            entry.SmartValue = getResult().FirstOrDefault();
                        }
                    }
                    else
                    {
                        entry.SmartValue = SirenixEditorFields.Dropdown(label, entry.SmartValue, selectList);
                    }
                }
            }
        }