Refactor: Remove grid and compact UI list layout in Python scripts

The grid layout type for UI list is planned for removal in 5.0, see
blender/blender#110461.

In previous UI meetings, we talked about deprecating the Grid mode of
the UI list, which is not actually accessible in UI and was never used.
Nowadays, there is a new grid view that can be exposed in the API in
the future.

Initially, I wanted to remove references to layout_type in UI templates
in the text editor, because a lot of add-on developers on the
extensions platform base their lists on that code, and a lot of them
are therefore including soon to be deprecated code in their add-ons,
which I want to avoid in the future. But I thought we might as well
remove it from our python scripts as well, since it's just basically
redundant code that doesn't do anything. And also because many add-on
developers use bundled python scripts for references as well.

Pull Request: https://projects.blender.org/blender/blender/pulls/138395
This commit is contained in:
Nika Kutsniashvili
2025-06-18 13:45:06 +02:00
committed by Julian Eisel
parent 7f5a57d219
commit efa8d942b8
23 changed files with 216 additions and 355 deletions

View File

@@ -60,12 +60,7 @@ class gltf2_KHR_materials_variants_variant(bpy.types.PropertyGroup):
class SCENE_UL_gltf2_variants(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(item, "name", text="", emboss=False)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.prop(item, "name", text="", emboss=False)
class SCENE_PT_gltf2_variants(bpy.types.Panel):
@@ -320,12 +315,8 @@ class MESH_UL_gltf2_mesh_variants(bpy.types.UIList):
vari = item.variant
layout.context_pointer_set("id", vari)
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(bpy.data.scenes[0].gltf2_KHR_materials_variants_variants[vari.variant_idx],
"name", text="", emboss=False)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.prop(bpy.data.scenes[0].gltf2_KHR_materials_variants_variants[vari.variant_idx],
"name", text="", emboss=False)
class MESH_PT_gltf2_mesh_variants(bpy.types.Panel):
@@ -502,16 +493,11 @@ class gltf2_animation_NLATrackNames(bpy.types.PropertyGroup):
class SCENE_UL_gltf2_animation_track(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row()
icon = 'SOLO_ON' if index == bpy.data.scenes[0].gltf2_animation_applied else 'SOLO_OFF'
row.prop(item, "name", text="", emboss=False)
op = row.operator("scene.gltf2_animation_apply", text='', icon=icon)
op.index = index
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
row = layout.row()
icon = 'SOLO_ON' if index == bpy.data.scenes[0].gltf2_animation_applied else 'SOLO_OFF'
row.prop(item, "name", text="", emboss=False)
op = row.operator("scene.gltf2_animation_apply", text='', icon=icon)
op.index = index
class SCENE_OT_gltf2_animation_apply(bpy.types.Operator):
@@ -642,13 +628,8 @@ class SCENE_UL_gltf2_filter_action(bpy.types.UIList):
action = item.action
layout.context_pointer_set("id", action)
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.split().prop(item.action, "name", text="", emboss=False)
layout.split().prop(item, "keep", text="", emboss=True)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.split().prop(item.action, "name", text="", emboss=False)
layout.split().prop(item, "keep", text="", emboss=True)
def export_panel_animation_action_filter(layout, operator):

View File

@@ -167,29 +167,26 @@ class RIGIFY_UL_FeatureSets(bpy.types.UIList):
# feature_sets = rigify_prefs.rigify_feature_sets
# active_set: RigifyFeatureSets = feature_sets[rigify_prefs.active_feature_set_index]
feature_set_entry: RigifyFeatureSets = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row()
row = layout.row()
name = feature_set_entry.name
icon = "BLANK1"
name = feature_set_entry.name
icon = "BLANK1"
if not feature_set_entry.module_name:
name += iface_(" (not installed)")
icon = "URL"
elif feature_set_entry.has_errors or feature_set_entry.has_exceptions:
icon = "ERROR"
row.alert = True
if not feature_set_entry.module_name:
name += iface_(" (not installed)")
icon = "URL"
elif feature_set_entry.has_errors or feature_set_entry.has_exceptions:
icon = "ERROR"
row.alert = True
row.label(text=name, icon=icon, translate=False)
row.label(text=name, icon=icon, translate=False)
if feature_set_entry.module_name:
icon = 'CHECKBOX_HLT' if feature_set_entry.enabled else 'CHECKBOX_DEHLT'
row.enabled = feature_set_entry.enabled
layout.prop(feature_set_entry, 'enabled', text="", icon=icon, emboss=False)
else:
row.enabled = False
elif self.layout_type in {'GRID'}:
pass
if feature_set_entry.module_name:
icon = 'CHECKBOX_HLT' if feature_set_entry.enabled else 'CHECKBOX_DEHLT'
row.enabled = feature_set_entry.enabled
layout.prop(feature_set_entry, 'enabled', text="", icon=icon, emboss=False)
else:
row.enabled = False
class RigifyPreferences(AddonPreferences):

View File

@@ -232,88 +232,84 @@ class RIGIFY_UL_action_slots(UIList):
action_slots, action_slot_idx = get_action_slots_active(data)
active_action = action_slots[action_slot_idx]
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if action_slot.action:
row = layout.row()
icon = 'ACTION'
if action_slot.action:
row = layout.row()
icon = 'ACTION'
# Check if this action is a trigger for the active corrective action
if active_action.is_corrective and \
action_slot.action in [active_action.trigger_action_a,
active_action.trigger_action_b]:
icon = 'RESTRICT_INSTANCED_OFF'
# Check if this action is a trigger for the active corrective action
if active_action.is_corrective and \
action_slot.action in [active_action.trigger_action_a,
active_action.trigger_action_b]:
icon = 'RESTRICT_INSTANCED_OFF'
# Check if the active action is a trigger for this corrective action.
if action_slot.is_corrective and \
active_action.action in [action_slot.trigger_action_a,
action_slot.trigger_action_b]:
icon = 'RESTRICT_INSTANCED_OFF'
# Check if the active action is a trigger for this corrective action.
if action_slot.is_corrective and \
active_action.action in [action_slot.trigger_action_a,
action_slot.trigger_action_b]:
icon = 'RESTRICT_INSTANCED_OFF'
row.prop(action_slot.action, 'name', text="", emboss=False, icon=icon)
row.prop(action_slot.action, 'name', text="", emboss=False, icon=icon)
# Highlight various errors
# Highlight various errors
if find_duplicate_slot(data, action_slot):
# Multiple entries for the same action
row.alert = True
row.label(text="Duplicate", icon='ERROR')
if find_duplicate_slot(data, action_slot):
# Multiple entries for the same action
row.alert = True
row.label(text="Duplicate", icon='ERROR')
elif action_slot.is_corrective:
text = "Corrective"
icon = 'RESTRICT_INSTANCED_OFF'
elif action_slot.is_corrective:
text = "Corrective"
icon = 'RESTRICT_INSTANCED_OFF'
for trigger in [action_slot.trigger_action_a,
action_slot.trigger_action_b]:
trigger_slot, trigger_idx = find_slot_by_action(data, trigger)
for trigger in [action_slot.trigger_action_a,
action_slot.trigger_action_b]:
trigger_slot, trigger_idx = find_slot_by_action(data, trigger)
# No trigger action set, no slot or invalid slot
if not trigger_slot or trigger_slot.is_corrective:
row.alert = True
text = "No Trigger Action"
icon = 'ERROR'
break
row.label(text=text, icon=icon)
else:
text = action_slot.subtarget
icon = 'BONE_DATA'
target_rig = get_rigify_target_rig(data)
if not action_slot.subtarget:
# No trigger action set, no slot or invalid slot
if not trigger_slot or trigger_slot.is_corrective:
row.alert = True
text = 'No Control Bone'
text = "No Trigger Action"
icon = 'ERROR'
break
row.label(text=text, icon=icon)
else:
text = action_slot.subtarget
icon = 'BONE_DATA'
target_rig = get_rigify_target_rig(data)
if not action_slot.subtarget:
row.alert = True
text = 'No Control Bone'
icon = 'ERROR'
elif target_rig:
# Check for bones not actually present in the generated rig
bones = target_rig.pose.bones
if action_slot.subtarget not in bones:
row.alert = True
text = 'Bad Control Bone'
icon = 'ERROR'
elif (action_slot.symmetrical
and mirror_name(action_slot.subtarget) not in bones):
row.alert = True
text = 'Bad Control Bone'
icon = 'ERROR'
elif target_rig:
# Check for bones not actually present in the generated rig
bones = target_rig.pose.bones
row.label(text=text, icon=icon)
if action_slot.subtarget not in bones:
row.alert = True
text = 'Bad Control Bone'
icon = 'ERROR'
elif (action_slot.symmetrical
and mirror_name(action_slot.subtarget) not in bones):
row.alert = True
text = 'Bad Control Bone'
icon = 'ERROR'
icon = 'CHECKBOX_HLT' if action_slot.enabled else 'CHECKBOX_DEHLT'
row.enabled = action_slot.enabled
row.label(text=text, icon=icon)
layout.prop(action_slot, 'enabled', text="", icon=icon, emboss=False)
icon = 'CHECKBOX_HLT' if action_slot.enabled else 'CHECKBOX_DEHLT'
row.enabled = action_slot.enabled
# No action
else:
layout.label(text="", translate=False, icon='ACTION')
layout.prop(action_slot, 'enabled', text="", icon=icon, emboss=False)
# No action
else:
layout.label(text="", translate=False, icon='ACTION')
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
# noinspection PyPep8Naming

View File

@@ -107,13 +107,8 @@ class UI_UL_i18n_languages(UIList):
""" """
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(text=item.name, icon_value=icon)
layout.prop(item, "use", text="")
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label(text=item.uid)
layout.prop(item, "use", text="")
layout.label(text=item.name, icon_value=icon)
layout.prop(item, "use", text="")
class UI_PT_i18n_update_translations_settings(Panel):

View File

@@ -383,8 +383,7 @@ class POSE_UL_selection_set(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
row = layout.row()
row.prop(item, "name", text="", emboss=False)
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row.prop(item, "is_selected", text="")
row.prop(item, "is_selected", text="")
class POSE_MT_selection_set_create(Menu):

View File

@@ -31,14 +31,10 @@ class LayerDataButtonsPanel:
class GREASE_PENCIL_UL_masks(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
mask = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row(align=True)
row.prop(mask, "name", text="", emboss=False, icon_value=icon)
row.prop(mask, "invert", text="", emboss=False)
row.prop(mask, "hide", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.prop(mask, "name", text="", emboss=False, icon_value=icon)
row = layout.row(align=True)
row.prop(mask, "name", text="", emboss=False, icon_value=icon)
row.prop(mask, "invert", text="", emboss=False)
row.prop(mask, "hide", text="", emboss=False)
class GreasePencil_LayerMaskPanel:

View File

@@ -109,25 +109,17 @@ class MESH_UL_vgroups(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data_, _active_propname, _index):
# assert(isinstance(item, bpy.types.VertexGroup))
vgroup = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon)
icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED'
layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon)
icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED'
layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
class MESH_UL_uvmaps(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, (bpy.types.MeshTexturePolyLayer, bpy.types.MeshLoopColorLayer)))
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(item, "name", text="", emboss=False, icon='GROUP_UVS')
icon = 'RESTRICT_RENDER_OFF' if item.active_render else 'RESTRICT_RENDER_ON'
layout.prop(item, "active_render", text="", icon=icon, emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
layout.prop(item, "name", text="", emboss=False, icon='GROUP_UVS')
icon = 'RESTRICT_RENDER_OFF' if item.active_render else 'RESTRICT_RENDER_ON'
layout.prop(item, "active_render", text="", icon=icon, emboss=False)
class MeshButtonsPanel:

View File

@@ -116,12 +116,8 @@ class ViewLayerFreestyleLinestyleStrokesSubPanel(ViewLayerFreestyleLineStyle):
class VIEWLAYER_UL_linesets(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, index):
lineset = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(lineset, "name", text="", emboss=False, icon_value=icon)
layout.prop(lineset, "show_render", text="", index=index)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
layout.prop(lineset, "name", text="", emboss=False, icon_value=icon)
layout.prop(lineset, "show_render", text="", index=index)
class RENDER_MT_lineset_context_menu(Menu):

View File

@@ -247,23 +247,18 @@ class GPENCIL_UL_annotation_layer(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.GPencilLayer)
gpl = item
if gpl.lock:
layout.active = False
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if gpl.lock:
layout.active = False
split = layout.split(factor=0.2)
split.prop(gpl, "color", text="", emboss=True)
split.prop(gpl, "info", text="", emboss=False)
split = layout.split(factor=0.2)
split.prop(gpl, "color", text="", emboss=True)
split.prop(gpl, "info", text="", emboss=False)
row = layout.row(align=True)
row = layout.row(align=True)
row.prop(gpl, "show_in_front", text="", icon='XRAY' if gpl.show_in_front else 'FACESEL', emboss=False)
row.prop(gpl, "show_in_front", text="", icon='XRAY' if gpl.show_in_front else 'FACESEL', emboss=False)
row.prop(gpl, "annotation_hide", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
row.prop(gpl, "annotation_hide", text="", emboss=False)
class AnnotationDataPanel:
@@ -510,40 +505,32 @@ class GPENCIL_UL_layer(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.GPencilLayer)
gpl = item
if gpl.lock:
layout.active = False
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if gpl.lock:
layout.active = False
row = layout.row(align=True)
row.label(
text="",
icon='BONE_DATA' if gpl.is_parented else 'BLANK1',
)
row.prop(gpl, "info", text="", emboss=False)
row = layout.row(align=True)
row.label(
text="",
icon='BONE_DATA' if gpl.is_parented else 'BLANK1',
)
row.prop(gpl, "info", text="", emboss=False)
row = layout.row(align=True)
row = layout.row(align=True)
icon_mask = 'CLIPUV_DEHLT' if gpl.use_mask_layer else 'CLIPUV_HLT'
icon_mask = 'CLIPUV_DEHLT' if gpl.use_mask_layer else 'CLIPUV_HLT'
row.prop(gpl, "use_mask_layer", text="", icon=icon_mask, emboss=False)
row.prop(gpl, "use_mask_layer", text="", icon=icon_mask, emboss=False)
subrow = row.row(align=True)
subrow.prop(
gpl,
"use_onion_skinning",
text="",
icon='ONIONSKIN_ON' if gpl.use_onion_skinning else 'ONIONSKIN_OFF',
emboss=False,
)
row.prop(gpl, "hide", text="", emboss=False)
row.prop(gpl, "lock", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(
text="",
icon_value=icon,
)
subrow = row.row(align=True)
subrow.prop(
gpl,
"use_onion_skinning",
text="",
icon='ONIONSKIN_ON' if gpl.use_onion_skinning else 'ONIONSKIN_OFF',
emboss=False,
)
row.prop(gpl, "hide", text="", emboss=False)
row.prop(gpl, "lock", text="", emboss=False)
class GreasePencilSimplifyPanel:
@@ -617,14 +604,10 @@ class GreasePencilLayerAdjustmentsPanel:
class GPENCIL_UL_masks(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
mask = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row(align=True)
row.prop(mask, "name", text="", emboss=False, icon_value=icon)
row.prop(mask, "invert", text="", emboss=False)
row.prop(mask, "hide", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.prop(mask, "name", text="", emboss=False, icon_value=icon)
row = layout.row(align=True)
row.prop(mask, "name", text="", emboss=False, icon_value=icon)
row.prop(mask, "invert", text="", emboss=False)
row.prop(mask, "hide", text="", emboss=False)
class GreasePencilLayerRelationsPanel:

View File

@@ -40,15 +40,11 @@ class MASK_UL_layers(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.MaskLayer)
mask = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(mask, "name", text="", emboss=False, icon_value=icon)
row = layout.row(align=True)
row.prop(mask, "hide", text="", emboss=False)
row.prop(mask, "hide_select", text="", emboss=False)
row.prop(mask, "hide_render", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
layout.prop(mask, "name", text="", emboss=False, icon_value=icon)
row = layout.row(align=True)
row.prop(mask, "hide", text="", emboss=False)
row.prop(mask, "hide_select", text="", emboss=False)
row.prop(mask, "hide_render", text="", emboss=False)
class MASK_PT_mask:

View File

@@ -35,13 +35,9 @@ class MATERIAL_UL_matslots(UIList):
layout.context_pointer_set("id", ma)
layout.context_pointer_set("material_slot", slot)
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if ma:
layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
else:
layout.label(text="", icon_value=icon)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
if ma:
layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
else:
layout.label(text="", icon_value=icon)

View File

@@ -48,33 +48,28 @@ class GPENCIL_UL_matslots(UIList):
slot = item
ma = slot.material
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row(align=True)
row.label(text="", icon_value=icon)
row = layout.row(align=True)
row.label(text="", icon_value=icon)
if ma is None:
return
if ma is None:
return
if (gpcolor := ma.grease_pencil) is None:
return
if (gpcolor := ma.grease_pencil) is None:
return
row = layout.row(align=True)
row.enabled = not gpcolor.lock
row.prop(ma, "name", text="", emboss=False, icon='NONE')
row = layout.row(align=True)
row.enabled = not gpcolor.lock
row.prop(ma, "name", text="", emboss=False, icon='NONE')
row = layout.row(align=True)
row = layout.row(align=True)
if gpcolor.ghost is True:
icon = 'ONIONSKIN_OFF'
else:
icon = 'ONIONSKIN_ON'
row.prop(gpcolor, "ghost", text="", icon=icon, emboss=False)
row.prop(gpcolor, "hide", text="", emboss=False)
row.prop(gpcolor, "lock", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
if gpcolor.ghost is True:
icon = 'ONIONSKIN_OFF'
else:
icon = 'ONIONSKIN_ON'
row.prop(gpcolor, "ghost", text="", icon=icon, emboss=False)
row.prop(gpcolor, "hide", text="", emboss=False)
row.prop(gpcolor, "lock", text="", emboss=False)
class GPMaterialButtonsPanel:

View File

@@ -625,16 +625,11 @@ class RENDER_PT_encoding_audio(RenderOutputButtonsPanel, Panel):
class RENDER_UL_renderviews(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, index):
view = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if view.name in {"left", "right"}:
layout.label(text=view.name, icon_value=icon + (not view.use))
else:
layout.prop(view, "name", text="", index=index, icon_value=icon, emboss=False)
layout.prop(view, "use", text="", index=index)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon + (not view.use))
if view.name in {"left", "right"}:
layout.label(text=view.name, icon_value=icon + (not view.use))
else:
layout.prop(view, "name", text="", index=index, icon_value=icon, emboss=False)
layout.prop(view, "use", text="", index=index)
class RENDER_PT_stereoscopy(RenderOutputButtonsPanel, Panel):

View File

@@ -134,28 +134,23 @@ class PARTICLE_UL_particle_systems(UIList):
ob = data
psys = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
md = find_modifier(ob, psys)
row = layout.row(align=True)
md = find_modifier(ob, psys)
row = layout.row(align=True)
row.prop(psys, "name", text="", emboss=False, icon_value=icon)
if md:
row.prop(
md,
"show_viewport",
emboss=False,
icon_only=True,
)
row.prop(
md,
"show_render",
emboss=False,
icon_only=True,
)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
row.prop(psys, "name", text="", emboss=False, icon_value=icon)
if md:
row.prop(
md,
"show_viewport",
emboss=False,
icon_only=True,
)
row.prop(
md,
"show_render",
emboss=False,
icon_only=True,
)
class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):

View File

@@ -19,18 +19,11 @@ class PHYSICS_UL_dynapaint_surfaces(UIList):
surf = item
sticon = layout.enum_item_icon(surf, "surface_type", surf.surface_type)
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row(align=True)
row.label(text="", icon_value=icon)
row.prop(surf, "name", text="", emboss=False, icon_value=sticon)
row = layout.row(align=True)
row.prop(surf, "is_active", text="")
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
row = layout.row(align=True)
row.label(text="", icon_value=icon)
row.label(text="", icon_value=sticon)
row = layout.row(align=True)
row.label(text="", icon_value=icon)
row.prop(surf, "name", text="", emboss=False, icon_value=sticon)
row = layout.row(align=True)
row.prop(surf, "is_active", text="")
class PhysicButtonsPanel:

View File

@@ -24,12 +24,8 @@ class SCENE_UL_keying_set_paths(UIList):
# assert(isinstance(item, bpy.types.KeyingSetPath)
kspath = item
icon = layout.enum_item_icon(kspath, "id_type", kspath.id_type)
if self.layout_type in {'DEFAULT', 'COMPACT'}:
# Do not make this one editable in uiList for now...
layout.label(text=kspath.data_path, translate=False, icon_value=icon)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
# Do not make this one editable in uiList for now...
layout.label(text=kspath.data_path, translate=False, icon_value=icon)
class SceneButtonsPanel:

View File

@@ -38,13 +38,9 @@ class TEXTURE_UL_texslots(UIList):
slot = item
tex = slot.texture if slot else None
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if tex:
layout.prop(tex, "name", text="", emboss=False, icon_value=icon)
else:
layout.label(text="", icon_value=icon)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
if tex:
layout.prop(tex, "name", text="", emboss=False, icon_value=icon)
else:
layout.label(text="", icon_value=icon)

View File

@@ -20,17 +20,10 @@ class CLIP_UL_tracking_objects(UIList):
def draw_item(self, _context, layout, _data, item, _icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.MovieTrackingObject)
tobj = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(
tobj, "name", text="", emboss=False,
icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA',
)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(
text="",
icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA',
)
layout.prop(
tobj, "name", text="", emboss=False,
icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA',
)
class CLIP_PT_display(Panel):

View File

@@ -210,18 +210,13 @@ class FILEBROWSER_UL_dir(UIList):
direntry = item
# space = context.space_data
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row(align=True)
row.enabled = direntry.is_valid
# Non-editable entries would show grayed-out, which is bad in this specific case, so switch to mere label.
if direntry.is_property_readonly("name"):
row.label(text=direntry.name, icon_value=icon)
else:
row.prop(direntry, "name", text="", emboss=False, icon_value=icon)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.prop(direntry, "path", text="")
row = layout.row(align=True)
row.enabled = direntry.is_valid
# Non-editable entries would show grayed-out, which is bad in this specific case, so switch to mere label.
if direntry.is_property_readonly("name"):
row.label(text=direntry.name, icon_value=icon)
else:
row.prop(direntry, "name", text="", emboss=False, icon_value=icon)
class FILEBROWSER_PT_bookmarks_volumes(Panel):

View File

@@ -1729,23 +1729,14 @@ class USERPREF_PT_file_paths_asset_libraries(FilePathsPanel, Panel):
class USERPREF_UL_asset_libraries(UIList):
def draw_item(self, _context, layout, _data, item, _icon, _active_data, _active_propname, _index):
asset_library = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(asset_library, "name", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.prop(asset_library, "name", text="", emboss=False)
layout.prop(asset_library, "name", text="", emboss=False)
class USERPREF_UL_extension_repos(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
repo = item
icon = 'INTERNET' if repo.use_remote_url else 'DISK_DRIVE'
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(repo, "name", text="", icon=icon, emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.prop(repo, "name", text="", icon=icon, emboss=False)
layout.prop(repo, "name", text="", icon=icon, emboss=False)
# Show an error icon if this repository has unusable settings.
if repo.enabled:

View File

@@ -265,11 +265,7 @@ class TEXTURE_UL_texpaintslots(UIList):
if ima is not None and ima.is_editable:
layout.enabled = False
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(text=item.name, icon_value=item.icon_value)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="")
layout.label(text=item.name, icon_value=item.icon_value)
class View3DPaintPanel(View3DPanel, UnifiedPaintPanel):

View File

@@ -14,12 +14,7 @@ class MESH_UL_mylist(bpy.types.UIList):
# Called for each drawn item.
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag):
# 'DEFAULT' and 'COMPACT' layout types should usually use the same draw code.
if self.layout_type in {'DEFAULT', 'COMPACT'}:
pass
# 'GRID' layout type should be as compact as possible (typically a single icon!).
elif self.layout_type == 'GRID':
pass
pass
# Called once to draw filtering/reordering options.
def draw_filter(self, context, layout):

View File

@@ -18,20 +18,14 @@ class MATERIAL_UL_matslots_example(bpy.types.UIList):
ob = data
slot = item
ma = slot.material
# draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
if self.layout_type in {'DEFAULT', 'COMPACT'}:
# You should always start your row layout by a label (icon + text), or a non-embossed text field,
# this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
# Note "data" names should never be translated!
if ma:
layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
else:
layout.label(text="", translate=False, icon_value=icon)
# 'GRID' layout type should be as compact as possible (typically a single icon!).
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
# You should always start your row layout by a label (icon + text), or a non-embossed text field,
# this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
# Note "data" names should never be translated!
if ma:
layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
else:
layout.label(text="", translate=False, icon_value=icon)
# And now we can use this list everywhere in Blender. Here is a small example panel.