Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_node/node_draw.cc
| Show First 20 Lines • Show All 304 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| const float x = co.x / UI_DPI_FAC; | const float x = co.x / UI_DPI_FAC; | ||||
| const float y = co.y / UI_DPI_FAC; | const float y = co.y / UI_DPI_FAC; | ||||
| float2 result; | float2 result; | ||||
| nodeFromView(&node, x, y, &result.x, &result.y); | nodeFromView(&node, x, y, &result.x, &result.y); | ||||
| return result; | return result; | ||||
| } | } | ||||
| static char *node_socket_get_tooltip(const SpaceNode *snode, | |||||
| const bNodeTree &ntree, | |||||
| const bNodeSocket &socket); | |||||
| /** | /** | ||||
| * Based on settings and sockets in node, set drawing rect info. | * Based on settings and sockets in node, set drawing rect info. | ||||
| */ | */ | ||||
| static void node_update_basis(const bContext &C, | static void node_update_basis(const bContext &C, | ||||
| const TreeDrawContext & /*tree_draw_ctx*/, | const TreeDrawContext & /*tree_draw_ctx*/, | ||||
| bNodeTree &ntree, | bNodeTree &ntree, | ||||
| bNode &node, | bNode &node, | ||||
| uiBlock &block, | uiBlock &block, | ||||
| ▲ Show 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | for (bNodeSocket *socket : node.input_sockets()) { | ||||
| } | } | ||||
| PointerRNA sockptr; | PointerRNA sockptr; | ||||
| RNA_pointer_create(&ntree.id, &RNA_NodeSocket, socket, &sockptr); | RNA_pointer_create(&ntree.id, &RNA_NodeSocket, socket, &sockptr); | ||||
| /* Add the half the height of a multi-input socket to cursor Y | /* Add the half the height of a multi-input socket to cursor Y | ||||
| * to account for the increased height of the taller sockets. */ | * to account for the increased height of the taller sockets. */ | ||||
| float multi_input_socket_offset = 0.0f; | float multi_input_socket_offset = 0.0f; | ||||
| if (socket->flag & SOCK_MULTI_INPUT) { | if (socket->is_multi_input()) { | ||||
| if (socket->runtime->total_inputs > 2) { | if (socket->runtime->total_inputs > 2) { | ||||
| multi_input_socket_offset = (socket->runtime->total_inputs - 2) * | multi_input_socket_offset = socket->runtime->total_inputs - 2; | ||||
| NODE_MULTI_INPUT_LINK_GAP; | multi_input_socket_offset *= NODE_MULTI_INPUT_LINK_GAP; | ||||
| dy -= multi_input_socket_offset * 0.5f; | |||||
| } | } | ||||
| } | } | ||||
| dy -= multi_input_socket_offset * 0.5f; | |||||
| uiLayout *layout = UI_block_layout(&block, | uiLayout *layout = UI_block_layout(&block, | ||||
| UI_LAYOUT_VERTICAL, | UI_LAYOUT_VERTICAL, | ||||
| UI_LAYOUT_PANEL, | UI_LAYOUT_PANEL, | ||||
| loc.x + NODE_DYS, | loc.x + NODE_DYS, | ||||
| dy, | dy, | ||||
| NODE_WIDTH(node) - NODE_DY, | NODE_WIDTH(node) - NODE_DY, | ||||
| NODE_DY, | NODE_DY, | ||||
| ▲ Show 20 Lines • Show All 225 Lines • ▼ Show 20 Lines | static void node_socket_draw(const bNodeSocket &sock, | ||||
| immAttr4fv(col_id, color); | immAttr4fv(col_id, color); | ||||
| immAttr1u(shape_id, flags); | immAttr1u(shape_id, flags); | ||||
| immAttr1f(size_id, size); | immAttr1f(size_id, size); | ||||
| immAttr4fv(outline_col_id, color_outline); | immAttr4fv(outline_col_id, color_outline); | ||||
| immVertex2f(pos_id, locx, locy); | immVertex2f(pos_id, locx, locy); | ||||
| } | } | ||||
| static void node_socket_draw_multi_input(const float color[4], | /* Ideally sockets themselves should be buttons, but they aren't currently. So add an invisible | ||||
| * button on top of them for the tooltip. */ | |||||
| static void node_socket_tooltip_set(uiBlock &block, | |||||
| const int socket_index_in_tree, | |||||
| const float2 location, | |||||
| const float2 size) | |||||
| { | |||||
| const float2 centre = location - size / 2.0f; | |||||
| const eUIEmbossType old_emboss = UI_block_emboss_get(&block); | |||||
| UI_block_emboss_set(&block, UI_EMBOSS_NONE); | |||||
| uiBut *but = uiDefBut(&block, | |||||
| UI_BTYPE_BUT, | |||||
| 0, | |||||
| "", | |||||
| centre.x, | |||||
| centre.y, | |||||
| size.x, | |||||
| size.y, | |||||
| nullptr, | |||||
| 0, | |||||
| 0, | |||||
| 0, | |||||
| 0, | |||||
| nullptr); | |||||
| UI_but_func_tooltip_set( | |||||
| but, | |||||
| [](bContext *C, void *argN, const char * /*tip*/) { | |||||
| const SpaceNode &snode = *CTX_wm_space_node(C); | |||||
| const bNodeTree &ntree = *snode.edittree; | |||||
| const int index_in_tree = POINTER_AS_INT(argN); | |||||
| ntree.ensure_topology_cache(); | |||||
| return node_socket_get_tooltip(&snode, ntree, *ntree.all_sockets()[index_in_tree]); | |||||
| }, | |||||
| POINTER_FROM_INT(socket_index_in_tree), | |||||
| nullptr); | |||||
| /* Disable the button so that clicks on it are ignored the link operator still works. */ | |||||
| UI_but_flag_enable(but, UI_BUT_DISABLED); | |||||
| UI_block_emboss_set(&block, old_emboss); | |||||
| } | |||||
| static void node_socket_draw_multi_input(uiBlock &block, | |||||
| const int index_in_tree, | |||||
| const float2 location, | |||||
| const float2 draw_size, | |||||
| const float color[4], | |||||
| const float color_outline[4], | const float color_outline[4], | ||||
| const float width, | const float2 tooltip_size, | ||||
| const float height, | const bool has_tooltip) | ||||
| const float2 location) | |||||
| { | { | ||||
| /* The other sockets are drawn with the keyframe shader. There, the outline has a base thickness | /* The other sockets are drawn with the keyframe shader. There, the outline has a base thickness | ||||
| * that can be varied but always scales with the size the socket is drawn at. Using `U.dpi_fac` | * that can be varied but always scales with the size the socket is drawn at. Using `U.dpi_fac` | ||||
| * has the same effect here. It scales the outline correctly across different screen DPI's | * has the same effect here. It scales the outline correctly across different screen DPI's | ||||
| * and UI scales without being affected by the 'line-width'. */ | * and UI scales without being affected by the 'line-width'. */ | ||||
| const float outline_width = NODE_SOCK_OUTLINE_SCALE * U.dpi_fac; | const float half_outline_width = NODE_SOCK_OUTLINE_SCALE * U.dpi_fac * 0.5f; | ||||
| /* UI_draw_roundbox draws the outline on the outer side, so compensate for the outline width. */ | /* UI_draw_roundbox draws the outline on the outer side, so compensate for the outline width. */ | ||||
| const rctf rect = { | const rctf rect = { | ||||
| location.x - width + outline_width * 0.5f, | location.x - draw_size.x + half_outline_width, | ||||
| location.x + width - outline_width * 0.5f, | location.x + draw_size.x - half_outline_width, | ||||
| location.y - height + outline_width * 0.5f, | location.y - draw_size.y + half_outline_width, | ||||
| location.y + height - outline_width * 0.5f, | location.y + draw_size.y - half_outline_width, | ||||
| }; | }; | ||||
| UI_draw_roundbox_corner_set(UI_CNR_ALL); | UI_draw_roundbox_corner_set(UI_CNR_ALL); | ||||
| UI_draw_roundbox_4fv_ex( | UI_draw_roundbox_4fv_ex(&rect, | ||||
| &rect, color, nullptr, 1.0f, color_outline, outline_width, width - outline_width * 0.5f); | color, | ||||
| nullptr, | |||||
| 1.0f, | |||||
| color_outline, | |||||
| half_outline_width * 2.0f, | |||||
| draw_size.x - half_outline_width); | |||||
| if (has_tooltip) { | |||||
| node_socket_tooltip_set(block, index_in_tree, location, tooltip_size); | |||||
| } | |||||
| } | } | ||||
| static const float virtual_node_socket_outline_color[4] = {0.5, 0.5, 0.5, 1.0}; | static const float virtual_node_socket_outline_color[4] = {0.5, 0.5, 0.5, 1.0}; | ||||
| static void node_socket_outline_color_get(const bool selected, | static void node_socket_outline_color_get(const bool selected, | ||||
| const int socket_type, | const int socket_type, | ||||
| float r_outline_color[4]) | float r_outline_color[4]) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | for (const int i : input_tooltips.index_range()) { | ||||
| if (i < input_tooltips.size() - 1) { | if (i < input_tooltips.size() - 1) { | ||||
| ss << ".\n"; | ss << ".\n"; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void create_inspection_string_for_geometry_info(const geo_log::GeometryInfoLog &value_log, | static void create_inspection_string_for_geometry_info(const geo_log::GeometryInfoLog &value_log, | ||||
| std::stringstream &ss) | std::stringstream &ss, | ||||
| const char *tab_space) | |||||
| { | { | ||||
| Span<GeometryComponentType> component_types = value_log.component_types; | Span<GeometryComponentType> component_types = value_log.component_types; | ||||
| if (component_types.is_empty()) { | if (component_types.is_empty()) { | ||||
| ss << TIP_("Empty Geometry"); | ss << TIP_("Empty Geometry"); | ||||
| return; | return; | ||||
| } | } | ||||
| auto to_string = [](int value) { | auto to_string = [](int value) -> std::string { | ||||
| char str[16]; | char str[16]; | ||||
| BLI_str_format_int_grouped(str, value); | BLI_str_format_int_grouped(str, value); | ||||
| return std::string(str); | return std::string(str); | ||||
| }; | }; | ||||
| ss << TIP_("Geometry:\n"); | ss << TIP_("Geometry:\n"); | ||||
| for (GeometryComponentType type : component_types) { | for (GeometryComponentType type : component_types) { | ||||
| switch (type) { | switch (type) { | ||||
| case GEO_COMPONENT_TYPE_MESH: { | case GEO_COMPONENT_TYPE_MESH: { | ||||
| const geo_log::GeometryInfoLog::MeshInfo &mesh_info = *value_log.mesh_info; | const geo_log::GeometryInfoLog::MeshInfo &mesh_info = *value_log.mesh_info; | ||||
| char line[256]; | char line[256]; | ||||
| BLI_snprintf(line, | BLI_snprintf(line, | ||||
| sizeof(line), | sizeof(line), | ||||
| TIP_("\u2022 Mesh: %s vertices, %s edges, %s faces"), | TIP_("%s\u2022 Mesh: %s vertices, %s edges, %s faces"), | ||||
| tab_space, | |||||
| to_string(mesh_info.verts_num).c_str(), | to_string(mesh_info.verts_num).c_str(), | ||||
| to_string(mesh_info.edges_num).c_str(), | to_string(mesh_info.edges_num).c_str(), | ||||
| to_string(mesh_info.faces_num).c_str()); | to_string(mesh_info.faces_num).c_str()); | ||||
| ss << line; | ss << line; | ||||
| break; | break; | ||||
| } | } | ||||
| case GEO_COMPONENT_TYPE_POINT_CLOUD: { | case GEO_COMPONENT_TYPE_POINT_CLOUD: { | ||||
| const geo_log::GeometryInfoLog::PointCloudInfo &pointcloud_info = | const geo_log::GeometryInfoLog::PointCloudInfo &pointcloud_info = | ||||
| *value_log.pointcloud_info; | *value_log.pointcloud_info; | ||||
| char line[256]; | char line[256]; | ||||
| BLI_snprintf(line, | BLI_snprintf(line, | ||||
| sizeof(line), | sizeof(line), | ||||
| TIP_("\u2022 Point Cloud: %s points"), | TIP_("%s\u2022 Point Cloud: %s points"), | ||||
| tab_space, | |||||
| to_string(pointcloud_info.points_num).c_str()); | to_string(pointcloud_info.points_num).c_str()); | ||||
| ss << line; | ss << line; | ||||
| break; | break; | ||||
| } | } | ||||
| case GEO_COMPONENT_TYPE_CURVE: { | case GEO_COMPONENT_TYPE_CURVE: { | ||||
| const geo_log::GeometryInfoLog::CurveInfo &curve_info = *value_log.curve_info; | const geo_log::GeometryInfoLog::CurveInfo &curve_info = *value_log.curve_info; | ||||
| char line[256]; | char line[256]; | ||||
| BLI_snprintf(line, | BLI_snprintf(line, | ||||
| sizeof(line), | sizeof(line), | ||||
| TIP_("\u2022 Curve: %s points, %s splines"), | TIP_("\u2022 Curve: %s points, %s splines"), | ||||
| to_string(curve_info.points_num).c_str(), | to_string(curve_info.points_num).c_str(), | ||||
| to_string(curve_info.splines_num).c_str()); | to_string(curve_info.splines_num).c_str()); | ||||
| ss << line; | ss << line; | ||||
| break; | break; | ||||
| } | } | ||||
| case GEO_COMPONENT_TYPE_INSTANCES: { | case GEO_COMPONENT_TYPE_INSTANCES: { | ||||
| const geo_log::GeometryInfoLog::InstancesInfo &instances_info = *value_log.instances_info; | const geo_log::GeometryInfoLog::InstancesInfo &instances_info = *value_log.instances_info; | ||||
| char line[256]; | char line[256]; | ||||
| BLI_snprintf(line, | BLI_snprintf(line, | ||||
| sizeof(line), | sizeof(line), | ||||
| TIP_("\u2022 Instances: %s"), | TIP_("%s\u2022 Instances: %s"), | ||||
| tab_space, | |||||
| to_string(instances_info.instances_num).c_str()); | to_string(instances_info.instances_num).c_str()); | ||||
| ss << line; | ss << line; | ||||
| break; | break; | ||||
| } | } | ||||
| case GEO_COMPONENT_TYPE_VOLUME: { | case GEO_COMPONENT_TYPE_VOLUME: { | ||||
| ss << TIP_("\u2022 Volume"); | ss << TIP_("\u2022 Volume"); | ||||
| break; | break; | ||||
| } | } | ||||
| case GEO_COMPONENT_TYPE_EDIT: { | case GEO_COMPONENT_TYPE_EDIT: { | ||||
| if (value_log.edit_data_info.has_value()) { | if (value_log.edit_data_info.has_value()) { | ||||
| const geo_log::GeometryInfoLog::EditDataInfo &edit_info = *value_log.edit_data_info; | const geo_log::GeometryInfoLog::EditDataInfo &edit_info = *value_log.edit_data_info; | ||||
| char line[256]; | char line[256]; | ||||
| BLI_snprintf(line, | BLI_snprintf(line, | ||||
| sizeof(line), | sizeof(line), | ||||
| TIP_("\u2022 Edit Curves: %s, %s"), | TIP_("%s\u2022 Edit Curves: %s, %s"), | ||||
| tab_space, | |||||
| edit_info.has_deformed_positions ? TIP_("positions") : TIP_("no positions"), | edit_info.has_deformed_positions ? TIP_("positions") : TIP_("no positions"), | ||||
| edit_info.has_deform_matrices ? TIP_("matrices") : TIP_("no matrices")); | edit_info.has_deform_matrices ? TIP_("matrices") : TIP_("no matrices")); | ||||
| ss << line; | ss << line; | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (type != component_types.last()) { | if (type != component_types.last()) { | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| using namespace blender::nodes::geo_eval_log; | using namespace blender::nodes::geo_eval_log; | ||||
| if (socket.typeinfo->base_cpp_type == nullptr) { | if (socket.typeinfo->base_cpp_type == nullptr) { | ||||
| return std::nullopt; | return std::nullopt; | ||||
| } | } | ||||
| tree_draw_ctx.geo_tree_log->ensure_socket_values(); | tree_draw_ctx.geo_tree_log->ensure_socket_values(); | ||||
| ValueLog *value_log = tree_draw_ctx.geo_tree_log->find_socket_value_log(socket); | |||||
| std::stringstream ss; | std::stringstream ss; | ||||
| auto log_socket_value = [&](const ValueLog *value_log, const char *tab_space) -> bool { | |||||
| if (const geo_log::GenericValueLog *generic_value_log = | if (const geo_log::GenericValueLog *generic_value_log = | ||||
| dynamic_cast<const geo_log::GenericValueLog *>(value_log)) { | dynamic_cast<const geo_log::GenericValueLog *>(value_log)) { | ||||
| create_inspection_string_for_generic_value(socket, generic_value_log->value, ss); | create_inspection_string_for_generic_value(socket, generic_value_log->value, ss); | ||||
| return true; | |||||
| } | } | ||||
| else if (const geo_log::FieldInfoLog *gfield_value_log = | if (const geo_log::FieldInfoLog *gfield_value_log = | ||||
| dynamic_cast<const geo_log::FieldInfoLog *>(value_log)) { | dynamic_cast<const geo_log::FieldInfoLog *>(value_log)) { | ||||
| create_inspection_string_for_field_info(socket, *gfield_value_log, ss); | create_inspection_string_for_field_info(socket, *gfield_value_log, ss); | ||||
| return true; | |||||
| } | } | ||||
| else if (const geo_log::GeometryInfoLog *geo_value_log = | if (const geo_log::GeometryInfoLog *geo_value_log = | ||||
| dynamic_cast<const geo_log::GeometryInfoLog *>(value_log)) { | dynamic_cast<const geo_log::GeometryInfoLog *>(value_log)) { | ||||
| create_inspection_string_for_geometry_info(*geo_value_log, ss); | create_inspection_string_for_geometry_info(*geo_value_log, ss, tab_space); | ||||
| return true; | |||||
| } | |||||
| return false; | |||||
| }; | |||||
| bool after_log = false; | |||||
| if (socket.is_multi_input()) { | |||||
| const Vector<ValueLog *> value_logs = multi_input_socket_value_logs( | |||||
| *tree_draw_ctx.geo_tree_log, socket); | |||||
| if (!value_logs.is_empty()) { | |||||
| if (value_logs.size() >= 1) { | |||||
| ss << "1. "; | |||||
| const bool is_empty_line = !log_socket_value(value_logs.first(), " "); | |||||
| if (is_empty_line) { | |||||
| ss << "Empty Input"; | |||||
| } | |||||
| after_log = true; | |||||
| } | |||||
| for (const int index : value_logs.index_range().drop_front(1)) { | |||||
| ss << ".\n" << index + 1 << ". "; | |||||
| const ValueLog *value_log = value_logs[index]; | |||||
| const bool is_empty_line = !log_socket_value(value_log, " "); | |||||
| if (is_empty_line) { | |||||
| ss << "Empty Input"; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| else { | |||||
| after_log = true; | |||||
| ValueLog *value_log = tree_draw_ctx.geo_tree_log->find_socket_value_log(socket); | |||||
| log_socket_value(value_log, ""); | |||||
| } | } | ||||
| if (const nodes::decl::Geometry *socket_decl = dynamic_cast<const nodes::decl::Geometry *>( | if (const nodes::decl::Geometry *socket_decl = dynamic_cast<const nodes::decl::Geometry *>( | ||||
| socket.runtime->declaration)) { | socket.runtime->declaration)) { | ||||
| const bool after_log = value_log != nullptr; | |||||
| create_inspection_string_for_geometry_socket(ss, socket_decl, after_log); | create_inspection_string_for_geometry_socket(ss, socket_decl, after_log); | ||||
| } | } | ||||
| std::string str = ss.str(); | std::string str = ss.str(); | ||||
| if (str.empty()) { | if (str.empty()) { | ||||
| return std::nullopt; | return std::nullopt; | ||||
| } | } | ||||
| return str; | return str; | ||||
| ▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | node_socket_draw(sock, | ||||
| location.x, | location.x, | ||||
| location.y, | location.y, | ||||
| pos_id, | pos_id, | ||||
| col_id, | col_id, | ||||
| shape_id, | shape_id, | ||||
| size_id, | size_id, | ||||
| outline_col_id); | outline_col_id); | ||||
| if (!node_socket_has_tooltip(ntree, sock)) { | if (node_socket_has_tooltip(ntree, sock)) { | ||||
| return; | node_socket_tooltip_set(block, sock.index_in_tree(), location, float2{size, size}); | ||||
| } | } | ||||
| /* 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, | |||||
| UI_BTYPE_BUT, | |||||
| 0, | |||||
| ICON_NONE, | |||||
| location.x - size / 2.0f, | |||||
| location.y - size / 2.0f, | |||||
| size, | |||||
| size, | |||||
| nullptr, | |||||
| 0, | |||||
| 0, | |||||
| 0, | |||||
| 0, | |||||
| nullptr); | |||||
| UI_but_func_tooltip_set( | |||||
| but, | |||||
| [](bContext *C, void *argN, const char * /*tip*/) { | |||||
| const SpaceNode &snode = *CTX_wm_space_node(C); | |||||
| const bNodeTree &ntree = *snode.edittree; | |||||
| const int index_in_tree = POINTER_AS_INT(argN); | |||||
| ntree.ensure_topology_cache(); | |||||
| return node_socket_get_tooltip(&snode, ntree, *ntree.all_sockets()[index_in_tree]); | |||||
| }, | |||||
| POINTER_FROM_INT(sock.index_in_tree()), | |||||
| nullptr); | |||||
| /* Disable the button so that clicks on it are ignored the link operator still works. */ | |||||
| UI_but_flag_enable(but, UI_BUT_DISABLED); | |||||
| UI_block_emboss_set(&block, old_emboss); | |||||
| } | } | ||||
| void node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[4], float scale) | void node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[4], float scale) | ||||
| { | { | ||||
| const float size = NODE_SOCKSIZE_DRAW_MULIPLIER * NODE_SOCKSIZE * scale; | const float size = NODE_SOCKSIZE_DRAW_MULIPLIER * NODE_SOCKSIZE * scale; | ||||
| rcti draw_rect = *rect; | rcti draw_rect = *rect; | ||||
| float outline_color[4] = {0}; | float outline_color[4] = {0}; | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | for (const bNodeSocket *sock : node.input_sockets()) { | ||||
| if (select_all || (sock->flag & SELECT)) { | if (select_all || (sock->flag & SELECT)) { | ||||
| if (!(sock->flag & SOCK_MULTI_INPUT)) { | if (!(sock->flag & SOCK_MULTI_INPUT)) { | ||||
| /* Don't add multi-input sockets here since they are drawn in a different batch. */ | /* Don't add multi-input sockets here since they are drawn in a different batch. */ | ||||
| selected_input_len++; | selected_input_len++; | ||||
| } | } | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* Don't draw multi-input sockets here since they are drawn in a different batch. */ | /* Don't draw multi-input sockets here since they are drawn in a different batch. */ | ||||
| if (sock->flag & SOCK_MULTI_INPUT) { | if (sock->is_multi_input()) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| node_socket_draw_nested(C, | node_socket_draw_nested(C, | ||||
| ntree, | ntree, | ||||
| socket_locations, | socket_locations, | ||||
| node_ptr, | node_ptr, | ||||
| block, | block, | ||||
| ▲ Show 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | static void node_draw_sockets(const View2D &v2d, | ||||
| GPU_blend(GPU_BLEND_NONE); | GPU_blend(GPU_BLEND_NONE); | ||||
| /* Draw multi-input sockets after the others because they are drawn with `UI_draw_roundbox` | /* Draw multi-input sockets after the others because they are drawn with `UI_draw_roundbox` | ||||
| * rather than with `GL_POINT`. */ | * rather than with `GL_POINT`. */ | ||||
| for (const bNodeSocket *socket : node.input_sockets()) { | for (const bNodeSocket *socket : node.input_sockets()) { | ||||
| if (!socket->is_visible()) { | if (!socket->is_visible()) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (!(socket->flag & SOCK_MULTI_INPUT)) { | if (!(socket->is_multi_input())) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| const bool is_node_hidden = (node.flag & NODE_HIDDEN); | const bool is_node_hidden = (node.flag & NODE_HIDDEN); | ||||
| const float width = 0.5f * socket_draw_size; | const float width = 0.5f * socket_draw_size; | ||||
| float height = is_node_hidden ? width : node_socket_calculate_height(*socket) - width; | float height = is_node_hidden ? width : node_socket_calculate_height(*socket) - width; | ||||
| float color[4]; | float color[4]; | ||||
| float outline_color[4]; | float outline_color[4]; | ||||
| node_socket_color_get(C, ntree, node_ptr, *socket, color); | node_socket_color_get(C, ntree, node_ptr, *socket, color); | ||||
| node_socket_outline_color_get(socket->flag & SELECT, socket->type, outline_color); | node_socket_outline_color_get(socket->flag & SELECT, socket->type, outline_color); | ||||
| const float2 location = socket_locations[socket->index_in_tree()]; | const int index_in_tree = socket->index_in_tree(); | ||||
| node_socket_draw_multi_input(color, outline_color, width, height, location); | const float2 location = socket_locations[index_in_tree]; | ||||
| const float2 draw_size{width, height}; | |||||
| const float2 tooltip_size{scale, height * 2.0f - socket_draw_size + scale}; | |||||
| const bool has_tooltip = node_socket_has_tooltip(ntree, *socket); | |||||
| node_socket_draw_multi_input(block, | |||||
| index_in_tree, | |||||
| location, | |||||
| draw_size, | |||||
| color, | |||||
| outline_color, | |||||
| tooltip_size, | |||||
| has_tooltip); | |||||
| } | } | ||||
| } | } | ||||
| static int node_error_type_to_icon(const geo_log::NodeWarningType type) | static int node_error_type_to_icon(const geo_log::NodeWarningType type) | ||||
| { | { | ||||
| switch (type) { | switch (type) { | ||||
| case geo_log::NodeWarningType::Error: | case geo_log::NodeWarningType::Error: | ||||
| return ICON_ERROR; | return ICON_ERROR; | ||||
| ▲ Show 20 Lines • Show All 1,735 Lines • Show Last 20 Lines | |||||