Access index or component type in list
I'd like to customize a list of elements to show a bold title that delineates each element. The list is of an abstract class, and each element might have a different subclass.
Ideally, the title would have the index and the class/type name and replace the reference picker. The HideReferenceObjectPicker
is nice, but the Title
attribute has to be a static string.
Maybe you could add an option to display the index in lists? Or support arbitrary functions in the Title attribute, and getting the index or class type within lists somehow?
Comments (6)
-
-
- changed status to open
-
reporter That suggested solution would be fantastic, but for now I'll use the messy suggestion. Thanks :)
-
Since the suggested approach has not been implemented yet, is there a way to modify the provided workaround to also still show an object picker?
So for example, to have the Label header of each element look like this:
[Index] : [Field/Property value on object (if not null)] [Object Picker]
If not, at least I would like to make sure that when the suggested approach is implemented, that this kind of a header format is possible. In other words,
OnListElementGUI
should still play nice withShowIndexLabels
and the Object picker. -
Sadly there is no pretty way of doing this at the moment. It could look something like this:
public class MyComponent : SerializedMonoBehaviour { [ListElementLabelText("Name", true)] public List<MyClass> Test; } public class MyClass { public string Name; } public class ListElementLabelTextAttribute : Attribute { public readonly string LabelMemberName; public readonly bool PrependListElementIndex; public ListElementLabelTextAttribute(string labelMemberName, bool prependListElementIndex) { this.LabelMemberName = labelMemberName; this.PrependListElementIndex = prependListElementIndex; } } [OdinDrawer] [DrawerPriority(0, 100, 0)] public class ListElementLabelTextAttributeDrawer : OdinAttributeDrawer<ListElementLabelTextAttribute> { public override bool CanDrawTypeFilter(Type type) { return !type.InheritsFrom<IList>(); } private class Context { public StringMemberHelper StringMemberHelper; public GUIContent Label; } protected override void DrawPropertyLayout(InspectorProperty property, ListElementLabelTextAttribute attribute, GUIContent label) { Context context; if (property.Context.Get<Context>(this, "Context", out context)) { context.StringMemberHelper = new StringMemberHelper(property.ValueEntry.TypeOfValue, "$" + attribute.LabelMemberName); context.Label = new GUIContent(); } if (context.StringMemberHelper.ErrorMessage != null) { SirenixEditorGUI.ErrorMessageBox(context.StringMemberHelper.ErrorMessage); this.CallNextDrawer(property, label); } else { var instance = property.ValueEntry.WeakValues[0]; context.Label.text = attribute.PrependListElementIndex ? property.Index.ToString() + " : " : ""; context.Label.text += instance == null ? "Null" : context.StringMemberHelper.GetString(instance); // If you want the object picker to be collapsed, then you could uncomment the code below. // It will also be applied for all child elements, so it's not the pretties way of doing it. Need to think a bit about that one. // var tmp = GeneralDrawerConfig.Instance.ExpandFoldoutByDefault; // GeneralDrawerConfig.Instance.ExpandFoldoutByDefault = false; this.CallNextDrawer(property, context.Label); // GeneralDrawerConfig.Instance.ExpandFoldoutByDefault = tmp; } } }
I don't think we'll implement this exact attribute. But something like that should be via ListDrawerSettings attribute in the future.
-
- changed status to resolved
- Added support for injecting GUI before and after each element is drawin inside a list. This is achived using the [ListDrawerSettingsAttribute(OnBeginListElementGUI = "OnBeginListElementGUIMethodName", OnEndListElementGUI = "OnEndListElementGUIMethodName")].
- Added support to the ListDrawerSettings attribute for defining custom label text for each list element. This is achived using the [ListDrawerSettingsAttribute(ListElementLabelName = "ListElementLabelName")].
- Log in to comment
Nice use-case you have. It is exactly cases like that that Odin needs to shine.
You can get some of the behavior by adding:
However, in 0.9.0.3, It shows the label name again, followed by the index. This is changed in the next patch to only show the index. In the next version it looks like this:
Alternatively, you could do something slightly messier:
Though I don't think it's the cleanest of solutions. I'll talk with the other about adding the option you suggested where you can inject GUI into each element. Something like this right?