diff --git a/source/blender/nodes/intern/geometry_nodes_caller_ui.cc b/source/blender/nodes/intern/geometry_nodes_caller_ui.cc index 1ff3ecd5e26..85059430474 100644 --- a/source/blender/nodes/intern/geometry_nodes_caller_ui.cc +++ b/source/blender/nodes/intern/geometry_nodes_caller_ui.cc @@ -644,70 +644,78 @@ static bool interface_panel_affects_output(DrawGroupInputsContext &ctx, return false; } +static void draw_interface_panel_content( + DrawGroupInputsContext &ctx, + uiLayout *layout, + const bNodeTreeInterfacePanel &interface_panel, + const bool skip_first = false, + const std::optional parent_name = std::nullopt); + +static void draw_interface_panel_as_panel(DrawGroupInputsContext &ctx, + uiLayout &layout, + const bNodeTreeInterfacePanel &interface_panel) +{ + if (!interface_panel_has_socket(ctx, interface_panel)) { + return; + } + PanelOpenProperty open_property = ctx.panel_open_property_fn(interface_panel); + PanelLayout panel_layout; + bool skip_first = false; + /* Check if the panel should have a toggle in the header. */ + const bNodeTreeInterfaceSocket *toggle_socket = interface_panel.header_toggle_socket(); + const StringRef panel_name = interface_panel.name; + if (toggle_socket && !(toggle_socket->flag & NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER)) { + const StringRefNull identifier = toggle_socket->identifier; + IDProperty *property = IDP_GetPropertyFromGroup_null(ctx.properties, identifier); + /* IDProperties can be removed with python, so there could be a situation where + * there isn't a property for a socket or it doesn't have the correct type. */ + if (property == nullptr || + !nodes::id_property_type_matches_socket(*toggle_socket, *property, ctx.use_name_for_ids)) + { + return; + } + const std::string rna_path = fmt::format("[\"{}\"]", BLI_str_escape(identifier.c_str())); + panel_layout = layout.panel_prop_with_bool_header(&ctx.C, + &open_property.ptr, + open_property.name, + ctx.properties_ptr, + rna_path, + IFACE_(panel_name)); + skip_first = true; + } + else { + panel_layout = layout.panel_prop(&ctx.C, &open_property.ptr, open_property.name); + panel_layout.header->label(IFACE_(panel_name), ICON_NONE); + } + if (!interface_panel_affects_output(ctx, interface_panel)) { + panel_layout.header->active_set(false); + } + uiLayoutSetTooltipFunc( + panel_layout.header, + [](bContext * /*C*/, void *panel_arg, const StringRef /*tip*/) -> std::string { + const auto *panel = static_cast(panel_arg); + return StringRef(panel->description); + }, + const_cast(&interface_panel), + nullptr, + nullptr); + if (panel_layout.body) { + draw_interface_panel_content(ctx, panel_layout.body, interface_panel, skip_first, panel_name); + } +} + static void draw_interface_panel_content(DrawGroupInputsContext &ctx, uiLayout *layout, const bNodeTreeInterfacePanel &interface_panel, - const bool skip_first = false, - const std::optional parent_name = std::nullopt) + const bool skip_first, + const std::optional parent_name) { for (const bNodeTreeInterfaceItem *item : interface_panel.items().drop_front(skip_first ? 1 : 0)) { switch (NodeTreeInterfaceItemType(item->item_type)) { case NODE_INTERFACE_PANEL: { const auto &sub_interface_panel = *reinterpret_cast(item); - if (!interface_panel_has_socket(ctx, sub_interface_panel)) { - continue; - } - PanelOpenProperty open_property = ctx.panel_open_property_fn(sub_interface_panel); - PanelLayout panel_layout; - bool skip_first = false; - /* Check if the panel should have a toggle in the header. */ - const bNodeTreeInterfaceSocket *toggle_socket = sub_interface_panel.header_toggle_socket(); - const StringRef panel_name = sub_interface_panel.name; - if (toggle_socket && !(toggle_socket->flag & NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER)) { - const StringRefNull identifier = toggle_socket->identifier; - IDProperty *property = IDP_GetPropertyFromGroup_null(ctx.properties, identifier); - /* IDProperties can be removed with python, so there could be a situation where - * there isn't a property for a socket or it doesn't have the correct type. */ - if (property == nullptr || !nodes::id_property_type_matches_socket( - *toggle_socket, *property, ctx.use_name_for_ids)) - { - continue; - } - char socket_id_esc[MAX_NAME * 2]; - BLI_str_escape(socket_id_esc, identifier.c_str(), sizeof(socket_id_esc)); - - char rna_path[sizeof(socket_id_esc) + 4]; - SNPRINTF_UTF8(rna_path, "[\"%s\"]", socket_id_esc); - - panel_layout = layout->panel_prop_with_bool_header(&ctx.C, - &open_property.ptr, - open_property.name, - ctx.properties_ptr, - rna_path, - IFACE_(panel_name)); - skip_first = true; - } - else { - panel_layout = layout->panel_prop(&ctx.C, &open_property.ptr, open_property.name); - panel_layout.header->label(IFACE_(panel_name), ICON_NONE); - } - if (!interface_panel_affects_output(ctx, sub_interface_panel)) { - panel_layout.header->active_set(false); - } - uiLayoutSetTooltipFunc( - panel_layout.header, - [](bContext * /*C*/, void *panel_arg, const StringRef /*tip*/) -> std::string { - const auto *panel = static_cast(panel_arg); - return StringRef(panel->description); - }, - const_cast(&sub_interface_panel), - nullptr, - nullptr); - if (panel_layout.body) { - draw_interface_panel_content( - ctx, panel_layout.body, sub_interface_panel, skip_first, panel_name); - } + draw_interface_panel_as_panel(ctx, *layout, sub_interface_panel); break; } case NODE_INTERFACE_SOCKET: {