/// <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); }
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); } } }
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); } } } }