Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-05-10 16:04:37 +0300
committerCampbell Barton <campbell@blender.org>2022-05-10 16:04:37 +0300
commitb4b85c5ce2752ea9241cbcfa1ddc3f639ad64262 (patch)
tree967bf4f3baaa9a6be6ff59b8ad300625eb8beace /source/blender/editors/space_node
parentde71cdb35df4790e2596fde12168d849206c663b (diff)
parent4c3e91e5f565b81dd79b5d42f55be5b93662d410 (diff)
Merge branch 'blender-v3.2-release'
Diffstat (limited to 'source/blender/editors/space_node')
-rw-r--r--source/blender/editors/space_node/node_select.cc170
1 files changed, 93 insertions, 77 deletions
diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc
index 1d0097068f1..147cbc5a05c 100644
--- a/source/blender/editors/space_node/node_select.cc
+++ b/source/blender/editors/space_node/node_select.cc
@@ -193,11 +193,6 @@ static bool is_event_over_node_or_socket(bContext *C, const wmEvent *event)
return is_position_over_node_or_socket(*snode, mouse);
}
-static void node_toggle(bNode *node)
-{
- nodeSetSelected(node, !(node->flag & SELECT));
-}
-
void node_socket_select(bNode *node, bNodeSocket &sock)
{
sock.flag |= SELECT;
@@ -510,10 +505,10 @@ void node_select_single(bContext &C, bNode &node)
WM_event_add_notifier(&C, NC_NODE | NA_SELECTED, nullptr);
}
-static int node_mouse_select(bContext *C,
- wmOperator *op,
- const int mval[2],
- bool wait_to_deselect_others)
+static bool node_mouse_select(bContext *C,
+ wmOperator *op,
+ const int mval[2],
+ struct SelectPick_Params *params)
{
Main &bmain = *CTX_data_main(C);
SpaceNode &snode = *CTX_wm_space_node(C);
@@ -525,36 +520,38 @@ static int node_mouse_select(bContext *C,
bNodeSocket *sock = nullptr;
bNodeSocket *tsock;
float cursor[2];
- int ret_value = OPERATOR_CANCELLED;
- const bool extend = RNA_boolean_get(op->ptr, "extend");
/* always do socket_select when extending selection. */
- const bool socket_select = extend || RNA_boolean_get(op->ptr, "socket_select");
- const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
-
- /* These cases are never modal. */
- if (extend || socket_select) {
- wait_to_deselect_others = false;
- }
+ const bool socket_select = (params->sel_op == SEL_OP_XOR) ||
+ RNA_boolean_get(op->ptr, "socket_select");
+ bool changed = false;
+ bool found = false;
+ bool node_was_selected = false;
/* get mouse coordinates in view2d space */
UI_view2d_region_to_view(&region.v2d, mval[0], mval[1], &cursor[0], &cursor[1]);
/* first do socket selection, these generally overlap with nodes. */
if (socket_select) {
+ /* NOTE: unlike nodes #SelectPick_Params isn't fully supported. */
+ const bool extend = (params->sel_op == SEL_OP_XOR);
if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) {
+ found = true;
+ node_was_selected = node->flag & SELECT;
+
/* NOTE: SOCK_IN does not take into account the extend case...
* This feature is not really used anyway currently? */
node_socket_toggle(node, *sock, true);
- ret_value = OPERATOR_FINISHED;
+ changed = true;
}
else if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) {
+ found = true;
+ node_was_selected = node->flag & SELECT;
+
if (sock->flag & SELECT) {
if (extend) {
node_socket_deselect(node, *sock, true);
- }
- else {
- ret_value = OPERATOR_FINISHED;
+ changed = true;
}
}
else {
@@ -566,6 +563,7 @@ static int node_mouse_select(bContext *C,
continue;
}
node_socket_deselect(node, *tsock, true);
+ changed = true;
}
}
if (!extend) {
@@ -575,69 +573,71 @@ static int node_mouse_select(bContext *C,
}
for (tsock = (bNodeSocket *)tnode->outputs.first; tsock; tsock = tsock->next) {
node_socket_deselect(tnode, *tsock, true);
+ changed = true;
}
}
}
node_socket_select(node, *sock);
- ret_value = OPERATOR_FINISHED;
+ changed = true;
}
}
}
if (!sock) {
+
/* find the closest visible node */
node = node_under_mouse_select(*snode.edittree, (int)cursor[0], (int)cursor[1]);
+ found = (node != nullptr);
+ node_was_selected = node && (node->flag & SELECT);
- if (extend) {
- if (node != nullptr) {
- /* If node is selected but not active, we want to make it active,
- * but not toggle (deselect) it. */
- if (!((node->flag & SELECT) && (node->flag & NODE_ACTIVE) == 0)) {
- node_toggle(node);
- }
- ret_value = OPERATOR_FINISHED;
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) && (node->flag & SELECT)) {
+ found = false;
}
- }
- else if (deselect_all && node == nullptr) {
- /* Rather than deselecting others, users may want to drag to box-select (drag from empty
- * space) or tweak-translate an already selected item. If these cases may apply, delay
- * deselection. */
- if (wait_to_deselect_others) {
- ret_value = OPERATOR_RUNNING_MODAL;
- }
- else {
- /* Deselect in empty space. */
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
for (tnode = (bNode *)snode.edittree->nodes.first; tnode; tnode = tnode->next) {
nodeSetSelected(tnode, false);
}
- ret_value = OPERATOR_FINISHED;
+ changed = true;
}
}
- else if (node != nullptr) {
- /* When clicking on an already selected node, we want to wait to deselect
- * others and allow the user to start moving the node without that. */
- if (wait_to_deselect_others && (node->flag & SELECT)) {
- ret_value = OPERATOR_RUNNING_MODAL;
- }
- else {
- nodeSetSelected(node, true);
- for (tnode = (bNode *)snode.edittree->nodes.first; tnode; tnode = tnode->next) {
- if (tnode != node) {
- nodeSetSelected(tnode, false);
- }
+ if (found) {
+ switch (params->sel_op) {
+ case SEL_OP_ADD: {
+ nodeSetSelected(node, true);
+ break;
+ }
+ case SEL_OP_SUB: {
+ nodeSetSelected(node, false);
+ break;
+ }
+ case SEL_OP_XOR: {
+ /* Check active so clicking on an inactive node activates it. */
+ bool is_selected = (node->flag & NODE_SELECT) && (node->flag & NODE_ACTIVE);
+ nodeSetSelected(node, !is_selected);
+ break;
+ }
+ case SEL_OP_SET: {
+ nodeSetSelected(node, true);
+ break;
+ }
+ case SEL_OP_AND: {
+ BLI_assert_unreachable(); /* Doesn't make sense for picking. */
+ break;
}
-
- ret_value = OPERATOR_FINISHED;
}
+
+ changed = true;
}
}
/* update node order */
- if (ret_value != OPERATOR_CANCELLED) {
+ if (changed || found) {
bool active_texture_changed = false;
bool viewer_node_changed = false;
- if (node != nullptr && ret_value != OPERATOR_RUNNING_MODAL) {
+ if ((node != nullptr) && (node_was_selected == false || params->select_passthrough == false)) {
viewer_node_changed = (node->flag & NODE_DO_OUTPUT) == 0 && node->type == GEO_NODE_VIEWER;
ED_node_set_active(&bmain, &snode, snode.edittree, node, &active_texture_changed);
}
@@ -654,23 +654,35 @@ static int node_mouse_select(bContext *C,
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
}
- return ret_value;
+ return changed || found;
}
static int node_select_exec(bContext *C, wmOperator *op)
{
- const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others");
-
/* get settings from RNA properties for operator */
int mval[2];
- mval[0] = RNA_int_get(op->ptr, "mouse_x");
- mval[1] = RNA_int_get(op->ptr, "mouse_y");
+ RNA_int_get_array(op->ptr, "location", mval);
+
+ struct SelectPick_Params params = {};
+ ED_select_pick_params_from_operator(op, &params);
/* perform the select */
- const int ret_value = node_mouse_select(C, op, mval, wait_to_deselect_others);
+ const bool changed = node_mouse_select(C, op, mval, &params);
- /* allow tweak event to work too */
- return ret_value | OPERATOR_PASS_THROUGH;
+ if (changed) {
+ return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
+ }
+ /* Nothing selected, just passthrough. */
+ return OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED;
+}
+
+static int node_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ RNA_int_set_array(op->ptr, "location", event->mval);
+
+ const int retval = node_select_exec(C, op);
+
+ return WM_operator_flag_only_pass_through_on_press(retval, event);
}
void NODE_OT_select(wmOperatorType *ot)
@@ -684,24 +696,28 @@ void NODE_OT_select(wmOperatorType *ot)
/* api callbacks */
ot->exec = node_select_exec;
- ot->invoke = WM_generic_select_invoke;
- ot->modal = WM_generic_select_modal;
+ ot->invoke = node_select_invoke;
ot->poll = ED_operator_node_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_generic_select(ot);
- prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ WM_operator_properties_mouse_select(ot);
+
+ prop = RNA_def_int_vector(ot->srna,
+ "location",
+ 2,
+ NULL,
+ INT_MIN,
+ INT_MAX,
+ "Location",
+ "Mouse location",
+ INT_MIN,
+ INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+
RNA_def_boolean(ot->srna, "socket_select", false, "Socket Select", "");
- prop = RNA_def_boolean(ot->srna,
- "deselect_all",
- false,
- "Deselect On Nothing",
- "Deselect all when nothing under the cursor");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/** \} */