From a23bd3d7f35eaf71eb05c01dd14d4ddf1e5ca429 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 5 Dec 2023 15:57:40 +0100 Subject: [PATCH] Nodes: add node callback for extra info that is drawn above node This allows nodes to show some extra information next to the node. This can be useful for debugging and will likely also be used for the new Bake node (#115466). Pull Request: https://projects.blender.org/blender/blender/pulls/115805 --- source/blender/blenkernel/BKE_node.h | 6 ++++ .../blender/editors/space_node/node_draw.cc | 36 +++++++++---------- source/blender/nodes/NOD_node_extra_info.hh | 27 ++++++++++++++ 3 files changed, 51 insertions(+), 18 deletions(-) create mode 100644 source/blender/nodes/NOD_node_extra_info.hh diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 20f379556a1..e76db42ebc6 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -100,6 +100,7 @@ class NodeDeclaration; class NodeDeclarationBuilder; class GatherAddNodeSearchParams; class GatherLinkSearchOpParams; +class NodeExtraInfoParams; } // namespace nodes namespace realtime_compositor { class Context; @@ -130,6 +131,7 @@ using NodeGetCompositorOperationFunction = blender::realtime_compositor::NodeOpe *(*)(blender::realtime_compositor::Context &context, blender::nodes::DNode node); using NodeGetCompositorShaderNodeFunction = blender::realtime_compositor::ShaderNode *(*)(blender::nodes::DNode node); +using NodeExtraInfoFunction = void (*)(blender::nodes::NodeExtraInfoParams ¶ms); #else typedef void *NodeGetCompositorOperationFunction; @@ -144,6 +146,7 @@ typedef void *SocketGetCPPTypeFunction; typedef void *SocketGetGeometryNodesCPPTypeFunction; typedef void *SocketGetGeometryNodesCPPValueFunction; typedef void *SocketGetCPPValueFunction; +typedef void *NodeExtraInfoFunction; typedef struct CPPTypeHandle CPPTypeHandle; #endif @@ -386,6 +389,9 @@ typedef struct bNodeType { */ NodeGatherSocketLinkOperationsFunction gather_link_search_ops; + /** Get extra information that is drawn next to the node. */ + NodeExtraInfoFunction get_extra_info; + /** True when the node cannot be muted. */ bool no_muting; diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index a8f94fe0981..5d5beb28d29 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -85,6 +85,7 @@ #include "NOD_geometry_exec.hh" #include "NOD_geometry_nodes_log.hh" #include "NOD_node_declaration.hh" +#include "NOD_node_extra_info.hh" #include "NOD_socket_declarations_geometry.hh" #include "FN_field.hh" @@ -100,6 +101,7 @@ namespace geo_log = blender::nodes::geo_eval_log; using blender::bke::bNodeTreeZone; using blender::bke::bNodeTreeZones; using blender::ed::space_node::NestedTreePreviews; +using blender::nodes::NodeExtraInfoRow; /** * This is passed to many functions which draw the node editor. @@ -2491,16 +2493,6 @@ static std::string node_get_execution_time_label(TreeDrawContext &tree_draw_ctx, return stream.str() + " ms"; } -struct NodeExtraInfoRow { - std::string text; - int icon; - const char *tooltip = nullptr; - - uiButToolTipFunc tooltip_fn = nullptr; - void *tooltip_fn_arg = nullptr; - void (*tooltip_fn_free_arg)(void *) = nullptr; -}; - struct NamedAttributeTooltipArg { Map usage_by_attribute; }; @@ -2609,11 +2601,18 @@ static std::optional node_get_accessed_attributes_row( return row_from_used_named_attribute(node_log->used_named_attributes); } -static Vector node_get_extra_info(TreeDrawContext &tree_draw_ctx, +static Vector node_get_extra_info(const bContext &C, + TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node) { Vector rows; + + if (node.typeinfo->get_extra_info) { + nodes::NodeExtraInfoParams params{rows, node, C}; + node.typeinfo->get_extra_info(params); + } + if (!(snode.edittree->type == NTREE_GEOMETRY)) { /* Currently geometry nodes are the only nodes to have extra infos per nodes. */ return rows; @@ -2754,13 +2753,14 @@ static void node_draw_extra_info_panel_back(const bNode &node, const rctf &extra &panel_back_rect, color, nullptr, 0.0f, color_outline, outline_width, BASIS_RAD); } -static void node_draw_extra_info_panel(const Scene *scene, +static void node_draw_extra_info_panel(const bContext &C, TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node, ImBuf *preview, uiBlock &block) { + const Scene *scene = CTX_data_scene(&C); if (!(snode.overlay.flag & SN_OVERLAY_SHOW_OVERLAYS)) { return; } @@ -2768,7 +2768,7 @@ static void node_draw_extra_info_panel(const Scene *scene, /* If the preview has an non-drawable size, just don't draw it. */ preview = nullptr; } - Vector extra_info_rows = node_get_extra_info(tree_draw_ctx, snode, node); + Vector extra_info_rows = node_get_extra_info(C, tree_draw_ctx, snode, node); if (extra_info_rows.size() == 0 && !preview) { return; } @@ -2879,7 +2879,7 @@ static void node_draw_basis(const bContext &C, if (previews_shader) { ImBuf *preview = node_preview_acquire_ibuf(ntree, *previews_shader, node); - node_draw_extra_info_panel(CTX_data_scene(&C), tree_draw_ctx, snode, node, preview, block); + node_draw_extra_info_panel(C, tree_draw_ctx, snode, node, preview, block); node_release_preview_ibuf(*previews_shader); drawn_with_previews = true; } @@ -2888,14 +2888,14 @@ static void node_draw_basis(const bContext &C, BKE_node_instance_hash_lookup(previews_compo, key)); if (preview_compositor) { node_draw_extra_info_panel( - CTX_data_scene(&C), tree_draw_ctx, snode, node, preview_compositor->ibuf, block); + C, tree_draw_ctx, snode, node, preview_compositor->ibuf, block); drawn_with_previews = true; } } } if (drawn_with_previews == false) { - node_draw_extra_info_panel(CTX_data_scene(&C), tree_draw_ctx, snode, node, nullptr, block); + node_draw_extra_info_panel(C, tree_draw_ctx, snode, node, nullptr, block); } } @@ -3212,7 +3212,7 @@ static void node_draw_hidden(const bContext &C, const int color_id = node_get_colorid(tree_draw_ctx, node); - node_draw_extra_info_panel(nullptr, tree_draw_ctx, snode, node, nullptr, block); + node_draw_extra_info_panel(C, tree_draw_ctx, snode, node, nullptr, block); /* Shadow. */ node_draw_shadow(snode, node, hiddenrad, 1.0f); @@ -3694,7 +3694,7 @@ static void frame_node_draw(const bContext &C, /* Label and text. */ frame_node_draw_label(tree_draw_ctx, ntree, node, snode); - node_draw_extra_info_panel(nullptr, tree_draw_ctx, snode, node, nullptr, block); + node_draw_extra_info_panel(C, tree_draw_ctx, snode, node, nullptr, block); UI_block_end(&C, &block); UI_block_draw(&C, &block); diff --git a/source/blender/nodes/NOD_node_extra_info.hh b/source/blender/nodes/NOD_node_extra_info.hh new file mode 100644 index 00000000000..a3923e54be9 --- /dev/null +++ b/source/blender/nodes/NOD_node_extra_info.hh @@ -0,0 +1,27 @@ +/* SPDX-FileCopyrightText: 2005 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "UI_interface_c.hh" + +namespace blender::nodes { + +struct NodeExtraInfoRow { + std::string text; + int icon = 0; + const char *tooltip = nullptr; + + uiButToolTipFunc tooltip_fn = nullptr; + void *tooltip_fn_arg = nullptr; + void (*tooltip_fn_free_arg)(void *) = nullptr; +}; + +struct NodeExtraInfoParams { + Vector &rows; + const bNode &node; + const bContext &C; +}; + +} // namespace blender::nodes