Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_node/drawnode.c10
-rw-r--r--source/blender/editors/space_node/node_geometry_attribute_search.cc151
-rw-r--r--source/blender/editors/space_node/node_intern.h8
4 files changed, 169 insertions, 1 deletions
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index c640b076ba4..bc043a4e665 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -42,6 +42,7 @@ set(SRC
node_buttons.c
node_draw.cc
node_edit.c
+ node_geometry_attribute_search.cc
node_gizmo.c
node_group.c
node_ops.c
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 82a1cd818c9..977c2053187 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -3389,7 +3389,15 @@ static void std_node_socket_draw(
case SOCK_STRING: {
uiLayout *row = uiLayoutSplit(layout, 0.5f, false);
uiItemL(row, text, 0);
- uiItemR(row, ptr, "default_value", DEFAULT_FLAGS, "", 0);
+
+ const bNodeTree *node_tree = (const bNodeTree *)node_ptr->owner_id;
+ if (node_tree->type == NTREE_GEOMETRY) {
+ node_geometry_add_attribute_search_button(node_tree, node, ptr, row);
+ }
+ else {
+ uiItemR(row, ptr, "default_value", DEFAULT_FLAGS, "", 0);
+ }
+
break;
}
case SOCK_OBJECT: {
diff --git a/source/blender/editors/space_node/node_geometry_attribute_search.cc b/source/blender/editors/space_node/node_geometry_attribute_search.cc
new file mode 100644
index 00000000000..41f04dad221
--- /dev/null
+++ b/source/blender/editors/space_node/node_geometry_attribute_search.cc
@@ -0,0 +1,151 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_index_range.hh"
+#include "BLI_listbase.h"
+#include "BLI_map.hh"
+#include "BLI_set.hh"
+#include "BLI_string_ref.hh"
+#include "BLI_string_search.h"
+
+#include "DNA_modifier_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_context.h"
+#include "BKE_node_ui_storage.hh"
+#include "BKE_object.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_intern.h"
+
+using blender::IndexRange;
+using blender::Map;
+using blender::Set;
+using blender::StringRef;
+
+struct AttributeSearchData {
+ const bNodeTree &node_tree;
+ const bNode &node;
+
+ uiBut *search_button;
+
+ /* Used to keep track of a button pointer over multiple redraws. Since the UI code
+ * may reallocate the button, without this we might end up with a dangling pointer. */
+ uiButStore *button_store;
+ uiBlock *button_store_block;
+};
+
+static void attribute_search_update_fn(
+ const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
+{
+ AttributeSearchData *data = static_cast<AttributeSearchData *>(arg);
+ const NodeUIStorage *ui_storage = BKE_node_tree_ui_storage_get_from_context(
+ C, data->node_tree, data->node);
+ if (ui_storage == nullptr) {
+ return;
+ }
+
+ const Set<std::string> &attribute_name_hints = ui_storage->attribute_name_hints;
+
+ if (str[0] != '\0' && !attribute_name_hints.contains_as(StringRef(str))) {
+ /* Any string may be valid, so add the current search string with the hints. */
+ UI_search_item_add(items, str, (void *)str, ICON_ADD, 0, 0);
+ }
+
+ /* Skip the filter when the menu is first opened, so all of the items are visible. */
+ if (is_first) {
+ for (const std::string &attribute_name : attribute_name_hints) {
+ /* Just use the pointer to the name string as the search data,
+ * since it's not used anyway but we need a pointer. */
+ UI_search_item_add(items, attribute_name.c_str(), (void *)&attribute_name, ICON_NONE, 0, 0);
+ }
+ return;
+ }
+
+ StringSearch *search = BLI_string_search_new();
+ for (const std::string &attribute_name : attribute_name_hints) {
+ BLI_string_search_add(search, attribute_name.c_str(), (void *)&attribute_name);
+ }
+
+ std::string **filtered_items;
+ const int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_items);
+
+ for (const int i : IndexRange(filtered_amount)) {
+ std::string *item = filtered_items[i];
+ if (!UI_search_item_add(items, item->c_str(), item, ICON_NONE, 0, 0)) {
+ break;
+ }
+ }
+
+ MEM_freeN(filtered_items);
+ BLI_string_search_free(search);
+}
+
+static void attribute_search_free_fn(void *arg)
+{
+ AttributeSearchData *data = static_cast<AttributeSearchData *>(arg);
+
+ UI_butstore_free(data->button_store_block, data->button_store);
+ delete data;
+}
+
+void node_geometry_add_attribute_search_button(const bNodeTree *node_tree,
+ const bNode *node,
+ PointerRNA *socket_ptr,
+ uiLayout *layout)
+{
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBut *but = uiDefIconTextButR(block,
+ UI_BTYPE_SEARCH_MENU,
+ 0,
+ ICON_NONE,
+ "",
+ 0,
+ 0,
+ 10 * UI_UNIT_X, /* Dummy value, replaced by layout system. */
+ UI_UNIT_Y,
+ socket_ptr,
+ "default_value",
+ 0,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ "");
+
+ AttributeSearchData *data = new AttributeSearchData{
+ *node_tree,
+ *node,
+ but,
+ UI_butstore_create(block),
+ block,
+ };
+
+ UI_butstore_register(data->button_store, &data->search_button);
+
+ UI_but_func_search_set_results_are_suggestions(but, true);
+ UI_but_func_search_set(but,
+ nullptr,
+ attribute_search_update_fn,
+ static_cast<void *>(data),
+ attribute_search_free_fn,
+ nullptr,
+ nullptr);
+}
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 5973d59e68f..972e6cab123 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -38,9 +38,11 @@ struct bContext;
struct bNode;
struct bNodeLink;
struct bNodeSocket;
+struct uiBut;
struct wmGizmoGroupType;
struct wmKeyConfig;
struct wmWindow;
+struct uiBlock;
#ifdef __cplusplus
extern "C" {
@@ -289,6 +291,12 @@ void NODE_GGT_backdrop_corner_pin(struct wmGizmoGroupType *gzgt);
void NODE_OT_cryptomatte_layer_add(struct wmOperatorType *ot);
void NODE_OT_cryptomatte_layer_remove(struct wmOperatorType *ot);
+/* node_geometry_attribute_search.cc */
+void node_geometry_add_attribute_search_button(const struct bNodeTree *node_tree,
+ const struct bNode *node,
+ struct PointerRNA *socket_ptr,
+ struct uiLayout *layout);
+
extern const char *node_context_dir[];
/* XXXXXX */