4
This script is the UIList subclass used to show material slots, with a bunch of additional commentaries.
6
Notice the name of the class, this naming convention is similar as the one for panels or menus.
10
UIList subclasses must be registered for blender to use them.
15
class MATERIAL_UL_matslots_example(bpy.types.UIList):
16
# The draw_item function is called for each item of the collection that is visible in the list.
17
# data is the RNA object containing the collection,
18
# item is the current drawn item of the collection,
19
# icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
20
# have custom icons ID, which are not available as enum items).
21
# active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
22
# active item of the collection).
23
# active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
24
# index is index of the current item in the collection.
25
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
29
# draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
30
if self.layout_type in {'DEFAULT', 'COMPACT'}:
31
# You should always start your row layout by a label (icon + text), this will also make the row easily
32
# selectable in the list!
33
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
34
# Note "data" names should never be translated!
35
layout.label(text=ma.name if ma else "", translate=False, icon_value=icon)
36
# And now we can add other UI stuff...
37
# Here, we add nodes info if this material uses (old!) shading nodes.
38
if ma and not context.scene.render.use_shading_nodes:
39
manode = ma.active_node_material
41
# The static method UILayout.icon returns the integer value of the icon ID "computed" for the given
43
layout.label(text="Node %s" % manode.name, translate=False, icon_value=layout.icon(manode))
45
layout.label(text="Node <none>", translate=False)
48
# 'GRID' layout type should be as compact as possible (typically a single icon!).
49
elif self.layout_type in {'GRID'}:
50
layout.alignment = 'CENTER'
51
layout.label(text="", icon_value=icon)
54
# And now we can use this list everywhere in Blender. Here is a small example panel.
55
class UIListPanelExample(bpy.types.Panel):
56
"""Creates a Panel in the Object properties window"""
57
bl_label = "UIList Panel"
58
bl_idname = "OBJECT_PT_ui_list_example"
59
bl_space_type = 'PROPERTIES'
60
bl_region_type = 'WINDOW'
63
def draw(self, context):
68
# template_list now takes two new args.
69
# The first one is the identifier of the registered UIList to use (if you want only the default list,
70
# with no custom draw code, use "UI_UL_list").
71
layout.template_list("MATERIAL_UL_matslots_example", "", obj, "material_slots", obj, "active_material_index")
73
# The second one can usually be left as an empty string. It's an additional ID used to distinguish lists in case you
74
# use the same list several times in a given area.
75
layout.template_list("MATERIAL_UL_matslots_example", "compact", obj, "material_slots",
76
obj, "active_material_index", type='COMPACT')
80
bpy.utils.register_class(MATERIAL_UL_matslots_example)
81
bpy.utils.register_class(UIListPanelExample)
85
bpy.utils.unregister_class(MATERIAL_UL_matslots_example)
86
bpy.utils.unregister_class(UIListPanelExample)
89
if __name__ == "__main__":