Node panels: Enable new node group interfaces #1

Closed
Lukas Tönne wants to merge 14 commits from node-panels-final into node-panels-rna

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
11 changed files with 79 additions and 36 deletions
Showing only changes of commit 74081c3b00 - Show all commits

View File

@ -928,6 +928,8 @@ class NODE_PT_node_tree_declaration(Panel):
layout.prop(active_item, "default_attribute_name") layout.prop(active_item, "default_attribute_name")
if active_item.item_type == 'PANEL': if active_item.item_type == 'PANEL':
layout.prop(active_item, "name") layout.prop(active_item, "name")
layout.prop(active_item, "description")
layout.prop(active_item, "default_closed")
class NODE_UL_simulation_zone_items(bpy.types.UIList): class NODE_UL_simulation_zone_items(bpy.types.UIList):

View File

@ -153,7 +153,6 @@ typedef struct CPPTypeHandle CPPTypeHandle;
* *
* Defines the appearance and behavior of a socket in the UI. * Defines the appearance and behavior of a socket in the UI.
*/ */
/* XXX replace interface parts when old tree interfaces are fully deprecated */
typedef struct bNodeSocketType { typedef struct bNodeSocketType {
/** Identifier name. */ /** Identifier name. */
char idname[64]; char idname[64];

View File

@ -182,7 +182,7 @@ inline bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree
const StringRefNull socket_type, const StringRefNull socket_type,
const StringRefNull name) const StringRefNull name)
{ {
eNodeTreeInterfaceSocketFlag flag = eNodeTreeInterfaceSocketFlag(0); NodeTreeInterfaceSocketFlag flag = NodeTreeInterfaceSocketFlag(0);
SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT); SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT);
SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT); SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT);

View File

@ -490,6 +490,7 @@ static void item_copy(bNodeTreeInterfaceItem &dst,
BLI_assert(src_panel.name != nullptr); BLI_assert(src_panel.name != nullptr);
dst_panel.name = BLI_strdup(src_panel.name); dst_panel.name = BLI_strdup(src_panel.name);
dst_panel.description = BLI_strdup_null(src_panel.description);
dst_panel.copy_from(src_panel.items(), flag); dst_panel.copy_from(src_panel.items(), flag);
break; break;
} }
@ -523,6 +524,7 @@ static void item_free(bNodeTreeInterfaceItem &item, const bool do_id_user)
panel.clear(do_id_user); panel.clear(do_id_user);
MEM_SAFE_FREE(panel.name); MEM_SAFE_FREE(panel.name);
MEM_SAFE_FREE(panel.description);
break; break;
} }
} }
@ -551,6 +553,7 @@ static void item_write_data(BlendWriter *writer, bNodeTreeInterfaceItem &item)
case NODE_INTERFACE_PANEL: { case NODE_INTERFACE_PANEL: {
bNodeTreeInterfacePanel &panel = reinterpret_cast<bNodeTreeInterfacePanel &>(item); bNodeTreeInterfacePanel &panel = reinterpret_cast<bNodeTreeInterfacePanel &>(item);
BLO_write_string(writer, panel.name); BLO_write_string(writer, panel.name);
BLO_write_string(writer, panel.description);
BLO_write_pointer_array(writer, panel.items_num, panel.items_array); BLO_write_pointer_array(writer, panel.items_num, panel.items_array);
for (bNodeTreeInterfaceItem *child_item : panel.items()) { for (bNodeTreeInterfaceItem *child_item : panel.items()) {
item_write_struct(writer, *child_item); item_write_struct(writer, *child_item);
@ -595,6 +598,7 @@ static void item_read_data(BlendDataReader *reader, bNodeTreeInterfaceItem &item
case NODE_INTERFACE_PANEL: { case NODE_INTERFACE_PANEL: {
bNodeTreeInterfacePanel &panel = reinterpret_cast<bNodeTreeInterfacePanel &>(item); bNodeTreeInterfacePanel &panel = reinterpret_cast<bNodeTreeInterfacePanel &>(item);
BLO_read_data_address(reader, &panel.name); BLO_read_data_address(reader, &panel.name);
BLO_read_data_address(reader, &panel.description);
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&panel.items_array)); BLO_read_pointer_array(reader, reinterpret_cast<void **>(&panel.items_array));
for (const int i : blender::IndexRange(panel.items_num)) { for (const int i : blender::IndexRange(panel.items_num)) {
BLO_read_data_address(reader, &panel.items_array[i]); BLO_read_data_address(reader, &panel.items_array[i]);
@ -1016,7 +1020,7 @@ static bNodeTreeInterfaceSocket *make_socket(const int uid,
blender::StringRefNull name, blender::StringRefNull name,
blender::StringRefNull description, blender::StringRefNull description,
blender::StringRefNull socket_type, blender::StringRefNull socket_type,
const eNodeTreeInterfaceSocketFlag flag) const NodeTreeInterfaceSocketFlag flag)
{ {
BLI_assert(name.c_str() != nullptr); BLI_assert(name.c_str() != nullptr);
BLI_assert(socket_type.c_str() != nullptr); BLI_assert(socket_type.c_str() != nullptr);
@ -1042,14 +1046,19 @@ static bNodeTreeInterfaceSocket *make_socket(const int uid,
return new_socket; return new_socket;
} }
static bNodeTreeInterfacePanel *make_panel(const int uid, blender::StringRefNull name) static bNodeTreeInterfacePanel *make_panel(const int uid,
blender::StringRefNull name,
blender::StringRefNull description,
const NodeTreeInterfacePanelFlag flag)
{ {
BLI_assert(name.c_str() != nullptr); BLI_assert(name.c_str() != nullptr);
bNodeTreeInterfacePanel *new_panel = MEM_cnew<bNodeTreeInterfacePanel>(__func__); bNodeTreeInterfacePanel *new_panel = MEM_cnew<bNodeTreeInterfacePanel>(__func__);
new_panel->item.item_type = NODE_INTERFACE_PANEL; new_panel->item.item_type = NODE_INTERFACE_PANEL;
new_panel->name = BLI_strdup(name.c_str()); new_panel->name = BLI_strdup(name.c_str());
new_panel->description = BLI_strdup_null(description.c_str());
new_panel->identifier = uid; new_panel->identifier = uid;
new_panel->flag = flag;
return new_panel; return new_panel;
} }
@ -1148,7 +1157,7 @@ void bNodeTreeInterface::active_item_set(bNodeTreeInterfaceItem *item)
bNodeTreeInterfaceSocket *bNodeTreeInterface::add_socket(blender::StringRefNull name, bNodeTreeInterfaceSocket *bNodeTreeInterface::add_socket(blender::StringRefNull name,
blender::StringRefNull description, blender::StringRefNull description,
blender::StringRefNull socket_type, blender::StringRefNull socket_type,
const eNodeTreeInterfaceSocketFlag flag, const NodeTreeInterfaceSocketFlag flag,
bNodeTreeInterfacePanel *parent) bNodeTreeInterfacePanel *parent)
{ {
if (parent == nullptr) { if (parent == nullptr) {
@ -1168,7 +1177,7 @@ bNodeTreeInterfaceSocket *bNodeTreeInterface::insert_socket(
blender::StringRefNull name, blender::StringRefNull name,
blender::StringRefNull description, blender::StringRefNull description,
blender::StringRefNull socket_type, blender::StringRefNull socket_type,
const eNodeTreeInterfaceSocketFlag flag, const NodeTreeInterfaceSocketFlag flag,
bNodeTreeInterfacePanel *parent, bNodeTreeInterfacePanel *parent,
const int position) const int position)
{ {
@ -1186,6 +1195,8 @@ bNodeTreeInterfaceSocket *bNodeTreeInterface::insert_socket(
} }
bNodeTreeInterfacePanel *bNodeTreeInterface::add_panel(blender::StringRefNull name, bNodeTreeInterfacePanel *bNodeTreeInterface::add_panel(blender::StringRefNull name,
blender::StringRefNull description,
const NodeTreeInterfacePanelFlag flag,
bNodeTreeInterfacePanel *parent) bNodeTreeInterfacePanel *parent)
{ {
if (parent == nullptr) { if (parent == nullptr) {
@ -1193,7 +1204,7 @@ bNodeTreeInterfacePanel *bNodeTreeInterface::add_panel(blender::StringRefNull na
} }
BLI_assert(this->find_item(parent->item)); BLI_assert(this->find_item(parent->item));
bNodeTreeInterfacePanel *new_panel = make_panel(next_uid++, name); bNodeTreeInterfacePanel *new_panel = make_panel(next_uid++, name, description, flag);
if (new_panel) { if (new_panel) {
parent->add_item(new_panel->item); parent->add_item(new_panel->item);
} }
@ -1201,6 +1212,8 @@ bNodeTreeInterfacePanel *bNodeTreeInterface::add_panel(blender::StringRefNull na
} }
bNodeTreeInterfacePanel *bNodeTreeInterface::insert_panel(blender::StringRefNull name, bNodeTreeInterfacePanel *bNodeTreeInterface::insert_panel(blender::StringRefNull name,
blender::StringRefNull description,
const NodeTreeInterfacePanelFlag flag,
bNodeTreeInterfacePanel *parent, bNodeTreeInterfacePanel *parent,
const int position) const int position)
{ {
@ -1209,7 +1222,7 @@ bNodeTreeInterfacePanel *bNodeTreeInterface::insert_panel(blender::StringRefNull
} }
BLI_assert(this->find_item(parent->item)); BLI_assert(this->find_item(parent->item));
bNodeTreeInterfacePanel *new_panel = make_panel(next_uid++, name); bNodeTreeInterfacePanel *new_panel = make_panel(next_uid++, name, description, flag);
if (new_panel) { if (new_panel) {
parent->insert_item(new_panel->item, position); parent->insert_item(new_panel->item, position);
} }

View File

@ -424,7 +424,7 @@ static void versioning_convert_node_tree_socket_lists_to_interface(bNodeTree *nt
bNodeTreeInterface &tree_interface = ntree->tree_interface; bNodeTreeInterface &tree_interface = ntree->tree_interface;
LISTBASE_FOREACH (const bNodeSocket *, socket, &ntree->inputs_legacy) { LISTBASE_FOREACH (const bNodeSocket *, socket, &ntree->inputs_legacy) {
eNodeTreeInterfaceSocketFlag flag = NODE_INTERFACE_SOCKET_INPUT; NodeTreeInterfaceSocketFlag flag = NODE_INTERFACE_SOCKET_INPUT;
SET_FLAG_FROM_TEST(flag, socket->flag & SOCK_HIDE_VALUE, NODE_INTERFACE_SOCKET_HIDE_VALUE); SET_FLAG_FROM_TEST(flag, socket->flag & SOCK_HIDE_VALUE, NODE_INTERFACE_SOCKET_HIDE_VALUE);
SET_FLAG_FROM_TEST( SET_FLAG_FROM_TEST(
flag, socket->flag & SOCK_HIDE_IN_MODIFIER, NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER); flag, socket->flag & SOCK_HIDE_IN_MODIFIER, NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER);
@ -436,7 +436,7 @@ static void versioning_convert_node_tree_socket_lists_to_interface(bNodeTree *nt
new_socket->identifier = BLI_strdup(socket->identifier); new_socket->identifier = BLI_strdup(socket->identifier);
} }
LISTBASE_FOREACH (const bNodeSocket *, socket, &ntree->outputs_legacy) { LISTBASE_FOREACH (const bNodeSocket *, socket, &ntree->outputs_legacy) {
eNodeTreeInterfaceSocketFlag flag = NODE_INTERFACE_SOCKET_OUTPUT; NodeTreeInterfaceSocketFlag flag = NODE_INTERFACE_SOCKET_OUTPUT;
SET_FLAG_FROM_TEST(flag, socket->flag & SOCK_HIDE_VALUE, NODE_INTERFACE_SOCKET_HIDE_VALUE); SET_FLAG_FROM_TEST(flag, socket->flag & SOCK_HIDE_VALUE, NODE_INTERFACE_SOCKET_HIDE_VALUE);
SET_FLAG_FROM_TEST( SET_FLAG_FROM_TEST(
flag, socket->flag & SOCK_HIDE_IN_MODIFIER, NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER); flag, socket->flag & SOCK_HIDE_IN_MODIFIER, NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER);

View File

@ -102,9 +102,8 @@ class NodeSocketViewItem : public BasicTreeViewItem {
if (socket_.flag & NODE_INTERFACE_SOCKET_INPUT) { if (socket_.flag & NODE_INTERFACE_SOCKET_INPUT) {
/* XXX Socket template only draws in embossed layouts (Julian). */ /* XXX Socket template only draws in embossed layouts (Julian). */
uiLayoutSetEmboss(input_socket_layout, UI_EMBOSS); uiLayoutSetEmboss(input_socket_layout, UI_EMBOSS);
/* XXX Context is not used by the template function. */ /* Context is not used by the template function. */
bContext *C = nullptr; uiTemplateNodeSocket(input_socket_layout, /*C*/ nullptr, socket_.socket_color());
uiTemplateNodeSocket(input_socket_layout, C, socket_.socket_color());
} }
else { else {
/* Blank item to align output socket labels with inputs. */ /* Blank item to align output socket labels with inputs. */
@ -117,9 +116,8 @@ class NodeSocketViewItem : public BasicTreeViewItem {
if (socket_.flag & NODE_INTERFACE_SOCKET_OUTPUT) { if (socket_.flag & NODE_INTERFACE_SOCKET_OUTPUT) {
/* XXX Socket template only draws in embossed layouts (Julian). */ /* XXX Socket template only draws in embossed layouts (Julian). */
uiLayoutSetEmboss(output_socket_layout, UI_EMBOSS); uiLayoutSetEmboss(output_socket_layout, UI_EMBOSS);
/* XXX Context is not used by the template function. */ /* Context is not used by the template function. */
bContext *C = nullptr; uiTemplateNodeSocket(output_socket_layout, /*C*/ nullptr, socket_.socket_color());
uiTemplateNodeSocket(output_socket_layout, C, socket_.socket_color());
} }
else { else {
/* Blank item to align input socket labels with outputs. */ /* Blank item to align input socket labels with outputs. */

View File

@ -88,7 +88,7 @@ static void add_group_input_node_fn(nodes::LinkSearchOpParams &params)
{ {
/* Add a group input based on the connected socket, and add a new group input node. */ /* Add a group input based on the connected socket, and add a new group input node. */
const eNodeSocketInOut in_out = eNodeSocketInOut(params.socket.in_out); const eNodeSocketInOut in_out = eNodeSocketInOut(params.socket.in_out);
eNodeTreeInterfaceSocketFlag flag = eNodeTreeInterfaceSocketFlag(0); NodeTreeInterfaceSocketFlag flag = NodeTreeInterfaceSocketFlag(0);
SET_FLAG_FROM_TEST(flag, in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT); SET_FLAG_FROM_TEST(flag, in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT);
SET_FLAG_FROM_TEST(flag, in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT); SET_FLAG_FROM_TEST(flag, in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT);
bNodeTreeInterfaceSocket *socket_iface = params.node_tree.tree_interface.add_socket( bNodeTreeInterfaceSocket *socket_iface = params.node_tree.tree_interface.add_socket(
@ -132,7 +132,7 @@ static void add_existing_group_input_fn(nodes::LinkSearchOpParams &params,
const bNodeTreeInterfaceSocket &interface_socket) const bNodeTreeInterfaceSocket &interface_socket)
{ {
const eNodeSocketInOut in_out = eNodeSocketInOut(params.socket.in_out); const eNodeSocketInOut in_out = eNodeSocketInOut(params.socket.in_out);
eNodeTreeInterfaceSocketFlag flag = eNodeTreeInterfaceSocketFlag(0); NodeTreeInterfaceSocketFlag flag = NodeTreeInterfaceSocketFlag(0);
SET_FLAG_FROM_TEST(flag, in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT); SET_FLAG_FROM_TEST(flag, in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT);
SET_FLAG_FROM_TEST(flag, in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT); SET_FLAG_FROM_TEST(flag, in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT);

View File

@ -524,10 +524,8 @@ static void node_update_basis_from_declaration(
{ {
switch (socket_decl->in_out) { switch (socket_decl->in_out) {
case SOCK_IN: case SOCK_IN:
if (!current_input) { /* Must match the declaration. */
/* XXX should match the declaration, assert? */ BLI_assert(current_input != nullptr);
break;
}
SET_FLAG_FROM_TEST(current_input->flag, is_parent_collapsed, SOCK_PANEL_COLLAPSED); SET_FLAG_FROM_TEST(current_input->flag, is_parent_collapsed, SOCK_PANEL_COLLAPSED);
if (is_parent_collapsed) { if (is_parent_collapsed) {
@ -540,10 +538,8 @@ static void node_update_basis_from_declaration(
current_input = current_input->next; current_input = current_input->next;
break; break;
case SOCK_OUT: case SOCK_OUT:
if (!current_output) { /* Must match the declaration. */
/* XXX should match the declaration, assert? */ BLI_assert(current_output != nullptr);
break;
}
SET_FLAG_FROM_TEST(current_output->flag, is_parent_collapsed, SOCK_PANEL_COLLAPSED); SET_FLAG_FROM_TEST(current_output->flag, is_parent_collapsed, SOCK_PANEL_COLLAPSED);
if (is_parent_collapsed) { if (is_parent_collapsed) {

View File

@ -53,13 +53,13 @@ typedef struct bNodeTreeInterfaceItem {
} bNodeTreeInterfaceItem; } bNodeTreeInterfaceItem;
/* Socket interface flags */ /* Socket interface flags */
typedef enum eNodeTreeInterfaceSocketFlag { typedef enum NodeTreeInterfaceSocketFlag {
NODE_INTERFACE_SOCKET_INPUT = 1 << 0, NODE_INTERFACE_SOCKET_INPUT = 1 << 0,
NODE_INTERFACE_SOCKET_OUTPUT = 1 << 1, NODE_INTERFACE_SOCKET_OUTPUT = 1 << 1,
NODE_INTERFACE_SOCKET_HIDE_VALUE = 1 << 2, NODE_INTERFACE_SOCKET_HIDE_VALUE = 1 << 2,
NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER = 1 << 3, NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER = 1 << 3,
} eNodeTreeInterfaceSocketFlag; } NodeTreeInterfaceSocketFlag;
ENUM_OPERATORS(eNodeTreeInterfaceSocketFlag, NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER); ENUM_OPERATORS(NodeTreeInterfaceSocketFlag, NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER);
typedef struct bNodeTreeInterfaceSocket { typedef struct bNodeTreeInterfaceSocket {
bNodeTreeInterfaceItem item; bNodeTreeInterfaceItem item;
@ -101,11 +101,21 @@ typedef struct bNodeTreeInterfaceSocket {
#endif #endif
} bNodeTreeInterfaceSocket; } bNodeTreeInterfaceSocket;
/* Panel interface flags */
typedef enum NodeTreeInterfacePanelFlag {
NODE_INTERFACE_PANEL_DEFAULT_CLOSED = 1 << 0,
} NodeTreeInterfacePanelFlag;
ENUM_OPERATORS(NodeTreeInterfacePanelFlag, NODE_INTERFACE_PANEL_DEFAULT_CLOSED);
typedef struct bNodeTreeInterfacePanel { typedef struct bNodeTreeInterfacePanel {
bNodeTreeInterfaceItem item; bNodeTreeInterfaceItem item;
/* UI name of the panel. */ /* UI name of the panel. */
char *name; char *name;
char *description;
/* eNodeTreeInterfacePanelFlag */
int flag;
char _pad[4];
bNodeTreeInterfaceItem **items_array; bNodeTreeInterfaceItem **items_array;
int items_num; int items_num;
@ -258,7 +268,7 @@ typedef struct bNodeTreeInterface {
bNodeTreeInterfaceSocket *add_socket(blender::StringRefNull name, bNodeTreeInterfaceSocket *add_socket(blender::StringRefNull name,
blender::StringRefNull description, blender::StringRefNull description,
blender::StringRefNull socket_type, blender::StringRefNull socket_type,
eNodeTreeInterfaceSocketFlag flag, NodeTreeInterfaceSocketFlag flag,
bNodeTreeInterfacePanel *parent); bNodeTreeInterfacePanel *parent);
/** /**
* Insert a new socket. * Insert a new socket.
@ -269,7 +279,7 @@ typedef struct bNodeTreeInterface {
bNodeTreeInterfaceSocket *insert_socket(blender::StringRefNull name, bNodeTreeInterfaceSocket *insert_socket(blender::StringRefNull name,
blender::StringRefNull description, blender::StringRefNull description,
blender::StringRefNull socket_type, blender::StringRefNull socket_type,
eNodeTreeInterfaceSocketFlag flag, NodeTreeInterfaceSocketFlag flag,
bNodeTreeInterfacePanel *parent, bNodeTreeInterfacePanel *parent,
int position); int position);
@ -278,7 +288,10 @@ typedef struct bNodeTreeInterface {
* \param parent: Panel in which the new panel is added as a child. If parent is null the new * \param parent: Panel in which the new panel is added as a child. If parent is null the new
* panel is made a child of the root panel. * panel is made a child of the root panel.
*/ */
bNodeTreeInterfacePanel *add_panel(blender::StringRefNull name, bNodeTreeInterfacePanel *parent); bNodeTreeInterfacePanel *add_panel(blender::StringRefNull name,
blender::StringRefNull description,
const NodeTreeInterfacePanelFlag flag,
bNodeTreeInterfacePanel *parent);
/** /**
* Insert a new panel. * Insert a new panel.
* \param parent: Panel in which the new panel is added as a child. If parent is null the new * \param parent: Panel in which the new panel is added as a child. If parent is null the new
@ -286,6 +299,8 @@ typedef struct bNodeTreeInterface {
* \param position: Position of the child panel within the parent panel. * \param position: Position of the child panel within the parent panel.
*/ */
bNodeTreeInterfacePanel *insert_panel(blender::StringRefNull name, bNodeTreeInterfacePanel *insert_panel(blender::StringRefNull name,
blender::StringRefNull description,
const NodeTreeInterfacePanelFlag flag,
bNodeTreeInterfacePanel *parent, bNodeTreeInterfacePanel *parent,
int position); int position);

View File

@ -415,7 +415,7 @@ static bNodeTreeInterfaceSocket *rna_NodeTreeInterfaceItems_new_socket(
} }
const char *socket_type = typeinfo->idname; const char *socket_type = typeinfo->idname;
eNodeTreeInterfaceSocketFlag flag = eNodeTreeInterfaceSocketFlag(0); NodeTreeInterfaceSocketFlag flag = NodeTreeInterfaceSocketFlag(0);
SET_FLAG_FROM_TEST(flag, is_input, NODE_INTERFACE_SOCKET_INPUT); SET_FLAG_FROM_TEST(flag, is_input, NODE_INTERFACE_SOCKET_INPUT);
SET_FLAG_FROM_TEST(flag, is_output, NODE_INTERFACE_SOCKET_OUTPUT); SET_FLAG_FROM_TEST(flag, is_output, NODE_INTERFACE_SOCKET_OUTPUT);
@ -443,6 +443,8 @@ static bNodeTreeInterfacePanel *rna_NodeTreeInterfaceItems_new_panel(
Main *bmain, Main *bmain,
ReportList *reports, ReportList *reports,
const char *name, const char *name,
const char *description,
bool default_closed,
bNodeTreeInterfacePanel *parent) bNodeTreeInterfacePanel *parent)
{ {
if (parent != nullptr && !interface->find_item(parent->item)) { if (parent != nullptr && !interface->find_item(parent->item)) {
@ -450,7 +452,11 @@ static bNodeTreeInterfacePanel *rna_NodeTreeInterfaceItems_new_panel(
return nullptr; return nullptr;
} }
bNodeTreeInterfacePanel *panel = interface->add_panel(name ? name : "", parent); NodeTreeInterfacePanelFlag flag = NodeTreeInterfacePanelFlag(0);
SET_FLAG_FROM_TEST(flag, default_closed, NODE_INTERFACE_PANEL_DEFAULT_CLOSED);
bNodeTreeInterfacePanel *panel = interface->add_panel(
name ? name : "", description ? description : "", flag, parent);
if (panel == nullptr) { if (panel == nullptr) {
BKE_report(reports, RPT_ERROR, "Unable to create panel"); BKE_report(reports, RPT_ERROR, "Unable to create panel");
@ -870,6 +876,17 @@ static void rna_def_node_interface_panel(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop); RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, nullptr, "description");
RNA_def_property_ui_text(prop, "Description", "Panel description");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
prop = RNA_def_property(srna, "default_closed", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "flag", NODE_INTERFACE_PANEL_DEFAULT_CLOSED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Default Closed", "Panel is closed by default on new nodes");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
prop = RNA_def_property(srna, "interface_items", PROP_COLLECTION, PROP_NONE); prop = RNA_def_property(srna, "interface_items", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, nullptr, "items_array", "items_num"); RNA_def_property_collection_sdna(prop, nullptr, "items_array", "items_num");
RNA_def_property_struct_type(prop, "NodeTreeInterfaceItem"); RNA_def_property_struct_type(prop, "NodeTreeInterfaceItem");
@ -927,6 +944,9 @@ static void rna_def_node_tree_interface_items_api(StructRNA *srna)
RNA_def_function_ui_description(func, "Add a new panel to the interface"); RNA_def_function_ui_description(func, "Add a new panel to the interface");
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_string(func, "name", nullptr, 0, "Name", "Name of the new panel"); parm = RNA_def_string(func, "name", nullptr, 0, "Name", "Name of the new panel");
RNA_def_string(func, "description", nullptr, 0, "Description", "Description of the panel");
RNA_def_boolean(
func, "default_closed", false, "Default Closed", "Panel is closed by default on new nodes");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED); RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_pointer(func, RNA_def_pointer(func,
"parent", "parent",

View File

@ -321,8 +321,8 @@ static PanelDeclarationPtr declaration_for_interface_panel(const bNodeTree & /*n
PanelDeclarationPtr dst = std::make_unique<PanelDeclaration>(); PanelDeclarationPtr dst = std::make_unique<PanelDeclaration>();
dst->uid = io_panel.identifier; dst->uid = io_panel.identifier;
dst->name = io_panel.name ? io_panel.name : ""; dst->name = io_panel.name ? io_panel.name : "";
dst->description = ""; /* TODO io_panel.description */ dst->description = io_panel.description ? io_panel.description : "";
dst->default_collapsed = false; /* TODO io_panel.default_collapsed */ dst->default_collapsed = (io_panel.flag & NODE_INTERFACE_PANEL_DEFAULT_CLOSED);
dst->num_items = io_panel.items_num; dst->num_items = io_panel.items_num;
return dst; return dst;
} }