private GenericSelector <UnityEngine.Object> CreateSelector() { var t = isList ? (this.Property.ChildResolver as ICollectionResolver).ElementType : typeof(T); var isGo = t == typeof(GameObject); var root = this.GetRoot(0); var children = root.GetComponentsInChildren(isGo ? typeof(Transform) : t) .Where(x => this.Attribute.IncludeSelf || x.transform != root) .OfType <UnityEngine.Object>(); if (isGo) { children = children.OfType <Component>().Select(x => x.gameObject).OfType <UnityEngine.Object>(); } Func <UnityEngine.Object, string> getName = x => { var c = x as Component; var o = x as GameObject; var transform = c ? c.transform : o.transform; return(this.GetGameObjectPath(root, transform)); }; var selector = new GenericSelector <UnityEngine.Object>( null, false, getName, children.Where(x => x.GetType().InheritsFrom(t))); selector.SelectionTree.Config.DrawSearchToolbar = true; selector.SetSelection(this.ValueEntry.SmartValue as UnityEngine.Object); selector.SelectionTree.EnumerateTree().AddThumbnailIcons(true); selector.SelectionTree.EnumerateTree().Where(x => x.Icon == null).ForEach(x => x.Icon = EditorIcons.UnityGameObjectIcon); selector.SelectionTree.EnumerateTree().ForEach(x => x.Toggled = true); selector.EnableSingleClickToSelect(); return(selector); }
private GenericSelector <object> CreateSelector() { IEnumerable <ValueDropdownItem> query = this.getValues(); if (query == null) { // God damm it bjarke. query = Enumerable.Empty <ValueDropdownItem>(); } var enableSearch = query.Take(10).Count() == 10; GenericSelector <object> selector = new GenericSelector <object>(this.Attribute.DropdownTitle, false, query.Select(x => new GenericSelectorItem <object>(x.Text, x.Value))); selector.CheckboxToggle = false; selector.EnableSingleClickToSelect(); selector.SelectionTree.Config.DrawSearchToolbar = enableSearch; IEnumerable <object> selection = Enumerable.Empty <object>(); if (!this.isList) { selection = this.getSelection(); } selection = selection.Select(x => (x == null ? null : x.GetType()) as object); selector.SetSelection(selection); selector.SelectionTree.EnumerateTree().AddThumbnailIcons(true); return(selector); }
protected override void OnEnable() { var types = typeof(Feedback).GetDependencies().ToArray(); dropdown = new GenericSelector <Type>(string.Empty, false, GetEffectName, types); dropdown.SelectionTree.DefaultMenuStyle.Height = (int)EditorGUIUtility.singleLineHeight + 4; dropdown.SetSelection(types.First()); dropdown.SelectionChanged += items => type = items.FirstOrDefault(); dropdown.SelectionConfirmed += items => type = items.FirstOrDefault(); }
private void SaveMethod(IEnumerable <MethodInfo> infos) { var persistentCall = Property.ValueEntry.WeakSmartValue as PersistentCallBase; var info = infos.FirstOrDefault(); if (info == null) { var current = persistentCall.GetMethod(); if (current != null) { dropdown.SetSelection(current); } return; } var parameters = info.GetParameters(); var types = new Type[parameters.Length]; var method = info.Name; for (var i = 0; i < parameters.Length; i++) { types[i] = parameters[i].ParameterType; method += $"/{types[i].AssemblyQualifiedName}"; } PersistentCallBase call; if (parameters.Length == 0) { call = new PersistentCall(); } else { var callDefinitions = new Type[] { typeof(PersistentCall <>), typeof(PersistentCall <,>), typeof(PersistentCall <, ,>), typeof(PersistentCall <, , ,>), }; var callType = callDefinitions[parameters.Length - 1].MakeGenericType(types); call = Activator.CreateInstance(callType) as PersistentCallBase; } call.Set(persistentCall.Target, method, persistentCall.Info); Property.BaseValueEntry.WeakSmartValue = call; }
public override void OnInspectorGUI() { base.OnInspectorGUI(); if (_odinTest.stringList.Count > 1) { int selectIndex = 0; if (_odinTest.stringList.Contains(_odinTest.selectString)) { for (int i = 0; i < _odinTest.stringList.Count; i++) { if (_odinTest.selectString == _odinTest.stringList[i]) { selectIndex = i; break; } } } //selectIndex = EditorGUILayout.Popup("SelectString", selectIndex, _odinTest.stringList.ToArray()); //_odinTest.selectString = _odinTest.stringList[selectIndex]; if (GUILayout.Button(_odinTest.selectString, "MiniPopup")) { GenericSelector <string> selector = new GenericSelector <string>("SelectString", false, _odinTest.stringList); selector.SetSelection(_odinTest.stringList[selectIndex]); selector.SelectionTree.DefaultMenuStyle.Height = 20; selector.SelectionConfirmed += stringList => { _odinTest.selectString = stringList.FirstOrDefault(); }; selector.SelectionTree.Config.DrawSearchToolbar = true; var window = selector.ShowInPopup(); window.OnClose += selector.SelectionTree.Selection.ConfirmSelection; } } }
private GenericSelector <object> CreateSelector() { // TODO: Attribute is now cached, could that become a problem here? this.Attribute.IsUniqueList = this.Attribute.IsUniqueList || this.Attribute.ExcludeExistingValuesInList; IEnumerable <ValueDropdownItem> query = this.getValues(); if (query == null) { // God damm it bjarke. query = Enumerable.Empty <ValueDropdownItem>(); } var isEmpty = query == null || query.Any() == false; if (!isEmpty) { if (this.isList && this.Attribute.ExcludeExistingValuesInList || (this.isListElement && this.Attribute.IsUniqueList)) { var list = query.ToList(); var listProperty = this.Property.FindParent(x => (x.ChildResolver as IOrderedCollectionResolver) != null, true); var comparer = new IValueDropdownEqualityComparer(false); listProperty.ValueEntry.WeakValues.Cast <IEnumerable>() .SelectMany(x => x.Cast <object>()) .ForEach(x => { list.RemoveAll(c => comparer.Equals(c, x)); }); query = list; } } var enableSearch = this.Attribute.NumberOfItemsBeforeEnablingSearch == 0 || (query != null && query.Take(this.Attribute.NumberOfItemsBeforeEnablingSearch).Count() == this.Attribute.NumberOfItemsBeforeEnablingSearch); GenericSelector <object> selector = new GenericSelector <object>(this.Attribute.DropdownTitle, false, query.Select(x => new GenericSelectorItem <object>(x.Text, x.Value))); this.enableMultiSelect = this.isList && this.Attribute.IsUniqueList && !this.Attribute.ExcludeExistingValuesInList; if (this.Attribute.FlattenTreeView) { selector.FlattenedTree = true; } if (this.isList && !this.Attribute.ExcludeExistingValuesInList && this.Attribute.IsUniqueList) { selector.CheckboxToggle = true; } else if (this.Attribute.DoubleClickToConfirm == false && !enableMultiSelect) { selector.EnableSingleClickToSelect(); } if (this.isList && enableMultiSelect) { selector.SelectionTree.Selection.SupportsMultiSelect = true; selector.DrawConfirmSelectionButton = true; } selector.SelectionTree.Config.DrawSearchToolbar = enableSearch; IEnumerable <object> selection = Enumerable.Empty <object>(); if (!this.isList) { selection = this.getSelection(); } else if (this.enableMultiSelect) { selection = this.getSelection().SelectMany(x => (x as IEnumerable).Cast <object>()); } selector.SetSelection(selection); selector.SelectionTree.EnumerateTree().AddThumbnailIcons(true); if (this.Attribute.ExpandAllMenuItems) { selector.SelectionTree.EnumerateTree(x => x.Toggled = true); } if (this.Attribute.SortDropdownItems) { selector.SelectionTree.SortMenuItemsByName(); } return(selector); }
protected override void OnBeginDrawEditors() { var selected = this.MenuTree.Selection.FirstOrDefault(); var toolbarHeight = this.MenuTree.Config.SearchToolbarHeight; // Draws a toolbar with the name of the currently selected menu item. SirenixEditorGUI.BeginHorizontalToolbar(toolbarHeight); { if (selected != null) { GUILayout.Label(selected.Name); if (selected.Value.GetType() == typeof(Domain)) { Domain currentDomain = (Domain)selected.Value; if (SirenixEditorGUI.ToolbarButton(new GUIContent("Add New Feature"))) { // Add Feature Here EditorInputDialog.Show("New Feature", "Enter new Feature name", "", ret: val => { if (!string.IsNullOrEmpty(val)) { var newFeature = new Feature() { name = val, components = new List <Component>(), }; _currentFeatures.AddIfNotContains(newFeature); MenuTree.Add($"{currentDomain.name}/{newFeature.name}", newFeature); base.TrySelectMenuItemWithObject(newFeature); hasUnsavedChanges = true; } }); } if (SirenixEditorGUI.ToolbarButton(new GUIContent("Add Existing Feature"))) { // Add Feature Here var features = domains.Select(item => item.features).ToList(); var distinctFeatures = features.SelectMany(list => list).Distinct().ToList(); var distinctFeatureNames = distinctFeatures.Select(item => item.name).ToList(); string selectedFeatureName = distinctFeatureNames[0]; GenericSelector <string> selector = new GenericSelector <string>("Title", false, distinctFeatureNames); selector.SetSelection(selectedFeatureName); selector.SelectionTree.Config.DrawSearchToolbar = true; selector.SelectionTree.DefaultMenuStyle.Height = 22; selector.SelectionConfirmed += (selection) => { selectedFeatureName = selection.FirstOrDefault(); var selectedFeature = new Feature(distinctFeatures.FirstOrDefault(item => item.name == selectedFeatureName)); _currentFeatures.AddIfNotContains(selectedFeature); MenuTree.Add($"{currentDomain.name}/{selectedFeature.name}", selectedFeature); base.TrySelectMenuItemWithObject(selectedFeature); hasUnsavedChanges = true; }; var popup = selector.ShowInPopup(); } if (SirenixEditorGUI.ToolbarButton(new GUIContent("Delete Domain"))) { // Delete Domains Here EditorYesNoDialog.Show("Delete Domain?", "Are you sure, this will delete the\n domain with its entire hierarchy!", () => { domains.Remove(currentDomain); ForceMenuTreeRebuild(); hasUnsavedChanges = true; }, () => { // Do Nothing }); } } else if (selected.Value.GetType() == typeof(Feature)) { Domain currentDomain = (Domain)selected.Parent.Value; Feature currentFeature = (Feature)selected.Value; if (SirenixEditorGUI.ToolbarButton(new GUIContent("Add Component"))) { // Add Component Here EditorInputDialog.Show("New Component", "Enter new Component name", "", ret: val => { if (!string.IsNullOrEmpty(val)) { var newComponent = new Component() { name = val, asset = null, }; _currentComponents.Add(newComponent); MenuTree.Add($"{currentDomain.name}/{currentFeature.name}/{newComponent.name}", newComponent); base.TrySelectMenuItemWithObject(newComponent); hasUnsavedChanges = true; } }); } if (SirenixEditorGUI.ToolbarButton(new GUIContent("Delete Feature"))) { // Delete Domains Here EditorYesNoDialog.Show("Delete Feature?", "Are you sure, this will delete the\n feature with its entire hierarchy!", () => { currentDomain.features.Remove(currentFeature); ForceMenuTreeRebuild(); hasUnsavedChanges = true; }, () => { // Do Nothing }); } } else if (selected.Value.GetType() == typeof(Component)) { Domain currentDomain = (Domain)selected.Parent.Parent.Value; Feature currentFeature = (Feature)selected.Parent.Value; Component currentComponent = (Component)selected.Value; if (SirenixEditorGUI.ToolbarButton(new GUIContent("Delete Component"))) { // Delete Domains Here EditorYesNoDialog.Show("Delete Component?", "Are you sure, this will delete the component!", () => { currentFeature.components.Remove(currentComponent); ForceMenuTreeRebuild(); hasUnsavedChanges = true; }, () => { // Do Nothing }); } } } if (SirenixEditorGUI.ToolbarButton(new GUIContent("Add Domain"))) { // Add Domain Here EditorInputDialog.Show("New Domain", "Enter new Domain name", "", ret: val => { if (!string.IsNullOrEmpty(val)) { var newDomain = new Domain() { name = val, features = new List <Feature>(), }; domains.Add(newDomain); MenuTree.Add(newDomain.name, newDomain); base.TrySelectMenuItemWithObject(newDomain); hasUnsavedChanges = true; } }); } if (SirenixEditorGUI.ToolbarButton(new GUIContent("Save"))) { SaveChanges(); hasUnsavedChanges = false; } } SirenixEditorGUI.EndHorizontalToolbar(); }
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); } } } }