Nodes: improve inserting nodes with link-drag-search
This makes link-drag-search more convenient when one wants to insert a new node between existing nodes. The change currently also affects normal node-insertion when dragging it. The exact behavior still has to be figured out. Pull Request: https://projects.blender.org/blender/blender/pulls/128197
This commit is contained in:
@@ -27,7 +27,14 @@ namespace blender::ed::space_node {
|
||||
|
||||
VectorSet<bNode *> get_selected_nodes(bNodeTree &node_tree);
|
||||
|
||||
void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion ®ion, bool attach_enabled);
|
||||
/**
|
||||
* \param is_new_node: If the node was just inserted, it is allowed to be inserted in a link, even
|
||||
* if it is linked already (after link-drag-search).
|
||||
*/
|
||||
void node_insert_on_link_flags_set(SpaceNode &snode,
|
||||
const ARegion ®ion,
|
||||
bool attach_enabled,
|
||||
bool is_new_node);
|
||||
|
||||
/**
|
||||
* Assumes link with #NODE_LINK_INSERT_TARGET set.
|
||||
|
||||
@@ -2255,18 +2255,6 @@ static bNode *get_selected_node_for_insertion(bNodeTree &node_tree)
|
||||
if (selected_node->input_sockets().is_empty() || selected_node->output_sockets().is_empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (std::any_of(selected_node->input_sockets().begin(),
|
||||
selected_node->input_sockets().end(),
|
||||
[&](const bNodeSocket *socket) { return socket->is_directly_linked(); }))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (std::any_of(selected_node->output_sockets().begin(),
|
||||
selected_node->output_sockets().end(),
|
||||
[&](const bNodeSocket *socket) { return socket->is_directly_linked(); }))
|
||||
{
|
||||
return nullptr;
|
||||
};
|
||||
return selected_node;
|
||||
}
|
||||
|
||||
@@ -2298,7 +2286,8 @@ static bool node_can_be_inserted_on_link(bNodeTree &tree, bNode &node, const bNo
|
||||
|
||||
void node_insert_on_link_flags_set(SpaceNode &snode,
|
||||
const ARegion ®ion,
|
||||
const bool attach_enabled)
|
||||
const bool attach_enabled,
|
||||
const bool is_new_node)
|
||||
{
|
||||
bNodeTree &node_tree = *snode.edittree;
|
||||
node_tree.ensure_topology_cache();
|
||||
@@ -2309,6 +2298,16 @@ void node_insert_on_link_flags_set(SpaceNode &snode,
|
||||
if (!node_to_insert) {
|
||||
return;
|
||||
}
|
||||
Vector<bNodeSocket *> already_linked_sockets;
|
||||
for (bNodeSocket *socket : node_to_insert->input_sockets()) {
|
||||
already_linked_sockets.extend(socket->directly_linked_sockets());
|
||||
}
|
||||
for (bNodeSocket *socket : node_to_insert->output_sockets()) {
|
||||
already_linked_sockets.extend(socket->directly_linked_sockets());
|
||||
}
|
||||
if (!is_new_node && !already_linked_sockets.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find link to select/highlight. */
|
||||
bNodeLink *selink = nullptr;
|
||||
@@ -2317,6 +2316,24 @@ void node_insert_on_link_flags_set(SpaceNode &snode,
|
||||
if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
|
||||
continue;
|
||||
}
|
||||
if (ELEM(node_to_insert, link->fromnode, link->tonode)) {
|
||||
/* Don't insert on a link that is connected to the node already. */
|
||||
continue;
|
||||
}
|
||||
if (is_new_node && !already_linked_sockets.is_empty()) {
|
||||
/* Only allow links coming from or going to the already linked socket after
|
||||
* link-drag-search. */
|
||||
bool is_linked_to_linked = false;
|
||||
for (const bNodeSocket *socket : already_linked_sockets) {
|
||||
if (ELEM(socket, link->fromsock, link->tosock)) {
|
||||
is_linked_to_linked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!is_linked_to_linked) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::array<float2, NODE_LINK_RESOL + 1> coords;
|
||||
node_link_bezier_points_evaluated(*link, coords);
|
||||
@@ -2407,6 +2424,8 @@ void node_insert_on_link_flags(Main &bmain, SpaceNode &snode)
|
||||
bNodeSocket *from_socket = old_link->fromsock;
|
||||
bNode *to_node = old_link->tonode;
|
||||
|
||||
const bool best_input_is_linked = best_input && best_input->is_directly_linked();
|
||||
|
||||
if (best_output != nullptr) {
|
||||
/* Relink the "start" of the existing link to the newly inserted node. */
|
||||
old_link->fromnode = node_to_insert;
|
||||
@@ -2418,8 +2437,11 @@ void node_insert_on_link_flags(Main &bmain, SpaceNode &snode)
|
||||
}
|
||||
|
||||
if (best_input != nullptr) {
|
||||
/* Add a new link that connects the node on the left to the newly inserted node. */
|
||||
bke::node_add_link(&ntree, from_node, from_socket, node_to_insert, best_input);
|
||||
/* Don't change an existing link. */
|
||||
if (!best_input_is_linked) {
|
||||
/* Add a new link that connects the node on the left to the newly inserted node. */
|
||||
bke::node_add_link(&ntree, from_node, from_socket, node_to_insert, best_input);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up insert offset data, it needs stuff from here. */
|
||||
|
||||
@@ -35,6 +35,8 @@ struct TransCustomDataNode {
|
||||
|
||||
/* Compare if the view has changed so we can update with `transformViewUpdate`. */
|
||||
rctf viewrect_prev;
|
||||
|
||||
bool is_new_node;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -109,8 +111,10 @@ static void createTransNodeData(bContext * /*C*/, TransInfo *t)
|
||||
NODE_EDGE_PAN_DELAY,
|
||||
NODE_EDGE_PAN_ZOOM_INFLUENCE);
|
||||
customdata->viewrect_prev = customdata->edgepan_data.initial_rect;
|
||||
customdata->is_new_node = t->remove_on_cancel;
|
||||
|
||||
space_node::node_insert_on_link_flags_set(*snode, *t->region, t->modifiers & MOD_NODE_ATTACH);
|
||||
space_node::node_insert_on_link_flags_set(
|
||||
*snode, *t->region, t->modifiers & MOD_NODE_ATTACH, customdata->is_new_node);
|
||||
|
||||
t->custom.type.data = customdata;
|
||||
t->custom.type.use_free = true;
|
||||
@@ -239,7 +243,7 @@ static void flushTransNodes(TransInfo *t)
|
||||
/* Handle intersection with noodles. */
|
||||
if (tc->data_len == 1) {
|
||||
space_node::node_insert_on_link_flags_set(
|
||||
*snode, *t->region, t->modifiers & MOD_NODE_ATTACH);
|
||||
*snode, *t->region, t->modifiers & MOD_NODE_ATTACH, customdata->is_new_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user