Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_node/node_draw.cc')
-rw-r--r--source/blender/editors/space_node/node_draw.cc502
1 files changed, 298 insertions, 204 deletions
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index 97655080192..a6496294f96 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -71,8 +71,10 @@
#include "ED_gpencil.h"
#include "ED_node.h"
+#include "ED_screen.h"
#include "ED_space_api.h"
+#include "UI_interface.hh"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -728,7 +730,7 @@ static void node_draw_mute_line(const View2D *v2d, const SpaceNode *snode, const
GPU_blend(GPU_BLEND_ALPHA);
LISTBASE_FOREACH (const bNodeLink *, link, &node->internal_links) {
- node_draw_link_bezier(v2d, snode, link, TH_REDALERT, TH_REDALERT, -1);
+ node_draw_link_bezier(v2d, snode, link, TH_WIRE_INNER, TH_WIRE_INNER, TH_WIRE);
}
GPU_blend(GPU_BLEND_NONE);
@@ -807,12 +809,10 @@ static void node_socket_outline_color_get(const bool selected,
float r_outline_color[4])
{
if (selected) {
- UI_GetThemeColor4fv(TH_TEXT_HI, r_outline_color);
- r_outline_color[3] = 0.9f;
+ UI_GetThemeColor4fv(TH_ACTIVE, r_outline_color);
}
else {
- copy_v4_fl(r_outline_color, 0.0f);
- r_outline_color[3] = 0.6f;
+ UI_GetThemeColor4fv(TH_WIRE, r_outline_color);
}
/* Until there is a better place for per socket color,
@@ -832,11 +832,6 @@ void node_socket_color_get(
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
sock->typeinfo->draw_color(C, &ptr, node_ptr, r_color);
-
- bNode *node = (bNode *)node_ptr->data;
- if (node->flag & NODE_MUTED) {
- r_color[3] *= 0.25f;
- }
}
struct SocketTooltipData {
@@ -854,60 +849,7 @@ static void create_inspection_string_for_generic_value(const geo_log::GenericVal
const GPointer value = value_log.value();
const CPPType &type = *value.type();
- if (const FieldCPPType *field_type = dynamic_cast<const FieldCPPType *>(&type)) {
- const CPPType &base_type = field_type->field_type();
- BUFFER_FOR_CPP_TYPE_VALUE(base_type, buffer);
- const GField &field = field_type->get_gfield(value.get());
- if (field.node().depends_on_input()) {
- if (base_type.is<int>()) {
- ss << TIP_("Integer Field");
- }
- else if (base_type.is<float>()) {
- ss << TIP_("Float Field");
- }
- else if (base_type.is<blender::float3>()) {
- ss << TIP_("Vector Field");
- }
- else if (base_type.is<bool>()) {
- ss << TIP_("Boolean Field");
- }
- else if (base_type.is<std::string>()) {
- ss << TIP_("String Field");
- }
- ss << TIP_(" based on:\n");
-
- /* Use vector set to deduplicate inputs. */
- VectorSet<std::reference_wrapper<const FieldInput>> field_inputs;
- field.node().foreach_field_input(
- [&](const FieldInput &field_input) { field_inputs.add(field_input); });
- for (const FieldInput &field_input : field_inputs) {
- ss << "\u2022 " << field_input.socket_inspection_name();
- if (field_input != field_inputs.as_span().last().get()) {
- ss << ".\n";
- }
- }
- }
- else {
- blender::fn::evaluate_constant_field(field, buffer);
- if (base_type.is<int>()) {
- ss << *(int *)buffer << TIP_(" (Integer)");
- }
- else if (base_type.is<float>()) {
- ss << *(float *)buffer << TIP_(" (Float)");
- }
- else if (base_type.is<blender::float3>()) {
- ss << *(blender::float3 *)buffer << TIP_(" (Vector)");
- }
- else if (base_type.is<bool>()) {
- ss << ((*(bool *)buffer) ? TIP_("True") : TIP_("False")) << TIP_(" (Boolean)");
- }
- else if (base_type.is<std::string>()) {
- ss << *(std::string *)buffer << TIP_(" (String)");
- }
- base_type.destruct(buffer);
- }
- }
- else if (type.is<Object *>()) {
+ if (type.is<Object *>()) {
id_to_inspection_string((ID *)*value.get<Object *>(), ID_OB);
}
else if (type.is<Material *>()) {
@@ -924,6 +866,71 @@ static void create_inspection_string_for_generic_value(const geo_log::GenericVal
}
}
+static void create_inspection_string_for_gfield(const geo_log::GFieldValueLog &value_log,
+ std::stringstream &ss)
+{
+ const CPPType &type = value_log.type();
+ const GField &field = value_log.field();
+ const Span<std::string> input_tooltips = value_log.input_tooltips();
+
+ if (input_tooltips.is_empty()) {
+ if (field) {
+ BUFFER_FOR_CPP_TYPE_VALUE(type, buffer);
+ blender::fn::evaluate_constant_field(field, buffer);
+ if (type.is<int>()) {
+ ss << *(int *)buffer << TIP_(" (Integer)");
+ }
+ else if (type.is<float>()) {
+ ss << *(float *)buffer << TIP_(" (Float)");
+ }
+ else if (type.is<blender::float3>()) {
+ ss << *(blender::float3 *)buffer << TIP_(" (Vector)");
+ }
+ else if (type.is<bool>()) {
+ ss << ((*(bool *)buffer) ? TIP_("True") : TIP_("False")) << TIP_(" (Boolean)");
+ }
+ else if (type.is<std::string>()) {
+ ss << *(std::string *)buffer << TIP_(" (String)");
+ }
+ type.destruct(buffer);
+ }
+ else {
+ /* Constant values should always be logged. */
+ BLI_assert_unreachable();
+ ss << "Value has not been logged";
+ }
+ }
+ else {
+ if (type.is<int>()) {
+ ss << TIP_("Integer field");
+ }
+ else if (type.is<float>()) {
+ ss << TIP_("Float field");
+ }
+ else if (type.is<blender::float3>()) {
+ ss << TIP_("Vector field");
+ }
+ else if (type.is<bool>()) {
+ ss << TIP_("Boolean field");
+ }
+ else if (type.is<std::string>()) {
+ ss << TIP_("String field");
+ }
+ else if (type.is<blender::ColorGeometry4f>()) {
+ ss << TIP_("Color field");
+ }
+ ss << TIP_(" based on:\n");
+
+ for (const int i : input_tooltips.index_range()) {
+ const blender::StringRef tooltip = input_tooltips[i];
+ ss << "\u2022 " << tooltip;
+ if (i < input_tooltips.size() - 1) {
+ ss << ".\n";
+ }
+ }
+ }
+}
+
static void create_inspection_string_for_geometry(const geo_log::GeometryValueLog &value_log,
std::stringstream &ss)
{
@@ -1015,6 +1022,10 @@ static std::optional<std::string> create_socket_inspection_string(bContext *C,
dynamic_cast<const geo_log::GenericValueLog *>(value_log)) {
create_inspection_string_for_generic_value(*generic_value_log, ss);
}
+ if (const geo_log::GFieldValueLog *gfield_value_log =
+ dynamic_cast<const geo_log::GFieldValueLog *>(value_log)) {
+ create_inspection_string_for_gfield(*gfield_value_log, ss);
+ }
else if (const geo_log::GeometryValueLog *geo_value_log =
dynamic_cast<const geo_log::GeometryValueLog *>(value_log)) {
create_inspection_string_for_geometry(*geo_value_log, ss);
@@ -1156,7 +1167,7 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE);
- immUniform1f("outline_scale", 0.7f);
+ immUniform1f("outline_scale", 1.0f);
immUniform2f("ViewportSize", -1.0f, -1.0f);
/* Single point. */
@@ -1301,7 +1312,7 @@ void node_draw_sockets(const View2D *v2d,
GPU_blend(GPU_BLEND_ALPHA);
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE);
- immUniform1f("outline_scale", 0.7f);
+ immUniform1f("outline_scale", 1.0f);
immUniform2f("ViewportSize", -1.0f, -1.0f);
/* Set handle size. */
@@ -1595,24 +1606,13 @@ static void node_draw_basis(const bContext *C,
/* Shadow. */
node_draw_shadow(snode, node, BASIS_RAD, 1.0f);
+ rctf *rct = &node->totr;
float color[4];
int color_id = node_get_colorid(node);
- if (node->flag & NODE_MUTED) {
- /* Muted nodes are semi-transparent and colorless. */
- UI_GetThemeColor3fv(TH_NODE, color);
- color[3] = 0.25f;
- }
- else {
- /* Opaque headers for regular nodes. */
- UI_GetThemeColor3fv(color_id, color);
- color[3] = 1.0f;
- }
GPU_line_width(1.0f);
- rctf *rct = &node->totr;
- UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
-
+ /* Header. */
{
const rctf rect = {
rct->xmin,
@@ -1620,7 +1620,19 @@ static void node_draw_basis(const bContext *C,
rct->ymax - NODE_DY,
rct->ymax,
};
- UI_draw_roundbox_aa(&rect, true, BASIS_RAD, color);
+
+ float color_header[4];
+
+ /* Muted nodes get a mix of the background with the node color. */
+ if (node->flag & NODE_MUTED) {
+ UI_GetThemeColorBlend4f(TH_BACK, color_id, 0.1f, color_header);
+ }
+ else {
+ UI_GetThemeColorBlend4f(TH_NODE, color_id, 0.4f, color_header);
+ }
+
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
+ UI_draw_roundbox_4fv(&rect, true, BASIS_RAD, color_header);
}
/* Show/hide icons. */
@@ -1703,31 +1715,28 @@ static void node_draw_basis(const bContext *C,
UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color);
}
- /* Open/close entirely. */
+ /* Collapse/expand icon. */
{
- int but_size = U.widget_unit * 0.8f;
- /* XXX button uses a custom triangle draw below, so make it invisible without icon. */
+ const int but_size = U.widget_unit * 0.8f;
UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
- uiBut *but = uiDefBut(node->block,
- UI_BTYPE_BUT_TOGGLE,
- 0,
- "",
- rct->xmin + 0.35f * U.widget_unit,
- rct->ymax - NODE_DY / 2.2f - but_size / 2,
- but_size,
- but_size,
- nullptr,
- 0,
- 0,
- 0,
- 0,
- "");
+
+ uiBut *but = uiDefIconBut(node->block,
+ UI_BTYPE_BUT_TOGGLE,
+ 0,
+ ICON_DOWNARROW_HLT,
+ rct->xmin + (NODE_MARGIN_X / 3),
+ rct->ymax - NODE_DY / 2.2f - but_size / 2,
+ but_size,
+ but_size,
+ nullptr,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ "");
+
UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
UI_block_emboss_set(node->block, UI_EMBOSS);
-
- UI_GetThemeColor4fv(TH_TEXT, color);
- /* Custom draw function for this button. */
- UI_draw_icon_tri(rct->xmin + 0.65f * U.widget_unit, rct->ymax - NODE_DY / 2.2f, 'v', color);
}
char showname[128];
@@ -1737,7 +1746,7 @@ static void node_draw_basis(const bContext *C,
UI_BTYPE_LABEL,
0,
showname,
- (int)(rct->xmin + NODE_MARGIN_X),
+ (int)(rct->xmin + NODE_MARGIN_X + 0.4f),
(int)(rct->ymax - NODE_DY),
(short)(iconofs - rct->xmin - (18.0f * U.dpi_fac)),
(short)NODE_DY,
@@ -1751,49 +1760,96 @@ static void node_draw_basis(const bContext *C,
UI_but_flag_enable(but, UI_BUT_INACTIVE);
}
+ /* Wire across the node when muted/disabled. */
+ if (node->flag & NODE_MUTED) {
+ node_draw_mute_line(v2d, snode, node);
+ }
+
/* Body. */
- if (nodeTypeUndefined(node)) {
+ const float outline_width = 1.0f;
+ {
/* Use warning color to indicate undefined types. */
- UI_GetThemeColor4fv(TH_REDALERT, color);
- }
- else if (node->flag & NODE_MUTED) {
- /* Muted nodes are semi-transparent and colorless. */
- UI_GetThemeColor4fv(TH_NODE, color);
- }
- else if (node->flag & NODE_CUSTOM_COLOR) {
- rgba_float_args_set(color, node->color[0], node->color[1], node->color[2], 1.0f);
- }
- else {
- UI_GetThemeColor4fv(TH_NODE, color);
- }
+ if (nodeTypeUndefined(node)) {
+ UI_GetThemeColorBlend4f(TH_REDALERT, TH_NODE, 0.4f, color);
+ }
+ /* Muted nodes get a mix of the background with the node color. */
+ else if (node->flag & NODE_MUTED) {
+ UI_GetThemeColorBlend4f(TH_BACK, TH_NODE, 0.2f, color);
+ }
+ else if (node->flag & NODE_CUSTOM_COLOR) {
+ rgba_float_args_set(color, node->color[0], node->color[1], node->color[2], 1.0f);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_NODE, color);
+ }
- if (node->flag & NODE_MUTED) {
- color[3] = 0.5f;
+ /* Draw selected nodes fully opaque. */
+ if (node->flag & SELECT) {
+ color[3] = 1.0f;
+ }
+
+ /* Draw muted nodes slightly transparent so the wires inside are visible. */
+ if (node->flag & NODE_MUTED) {
+ color[3] -= 0.2f;
+ }
+
+ const rctf rect = {
+ rct->xmin,
+ rct->xmax,
+ rct->ymin,
+ rct->ymax - (NODE_DY + outline_width),
+ };
+
+ UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
+ UI_draw_roundbox_4fv(&rect, true, BASIS_RAD, color);
}
+ /* Header underline. */
{
- UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
+ float color_underline[4];
+
+ if (node->flag & NODE_MUTED) {
+ UI_GetThemeColor4fv(TH_WIRE, color_underline);
+ }
+ else {
+ UI_GetThemeColorBlend4f(TH_BACK, color_id, 0.2f, color_underline);
+ }
+
const rctf rect = {
rct->xmin,
rct->xmax,
- rct->ymin,
+ rct->ymax - (NODE_DY + outline_width),
rct->ymax - NODE_DY,
};
- UI_draw_roundbox_aa(&rect, true, BASIS_RAD, color);
+
+ UI_draw_roundbox_corner_set(UI_CNR_NONE);
+ UI_draw_roundbox_4fv(&rect, true, 0.0f, color_underline);
}
- /* Outline active and selected emphasis. */
- if (node->flag & SELECT) {
- UI_GetThemeColorShadeAlpha4fv(
- (node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
+ /* Outline. */
+ {
+ const rctf rect = {
+ rct->xmin - outline_width,
+ rct->xmax + outline_width,
+ rct->ymin - outline_width,
+ rct->ymax + outline_width,
+ };
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(rct, false, BASIS_RAD, color);
- }
+ /* Color the outline according to active, selected, or undefined status. */
+ float color_outline[4];
- /* Disable lines. */
- if (node->flag & NODE_MUTED) {
- node_draw_mute_line(v2d, snode, node);
+ if (node->flag & SELECT) {
+ UI_GetThemeColor4fv((node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, color_outline);
+ }
+ else if (nodeTypeUndefined(node)) {
+ UI_GetThemeColor4fv(TH_REDALERT, color_outline);
+ }
+ else {
+ UI_GetThemeColorBlendShade4fv(TH_BACK, TH_NODE, 0.4f, -20, color_outline);
+ }
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv(&rect, false, BASIS_RAD, color_outline);
}
node_draw_sockets(v2d, C, ntree, node, true, false);
@@ -1828,46 +1884,45 @@ static void node_draw_hidden(const bContext *C,
float scale;
UI_view2d_scale_get(v2d, &scale, nullptr);
+ const int color_id = node_get_colorid(node);
+
/* Shadow. */
node_draw_shadow(snode, node, hiddenrad, 1.0f);
- /* Body. */
- float color[4];
- int color_id = node_get_colorid(node);
+ /* Wire across the node when muted/disabled. */
if (node->flag & NODE_MUTED) {
- /* Muted nodes are semi-transparent and colorless. */
- UI_GetThemeColor4fv(TH_NODE, color);
- color[3] = 0.25f;
- }
- else {
- UI_GetThemeColor4fv(color_id, color);
+ node_draw_mute_line(v2d, snode, node);
}
- UI_draw_roundbox_aa(rct, true, hiddenrad, color);
-
- /* Outline active and selected emphasis. */
- if (node->flag & SELECT) {
- UI_GetThemeColorShadeAlpha4fv(
- (node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
-
- UI_draw_roundbox_aa(rct, false, hiddenrad, color);
- }
+ /* Body. */
+ float color[4];
+ {
+ if (nodeTypeUndefined(node)) {
+ /* Use warning color to indicate undefined types. */
+ UI_GetThemeColorBlend4f(TH_REDALERT, TH_NODE, 0.4f, color);
+ }
+ else if (node->flag & NODE_MUTED) {
+ /* Muted nodes get a mix of the background with the node color. */
+ UI_GetThemeColorBlendShade4fv(TH_BACK, color_id, 0.1f, 0, color);
+ }
+ else if (node->flag & NODE_CUSTOM_COLOR) {
+ rgba_float_args_set(color, node->color[0], node->color[1], node->color[2], 1.0f);
+ }
+ else {
+ UI_GetThemeColorBlend4f(TH_NODE, color_id, 0.4f, color);
+ }
- /* Custom color inline. */
- if (node->flag & NODE_CUSTOM_COLOR) {
- GPU_blend(GPU_BLEND_ALPHA);
- GPU_line_smooth(true);
+ /* Draw selected nodes fully opaque. */
+ if (node->flag & SELECT) {
+ color[3] = 1.0f;
+ }
- const rctf rect = {
- rct->xmin + 1,
- rct->xmax - 1,
- rct->ymin + 1,
- rct->ymax - 1,
- };
- UI_draw_roundbox_3fv_alpha(&rect, false, hiddenrad, node->color, 1.0f);
+ /* Draw muted nodes slightly transparent so the wires inside are visible. */
+ if (node->flag & NODE_MUTED) {
+ color[3] -= 0.2f;
+ }
- GPU_line_smooth(false);
- GPU_blend(GPU_BLEND_NONE);
+ UI_draw_roundbox_4fv(rct, true, hiddenrad, color);
}
/* Title. */
@@ -1878,36 +1933,28 @@ static void node_draw_hidden(const bContext *C,
UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color);
}
- /* Open / collapse icon. */
+ /* Collapse/expand icon. */
{
- int but_size = U.widget_unit * 0.8f;
- /* XXX button uses a custom triangle draw below, so make it invisible without icon */
+ const int but_size = U.widget_unit * 1.0f;
UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
- uiBut *but = uiDefBut(node->block,
- UI_BTYPE_BUT_TOGGLE,
- 0,
- "",
- rct->xmin + 0.35f * U.widget_unit,
- centy - but_size / 2,
- but_size,
- but_size,
- nullptr,
- 0,
- 0,
- 0,
- 0,
- "");
- UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
- UI_block_emboss_set(node->block, UI_EMBOSS);
- UI_GetThemeColor4fv(TH_TEXT, color);
- /* Custom draw function for this button. */
- UI_draw_icon_tri(rct->xmin + 0.65f * U.widget_unit, centy, 'h', color);
- }
+ uiBut *but = uiDefIconBut(node->block,
+ UI_BTYPE_BUT_TOGGLE,
+ 0,
+ ICON_RIGHTARROW,
+ rct->xmin + (NODE_MARGIN_X / 3),
+ centy - but_size / 2,
+ but_size,
+ but_size,
+ nullptr,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ "");
- /* Disable lines. */
- if (node->flag & NODE_MUTED) {
- node_draw_mute_line(v2d, snode, node);
+ UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
+ UI_block_emboss_set(node->block, UI_EMBOSS);
}
char showname[128];
@@ -1927,15 +1974,44 @@ static void node_draw_hidden(const bContext *C,
0,
0,
"");
+
+ /* Outline. */
+ {
+ const float outline_width = 1.0f;
+ const rctf rect = {
+ rct->xmin - outline_width,
+ rct->xmax + outline_width,
+ rct->ymin - outline_width,
+ rct->ymax + outline_width,
+ };
+
+ /* Color the outline according to active, selected, or undefined status. */
+ float color_outline[4];
+
+ if (node->flag & SELECT) {
+ UI_GetThemeColor4fv((node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, color_outline);
+ }
+ else if (nodeTypeUndefined(node)) {
+ UI_GetThemeColor4fv(TH_REDALERT, color_outline);
+ }
+ else {
+ UI_GetThemeColorBlendShade4fv(TH_BACK, TH_NODE, 0.4f, -20, color_outline);
+ }
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv(&rect, false, hiddenrad, color_outline);
+ }
+
if (node->flag & NODE_MUTED) {
UI_but_flag_enable(but, UI_BUT_INACTIVE);
}
/* Scale widget thing. */
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPU_blend(GPU_BLEND_ALPHA);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColorShade(color_id, -10);
+ immUniformThemeColorShadeAlpha(TH_TEXT, -40, -180);
float dx = 10.0f;
immBegin(GPU_PRIM_LINES, 4);
@@ -1946,7 +2022,7 @@ static void node_draw_hidden(const bContext *C,
immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy + 4.0f);
immEnd();
- immUniformThemeColorShade(color_id, 30);
+ immUniformThemeColorShadeAlpha(TH_TEXT, 0, -180);
dx -= snode->runtime->aspect;
immBegin(GPU_PRIM_LINES, 4);
@@ -1958,6 +2034,7 @@ static void node_draw_hidden(const bContext *C,
immEnd();
immUnbindProgram();
+ GPU_blend(GPU_BLEND_NONE);
node_draw_sockets(v2d, C, ntree, node, true, false);
@@ -2142,15 +2219,34 @@ void node_draw_nodetree(const bContext *C,
}
}
-/* Draw tree path info in lower left corner. */
-static void draw_tree_path(SpaceNode *snode)
+/* Draw the breadcrumb on the bottom of the editor. */
+static void draw_tree_path(const bContext &C, ARegion &region)
{
- char info[256];
+ using namespace blender;
+
+ GPU_matrix_push_projection();
+ wmOrtho2_region_pixelspace(&region);
+
+ const rcti *rect = ED_region_visible_rect(&region);
+
+ const uiStyle *style = UI_style_get_dpi();
+ const float padding_x = 16 * UI_DPI_FAC;
+ const int x = rect->xmin + padding_x;
+ const int y = region.winy - UI_UNIT_Y * 0.6f;
+ const int width = BLI_rcti_size_x(rect) - 2 * padding_x;
- ED_node_tree_path_get_fixedbuf(snode, info, sizeof(info));
+ uiBlock *block = UI_block_begin(&C, &region, __func__, UI_EMBOSS_NONE);
+ uiLayout *layout = UI_block_layout(
+ block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, width, 1, 0, style);
- UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
- BLF_draw_default(1.5f * UI_UNIT_X, 1.5f * UI_UNIT_Y, 0.0f, info, sizeof(info));
+ Vector<ui::ContextPathItem> context_path = ed::space_node::context_path_for_space_node(C);
+ ui::template_breadcrumbs(*layout, context_path);
+
+ UI_block_layout_resolve(block, nullptr, nullptr);
+ UI_block_end(&C, block);
+ UI_block_draw(&C, block);
+
+ GPU_matrix_pop_projection();
}
static void snode_setup_v2d(SpaceNode *snode, ARegion *region, const float center[2])
@@ -2227,8 +2323,6 @@ void node_draw_space(const bContext *C, ARegion *region)
snode->runtime->cursor[0] /= UI_DPI_FAC;
snode->runtime->cursor[1] /= UI_DPI_FAC;
- int grid_levels = UI_GetThemeValueType(TH_NODE_GRID_LEVELS, SPACE_NODE);
-
ED_region_draw_cb_draw(C, region, REGION_DRAW_PRE_VIEW);
/* Only set once. */
@@ -2237,6 +2331,9 @@ void node_draw_space(const bContext *C, ARegion *region)
/* Nodes. */
snode_set_context(C);
+ const int grid_levels = UI_GetThemeValueType(TH_NODE_GRID_LEVELS, SPACE_NODE);
+ UI_view2d_dot_grid_draw(v2d, TH_GRID, NODE_GRID_STEP_SIZE, grid_levels);
+
/* Draw parent node trees. */
if (snode->treepath.last) {
bNodeTreePath *path = (bNodeTreePath *)snode->treepath.last;
@@ -2264,9 +2361,6 @@ void node_draw_space(const bContext *C, ARegion *region)
if (ntree) {
snode_setup_v2d(snode, region, center);
- /* Grid. */
- UI_view2d_multi_grid_draw(v2d, TH_GRID, ED_node_grid_size(), NODE_GRID_STEPS, grid_levels);
-
/* Backdrop. */
draw_nodespace_back_pix(C, region, snode, path->parent_key);
@@ -2305,8 +2399,6 @@ void node_draw_space(const bContext *C, ARegion *region)
}
}
else {
- /* Default grid. */
- UI_view2d_multi_grid_draw(v2d, TH_GRID, ED_node_grid_size(), NODE_GRID_STEPS, grid_levels);
/* Backdrop. */
draw_nodespace_back_pix(C, region, snode, NODE_INSTANCE_KEY_NONE);
@@ -2324,8 +2416,10 @@ void node_draw_space(const bContext *C, ARegion *region)
}
}
- /* Tree path info. */
- draw_tree_path(snode);
+ /* Draw context path. */
+ if (snode->edittree) {
+ draw_tree_path(*C, *region);
+ }
/* Scrollers. */
UI_view2d_scrollers_draw(v2d, nullptr);