Nodes: Moved group interface panel code to python.
The node group interface panels were still implemented in C. Now they ported over to python for easier maintenance. Differential Revision: https://developer.blender.org/D11834
This commit is contained in:
@@ -694,6 +694,97 @@ class NODE_UL_interface_sockets(bpy.types.UIList):
|
||||
layout.template_node_socket(color=color)
|
||||
|
||||
|
||||
class NodeTreeInterfacePanel:
|
||||
def draw_socket_list(self, context, in_out, sockets_propname, active_socket_propname):
|
||||
layout = self.layout
|
||||
|
||||
snode = context.space_data
|
||||
tree = snode.edit_tree
|
||||
sockets = getattr(tree, sockets_propname)
|
||||
active_socket_index = getattr(tree, active_socket_propname)
|
||||
active_socket = sockets[active_socket_index] if active_socket_index >= 0 else None
|
||||
|
||||
split = layout.row()
|
||||
|
||||
split.template_list("NODE_UL_interface_sockets", in_out, tree, sockets_propname, tree, active_socket_propname)
|
||||
|
||||
ops_col = split.column()
|
||||
|
||||
add_remove_col = ops_col.column(align=True)
|
||||
props = add_remove_col.operator("node.tree_socket_add", icon='ADD', text="")
|
||||
props.in_out = in_out
|
||||
props = add_remove_col.operator("node.tree_socket_remove", icon='REMOVE', text="")
|
||||
props.in_out = in_out
|
||||
|
||||
ops_col.separator()
|
||||
|
||||
up_down_col = ops_col.column(align=True)
|
||||
props = up_down_col.operator("node.tree_socket_move", icon='TRIA_UP', text="")
|
||||
props.in_out = in_out
|
||||
props.direction = 'UP'
|
||||
props = up_down_col.operator("node.tree_socket_move", icon='TRIA_DOWN', text="")
|
||||
props.in_out = in_out
|
||||
props.direction = 'DOWN'
|
||||
|
||||
if active_socket is not None:
|
||||
# Mimicking property split.
|
||||
layout.use_property_split = False
|
||||
layout.use_property_decorate = False
|
||||
layout_row = layout.row(align=True)
|
||||
layout_split = layout_row.split(factor=0.4, align=True)
|
||||
|
||||
label_column = layout_split.column(align=True)
|
||||
label_column.alignment = 'RIGHT'
|
||||
# Menu to change the socket type.
|
||||
label_column.label(text="Type")
|
||||
|
||||
property_row = layout_split.row(align=True)
|
||||
props = property_row.operator_menu_enum(
|
||||
"node.tree_socket_change_type",
|
||||
"socket_type",
|
||||
text=active_socket.bl_label if active_socket.bl_label else active_socket.bl_idname
|
||||
)
|
||||
props.in_out = in_out
|
||||
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
layout.prop(active_socket, "name")
|
||||
# Display descriptions only for Geometry Nodes, since it's only used in the modifier panel.
|
||||
if tree.type == 'GEOMETRY':
|
||||
layout.prop(active_socket, "description")
|
||||
active_socket.draw(context, layout)
|
||||
|
||||
|
||||
class NODE_PT_node_tree_interface_inputs(NodeTreeInterfacePanel, Panel):
|
||||
bl_space_type = 'NODE_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = "Group"
|
||||
bl_label = "Inputs"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
snode = context.space_data
|
||||
return snode.edit_tree is not None
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_socket_list(context, "IN", "inputs", "active_input")
|
||||
|
||||
class NODE_PT_node_tree_interface_outputs(NodeTreeInterfacePanel, Panel):
|
||||
bl_space_type = 'NODE_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = "Group"
|
||||
bl_label = "Outputs"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
snode = context.space_data
|
||||
return snode.edit_tree is not None
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_socket_list(context, "OUT", "outputs", "active_output")
|
||||
|
||||
|
||||
# Grease Pencil properties
|
||||
class NODE_PT_annotation(AnnotationDataPanel, Panel):
|
||||
bl_space_type = 'NODE_EDITOR'
|
||||
@@ -752,6 +843,8 @@ classes = (
|
||||
NODE_PT_quality,
|
||||
NODE_PT_annotation,
|
||||
NODE_UL_interface_sockets,
|
||||
NODE_PT_node_tree_interface_inputs,
|
||||
NODE_PT_node_tree_interface_outputs,
|
||||
|
||||
node_panel(EEVEE_MATERIAL_PT_settings),
|
||||
node_panel(MATERIAL_PT_viewport),
|
||||
|
||||
@@ -40,7 +40,6 @@ set(INC
|
||||
set(SRC
|
||||
drawnode.cc
|
||||
node_add.cc
|
||||
node_buttons.c
|
||||
node_draw.cc
|
||||
node_edit.cc
|
||||
node_geometry_attribute_search.cc
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2009 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup spnode
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_node_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "node_intern.h" /* own include */
|
||||
|
||||
/* ******************* node space & buttons ************** */
|
||||
|
||||
#if 0
|
||||
/* poll for active nodetree */
|
||||
static bool active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt))
|
||||
{
|
||||
SpaceNode *snode = CTX_wm_space_node(C);
|
||||
|
||||
return (snode && snode->nodetree);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool node_sockets_poll(const bContext *C, PanelType *UNUSED(pt))
|
||||
{
|
||||
SpaceNode *snode = CTX_wm_space_node(C);
|
||||
|
||||
return (snode && snode->nodetree && G.debug_value == 777);
|
||||
}
|
||||
|
||||
static void node_sockets_panel(const bContext *C, Panel *panel)
|
||||
{
|
||||
SpaceNode *snode = CTX_wm_space_node(C); /* NULL checked in poll function. */
|
||||
bNodeTree *ntree = snode->edittree; /* NULL checked in poll function. */
|
||||
bNode *node = nodeGetActive(ntree);
|
||||
if (node == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
|
||||
char name[UI_MAX_NAME_STR];
|
||||
BLI_snprintf(name, sizeof(name), "%s:", socket->name);
|
||||
|
||||
uiLayout *split = uiLayoutSplit(panel->layout, 0.35f, false);
|
||||
uiItemL(split, name, ICON_NONE);
|
||||
uiTemplateNodeLink(split, (bContext *)C, ntree, node, socket);
|
||||
}
|
||||
}
|
||||
|
||||
static bool node_tree_interface_poll(const bContext *C, PanelType *UNUSED(pt))
|
||||
{
|
||||
SpaceNode *snode = CTX_wm_space_node(C);
|
||||
|
||||
return (snode && snode->edittree &&
|
||||
(snode->edittree->inputs.first || snode->edittree->outputs.first));
|
||||
}
|
||||
|
||||
static bNodeSocket *node_tree_find_active_socket(bNodeTree *ntree, const eNodeSocketInOut in_out)
|
||||
{
|
||||
ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs;
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, sockets) {
|
||||
if (socket->flag & SELECT) {
|
||||
return socket;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void draw_socket_list(const bContext *C,
|
||||
uiLayout *layout,
|
||||
bNodeTree *ntree,
|
||||
const eNodeSocketInOut in_out)
|
||||
{
|
||||
PointerRNA tree_ptr;
|
||||
RNA_id_pointer_create((ID *)ntree, &tree_ptr);
|
||||
|
||||
uiLayout *split = uiLayoutRow(layout, false);
|
||||
uiLayout *list_col = uiLayoutColumn(split, true);
|
||||
uiTemplateList(list_col,
|
||||
(bContext *)C,
|
||||
"NODE_UL_interface_sockets",
|
||||
(in_out == SOCK_IN) ? "inputs" : "outputs",
|
||||
&tree_ptr,
|
||||
(in_out == SOCK_IN) ? "inputs" : "outputs",
|
||||
&tree_ptr,
|
||||
(in_out == SOCK_IN) ? "active_input" : "active_output",
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
false);
|
||||
PointerRNA opptr;
|
||||
uiLayout *ops_col = uiLayoutColumn(split, false);
|
||||
uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
|
||||
wmOperatorType *ot = WM_operatortype_find("NODE_OT_tree_socket_add", false);
|
||||
uiItemFullO_ptr(add_remove_col, ot, "", ICON_ADD, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
|
||||
RNA_enum_set(&opptr, "in_out", in_out);
|
||||
ot = WM_operatortype_find("NODE_OT_tree_socket_remove", false);
|
||||
uiItemFullO_ptr(add_remove_col, ot, "", ICON_REMOVE, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
|
||||
RNA_enum_set(&opptr, "in_out", in_out);
|
||||
|
||||
uiItemS(ops_col);
|
||||
|
||||
uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
|
||||
ot = WM_operatortype_find("NODE_OT_tree_socket_move", false);
|
||||
uiItemFullO_ptr(up_down_col, ot, "", ICON_TRIA_UP, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
|
||||
RNA_enum_set(&opptr, "direction", 1);
|
||||
RNA_enum_set(&opptr, "in_out", in_out);
|
||||
uiItemFullO_ptr(up_down_col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
|
||||
RNA_enum_set(&opptr, "direction", 2);
|
||||
RNA_enum_set(&opptr, "in_out", in_out);
|
||||
|
||||
bNodeSocket *socket = node_tree_find_active_socket(ntree, in_out);
|
||||
if (socket != NULL) {
|
||||
PointerRNA socket_ptr;
|
||||
RNA_pointer_create((ID *)ntree, &RNA_NodeSocketInterface, socket, &socket_ptr);
|
||||
|
||||
{
|
||||
/* Mimicking property split */
|
||||
uiLayoutSetPropSep(layout, false);
|
||||
uiLayoutSetPropDecorate(layout, false);
|
||||
uiLayout *layout_row = uiLayoutRow(layout, true);
|
||||
uiLayout *layout_split = uiLayoutSplit(layout_row, 0.4f, true);
|
||||
|
||||
uiLayout *label_column = uiLayoutColumn(layout_split, true);
|
||||
uiLayoutSetAlignment(label_column, UI_LAYOUT_ALIGN_RIGHT);
|
||||
/* Menu to change the socket type. */
|
||||
uiItemL(label_column, "Type", ICON_NONE);
|
||||
|
||||
uiLayout *property_row = uiLayoutRow(layout_split, true);
|
||||
|
||||
PointerRNA props_ptr;
|
||||
uiItemMenuEnumFullO(property_row,
|
||||
(bContext *)C,
|
||||
"NODE_OT_tree_socket_change_type",
|
||||
"socket_type",
|
||||
nodeSocketTypeLabel(socket->typeinfo),
|
||||
ICON_NONE,
|
||||
&props_ptr);
|
||||
RNA_enum_set(&props_ptr, "in_out", in_out);
|
||||
}
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
uiLayoutSetPropDecorate(layout, false);
|
||||
|
||||
uiItemR(layout, &socket_ptr, "name", 0, NULL, ICON_NONE);
|
||||
|
||||
/* Display descriptions only for Geometry Nodes, since it's only used in the modifier panel. */
|
||||
if (ntree->type == NTREE_GEOMETRY) {
|
||||
uiItemR(layout, &socket_ptr, "description", 0, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
if (socket->typeinfo->interface_draw) {
|
||||
socket->typeinfo->interface_draw((bContext *)C, layout, &socket_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void node_tree_interface_inputs_panel(const bContext *C, Panel *panel)
|
||||
{
|
||||
SpaceNode *snode = CTX_wm_space_node(C); /* NULL checked in poll function. */
|
||||
bNodeTree *ntree = snode->edittree; /* NULL checked in poll function. */
|
||||
|
||||
draw_socket_list(C, panel->layout, ntree, SOCK_IN);
|
||||
}
|
||||
|
||||
static void node_tree_interface_outputs_panel(const bContext *C, Panel *panel)
|
||||
{
|
||||
SpaceNode *snode = CTX_wm_space_node(C); /* NULL checked in poll function. */
|
||||
bNodeTree *ntree = snode->edittree; /* NULL checked in poll function. */
|
||||
|
||||
draw_socket_list(C, panel->layout, ntree, SOCK_OUT);
|
||||
}
|
||||
|
||||
/* ******************* node buttons registration ************** */
|
||||
|
||||
void node_buttons_register(ARegionType *art)
|
||||
{
|
||||
{
|
||||
PanelType *pt = MEM_callocN(sizeof(PanelType), __func__);
|
||||
strcpy(pt->idname, "NODE_PT_sockets");
|
||||
strcpy(pt->category, N_("Node"));
|
||||
strcpy(pt->label, N_("Sockets"));
|
||||
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
pt->draw = node_sockets_panel;
|
||||
pt->poll = node_sockets_poll;
|
||||
pt->flag |= PANEL_TYPE_DEFAULT_CLOSED;
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
}
|
||||
|
||||
{
|
||||
PanelType *pt = MEM_callocN(sizeof(PanelType), __func__);
|
||||
strcpy(pt->idname, "NODE_PT_node_tree_interface_inputs");
|
||||
strcpy(pt->category, N_("Group"));
|
||||
strcpy(pt->label, N_("Inputs"));
|
||||
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
pt->draw = node_tree_interface_inputs_panel;
|
||||
pt->poll = node_tree_interface_poll;
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
}
|
||||
{
|
||||
PanelType *pt = MEM_callocN(sizeof(PanelType), __func__);
|
||||
strcpy(pt->idname, "NODE_PT_node_tree_interface_outputs");
|
||||
strcpy(pt->category, N_("Group"));
|
||||
strcpy(pt->label, N_("Outputs"));
|
||||
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
pt->draw = node_tree_interface_outputs_panel;
|
||||
pt->poll = node_tree_interface_poll;
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
}
|
||||
}
|
||||
@@ -140,9 +140,6 @@ void node_to_view(const struct bNode *node, float x, float y, float *rx, float *
|
||||
void node_to_updated_rect(const struct bNode *node, rctf *r_rect);
|
||||
void node_from_view(const struct bNode *node, float x, float y, float *rx, float *ry);
|
||||
|
||||
/* node_buttons.c */
|
||||
void node_buttons_register(struct ARegionType *art);
|
||||
|
||||
/* node_toolbar.c */
|
||||
void node_toolbar_register(struct ARegionType *art);
|
||||
|
||||
|
||||
@@ -1098,8 +1098,6 @@ void ED_spacetype_node(void)
|
||||
art->draw = node_buttons_region_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
node_buttons_register(art);
|
||||
|
||||
/* regions: toolbar */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
|
||||
art->regionid = RGN_TYPE_TOOLS;
|
||||
|
||||
@@ -3205,7 +3205,7 @@ static void rna_NodeSocketInterfaceStandard_draw(ID *id,
|
||||
struct uiLayout *layout)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(id, &RNA_NodeSocket, sock, &ptr);
|
||||
RNA_pointer_create(id, &RNA_NodeSocketInterface, sock, &ptr);
|
||||
sock->typeinfo->interface_draw(C, layout, &ptr);
|
||||
}
|
||||
|
||||
@@ -3215,7 +3215,7 @@ static void rna_NodeSocketInterfaceStandard_draw_color(ID *id,
|
||||
float r_color[4])
|
||||
{
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(id, &RNA_NodeSocket, sock, &ptr);
|
||||
RNA_pointer_create(id, &RNA_NodeSocketInterface, sock, &ptr);
|
||||
sock->typeinfo->interface_draw_color(C, &ptr, r_color);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user