Geometry Nodes: shortcuts for viewer nodes
Implement shortcuts for viewer nodes. Viewer nodes are now activated using the operator `bpy.ops.node.activate_viewer()` instead of activating the viewer by setting the node to active. This also unifies the behavior with viewer shortcuts in the compositor (see attachment in the original PR). Pull Request: https://projects.blender.org/blender/blender/pulls/134555
This commit is contained in:
@@ -3608,14 +3608,16 @@ void node_tree_free_local_tree(bNodeTree *ntree)
|
||||
void node_tree_set_output(bNodeTree &ntree)
|
||||
{
|
||||
const bool is_compositor = ntree.type == NTREE_COMPOSIT;
|
||||
const bool is_geometry = ntree.type == NTREE_GEOMETRY;
|
||||
/* find the active outputs, might become tree type dependent handler */
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
|
||||
if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
|
||||
/* we need a check for which output node should be tagged like this, below an exception */
|
||||
if (ELEM(node->type_legacy, CMP_NODE_OUTPUT_FILE, GEO_NODE_VIEWER)) {
|
||||
if (node->is_type("CompositorNodeOutputFile")) {
|
||||
continue;
|
||||
}
|
||||
const bool node_is_output = node->type_legacy == CMP_NODE_VIEWER;
|
||||
const bool node_is_output = node->is_type("CompositorNodeViewer") ||
|
||||
node->is_type("GeometryNodeViewer");
|
||||
|
||||
int output = 0;
|
||||
/* there is more types having output class, each one is checked */
|
||||
@@ -3626,12 +3628,15 @@ void node_tree_set_output(bNodeTree &ntree)
|
||||
}
|
||||
|
||||
/* same type, exception for viewer */
|
||||
const bool tnode_is_output = tnode->type_legacy == CMP_NODE_VIEWER;
|
||||
const bool compositor_case = is_compositor && tnode_is_output && node_is_output;
|
||||
const bool has_same_shortcut = compositor_case && node != tnode &&
|
||||
const bool tnode_is_output = tnode->is_type("CompositorNodeViewer") ||
|
||||
tnode->is_type("GeometryNodeViewer");
|
||||
const bool viewer_case = (is_compositor || is_geometry) && tnode_is_output &&
|
||||
node_is_output;
|
||||
const bool has_same_shortcut = viewer_case && node != tnode &&
|
||||
tnode->custom1 == node->custom1 &&
|
||||
tnode->custom1 != NODE_VIEWER_SHORTCUT_NONE;
|
||||
if (tnode->type_legacy == node->type_legacy || compositor_case) {
|
||||
|
||||
if (tnode->type_legacy == node->type_legacy || viewer_case) {
|
||||
if (tnode->flag & NODE_DO_OUTPUT) {
|
||||
output++;
|
||||
if (output > 1) {
|
||||
|
||||
@@ -3317,7 +3317,7 @@ static void node_draw_extra_info_panel(const bContext &C,
|
||||
|
||||
static short get_viewer_shortcut_icon(const bNode &node)
|
||||
{
|
||||
BLI_assert(node.is_type("CompositorNodeViewer"));
|
||||
BLI_assert(node.is_type("CompositorNodeViewer") || node.is_type("GeometryNodeViewer"));
|
||||
switch (node.custom1) {
|
||||
case NODE_VIEWER_SHORTCUT_NONE:
|
||||
/* No change by default. */
|
||||
@@ -3532,9 +3532,24 @@ static void node_draw_basis(const bContext &C,
|
||||
0,
|
||||
"");
|
||||
/* Selection implicitly activates the node. */
|
||||
const char *operator_idname = is_active ? "NODE_OT_deactivate_viewer" : "NODE_OT_select";
|
||||
const char *operator_idname = is_active ? "NODE_OT_deactivate_viewer" :
|
||||
"NODE_OT_activate_viewer";
|
||||
UI_but_func_set(
|
||||
but, node_toggle_button_cb, POINTER_FROM_INT(node.identifier), (void *)operator_idname);
|
||||
|
||||
short shortcut_icon = get_viewer_shortcut_icon(node);
|
||||
uiDefIconBut(&block,
|
||||
UI_BTYPE_BUT,
|
||||
0,
|
||||
shortcut_icon,
|
||||
iconofs - 1.2 * iconbutw,
|
||||
rct.ymax - NODE_DY,
|
||||
iconbutw,
|
||||
UI_UNIT_Y,
|
||||
nullptr,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
UI_block_emboss_set(&block, UI_EMBOSS);
|
||||
}
|
||||
/* Viewer node shortcuts. */
|
||||
|
||||
@@ -1344,18 +1344,40 @@ static void rna_NodeTree_active_node_set(PointerRNA *ptr,
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_Node_shortcut_node_set(PointerRNA *ptr, int value)
|
||||
static void node_viewer_set_shortcut_fn(bNode *node, bNodeTree &ntree, int value)
|
||||
{
|
||||
/* Avoid having two nodes with the same shortcut. */
|
||||
for (bNode *other_node : ntree.all_nodes()) {
|
||||
if ((other_node->is_type("CompositorNodeViewer") ||
|
||||
other_node->is_type("GeometryNodeViewer")) &&
|
||||
other_node->custom1 == value)
|
||||
{
|
||||
other_node->custom1 = NODE_VIEWER_SHORTCUT_NONE;
|
||||
}
|
||||
}
|
||||
node->custom1 = value;
|
||||
}
|
||||
|
||||
void rna_Node_Viewer_shortcut_node_set(PointerRNA *ptr, PropertyRNA * /*prop*/, int value)
|
||||
{
|
||||
bNode *curr_node = static_cast<bNode *>(ptr->data);
|
||||
bNodeTree &ntree = curr_node->owner_tree();
|
||||
|
||||
/* Avoid having two nodes with the same shortcut. */
|
||||
for (bNode *node : ntree.all_nodes()) {
|
||||
if (node->is_type("CompositorNodeViewer") && node->custom1 == value) {
|
||||
node->custom1 = NODE_VIEWER_SHORTCUT_NONE;
|
||||
}
|
||||
}
|
||||
curr_node->custom1 = value;
|
||||
node_viewer_set_shortcut_fn(curr_node, ntree, value);
|
||||
}
|
||||
|
||||
int rna_Node_Viewer_shortcut_node_get(PointerRNA *ptr, PropertyRNA * /*prop*/)
|
||||
{
|
||||
bNode *curr_node = static_cast<bNode *>(ptr->data);
|
||||
return curr_node->custom1;
|
||||
}
|
||||
|
||||
void rna_Node_Viewer_shortcut_node_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
bNode *curr_node = static_cast<bNode *>(ptr->data);
|
||||
bNodeTree &ntree = curr_node->owner_tree();
|
||||
|
||||
node_viewer_set_shortcut_fn(curr_node, ntree, value);
|
||||
}
|
||||
|
||||
static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree,
|
||||
@@ -9164,7 +9186,7 @@ static void def_cmp_viewer(BlenderRNA * /*brna*/, StructRNA *srna)
|
||||
|
||||
prop = RNA_def_property(srna, "ui_shortcut", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, nullptr, "custom1");
|
||||
RNA_def_property_int_funcs(prop, nullptr, "rna_Node_shortcut_node_set", nullptr);
|
||||
RNA_def_property_int_funcs(prop, nullptr, "rna_Node_Viewer_shortcut_node_set", nullptr);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
|
||||
RNA_def_property_int_default(prop, NODE_VIEWER_SHORTCUT_NONE);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
void rna_Node_update(Main *bmain, Scene *scene, PointerRNA *ptr);
|
||||
void rna_Node_socket_update(Main *bmain, Scene *scene, PointerRNA *ptr);
|
||||
void rna_Node_update_relations(Main *bmain, Scene *scne, PointerRNA *ptr);
|
||||
void rna_Node_Viewer_shortcut_node_set(PointerRNA *ptr, PropertyRNA *prop, int value);
|
||||
int rna_Node_Viewer_shortcut_node_get(PointerRNA *ptr, PropertyRNA *prop);
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
|
||||
@@ -138,6 +138,15 @@ static void node_rna(StructRNA *srna)
|
||||
rna_enum_attribute_domain_with_auto_items,
|
||||
NOD_storage_enum_accessors(domain),
|
||||
int(AttrDomain::Point));
|
||||
|
||||
PropertyRNA *prop;
|
||||
prop = RNA_def_property(srna, "ui_shortcut", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_funcs_runtime(
|
||||
prop, rna_Node_Viewer_shortcut_node_get, rna_Node_Viewer_shortcut_node_set, nullptr);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
|
||||
RNA_def_property_int_default(prop, NODE_VIEWER_SHORTCUT_NONE);
|
||||
RNA_def_property_update_notifier(prop, NC_NODE | ND_DISPLAY);
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
|
||||
Reference in New Issue
Block a user