I created a panel called "Platforms", which displays some information. In that panel, I have an "Add" operator, which creates expandable rows (which can all be individually deleted by pressing a "Delete" button). To do so, I wrote the following code
import bpy
def update_platform_side(self, context):
if self.platform_side == "blue":
context.scene.platform_panel_props.nblue += 1
elif self.platform_side == "red":
context.scene.platform_panel_props.nred += 1
else:
pass
class PLATFORM_PlatformPanelProps(bpy.types.PropertyGroup):
ntot: bpy.props.IntProperty(
name = "Total",
description = "Total number of platforms",
min = 0,
default = 0,
)
nred: bpy.props.IntProperty(
name = "Red",
description = "Number of red platforms",
min = 0,
default = 0,
)
nblue: bpy.props.IntProperty(
name = "Blue",
description = "Number of blue platforms",
min = 0,
default = 0,
)
side: bpy.props.EnumProperty(
name = "Side",
description = "Choose the platform side (either 'blue' or 'red')",
update = update_platform_side,
items = [
("platform_blue", "Blue", "Set the platform to 'blue' side"),
("platform_red", "Red", "Set the platform to 'red' side")
],
default = "platform_blue",
)
is_expanded: bpy.props.BoolProperty(
name = "Platform expand",
description = "Expands a platform panel to show all its attributes",
default = False,
)
class PLATFORM_PT_Platform(bpy.types.Panel):
bl_idname = 'PLATFORM_PT_Platform'
bl_label = 'Platforms'
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'platform'
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
icon = 'TRIA_RIGHT' if not context.scene.is_expanded else 'TRIA_DOWN'
box = layout.box()
row = box.row(align = True)
row.label(text = f"Red {context.scene.platform_panel_props.nred}")
row.label(text = f"Blue {context.scene.platform_panel_props.nblue}")
row.label(text = f"Total {context.scene.platform_panel_props.ntot}")
box.operator('platform.add_platform', text = "Add")
for i in range(context.scene.platform_panel_props.ntot):
row = layout.row()
row.prop(context.scene, 'is_expanded', icon=icon, icon_only=True)
row.label(text = f'Platform {i + 1}')
row.alert = True
row.operator('platform.delete_platform', text = "Delete")
if context.scene.is_expanded:
box = layout.box()
row = box.row(align = True)
row.label(text = "Side")
class PLATFORM_OT_AddPlatform(bpy.types.Operator):
""" Create a new platform with its sensor(s) and/or effector(s) """
bl_idname = "platform.add_platform"
bl_label = "Create new platform"
def execute(self, context):
context.scene.platform_panel_props.ntot += 1
return {'FINISHED'}
class PLATFORM_OT_DeletePlatform(bpy.types.Operator):
""" Delete a platform with its sensor(s) and/or effector(s) """
bl_idname = "platform.delete_platform"
bl_label = "Delete platform"
def execute(self, context):
context.scene.platform_panel_props.ntot -= 1
return {'FINISHED'}
classes = (
PLATFORM_PlatformPanelProps,
PLATFORM_PT_Platform,
PLATFORM_OT_AddPlatform,
PLATFORM_OT_DeletePlatform,
)
if __name__ == '__main__':
for my_class in classes:
bpy.utils.register_class(my_class)
bpy.types.Scene.is_expanded = bpy.props.BoolProperty(default = False)
bpy.types.Scene.platform_panel_props = bpy.props.PointerProperty(
type = PLATFORM_PlatformPanelProps,
)
The provided code runs, but not as intended: When I add several expandable rows, I cannot expand a particular one (i.e. they all expand simultaneously). How can I solve that issue? I also do not get why I have to declare bpy.types.Scene.is_expanded
in the main to be able to expand the rows, instead of just calling platform_panel_props.is_expanded
where is_expanded
or context.scene.is_expanded
is used?