Cleanup: Remove runtime uiBlock pointer from nodes

Code is simpler when the uiBlocks used during drawing are simply
stored in an array. Additionally, looping can be simpler when we use
an vector to hold a temporary copy of the tree's linked list of nodes.

This patch also slightly changes how uiBlocks are "named" in
`node_uiblocks_init`. Now it uses the node name instead of the
pointer, which is helpful so we rely less on the node's address.

Differential Revision: https://developer.blender.org/D13540
This commit is contained in:
Hans Goudey 2021-12-14 11:19:47 -06:00
parent fdd41ac49e
commit d56bbfea7b
Notes: blender-bot 2023-02-14 01:07:44 +01:00
Referenced by issue #100627, Regression: Nodes UI: Node Frame updating after draw causes artifacts
Referenced by issue #94173, Node editor frames don't immediately update to "Toggle Hidden Sockets"
3 changed files with 129 additions and 121 deletions

View File

@ -36,6 +36,7 @@
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
#include "BLI_array.hh"
#include "BLI_map.hh"
#include "BLI_set.hh"
#include "BLI_span.hh"
@ -87,6 +88,7 @@
#include "node_intern.hh" /* own include */
using blender::Array;
using blender::float2;
using blender::Map;
using blender::Set;
@ -314,19 +316,18 @@ void ED_node_sort(bNodeTree *ntree)
}
}
static void node_uiblocks_init(const bContext &C, bNodeTree &ntree)
static Array<uiBlock *> node_uiblocks_init(const bContext &C, Span<bNode *> nodes)
{
Array<uiBlock *> blocks(nodes.size());
/* Add node uiBlocks in drawing order - prevents events going to overlapping nodes. */
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
/* ui block */
char uiblockstr[32];
BLI_snprintf(uiblockstr, sizeof(uiblockstr), "node buttons %p", (void *)node);
node->block = UI_block_begin(&C, CTX_wm_region(&C), uiblockstr, UI_EMBOSS);
for (const int i : nodes.index_range()) {
const std::string block_name = "node_" + std::string(nodes[i]->name);
blocks[i] = UI_block_begin(&C, CTX_wm_region(&C), block_name.c_str(), UI_EMBOSS);
/* this cancels events for background nodes */
UI_block_flag_enable(node->block, UI_BLOCK_CLIP_EVENTS);
UI_block_flag_enable(blocks[i], UI_BLOCK_CLIP_EVENTS);
}
return blocks;
}
float2 node_to_view(const bNode &node, const float2 &co)
@ -359,7 +360,7 @@ float2 node_from_view(const bNode &node, const float2 &co)
/**
* Based on settings and sockets in node, set drawing rect info.
*/
static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node)
static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node, uiBlock &block)
{
PointerRNA nodeptr;
RNA_pointer_create(&ntree.id, &RNA_Node, &node, &nodeptr);
@ -392,7 +393,7 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node)
PointerRNA sockptr;
RNA_pointer_create(&ntree.id, &RNA_NodeSocket, nsock, &sockptr);
uiLayout *layout = UI_block_layout(node.block,
uiLayout *layout = UI_block_layout(&block,
UI_LAYOUT_VERTICAL,
UI_LAYOUT_PANEL,
loc.x + NODE_DYS,
@ -416,8 +417,8 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node)
const char *socket_label = nodeSocketLabel(nsock);
nsock->typeinfo->draw((bContext *)&C, row, &sockptr, &nodeptr, IFACE_(socket_label));
UI_block_align_end(node.block);
UI_block_layout_resolve(node.block, nullptr, &buty);
UI_block_align_end(&block);
UI_block_layout_resolve(&block, nullptr, &buty);
/* Ensure minimum socket height in case layout is empty. */
buty = min_ii(buty, dy - NODE_DY);
@ -480,7 +481,7 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node)
if (node.typeinfo->draw_buttons && (node.flag & NODE_OPTIONS)) {
dy -= NODE_DYS / 2;
uiLayout *layout = UI_block_layout(node.block,
uiLayout *layout = UI_block_layout(&block,
UI_LAYOUT_VERTICAL,
UI_LAYOUT_PANEL,
loc.x + NODE_DYS,
@ -498,8 +499,8 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node)
node.typeinfo->draw_buttons(layout, (bContext *)&C, &nodeptr);
UI_block_align_end(node.block);
UI_block_layout_resolve(node.block, nullptr, &buty);
UI_block_align_end(&block);
UI_block_layout_resolve(&block, nullptr, &buty);
dy = buty - NODE_DYS / 2;
}
@ -523,7 +524,7 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node)
}
dy -= multi_input_socket_offset * 0.5f;
uiLayout *layout = UI_block_layout(node.block,
uiLayout *layout = UI_block_layout(&block,
UI_LAYOUT_VERTICAL,
UI_LAYOUT_PANEL,
loc.x + NODE_DYS,
@ -546,8 +547,8 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node)
const char *socket_label = nodeSocketLabel(nsock);
nsock->typeinfo->draw((bContext *)&C, row, &sockptr, &nodeptr, IFACE_(socket_label));
UI_block_align_end(node.block);
UI_block_layout_resolve(node.block, nullptr, &buty);
UI_block_align_end(&block);
UI_block_layout_resolve(&block, nullptr, &buty);
/* Ensure minimum socket height in case layout is empty. */
buty = min_ii(buty, dy - NODE_DY);
@ -574,7 +575,7 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node)
/* Set the block bounds to clip mouse events from underlying nodes.
* Add a margin for sockets on each side. */
UI_block_bounds_set_explicit(node.block,
UI_block_bounds_set_explicit(&block,
node.totr.xmin - NODE_SOCKSIZE,
node.totr.ymin,
node.totr.xmax + NODE_SOCKSIZE,
@ -584,7 +585,7 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node)
/**
* Based on settings in node, sets drawing rect info.
*/
static void node_update_hidden(bNode &node)
static void node_update_hidden(bNode &node, uiBlock &block)
{
int totin = 0, totout = 0;
@ -644,7 +645,7 @@ static void node_update_hidden(bNode &node)
/* Set the block bounds to clip mouse events from underlying nodes.
* Add a margin for sockets on each side. */
UI_block_bounds_set_explicit(node.block,
UI_block_bounds_set_explicit(&block,
node.totr.xmin - NODE_SOCKSIZE,
node.totr.ymin,
node.totr.xmax + NODE_SOCKSIZE,
@ -1009,6 +1010,7 @@ static std::optional<std::string> create_socket_inspection_string(bContext *C,
static void node_socket_draw_nested(const bContext &C,
bNodeTree &ntree,
PointerRNA &node_ptr,
uiBlock &block,
bNodeSocket &sock,
const uint pos_id,
const uint col_id,
@ -1041,14 +1043,11 @@ static void node_socket_draw_nested(const bContext &C,
return;
}
bNode *node = (bNode *)node_ptr.data;
uiBlock *block = node->block;
/* Ideally sockets themselves should be buttons, but they aren't currently. So add an invisible
* button on top of them for the tooltip. */
const eUIEmbossType old_emboss = UI_block_emboss_get(block);
UI_block_emboss_set(block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(block,
const eUIEmbossType old_emboss = UI_block_emboss_get(&block);
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(&block,
UI_BTYPE_BUT,
0,
ICON_NONE,
@ -1095,7 +1094,7 @@ static void node_socket_draw_nested(const bContext &C,
MEM_freeN);
/* Disable the button so that clicks on it are ignored the the link operator still works. */
UI_but_flag_enable(but, UI_BUT_DISABLED);
UI_block_emboss_set(block, old_emboss);
UI_block_emboss_set(&block, old_emboss);
}
void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[4], float scale)
@ -1243,6 +1242,7 @@ static void node_draw_sockets(const View2D &v2d,
const bContext &C,
bNodeTree &ntree,
bNode &node,
uiBlock &block,
const bool draw_outputs,
const bool select_all)
{
@ -1299,6 +1299,7 @@ static void node_draw_sockets(const View2D &v2d,
node_socket_draw_nested(C,
ntree,
node_ptr,
block,
*sock,
pos_id,
col_id,
@ -1324,6 +1325,7 @@ static void node_draw_sockets(const View2D &v2d,
node_socket_draw_nested(C,
ntree,
node_ptr,
block,
*sock,
pos_id,
col_id,
@ -1357,6 +1359,7 @@ static void node_draw_sockets(const View2D &v2d,
node_socket_draw_nested(C,
ntree,
node_ptr,
block,
*sock,
pos_id,
col_id,
@ -1382,6 +1385,7 @@ static void node_draw_sockets(const View2D &v2d,
node_socket_draw_nested(C,
ntree,
node_ptr,
block,
*sock,
pos_id,
col_id,
@ -1502,10 +1506,8 @@ static char *node_errors_tooltip_fn(bContext *UNUSED(C), void *argN, const char
#define NODE_HEADER_ICON_SIZE (0.8f * U.widget_unit)
static void node_add_error_message_button(const bContext &C,
bNode &node,
const rctf &rect,
float &icon_offset)
static void node_add_error_message_button(
const bContext &C, bNode &node, uiBlock &block, const rctf &rect, float &icon_offset)
{
SpaceNode *snode = CTX_wm_space_node(&C);
const geo_log::NodeLog *node_log = geo_log::ModifierLog::find_node_by_node_editor_context(*snode,
@ -1527,8 +1529,8 @@ static void node_add_error_message_button(const bContext &C,
const geo_log::NodeWarningType display_type = node_error_highest_priority(warnings);
icon_offset -= NODE_HEADER_ICON_SIZE;
UI_block_emboss_set(node.block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(node.block,
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(&block,
UI_BTYPE_BUT,
0,
node_error_type_to_icon(display_type),
@ -1543,7 +1545,7 @@ static void node_add_error_message_button(const bContext &C,
0,
nullptr);
UI_but_func_tooltip_set(but, node_errors_tooltip_fn, tooltip_data, MEM_freeN);
UI_block_emboss_set(node.block, UI_EMBOSS);
UI_block_emboss_set(&block, UI_EMBOSS);
}
static void get_exec_time_other_nodes(const bNode &node,
@ -1689,11 +1691,12 @@ static Vector<NodeExtraInfoRow> node_get_extra_info(const SpaceNode &snode, cons
}
static void node_draw_extra_info_row(const bNode &node,
uiBlock &block,
const rctf &rect,
const int row,
const NodeExtraInfoRow &extra_info_row)
{
uiBut *but_timing = uiDefBut(node.block,
uiBut *but_timing = uiDefBut(&block,
UI_BTYPE_LABEL,
0,
extra_info_row.text.c_str(),
@ -1707,8 +1710,8 @@ static void node_draw_extra_info_row(const bNode &node,
0,
0,
"");
UI_block_emboss_set(node.block, UI_EMBOSS_NONE);
uiBut *but_icon = uiDefIconBut(node.block,
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
uiBut *but_icon = uiDefIconBut(&block,
UI_BTYPE_BUT,
0,
extra_info_row.icon,
@ -1722,14 +1725,14 @@ static void node_draw_extra_info_row(const bNode &node,
0,
0,
extra_info_row.tooltip);
UI_block_emboss_set(node.block, UI_EMBOSS);
UI_block_emboss_set(&block, UI_EMBOSS);
if (node.flag & NODE_MUTED) {
UI_but_flag_enable(but_timing, UI_BUT_INACTIVE);
UI_but_flag_enable(but_icon, UI_BUT_INACTIVE);
}
}
static void node_draw_extra_info_panel(const SpaceNode &snode, const bNode &node)
static void node_draw_extra_info_panel(const SpaceNode &snode, const bNode &node, uiBlock &block)
{
Vector<NodeExtraInfoRow> extra_info_rows = node_get_extra_info(snode, node);
@ -1780,7 +1783,7 @@ static void node_draw_extra_info_panel(const SpaceNode &snode, const bNode &node
}
for (int row : extra_info_rows.index_range()) {
node_draw_extra_info_row(node, extra_info_rect, row, extra_info_rows[row]);
node_draw_extra_info_row(node, block, extra_info_rect, row, extra_info_rows[row]);
}
}
@ -1789,14 +1792,14 @@ static void node_draw_basis(const bContext &C,
const SpaceNode &snode,
bNodeTree &ntree,
bNode &node,
uiBlock &block,
bNodeInstanceKey key)
{
const float iconbutw = NODE_HEADER_ICON_SIZE;
/* Skip if out of view. */
if (BLI_rctf_isect(&node.totr, &v2d.cur, nullptr) == false) {
UI_block_end(&C, node.block);
node.block = nullptr;
UI_block_end(&C, &block);
return;
}
@ -1809,7 +1812,7 @@ static void node_draw_basis(const bContext &C,
GPU_line_width(1.0f);
node_draw_extra_info_panel(snode, node);
node_draw_extra_info_panel(snode, node, block);
/* Header. */
{
@ -1840,8 +1843,8 @@ static void node_draw_basis(const bContext &C,
/* Preview. */
if (node.typeinfo->flag & NODE_PREVIEW) {
iconofs -= iconbutw;
UI_block_emboss_set(node.block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(node.block,
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(&block,
UI_BTYPE_BUT_TOGGLE,
0,
ICON_MATERIAL,
@ -1861,13 +1864,13 @@ static void node_draw_basis(const bContext &C,
* This can only work as visual indicator! */
// if (!(node.flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT)))
// UI_but_flag_enable(but, UI_BUT_DISABLED);
UI_block_emboss_set(node.block, UI_EMBOSS);
UI_block_emboss_set(&block, UI_EMBOSS);
}
/* Group edit. */
if (node.type == NODE_GROUP) {
iconofs -= iconbutw;
UI_block_emboss_set(node.block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(node.block,
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(&block,
UI_BTYPE_BUT_TOGGLE,
0,
ICON_NODETREE,
@ -1882,12 +1885,12 @@ static void node_draw_basis(const bContext &C,
0,
"");
UI_but_func_set(but, node_toggle_button_cb, &node, (void *)"NODE_OT_group_edit");
UI_block_emboss_set(node.block, UI_EMBOSS);
UI_block_emboss_set(&block, UI_EMBOSS);
}
if (node.type == NODE_CUSTOM && node.typeinfo->ui_icon != ICON_NONE) {
iconofs -= iconbutw;
UI_block_emboss_set(node.block, UI_EMBOSS_NONE);
uiDefIconBut(node.block,
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
uiDefIconBut(&block,
UI_BTYPE_BUT,
0,
node.typeinfo->ui_icon,
@ -1901,10 +1904,10 @@ static void node_draw_basis(const bContext &C,
0,
0,
"");
UI_block_emboss_set(node.block, UI_EMBOSS);
UI_block_emboss_set(&block, UI_EMBOSS);
}
node_add_error_message_button(C, node, rct, iconofs);
node_add_error_message_button(C, node, block, rct, iconofs);
/* Title. */
if (node.flag & SELECT) {
@ -1917,9 +1920,9 @@ static void node_draw_basis(const bContext &C,
/* Collapse/expand icon. */
{
const int but_size = U.widget_unit * 0.8f;
UI_block_emboss_set(node.block, UI_EMBOSS_NONE);
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(node.block,
uiBut *but = uiDefIconBut(&block,
UI_BTYPE_BUT_TOGGLE,
0,
ICON_DOWNARROW_HLT,
@ -1935,13 +1938,13 @@ static void node_draw_basis(const bContext &C,
"");
UI_but_func_set(but, node_toggle_button_cb, &node, (void *)"NODE_OT_hide_toggle");
UI_block_emboss_set(node.block, UI_EMBOSS);
UI_block_emboss_set(&block, UI_EMBOSS);
}
char showname[128];
nodeLabel(&ntree, &node, showname, sizeof(showname));
uiBut *but = uiDefBut(node.block,
uiBut *but = uiDefBut(&block,
UI_BTYPE_LABEL,
0,
showname,
@ -2056,7 +2059,7 @@ static void node_draw_basis(const bContext &C,
/* Skip slow socket drawing if zoom is small. */
if (scale > 0.2f) {
node_draw_sockets(v2d, C, ntree, node, true, false);
node_draw_sockets(v2d, C, ntree, node, block, true, false);
}
/* Preview. */
@ -2071,13 +2074,16 @@ static void node_draw_basis(const bContext &C,
}
}
UI_block_end(&C, node.block);
UI_block_draw(&C, node.block);
node.block = nullptr;
UI_block_end(&C, &block);
UI_block_draw(&C, &block);
}
static void node_draw_hidden(
const bContext &C, const View2D &v2d, const SpaceNode &snode, bNodeTree &ntree, bNode &node)
static void node_draw_hidden(const bContext &C,
const View2D &v2d,
const SpaceNode &snode,
bNodeTree &ntree,
bNode &node,
uiBlock &block)
{
const rctf &rct = node.totr;
float centy = BLI_rctf_cent_y(&rct);
@ -2138,9 +2144,9 @@ static void node_draw_hidden(
/* Collapse/expand icon. */
{
const int but_size = U.widget_unit * 1.0f;
UI_block_emboss_set(node.block, UI_EMBOSS_NONE);
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(node.block,
uiBut *but = uiDefIconBut(&block,
UI_BTYPE_BUT_TOGGLE,
0,
ICON_RIGHTARROW,
@ -2156,13 +2162,13 @@ static void node_draw_hidden(
"");
UI_but_func_set(but, node_toggle_button_cb, &node, (void *)"NODE_OT_hide_toggle");
UI_block_emboss_set(node.block, UI_EMBOSS);
UI_block_emboss_set(&block, UI_EMBOSS);
}
char showname[128];
nodeLabel(&ntree, &node, showname, sizeof(showname));
uiBut *but = uiDefBut(node.block,
uiBut *but = uiDefBut(&block,
UI_BTYPE_LABEL,
0,
showname,
@ -2240,11 +2246,10 @@ static void node_draw_hidden(
immUnbindProgram();
GPU_blend(GPU_BLEND_NONE);
node_draw_sockets(v2d, C, ntree, node, true, false);
node_draw_sockets(v2d, C, ntree, node, block, true, false);
UI_block_end(&C, node.block);
UI_block_draw(&C, node.block);
node.block = nullptr;
UI_block_end(&C, &block);
UI_block_draw(&C, &block);
}
int node_get_resize_cursor(NodeResizeDirection directions)
@ -2325,7 +2330,7 @@ static void count_multi_input_socket_links(bNodeTree &ntree, SpaceNode &snode)
* Not ideal to do this in every draw call, but doing as transform callback doesn't work,
* since the child node totr rects are not updated properly at that point.
*/
static void frame_node_prepare_for_draw(bNodeTree &ntree, bNode &node)
static void frame_node_prepare_for_draw(bNodeTree &ntree, bNode &node, Span<bNode *> nodes)
{
const float margin = 1.5f * U.widget_unit;
NodeFrame *data = (NodeFrame *)node.storage;
@ -2339,7 +2344,7 @@ static void frame_node_prepare_for_draw(bNodeTree &ntree, bNode &node)
/* for shrinking bbox, initialize the rect from first child node */
bool bbinit = (data->flag & NODE_FRAME_SHRINK);
/* fit bounding box to all children */
LISTBASE_FOREACH (bNode *, tnode, &ntree.nodes) {
for (const bNode *tnode : nodes) {
if (tnode->parent != &node) {
continue;
}
@ -2395,7 +2400,10 @@ static void reroute_node_prepare_for_draw(bNode &node)
node.totr.ymin = loc.y - size;
}
void node_update_nodetree(const bContext &C, bNodeTree &ntree)
static void node_update_nodetree(const bContext &C,
bNodeTree &ntree,
Span<bNode *> nodes,
Span<uiBlock *> blocks)
{
/* Make sure socket "used" tags are correct, for displaying value buttons. */
SpaceNode *snode = CTX_wm_space_node(&C);
@ -2404,19 +2412,21 @@ void node_update_nodetree(const bContext &C, bNodeTree &ntree)
count_multi_input_socket_links(ntree, *snode);
/* Update nodes front to back, so children sizes get updated before parents. */
LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree.nodes) {
if (node->type == NODE_FRAME) {
frame_node_prepare_for_draw(ntree, *node);
for (const int i : nodes.index_range()) {
bNode &node = *nodes[i];
uiBlock &block = *blocks[i];
if (node.type == NODE_FRAME) {
frame_node_prepare_for_draw(ntree, node, nodes);
}
else if (node->type == NODE_REROUTE) {
reroute_node_prepare_for_draw(*node);
else if (node.type == NODE_REROUTE) {
reroute_node_prepare_for_draw(node);
}
else {
if (node->flag & NODE_HIDDEN) {
node_update_hidden(*node);
if (node.flag & NODE_HIDDEN) {
node_update_hidden(node, block);
}
else {
node_update_basis(C, ntree, *node);
node_update_basis(C, ntree, node, block);
}
}
}
@ -2513,12 +2523,12 @@ static void frame_node_draw(const bContext &C,
const ARegion &region,
const SpaceNode &snode,
bNodeTree &ntree,
bNode &node)
bNode &node,
uiBlock &block)
{
/* skip if out of view */
if (BLI_rctf_isect(&node.totr, &region.v2d.cur, nullptr) == false) {
UI_block_end(&C, node.block);
node.block = nullptr;
UI_block_end(&C, &block);
return;
}
@ -2556,14 +2566,14 @@ static void frame_node_draw(const bContext &C,
/* label and text */
frame_node_draw_label(ntree, node, snode);
node_draw_extra_info_panel(snode, node);
node_draw_extra_info_panel(snode, node, block);
UI_block_end(&C, node.block);
UI_block_draw(&C, node.block);
node.block = nullptr;
UI_block_end(&C, &block);
UI_block_draw(&C, &block);
}
static void reroute_node_draw(const bContext &C, ARegion &region, bNodeTree &ntree, bNode &node)
static void reroute_node_draw(
const bContext &C, ARegion &region, bNodeTree &ntree, bNode &node, uiBlock &block)
{
char showname[128]; /* 128 used below */
const rctf &rct = node.totr;
@ -2571,15 +2581,14 @@ static void reroute_node_draw(const bContext &C, ARegion &region, bNodeTree &ntr
/* skip if out of view */
if (rct.xmax < region.v2d.cur.xmin || rct.xmin > region.v2d.cur.xmax ||
rct.ymax < region.v2d.cur.ymin || node.totr.ymin > region.v2d.cur.ymax) {
UI_block_end(&C, node.block);
node.block = nullptr;
UI_block_end(&C, &block);
return;
}
if (node.label[0] != '\0') {
/* draw title (node label) */
BLI_strncpy(showname, node.label, sizeof(showname));
uiDefBut(node.block,
uiDefBut(&block,
UI_BTYPE_LABEL,
0,
showname,
@ -2598,11 +2607,10 @@ static void reroute_node_draw(const bContext &C, ARegion &region, bNodeTree &ntr
/* only draw input socket. as they all are placed on the same position.
* highlight also if node itself is selected, since we don't display the node body separately!
*/
node_draw_sockets(region.v2d, C, ntree, node, false, node.flag & SELECT);
node_draw_sockets(region.v2d, C, ntree, node, block, false, node.flag & SELECT);
UI_block_end(&C, node.block);
UI_block_draw(&C, node.block);
node.block = nullptr;
UI_block_end(&C, &block);
UI_block_draw(&C, &block);
}
static void node_draw(const bContext &C,
@ -2610,21 +2618,22 @@ static void node_draw(const bContext &C,
const SpaceNode &snode,
bNodeTree &ntree,
bNode &node,
uiBlock &block,
bNodeInstanceKey key)
{
if (node.type == NODE_FRAME) {
frame_node_draw(C, region, snode, ntree, node);
frame_node_draw(C, region, snode, ntree, node, block);
}
else if (node.type == NODE_REROUTE) {
reroute_node_draw(C, region, ntree, node);
reroute_node_draw(C, region, ntree, node, block);
}
else {
const View2D &v2d = region.v2d;
if (node.flag & NODE_HIDDEN) {
node_draw_hidden(C, v2d, snode, ntree, node);
node_draw_hidden(C, v2d, snode, ntree, node, block);
}
else {
node_draw_basis(C, v2d, snode, ntree, node, key);
node_draw_basis(C, v2d, snode, ntree, node, block, key);
}
}
}
@ -2635,28 +2644,28 @@ static void node_draw_nodetree(const bContext &C,
ARegion &region,
SpaceNode &snode,
bNodeTree &ntree,
Span<bNode *> nodes,
Span<uiBlock *> blocks,
bNodeInstanceKey parent_key)
{
#ifdef USE_DRAW_TOT_UPDATE
if (ntree.nodes.first) {
BLI_rctf_init_minmax(&region.v2d.tot);
}
BLI_rctf_init_minmax(&region.v2d.tot);
#endif
/* Draw background nodes, last nodes in front. */
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
for (const int i : nodes.index_range()) {
#ifdef USE_DRAW_TOT_UPDATE
/* Unrelated to background nodes, update the v2d->tot,
* can be anywhere before we draw the scroll bars. */
BLI_rctf_union(&region.v2d.tot, &node->totr);
BLI_rctf_union(&region.v2d.tot, &nodes[i]->totr);
#endif
if (!(node->flag & NODE_BACKGROUND)) {
if (!(nodes[i]->flag & NODE_BACKGROUND)) {
continue;
}
bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, node);
node_draw(C, region, snode, ntree, *node, key);
bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]);
node_draw(C, region, snode, ntree, *nodes[i], *blocks[i], key);
}
/* Node lines. */
@ -2672,13 +2681,13 @@ static void node_draw_nodetree(const bContext &C,
GPU_blend(GPU_BLEND_NONE);
/* Draw foreground nodes, last nodes in front. */
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
if (node->flag & NODE_BACKGROUND) {
for (const int i : nodes.index_range()) {
if (nodes[i]->flag & NODE_BACKGROUND) {
continue;
}
bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, node);
node_draw(C, region, snode, ntree, *node, key);
bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]);
node_draw(C, region, snode, ntree, *nodes[i], *blocks[i], key);
}
}
@ -2732,10 +2741,12 @@ static void draw_nodetree(const bContext &C,
{
SpaceNode *snode = CTX_wm_space_node(&C);
node_uiblocks_init(C, ntree);
Vector<bNode *> nodes = ntree.nodes;
node_update_nodetree(C, ntree);
node_draw_nodetree(C, region, *snode, ntree, parent_key);
Array<uiBlock *> blocks = node_uiblocks_init(C, nodes);
node_update_nodetree(C, ntree, nodes, blocks);
node_draw_nodetree(C, region, *snode, ntree, nodes, blocks, parent_key);
}
/**

View File

@ -110,7 +110,6 @@ void node_socket_color_get(const bContext &C,
PointerRNA &node_ptr,
const bNodeSocket &sock,
float r_color[4]);
void node_update_nodetree(const bContext &C, bNodeTree &ntree);
void node_draw_space(const bContext &C, ARegion &region);
void node_set_cursor(wmWindow &win, SpaceNode &snode, const blender::float2 &cursor);

View File

@ -323,8 +323,6 @@ typedef struct bNode {
char branch_tag;
/** Used at runtime when iterating over node branches. */
char iter_flag;
/** Runtime during drawing. */
struct uiBlock *block;
/**
* XXX: eevee only, id of screen space reflection layer,