Nodes: initial support for socket tooltips
This adds initial limited support for socket tooltips. It's limited in a couple of ways for now: * Only works when hovering over the socket shape, not when hovering over the value in the socket. * Only works for built-in nodes that already use the new node declaration system. This can later be extended to support pynodes. Those limitations are well worth it for now, given that the implementation is quite simple and the impact on usability is quite large. More complex updates to the layout system, that would allow showing socket tooltips in the nodes, can be done later. With the current implementation we can at least start writing tooltips for geometry nodes now. This commit already adds tooltips for the Cylinder node as an example. Differential Revision: https://developer.blender.org/D12607
This commit is contained in:
committed by
Jacques Lucke
parent
4a2c63f4bd
commit
ef45399f3b
@@ -79,6 +79,7 @@
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "NOD_geometry_nodes_eval_log.hh"
|
||||
#include "NOD_node_declaration.hh"
|
||||
|
||||
#include "FN_field_cpp_type.hh"
|
||||
|
||||
@@ -1085,12 +1086,37 @@ static void node_socket_draw_nested(const bContext *C,
|
||||
but,
|
||||
[](bContext *C, void *argN, const char *UNUSED(tip)) {
|
||||
SocketTooltipData *data = (SocketTooltipData *)argN;
|
||||
std::optional<std::string> str = create_socket_inspection_string(
|
||||
std::optional<std::string> socket_inspection_str = create_socket_inspection_string(
|
||||
C, *data->ntree, *data->node, *data->socket);
|
||||
if (str.has_value()) {
|
||||
return BLI_strdup(str->c_str());
|
||||
|
||||
std::stringstream output;
|
||||
if (data->node->declaration != nullptr) {
|
||||
ListBase *list;
|
||||
Span<blender::nodes::SocketDeclarationPtr> decl_list;
|
||||
|
||||
if (data->socket->in_out == SOCK_IN) {
|
||||
list = &data->node->inputs;
|
||||
decl_list = data->node->declaration->inputs();
|
||||
}
|
||||
else {
|
||||
list = &data->node->outputs;
|
||||
decl_list = data->node->declaration->outputs();
|
||||
}
|
||||
|
||||
const int socket_index = BLI_findindex(list, data->socket);
|
||||
const blender::nodes::SocketDeclaration &socket_decl = *decl_list[socket_index];
|
||||
blender::StringRef description = socket_decl.description();
|
||||
if (!description.is_empty()) {
|
||||
output << TIP_(description.data()) << ".\n\n";
|
||||
}
|
||||
|
||||
if (socket_inspection_str.has_value()) {
|
||||
output << *socket_inspection_str;
|
||||
return BLI_strdup(output.str().c_str());
|
||||
}
|
||||
}
|
||||
return BLI_strdup(TIP_("The socket value has not been computed yet"));
|
||||
output << TIP_("The socket value has not been computed yet");
|
||||
return BLI_strdup(output.str().c_str());
|
||||
},
|
||||
data,
|
||||
MEM_freeN);
|
||||
|
||||
@@ -119,6 +119,7 @@ class SocketDeclaration {
|
||||
protected:
|
||||
std::string name_;
|
||||
std::string identifier_;
|
||||
std::string description_;
|
||||
bool hide_label_ = false;
|
||||
bool hide_value_ = false;
|
||||
bool is_multi_input_ = false;
|
||||
@@ -138,6 +139,7 @@ class SocketDeclaration {
|
||||
virtual bNodeSocket &update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const;
|
||||
|
||||
StringRefNull name() const;
|
||||
StringRefNull description() const;
|
||||
StringRefNull identifier() const;
|
||||
|
||||
InputSocketFieldType input_field_type() const;
|
||||
@@ -186,6 +188,11 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder {
|
||||
return *(Self *)this;
|
||||
}
|
||||
|
||||
Self &description(std::string value = "")
|
||||
{
|
||||
decl_->description_ = std::move(value);
|
||||
return *(Self *)this;
|
||||
}
|
||||
Self &no_muted_links(bool value = true)
|
||||
{
|
||||
decl_->no_mute_links_ = value;
|
||||
@@ -297,6 +304,10 @@ inline StringRefNull SocketDeclaration::identifier() const
|
||||
return identifier_;
|
||||
}
|
||||
|
||||
inline StringRefNull SocketDeclaration::description() const
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
inline InputSocketFieldType SocketDeclaration::input_field_type() const
|
||||
{
|
||||
return input_field_type_;
|
||||
|
||||
@@ -29,9 +29,21 @@ namespace blender::nodes {
|
||||
|
||||
static void geo_node_mesh_primitive_cylinder_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Int>("Vertices").default_value(32).min(3).max(4096);
|
||||
b.add_input<decl::Float>("Radius").default_value(1.0f).min(0.0f).subtype(PROP_DISTANCE);
|
||||
b.add_input<decl::Float>("Depth").default_value(2.0f).min(0.0f).subtype(PROP_DISTANCE);
|
||||
b.add_input<decl::Int>("Vertices")
|
||||
.default_value(32)
|
||||
.min(3)
|
||||
.max(4096)
|
||||
.description("The number of vertices around the circumference");
|
||||
b.add_input<decl::Float>("Radius")
|
||||
.default_value(1.0f)
|
||||
.min(0.0f)
|
||||
.subtype(PROP_DISTANCE)
|
||||
.description("The radius of the cylinder");
|
||||
b.add_input<decl::Float>("Depth")
|
||||
.default_value(2.0f)
|
||||
.min(0.0f)
|
||||
.subtype(PROP_DISTANCE)
|
||||
.description("The height of the cylinder on the Z axis");
|
||||
b.add_output<decl::Geometry>("Geometry");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user