From 87c011f8bb0ac47280d866a644f12341f428133d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 26 May 2025 15:47:54 +0200 Subject: [PATCH] Nodes: minify value input nodes This removes redundant labels from various input nodes like the Value, Integer and Object node. Design wise, this is mostly straight forward except for two aspects: * Some input nodes some have a gizmo icon. In this case I just added the gizmo icon on the same row. * The checkbox in the Boolean input node should probably still have a label, so I kept that. Implementation wise this adds a new function to socket declarations that allows us to override the draw behavior of individual sockets per node. Pull Request: https://projects.blender.org/blender/blender/pulls/139432 --- source/blender/editors/space_node/drawnode.cc | 76 ++++--------------- .../nodes/NOD_geometry_nodes_gizmos.hh | 5 ++ source/blender/nodes/NOD_node_declaration.hh | 21 +++++ .../composite/nodes/node_composite_rgb.cc | 13 +++- .../composite/nodes/node_composite_value.cc | 10 ++- source/blender/nodes/function/CMakeLists.txt | 2 + .../function/nodes/node_fn_input_bool.cc | 17 +++-- .../function/nodes/node_fn_input_color.cc | 14 ++-- .../nodes/function/nodes/node_fn_input_int.cc | 18 +++-- .../function/nodes/node_fn_input_rotation.cc | 17 ++--- .../function/nodes/node_fn_input_string.cc | 14 ++-- .../function/nodes/node_fn_input_vector.cc | 17 +++-- .../nodes/geometry/nodes/node_geo_image.cc | 17 +++-- .../nodes/node_geo_input_collection.cc | 11 +-- .../geometry/nodes/node_geo_input_material.cc | 11 +-- .../geometry/nodes/node_geo_input_object.cc | 11 +-- .../nodes/intern/geometry_nodes_gizmos.cc | 12 ++- .../blender/nodes/intern/node_declaration.cc | 6 ++ .../nodes/shader/nodes/node_shader_rgb.cc | 13 +++- .../nodes/shader/nodes/node_shader_value.cc | 12 ++- 20 files changed, 175 insertions(+), 142 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 31060ee69a8..019453a72e1 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -89,30 +89,6 @@ static void node_socket_button_label(bContext * /*C*/, /* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */ -static void node_buts_value(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - bNode *node = (bNode *)ptr->data; - /* first output stores value */ - bNodeSocket *output = (bNodeSocket *)node->outputs.first; - PointerRNA sockptr = RNA_pointer_create_discrete(ptr->owner_id, &RNA_NodeSocket, output); - - uiLayout *row = &layout->row(true); - row->prop(&sockptr, "default_value", DEFAULT_FLAGS, "", ICON_NONE); -} - -static void node_buts_rgb(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - bNode *node = (bNode *)ptr->data; - /* first output stores value */ - bNodeSocket *output = (bNodeSocket *)node->outputs.first; - uiLayout *col; - PointerRNA sockptr = RNA_pointer_create_discrete(ptr->owner_id, &RNA_NodeSocket, output); - - col = &layout->column(false); - uiTemplateColorPicker(col, &sockptr, "default_value", true, false, false, false); - col->prop(&sockptr, "default_value", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE); -} - static void node_buts_mix_rgb(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; @@ -462,12 +438,6 @@ static void node_shader_set_butfunc(blender::bke::bNodeType *ntype) case SH_NODE_CURVE_FLOAT: ntype->draw_buttons = node_buts_curvefloat; break; - case SH_NODE_VALUE: - ntype->draw_buttons = node_buts_value; - break; - case SH_NODE_RGB: - ntype->draw_buttons = node_buts_rgb; - break; case SH_NODE_MIX_RGB_LEGACY: ntype->draw_buttons = node_buts_mix_rgb; break; @@ -663,12 +633,6 @@ static void node_composit_set_butfunc(blender::bke::bNodeType *ntype) case CMP_NODE_CURVE_RGB: ntype->draw_buttons = node_buts_curvecol; break; - case CMP_NODE_VALUE: - ntype->draw_buttons = node_buts_value; - break; - case CMP_NODE_RGB: - ntype->draw_buttons = node_buts_rgb; - break; case CMP_NODE_MIX_RGB: ntype->draw_buttons = node_buts_mix_rgb; break; @@ -1182,6 +1146,15 @@ static void std_node_socket_draw( int type = sock->typeinfo->type; // int subtype = sock->typeinfo->subtype; + const nodes::SocketDeclaration *socket_decl = sock->runtime->declaration; + if (socket_decl) { + if (socket_decl->custom_draw_fn) { + nodes::CustomSocketDrawParams params{*C, *layout, *tree, *node, *sock, *node_ptr, *ptr}; + (*socket_decl->custom_draw_fn)(params); + return; + } + } + if (sock->is_inactive()) { uiLayoutSetActive(layout, false); } @@ -1198,26 +1171,11 @@ static void std_node_socket_draw( false; if (has_gizmo) { - if (sock->in_out == SOCK_OUT && ELEM(node->type_legacy, - SH_NODE_VALUE, - FN_NODE_INPUT_VECTOR, - FN_NODE_INPUT_INT, - FN_NODE_INPUT_BOOL, - FN_NODE_INPUT_ROTATION, - NODE_GROUP_INPUT)) - { - if (node->is_group_input()) { - uiLayout *row = &layout->row(false); - uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT); - node_socket_button_label(C, row, ptr, node_ptr, text); - row->label("", ICON_GIZMO); - } - else if (nodes::partial_eval::is_supported_value_node(*node)) { - uiLayout *row = &layout->row(false); - uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT); - node_socket_button_label(C, row, ptr, node_ptr, text); - draw_gizmo_pin_icon(row, ptr); - } + if (sock->in_out == SOCK_OUT && node->is_group_input()) { + uiLayout *row = &layout->row(false); + uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT); + node_socket_button_label(C, row, ptr, node_ptr, text); + row->label("", ICON_GIZMO); return; } if (sock->in_out == SOCK_IN && sock->index() == 0 && @@ -1349,10 +1307,8 @@ static void std_node_socket_draw( row->label(IFACE_("No Items"), ICON_NONE); } else { - if (const auto *socket_decl = dynamic_cast( - sock->runtime->declaration)) - { - if (socket_decl->is_expanded) { + if (const auto *menu_decl = dynamic_cast(socket_decl)) { + if (menu_decl->is_expanded) { layout->prop(ptr, "default_value", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE); break; } diff --git a/source/blender/nodes/NOD_geometry_nodes_gizmos.hh b/source/blender/nodes/NOD_geometry_nodes_gizmos.hh index 603398ada08..d8273f6d0c1 100644 --- a/source/blender/nodes/NOD_geometry_nodes_gizmos.hh +++ b/source/blender/nodes/NOD_geometry_nodes_gizmos.hh @@ -135,4 +135,9 @@ void apply_gizmo_change(bContext &C, const bNodeSocket &gizmo_socket, FunctionRef apply_on_gizmo_value_fn); +/** + * Returns true if the value if the given node is controlled by a gizmo. + */ +bool value_node_has_gizmo(const bNodeTree &tree, const bNode &node); + } // namespace blender::nodes::gizmos diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index 9fce28e28d6..6db0d136f30 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -165,6 +165,18 @@ struct SocketNameRNA { std::string property_name; }; +struct CustomSocketDrawParams { + const bContext &C; + uiLayout &layout; + bNodeTree &tree; + bNode &node; + bNodeSocket &socket; + PointerRNA node_ptr; + PointerRNA socket_ptr; +}; + +using CustomSocketDrawFn = std::function; + /** * Describes a single input or output socket. This is subclassed for different socket types. */ @@ -224,6 +236,10 @@ class SocketDeclaration : public ItemDeclaration { * node without going to the side-bar. */ std::unique_ptr socket_name_rna; + /** + * Draw function that overrides how the socket is drawn for a specific node. + */ + std::unique_ptr custom_draw_fn; friend NodeDeclarationBuilder; friend class BaseSocketDeclarationBuilder; @@ -381,6 +397,11 @@ class BaseSocketDeclarationBuilder { */ BaseSocketDeclarationBuilder &make_available(std::function fn); + /** + * Provide a fully custom draw function for the socket that overrides any default behaviour. + */ + BaseSocketDeclarationBuilder &custom_draw(CustomSocketDrawFn fn); + /** * Puts this socket on the same row as the previous socket. This only works when one of them is * an input and the other is an output. diff --git a/source/blender/nodes/composite/nodes/node_composite_rgb.cc b/source/blender/nodes/composite/nodes/node_composite_rgb.cc index ecf7d02af12..dea3657d043 100644 --- a/source/blender/nodes/composite/nodes/node_composite_rgb.cc +++ b/source/blender/nodes/composite/nodes/node_composite_rgb.cc @@ -12,6 +12,9 @@ #include "COM_node_operation.hh" +#include "UI_interface.hh" +#include "UI_resources.hh" + #include "node_composite_util.hh" /* **************** RGB ******************** */ @@ -20,7 +23,15 @@ namespace blender::nodes::node_composite_rgb_cc { static void cmp_node_rgb_declare(NodeDeclarationBuilder &b) { - b.add_output("RGBA").default_value({0.5f, 0.5f, 0.5f, 1.0f}); + b.add_output("RGBA") + .default_value({0.5f, 0.5f, 0.5f, 1.0f}) + .custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayoutSetAlignment(¶ms.layout, UI_LAYOUT_ALIGN_EXPAND); + uiLayout &col = params.layout.column(true); + uiTemplateColorPicker( + &col, ¶ms.socket_ptr, "default_value", true, false, false, false); + col.prop(¶ms.socket_ptr, "default_value", UI_ITEM_R_SLIDER, "", ICON_NONE); + }); } using namespace blender::compositor; diff --git a/source/blender/nodes/composite/nodes/node_composite_value.cc b/source/blender/nodes/composite/nodes/node_composite_value.cc index 8fdd4fb61bf..362f9e282c0 100644 --- a/source/blender/nodes/composite/nodes/node_composite_value.cc +++ b/source/blender/nodes/composite/nodes/node_composite_value.cc @@ -10,13 +10,21 @@ #include "node_composite_util.hh" +#include "UI_interface.hh" +#include "UI_resources.hh" + /* **************** VALUE ******************** */ namespace blender::nodes::node_composite_value_cc { static void cmp_node_value_declare(NodeDeclarationBuilder &b) { - b.add_output("Value").default_value(0.5f); + b.add_output("Value").default_value(0.5f).custom_draw( + [](CustomSocketDrawParams ¶ms) { + uiLayout &row = params.layout.row(true); + row.prop(¶ms.socket_ptr, "default_value", UI_ITEM_NONE, "", ICON_NONE); + }); + ; } using namespace blender::compositor; diff --git a/source/blender/nodes/function/CMakeLists.txt b/source/blender/nodes/function/CMakeLists.txt index 9c93b549f75..8bfcc9e5380 100644 --- a/source/blender/nodes/function/CMakeLists.txt +++ b/source/blender/nodes/function/CMakeLists.txt @@ -8,6 +8,8 @@ set(INC ../intern ../../editors/include ../../makesrna + # RNA_prototypes.hh + ${CMAKE_BINARY_DIR}/source/blender/makesrna ) set(INC_SYS diff --git a/source/blender/nodes/function/nodes/node_fn_input_bool.cc b/source/blender/nodes/function/nodes/node_fn_input_bool.cc index 46ac52918c4..a42f22a1d4e 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_bool.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_bool.cc @@ -4,6 +4,8 @@ #include "node_function_util.hh" +#include "NOD_geometry_nodes_gizmos.hh" + #include "UI_interface.hh" #include "UI_resources.hh" @@ -11,13 +13,13 @@ namespace blender::nodes::node_fn_input_bool_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_output("Boolean"); -} - -static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - uiLayout *col = &layout->column(true); - col->prop(ptr, "boolean", UI_ITEM_R_EXPAND, IFACE_("Value"), ICON_NONE); + b.add_output("Boolean").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayout &row = params.layout.row(true); + row.prop(¶ms.node_ptr, "boolean", UI_ITEM_NONE, "Boolean", ICON_NONE); + if (gizmos::value_node_has_gizmo(params.tree, params.node)) { + row.prop(¶ms.socket_ptr, "pin_gizmo", UI_ITEM_NONE, "", ICON_GIZMO); + } + }); } static void node_build_multi_function(NodeMultiFunctionBuilder &builder) @@ -46,7 +48,6 @@ static void node_register() blender::bke::node_type_storage( ntype, "NodeInputBool", node_free_standard_storage, node_copy_standard_storage); ntype.build_multi_function = node_build_multi_function; - ntype.draw_buttons = node_layout; blender::bke::node_register_type(ntype); } NOD_REGISTER_NODE(node_register) diff --git a/source/blender/nodes/function/nodes/node_fn_input_color.cc b/source/blender/nodes/function/nodes/node_fn_input_color.cc index 090420de101..ba052b711dd 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_color.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_color.cc @@ -13,13 +13,12 @@ namespace blender::nodes::node_fn_input_color_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_output("Color"); -} - -static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - uiTemplateColorPicker(layout, ptr, "value", true, false, false, true); - layout->prop(ptr, "value", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE); + b.add_output("Color").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayoutSetAlignment(¶ms.layout, UI_LAYOUT_ALIGN_EXPAND); + uiLayout &col = params.layout.column(true); + uiTemplateColorPicker(&col, ¶ms.node_ptr, "value", true, false, false, true); + col.prop(¶ms.node_ptr, "value", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE); + }); } static void node_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder) @@ -50,7 +49,6 @@ static void node_register() blender::bke::node_type_storage( ntype, "NodeInputColor", node_free_standard_storage, node_copy_standard_storage); ntype.build_multi_function = node_build_multi_function; - ntype.draw_buttons = node_layout; blender::bke::node_register_type(ntype); } NOD_REGISTER_NODE(node_register) diff --git a/source/blender/nodes/function/nodes/node_fn_input_int.cc b/source/blender/nodes/function/nodes/node_fn_input_int.cc index 33d2ce5a3a4..f87815a5f9b 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_int.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_int.cc @@ -7,17 +7,20 @@ #include "UI_interface.hh" #include "UI_resources.hh" +#include "NOD_geometry_nodes_gizmos.hh" + namespace blender::nodes::node_fn_input_int_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_output("Integer"); -} - -static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - uiLayout *col = &layout->column(true); - col->prop(ptr, "integer", UI_ITEM_R_EXPAND, "", ICON_NONE); + b.add_output("Integer").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayout &row = params.layout.row(true); + row.prop(¶ms.node_ptr, "integer", UI_ITEM_NONE, "", ICON_NONE); + if (gizmos::value_node_has_gizmo(params.tree, params.node)) { + row.prop(¶ms.socket_ptr, "pin_gizmo", UI_ITEM_NONE, "", ICON_GIZMO); + } + }); + ; } static void node_build_multi_function(NodeMultiFunctionBuilder &builder) @@ -46,7 +49,6 @@ static void node_register() blender::bke::node_type_storage( ntype, "NodeInputInt", node_free_standard_storage, node_copy_standard_storage); ntype.build_multi_function = node_build_multi_function; - ntype.draw_buttons = node_layout; blender::bke::node_register_type(ntype); } NOD_REGISTER_NODE(node_register) diff --git a/source/blender/nodes/function/nodes/node_fn_input_rotation.cc b/source/blender/nodes/function/nodes/node_fn_input_rotation.cc index 2e4c4fcdd35..f0c51aecdc9 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_rotation.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_rotation.cc @@ -4,7 +4,7 @@ #include "BLI_math_euler.hh" -#include "NOD_socket_search_link.hh" +#include "NOD_geometry_nodes_gizmos.hh" #include "UI_interface.hh" #include "UI_resources.hh" @@ -15,13 +15,13 @@ namespace blender::nodes::node_fn_input_rotation_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_output("Rotation"); -} - -static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - uiLayout *col = &layout->column(true); - col->prop(ptr, "rotation_euler", UI_ITEM_R_EXPAND, "", ICON_NONE); + b.add_output("Rotation").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayout &row = params.layout.row(true); + row.column(true).prop(¶ms.node_ptr, "rotation_euler", UI_ITEM_NONE, "", ICON_NONE); + if (gizmos::value_node_has_gizmo(params.tree, params.node)) { + row.prop(¶ms.socket_ptr, "pin_gizmo", UI_ITEM_NONE, "", ICON_GIZMO); + } + }); } static void node_build_multi_function(NodeMultiFunctionBuilder &builder) @@ -54,7 +54,6 @@ static void node_register() blender::bke::node_type_storage( ntype, "NodeInputRotation", node_free_standard_storage, node_copy_standard_storage); ntype.build_multi_function = node_build_multi_function; - ntype.draw_buttons = node_layout; blender::bke::node_register_type(ntype); } NOD_REGISTER_NODE(node_register) diff --git a/source/blender/nodes/function/nodes/node_fn_input_string.cc b/source/blender/nodes/function/nodes/node_fn_input_string.cc index 4d850242695..4e0915a52a9 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_string.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_string.cc @@ -16,13 +16,12 @@ namespace blender::nodes::node_fn_input_string_cc { static void node_declare(NodeDeclarationBuilder &b) { b.is_function_node(); - b.add_output("String"); -} - -static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - PropertyRNA *prop = RNA_struct_find_property(ptr, "string"); - layout->prop(ptr, prop, -1, 0, UI_ITEM_NONE, "", ICON_NONE, IFACE_("String")); + b.add_output("String").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayoutSetAlignment(¶ms.layout, UI_LAYOUT_ALIGN_EXPAND); + PropertyRNA *prop = RNA_struct_find_property(¶ms.node_ptr, "string"); + params.layout.prop( + ¶ms.node_ptr, prop, -1, 0, UI_ITEM_NONE, "", ICON_NONE, IFACE_("String")); + }); } static void node_build_multi_function(NodeMultiFunctionBuilder &builder) @@ -86,7 +85,6 @@ static void node_register() ntype.initfunc = node_init; blender::bke::node_type_storage(ntype, "NodeInputString", node_storage_free, node_storage_copy); ntype.build_multi_function = node_build_multi_function; - ntype.draw_buttons = node_layout; ntype.blend_write_storage_content = node_blend_write; ntype.blend_data_read_storage_content = node_blend_read; blender::bke::node_register_type(ntype); diff --git a/source/blender/nodes/function/nodes/node_fn_input_vector.cc b/source/blender/nodes/function/nodes/node_fn_input_vector.cc index 8275a4ec0d2..23f6de264af 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_vector.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_vector.cc @@ -4,6 +4,8 @@ #include "node_function_util.hh" +#include "NOD_geometry_nodes_gizmos.hh" + #include "UI_interface.hh" #include "UI_resources.hh" @@ -11,13 +13,13 @@ namespace blender::nodes::node_fn_input_vector_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_output("Vector"); -} - -static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - uiLayout *col = &layout->column(true); - col->prop(ptr, "vector", UI_ITEM_R_EXPAND, "", ICON_NONE); + b.add_output("Vector").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayout &row = params.layout.row(true); + row.column(true).prop(¶ms.node_ptr, "vector", UI_ITEM_NONE, "", ICON_NONE); + if (gizmos::value_node_has_gizmo(params.tree, params.node)) { + row.prop(¶ms.socket_ptr, "pin_gizmo", UI_ITEM_NONE, "", ICON_GIZMO); + } + }); } static void node_build_multi_function(NodeMultiFunctionBuilder &builder) @@ -47,7 +49,6 @@ static void node_register() blender::bke::node_type_storage( ntype, "NodeInputVector", node_free_standard_storage, node_copy_standard_storage); ntype.build_multi_function = node_build_multi_function; - ntype.draw_buttons = node_layout; blender::bke::node_register_type(ntype); } NOD_REGISTER_NODE(node_register) diff --git a/source/blender/nodes/geometry/nodes/node_geo_image.cc b/source/blender/nodes/geometry/nodes/node_geo_image.cc index 1505e7ef825..993bb4538a5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image.cc @@ -12,12 +12,16 @@ namespace blender::nodes::node_geo_image_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_output("Image"); -} - -static void node_layout(uiLayout *layout, bContext *C, PointerRNA *ptr) -{ - uiTemplateID(layout, C, ptr, "image", "IMAGE_OT_new", "IMAGE_OT_open", nullptr); + b.add_output("Image").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayoutSetAlignment(¶ms.layout, UI_LAYOUT_ALIGN_EXPAND); + uiTemplateID(¶ms.layout, + ¶ms.C, + ¶ms.node_ptr, + "image", + "IMAGE_OT_new", + "IMAGE_OT_open", + nullptr); + }); } static void node_geo_exec(GeoNodeExecParams params) @@ -35,7 +39,6 @@ static void node_register() ntype.enum_name_legacy = "IMAGE"; ntype.nclass = NODE_CLASS_INPUT; ntype.geometry_node_execute = node_geo_exec; - ntype.draw_buttons = node_layout; ntype.declare = node_declare; blender::bke::node_type_size_preset(ntype, blender::bke::eNodeSizePreset::Large); blender::bke::node_register_type(ntype); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_collection.cc b/source/blender/nodes/geometry/nodes/node_geo_input_collection.cc index 102a340520d..21e990aad4c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_collection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_collection.cc @@ -11,12 +11,10 @@ namespace blender::nodes::node_geo_input_collection_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_output("Collection"); -} - -static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - layout->prop(ptr, "collection", UI_ITEM_NONE, "", ICON_NONE); + b.add_output("Collection").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayoutSetAlignment(¶ms.layout, UI_LAYOUT_ALIGN_EXPAND); + params.layout.prop(¶ms.node_ptr, "collection", UI_ITEM_NONE, "", ICON_NONE); + }); } static void node_geo_exec(GeoNodeExecParams params) @@ -34,7 +32,6 @@ static void node_register() ntype.ui_description = "Output a single collection"; ntype.enum_name_legacy = "INPUT_COLLECTION"; ntype.nclass = NODE_CLASS_INPUT; - ntype.draw_buttons = node_layout; ntype.declare = node_declare; ntype.geometry_node_execute = node_geo_exec; blender::bke::node_register_type(ntype); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_material.cc b/source/blender/nodes/geometry/nodes/node_geo_input_material.cc index a01ebb6f970..82c3d0e05e1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_material.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_material.cc @@ -11,12 +11,10 @@ namespace blender::nodes::node_geo_input_material_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_output("Material"); -} - -static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - layout->prop(ptr, "material", UI_ITEM_NONE, "", ICON_NONE); + b.add_output("Material").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayoutSetAlignment(¶ms.layout, UI_LAYOUT_ALIGN_EXPAND); + params.layout.prop(¶ms.node_ptr, "material", UI_ITEM_NONE, "", ICON_NONE); + }); } static void node_geo_exec(GeoNodeExecParams params) @@ -34,7 +32,6 @@ static void node_register() ntype.ui_description = "Output a single material"; ntype.enum_name_legacy = "INPUT_MATERIAL"; ntype.nclass = NODE_CLASS_INPUT; - ntype.draw_buttons = node_layout; ntype.declare = node_declare; ntype.geometry_node_execute = node_geo_exec; blender::bke::node_register_type(ntype); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_object.cc b/source/blender/nodes/geometry/nodes/node_geo_input_object.cc index 78d1c9c16d5..bb09b688f3d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_object.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_object.cc @@ -11,12 +11,10 @@ namespace blender::nodes::node_geo_input_object_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_output("Object"); -} - -static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - layout->prop(ptr, "object", UI_ITEM_NONE, "", ICON_NONE); + b.add_output("Object").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayoutSetAlignment(¶ms.layout, UI_LAYOUT_ALIGN_EXPAND); + params.layout.prop(¶ms.node_ptr, "object", UI_ITEM_NONE, "", ICON_NONE); + }); } static void node_geo_exec(GeoNodeExecParams params) @@ -34,7 +32,6 @@ static void node_register() ntype.ui_description = "Output a single object"; ntype.enum_name_legacy = "INPUT_OBJECT"; ntype.nclass = NODE_CLASS_INPUT; - ntype.draw_buttons = node_layout; ntype.declare = node_declare; ntype.geometry_node_execute = node_geo_exec; blender::bke::node_register_type(ntype); diff --git a/source/blender/nodes/intern/geometry_nodes_gizmos.cc b/source/blender/nodes/intern/geometry_nodes_gizmos.cc index 70f9cb25e7f..a176f7dfd10 100644 --- a/source/blender/nodes/intern/geometry_nodes_gizmos.cc +++ b/source/blender/nodes/intern/geometry_nodes_gizmos.cc @@ -16,13 +16,14 @@ #include "NOD_geometry_nodes_gizmos.hh" #include "NOD_inverse_eval_path.hh" +#include "NOD_partial_eval.hh" +#include "NOD_socket_usage_inference.hh" #include "DNA_modifier_types.h" #include "DNA_space_types.h" #include "DNA_windowmanager_types.h" #include "ED_node.hh" -#include "NOD_socket_usage_inference.hh" namespace blender::nodes::gizmos { @@ -543,4 +544,13 @@ void apply_gizmo_change( ie::backpropagate_socket_values(C, object, nmd, eval_log, sockets_to_update); } +bool value_node_has_gizmo(const bNodeTree &tree, const bNode &node) +{ + BLI_assert(partial_eval::is_supported_value_node(node)); + if (!tree.runtime->gizmo_propagation) { + return false; + } + return tree.runtime->gizmo_propagation->gizmo_endpoint_sockets.contains(&node.output_socket(0)); +} + } // namespace blender::nodes::gizmos diff --git a/source/blender/nodes/intern/node_declaration.cc b/source/blender/nodes/intern/node_declaration.cc index f58f6830967..9704c5b9b0a 100644 --- a/source/blender/nodes/intern/node_declaration.cc +++ b/source/blender/nodes/intern/node_declaration.cc @@ -757,6 +757,12 @@ BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::make_available( return *this; } +BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::custom_draw(CustomSocketDrawFn fn) +{ + decl_base_->custom_draw_fn = std::make_unique(std::move(fn)); + return *this; +} + BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::align_with_previous(const bool value) { decl_base_->align_with_previous_socket = value; diff --git a/source/blender/nodes/shader/nodes/node_shader_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_rgb.cc index cc6bcbb5888..ec73580405d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_rgb.cc @@ -8,11 +8,22 @@ #include "node_shader_util.hh" +#include "UI_interface.hh" +#include "UI_resources.hh" + namespace blender::nodes::node_shader_rgb_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_output("Color").default_value({0.5f, 0.5f, 0.5f, 1.0f}); + b.add_output("Color") + .default_value({0.5f, 0.5f, 0.5f, 1.0f}) + .custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayoutSetAlignment(¶ms.layout, UI_LAYOUT_ALIGN_EXPAND); + uiLayout &col = params.layout.column(true); + uiTemplateColorPicker( + &col, ¶ms.socket_ptr, "default_value", true, false, false, false); + col.prop(¶ms.socket_ptr, "default_value", UI_ITEM_R_SLIDER, "", ICON_NONE); + }); } static int gpu_shader_rgb(GPUMaterial *mat, diff --git a/source/blender/nodes/shader/nodes/node_shader_value.cc b/source/blender/nodes/shader/nodes/node_shader_value.cc index 1657abe26b5..e7205e3177c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_value.cc +++ b/source/blender/nodes/shader/nodes/node_shader_value.cc @@ -10,13 +10,23 @@ #include "FN_multi_function_builder.hh" +#include "NOD_geometry_nodes_gizmos.hh" #include "NOD_multi_function.hh" +#include "UI_interface.hh" +#include "UI_resources.hh" + namespace blender::nodes::node_shader_value_cc { static void sh_node_value_declare(NodeDeclarationBuilder &b) { - b.add_output("Value"); + b.add_output("Value").custom_draw([](CustomSocketDrawParams ¶ms) { + uiLayout &row = params.layout.row(true); + row.prop(¶ms.socket_ptr, "default_value", UI_ITEM_NONE, "", ICON_NONE); + if (gizmos::value_node_has_gizmo(params.tree, params.node)) { + row.prop(¶ms.socket_ptr, "pin_gizmo", UI_ITEM_NONE, "", ICON_GIZMO); + } + }); } static int gpu_shader_value(GPUMaterial *mat,