Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_node/node_draw.cc
| Show First 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "ED_gpencil.h" | #include "ED_gpencil.h" | ||||
| #include "ED_node.h" | #include "ED_node.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_space_api.h" | #include "ED_space_api.h" | ||||
| #include "ED_viewer_path.hh" | |||||
| #include "UI_interface.hh" | #include "UI_interface.hh" | ||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "UI_view2d.h" | #include "UI_view2d.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_prototypes.h" | #include "RNA_prototypes.h" | ||||
| Show All 19 Lines | extern void ui_draw_dropshadow( | ||||
| const rctf *rct, float radius, float aspect, float alpha, int select); | const rctf *rct, float radius, float aspect, float alpha, int select); | ||||
| } | } | ||||
| /** | /** | ||||
| * This is passed to many functions which draw the node editor. | * This is passed to many functions which draw the node editor. | ||||
| */ | */ | ||||
| struct TreeDrawContext { | struct TreeDrawContext { | ||||
| /** | /** | ||||
| * Whether a viewer node is active in geometry nodes can not be determined by a flag on the node | |||||
| * alone. That's because if the node group with the viewer is used multiple times, it's only | |||||
| * active in one of these cases. | |||||
| * The active node is cached here to avoid doing the more expensive check for every viewer node | |||||
| * in the tree. | |||||
| */ | |||||
| const bNode *active_geometry_nodes_viewer = nullptr; | |||||
| /** | |||||
| * Geometry nodes logs various data during execution. The logged data that corresponds to the | * Geometry nodes logs various data during execution. The logged data that corresponds to the | ||||
| * currently drawn node tree can be retrieved from the log below. | * currently drawn node tree can be retrieved from the log below. | ||||
| */ | */ | ||||
| geo_log::GeoTreeLog *geo_tree_log = nullptr; | geo_log::GeoTreeLog *geo_tree_log = nullptr; | ||||
| }; | }; | ||||
| float ED_node_grid_size() | float ED_node_grid_size() | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 528 Lines • ▼ Show 20 Lines | static void node_update_hidden(bNode &node, uiBlock &block) | ||||
| * Add a margin for sockets on each side. */ | * Add a margin for sockets on each side. */ | ||||
| UI_block_bounds_set_explicit(&block, | UI_block_bounds_set_explicit(&block, | ||||
| node.totr.xmin - NODE_SOCKSIZE, | node.totr.xmin - NODE_SOCKSIZE, | ||||
| node.totr.ymin, | node.totr.ymin, | ||||
| node.totr.xmax + NODE_SOCKSIZE, | node.totr.xmax + NODE_SOCKSIZE, | ||||
| node.totr.ymax); | node.totr.ymax); | ||||
| } | } | ||||
| static int node_get_colorid(const bNode &node) | static int node_get_colorid(TreeDrawContext &tree_draw_ctx, const bNode &node) | ||||
| { | { | ||||
| const int nclass = (node.typeinfo->ui_class == nullptr) ? node.typeinfo->nclass : | const int nclass = (node.typeinfo->ui_class == nullptr) ? node.typeinfo->nclass : | ||||
| node.typeinfo->ui_class(&node); | node.typeinfo->ui_class(&node); | ||||
| switch (nclass) { | switch (nclass) { | ||||
| case NODE_CLASS_INPUT: | case NODE_CLASS_INPUT: | ||||
| return TH_NODE_INPUT; | return TH_NODE_INPUT; | ||||
| case NODE_CLASS_OUTPUT: | case NODE_CLASS_OUTPUT: { | ||||
| if (node.type == GEO_NODE_VIEWER) { | |||||
| return &node == tree_draw_ctx.active_geometry_nodes_viewer ? TH_NODE_OUTPUT : TH_NODE; | |||||
| } | |||||
| return (node.flag & NODE_DO_OUTPUT) ? TH_NODE_OUTPUT : TH_NODE; | return (node.flag & NODE_DO_OUTPUT) ? TH_NODE_OUTPUT : TH_NODE; | ||||
| } | |||||
| case NODE_CLASS_CONVERTER: | case NODE_CLASS_CONVERTER: | ||||
| return TH_NODE_CONVERTER; | return TH_NODE_CONVERTER; | ||||
| case NODE_CLASS_OP_COLOR: | case NODE_CLASS_OP_COLOR: | ||||
| return TH_NODE_COLOR; | return TH_NODE_COLOR; | ||||
| case NODE_CLASS_OP_VECTOR: | case NODE_CLASS_OP_VECTOR: | ||||
| return TH_NODE_VECTOR; | return TH_NODE_VECTOR; | ||||
| case NODE_CLASS_OP_FILTER: | case NODE_CLASS_OP_FILTER: | ||||
| return TH_NODE_FILTER; | return TH_NODE_FILTER; | ||||
| ▲ Show 20 Lines • Show All 1,391 Lines • ▼ Show 20 Lines | if (BLI_rctf_isect(&node.totr, &v2d.cur, nullptr) == false) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* Shadow. */ | /* Shadow. */ | ||||
| node_draw_shadow(snode, node, BASIS_RAD, 1.0f); | node_draw_shadow(snode, node, BASIS_RAD, 1.0f); | ||||
| const rctf &rct = node.totr; | const rctf &rct = node.totr; | ||||
| float color[4]; | float color[4]; | ||||
| int color_id = node_get_colorid(node); | int color_id = node_get_colorid(tree_draw_ctx, node); | ||||
| GPU_line_width(1.0f); | GPU_line_width(1.0f); | ||||
| node_draw_extra_info_panel(tree_draw_ctx, snode, node, block); | node_draw_extra_info_panel(tree_draw_ctx, snode, node, block); | ||||
| /* Header. */ | /* Header. */ | ||||
| { | { | ||||
| const rctf rect = { | const rctf rect = { | ||||
| ▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | uiDefIconBut(&block, | ||||
| nullptr, | nullptr, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| ""); | ""); | ||||
| UI_block_emboss_set(&block, UI_EMBOSS); | UI_block_emboss_set(&block, UI_EMBOSS); | ||||
| } | } | ||||
| if (node.type == GEO_NODE_VIEWER) { | |||||
| const bool is_active = &node == tree_draw_ctx.active_geometry_nodes_viewer; | |||||
| iconofs -= iconbutw; | |||||
| UI_block_emboss_set(&block, UI_EMBOSS_NONE); | |||||
| uiBut *but = uiDefIconBut(&block, | |||||
| UI_BTYPE_BUT, | |||||
| 0, | |||||
| is_active ? ICON_HIDE_OFF : ICON_HIDE_ON, | |||||
| iconofs, | |||||
| rct.ymax - NODE_DY, | |||||
| iconbutw, | |||||
| UI_UNIT_Y, | |||||
| nullptr, | |||||
| 0, | |||||
| 0, | |||||
| 0, | |||||
| 0, | |||||
| ""); | |||||
| /* Selection implicitly activates the node. */ | |||||
| const char *operator_idname = is_active ? "NODE_OT_deactivate_viewer" : "NODE_OT_select"; | |||||
| UI_but_func_set(but, node_toggle_button_cb, &node, (void *)operator_idname); | |||||
| UI_block_emboss_set(&block, UI_EMBOSS); | |||||
| } | |||||
| node_add_error_message_button(tree_draw_ctx, node, block, rct, iconofs); | node_add_error_message_button(tree_draw_ctx, node, block, rct, iconofs); | ||||
| /* Title. */ | /* Title. */ | ||||
| if (node.flag & SELECT) { | if (node.flag & SELECT) { | ||||
| UI_GetThemeColor4fv(TH_SELECT, color); | UI_GetThemeColor4fv(TH_SELECT, color); | ||||
| } | } | ||||
| else { | else { | ||||
| ▲ Show 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| const rctf &rct = node.totr; | const rctf &rct = node.totr; | ||||
| float centy = BLI_rctf_cent_y(&rct); | float centy = BLI_rctf_cent_y(&rct); | ||||
| float hiddenrad = BLI_rctf_size_y(&rct) / 2.0f; | float hiddenrad = BLI_rctf_size_y(&rct) / 2.0f; | ||||
| float scale; | float scale; | ||||
| UI_view2d_scale_get(&v2d, &scale, nullptr); | UI_view2d_scale_get(&v2d, &scale, nullptr); | ||||
| const int color_id = node_get_colorid(node); | const int color_id = node_get_colorid(tree_draw_ctx, node); | ||||
| node_draw_extra_info_panel(tree_draw_ctx, snode, node, block); | node_draw_extra_info_panel(tree_draw_ctx, snode, node, block); | ||||
| /* Shadow. */ | /* Shadow. */ | ||||
| node_draw_shadow(snode, node, hiddenrad, 1.0f); | node_draw_shadow(snode, node, hiddenrad, 1.0f); | ||||
| /* Wire across the node when muted/disabled. */ | /* Wire across the node when muted/disabled. */ | ||||
| if (node.flag & NODE_MUTED) { | if (node.flag & NODE_MUTED) { | ||||
| ▲ Show 20 Lines • Show All 340 Lines • ▼ Show 20 Lines | static void node_update_nodetree(const bContext &C, | ||||
| /* Now calculate the size of frame nodes, which can depend on the size of other nodes. */ | /* Now calculate the size of frame nodes, which can depend on the size of other nodes. */ | ||||
| for (const int i : nodes.index_range()) { | for (const int i : nodes.index_range()) { | ||||
| if (nodes[i]->type == NODE_FRAME) { | if (nodes[i]->type == NODE_FRAME) { | ||||
| frame_node_prepare_for_draw(*nodes[i], nodes); | frame_node_prepare_for_draw(*nodes[i], nodes); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void frame_node_draw_label(const bNodeTree &ntree, | static void frame_node_draw_label(TreeDrawContext &tree_draw_ctx, | ||||
| const bNodeTree &ntree, | |||||
| const bNode &node, | const bNode &node, | ||||
| const SpaceNode &snode) | const SpaceNode &snode) | ||||
| { | { | ||||
| const float aspect = snode.runtime->aspect; | const float aspect = snode.runtime->aspect; | ||||
| /* XXX font id is crap design */ | /* XXX font id is crap design */ | ||||
| const int fontid = UI_style_get()->widgetlabel.uifont_id; | const int fontid = UI_style_get()->widgetlabel.uifont_id; | ||||
| const NodeFrame *data = (const NodeFrame *)node.storage; | const NodeFrame *data = (const NodeFrame *)node.storage; | ||||
| const float font_size = data->label_size / aspect; | const float font_size = data->label_size / aspect; | ||||
| char label[MAX_NAME]; | char label[MAX_NAME]; | ||||
| nodeLabel(&ntree, &node, label, sizeof(label)); | nodeLabel(&ntree, &node, label, sizeof(label)); | ||||
| BLF_enable(fontid, BLF_ASPECT); | BLF_enable(fontid, BLF_ASPECT); | ||||
| BLF_aspect(fontid, aspect, aspect, 1.0f); | BLF_aspect(fontid, aspect, aspect, 1.0f); | ||||
| /* clamp otherwise it can suck up a LOT of memory */ | /* clamp otherwise it can suck up a LOT of memory */ | ||||
| BLF_size(fontid, MIN2(24.0f, font_size) * U.dpi_fac); | BLF_size(fontid, MIN2(24.0f, font_size) * U.dpi_fac); | ||||
| /* title color */ | /* title color */ | ||||
| int color_id = node_get_colorid(node); | int color_id = node_get_colorid(tree_draw_ctx, node); | ||||
| uchar color[3]; | uchar color[3]; | ||||
| UI_GetThemeColorBlendShade3ubv(TH_TEXT, color_id, 0.4f, 10, color); | UI_GetThemeColorBlendShade3ubv(TH_TEXT, color_id, 0.4f, 10, color); | ||||
| BLF_color3ubv(fontid, color); | BLF_color3ubv(fontid, color); | ||||
| const float margin = float(NODE_DY / 4); | const float margin = float(NODE_DY / 4); | ||||
| const float width = BLF_width(fontid, label, sizeof(label)); | const float width = BLF_width(fontid, label, sizeof(label)); | ||||
| const float ascender = BLF_ascender(fontid); | const float ascender = BLF_ascender(fontid); | ||||
| const int label_height = ((margin / aspect) + (ascender * aspect)); | const int label_height = ((margin / aspect) + (ascender * aspect)); | ||||
| ▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | if (node.flag & SELECT) { | ||||
| else { | else { | ||||
| UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0, -40, color); | UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0, -40, color); | ||||
| } | } | ||||
| UI_draw_roundbox_aa(&rct, false, BASIS_RAD, color); | UI_draw_roundbox_aa(&rct, false, BASIS_RAD, color); | ||||
| } | } | ||||
| /* label and text */ | /* label and text */ | ||||
| frame_node_draw_label(ntree, node, snode); | frame_node_draw_label(tree_draw_ctx, ntree, node, snode); | ||||
| node_draw_extra_info_panel(tree_draw_ctx, snode, node, block); | node_draw_extra_info_panel(tree_draw_ctx, snode, node, block); | ||||
| UI_block_end(&C, &block); | UI_block_end(&C, &block); | ||||
| UI_block_draw(&C, &block); | UI_block_draw(&C, &block); | ||||
| } | } | ||||
| static void reroute_node_draw( | static void reroute_node_draw( | ||||
| ▲ Show 20 Lines • Show All 188 Lines • ▼ Show 20 Lines | static void draw_nodetree(const bContext &C, | ||||
| TreeDrawContext tree_draw_ctx; | TreeDrawContext tree_draw_ctx; | ||||
| if (ntree.type == NTREE_GEOMETRY) { | if (ntree.type == NTREE_GEOMETRY) { | ||||
| tree_draw_ctx.geo_tree_log = geo_log::GeoModifierLog::get_tree_log_for_node_editor(*snode); | tree_draw_ctx.geo_tree_log = geo_log::GeoModifierLog::get_tree_log_for_node_editor(*snode); | ||||
| if (tree_draw_ctx.geo_tree_log != nullptr) { | if (tree_draw_ctx.geo_tree_log != nullptr) { | ||||
| tree_draw_ctx.geo_tree_log->ensure_node_warnings(); | tree_draw_ctx.geo_tree_log->ensure_node_warnings(); | ||||
| tree_draw_ctx.geo_tree_log->ensure_node_run_time(); | tree_draw_ctx.geo_tree_log->ensure_node_run_time(); | ||||
| } | } | ||||
| WorkSpace *workspace = CTX_wm_workspace(&C); | |||||
| tree_draw_ctx.active_geometry_nodes_viewer = viewer_path::find_geometry_nodes_viewer( | |||||
| workspace->viewer_path, *snode); | |||||
| } | } | ||||
| node_update_nodetree(C, tree_draw_ctx, ntree, nodes, blocks); | node_update_nodetree(C, tree_draw_ctx, ntree, nodes, blocks); | ||||
| node_draw_nodetree(C, tree_draw_ctx, region, *snode, ntree, nodes, blocks, parent_key); | node_draw_nodetree(C, tree_draw_ctx, region, *snode, ntree, nodes, blocks, parent_key); | ||||
| } | } | ||||
| /** | /** | ||||
| * Make the background slightly brighter to indicate that users are inside a node-group. | * Make the background slightly brighter to indicate that users are inside a node-group. | ||||
| ▲ Show 20 Lines • Show All 149 Lines • Show Last 20 Lines | |||||