Refactor: Geometry Nodes: extract function to draw panel content in modifier

Besides extracting a function, this also cleans up the construction of the rna_path.
This commit is contained in:
Jacques Lucke
2025-09-30 06:56:55 +02:00
parent 083cc599f9
commit d21f9fa07d

View File

@@ -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<StringRef> 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<bNodeTreeInterfacePanel *>(panel_arg);
return StringRef(panel->description);
},
const_cast<bNodeTreeInterfacePanel *>(&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<StringRef> parent_name = std::nullopt)
const bool skip_first,
const std::optional<StringRef> 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<const bNodeTreeInterfacePanel *>(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<bNodeTreeInterfacePanel *>(panel_arg);
return StringRef(panel->description);
},
const_cast<bNodeTreeInterfacePanel *>(&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: {