I18n: add per-socket translation contexts for nodes #105195
|
@ -6,6 +6,7 @@ set(INC
|
|||
cached_resources
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../blentranslation
|
||||
../../gpu
|
||||
../../imbuf
|
||||
../../makesdna
|
||||
|
|
|
@ -181,6 +181,23 @@ void ED_node_tag_update_id(ID *id)
|
|||
|
||||
namespace blender::ed::space_node {
|
||||
|
||||
static const char *node_socket_get_translation_context(const bNodeSocket &socket)
|
||||
{
|
||||
/* The node is not explicitly defined. */
|
||||
if (socket.runtime->declaration == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
blender::StringRefNull translation_context = socket.runtime->declaration->translation_context;
|
||||
|
||||
/* Default context. */
|
||||
if (translation_context.is_empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return translation_context.data();
|
||||
pioverfour marked this conversation as resolved
Hans Goudey
commented
Why Why `BLI_strdup`? Could you just use `StringRefNull` and return that directly? It looks like the result isn't being freed, and this negates the benefit of any small string optimization in `std::string`
|
||||
}
|
||||
|
||||
static void node_socket_add_tooltip_in_node_editor(const bNodeTree &ntree,
|
||||
pioverfour marked this conversation as resolved
Bastien Montagne
commented
Not sure why you are using an intermediate Not sure why you are using an intermediate `std::stringstream` here? Can't you just do `return BLI_strdup(socket_decl.translation_context.c_str());` ?
Jacques Lucke
commented
That sounds reasonable. That sounds reasonable.
I guess the reason for why the `std::stringstream` was used is that you assigned it to a `StringRef` which does not have `c_str` method, because it might not be null-terminated. Using `const StringRefNull` or what @mont29 would be better though.
Damien Picard
commented
To be quite honest I copied code doing a similar thing from To be quite honest I copied code doing a similar thing from `node_socket_get_tooltip()`, but I see that it doesn’t really apply here.
I’ll go with @mont29 ’s solution.
|
||||
const bNodeSocket &sock,
|
||||
uiLayout &layout);
|
||||
|
@ -377,8 +394,14 @@ static void node_update_basis(const bContext &C,
|
|||
/* Align output buttons to the right. */
|
||||
uiLayout *row = uiLayoutRow(layout, true);
|
||||
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT);
|
||||
|
||||
const char *socket_label = nodeSocketLabel(socket);
|
||||
socket->typeinfo->draw((bContext *)&C, row, &sockptr, &nodeptr, IFACE_(socket_label));
|
||||
const char *socket_translation_context = node_socket_get_translation_context(*socket);
|
||||
socket->typeinfo->draw((bContext *)&C,
|
||||
row,
|
||||
&sockptr,
|
||||
&nodeptr,
|
||||
CTX_IFACE_(socket_translation_context, socket_label));
|
||||
|
||||
node_socket_add_tooltip_in_node_editor(ntree, *socket, *row);
|
||||
|
||||
|
@ -511,7 +534,12 @@ static void node_update_basis(const bContext &C,
|
|||
uiLayout *row = uiLayoutRow(layout, true);
|
||||
|
||||
const char *socket_label = nodeSocketLabel(socket);
|
||||
socket->typeinfo->draw((bContext *)&C, row, &sockptr, &nodeptr, IFACE_(socket_label));
|
||||
const char *socket_translation_context = node_socket_get_translation_context(*socket);
|
||||
socket->typeinfo->draw((bContext *)&C,
|
||||
row,
|
||||
&sockptr,
|
||||
&nodeptr,
|
||||
CTX_IFACE_(socket_translation_context, socket_label));
|
||||
|
||||
node_socket_add_tooltip_in_node_editor(ntree, *socket, *row);
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "DNA_node_types.h"
|
||||
|
||||
struct bNode;
|
||||
|
@ -145,6 +147,7 @@ class SocketDeclaration {
|
|||
std::string name;
|
||||
std::string identifier;
|
||||
std::string description;
|
||||
std::string translation_context;
|
||||
/** Defined by whether the socket is part of the node's input or
|
||||
* output socket declaration list. Included here for convenience. */
|
||||
eNodeSocketInOut in_out;
|
||||
|
@ -275,6 +278,12 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder {
|
|||
return *(Self *)this;
|
||||
}
|
||||
|
||||
Self &translation_context(std::string value = BLT_I18NCONTEXT_DEFAULT)
|
||||
{
|
||||
decl_->translation_context = std::move(value);
|
||||
return *(Self *)this;
|
||||
}
|
||||
|
||||
Self &no_muted_links(bool value = true)
|
||||
{
|
||||
decl_->no_mute_links = value;
|
||||
|
|
|
@ -33,7 +33,8 @@ namespace blender::nodes::node_composite_keyingscreen_cc {
|
|||
|
||||
static void cmp_node_keyingscreen_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_output<decl::Color>(N_("Screen"));
|
||||
b.add_output<decl::Color>(CTX_N_(BLT_I18NCONTEXT_ID_SCREEN, "Screen"))
|
||||
.translation_context(BLT_I18NCONTEXT_ID_SCREEN);
|
||||
}
|
||||
|
||||
static void node_composit_init_keyingscreen(const bContext *C, PointerRNA *ptr)
|
||||
|
|
This is needed to avoid a crash when certain nodes are added (for instance, Render Layers in the compositing nodes).
GCC gives a warning:
the compiler can assume that the address of ‘socket_decl’ will never be NULL [-Waddress]
.I suppose it means this should not happen because a null pointer would mean a bug occurs before reaching this point. But I don’t know how to fix this better since it appears not all nodes have a declaration.
You cannot use a reference if there is a chance that the pointer will be NULL. So if
socket.runtime->declaration
can benullptr
, you need to use a pointer forsocket_decl
- or do the check before assigning it to your reference.At first check
socket.runtime->declaration != nullptr
, and after that dereference pointerThanks for the help! I hope I fixed this correctly.