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
This commit is contained in:
Jacques Lucke
2025-05-26 15:47:54 +02:00
parent 790d808b71
commit 87c011f8bb
20 changed files with 175 additions and 142 deletions

View File

@@ -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<const nodes::decl::Menu *>(
sock->runtime->declaration))
{
if (socket_decl->is_expanded) {
if (const auto *menu_decl = dynamic_cast<const nodes::decl::Menu *>(socket_decl)) {
if (menu_decl->is_expanded) {
layout->prop(ptr, "default_value", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
break;
}

View File

@@ -135,4 +135,9 @@ void apply_gizmo_change(bContext &C,
const bNodeSocket &gizmo_socket,
FunctionRef<void(bke::SocketValueVariant &value)> 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

View File

@@ -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<void(CustomSocketDrawParams &params)>;
/**
* 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<SocketNameRNA> socket_name_rna;
/**
* Draw function that overrides how the socket is drawn for a specific node.
*/
std::unique_ptr<CustomSocketDrawFn> custom_draw_fn;
friend NodeDeclarationBuilder;
friend class BaseSocketDeclarationBuilder;
@@ -381,6 +397,11 @@ class BaseSocketDeclarationBuilder {
*/
BaseSocketDeclarationBuilder &make_available(std::function<void(bNode &)> 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.

View File

@@ -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<decl::Color>("RGBA").default_value({0.5f, 0.5f, 0.5f, 1.0f});
b.add_output<decl::Color>("RGBA")
.default_value({0.5f, 0.5f, 0.5f, 1.0f})
.custom_draw([](CustomSocketDrawParams &params) {
uiLayoutSetAlignment(&params.layout, UI_LAYOUT_ALIGN_EXPAND);
uiLayout &col = params.layout.column(true);
uiTemplateColorPicker(
&col, &params.socket_ptr, "default_value", true, false, false, false);
col.prop(&params.socket_ptr, "default_value", UI_ITEM_R_SLIDER, "", ICON_NONE);
});
}
using namespace blender::compositor;

View File

@@ -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<decl::Float>("Value").default_value(0.5f);
b.add_output<decl::Float>("Value").default_value(0.5f).custom_draw(
[](CustomSocketDrawParams &params) {
uiLayout &row = params.layout.row(true);
row.prop(&params.socket_ptr, "default_value", UI_ITEM_NONE, "", ICON_NONE);
});
;
}
using namespace blender::compositor;

View File

@@ -8,6 +8,8 @@ set(INC
../intern
../../editors/include
../../makesrna
# RNA_prototypes.hh
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS

View File

@@ -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<decl::Bool>("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<decl::Bool>("Boolean").custom_draw([](CustomSocketDrawParams &params) {
uiLayout &row = params.layout.row(true);
row.prop(&params.node_ptr, "boolean", UI_ITEM_NONE, "Boolean", ICON_NONE);
if (gizmos::value_node_has_gizmo(params.tree, params.node)) {
row.prop(&params.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)

View File

@@ -13,13 +13,12 @@ namespace blender::nodes::node_fn_input_color_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Color>("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<decl::Color>("Color").custom_draw([](CustomSocketDrawParams &params) {
uiLayoutSetAlignment(&params.layout, UI_LAYOUT_ALIGN_EXPAND);
uiLayout &col = params.layout.column(true);
uiTemplateColorPicker(&col, &params.node_ptr, "value", true, false, false, true);
col.prop(&params.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)

View File

@@ -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<decl::Int>("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<decl::Int>("Integer").custom_draw([](CustomSocketDrawParams &params) {
uiLayout &row = params.layout.row(true);
row.prop(&params.node_ptr, "integer", UI_ITEM_NONE, "", ICON_NONE);
if (gizmos::value_node_has_gizmo(params.tree, params.node)) {
row.prop(&params.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)

View File

@@ -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<decl::Rotation>("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<decl::Rotation>("Rotation").custom_draw([](CustomSocketDrawParams &params) {
uiLayout &row = params.layout.row(true);
row.column(true).prop(&params.node_ptr, "rotation_euler", UI_ITEM_NONE, "", ICON_NONE);
if (gizmos::value_node_has_gizmo(params.tree, params.node)) {
row.prop(&params.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)

View File

@@ -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<decl::String>("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<decl::String>("String").custom_draw([](CustomSocketDrawParams &params) {
uiLayoutSetAlignment(&params.layout, UI_LAYOUT_ALIGN_EXPAND);
PropertyRNA *prop = RNA_struct_find_property(&params.node_ptr, "string");
params.layout.prop(
&params.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);

View File

@@ -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<decl::Vector>("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<decl::Vector>("Vector").custom_draw([](CustomSocketDrawParams &params) {
uiLayout &row = params.layout.row(true);
row.column(true).prop(&params.node_ptr, "vector", UI_ITEM_NONE, "", ICON_NONE);
if (gizmos::value_node_has_gizmo(params.tree, params.node)) {
row.prop(&params.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)

View File

@@ -12,12 +12,16 @@ namespace blender::nodes::node_geo_image_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Image>("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<decl::Image>("Image").custom_draw([](CustomSocketDrawParams &params) {
uiLayoutSetAlignment(&params.layout, UI_LAYOUT_ALIGN_EXPAND);
uiTemplateID(&params.layout,
&params.C,
&params.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);

View File

@@ -11,12 +11,10 @@ namespace blender::nodes::node_geo_input_collection_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Collection>("Collection");
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
layout->prop(ptr, "collection", UI_ITEM_NONE, "", ICON_NONE);
b.add_output<decl::Collection>("Collection").custom_draw([](CustomSocketDrawParams &params) {
uiLayoutSetAlignment(&params.layout, UI_LAYOUT_ALIGN_EXPAND);
params.layout.prop(&params.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);

View File

@@ -11,12 +11,10 @@ namespace blender::nodes::node_geo_input_material_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Material>("Material");
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
layout->prop(ptr, "material", UI_ITEM_NONE, "", ICON_NONE);
b.add_output<decl::Material>("Material").custom_draw([](CustomSocketDrawParams &params) {
uiLayoutSetAlignment(&params.layout, UI_LAYOUT_ALIGN_EXPAND);
params.layout.prop(&params.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);

View File

@@ -11,12 +11,10 @@ namespace blender::nodes::node_geo_input_object_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Object>("Object");
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
layout->prop(ptr, "object", UI_ITEM_NONE, "", ICON_NONE);
b.add_output<decl::Object>("Object").custom_draw([](CustomSocketDrawParams &params) {
uiLayoutSetAlignment(&params.layout, UI_LAYOUT_ALIGN_EXPAND);
params.layout.prop(&params.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);

View File

@@ -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

View File

@@ -757,6 +757,12 @@ BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::make_available(
return *this;
}
BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::custom_draw(CustomSocketDrawFn fn)
{
decl_base_->custom_draw_fn = std::make_unique<CustomSocketDrawFn>(std::move(fn));
return *this;
}
BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::align_with_previous(const bool value)
{
decl_base_->align_with_previous_socket = value;

View File

@@ -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<decl::Color>("Color").default_value({0.5f, 0.5f, 0.5f, 1.0f});
b.add_output<decl::Color>("Color")
.default_value({0.5f, 0.5f, 0.5f, 1.0f})
.custom_draw([](CustomSocketDrawParams &params) {
uiLayoutSetAlignment(&params.layout, UI_LAYOUT_ALIGN_EXPAND);
uiLayout &col = params.layout.column(true);
uiTemplateColorPicker(
&col, &params.socket_ptr, "default_value", true, false, false, false);
col.prop(&params.socket_ptr, "default_value", UI_ITEM_R_SLIDER, "", ICON_NONE);
});
}
static int gpu_shader_rgb(GPUMaterial *mat,

View File

@@ -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<decl::Float>("Value");
b.add_output<decl::Float>("Value").custom_draw([](CustomSocketDrawParams &params) {
uiLayout &row = params.layout.row(true);
row.prop(&params.socket_ptr, "default_value", UI_ITEM_NONE, "", ICON_NONE);
if (gizmos::value_node_has_gizmo(params.tree, params.node)) {
row.prop(&params.socket_ptr, "pin_gizmo", UI_ITEM_NONE, "", ICON_GIZMO);
}
});
}
static int gpu_shader_value(GPUMaterial *mat,