I asked a similar question quite a while ago but I'm still having trouble with this. For those that didn't see my last question, basically I want to replicate what the background image system does, or at least the panel. I want to have an add button and an X button, and when the add button is pressed by the user, a section is added to the panel and that can be done as many times as the user is willing to click it. Then added to each one of those sections is the X button, and when that X button is clicked, it removes that section, just like the background images. I have this code so far, I've only added the parts of that should concern:
class IgnitProperties(bpy.types.PropertyGroup):
collapse = BoolProperty(
name = "Collapse",
description = "Allows the MacBook Controller to be collapsable",
default = True,
update = lambda self, context: common_update(self, context, 'collapse')
)
class AddMacBook(bpy.types.Operator):
bl_label = "Add MacBook"
bl_idname = "macbook_controller.add_macbook"
def execute(self, context):
item = context.scene.ignit_panel.add()
def unique_name(names):
# from wm.py
prop = "MacBook"
prop_new = prop
i = 1
while prop_new in names:
prop_new = prop + str(i)
i += 1
return prop_new
item.title = unique_name([i.title for i in context.scene.ignit_panel])
return{'FINISHED'}
class RemoveMacBook(bpy.types.Operator):
bl_label = "Remove MacBook"
bl_idname = "macbook_controler.remove_macbook"
del_item = bpy.props.IntProperty(name='item index to remove')
def execute(self, context):
context.scene.ignit_panel.remove(self.del_item)
return{'FINISHED'}
class IGLayoutDemoPanel(bpy.types.Panel):
"""Creates a Panel in the scene context of the properties editor"""
bl_label = "MacBook Controller"
bl_idname = "macbook_controller.macbook_controller"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
def draw(self, context):
layout = self.layout
scene = context.scene
split = layout.split()
scene = context.scene
camera = scene.camera.data
obj = context.object
# Add
row = layout.row(align=True)
layout.operator("macbook_controller.add_macbook")
for idx,ignit_options in enumerate(scene.ignit_panel):
# Box
box = layout.box()
row = box.row()
# Collapsable Menu
collapse = scene.ignit_panel.collapse
if collapse == True:
row.prop(scene.ignit_panel, "collapse",
icon="TRIA_DOWN",
icon_only=True, emboss=False
)
else:
row.prop(scene.ignit_panel, "collapse",
icon="TRIA_RIGHT",
icon_only=True, emboss=False
)
# Title (per object)
row.label(text = "MacBook")
row.operator("macbook_controler.remove_macbook", text="", icon = "X", emboss = False).del_item = idx
# Collapsing everything inside the box
if not ignit_options.collapse:
#This is the section that I want to be drawn every time the add button is clicked
def register():
bpy.utils.register_module(__name__)
bpy.types.Scene.ignit_panel = bpy.props.PointerProperty(type=IgnitProperties)
def unregister():
bpy.utils.unregister__module(__name__)
del bpy.types.Scene.ignit_panel
if __name__ == "__main__":
register()
No errors in the console at first, but as soon as I try to click one of those buttons, it tells me this:
Traceback (most recent call last):
File "/Users....../macbook_controller.py", line 1202 in execute
AttributeError: 'IgnitProperties' object has no attribute 'add'
bpy.types.Scene.ignit_panel = bpy.props.CollectionProperty()
so you can calladd()
( it has to be collection prop not a pointer ) $\endgroup$collapse = ignit_options.collapse
should be thiscollapse = ignit_options.collapse
and change it to thisrow.prop(ignit_options, .......)
or thisrow.prop(ignit_options.collapse, .......)
I can't test on my current system now sorry $\endgroup$