Blender V5.0
node_tree_interface_ui.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BKE_library.hh"
6#include "BKE_screen.hh"
7
8#include "BLI_listbase.h"
9#include "BLI_string_utf8.h"
10
11#include "BLT_translation.hh"
12
13#include "DNA_screen_types.h"
14#include "DNA_space_types.h"
15
16#include "NOD_socket.hh"
17
18#include "RNA_access.hh"
19#include "RNA_prototypes.hh"
20
22#include "UI_resources.hh"
23
24#include "ED_node.hh"
25
26#include "node_intern.hh"
27
29
31{
33 if (!snode) {
34 return false;
35 }
36 bNodeTree *ntree = snode->edittree;
37 if (!ntree) {
38 return false;
39 }
40 if (ntree->flag & ID_FLAG_EMBEDDED_DATA) {
41 return false;
42 }
43 if (ntree->typeinfo->no_group_interface) {
44 return false;
45 }
46 return true;
47}
48
50{
51 PointerRNA tree_ptr = RNA_pointer_create_discrete(&tree.id, &RNA_NodeTree, &tree);
52 PointerRNA interface_ptr = RNA_pointer_get(&tree_ptr, "interface");
53
54 {
55 uiLayout &row = layout.row(false);
56 uiTemplateNodeTreeInterface(&row, &C, &interface_ptr);
57
58 uiLayout &col = row.column(true);
59 col.enabled_set(ID_IS_EDITABLE(&tree.id));
60 col.menu("NODE_MT_node_tree_interface_new_item", "", ICON_ADD);
61 col.op("node.interface_item_remove", "", ICON_REMOVE);
62 col.separator();
63 col.menu("NODE_MT_node_tree_interface_context_menu", "", ICON_DOWNARROW_HLT);
64 }
65
66 bNodeTreeInterfaceItem *active_item = tree.tree_interface.active_item();
67 if (!active_item) {
68 return;
69 }
70 PointerRNA active_item_ptr = RNA_pointer_get(&interface_ptr, "active");
71
72 layout.use_property_split_set(true);
73 layout.use_property_decorate_set(false);
74
75 if (active_item->item_type == NODE_INTERFACE_SOCKET) {
76 bNodeTreeInterfaceSocket *socket = reinterpret_cast<bNodeTreeInterfaceSocket *>(active_item);
77 const bke::bNodeSocketType *stype = socket->socket_typeinfo();
78 layout.prop(&active_item_ptr, "socket_type", UI_ITEM_NONE, IFACE_("Type"), ICON_NONE);
79 layout.prop(&active_item_ptr, "description", UI_ITEM_NONE, std::nullopt, ICON_NONE);
80 if (tree.type == NTREE_GEOMETRY) {
81 if (nodes::socket_type_supports_fields(stype->type) && stype->type != SOCK_MENU) {
82 if (socket->flag & NODE_INTERFACE_SOCKET_OUTPUT) {
83 layout.prop(&active_item_ptr, "attribute_domain", UI_ITEM_NONE, std::nullopt, ICON_NONE);
84 }
85 layout.prop(
86 &active_item_ptr, "default_attribute_name", UI_ITEM_NONE, std::nullopt, ICON_NONE);
87 }
88 }
89 if (stype->interface_draw) {
90 stype->interface_draw(&tree.id, socket, &C, &layout);
91 }
92 }
93 if (active_item->item_type == NODE_INTERFACE_PANEL) {
94 bNodeTreeInterfacePanel *panel_item = reinterpret_cast<bNodeTreeInterfacePanel *>(active_item);
95 layout.prop(&active_item_ptr, "description", UI_ITEM_NONE, std::nullopt, ICON_NONE);
96 layout.prop(
97 &active_item_ptr, "default_closed", UI_ITEM_NONE, IFACE_("Closed by Default"), ICON_NONE);
98
99 if (bNodeTreeInterfaceSocket *panel_toggle_socket = panel_item->header_toggle_socket()) {
100 if (uiLayout *panel = layout.panel(&C, "panel_toggle", false, IFACE_("Panel Toggle"))) {
101 PointerRNA panel_toggle_socket_ptr = RNA_pointer_create_discrete(
102 &tree.id, &RNA_NodeTreeInterfaceSocket, panel_toggle_socket);
103 panel->prop(
104 &panel_toggle_socket_ptr, "default_value", UI_ITEM_NONE, IFACE_("Default"), ICON_NONE);
105 uiLayout &col = panel->column(false);
106 col.prop(
107 &panel_toggle_socket_ptr, "hide_in_modifier", UI_ITEM_NONE, std::nullopt, ICON_NONE);
108 col.prop(
109 &panel_toggle_socket_ptr, "structure_type", UI_ITEM_NONE, IFACE_("Shape"), ICON_NONE);
110 }
111 }
112 }
113}
114
116{
117 SpaceNode &snode = *CTX_wm_space_node(C);
118 bNodeTree &tree = *snode.edittree;
119 uiLayout &layout = *panel->layout;
120
121 node_tree_interface_draw(const_cast<bContext &>(*C), layout, tree);
122}
123
125{
126 PanelType *pt = MEM_callocN<PanelType>("NODE_PT_node_tree_interface");
127 STRNCPY_UTF8(pt->idname, "NODE_PT_node_tree_interface");
128 STRNCPY_UTF8(pt->label, N_("Group Sockets"));
129 STRNCPY_UTF8(pt->category, "Group");
133 pt->order = 10;
134 BLI_addtail(&art->paneltypes, pt);
135}
136
137} // namespace blender::ed::space_node
SpaceNode * CTX_wm_space_node(const bContext *C)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
#define STRNCPY_UTF8(dst, src)
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:705
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:774
@ NTREE_GEOMETRY
@ SOCK_MENU
#define C
Definition RandGen.cpp:29
void uiTemplateNodeTreeInterface(uiLayout *layout, const bContext *C, PointerRNA *ptr)
#define UI_ITEM_NONE
KDTree_3d * tree
uint col
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
static void node_tree_interface_panel_draw(const bContext *C, Panel *panel)
void node_tree_interface_panel_register(ARegionType *art)
void node_tree_interface_draw(bContext &C, uiLayout &layout, bNodeTree &tree)
static bool node_tree_interface_panel_poll(const bContext *C, PanelType *)
bool socket_type_supports_fields(const eNodeSocketDatatype socket_type)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
ListBase paneltypes
void(* draw)(const bContext *C, Panel *panel)
char idname[BKE_ST_MAXNAME]
bool(* poll)(const bContext *C, PanelType *pt)
char translation_context[BKE_ST_MAXNAME]
char category[BKE_ST_MAXNAME]
char label[BKE_ST_MAXNAME]
struct uiLayout * layout
struct bNodeTree * edittree
bNodeTreeTypeHandle * typeinfo
Defines a socket type.
Definition BKE_node.hh:158
void(* interface_draw)(ID *id, bNodeTreeInterfaceSocket *socket, bContext *C, uiLayout *layout)
Definition BKE_node.hh:174
eNodeSocketDatatype type
Definition BKE_node.hh:193
void use_property_decorate_set(bool is_sep)
PanelLayout panel(const bContext *C, blender::StringRef idname, bool default_closed)
uiLayout & column(bool align)
uiLayout & row(bool align)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
#define N_(msgid)