Light linking: Make list interface look more similar to other places

This change makes it so the list interface in the properties panels looks
closer to things like shape keys, vertex groups and so on: there are two
buttons to add selected objects to the collection and remove active item
from the collection, as well as the "extra" drop down menu.

The add operator adds selected objects to the light linking collection
using the Include policy. For the light linking it means that the objects
are added as receivers that receive the light, and for the shadow linking
it means that objects are added as blockers which cast shadow from the
light.

The communication of the active list element is done via context property
similar to how it was done before. The difference is that these properties
are set on a parent of the list layout, which makes it so they are inherited
by the layout hierarchy needed to place the Remove button.

Pull Request: https://projects.blender.org/blender/blender/pulls/112713
This commit is contained in:
Sergey Sharybin
2023-09-22 17:44:25 +02:00
committed by Sergey Sharybin
parent 427bdc8dcf
commit 015bc7ca4d
4 changed files with 49 additions and 22 deletions
+10 -2
View File
@@ -1367,10 +1367,14 @@ class CYCLES_OBJECT_PT_light_linking(CyclesButtonsPanel, Panel):
row = layout.row()
col = row.column()
col.template_light_linking_collection(light_linking, "receiver_collection")
col.template_light_linking_collection(row, light_linking, "receiver_collection")
col = row.column()
sub = col.column(align=True)
prop = sub.operator("object.light_linking_receivers_link", icon='ADD', text="")
prop.link_state = 'INCLUDE'
sub.operator("object.light_linking_unlink_from_collection", icon='REMOVE', text="")
sub = col.column()
sub.menu("CYCLES_OBJECT_MT_light_linking_context_menu", icon='DOWNARROW_HLT', text="")
@@ -1399,10 +1403,14 @@ class CYCLES_OBJECT_PT_shadow_linking(CyclesButtonsPanel, Panel):
row = layout.row()
col = row.column()
col.template_light_linking_collection(light_linking, "blocker_collection")
col.template_light_linking_collection(row, light_linking, "blocker_collection")
col = row.column()
sub = col.column(align=True)
prop = sub.operator("object.light_linking_blockers_link", icon='ADD', text="")
prop.link_state = 'INCLUDE'
sub.operator("object.light_linking_unlink_from_collection", icon='REMOVE', text="")
sub = col.column()
sub.menu("CYCLES_OBJECT_MT_shadow_linking_context_menu", icon='DOWNARROW_HLT', text="")
@@ -2638,7 +2638,10 @@ void uiTemplateAssetView(uiLayout *layout,
const char *drag_opname,
PointerRNA *r_drag_op_properties);
void uiTemplateLightLinkingCollection(uiLayout *layout, PointerRNA *ptr, const char *propname);
void uiTemplateLightLinkingCollection(uiLayout *layout,
uiLayout *context_layout,
PointerRNA *ptr,
const char *propname);
void uiTemplateGreasePencilLayerTree(uiLayout *layout, bContext *C);
@@ -89,17 +89,20 @@ class CollectionDropTarget : public DropTargetInterface {
};
class CollectionViewItem : public BasicTreeViewItem {
uiLayout &context_layout_;
Collection &collection_;
ID *id_ = nullptr;
CollectionLightLinking &collection_light_linking_;
public:
CollectionViewItem(Collection &collection,
CollectionViewItem(uiLayout &context_layout,
Collection &collection,
ID &id,
CollectionLightLinking &collection_light_linking,
const BIFIconID icon)
: BasicTreeViewItem(id.name + 2, icon),
context_layout_(context_layout),
collection_(collection),
id_(&id),
collection_light_linking_(collection_light_linking)
@@ -108,13 +111,20 @@ class CollectionViewItem : public BasicTreeViewItem {
void build_row(uiLayout &row) override
{
if (is_active()) {
PointerRNA id_ptr = RNA_id_pointer_create(id_);
PointerRNA collection_ptr = RNA_id_pointer_create(&collection_.id);
uiLayoutSetContextPointer(&context_layout_, "id", &id_ptr);
uiLayoutSetContextPointer(&context_layout_, "collection", &collection_ptr);
}
add_label(row);
uiLayout *sub = uiLayoutRow(&row, true);
uiLayoutSetPropDecorate(sub, false);
build_state_button(*sub);
build_remove_button(*sub);
}
private:
@@ -174,30 +184,24 @@ class CollectionViewItem : public BasicTreeViewItem {
link_state_toggle(collection_light_linking);
});
}
void build_remove_button(uiLayout &row)
{
PointerRNA id_ptr = RNA_id_pointer_create(id_);
PointerRNA collection_ptr = RNA_id_pointer_create(&collection_.id);
uiLayoutSetContextPointer(&row, "id", &id_ptr);
uiLayoutSetContextPointer(&row, "collection", &collection_ptr);
uiItemO(&row, "", ICON_X, "OBJECT_OT_light_linking_unlink_from_collection");
}
};
class CollectionView : public AbstractTreeView {
uiLayout &context_layout_;
Collection &collection_;
public:
explicit CollectionView(Collection &collection) : collection_(collection) {}
CollectionView(uiLayout &context_layout, Collection &collection)
: context_layout_(context_layout), collection_(collection)
{
}
void build_tree() override
{
LISTBASE_FOREACH (CollectionChild *, collection_child, &collection_.children) {
Collection *child_collection = collection_child->collection;
add_tree_item<CollectionViewItem>(collection_,
add_tree_item<CollectionViewItem>(context_layout_,
collection_,
child_collection->id,
collection_child->light_linking,
ICON_OUTLINER_COLLECTION);
@@ -205,8 +209,11 @@ class CollectionView : public AbstractTreeView {
LISTBASE_FOREACH (CollectionObject *, collection_object, &collection_.gobject) {
Object *child_object = collection_object->ob;
add_tree_item<CollectionViewItem>(
collection_, child_object->id, collection_object->light_linking, ICON_OBJECT_DATA);
add_tree_item<CollectionViewItem>(context_layout_,
collection_,
child_object->id,
collection_object->light_linking,
ICON_OBJECT_DATA);
}
}
@@ -220,7 +227,10 @@ class CollectionView : public AbstractTreeView {
} // namespace blender::ui::light_linking
void uiTemplateLightLinkingCollection(uiLayout *layout, PointerRNA *ptr, const char *propname)
void uiTemplateLightLinkingCollection(uiLayout *layout,
uiLayout *context_layout,
PointerRNA *ptr,
const char *propname)
{
if (!ptr->data) {
return;
@@ -260,7 +270,7 @@ void uiTemplateLightLinkingCollection(uiLayout *layout, PointerRNA *ptr, const c
blender::ui::AbstractTreeView *tree_view = UI_block_add_view(
*block,
"Light Linking Collection Tree View",
std::make_unique<blender::ui::light_linking::CollectionView>(*collection));
std::make_unique<blender::ui::light_linking::CollectionView>(*context_layout, *collection));
tree_view->set_min_rows(3);
blender::ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
@@ -2096,6 +2096,12 @@ void RNA_api_ui_layout(StructRNA *srna)
srna, "template_light_linking_collection", "uiTemplateLightLinkingCollection");
RNA_def_function_ui_description(func,
"Visualization of a content of a light linking collection");
parm = RNA_def_pointer(func,
"context_layout",
"UILayout",
"",
"Layout to set active list element as context properties");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
api_ui_item_rna_common(func);
func = RNA_def_function(