I'm making an add-on and would like to have properties for selecting ID-blocks and data paths, similar to those in KeyingSetPath. Here's how I'm declaring them:
item: PointerProperty(name="Data",
type=bpy.types.ID,
description="Data with an animatable property")
item_type: EnumProperty(name="Data type", items=id_type_items, default="OBJECT")
data_path: StringProperty(name="Data path",
description="RNA path of property to check")
Here's how I'm making the UI (referencing properties_scene.py):
flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=True)
layout.use_property_split = True
layout.use_property_decorate = False
col = flow.column()
col.template_any_ID(myobject, "item", "item_type", text="Target ID-Block")
col.separator()
col.template_path_builder(myobject, "data_path", myobject.item)
However, the resulting search box is always disabled/grayed-out. As far as I can tell the only difference between the property that I declared and KeyingSetPath.id is that mine is created dynamically (i.e., in a Python script). What else could I be doing wrong?
Strangely, if I change the property type to a specific ID subclass, like Object, it works. The documentation suggests this might be intentional, but I can't find the code that enforces it:
type (class) – A subclass of
bpy.types.PropertyGrouporbpy.types.ID.
If it is intentional, what is the reason for the limitation, and why is KeyingSetPath.id exempt?
Update 1: KeyingSetPath.id does have "editable" and "type" functions set, to dynamically determine those things, and I can't set those functions from Python, but it seems like it should still work correctly without them. I don't need the type of the data block so I tried just using template_ID instead of template_any_ID, but then the field disappears entirely!
Update 2: I found this answer which makes their own ID type selector and search box but does so by creating a separate property for every single ID data type. It would still be nice to know why template_any_ID doesn't work.
Update 3: I figured out that it is indeed the "type" function that makes it work for KeyingSetPath.id. ui_but_add_search calls RNA_property_pointer_type to get the pointed type, which calls type_fn, and then search_id_collection which looks for a collection that holds that type. I'll see if I can make a workaround or patch.
KeyingSetPath.idis defined directly as a property in the C code, not a getter function. You can check this withbpy.types.KeyingSetPath.bl_rna.properties['id']. It's declared inrna_animation.crna_def_keyingset_path, and the lineRNA_def_property_struct_type(prop, "ID");seems to suggest that it's a pointer property with typeID, just like the one I defined. $\endgroup$