[Bf-blender-cvs] [2bd9f9d9765] master: UI/Nodes: Improve feedback when adding node fails (e.g. on drag & drop)

Julian Eisel noreply at git.blender.org
Mon Apr 12 18:49:28 CEST 2021


Commit: 2bd9f9d976560c55a15ed297032f7d73c2f101cc
Author: Julian Eisel
Date:   Mon Apr 12 18:43:23 2021 +0200
Branches: master
https://developer.blender.org/rB2bd9f9d976560c55a15ed297032f7d73c2f101cc

UI/Nodes: Improve feedback when adding node fails (e.g. on drag & drop)

This is especially useful when trying to add a node group instance, e.g. via
drag & drop from the Outliner or Asset Browser.
Previously this would just silently fail, with no information why. This is a
source of confusion, e.g. earlier, it took me a moment to realize I was
dragging a node group into itself, which failed of course.
Blender should always try to help the user with useful error messages.

Adds error messages like: "Nesting a node group inside of itself is not
allowed", "Not a compositor node tree", etc.

Adds a disabled hint return argument to node and node tree polling functions.
On error the hint is reported, or could even be shown in advance (e.g. if
checked via an operator poll option).

Differential Revision: https://developer.blender.org/D10422

Reviewed by: Jacques Lucke

===================================================================

M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.cc
M	source/blender/editors/space_node/node_add.c
M	source/blender/editors/space_node/node_edit.c
M	source/blender/editors/space_node/node_group.c
M	source/blender/editors/space_node/node_templates.c
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/composite/node_composite_util.c
M	source/blender/nodes/composite/node_composite_util.h
M	source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
M	source/blender/nodes/composite/nodes/node_composite_image.c
M	source/blender/nodes/function/node_function_util.cc
M	source/blender/nodes/function/node_function_util.hh
M	source/blender/nodes/geometry/node_geometry_util.cc
M	source/blender/nodes/geometry/node_geometry_util.hh
M	source/blender/nodes/intern/node_common.c
M	source/blender/nodes/intern/node_common.h
M	source/blender/nodes/shader/node_shader_util.c
M	source/blender/nodes/shader/node_shader_util.h
M	source/blender/nodes/texture/node_texture_util.c
M	source/blender/nodes/texture/node_texture_util.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 30c76dc894c..d6c4ad037e2 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -289,10 +289,22 @@ typedef struct bNodeType {
   void (*freefunc_api)(struct PointerRNA *ptr);
   void (*copyfunc_api)(struct PointerRNA *ptr, const struct bNode *src_node);
 
-  /* can this node type be added to a node tree */
-  bool (*poll)(struct bNodeType *ntype, struct bNodeTree *nodetree);
-  /* can this node be added to a node tree */
-  bool (*poll_instance)(struct bNode *node, struct bNodeTree *nodetree);
+  /**
+   * Can this node type be added to a node tree?
+   * \param r_disabled_hint: Optional hint to display in the UI when the poll fails.
+   *                         The callback can set this to a static string without having to
+   *                         null-check it (or without setting it to null if it's not used).
+   *                         The caller must pass a valid `const char **` and null-initialize it
+   *                         when it's not just a dummy, that is, if it actually wants to access
+   *                         the returned disabled-hint (null-check needed!).
+   */
+  bool (*poll)(struct bNodeType *ntype, struct bNodeTree *nodetree, const char **r_disabled_hint);
+  /** Can this node be added to a node tree?
+   * \param r_disabled_hint: See `poll()`.
+   */
+  bool (*poll_instance)(struct bNode *node,
+                        struct bNodeTree *nodetree,
+                        const char **r_disabled_hint);
 
   /* optional handling of link insertion */
   void (*insert_link)(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link);
@@ -804,7 +816,9 @@ void BKE_node_preview_set_pixel(
 void nodeLabel(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen);
 const char *nodeSocketLabel(const struct bNodeSocket *sock);
 
-int nodeGroupPoll(struct bNodeTree *nodetree, struct bNodeTree *grouptree);
+bool nodeGroupPoll(struct bNodeTree *nodetree,
+                   struct bNodeTree *grouptree,
+                   const char **r_disabled_hint);
 
 /* Init a new node type struct with default values and callbacks */
 void node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 52f6c4f93ad..02195e0d60f 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -2007,7 +2007,8 @@ bNode *nodeAddStaticNode(const struct bContext *C, bNodeTree *ntree, int type)
     /* do an extra poll here, because some int types are used
      * for multiple node types, this helps find the desired type
      */
-    if (ntype->type == type && (!ntype->poll || ntype->poll(ntype, ntree))) {
+    const char *disabled_hint;
+    if (ntype->type == type && (!ntype->poll || ntype->poll(ntype, ntree, &disabled_hint))) {
       idname = ntype->idname;
       break;
     }
@@ -4407,15 +4408,17 @@ static void node_type_base_defaults(bNodeType *ntype)
 }
 
 /* allow this node for any tree type */
-static bool node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(ntree))
+static bool node_poll_default(bNodeType *UNUSED(ntype),
+                              bNodeTree *UNUSED(ntree),
+                              const char **UNUSED(disabled_hint))
 {
   return true;
 }
 
 /* use the basic poll function */
-static bool node_poll_instance_default(bNode *node, bNodeTree *ntree)
+static bool node_poll_instance_default(bNode *node, bNodeTree *ntree, const char **disabled_hint)
 {
-  return node->typeinfo->poll(node->typeinfo, ntree);
+  return node->typeinfo->poll(node->typeinfo, ntree, disabled_hint);
 }
 
 /* NOLINTNEXTLINE: readability-function-size */
@@ -4634,7 +4637,9 @@ void node_type_internal_links(bNodeType *ntype,
 
 /* callbacks for undefined types */
 
-static bool node_undefined_poll(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(nodetree))
+static bool node_undefined_poll(bNodeType *UNUSED(ntype),
+                                bNodeTree *UNUSED(nodetree),
+                                const char **UNUSED(r_disabled_hint))
 {
   /* this type can not be added deliberately, it's just a placeholder */
   return false;
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 82a315366dc..a28d467df2e 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -339,7 +339,25 @@ static bNodeTree *node_add_group_get_and_poll_group_node_tree(Main *bmain,
   if (!node_group) {
     return NULL;
   }
-  if ((node_group->type != ntree->type) || !nodeGroupPoll(ntree, node_group)) {
+
+  const char *disabled_hint = NULL;
+  if ((node_group->type != ntree->type) || !nodeGroupPoll(ntree, node_group, &disabled_hint)) {
+    if (disabled_hint) {
+      BKE_reportf(op->reports,
+                  RPT_ERROR,
+                  "Can not add node group '%s' to '%s':\n  %s",
+                  node_group->id.name + 2,
+                  ntree->id.name + 2,
+                  disabled_hint);
+    }
+    else {
+      BKE_reportf(op->reports,
+                  RPT_ERROR,
+                  "Can not add node group '%s' to '%s'",
+                  node_group->id.name + 2,
+                  ntree->id.name + 2);
+    }
+
     return NULL;
   }
 
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 518f5639c93..1cbd0fd607c 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -2241,13 +2241,25 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
   /* make sure all clipboard nodes would be valid in the target tree */
   bool all_nodes_valid = true;
   LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) {
-    if (!node->typeinfo->poll_instance || !node->typeinfo->poll_instance(node, ntree)) {
+    const char *disabled_hint = NULL;
+    if (!node->typeinfo->poll_instance ||
+        !node->typeinfo->poll_instance(node, ntree, &disabled_hint)) {
       all_nodes_valid = false;
-      BKE_reportf(op->reports,
-                  RPT_ERROR,
-                  "Cannot add node %s into node tree %s",
-                  node->name,
-                  ntree->id.name + 2);
+      if (disabled_hint) {
+        BKE_reportf(op->reports,
+                    RPT_ERROR,
+                    "Cannot add node %s into node tree %s:\n  %s",
+                    node->name,
+                    ntree->id.name + 2,
+                    disabled_hint);
+      }
+      else {
+        BKE_reportf(op->reports,
+                    RPT_ERROR,
+                    "Cannot add node %s into node tree %s",
+                    node->name,
+                    ntree->id.name + 2);
+      }
     }
   }
   if (!all_nodes_valid) {
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index e1de4bfc21e..335e2f93ff3 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -679,8 +679,19 @@ static bool node_group_make_test_selected(bNodeTree *ntree,
   /* check poll functions for selected nodes */
   LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
     if (node_group_make_use_node(node, gnode)) {
-      if (node->typeinfo->poll_instance && !node->typeinfo->poll_instance(node, ngroup)) {
-        BKE_reportf(reports, RPT_WARNING, "Can not add node '%s' in a group", node->name);
+      const char *disabled_hint = NULL;
+      if (node->typeinfo->poll_instance &&
+          !node->typeinfo->poll_instance(node, ngroup, &disabled_hint)) {
+        if (disabled_hint) {
+          BKE_reportf(reports,
+                      RPT_WARNING,
+                      "Can not add node '%s' in a group:\n  %s",
+                      node->name,
+                      disabled_hint);
+        }
+        else {
+          BKE_reportf(reports, RPT_WARNING, "Can not add node '%s' in a group", node->name);
+        }
         ok = false;
         break;
       }
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 3873985d93a..54145f62895 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -330,7 +330,9 @@ static void ui_node_link_items(NodeLinkArg *arg,
     int i;
 
     for (ngroup = arg->bmain->nodetrees.first; ngroup; ngroup = ngroup->id.next) {
-      if ((ngroup->type != arg->ntree->type) || !nodeGroupPoll(arg->ntree, ngroup)) {
+      const char *disabled_hint;
+      if ((ngroup->type != arg->ntree->type) ||
+          !nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
         continue;
       }
 
@@ -343,7 +345,9 @@ static void ui_node_link_items(NodeLinkArg *arg,
 
       i = 0;
       for (ngroup = arg->bmain->nodetrees.first; ngroup; ngroup = ngroup->id.next) {
-        if ((ngroup->type != arg->ntree->type) || !nodeGroupPoll(arg->ntree, ngroup)) {
+        const char *disabled_hint;
+        if ((ngroup->type != arg->ntree->type) ||
+            !nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
           continue;
         }
 
@@ -481,7 +485,8 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
   BLI_array_declare(sorted_ntypes);
 
   NODE_TYPES_BEGIN (ntype) {
-    if (!(ntype->poll && ntype->poll(ntype, ntree))) {
+    const char *disabled_hint;
+    if (!(ntype->poll && ntype->poll(ntype, ntree, &disabled_hint))) {
       continue;
     }
 
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index b79381ac26f..1016d31f11b 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1085,13 +1085,25 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
     return NULL;
   }
 
-  if (ntype->poll && !ntype->poll(ntype, ntree)) {
-    BKE_reportf(reports,
-                RPT_ERROR,
-                "Cannot add node o

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list