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")
if active_item.item_type == 'PANEL':
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):

View File

@ -153,7 +153,6 @@ typedef struct CPPTypeHandle CPPTypeHandle;
*
* 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 {
/** Identifier name. */
char idname[64];

View File

@ -182,7 +182,7 @@ inline bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree
const StringRefNull socket_type,
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_OUT, NODE_INTERFACE_SOCKET_OUTPUT);

View File

@ -490,6 +490,7 @@ static void item_copy(bNodeTreeInterfaceItem &dst,
BLI_assert(src_panel.name != nullptr);
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);
break;
}
@ -523,6 +524,7 @@ static void item_free(bNodeTreeInterfaceItem &item, const bool do_id_user)
panel.clear(do_id_user);
MEM_SAFE_FREE(panel.name);
MEM_SAFE_FREE(panel.description);
break;
}
}
@ -551,6 +553,7 @@ static void item_write_data(BlendWriter *writer, bNodeTreeInterfaceItem &item)
case NODE_INTERFACE_PANEL: {
bNodeTreeInterfacePanel &panel = reinterpret_cast<bNodeTreeInterfacePanel &>(item);
BLO_write_string(writer, panel.name);
BLO_write_string(writer, panel.description);
BLO_write_pointer_array(writer, panel.items_num, panel.items_array);
for (bNodeTreeInterfaceItem *child_item : panel.items()) {
item_write_struct(writer, *child_item);
@ -595,6 +598,7 @@ static void item_read_data(BlendDataReader *reader, bNodeTreeInterfaceItem &item
case NODE_INTERFACE_PANEL: {
bNodeTreeInterfacePanel &panel = reinterpret_cast<bNodeTreeInterfacePanel &>(item);
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));
for (const int i : blender::IndexRange(panel.items_num)) {
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 description,
blender::StringRefNull socket_type,
const eNodeTreeInterfaceSocketFlag flag)
const NodeTreeInterfaceSocketFlag flag)
{
BLI_assert(name.c_str() != nullptr);
BLI_assert(socket_type.c_str() != nullptr);
@ -1042,14 +1046,19 @@ static bNodeTreeInterfaceSocket *make_socket(const int uid,
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);
bNodeTreeInterfacePanel *new_panel = MEM_cnew<bNodeTreeInterfacePanel>(__func__);
new_panel->item.item_type = NODE_INTERFACE_PANEL;
new_panel->name = BLI_strdup(name.c_str());
new_panel->description = BLI_strdup_null(description.c_str());
new_panel->identifier = uid;
new_panel->flag = flag;
return new_panel;
}
@ -1148,7 +1157,7 @@ void bNodeTreeInterface::active_item_set(bNodeTreeInterfaceItem *item)
bNodeTreeInterfaceSocket *bNodeTreeInterface::add_socket(blender::StringRefNull name,
blender::StringRefNull description,
blender::StringRefNull socket_type,
const eNodeTreeInterfaceSocketFlag flag,
const NodeTreeInterfaceSocketFlag flag,
bNodeTreeInterfacePanel *parent)
{
if (parent == nullptr) {
@ -1168,7 +1177,7 @@ bNodeTreeInterfaceSocket *bNodeTreeInterface::insert_socket(
blender::StringRefNull name,
blender::StringRefNull description,
blender::StringRefNull socket_type,
const eNodeTreeInterfaceSocketFlag flag,
const NodeTreeInterfaceSocketFlag flag,
bNodeTreeInterfacePanel *parent,
const int position)
{
@ -1186,6 +1195,8 @@ bNodeTreeInterfaceSocket *bNodeTreeInterface::insert_socket(
}
bNodeTreeInterfacePanel *bNodeTreeInterface::add_panel(blender::StringRefNull name,
blender::StringRefNull description,
const NodeTreeInterfacePanelFlag flag,
bNodeTreeInterfacePanel *parent)
{
if (parent == nullptr) {
@ -1193,7 +1204,7 @@ bNodeTreeInterfacePanel *bNodeTreeInterface::add_panel(blender::StringRefNull na
}
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) {
parent->add_item(new_panel->item);
}
@ -1201,6 +1212,8 @@ bNodeTreeInterfacePanel *bNodeTreeInterface::add_panel(blender::StringRefNull na
}
bNodeTreeInterfacePanel *bNodeTreeInterface::insert_panel(blender::StringRefNull name,
blender::StringRefNull description,
const NodeTreeInterfacePanelFlag flag,
bNodeTreeInterfacePanel *parent,
const int position)
{
@ -1209,7 +1222,7 @@ bNodeTreeInterfacePanel *bNodeTreeInterface::insert_panel(blender::StringRefNull
}
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) {
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;
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_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);
}
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_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) {
/* XXX Socket template only draws in embossed layouts (Julian). */
uiLayoutSetEmboss(input_socket_layout, UI_EMBOSS);
/* XXX Context is not used by the template function. */
bContext *C = nullptr;
uiTemplateNodeSocket(input_socket_layout, C, socket_.socket_color());
/* Context is not used by the template function. */
uiTemplateNodeSocket(input_socket_layout, /*C*/ nullptr, socket_.socket_color());
}
else {
/* Blank item to align output socket labels with inputs. */
@ -117,9 +116,8 @@ class NodeSocketViewItem : public BasicTreeViewItem {
if (socket_.flag & NODE_INTERFACE_SOCKET_OUTPUT) {
/* XXX Socket template only draws in embossed layouts (Julian). */
uiLayoutSetEmboss(output_socket_layout, UI_EMBOSS);
/* XXX Context is not used by the template function. */
bContext *C = nullptr;
uiTemplateNodeSocket(output_socket_layout, C, socket_.socket_color());
/* Context is not used by the template function. */
uiTemplateNodeSocket(output_socket_layout, /*C*/ nullptr, socket_.socket_color());
}
else {
/* 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. */
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_OUT, NODE_INTERFACE_SOCKET_OUTPUT);
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 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_OUT, NODE_INTERFACE_SOCKET_OUTPUT);

View File

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

View File

@ -53,13 +53,13 @@ typedef struct bNodeTreeInterfaceItem {
} bNodeTreeInterfaceItem;
/* Socket interface flags */
typedef enum eNodeTreeInterfaceSocketFlag {
typedef enum NodeTreeInterfaceSocketFlag {
NODE_INTERFACE_SOCKET_INPUT = 1 << 0,
NODE_INTERFACE_SOCKET_OUTPUT = 1 << 1,
NODE_INTERFACE_SOCKET_HIDE_VALUE = 1 << 2,
NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER = 1 << 3,
} eNodeTreeInterfaceSocketFlag;
ENUM_OPERATORS(eNodeTreeInterfaceSocketFlag, NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER);
} NodeTreeInterfaceSocketFlag;
ENUM_OPERATORS(NodeTreeInterfaceSocketFlag, NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER);
typedef struct bNodeTreeInterfaceSocket {
bNodeTreeInterfaceItem item;
@ -101,11 +101,21 @@ typedef struct bNodeTreeInterfaceSocket {
#endif
} 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 {
bNodeTreeInterfaceItem item;
/* UI name of the panel. */
char *name;
char *description;
/* eNodeTreeInterfacePanelFlag */
int flag;
char _pad[4];
bNodeTreeInterfaceItem **items_array;
int items_num;
@ -258,7 +268,7 @@ typedef struct bNodeTreeInterface {
bNodeTreeInterfaceSocket *add_socket(blender::StringRefNull name,
blender::StringRefNull description,
blender::StringRefNull socket_type,
eNodeTreeInterfaceSocketFlag flag,
NodeTreeInterfaceSocketFlag flag,
bNodeTreeInterfacePanel *parent);
/**
* Insert a new socket.
@ -269,7 +279,7 @@ typedef struct bNodeTreeInterface {
bNodeTreeInterfaceSocket *insert_socket(blender::StringRefNull name,
blender::StringRefNull description,
blender::StringRefNull socket_type,
eNodeTreeInterfaceSocketFlag flag,
NodeTreeInterfaceSocketFlag flag,
bNodeTreeInterfacePanel *parent,
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
* 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.
* \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.
*/
bNodeTreeInterfacePanel *insert_panel(blender::StringRefNull name,
blender::StringRefNull description,
const NodeTreeInterfacePanelFlag flag,
bNodeTreeInterfacePanel *parent,
int position);

View File

@ -415,7 +415,7 @@ static bNodeTreeInterfaceSocket *rna_NodeTreeInterfaceItems_new_socket(
}
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_output, NODE_INTERFACE_SOCKET_OUTPUT);
@ -443,6 +443,8 @@ static bNodeTreeInterfacePanel *rna_NodeTreeInterfaceItems_new_panel(
Main *bmain,
ReportList *reports,
const char *name,
const char *description,
bool default_closed,
bNodeTreeInterfacePanel *parent)
{
if (parent != nullptr && !interface->find_item(parent->item)) {
@ -450,7 +452,11 @@ static bNodeTreeInterfacePanel *rna_NodeTreeInterfaceItems_new_panel(
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) {
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_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);
RNA_def_property_collection_sdna(prop, nullptr, "items_array", "items_num");
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_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");
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_pointer(func,
"parent",

View File

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