1import bpy 2 3 4class MATERIAL_UL_matslots_example(bpy.types.UIList): 5 # The draw_item function is called for each item of the collection that is visible in the list. 6 # data is the RNA object containing the collection, 7 # item is the current drawn item of the collection, 8 # icon is the "computed" icon for the item (as an integer, because some objects like materials or textures 9 # have custom icons ID, which are not available as enum items). 10 # active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the 11 # active item of the collection). 12 # active_propname is the name of the active property (use 'getattr(active_data, active_propname)'). 13 # index is index of the current item in the collection. 14 # flt_flag is the result of the filtering process for this item. 15 # Note: as index and flt_flag are optional arguments, you do not have to use/declare them here if you don't 16 # need them. 17 def draw_item(self, context, layout, data, item, icon, active_data, active_propname): 18 ob = data 19 slot = item 20 ma = slot.material 21 # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code. 22 if self.layout_type in {'DEFAULT', 'COMPACT'}: 23 # You should always start your row layout by a label (icon + text), or a non-embossed text field, 24 # this will also make the row easily selectable in the list! The later also enables ctrl-click rename. 25 # We use icon_value of label, as our given icon is an integer value, not an enum ID. 26 # Note "data" names should never be translated! 27 if ma: 28 layout.prop(ma, "name", text="", emboss=False, icon_value=icon) 29 else: 30 layout.label(text="", translate=False, icon_value=icon) 31 # 'GRID' layout type should be as compact as possible (typically a single icon!). 32 elif self.layout_type in {'GRID'}: 33 layout.alignment = 'CENTER' 34 layout.label(text="", icon_value=icon) 35 36 37# And now we can use this list everywhere in Blender. Here is a small example panel. 38class UIListPanelExample(bpy.types.Panel): 39 """Creates a Panel in the Object properties window""" 40 bl_label = "UIList Panel" 41 bl_idname = "OBJECT_PT_ui_list_example" 42 bl_space_type = 'PROPERTIES' 43 bl_region_type = 'WINDOW' 44 bl_context = "object" 45 46 def draw(self, context): 47 layout = self.layout 48 49 obj = context.object 50 51 # template_list now takes two new args. 52 # The first one is the identifier of the registered UIList to use (if you want only the default list, 53 # with no custom draw code, use "UI_UL_list"). 54 layout.template_list("MATERIAL_UL_matslots_example", "", obj, "material_slots", obj, "active_material_index") 55 56 # The second one can usually be left as an empty string. 57 # It's an additional ID used to distinguish lists in case you 58 # use the same list several times in a given area. 59 layout.template_list("MATERIAL_UL_matslots_example", "compact", obj, "material_slots", 60 obj, "active_material_index", type='COMPACT') 61 62 63def register(): 64 bpy.utils.register_class(MATERIAL_UL_matslots_example) 65 bpy.utils.register_class(UIListPanelExample) 66 67 68def unregister(): 69 bpy.utils.unregister_class(MATERIAL_UL_matslots_example) 70 bpy.utils.unregister_class(UIListPanelExample) 71 72 73if __name__ == "__main__": 74 register() 75