From 1d88aeb95fc40771be7ef3a835af4206c845aa9b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 17 Mar 2022 14:37:20 +1100 Subject: View 3D: support for select passthrough when picking selected items Currently this isn't used in the key-map, it will eventually allow the 3D viewports tweak tool to match the behavior of other editors that support tweaking a selection without first de-selecting all other elements. --- source/blender/editors/armature/armature_select.c | 22 ++- source/blender/editors/armature/pose_select.c | 26 +-- source/blender/editors/curve/editcurve.c | 32 ++-- source/blender/editors/include/ED_select_utils.h | 6 + .../blender/editors/lattice/editlattice_select.c | 31 ++-- source/blender/editors/mesh/editface.c | 10 +- source/blender/editors/mesh/editmesh_select.c | 29 ++-- source/blender/editors/metaball/mball_edit.c | 11 +- source/blender/editors/physics/particle_edit.c | 12 +- .../blender/editors/space_view3d/view3d_select.c | 176 ++++++++++++--------- .../windowmanager/intern/wm_operator_props.c | 8 + 11 files changed, 221 insertions(+), 142 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index d1a5c128c35..08d5d6558e0 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -965,14 +965,20 @@ bool ED_armature_edit_select_pick_bone(bContext *C, } } - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - /* Deselect everything. */ - uint bases_len = 0; - Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data( - view_layer, v3d, &bases_len); - ED_armature_edit_deselect_all_multi_ex(bases, bases_len); - MEM_freeN(bases); - changed = true; + if (params->sel_op == SEL_OP_SET) { + if ((found && params->select_passthrough) && + (ED_armature_ebone_selectflag_get(ebone) & selmask)) { + found = false; + } + else if (found || params->deselect_all) { + /* Deselect everything. */ + uint bases_len = 0; + Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data( + view_layer, v3d, &bases_len); + ED_armature_edit_deselect_all_multi_ex(bases, bases_len); + MEM_freeN(bases); + changed = true; + } } if (found) { diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 1cf56389580..8790a10f3e5 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -136,19 +136,25 @@ bool ED_armature_pose_select_pick_bone(ViewLayer *view_layer, } } - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - /* Don't use 'BKE_object_pose_base_array_get_unique' - * because we may be selecting from object mode. */ - FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) { - Object *ob_iter = base_iter->object; - if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) { - if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) { - ED_pose_bone_select_tag_update(ob_iter); + if (params->sel_op == SEL_OP_SET) { + if ((found && params->select_passthrough) && (bone->flag & BONE_SELECTED)) { + found = false; + } + else if (found || params->deselect_all) { + /* Deselect everything. */ + /* Don't use 'BKE_object_pose_base_array_get_unique' + * because we may be selecting from object mode. */ + FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) { + Object *ob_iter = base_iter->object; + if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) { + if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) { + ED_pose_bone_select_tag_update(ob_iter); + } } } + FOREACH_VISIBLE_BASE_END; + changed = true; } - FOREACH_VISIBLE_BASE_END; - changed = true; } if (found) { diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 1c1783669c3..5ff63e767f6 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -4740,23 +4740,29 @@ bool ED_curve_editnurb_select_pick(bContext *C, ED_view3d_viewcontext_init(C, &vc, depsgraph); copy_v2_v2_int(vc.mval, mval); - const bool found = ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, &hand, &basact); + bool found = ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, &hand, &basact); - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - /* Deselect everything. */ - uint objects_len = 0; - Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( - vc.view_layer, vc.v3d, &objects_len); - for (uint ob_index = 0; ob_index < objects_len; ob_index++) { - Object *ob_iter = objects[ob_index]; + if (params->sel_op == SEL_OP_SET) { + if ((found && params->select_passthrough) && + (((bezt ? (&bezt->f1)[hand] : bp->f1) & SELECT) != 0)) { + found = false; + } + else if (found || params->deselect_all) { + /* Deselect everything. */ + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( + vc.view_layer, vc.v3d, &objects_len); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *ob_iter = objects[ob_index]; - ED_curve_deselect_all(((Curve *)ob_iter->data)->editnurb); + ED_curve_deselect_all(((Curve *)ob_iter->data)->editnurb); - DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data); + DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data); + } + MEM_freeN(objects); + changed = true; } - MEM_freeN(objects); - changed = true; } if (found) { diff --git a/source/blender/editors/include/ED_select_utils.h b/source/blender/editors/include/ED_select_utils.h index c24c9168fe8..b9ef5c283aa 100644 --- a/source/blender/editors/include/ED_select_utils.h +++ b/source/blender/editors/include/ED_select_utils.h @@ -82,6 +82,12 @@ struct SelectPick_Params { eSelectOp sel_op; /** Deselect all, even when there is nothing found at the cursor location. */ bool deselect_all; + /** + * When selecting an element that is already selected, do nothing (passthrough). + * don't even make it active. + * Use to implement tweaking to move the selection without first de-selecting. + */ + bool select_passthrough; }; /** diff --git a/source/blender/editors/lattice/editlattice_select.c b/source/blender/editors/lattice/editlattice_select.c index bc3bca248a4..ea99c6e23ff 100644 --- a/source/blender/editors/lattice/editlattice_select.c +++ b/source/blender/editors/lattice/editlattice_select.c @@ -623,22 +623,27 @@ bool ED_lattice_select_pick(bContext *C, const int mval[2], const struct SelectP vc.mval[1] = mval[1]; bp = findnearestLattvert(&vc, true, &basact); - const bool found = (bp != NULL); + bool found = (bp != NULL); - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - /* Deselect everything. */ - uint objects_len = 0; - Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( - vc.view_layer, vc.v3d, &objects_len); - for (uint ob_index = 0; ob_index < objects_len; ob_index++) { - Object *ob = objects[ob_index]; - if (ED_lattice_flags_set(ob, 0)) { - DEG_id_tag_update(ob->data, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data); + if (params->sel_op == SEL_OP_SET) { + if ((found && params->select_passthrough) && (bp->f1 & SELECT)) { + found = false; + } + else if (found || params->deselect_all) { + /* Deselect everything. */ + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( + vc.view_layer, vc.v3d, &objects_len); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *ob = objects[ob_index]; + if (ED_lattice_flags_set(ob, 0)) { + DEG_id_tag_update(ob->data, ID_RECALC_SELECT); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data); + } } + MEM_freeN(objects); + changed = true; } - MEM_freeN(objects); - changed = true; } if (found) { diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 9832f7ba9cf..a5c6adaa43e 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -389,8 +389,14 @@ bool paintface_mouse_select(struct bContext *C, } } - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - changed |= paintface_deselect_all_visible(C, ob, SEL_DESELECT, false); + if (params->sel_op == SEL_OP_SET) { + if ((found && params->select_passthrough) && (mpoly_sel->flag & ME_FACE_SEL)) { + found = false; + } + else if (found || params->deselect_all) { + /* Deselect everything. */ + changed |= paintface_deselect_all_visible(C, ob, SEL_DESELECT, false); + } } if (found) { diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index fba6838fd99..9c8c5c45cb7 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -2034,19 +2034,24 @@ bool EDBM_select_pick(bContext *C, const int mval[2], const struct SelectPick_Pa Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len); bool changed = false; - const bool found = unified_findnearest( - &vc, bases, bases_len, &base_index_active, &eve, &eed, &efa); - - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - /* Deselect everything. */ - for (uint base_index = 0; base_index < bases_len; base_index++) { - Base *base_iter = bases[base_index]; - Object *ob_iter = base_iter->object; - EDBM_flag_disable_all(BKE_editmesh_from_object(ob_iter), BM_ELEM_SELECT); - DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data); + bool found = unified_findnearest(&vc, bases, bases_len, &base_index_active, &eve, &eed, &efa); + + if (params->sel_op == SEL_OP_SET) { + BMElem *ele = efa ? (BMElem *)efa : (eed ? (BMElem *)eed : (BMElem *)eve); + if ((found && params->select_passthrough) && BM_elem_flag_test(ele, BM_ELEM_SELECT)) { + found = false; + } + else if (found || params->deselect_all) { + /* Deselect everything. */ + for (uint base_index = 0; base_index < bases_len; base_index++) { + Base *base_iter = bases[base_index]; + Object *ob_iter = base_iter->object; + EDBM_flag_disable_all(BKE_editmesh_from_object(ob_iter), BM_ELEM_SELECT); + DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data); + } + changed = true; } - changed = true; } if (found) { diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 55cae268e75..06a649e5b6c 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -854,9 +854,14 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], const struct SelectPic bool found = ed_mball_findnearest_metaelem(C, mval, true, &base, &ml, &selmask); - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - /* Deselect everything. */ - changed |= ED_mball_deselect_all_multi(C); + if (params->sel_op == SEL_OP_SET) { + if ((found && params->select_passthrough) && (ml->flag & SELECT)) { + found = false; + } + else if (found || params->deselect_all) { + /* Deselect everything. */ + changed |= ED_mball_deselect_all_multi(C); + } } if (found) { diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 73885ab2a78..4a639e227f7 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -1879,10 +1879,16 @@ bool PE_mouse_particles(bContext *C, const int mval[2], const struct SelectPick_ PTCacheEditKey *key; bool changed = false; - const bool found = pe_nearest_point_and_key(C, mval, &point, &key); + bool found = pe_nearest_point_and_key(C, mval, &point, &key); - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - changed |= PE_deselect_all_visible_ex(edit); + if (params->sel_op == SEL_OP_SET) { + if ((found && params->select_passthrough) && (key->flag & PEK_SELECT)) { + found = false; + } + else if (found || params->deselect_all) { + /* Deselect everything. */ + changed |= PE_deselect_all_visible_ex(edit); + } } if (found) { diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 25e47f9f6b9..de078fdf78b 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -43,6 +43,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "BKE_action.h" #include "BKE_armature.h" #include "BKE_context.h" #include "BKE_curve.h" @@ -2345,9 +2346,10 @@ static bool ed_object_select_pick(bContext *C, // TIMEIT_END(select_time); + const bool has_bones = (object && hits > 0) ? false : selectbuffer_has_bones(buffer, hits); + if (hits > 0) { /* NOTE: bundles are handling in the same way as bones. */ - const bool has_bones = object ? false : selectbuffer_has_bones(buffer, hits); /* NOTE: shift+alt goes to group-flush-selecting. */ if (enumerate) { @@ -2362,75 +2364,86 @@ static bool ed_object_select_pick(bContext *C, basact = mouse_select_eval_buffer( &vc, buffer, hits, startbase, has_bones, do_nearest, NULL); } + } - if (has_bones && basact) { - if (basact->object->type == OB_CAMERA) { - MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false); - if (clip != NULL && oldbasact == basact) { - bool track_changed = false; + if (((hits > 0) && has_bones) || + /* Special case, even when there are no hits, pose logic may de-select all bones. */ + ((hits == 0) && is_pose_mode)) { - for (int i = 0; i < hits; i++) { - const int hitresult = buffer[i].id; + if (basact && (has_bones && (basact->object->type == OB_CAMERA))) { + MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false); + if (clip != NULL && oldbasact == basact) { + bool track_changed = false; - /* if there's bundles in buffer select bundles first, - * so non-camera elements should be ignored in buffer */ - if (basact->object->runtime.select_id != (hitresult & 0xFFFF)) { - continue; - } + for (int i = 0; i < hits; i++) { + const int hitresult = buffer[i].id; + + /* if there's bundles in buffer select bundles first, + * so non-camera elements should be ignored in buffer */ + if (basact->object->runtime.select_id != (hitresult & 0xFFFF)) { + continue; + } - /* index of bundle is 1<<16-based. if there's no "bone" index - * in height word, this buffer value belongs to camera. not to bundle - */ - if (hitresult & 0xFFFF0000) { - const bool extend = params->sel_op == SEL_OP_ADD; - MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase; - MovieTrackingTrack *track; - - track = BKE_tracking_track_get_indexed( - &clip->tracking, hitresult >> 16, &tracksbase); - - if (TRACK_SELECTED(track) && extend) { - track_changed = false; - BKE_tracking_track_deselect(track, TRACK_AREA_ALL); + /* index of bundle is 1<<16-based. if there's no "bone" index + * in height word, this buffer value belongs to camera. not to bundle + */ + if (hitresult & 0xFFFF0000) { + const bool extend = params->sel_op == SEL_OP_ADD; + MovieTracking *tracking = &clip->tracking; + ListBase *tracksbase; + MovieTrackingTrack *track; + + track = BKE_tracking_track_get_indexed( + &clip->tracking, hitresult >> 16, &tracksbase); + + if (TRACK_SELECTED(track) && extend) { + track_changed = false; + BKE_tracking_track_deselect(track, TRACK_AREA_ALL); + } + else { + int oldsel = TRACK_SELECTED(track) ? 1 : 0; + if (!extend) { + deselect_all_tracks(tracking); } - else { - int oldsel = TRACK_SELECTED(track) ? 1 : 0; - if (!extend) { - deselect_all_tracks(tracking); - } - BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, extend); + BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, extend); - if (oldsel != (TRACK_SELECTED(track) ? 1 : 0)) { - track_changed = true; - } + if (oldsel != (TRACK_SELECTED(track) ? 1 : 0)) { + track_changed = true; } + } - ED_object_base_select(basact, BA_SELECT); + ED_object_base_select(basact, BA_SELECT); - changed = true; + changed = true; - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - DEG_id_tag_update(&clip->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, track); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); + DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); + DEG_id_tag_update(&clip->id, ID_RECALC_SELECT); + WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, track); + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - break; - } + break; } + } - if (!track_changed) { - /* fallback to regular object selection if no new bundles were selected, - * allows to select object parented to reconstruction object */ - basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest, NULL); - } + if (!track_changed) { + /* fallback to regular object selection if no new bundles were selected, + * allows to select object parented to reconstruction object */ + basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest, NULL); } } - else if (ED_armature_pose_select_pick_with_buffer( - view_layer, v3d, basact, buffer, hits, params, do_nearest)) { + } + else if (ED_armature_pose_select_pick_with_buffer(view_layer, + v3d, + basact ? basact : (Base *)oldbasact, + buffer, + hits, + params, + do_nearest)) { + /* When there is no `baseact` this will have operated on `oldbasact`, + * no object operations are needed. */ + if (basact != NULL) { /* then bone is found */ - /* we make the armature selected: * not-selected active object in posemode won't work well for tools */ ED_object_base_select(basact, BA_SELECT); @@ -2457,17 +2470,17 @@ static bool ed_object_select_pick(bContext *C, basact = NULL; } } + } - if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) { - if (is_obedit == false) { - if (basact && !BKE_object_is_mode_compat(basact->object, object_mode)) { - if (object_mode == OB_MODE_OBJECT) { - struct Main *bmain = CTX_data_main(C); - ED_object_mode_generic_exit(bmain, vc.depsgraph, scene, basact->object); - } - if (!BKE_object_is_mode_compat(basact->object, object_mode)) { - basact = NULL; - } + if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) { + if (is_obedit == false) { + if (basact && !BKE_object_is_mode_compat(basact->object, object_mode)) { + if (object_mode == OB_MODE_OBJECT) { + struct Main *bmain = CTX_data_main(C); + ED_object_mode_generic_exit(bmain, vc.depsgraph, scene, basact->object); + } + if (!BKE_object_is_mode_compat(basact->object, object_mode)) { + basact = NULL; } } } @@ -2490,31 +2503,31 @@ static bool ed_object_select_pick(bContext *C, /* Ensure code above doesn't change the active base. */ BLI_assert(oldbasact == (vc.obact ? BASACT(view_layer) : NULL)); + bool found = (basact != NULL); if (vc.obedit) { /* Edit-mode, pass. */ } else if (is_pose_mode && (basact == NULL || (basact->object->mode & OB_MODE_POSE))) { /* Pose-mode, pass (or moved into pose mode). */ - if (changed == false) { - /* Pose selection handles this but it wont run if there are no bones under the cursor. */ - const bool found = false; - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - changed |= ED_pose_deselect_all_multi(C, SEL_DESELECT, false); - } - } } else { /* Object-mode. */ - const bool found = (basact != NULL); - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - /* `basact` may be NULL. */ - changed |= object_deselect_all_except(view_layer, basact); - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); + + if (params->sel_op == SEL_OP_SET) { + if ((found && params->select_passthrough) && (basact->flag & BASE_SELECTED)) { + found = false; + } + else if (found || params->deselect_all) { + /* Deselect everything. */ + /* `basact` may be NULL. */ + changed |= object_deselect_all_except(view_layer, basact); + DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); + } } } /* so, do we have something selected? */ - if (basact) { + if (found) { changed = true; if (vc.obedit) { @@ -2626,8 +2639,14 @@ static bool ed_wpaint_vertex_select_pick(bContext *C, bool found = ED_mesh_pick_vert(C, obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf, &index); - if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) { - changed |= paintface_deselect_all_visible(C, obact, SEL_DESELECT, false); + if (params->sel_op == SEL_OP_SET) { + if ((found && params->select_passthrough) && (me->mvert[index].flag & SELECT)) { + found = false; + } + else if (found || params->deselect_all) { + /* Deselect everything. */ + changed |= paintface_deselect_all_visible(C, obact, SEL_DESELECT, false); + } } if (found) { @@ -2686,6 +2705,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op) RNA_boolean_get(op->ptr, "deselect"), RNA_boolean_get(op->ptr, "toggle")), .deselect_all = RNA_boolean_get(op->ptr, "deselect_all"), + .select_passthrough = RNA_boolean_get(op->ptr, "select_passthrough"), }; bool center = RNA_boolean_get(op->ptr, "center"); diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c index 1c7e63749f8..dacc17c2c1e 100644 --- a/source/blender/windowmanager/intern/wm_operator_props.c +++ b/source/blender/windowmanager/intern/wm_operator_props.c @@ -518,6 +518,14 @@ void WM_operator_properties_mouse_select(wmOperatorType *ot) "Deselect On Nothing", "Deselect all when nothing under the cursor"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); + + /* TODO: currently only used for the 3D viewport. */ + prop = RNA_def_boolean(ot->srna, + "select_passthrough", + false, + "Only Select Unselected", + "Ignore the select action when the element is already selected"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } void WM_operator_properties_checker_interval(wmOperatorType *ot, bool nth_can_disable) -- cgit v1.2.3