利用者:Mont29/Dev/UI Template List Enhancement

提供: wiki
移動先: 案内検索

UI Template List Enhancement

Exclamation mark.png

This page is about an old “customization” system, which has now been replaced by a fully pythonic system to define your own lists, pretty much like you define your own menus or panels. Please refer to current ui py code ([code]release/scripts/startup/bl_ui/properties_data_mesh.py[/code] & co) for examples…

What?

A generic list display of a collection, with custom item controls.

This patch adds an opportunity for generic items in a collection displayed by that template to display custom controls (e.g. check boxes, numfield, etc.). See the picture to the right (note that you could even, if you like, have different controls for each row/item).

Why?

Well, because right now, except for a limited, hard-coded set of collections (e.g. vertex groups, textures/materials slots…), the template list only displays the name of each item in a generic collection, which isn’t so useful… That is especially frustrating when using python-defined collections!

How?

Right now, I implemented that by searching, for each item, in the default case, a given string property (which name is given to the template function). That string is then split on ':', and the resulting strings should correspond to the names of some properties in the template-listed item, that are to be displayed in that row of the list.

To test it, you first need to build your own blender patched with the patch linked below.

Then, copy/paste the following code in a Blender text block, and execute it as a Python script:

import bpy
from bpy.props import StringProperty, BoolProperty, IntProperty, CollectionProperty

class TestPropertyGroup(bpy.types.PropertyGroup):
    bool    = BoolProperty(default=False)
    integer = IntProperty()
    string  = StringProperty()
    # A list of identifiers (colon-separated strings) which property’s controls should be displayed
    # in a template_list.
    # Note that the order is respected.
    template_list_controls = StringProperty(default="integer:string:bool", options={"HIDDEN"})

bpy.utils.register_class(TestPropertyGroup)

bpy.types.Scene.my_settings = CollectionProperty(type=TestPropertyGroup)
# Unused, but this is needed for the TemplateList to work…
bpy.types.Scene.my_settings_idx = IntProperty()

# Add ten default items…
my_sett = bpy.context.scene.my_settings
for i in range(10):
    my_item = my_sett.add()
    my_item.name = "item {}".format(i)
    # Hide one property for odd items.
    if i % 2:
        my_item.template_list_controls = "string:bool"

# Now, create a panel to show all this!
class OBJECT_PT_TemplateListTest(bpy.types.Panel):
    bl_label = "Template List Test Panel"
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "render"
    def draw(self, context):
        layout = self.layout
        layout.template_list(context.scene, "my_settings", context.scene, "my_settings_idx",
                             prop_list="template_list_controls", rows=5)

bpy.utils.register_class(OBJECT_PT_TemplateListTest)

This should give you a Template List Test Panel in the Buttons window, Render context, with a list which items have a label, a numeric field (for even items only), a text field and a check box. Note how the order of the identifiers in the template_list_controls string determines the order of the UI elements…

You can also enable the Render: Copy Setting addon, as I coded this patch for this purpose!

Links

Change Log

0.0.1

Initial release.

0.0.2

As asked by Campbell, made the name of the “control property” customizable – you now just have to pass it as an optional parameter of template_list() bpy func. Leave it empty if you want the default behavior !

0.0.3

Now list of properties to display is a simple, colon-separated string, much much easier to handle!