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): class SCENE_UL_gltf2_variants(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
layout.prop(item, "name", text="", emboss=False)
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(item, "name", text="", emboss=False)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
class SCENE_PT_gltf2_variants(bpy.types.Panel): class SCENE_PT_gltf2_variants(bpy.types.Panel):
@@ -320,12 +315,8 @@ class MESH_UL_gltf2_mesh_variants(bpy.types.UIList):
vari = item.variant vari = item.variant
layout.context_pointer_set("id", vari) layout.context_pointer_set("id", vari)
layout.prop(bpy.data.scenes[0].gltf2_KHR_materials_variants_variants[vari.variant_idx],
if self.layout_type in {'DEFAULT', 'COMPACT'}: "name", text="", emboss=False)
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'
class MESH_PT_gltf2_mesh_variants(bpy.types.Panel): 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): class SCENE_UL_gltf2_animation_track(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
row = layout.row()
if self.layout_type in {'DEFAULT', 'COMPACT'}: icon = 'SOLO_ON' if index == bpy.data.scenes[0].gltf2_animation_applied else 'SOLO_OFF'
row = layout.row() row.prop(item, "name", text="", emboss=False)
icon = 'SOLO_ON' if index == bpy.data.scenes[0].gltf2_animation_applied else 'SOLO_OFF' op = row.operator("scene.gltf2_animation_apply", text='', icon=icon)
row.prop(item, "name", text="", emboss=False) op.index = index
op = row.operator("scene.gltf2_animation_apply", text='', icon=icon)
op.index = index
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
class SCENE_OT_gltf2_animation_apply(bpy.types.Operator): 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 action = item.action
layout.context_pointer_set("id", action) layout.context_pointer_set("id", action)
layout.split().prop(item.action, "name", text="", emboss=False)
if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.split().prop(item, "keep", text="", emboss=True)
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'
def export_panel_animation_action_filter(layout, operator): 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 # feature_sets = rigify_prefs.rigify_feature_sets
# active_set: RigifyFeatureSets = feature_sets[rigify_prefs.active_feature_set_index] # active_set: RigifyFeatureSets = feature_sets[rigify_prefs.active_feature_set_index]
feature_set_entry: RigifyFeatureSets = item feature_set_entry: RigifyFeatureSets = item
if self.layout_type in {'DEFAULT', 'COMPACT'}: row = layout.row()
row = layout.row()
name = feature_set_entry.name name = feature_set_entry.name
icon = "BLANK1" icon = "BLANK1"
if not feature_set_entry.module_name: if not feature_set_entry.module_name:
name += iface_(" (not installed)") name += iface_(" (not installed)")
icon = "URL" icon = "URL"
elif feature_set_entry.has_errors or feature_set_entry.has_exceptions: elif feature_set_entry.has_errors or feature_set_entry.has_exceptions:
icon = "ERROR" icon = "ERROR"
row.alert = True 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: if feature_set_entry.module_name:
icon = 'CHECKBOX_HLT' if feature_set_entry.enabled else 'CHECKBOX_DEHLT' icon = 'CHECKBOX_HLT' if feature_set_entry.enabled else 'CHECKBOX_DEHLT'
row.enabled = feature_set_entry.enabled row.enabled = feature_set_entry.enabled
layout.prop(feature_set_entry, 'enabled', text="", icon=icon, emboss=False) layout.prop(feature_set_entry, 'enabled', text="", icon=icon, emboss=False)
else: else:
row.enabled = False row.enabled = False
elif self.layout_type in {'GRID'}:
pass
class RigifyPreferences(AddonPreferences): 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) action_slots, action_slot_idx = get_action_slots_active(data)
active_action = action_slots[action_slot_idx] active_action = action_slots[action_slot_idx]
if self.layout_type in {'DEFAULT', 'COMPACT'}: if action_slot.action:
if action_slot.action: row = layout.row()
row = layout.row() icon = 'ACTION'
icon = 'ACTION'
# Check if this action is a trigger for the active corrective action # Check if this action is a trigger for the active corrective action
if active_action.is_corrective and \ if active_action.is_corrective and \
action_slot.action in [active_action.trigger_action_a, action_slot.action in [active_action.trigger_action_a,
active_action.trigger_action_b]: active_action.trigger_action_b]:
icon = 'RESTRICT_INSTANCED_OFF' icon = 'RESTRICT_INSTANCED_OFF'
# Check if the active action is a trigger for this corrective action. # Check if the active action is a trigger for this corrective action.
if action_slot.is_corrective and \ if action_slot.is_corrective and \
active_action.action in [action_slot.trigger_action_a, active_action.action in [action_slot.trigger_action_a,
action_slot.trigger_action_b]: action_slot.trigger_action_b]:
icon = 'RESTRICT_INSTANCED_OFF' 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): if find_duplicate_slot(data, action_slot):
# Multiple entries for the same action # Multiple entries for the same action
row.alert = True row.alert = True
row.label(text="Duplicate", icon='ERROR') row.label(text="Duplicate", icon='ERROR')
elif action_slot.is_corrective: elif action_slot.is_corrective:
text = "Corrective" text = "Corrective"
icon = 'RESTRICT_INSTANCED_OFF' icon = 'RESTRICT_INSTANCED_OFF'
for trigger in [action_slot.trigger_action_a, for trigger in [action_slot.trigger_action_a,
action_slot.trigger_action_b]: action_slot.trigger_action_b]:
trigger_slot, trigger_idx = find_slot_by_action(data, trigger) trigger_slot, trigger_idx = find_slot_by_action(data, trigger)
# No trigger action set, no slot or invalid slot # No trigger action set, no slot or invalid slot
if not trigger_slot or trigger_slot.is_corrective: 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:
row.alert = True 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' icon = 'ERROR'
elif target_rig: row.label(text=text, icon=icon)
# Check for bones not actually present in the generated rig
bones = target_rig.pose.bones
if action_slot.subtarget not in bones: icon = 'CHECKBOX_HLT' if action_slot.enabled else 'CHECKBOX_DEHLT'
row.alert = True row.enabled = action_slot.enabled
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'
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' # No action
row.enabled = action_slot.enabled 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 # 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): 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.label(text=item.name, icon_value=icon) layout.prop(item, "use", text="")
layout.prop(item, "use", text="")
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label(text=item.uid)
layout.prop(item, "use", text="")
class UI_PT_i18n_update_translations_settings(Panel): 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): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
row = layout.row() row = layout.row()
row.prop(item, "name", text="", emboss=False) 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): class POSE_MT_selection_set_create(Menu):

View File

@@ -31,14 +31,10 @@ class LayerDataButtonsPanel:
class GREASE_PENCIL_UL_masks(UIList): class GREASE_PENCIL_UL_masks(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
mask = item mask = item
if self.layout_type in {'DEFAULT', 'COMPACT'}: row = layout.row(align=True)
row = layout.row(align=True) row.prop(mask, "name", text="", emboss=False, icon_value=icon)
row.prop(mask, "name", text="", emboss=False, icon_value=icon) row.prop(mask, "invert", text="", emboss=False)
row.prop(mask, "invert", text="", emboss=False) row.prop(mask, "hide", 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)
class GreasePencil_LayerMaskPanel: 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): def draw_item(self, _context, layout, _data, item, icon, _active_data_, _active_propname, _index):
# assert(isinstance(item, bpy.types.VertexGroup)) # assert(isinstance(item, bpy.types.VertexGroup))
vgroup = item vgroup = item
if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon)
layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon) icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED'
icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED' layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
class MESH_UL_uvmaps(UIList): class MESH_UL_uvmaps(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, (bpy.types.MeshTexturePolyLayer, bpy.types.MeshLoopColorLayer))) # 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')
layout.prop(item, "name", text="", emboss=False, icon='GROUP_UVS') icon = 'RESTRICT_RENDER_OFF' if item.active_render else 'RESTRICT_RENDER_ON'
icon = 'RESTRICT_RENDER_OFF' if item.active_render else 'RESTRICT_RENDER_ON' layout.prop(item, "active_render", text="", icon=icon, emboss=False)
layout.prop(item, "active_render", text="", icon=icon, emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
class MeshButtonsPanel: class MeshButtonsPanel:

View File

@@ -116,12 +116,8 @@ class ViewLayerFreestyleLinestyleStrokesSubPanel(ViewLayerFreestyleLineStyle):
class VIEWLAYER_UL_linesets(UIList): class VIEWLAYER_UL_linesets(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, index): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, index):
lineset = item lineset = item
if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.prop(lineset, "name", text="", emboss=False, icon_value=icon)
layout.prop(lineset, "name", text="", emboss=False, icon_value=icon) layout.prop(lineset, "show_render", text="", index=index)
layout.prop(lineset, "show_render", text="", index=index)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
class RENDER_MT_lineset_context_menu(Menu): 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): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.GPencilLayer) # assert(isinstance(item, bpy.types.GPencilLayer)
gpl = item gpl = item
if gpl.lock:
layout.active = False
if self.layout_type in {'DEFAULT', 'COMPACT'}: split = layout.split(factor=0.2)
if gpl.lock: split.prop(gpl, "color", text="", emboss=True)
layout.active = False split.prop(gpl, "info", text="", emboss=False)
split = layout.split(factor=0.2) row = layout.row(align=True)
split.prop(gpl, "color", text="", emboss=True)
split.prop(gpl, "info", text="", emboss=False)
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)
row.prop(gpl, "annotation_hide", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
class AnnotationDataPanel: 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): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.GPencilLayer) # assert(isinstance(item, bpy.types.GPencilLayer)
gpl = item gpl = item
if gpl.lock:
layout.active = False
if self.layout_type in {'DEFAULT', 'COMPACT'}: row = layout.row(align=True)
if gpl.lock: row.label(
layout.active = False 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)
row.label(
text="",
icon='BONE_DATA' if gpl.is_parented else 'BLANK1',
)
row.prop(gpl, "info", text="", emboss=False)
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(
subrow = row.row(align=True) gpl,
subrow.prop( "use_onion_skinning",
gpl, text="",
"use_onion_skinning", icon='ONIONSKIN_ON' if gpl.use_onion_skinning else 'ONIONSKIN_OFF',
text="", emboss=False,
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)
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,
)
class GreasePencilSimplifyPanel: class GreasePencilSimplifyPanel:
@@ -617,14 +604,10 @@ class GreasePencilLayerAdjustmentsPanel:
class GPENCIL_UL_masks(UIList): class GPENCIL_UL_masks(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
mask = item mask = item
if self.layout_type in {'DEFAULT', 'COMPACT'}: row = layout.row(align=True)
row = layout.row(align=True) row.prop(mask, "name", text="", emboss=False, icon_value=icon)
row.prop(mask, "name", text="", emboss=False, icon_value=icon) row.prop(mask, "invert", text="", emboss=False)
row.prop(mask, "invert", text="", emboss=False) row.prop(mask, "hide", 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)
class GreasePencilLayerRelationsPanel: 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): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.MaskLayer) # assert(isinstance(item, bpy.types.MaskLayer)
mask = item mask = item
if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.prop(mask, "name", text="", emboss=False, icon_value=icon)
layout.prop(mask, "name", text="", emboss=False, icon_value=icon) row = layout.row(align=True)
row = layout.row(align=True) row.prop(mask, "hide", text="", emboss=False)
row.prop(mask, "hide", text="", emboss=False) row.prop(mask, "hide_select", text="", emboss=False)
row.prop(mask, "hide_select", text="", emboss=False) row.prop(mask, "hide_render", 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)
class MASK_PT_mask: 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("id", ma)
layout.context_pointer_set("material_slot", slot) layout.context_pointer_set("material_slot", slot)
if self.layout_type in {'DEFAULT', 'COMPACT'}: if ma:
if ma: layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
layout.prop(ma, "name", text="", emboss=False, icon_value=icon) else:
else:
layout.label(text="", icon_value=icon)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon) layout.label(text="", icon_value=icon)

View File

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

View File

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

View File

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

View File

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

View File

@@ -24,12 +24,8 @@ class SCENE_UL_keying_set_paths(UIList):
# assert(isinstance(item, bpy.types.KeyingSetPath) # assert(isinstance(item, bpy.types.KeyingSetPath)
kspath = item kspath = item
icon = layout.enum_item_icon(kspath, "id_type", kspath.id_type) 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...
# Do not make this one editable in uiList for now... layout.label(text=kspath.data_path, translate=False, icon_value=icon)
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)
class SceneButtonsPanel: class SceneButtonsPanel:

View File

@@ -38,13 +38,9 @@ class TEXTURE_UL_texslots(UIList):
slot = item slot = item
tex = slot.texture if slot else None tex = slot.texture if slot else None
if self.layout_type in {'DEFAULT', 'COMPACT'}: if tex:
if tex: layout.prop(tex, "name", text="", emboss=False, icon_value=icon)
layout.prop(tex, "name", text="", emboss=False, icon_value=icon) else:
else:
layout.label(text="", icon_value=icon)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon) 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): def draw_item(self, _context, layout, _data, item, _icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.MovieTrackingObject) # assert(isinstance(item, bpy.types.MovieTrackingObject)
tobj = item tobj = item
if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.prop(
layout.prop( tobj, "name", text="", emboss=False,
tobj, "name", text="", emboss=False, icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA',
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',
)
class CLIP_PT_display(Panel): class CLIP_PT_display(Panel):

View File

@@ -210,18 +210,13 @@ class FILEBROWSER_UL_dir(UIList):
direntry = item direntry = item
# space = context.space_data # space = context.space_data
if self.layout_type in {'DEFAULT', 'COMPACT'}: row = layout.row(align=True)
row = layout.row(align=True) row.enabled = direntry.is_valid
row.enabled = direntry.is_valid # Non-editable entries would show grayed-out, which is bad in this specific case, so switch to mere label.
# 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"):
if direntry.is_property_readonly("name"): row.label(text=direntry.name, icon_value=icon)
row.label(text=direntry.name, icon_value=icon) else:
else: row.prop(direntry, "name", text="", emboss=False, icon_value=icon)
row.prop(direntry, "name", text="", emboss=False, icon_value=icon)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.prop(direntry, "path", text="")
class FILEBROWSER_PT_bookmarks_volumes(Panel): 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): class USERPREF_UL_asset_libraries(UIList):
def draw_item(self, _context, layout, _data, item, _icon, _active_data, _active_propname, _index): def draw_item(self, _context, layout, _data, item, _icon, _active_data, _active_propname, _index):
asset_library = item asset_library = item
layout.prop(asset_library, "name", text="", emboss=False)
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)
class USERPREF_UL_extension_repos(UIList): class USERPREF_UL_extension_repos(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
repo = item repo = item
icon = 'INTERNET' if repo.use_remote_url else 'DISK_DRIVE' 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)
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)
# Show an error icon if this repository has unusable settings. # Show an error icon if this repository has unusable settings.
if repo.enabled: if repo.enabled:

View File

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

View File

@@ -14,12 +14,7 @@ class MESH_UL_mylist(bpy.types.UIList):
# Called for each drawn item. # Called for each drawn item.
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag): 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. pass
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
# Called once to draw filtering/reordering options. # Called once to draw filtering/reordering options.
def draw_filter(self, context, layout): def draw_filter(self, context, layout):

View File

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