RNA: add callback to support dynamic property ui name

This adds a new `PropertyRNA::name_func` property which is similar to the many
existing functions like `editable`, `get_default`, etc. It allows dynamically
getting a UI name for the property.

This is especially useful for node sockets, because those all have the same
hardcoded name "Default Value" which is not helpful. Since we already have
custom tooltips for sockets, this is mostly not visible to the user anymore. The
exception being menu sockets which draw the property name as title. Instead of
"Default Value", this patch makes it show the correct title.

Pull Request: https://projects.blender.org/blender/blender/pulls/147137
This commit is contained in:
Jacques Lucke
2025-10-06 10:40:05 +02:00
parent 47a0d9b52f
commit ceca413bcb
11 changed files with 65 additions and 8 deletions

View File

@@ -144,4 +144,6 @@ void ui_template_node_asset_menu_items(uiLayout &layout,
/** See #SpaceNode_Runtime::node_can_sync_states. */
Map<int, bool> &node_can_sync_cache_get(SpaceNode &snode);
const char *node_socket_get_label(const bNodeSocket *socket, const char *panel_label = nullptr);
} // namespace blender::ed::space_node

View File

@@ -4582,7 +4582,8 @@ static void ui_def_but_rna__menu(bContext *C, uiLayout *layout, void *but_p)
rows = totitems;
}
const char *title = RNA_property_ui_name(but->rnaprop);
const char *title = RNA_property_ui_name(
but->rnaprop, RNA_pointer_is_null(&but->rnapoin) ? nullptr : &but->rnapoin);
/* Is there a non-blank label before this button on the same row? */
uiBut *but_prev = but->block->prev_but(but);

View File

@@ -170,8 +170,6 @@ void node_socket_color_get(const bContext &C,
const bNodeSocket &sock,
float r_color[4]);
const char *node_socket_get_label(const bNodeSocket *socket, const char *panel_label);
void node_draw_space(const bContext &C, ARegion &region);
void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, uiLayout &layout);

View File

@@ -25,6 +25,8 @@
#include "NOD_node_declaration.hh"
#include "NOD_socket.hh"
#include "ED_node.hh"
#include "node_intern.hh"
namespace geo_log = blender::nodes::geo_eval_log;

View File

@@ -276,8 +276,8 @@ int RNA_property_array_item_index(PropertyRNA *prop, char name);
*/
int RNA_property_string_maxlength(PropertyRNA *prop);
const char *RNA_property_ui_name(const PropertyRNA *prop);
const char *RNA_property_ui_name_raw(const PropertyRNA *prop);
const char *RNA_property_ui_name(const PropertyRNA *prop, const PointerRNA *ptr = nullptr);
const char *RNA_property_ui_name_raw(const PropertyRNA *prop, const PointerRNA *ptr = nullptr);
const char *RNA_property_ui_description(const PropertyRNA *prop);
const char *RNA_property_ui_description_raw(const PropertyRNA *prop);
const char *RNA_property_translation_context(const PropertyRNA *prop);

View File

@@ -493,6 +493,7 @@ void RNA_def_property_enum_default(PropertyRNA *prop, int value);
void RNA_def_property_string_default(PropertyRNA *prop, const char *value);
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description);
void RNA_def_property_ui_name_func(PropertyRNA *prop, const char *name_func);
void RNA_def_property_deprecated(PropertyRNA *prop,
const char *note,

View File

@@ -4428,13 +4428,14 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
prop->arraylength[2],
prop->totarraylength);
fprintf(f,
"\t%s%s, %d, %s, %s, %s, %s, %s,\n",
"\t%s%s, %d, %s, %s, %s, %s, %s, %s,\n",
/* NOTE: void cast is needed to quiet function cast warning in C++. */
(prop->flag & PROP_CONTEXT_UPDATE) ? "(UpdateFunc)(void *)" : "",
rna_function_string(prop->update),
prop->noteflag,
rna_function_string(prop->editable),
rna_function_string(prop->itemeditable),
rna_function_string(prop->ui_name_func),
rna_function_string(prop->override_diff),
rna_function_string(prop->override_store),
rna_function_string(prop->override_apply));

View File

@@ -2208,13 +2208,23 @@ int RNA_property_enum_bitflag_identifiers(
return 0;
}
const char *RNA_property_ui_name(const PropertyRNA *prop)
const char *RNA_property_ui_name(const PropertyRNA *prop, const PointerRNA *ptr)
{
if (ptr && prop->magic == RNA_MAGIC && prop->ui_name_func) {
if (const char *name = prop->ui_name_func(ptr, prop, true)) {
return name;
}
}
return CTX_IFACE_(RNA_property_translation_context(prop), rna_ensure_property_name(prop));
}
const char *RNA_property_ui_name_raw(const PropertyRNA *prop)
const char *RNA_property_ui_name_raw(const PropertyRNA *prop, const PointerRNA *ptr)
{
if (ptr && prop->magic == RNA_MAGIC && prop->ui_name_func) {
if (const char *name = prop->ui_name_func(ptr, prop, false)) {
return name;
}
}
return rna_ensure_property_name(prop);
}

View File

@@ -3223,6 +3223,18 @@ void RNA_def_property_override_funcs(PropertyRNA *prop,
}
}
void RNA_def_property_ui_name_func(PropertyRNA *prop, const char *name_func)
{
if (!DefRNA.preprocess) {
CLOG_ERROR(&LOG, "only during preprocessing.");
return;
}
if (name_func) {
prop->ui_name_func = (PropUINameFunc)name_func;
}
}
void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
{
if (!DefRNA.preprocess) {

View File

@@ -56,6 +56,9 @@ using ItemEditableFunc = int (*)(const PointerRNA *ptr, int index);
using IDPropertiesFunc = IDProperty **(*)(PointerRNA * ptr);
using StructRefineFunc = StructRNA *(*)(PointerRNA * ptr);
using StructPathFunc = std::optional<std::string> (*)(const PointerRNA *ptr);
using PropUINameFunc = const char *(*)(const PointerRNA *ptr,
const PropertyRNA *prop,
bool do_translate);
using PropArrayLengthGetFunc = int (*)(const PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]);
using PropBooleanGetFunc = bool (*)(PointerRNA *ptr);
@@ -422,6 +425,9 @@ struct PropertyRNA {
/** Callback for testing if array-item editable (if applicable). */
ItemEditableFunc itemeditable;
/** Optional function to dynamically override the user-readable #name. */
PropUINameFunc ui_name_func;
/** Override handling callbacks (diff is also used for comparison). */
RNAPropOverrideDiff override_diff;
RNAPropOverrideStore override_store;

View File

@@ -467,6 +467,17 @@ static void rna_NodeSocketStandard_draw_color_simple(StructRNA *type, float r_co
typeinfo->draw_color_simple(typeinfo, r_color);
}
static const char *rna_NodeSocketStandard_name_func(const PointerRNA *ptr,
const PropertyRNA * /*prop*/,
const bool do_translate)
{
const bNodeSocket *socket = ptr->data_as<bNodeSocket>();
if (do_translate) {
return blender::ed::space_node::node_socket_get_label(socket);
}
return socket->name;
}
/* ******** Node Socket Subtypes ******** */
void rna_NodeSocketStandard_float_range(
@@ -1027,6 +1038,7 @@ static void rna_def_node_socket_float(BlenderRNA *brna,
RNA_def_property_float_funcs(prop, nullptr, nullptr, "rna_NodeSocketStandard_float_range");
RNA_def_property_float_default_func(prop, "rna_NodeSocketStandard_float_default");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -1131,6 +1143,7 @@ static void rna_def_node_socket_int(BlenderRNA *brna,
RNA_def_property_int_funcs(prop, nullptr, nullptr, "rna_NodeSocketStandard_int_range");
RNA_def_property_int_default_func(prop, "rna_NodeSocketStandard_int_default");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -1200,6 +1213,7 @@ static void rna_def_node_socket_bool(BlenderRNA *brna, const char *identifier)
prop = RNA_def_property(srna, "default_value", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "value", 1);
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_boolean_default_func(prop, "rna_NodeSocketStandard_boolean_default");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -1245,6 +1259,7 @@ static void rna_def_node_socket_rotation(BlenderRNA *brna, const char *identifie
RNA_def_property_float_sdna(prop, nullptr, "value_euler");
// RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -1320,6 +1335,7 @@ static void rna_def_node_socket_vector(BlenderRNA *brna,
RNA_def_property_float_default_func(prop, "rna_NodeSocketStandard_vector_default");
RNA_def_property_float_funcs(prop, nullptr, nullptr, "rna_NodeSocketStandard_vector_range");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -1399,6 +1415,7 @@ static void rna_def_node_socket_color(BlenderRNA *brna, const char *identifier)
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, nullptr, "value");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_float_default_func(prop, "rna_NodeSocketStandard_color_default");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -1445,6 +1462,7 @@ static void rna_def_node_socket_string(BlenderRNA *brna,
prop = RNA_def_property(srna, "default_value", PROP_STRING, subtype);
RNA_def_property_string_sdna(prop, nullptr, "value");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -1509,6 +1527,7 @@ static void rna_def_node_socket_menu(BlenderRNA *brna, const char *identifier)
RNA_def_property_enum_funcs(prop, nullptr, nullptr, "RNA_node_socket_menu_itemf");
RNA_def_property_enum_default_func(prop, "rna_NodeSocketStandard_menu_default");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -1577,6 +1596,7 @@ static void rna_def_node_socket_object(BlenderRNA *brna, const char *identifier)
RNA_def_property_pointer_sdna(prop, nullptr, "value");
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(
prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);
@@ -1621,6 +1641,7 @@ static void rna_def_node_socket_image(BlenderRNA *brna, const char *identifier)
RNA_def_property_pointer_sdna(prop, nullptr, "value");
RNA_def_property_struct_type(prop, "Image");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(
prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);
@@ -1728,6 +1749,7 @@ static void rna_def_node_socket_collection(BlenderRNA *brna, const char *identif
RNA_def_property_pointer_sdna(prop, nullptr, "value");
RNA_def_property_struct_type(prop, "Collection");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(
prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);
@@ -1772,6 +1794,7 @@ static void rna_def_node_socket_texture(BlenderRNA *brna, const char *identifier
RNA_def_property_pointer_sdna(prop, nullptr, "value");
RNA_def_property_struct_type(prop, "Texture");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(
prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);
@@ -1816,6 +1839,7 @@ static void rna_def_node_socket_material(BlenderRNA *brna, const char *identifie
RNA_def_property_pointer_sdna(prop, nullptr, "value");
RNA_def_property_struct_type(prop, "Material");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_ui_name_func(prop, "rna_NodeSocketStandard_name_func");
RNA_def_property_update(
prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);