/// <summary> /// Not yet documented. /// </summary> protected override void DrawPropertyLayout(IPropertyValueEntry <TElement> entry, AssetListAttribute attribute, GUIContent label) { var config = entry.Property.Context.Get(this, "Test", (CurrentContext)null); if (config.Value == null) { config.Value = new CurrentContext(); config.Value.Attribute = attribute; config.Value.Tags = attribute.Tags != null?attribute.Tags.Trim().Split(',').Select(i => i.Trim()).ToArray() : null; config.Value.LayerNames = attribute.LayerNames != null?attribute.LayerNames.Trim().Split(',').Select(i => i.Trim()).ToArray() : null; config.Value.Property = entry.Property; if (attribute.Path != null) { var path = attribute.Path.Trim('/', ' '); path = "Assets/" + path + "/"; path = Application.dataPath + "/" + path; config.Value.AssetsFolderLocation = new DirectoryInfo(path); path = attribute.Path.TrimStart('/').TrimEnd('/'); config.Value.PrettyPath = "/" + path.TrimStart('/'); } if (attribute.CustomFilterMethod != null) { MethodInfo methodInfo; string error; if (MemberFinder.Start(entry.ParentType) .IsMethod() .IsNamed(attribute.CustomFilterMethod) .HasReturnType <bool>() .HasParameters <TElement>() .TryGetMember <MethodInfo>(out methodInfo, out error)) { if (methodInfo.IsStatic) { config.Value.StaticCustomIncludeMethod = (Func <TElement, bool>)Delegate.CreateDelegate(typeof(Func <TElement, bool>), methodInfo, true); } else { config.Value.InstanceCustomIncludeMethod = EmitUtilities.CreateWeakInstanceMethodCaller <bool, TElement>(methodInfo); } } config.Value.ErrorMessage = error; } if (config.Value.ErrorMessage != null) { // We can get away with lag on load. config.Value.MaxSearchDurationPrFrameInMS = 20; config.Value.EnsureListPopulation(); config.Value.MaxSearchDurationPrFrameInMS = 1; } } var currentValue = (UnityEngine.Object)entry.WeakSmartValue; if (config.Value.ErrorMessage != null) { AllEditorGUI.ErrorMessageBox(config.Value.ErrorMessage); } else { config.Value.EnsureListPopulation(); } AllEditorGUI.BeginIndentedVertical(SirenixGUIStyles.PropertyPadding); { AllEditorGUI.BeginHorizontalToolbar(); if (label != null) { GUILayout.Label(label); } GUILayout.FlexibleSpace(); if (config.Value.PrettyPath != null) { GUILayout.Label(config.Value.PrettyPath, SirenixGUIStyles.RightAlignedGreyMiniLabel); AllEditorGUI.VerticalLineSeparator(); } if (config.Value.IsPopulated) { GUILayout.Label(config.Value.AvailableAsset.Count + " items", SirenixGUIStyles.RightAlignedGreyMiniLabel); GUIHelper.PushGUIEnabled(GUI.enabled && (config.Value.AvailableAsset.Count > 0 && config.Value.ErrorMessage == null)); } else { GUILayout.Label("Scanning " + config.Value.CurrentSearchingIndex + " / " + config.Value.NumberOfResultsToSearch, SirenixGUIStyles.RightAlignedGreyMiniLabel); GUIHelper.PushGUIEnabled(false); } AllEditorGUI.VerticalLineSeparator(); bool drawConflict = entry.Property.ParentValues.Count > 1; if (drawConflict == false) { var index = config.Value.AvailableAsset.IndexOf(currentValue) + 1; if (index > 0) { GUILayout.Label(index.ToString(), SirenixGUIStyles.RightAlignedGreyMiniLabel); } else { drawConflict = true; } } if (drawConflict) { GUILayout.Label("-", SirenixGUIStyles.RightAlignedGreyMiniLabel); } if (AllEditorGUI.ToolbarButton(EditorIcons.TriangleLeft) && config.Value.IsPopulated) { var index = config.Value.AvailableAsset.IndexOf(currentValue) - 1; index = index < 0 ? config.Value.AvailableAsset.Count - 1 : index; entry.WeakSmartValue = config.Value.AvailableAsset[index]; } if (AllEditorGUI.ToolbarButton(EditorIcons.TriangleDown) && config.Value.IsPopulated) { GenericMenu m = new GenericMenu(); var selected = currentValue; int itemsPrPage = 40; bool showPages = config.Value.AvailableAsset.Count > 50; string page = ""; int selectedPage = (config.Value.AvailableAsset.IndexOf(entry.WeakSmartValue as UnityEngine.Object) / itemsPrPage); for (int i = 0; i < config.Value.AvailableAsset.Count; i++) { var obj = config.Value.AvailableAsset[i]; if (obj != null) { var path = AssetDatabase.GetAssetPath(obj); var name = string.IsNullOrEmpty(path) ? obj.name : path.Substring(7).Replace("/", "\\"); var localEntry = entry; if (showPages) { var p = (i / itemsPrPage); page = (p * itemsPrPage) + " - " + Mathf.Min(((p + 1) * itemsPrPage), config.Value.AvailableAsset.Count - 1); if (selectedPage == p) { page += " (contains selected)"; } page += "/"; } m.AddItem(new GUIContent(page + name), obj == selected, () => { localEntry.Property.Tree.DelayActionUntilRepaint(() => localEntry.WeakSmartValue = obj); }); } } m.ShowAsContext(); } if (AllEditorGUI.ToolbarButton(EditorIcons.TriangleRight) && config.Value.IsPopulated) { var index = config.Value.AvailableAsset.IndexOf(currentValue) + 1; entry.WeakSmartValue = config.Value.AvailableAsset[index % config.Value.AvailableAsset.Count]; } GUIHelper.PopGUIEnabled(); AllEditorGUI.EndHorizontalToolbar(); AllEditorGUI.BeginVerticalList(); AllEditorGUI.BeginListItem(false, padding); this.CallNextDrawer(entry.Property, null); AllEditorGUI.EndListItem(); AllEditorGUI.EndVerticalList(); } AllEditorGUI.EndIndentedVertical(); }
/// <summary> /// Draws the property. /// </summary> protected override void DrawPropertyImplementation(InspectorProperty property, GUIContent label) { if (label == null) { AllEditorGUI.BeginIndentedVertical(); for (int i = 0; i < property.Children.Count; i++) { InspectorUtilities.DrawProperty(property.Children[i]); } AllEditorGUI.EndIndentedVertical(); } else { Context context; if (property.Context.Get <Context>(this, "context", out context)) { context.IsVisisble = property.Context.GetPersistent(this, "IsVisible", AllEditorGUI.ExpandFoldoutByDefault); context.IsInlineProperty = property.ValueEntry.TypeOfValue.GetAttribute <InlinePropertyAttribute>() ?? property.Info.GetAttribute <InlinePropertyAttribute>(); } if (context.IsInlineProperty != null) { var outerRect = EditorGUILayout.BeginHorizontal(); { if (Event.current.type == EventType.Repaint) { outerRect.y += 1; EditorGUI.PrefixLabel(outerRect, label); } GUILayout.Space(EditorGUIUtility.labelWidth); GUILayout.BeginVertical(); { if (context.IsInlineProperty.LabelWidth > 0) { GUIHelper.PushLabelWidth(context.IsInlineProperty.LabelWidth); } GUIHelper.PushIndentLevel(0); for (int i = 0; i < property.Children.Count; i++) { InspectorUtilities.DrawProperty(property.Children[i]); } GUIHelper.PopIndentLevel(); if (context.IsInlineProperty.LabelWidth > 0) { GUIHelper.PopLabelWidth(); } } GUILayout.EndVertical(); } EditorGUILayout.EndHorizontal(); } else { context.IsVisisble.Value = AllEditorGUI.Foldout(context.IsVisisble.Value, label); if (AllEditorGUI.BeginFadeGroup(context, context.IsVisisble.Value)) { EditorGUI.indentLevel++; for (int i = 0; i < property.Children.Count; i++) { InspectorUtilities.DrawProperty(property.Children[i]); } EditorGUI.indentLevel--; } AllEditorGUI.EndFadeGroup(); } } }
/// <summary> /// Draws the property. /// </summary> protected override void DrawPropertyGroupLayout(InspectorProperty property, TabGroupAttribute attribute, GUIContent label) { var tabGroup = AllEditorGUI.CreateAnimatedTabGroup(property); tabGroup.AnimationSpeed = 1 / AllEditorGUI.TabPageSlideAnimationDuration; tabGroup.FixedHeight = attribute.UseFixedHeight; LocalPersistentContext <int> persistentPageContext = property.Context.GetPersistent(this, "CurrentPage", 0); bool setPersistentPage = false; PropertyContext <List <Tab> > tabs; if (property.Context.Get(this, "Tabs", out tabs)) { setPersistentPage = true; tabs.Value = new List <Tab>(); var addLastTabs = new List <Tab>(); for (int j = 0; j < property.Children.Count; j++) { var child = property.Children[j]; bool added = false; if (child.Info.PropertyType == PropertyType.Group) { var attrType = child.Info.GetAttribute <PropertyGroupAttribute>().GetType(); if (attrType.IsNested && attrType.DeclaringType == typeof(TabGroupAttribute)) { // This is a tab subgroup; add all its children to a tab for that subgroup Tab tab = new Tab(); tab.TabName = child.NiceName; tab.Title = new StringMemberHelper(property.ParentType, child.Name.TrimStart('#')); for (int i = 0; i < child.Children.Count; i++) { tab.InspectorProperties.Add(child.Children[i]); } tabs.Value.Add(tab); added = true; } } if (!added) { // This is a group member of the tab group itself, so it gets its own tab Tab tab = new Tab(); tab.TabName = child.NiceName; tab.Title = new StringMemberHelper(property.ParentType, child.Name.TrimStart('#')); tab.InspectorProperties.Add(child); addLastTabs.Add(tab); } } foreach (var tab in addLastTabs) { tabs.Value.Add(tab); } } for (int i = 0; i < tabs.Value.Count; i++) { tabGroup.RegisterTab(tabs.Value[i].TabName); } if (setPersistentPage) { if (persistentPageContext.Value >= tabs.Value.Count || persistentPageContext.Value < 0) { persistentPageContext.Value = 0; } tabGroup.SetCurrentPage(tabGroup.RegisterTab(tabs.Value[persistentPageContext.Value].TabName)); } AllEditorGUI.BeginIndentedVertical(SirenixGUIStyles.PropertyPadding); tabGroup.BeginGroup(); for (int i = 0; i < tabs.Value.Count; i++) { var page = tabGroup.RegisterTab(tabs.Value[i].TabName); page.Title = tabs.Value[i].Title.GetString(property); if (page.BeginPage()) { persistentPageContext.Value = i; int pageCount = tabs.Value[i].InspectorProperties.Count; for (int j = 0; j < pageCount; j++) { InspectorUtilities.DrawProperty(tabs.Value[i].InspectorProperties[j]); } } page.EndPage(); } tabGroup.EndGroup(); AllEditorGUI.EndIndentedVertical(); }
/// <summary> /// Draws the property. /// </summary> protected override void DrawPropertyLayout(IPropertyValueEntry <TList> entry, GUIContent label) { var property = entry.Property; var infoContext = property.Context.Get(this, "Context", (ListDrawerConfigInfo)null); var info = infoContext.Value; bool isReadOnly = false; if (entry.TypeOfValue.IsArray == false) { for (int i = 0; i < entry.ValueCount; i++) { if ((entry.WeakValues[i] as IList <TElement>).IsReadOnly) { isReadOnly = true; break; } } } if (info == null) { var customListDrawerOptions = property.Info.GetAttribute <ListDrawerSettingsAttribute>() ?? new ListDrawerSettingsAttribute(); isReadOnly = entry.IsEditable == false || isReadOnly || customListDrawerOptions.IsReadOnlyHasValue && customListDrawerOptions.IsReadOnly; info = infoContext.Value = new ListDrawerConfigInfo() { StartIndex = 0, Toggled = entry.Context.GetPersistent <bool>(this, "ListDrawerToggled", customListDrawerOptions.ExpandedHasValue ? customListDrawerOptions.Expanded : GeneralDrawerConfig.Instance.OpenListsByDefault), RemoveAt = -1, label = new GUIContent(label == null || string.IsNullOrEmpty(label.text) ? property.ValueEntry.TypeOfValue.GetNiceName() : label.text, label == null ? string.Empty : label.tooltip), ShowAllWhilePageing = false, EndIndex = 0, CustomListDrawerOptions = customListDrawerOptions, IsReadOnly = isReadOnly, Draggable = !isReadOnly && (!customListDrawerOptions.IsReadOnlyHasValue) }; info.listConfig = GeneralDrawerConfig.Instance; info.property = property; if (customListDrawerOptions.DraggableHasValue && !customListDrawerOptions.DraggableItems) { info.Draggable = false; } if (info.CustomListDrawerOptions.OnBeginListElementGUI != null) { string errorMessage; MemberInfo memberInfo = property.ParentType .FindMember() .IsMethod() .IsNamed(info.CustomListDrawerOptions.OnBeginListElementGUI) .HasParameters <int>() .ReturnsVoid() .GetMember <MethodInfo>(out errorMessage); if (memberInfo == null || errorMessage != null) { Debug.LogError(errorMessage ?? "There should really be an error message here."); } else { info.OnBeginListElementGUI = EmitUtilities.CreateWeakInstanceMethodCaller <int>(memberInfo as MethodInfo); } } if (info.CustomListDrawerOptions.OnEndListElementGUI != null) { string errorMessage; MemberInfo memberInfo = property.ParentType .FindMember() .IsMethod() .IsNamed(info.CustomListDrawerOptions.OnEndListElementGUI) .HasParameters <int>() .ReturnsVoid() .GetMember <MethodInfo>(out errorMessage); if (memberInfo == null || errorMessage != null) { Debug.LogError(errorMessage ?? "There should really be an error message here."); } else { info.OnEndListElementGUI = EmitUtilities.CreateWeakInstanceMethodCaller <int>(memberInfo as MethodInfo); } } if (info.CustomListDrawerOptions.OnTitleBarGUI != null) { string errorMessage; MemberInfo memberInfo = property.ParentType .FindMember() .IsMethod() .IsNamed(info.CustomListDrawerOptions.OnTitleBarGUI) .HasNoParameters() .ReturnsVoid() .GetMember <MethodInfo>(out errorMessage); if (memberInfo == null || errorMessage != null) { Debug.LogError(errorMessage ?? "There should really be an error message here."); } else { info.OnTitleBarGUI = EmitUtilities.CreateWeakInstanceMethodCaller(memberInfo as MethodInfo); } } if (info.CustomListDrawerOptions.ListElementLabelName != null) { string errorMessage; MemberInfo memberInfo = typeof(TElement) .FindMember() .HasNoParameters() .IsNamed(info.CustomListDrawerOptions.ListElementLabelName) .HasReturnType <object>(true) .GetMember(out errorMessage); if (memberInfo == null || errorMessage != null) { Debug.LogError(errorMessage ?? "There should really be an error message here."); } else { string methodSuffix = memberInfo as MethodInfo == null ? "" : "()"; info.GetListElementLabelText = DeepReflection.CreateWeakInstanceValueGetter(typeof(TElement), typeof(object), info.CustomListDrawerOptions.ListElementLabelName + methodSuffix); } } } info.listConfig = GeneralDrawerConfig.Instance; info.property = property; info.ListItemStyle.padding.left = info.Draggable ? 25 : 7; info.ListItemStyle.padding.right = info.IsReadOnly ? 4 : 20; if (Event.current.type == EventType.Repaint) { info.DropZoneTopLeft = GUIUtility.GUIToScreenPoint(new Vector2(0, 0)); } info.ListValueChanger = property.ValueEntry.GetListValueEntryChanger(); info.Count = property.Children.Count; info.IsEmpty = property.Children.Count == 0; AllEditorGUI.BeginIndentedVertical(SirenixGUIStyles.PropertyPadding); this.BeginDropZone(info); { this.DrawToolbar(info); if (AllEditorGUI.BeginFadeGroup(UniqueDrawerKey.Create(property, this), info.Toggled.Value)) { GUIHelper.PushLabelWidth(EditorGUIUtility.labelWidth - info.ListItemStyle.padding.left); this.DrawItems(info); GUIHelper.PopLabelWidth(); } AllEditorGUI.EndFadeGroup(); } this.EndDropZone(info); AllEditorGUI.EndIndentedVertical(); if (info.RemoveAt >= 0 && Event.current.type == EventType.Repaint) { info.ListValueChanger.RemoveListElementAt(info.RemoveAt, CHANGE_ID); info.RemoveAt = -1; GUIHelper.RequestRepaint(); } if (info.ObjectPicker != null && info.ObjectPicker.IsReadyToClaim && Event.current.type == EventType.Repaint) { var value = info.ObjectPicker.ClaimObject(); if (info.JumpToNextPageOnAdd) { info.StartIndex = int.MaxValue; } object[] values = new object[info.ListValueChanger.ValueCount]; values[0] = value; for (int j = 1; j < values.Length; j++) { values[j] = SerializationUtility.CreateCopy(value); } info.ListValueChanger.AddListElement(values, CHANGE_ID); } }
/// <summary> /// Draws the property. /// </summary> protected override void DrawPropertyLayout(IPropertyValueEntry <TDictionary> entry, GUIContent label) { var context = entry.Property.Context.Get(this, "context", (Context)null); if (context.Value == null) { context.Value = new Context(); context.Value.Toggled = entry.Context.GetPersistent(this, "Toggled", GeneralDrawerConfig.Instance.OpenListsByDefault); context.Value.KeyWidthOffset = 130; context.Value.Label = label ?? new GUIContent(typeof(TDictionary).GetNiceName()); context.Value.AttrSettings = entry.Property.Info.GetAttribute <DictionaryDrawerSettings>() ?? new DictionaryDrawerSettings(); context.Value.DisableAddKey = entry.Property.Tree.HasPrefabs && !entry.GetDictionaryHandler().SupportsPrefabModifications; if (!context.Value.DisableAddKey) { context.Value.TempKeyValue = new TempKeyValue(); var tree = PropertyTree.Create(context.Value.TempKeyValue); tree.UpdateTree(); context.Value.TempKeyEntry = (IPropertyValueEntry <TKey>)tree.GetPropertyAtPath("Key").ValueEntry; context.Value.TempValueEntry = (IPropertyValueEntry <TValue>)tree.GetPropertyAtPath("Value").ValueEntry; } } context.Value.DictionaryHandler = (DictionaryHandler <TDictionary, TKey, TValue>)entry.GetDictionaryHandler(); context.Value.Config = GeneralDrawerConfig.Instance; context.Value.Paging.NumberOfItemsPerPage = context.Value.Config.NumberOfItemsPrPage; context.Value.ListItemStyle.padding.right = !entry.IsEditable || context.Value.AttrSettings.IsReadOnly ? 4 : 20; //if (!IsSupportedKeyType) //{ // var message = entry.Property.Context.Get(this, "error_message", (string)null); // var detailedMessage = entry.Property.Context.Get(this, "error_message_detailed", (string)null); // var folded = entry.Property.Context.Get(this, "error_message_folded", true); // if (message.Value == null) // { // string str = ""; // if (label != null) // { // str += label.text + "\n\n"; // } // str += "The dictionary key type '" + typeof(TKey).GetNiceFullName() + "' is not supported in prefab instances. Expand this box to see which key types are supported."; // message.Value = str; // } // if (detailedMessage.Value == null) // { // var sb = new StringBuilder("The following key types are supported:"); // sb.AppendLine() // .AppendLine(); // foreach (var type in DictionaryKeyUtility.GetPersistentPathKeyTypes()) // { // sb.AppendLine(type.GetNiceName()); // } // sb.AppendLine("Enums of any type"); // detailedMessage.Value = sb.ToString(); // } // folded.Value = AllEditorGUI.DetailedMessageBox(message.Value, detailedMessage.Value, MessageType.Error, folded.Value); // return; //} AllEditorGUI.BeginIndentedVertical(SirenixGUIStyles.PropertyPadding); { context.Value.Paging.Update(elementCount: entry.Property.Children.Count); this.DrawToolbar(entry, context.Value); context.Value.Paging.Update(elementCount: entry.Property.Children.Count); if (!context.Value.DisableAddKey && context.Value.AttrSettings.IsReadOnly == false) { this.DrawAddKey(entry, context.Value); } float t; GUIHelper.BeginLayoutMeasuring(); if (AllEditorGUI.BeginFadeGroup(UniqueDrawerKey.Create(entry.Property, this), context.Value.Toggled.Value, out t)) { var rect = AllEditorGUI.BeginVerticalList(false); if (context.Value.AttrSettings.DisplayMode == DictionaryDisplayOptions.OneLine) { var maxWidth = rect.width - 90; rect.xMin = context.Value.KeyWidthOffset + 22; rect.xMax = rect.xMin + 10; context.Value.KeyWidthOffset = context.Value.KeyWidthOffset + AllEditorGUI.SlideRect(rect).x; if (Event.current.type == EventType.Repaint) { context.Value.KeyWidthOffset = Mathf.Clamp(context.Value.KeyWidthOffset, 90, maxWidth); } if (context.Value.Paging.ElementCount != 0) { var headerRect = AllEditorGUI.BeginListItem(false); { GUILayout.Space(14); if (Event.current.type == EventType.Repaint) { GUI.Label(headerRect.SetWidth(context.Value.KeyWidthOffset), context.Value.AttrSettings.KeyLabel, SirenixGUIStyles.LabelCentered); GUI.Label(headerRect.AddXMin(context.Value.KeyWidthOffset), context.Value.AttrSettings.ValueLabel, SirenixGUIStyles.LabelCentered); AllEditorGUI.DrawSolidRect(headerRect.AlignBottom(1), SirenixGUIStyles.BorderColor); } } AllEditorGUI.EndListItem(); } } this.DrawElements(entry, label, context.Value); AllEditorGUI.EndVerticalList(); } AllEditorGUI.EndFadeGroup(); // Draw borders var outerRect = GUIHelper.EndLayoutMeasuring(); if (t > 0.01f && Event.current.type == EventType.Repaint) { Color col = SirenixGUIStyles.BorderColor; outerRect.yMin -= 1; AllEditorGUI.DrawBorders(outerRect, 1, col); col.a *= t; if (context.Value.AttrSettings.DisplayMode == DictionaryDisplayOptions.OneLine) { // Draw Slide Rect Border outerRect.width = 1; outerRect.x += context.Value.KeyWidthOffset + 13; AllEditorGUI.DrawSolidRect(outerRect, col); } } } AllEditorGUI.EndIndentedVertical(); }