From 24d8a47f68505e4fd5ca7a442828689c9f957f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Mon, 15 Jan 2024 14:29:15 +0100 Subject: [PATCH 1/4] New UI template function for showing node inputs in panel order. --- scripts/startup/bl_ui/space_node.py | 45 +++--- .../blender/editors/include/UI_interface_c.hh | 4 + .../blender/editors/interface/CMakeLists.txt | 1 + .../interface_template_node_inputs.cc | 128 ++++++++++++++++++ .../blender/makesrna/intern/rna_nodetree.cc | 46 ++++++- source/blender/makesrna/intern/rna_ui_api.cc | 6 + 6 files changed, 206 insertions(+), 24 deletions(-) create mode 100644 source/blender/editors/interface/interface_template_node_inputs.cc diff --git a/scripts/startup/bl_ui/space_node.py b/scripts/startup/bl_ui/space_node.py index 8212c2b82e3..499d030943d 100644 --- a/scripts/startup/bl_ui/space_node.py +++ b/scripts/startup/bl_ui/space_node.py @@ -705,31 +705,32 @@ class NODE_PT_active_node_properties(Panel): def draw(self, context): layout = self.layout node = context.active_node - # set "node" context pointer for the panel layout - layout.context_pointer_set("node", node) + layout.template_node_inputs(node) + # # set "node" context pointer for the panel layout + # layout.context_pointer_set("node", node) - if hasattr(node, "draw_buttons_ext"): - node.draw_buttons_ext(context, layout) - elif hasattr(node, "draw_buttons"): - node.draw_buttons(context, layout) + # if hasattr(node, "draw_buttons_ext"): + # node.draw_buttons_ext(context, layout, draw_panel_buttons=True) + # elif hasattr(node, "draw_buttons"): + # node.draw_buttons(context, layout, draw_panel_buttons=True) - # XXX this could be filtered further to exclude socket types - # which don't have meaningful input values (e.g. cycles shader) - value_inputs = [socket for socket in node.inputs if self.show_socket_input(socket)] - if value_inputs: - layout.separator() - layout.label(text="Inputs:") - for socket in value_inputs: - row = layout.row() - socket.draw( - context, - row, - node, - iface_(socket.label if socket.label else socket.name, socket.bl_rna.translation_context), - ) + # # XXX this could be filtered further to exclude socket types + # # which don't have meaningful input values (e.g. cycles shader) + # value_inputs = [socket for socket in node.inputs if self.show_socket_input(socket)] + # if value_inputs: + # layout.separator() + # layout.label(text="Inputs:") + # for socket in value_inputs: + # row = layout.row() + # socket.draw( + # context, + # row, + # node, + # iface_(socket.label if socket.label else socket.name, socket.bl_rna.translation_context), + # ) - def show_socket_input(self, socket): - return hasattr(socket, "draw") and socket.enabled and not socket.is_linked + # def show_socket_input(self, socket): + # return hasattr(socket, "draw") and socket.enabled and not socket.is_linked class NODE_PT_texture_mapping(Panel): diff --git a/source/blender/editors/include/UI_interface_c.hh b/source/blender/editors/include/UI_interface_c.hh index 81109a676fc..e2027c3058d 100644 --- a/source/blender/editors/include/UI_interface_c.hh +++ b/source/blender/editors/include/UI_interface_c.hh @@ -2712,6 +2712,10 @@ void uiTemplateGreasePencilLayerTree(uiLayout *layout, bContext *C); #endif void uiTemplateNodeTreeInterface(uiLayout *layout, PointerRNA *ptr); +/** + * Draw all node buttons and socket default values with the same panel structure used by the node. + */ +void uiTemplateNodeInputs(uiLayout *layout, bContext *C, PointerRNA *ptr); /** * \return: A RNA pointer for the operator properties. diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt index 5a1f98f5aa4..d31d67ee8c2 100644 --- a/source/blender/editors/interface/CMakeLists.txt +++ b/source/blender/editors/interface/CMakeLists.txt @@ -70,6 +70,7 @@ set(SRC interface_template_bone_collection_tree.cc interface_template_light_linking.cc interface_template_list.cc + interface_template_node_inputs.cc interface_template_node_tree_interface.cc interface_template_search_menu.cc interface_template_search_operator.cc diff --git a/source/blender/editors/interface/interface_template_node_inputs.cc b/source/blender/editors/interface/interface_template_node_inputs.cc new file mode 100644 index 00000000000..3e7f1c66c13 --- /dev/null +++ b/source/blender/editors/interface/interface_template_node_inputs.cc @@ -0,0 +1,128 @@ +/* SPDX-FileCopyrightText: 2023 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup edinterface + */ + +#include "BLI_vector.hh" + +#include "BKE_context.hh" +#include "BKE_node.hh" +#include "BKE_node_runtime.hh" + +#include "BLT_translation.h" + +#include "NOD_node_declaration.hh" + +#include "RNA_access.hh" +#include "RNA_prototypes.h" + +#include "UI_interface.hh" +#include "UI_resources.hh" + +/* -------------------------------------------------------------------- */ +/** \name Node Input Buttons Template + * \{ */ + +using blender::nodes::ItemDeclaration; +using blender::nodes::NodeDeclaration; +using blender::nodes::PanelDeclaration; +using blender::nodes::SocketDeclaration; + +using ItemIterator = blender::Vector::const_iterator; + +namespace blender::ui::nodes { + +static void draw_node_input(bContext *C, + uiLayout *layout, + PointerRNA *node_ptr, + bNodeSocket &socket) +{ + BLI_assert(socket.typeinfo != nullptr); + /* Ignore disabled sockets and linked sockets and sockets without a `draw` callback. */ + if (!socket.is_available() || (socket.flag & SOCK_IS_LINKED) || socket.typeinfo->draw == nullptr) + { + return; + } + + PointerRNA socket_ptr = RNA_pointer_create(node_ptr->owner_id, &RNA_NodeSocket, &socket); + const char *text = IFACE_(bke::nodeSocketLabel(&socket)); + socket.typeinfo->draw(C, layout, &socket_ptr, node_ptr, text); +} + +static void draw_node_input(bContext *C, + uiLayout *layout, + PointerRNA *node_ptr, + StringRefNull identifier) +{ + bNode &node = *static_cast(node_ptr->data); + bNodeSocket *socket = node.runtime->inputs_by_identifier.lookup(identifier); + draw_node_input(C, layout, node_ptr, *socket); +} + +static void draw_node_declaration_items(bContext *C, + uiLayout *layout, + PointerRNA *node_ptr, + ItemIterator &item_iter, + const ItemIterator item_end) +{ + while (item_iter != item_end) { + const ItemDeclaration *item_decl = item_iter->get(); + ++item_iter; + + if (const SocketDeclaration *socket_decl = dynamic_cast(item_decl)) + { + if (socket_decl->in_out == SOCK_IN) { + draw_node_input(C, layout, node_ptr, socket_decl->identifier); + } + } + else if (const PanelDeclaration *panel_decl = dynamic_cast( + item_decl)) + { + /* Draw panel buttons at the top of each panel section. */ + if (panel_decl->draw_buttons) { + panel_decl->draw_buttons(layout, C, node_ptr); + } + + const ItemIterator panel_item_end = item_iter + panel_decl->num_child_decls; + BLI_assert(panel_item_end <= item_end); + draw_node_declaration_items(C, layout, node_ptr, item_iter, panel_item_end); + } + } +} + +} // namespace blender::ui::nodes + +void uiTemplateNodeInputs(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + bNodeTree &tree = *reinterpret_cast(ptr->owner_id); + bNode &node = *static_cast(ptr->data); + + tree.ensure_topology_cache(); + + BLI_assert(node.typeinfo != nullptr); + /* Draw top-level node buttons. */ + if (node.typeinfo->draw_buttons_ex) { + node.typeinfo->draw_buttons_ex(layout, C, ptr); + } + else if (node.typeinfo->draw_buttons) { + node.typeinfo->draw_buttons(layout, C, ptr); + } + + if (node.declaration()) { + /* Draw socket inputs and panel buttons in the order of declaration panels. */ + ItemIterator item_iter = node.declaration()->items.begin(); + const ItemIterator item_end = node.declaration()->items.end(); + blender::ui::nodes::draw_node_declaration_items(C, layout, ptr, item_iter, item_end); + } + else { + /* Draw socket values using the flat inputs list. */ + for (bNodeSocket *input : node.runtime->inputs) { + blender::ui::nodes::draw_node_input(C, layout, ptr, *input); + } + } +} + +/** \} */ diff --git a/source/blender/makesrna/intern/rna_nodetree.cc b/source/blender/makesrna/intern/rna_nodetree.cc index 58ab0462d28..2499938006d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.cc +++ b/source/blender/makesrna/intern/rna_nodetree.cc @@ -602,8 +602,10 @@ static const EnumPropertyItem node_cryptomatte_layer_name_items[] = { # include "NOD_common.h" # include "NOD_composite.hh" # include "NOD_geometry.hh" +# include "NOD_node_declaration.hh" # include "NOD_shader.h" # include "NOD_socket.hh" +# include "NOD_socket_declarations.hh" # include "NOD_socket_items.hh" # include "NOD_texture.h" # include "NOD_zone_socket_items.hh" @@ -2515,15 +2517,43 @@ static void rna_NodeInternal_update(ID *id, bNode *node, Main *bmain) ED_node_tree_propagate_change(nullptr, bmain, ntree); } -static void rna_NodeInternal_draw_buttons(ID *id, bNode *node, bContext *C, uiLayout *layout) +static void rna_NodeInternal_draw_panel_buttons(ID *id, bNode *node, bContext *C, uiLayout *layout) +{ + using blender::nodes::ItemDeclarationPtr; + using blender::nodes::NodeDeclaration; + using blender::nodes::PanelDeclaration; + + if (!node->declaration()) { + return; + } + + PointerRNA ptr = RNA_pointer_create(id, &RNA_Node, node); + for (const ItemDeclarationPtr &item_decl : node->declaration()->items) { + if (const PanelDeclaration *panel_decl = dynamic_cast( + item_decl.get())) + { + if (panel_decl->draw_buttons) { + panel_decl->draw_buttons(layout, C, &ptr); + } + } + } +} + +static void rna_NodeInternal_draw_buttons( + ID *id, bNode *node, bContext *C, uiLayout *layout, bool draw_panel_buttons) { if (node->typeinfo->draw_buttons) { PointerRNA ptr = RNA_pointer_create(id, &RNA_Node, node); node->typeinfo->draw_buttons(layout, C, &ptr); } + + if (draw_panel_buttons) { + rna_NodeInternal_draw_panel_buttons(id, node, C, layout); + } } -static void rna_NodeInternal_draw_buttons_ext(ID *id, bNode *node, bContext *C, uiLayout *layout) +static void rna_NodeInternal_draw_buttons_ext( + ID *id, bNode *node, bContext *C, uiLayout *layout, bool draw_panel_buttons) { if (node->typeinfo->draw_buttons_ex) { PointerRNA ptr = RNA_pointer_create(id, &RNA_Node, node); @@ -2533,6 +2563,10 @@ static void rna_NodeInternal_draw_buttons_ext(ID *id, bNode *node, bContext *C, PointerRNA ptr = RNA_pointer_create(id, &RNA_Node, node); node->typeinfo->draw_buttons(layout, C, &ptr); } + + if (draw_panel_buttons) { + rna_NodeInternal_draw_panel_buttons(id, node, C, layout); + } } static StructRNA *rna_NodeCustomGroup_register(Main *bmain, @@ -9606,6 +9640,10 @@ static void rna_def_internal_node(BlenderRNA *brna) RNA_def_property_struct_type(parm, "UILayout"); RNA_def_property_ui_text(parm, "Layout", "Layout in the UI"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + parm = RNA_def_property(func, "draw_panel_buttons", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_default(parm, false); + RNA_def_property_ui_text( + parm, "Draw Panel Buttons", "Draw buttons from panels as well as top-level buttons"); /* draw buttons extended */ func = RNA_def_function(srna, "draw_buttons_ext", "rna_NodeInternal_draw_buttons_ext"); @@ -9617,6 +9655,10 @@ static void rna_def_internal_node(BlenderRNA *brna) RNA_def_property_struct_type(parm, "UILayout"); RNA_def_property_ui_text(parm, "Layout", "Layout in the UI"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + parm = RNA_def_property(func, "draw_panel_buttons", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_default(parm, false); + RNA_def_property_ui_text( + parm, "Draw Panel Buttons", "Draw buttons from panels as well as top-level buttons"); } static void rna_def_node_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int in_out) diff --git a/source/blender/makesrna/intern/rna_ui_api.cc b/source/blender/makesrna/intern/rna_ui_api.cc index 2f775dc3ea4..786a4820e95 100644 --- a/source/blender/makesrna/intern/rna_ui_api.cc +++ b/source/blender/makesrna/intern/rna_ui_api.cc @@ -2205,6 +2205,12 @@ void RNA_api_ui_layout(StructRNA *srna) "Node Tree Interface", "Interface of a node tree to display"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + + func = RNA_def_function(srna, "template_node_inputs", "uiTemplateNodeInputs"); + RNA_def_function_ui_description(func, "Show a node settings and input socket values"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + parm = RNA_def_pointer(func, "node", "Node", "Node", "Display inputs of this node"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); } #endif -- 2.30.2 From a701aa44dccb7b80b28a5513196c827a2899240f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Mon, 15 Jan 2024 14:31:34 +0100 Subject: [PATCH 2/4] Removed unused python code for node inputs. --- scripts/startup/bl_ui/space_node.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/scripts/startup/bl_ui/space_node.py b/scripts/startup/bl_ui/space_node.py index 499d030943d..d4ee6f2dcb9 100644 --- a/scripts/startup/bl_ui/space_node.py +++ b/scripts/startup/bl_ui/space_node.py @@ -706,31 +706,6 @@ class NODE_PT_active_node_properties(Panel): layout = self.layout node = context.active_node layout.template_node_inputs(node) - # # set "node" context pointer for the panel layout - # layout.context_pointer_set("node", node) - - # if hasattr(node, "draw_buttons_ext"): - # node.draw_buttons_ext(context, layout, draw_panel_buttons=True) - # elif hasattr(node, "draw_buttons"): - # node.draw_buttons(context, layout, draw_panel_buttons=True) - - # # XXX this could be filtered further to exclude socket types - # # which don't have meaningful input values (e.g. cycles shader) - # value_inputs = [socket for socket in node.inputs if self.show_socket_input(socket)] - # if value_inputs: - # layout.separator() - # layout.label(text="Inputs:") - # for socket in value_inputs: - # row = layout.row() - # socket.draw( - # context, - # row, - # node, - # iface_(socket.label if socket.label else socket.name, socket.bl_rna.translation_context), - # ) - - # def show_socket_input(self, socket): - # return hasattr(socket, "draw") and socket.enabled and not socket.is_linked class NODE_PT_texture_mapping(Panel): -- 2.30.2 From e7b25fd4fe892d8f72c884e933482e8b1368a68f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Mon, 15 Jan 2024 14:35:48 +0100 Subject: [PATCH 3/4] Reverted RNA changes to `draw_buttons` functions. --- .../blender/makesrna/intern/rna_nodetree.cc | 46 +------------------ 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.cc b/source/blender/makesrna/intern/rna_nodetree.cc index 2499938006d..58ab0462d28 100644 --- a/source/blender/makesrna/intern/rna_nodetree.cc +++ b/source/blender/makesrna/intern/rna_nodetree.cc @@ -602,10 +602,8 @@ static const EnumPropertyItem node_cryptomatte_layer_name_items[] = { # include "NOD_common.h" # include "NOD_composite.hh" # include "NOD_geometry.hh" -# include "NOD_node_declaration.hh" # include "NOD_shader.h" # include "NOD_socket.hh" -# include "NOD_socket_declarations.hh" # include "NOD_socket_items.hh" # include "NOD_texture.h" # include "NOD_zone_socket_items.hh" @@ -2517,43 +2515,15 @@ static void rna_NodeInternal_update(ID *id, bNode *node, Main *bmain) ED_node_tree_propagate_change(nullptr, bmain, ntree); } -static void rna_NodeInternal_draw_panel_buttons(ID *id, bNode *node, bContext *C, uiLayout *layout) -{ - using blender::nodes::ItemDeclarationPtr; - using blender::nodes::NodeDeclaration; - using blender::nodes::PanelDeclaration; - - if (!node->declaration()) { - return; - } - - PointerRNA ptr = RNA_pointer_create(id, &RNA_Node, node); - for (const ItemDeclarationPtr &item_decl : node->declaration()->items) { - if (const PanelDeclaration *panel_decl = dynamic_cast( - item_decl.get())) - { - if (panel_decl->draw_buttons) { - panel_decl->draw_buttons(layout, C, &ptr); - } - } - } -} - -static void rna_NodeInternal_draw_buttons( - ID *id, bNode *node, bContext *C, uiLayout *layout, bool draw_panel_buttons) +static void rna_NodeInternal_draw_buttons(ID *id, bNode *node, bContext *C, uiLayout *layout) { if (node->typeinfo->draw_buttons) { PointerRNA ptr = RNA_pointer_create(id, &RNA_Node, node); node->typeinfo->draw_buttons(layout, C, &ptr); } - - if (draw_panel_buttons) { - rna_NodeInternal_draw_panel_buttons(id, node, C, layout); - } } -static void rna_NodeInternal_draw_buttons_ext( - ID *id, bNode *node, bContext *C, uiLayout *layout, bool draw_panel_buttons) +static void rna_NodeInternal_draw_buttons_ext(ID *id, bNode *node, bContext *C, uiLayout *layout) { if (node->typeinfo->draw_buttons_ex) { PointerRNA ptr = RNA_pointer_create(id, &RNA_Node, node); @@ -2563,10 +2533,6 @@ static void rna_NodeInternal_draw_buttons_ext( PointerRNA ptr = RNA_pointer_create(id, &RNA_Node, node); node->typeinfo->draw_buttons(layout, C, &ptr); } - - if (draw_panel_buttons) { - rna_NodeInternal_draw_panel_buttons(id, node, C, layout); - } } static StructRNA *rna_NodeCustomGroup_register(Main *bmain, @@ -9640,10 +9606,6 @@ static void rna_def_internal_node(BlenderRNA *brna) RNA_def_property_struct_type(parm, "UILayout"); RNA_def_property_ui_text(parm, "Layout", "Layout in the UI"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); - parm = RNA_def_property(func, "draw_panel_buttons", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_default(parm, false); - RNA_def_property_ui_text( - parm, "Draw Panel Buttons", "Draw buttons from panels as well as top-level buttons"); /* draw buttons extended */ func = RNA_def_function(srna, "draw_buttons_ext", "rna_NodeInternal_draw_buttons_ext"); @@ -9655,10 +9617,6 @@ static void rna_def_internal_node(BlenderRNA *brna) RNA_def_property_struct_type(parm, "UILayout"); RNA_def_property_ui_text(parm, "Layout", "Layout in the UI"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); - parm = RNA_def_property(func, "draw_panel_buttons", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_default(parm, false); - RNA_def_property_ui_text( - parm, "Draw Panel Buttons", "Draw buttons from panels as well as top-level buttons"); } static void rna_def_node_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int in_out) -- 2.30.2 From 82a26c89c779cbd756285c1b8b258b8f54c7d70a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 16 Jan 2024 10:19:52 +0100 Subject: [PATCH 4/4] Draw panel layouts in the node editor sidebar for node input buttons. --- .../interface_template_node_inputs.cc | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/interface/interface_template_node_inputs.cc b/source/blender/editors/interface/interface_template_node_inputs.cc index 3e7f1c66c13..5b4c90f1417 100644 --- a/source/blender/editors/interface/interface_template_node_inputs.cc +++ b/source/blender/editors/interface/interface_template_node_inputs.cc @@ -11,6 +11,7 @@ #include "BKE_context.hh" #include "BKE_node.hh" #include "BKE_node_runtime.hh" +#include "BKE_screen.hh" #include "BLT_translation.h" @@ -62,11 +63,13 @@ static void draw_node_input(bContext *C, draw_node_input(C, layout, node_ptr, *socket); } -static void draw_node_declaration_items(bContext *C, - uiLayout *layout, - PointerRNA *node_ptr, - ItemIterator &item_iter, - const ItemIterator item_end) +/* Consume the item range, draw buttons if layout is not null. */ +static void handle_node_declaration_items(bContext *C, + Panel *root_panel, + uiLayout *layout, + PointerRNA *node_ptr, + ItemIterator &item_iter, + const ItemIterator item_end) { while (item_iter != item_end) { const ItemDeclaration *item_decl = item_iter->get(); @@ -74,21 +77,30 @@ static void draw_node_declaration_items(bContext *C, if (const SocketDeclaration *socket_decl = dynamic_cast(item_decl)) { - if (socket_decl->in_out == SOCK_IN) { + if (layout && socket_decl->in_out == SOCK_IN) { draw_node_input(C, layout, node_ptr, socket_decl->identifier); } } else if (const PanelDeclaration *panel_decl = dynamic_cast( item_decl)) { - /* Draw panel buttons at the top of each panel section. */ - if (panel_decl->draw_buttons) { - panel_decl->draw_buttons(layout, C, node_ptr); - } - const ItemIterator panel_item_end = item_iter + panel_decl->num_child_decls; BLI_assert(panel_item_end <= item_end); - draw_node_declaration_items(C, layout, node_ptr, item_iter, panel_item_end); + + /* Use a root panel property to toggle open/closed state. */ + const std::string panel_idname = "NodePanel" + std::to_string(panel_decl->identifier); + LayoutPanelState *state = BKE_panel_layout_panel_state_ensure( + root_panel, panel_idname.c_str(), panel_decl->default_collapsed); + PointerRNA state_ptr = RNA_pointer_create(nullptr, &RNA_LayoutPanelState, state); + uiLayout *panel_layout = uiLayoutPanel( + C, layout, IFACE_(panel_decl->name.c_str()), &state_ptr, "is_open"); + /* Draw panel buttons at the top of each panel section. */ + if (panel_layout && panel_decl->draw_buttons) { + panel_decl->draw_buttons(panel_layout, C, node_ptr); + } + + handle_node_declaration_items( + C, root_panel, panel_layout, node_ptr, item_iter, panel_item_end); } } } @@ -115,7 +127,9 @@ void uiTemplateNodeInputs(uiLayout *layout, bContext *C, PointerRNA *ptr) /* Draw socket inputs and panel buttons in the order of declaration panels. */ ItemIterator item_iter = node.declaration()->items.begin(); const ItemIterator item_end = node.declaration()->items.end(); - blender::ui::nodes::draw_node_declaration_items(C, layout, ptr, item_iter, item_end); + Panel *root_panel = uiLayoutGetRootPanel(layout); + blender::ui::nodes::handle_node_declaration_items( + C, root_panel, layout, ptr, item_iter, item_end); } else { /* Draw socket values using the flat inputs list. */ -- 2.30.2