Modifications to the view3d.select() operator:

1. Two new boolean options have been added to the operator: "deselect"
   and "toggle".
2. The previous behavior of "extend" (toggling the selection) has
   been moved to the "toggle" option.
3. "extend" now only extends the selection, it never deselects.
4. "deselect" is pretty self-explanatory: it deselects (i.e. opposite
   of extend).
5. The built-in keymap has been changed to use "toggle" where
   "extend" was used before for this operator, to maintain the
   previous behavior in the default keymap.

In short, this works towards making "extend" and "deselect" fully
consistent across all selection tools (adding to and removing from
selection, respectively), but still preserves the old behavior
as well.

(Patch reviewed by Brecht.)
This commit is contained in:
Nathan Vegdahl 2012-05-24 21:05:27 +00:00
parent 9dc161e8ed
commit 19e1d05461
Notes: blender-bot 2023-02-14 05:26:50 +01:00
Referenced by issue #56411, Selecting with Shift-Ctrl-RMB not allow to Toggle
15 changed files with 275 additions and 87 deletions

View File

@ -1842,7 +1842,7 @@ static int ebone_select_flag(EditBone *ebone)
}
/* context: editmode armature in view3d */
int mouse_armature(bContext *C, const int mval[2], int extend)
int mouse_armature(bContext *C, const int mval[2], int extend, int deselect, int toggle)
{
Object *obedit = CTX_data_edit_object(C);
bArmature *arm = obedit->data;
@ -1857,7 +1857,7 @@ int mouse_armature(bContext *C, const int mval[2], int extend)
nearBone = get_nearest_editbonepoint(&vc, mval, arm->edbo, 1, &selmask);
if (nearBone) {
if (!extend)
if (!extend && !deselect && !toggle)
ED_armature_deselect_all(obedit, 0);
/* by definition the non-root connected bones have no root point drawn,
@ -1867,6 +1867,18 @@ int mouse_armature(bContext *C, const int mval[2], int extend)
if (nearBone->parent && (nearBone->flag & BONE_CONNECTED)) {
/* click in a chain */
if (extend) {
/* select this bone */
nearBone->flag |= BONE_TIPSEL;
nearBone->parent->flag |= BONE_TIPSEL;
}
else if (deselect) {
/* deselect this bone */
nearBone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
/* only deselect parent tip if it is not selected */
if (!(nearBone->parent->flag & BONE_SELECTED))
nearBone->parent->flag &= ~BONE_TIPSEL;
}
else if (toggle) {
/* hold shift inverts this bone's selection */
if (nearBone->flag & BONE_SELECTED) {
/* deselect this bone */
@ -1889,17 +1901,28 @@ int mouse_armature(bContext *C, const int mval[2], int extend)
}
else {
if (extend) {
nearBone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
}
else if (deselect) {
nearBone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
}
else if (toggle) {
/* hold shift inverts this bone's selection */
if (nearBone->flag & BONE_SELECTED)
nearBone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
else
nearBone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
}
else nearBone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
else
nearBone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
}
}
else {
if (extend && (nearBone->flag & selmask))
if (extend)
nearBone->flag |= selmask;
else if (deselect)
nearBone->flag &= ~selmask;
else if (toggle && (nearBone->flag & selmask))
nearBone->flag &= ~selmask;
else
nearBone->flag |= selmask;
@ -4475,7 +4498,7 @@ static int bone_looper(Object *ob, Bone *bone, void *data,
/* called from editview.c, for mode-less pose selection */
/* assumes scene obact and basact is still on old situation */
int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short extend)
int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short extend, short deselect, short toggle)
{
Object *ob = base->object;
Bone *nearBone;
@ -4494,7 +4517,7 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor
* note, special exception for armature mode so we can do multi-select
* we could check for multi-select explicitly but think its fine to
* always give predictable behavior in weight paint mode - campbell */
if (!extend || ((ob_act && (ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0))) {
if ((!extend && !deselect && !toggle)|| ((ob_act && (ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0))) {
ED_pose_deselectall(ob, 0);
nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
arm->act_bone = nearBone;
@ -4503,25 +4526,34 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor
//select_actionchannel_by_name(ob->action, nearBone->name, 1);
}
else {
if (nearBone->flag & BONE_SELECTED) {
/* if not active, we make it active */
if (nearBone != arm->act_bone) {
arm->act_bone = nearBone;
}
else {
nearBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
// XXX old cruft! use notifiers instead
//select_actionchannel_by_name(ob->action, nearBone->name, 0);
}
}
else {
if (extend) {
nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
arm->act_bone = nearBone;
// XXX old cruft! use notifiers instead
//select_actionchannel_by_name(ob->action, nearBone->name, 1);
}
else if (deselect) {
nearBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
}
else if (toggle) {
if (nearBone->flag & BONE_SELECTED) {
/* if not active, we make it active */
if (nearBone != arm->act_bone) {
arm->act_bone = nearBone;
}
else {
nearBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
// XXX old cruft! use notifiers instead
//select_actionchannel_by_name(ob->action, nearBone->name, 0);
}
}
else {
nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
arm->act_bone = nearBone;
// XXX old cruft! use notifiers instead
//select_actionchannel_by_name(ob->action, nearBone->name, 1);
}
}
}
/* in weightpaint we select the associated vertex group too */

View File

@ -4126,7 +4126,7 @@ void CURVE_OT_make_segment(wmOperatorType *ot)
/***************** pick select from 3d view **********************/
int mouse_nurb(bContext *C, const int mval[2], int extend)
int mouse_nurb(bContext *C, const int mval[2], int extend, int deselect, int toggle)
{
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
@ -4146,12 +4146,8 @@ int mouse_nurb(bContext *C, const int mval[2], int extend)
hand = findnearestNurbvert(&vc, 1, location, &nu, &bezt, &bp);
if (bezt || bp) {
if (extend == 0) {
setflagsNurb(editnurb, 0);
if (extend) {
if (bezt) {
if (hand == 1) {
select_beztriple(bezt, SELECT, 1, HIDDEN);
cu->lastsel = bezt;
@ -4167,9 +4163,26 @@ int mouse_nurb(bContext *C, const int mval[2], int extend)
cu->lastsel = bp;
select_bpoint(bp, SELECT, 1, HIDDEN);
}
}
else {
else if (deselect) {
if (bezt) {
if (hand == 1) {
select_beztriple(bezt, DESELECT, 1, HIDDEN);
if (bezt == cu->lastsel) cu->lastsel = NULL;
}
else if (hand == 0) {
bezt->f1 &= ~SELECT;
}
else {
bezt->f3 &= ~SELECT;
}
}
else {
select_bpoint(bp, DESELECT, 1, HIDDEN);
if (cu->lastsel == bp) cu->lastsel = NULL;
}
}
else if (toggle) {
if (bezt) {
if (hand == 1) {
if (bezt->f2 & SELECT) {
@ -4198,7 +4211,27 @@ int mouse_nurb(bContext *C, const int mval[2], int extend)
cu->lastsel = bp;
}
}
}
else {
setflagsNurb(editnurb, 0);
if (bezt) {
if (hand == 1) {
select_beztriple(bezt, SELECT, 1, HIDDEN);
cu->lastsel = bezt;
}
else {
if (hand == 0) bezt->f1 |= SELECT;
else bezt->f3 |= SELECT;
cu->lastsel = NULL;
}
}
else {
cu->lastsel = bp;
select_bpoint(bp, SELECT, 1, HIDDEN);
}
}
if (nu != get_actNurb(obedit))

View File

@ -113,8 +113,8 @@ void ED_armature_deselect_all(struct Object *obedit, int toggle);
void ED_armature_deselect_all_visible(struct Object *obedit);
int ED_do_pose_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer,
short hits, short extend);
int mouse_armature(struct bContext *C, const int mval[2], int extend);
short hits, short extend, short deselect, short toggle);
int mouse_armature(struct bContext *C, const int mval[2], int extend, int deselect, int toggle);
int join_armature_exec(struct bContext *C, struct wmOperator *op);
struct Bone *get_indexed_bone(struct Object *ob, int index);
float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const short axis_only);

View File

@ -65,7 +65,7 @@ void free_editNurb(struct Object *obedit);
void BKE_curve_editNurb_free(struct Curve *cu);
int mouse_nurb(struct bContext *C, const int mval[2], int extend);
int mouse_nurb(struct bContext *C, const int mval[2], int extend, int deselect, int toggle);
struct Nurb *add_nurbs_primitive(struct bContext *C, float mat[4][4], int type, int newob);

View File

@ -40,7 +40,7 @@ void ED_keymap_metaball(struct wmKeyConfig *keyconf);
struct MetaElem *add_metaball_primitive(struct bContext *C, float mat[4][4], int type, int newname);
int mouse_mball(struct bContext *C, const int mval[2], int extend);
int mouse_mball(struct bContext *C, const int mval[2], int extend, int deselect, int toggle);
void free_editMball(struct Object *obedit);
void make_editMball(struct Object *obedit);

View File

@ -156,7 +156,7 @@ void EDBM_automerge(struct Scene *scene, struct Object *ob, int update);
/* editmesh_mods.c */
extern unsigned int bm_vertoffs, bm_solidoffs, bm_wireoffs;
int mouse_mesh(struct bContext *C, const int mval[2], short extend);
int mouse_mesh(struct bContext *C, const int mval[2], short extend, short deselect, short toggle);
struct BMVert *editbmesh_get_x_mirror_vert(struct Object *ob, struct BMEditMesh *em, struct BMVert *eve, const float co[3], int index);
int mesh_get_x_mirror_vert(struct Object *ob, int index);
@ -184,7 +184,7 @@ void EMBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct Obje
/* editface.c */
void paintface_flush_flags(struct Object *ob);
int paintface_mouse_select(struct bContext *C, struct Object *ob, const int mval[2], int extend);
int paintface_mouse_select(struct bContext *C, struct Object *ob, const int mval[2], int extend, int deselect, int toggle);
int do_paintface_box_select(struct ViewContext *vc, struct rcti *rect, int select, int extend);
void paintface_deselect_all_visible(struct Object *ob, int action, short flush_flags);
void paintface_select_linked(struct bContext *C, struct Object *ob, int mval[2], int mode);

View File

@ -152,7 +152,7 @@ void ED_object_constraint_update(struct Object *ob);
void ED_object_constraint_dependency_update(struct Main *bmain, struct Scene *scene, struct Object *ob);
/* object_lattice.c */
int mouse_lattice(struct bContext *C, const int mval[2], int extend);
int mouse_lattice(struct bContext *C, const int mval[2], int extend, int deselect, int toggle);
void undo_push_lattice(struct bContext *C, const char *name);
/* object_lattice.c */

View File

@ -58,7 +58,7 @@ void PE_hide_keys_time(struct Scene *scene, struct PTCacheEdit *edit, float cfra
void PE_update_object(struct Scene *scene, struct Object *ob, int useflag);
/* selection tools */
int PE_mouse_particles(struct bContext *C, const int mval[2], int extend);
int PE_mouse_particles(struct bContext *C, const int mval[2], int extend, int deselect, int toggle);
int PE_border_select(struct bContext *C, struct rcti *rect, int select, int extend);
int PE_circle_select(struct bContext *C, int selecting, const int mval[2], float rad);
int PE_lasso_select(struct bContext *C, int mcords[][2], short moves, short extend, short select);

View File

@ -509,7 +509,7 @@ void seam_mark_clear_tface(Scene *scene, short mode)
}
#endif
int paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], int extend)
int paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], int extend, int deselect, int toggle)
{
Mesh *me;
MPoly *mpoly, *mpoly_sel;
@ -530,7 +530,7 @@ int paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], in
/* clear flags */
mpoly = me->mpoly;
a = me->totpoly;
if (!extend) {
if (!extend && !deselect && !toggle) {
while (a--) {
mpoly->flag &= ~ME_FACE_SEL;
mpoly++;
@ -540,6 +540,12 @@ int paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], in
me->act_face = (int)index;
if (extend) {
mpoly_sel->flag |= ME_FACE_SEL;
}
else if (deselect) {
mpoly_sel->flag &= ~ME_FACE_SEL;
}
else if (toggle) {
if (mpoly_sel->flag & ME_FACE_SEL)
mpoly_sel->flag &= ~ME_FACE_SEL;
else

View File

@ -1454,7 +1454,7 @@ void MESH_OT_select_shortest_path(wmOperatorType *ot)
/* ************************************************** */
/* here actual select happens */
/* gets called via generic mouse select operator */
int mouse_mesh(bContext *C, const int mval[2], short extend)
int mouse_mesh(bContext *C, const int mval[2], short extend, short deselect, short toggle)
{
ViewContext vc;
BMVert *eve = NULL;
@ -1468,40 +1468,87 @@ int mouse_mesh(bContext *C, const int mval[2], short extend)
if (unified_findnearest(&vc, &eve, &eed, &efa)) {
if (extend == 0) EDBM_flag_disable_all(vc.em, BM_ELEM_SELECT);
// Deselect everything
if (extend == 0 && deselect == 0 && toggle == 0)
EDBM_flag_disable_all(vc.em, BM_ELEM_SELECT);
if (efa) {
/* set the last selected face */
BM_active_face_set(vc.em->bm, efa);
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
if (extend) {
// set the last selected face
BM_active_face_set(vc.em->bm, efa);
// Work-around: deselect first, so we can guarantee it will
// be active even if it was already selected
BM_select_history_remove(vc.em->bm, efa);
BM_face_select_set(vc.em->bm, efa, FALSE);
BM_select_history_store(vc.em->bm, efa);
BM_face_select_set(vc.em->bm, efa, TRUE);
}
else if (extend) {
else if (deselect) {
BM_select_history_remove(vc.em->bm, efa);
BM_face_select_set(vc.em->bm, efa, FALSE);
}
else {
// set the last selected face
BM_active_face_set(vc.em->bm, efa);
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
BM_select_history_store(vc.em->bm, efa);
BM_face_select_set(vc.em->bm, efa, TRUE);
}
else if (toggle) {
BM_select_history_remove(vc.em->bm, efa);
BM_face_select_set(vc.em->bm, efa, FALSE);
}
}
}
else if (eed) {
if (!BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
if (extend) {
// Work-around: deselect first, so we can guarantee it will
// be active even if it was already selected
BM_select_history_remove(vc.em->bm, eed);
BM_edge_select_set(vc.em->bm, eed, FALSE);
BM_select_history_store(vc.em->bm, eed);
BM_edge_select_set(vc.em->bm, eed, TRUE);
}
else if (extend) {
else if (deselect) {
BM_select_history_remove(vc.em->bm, eed);
BM_edge_select_set(vc.em->bm, eed, FALSE);
}
else {
if (!BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
BM_select_history_store(vc.em->bm, eed);
BM_edge_select_set(vc.em->bm, eed, TRUE);
}
else if (toggle) {
BM_select_history_remove(vc.em->bm, eed);
BM_edge_select_set(vc.em->bm, eed, FALSE);
}
}
}
else if (eve) {
if (!BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
if (extend) {
// Work-around: deselect first, so we can guarantee it will
// be active even if it was already selected
BM_select_history_remove(vc.em->bm, eve);
BM_vert_select_set(vc.em->bm, eve, FALSE);
BM_select_history_store(vc.em->bm, eve);
BM_vert_select_set(vc.em->bm, eve, TRUE);
}
else if (extend) {
else if (deselect) {
BM_select_history_remove(vc.em->bm, eve);
BM_vert_select_set(vc.em->bm, eve, FALSE);
}
else {
if (!BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
BM_select_history_store(vc.em->bm, eve);
BM_vert_select_set(vc.em->bm, eve, TRUE);
}
else if (toggle) {
BM_select_history_remove(vc.em->bm, eve);
BM_vert_select_set(vc.em->bm, eve, FALSE);
}
}
}
EDBM_selectmode_flush(vc.em);

View File

@ -415,7 +415,7 @@ void MBALL_OT_reveal_metaelems(wmOperatorType *ot)
/* Select MetaElement with mouse click (user can select radius circle or
* stiffness circle) */
int mouse_mball(bContext *C, const int mval[2], int extend)
int mouse_mball(bContext *C, const int mval[2], int extend, int deselect, int toggle)
{
static MetaElem *startelem = NULL;
Object *obedit = CTX_data_edit_object(C);
@ -467,7 +467,19 @@ int mouse_mball(bContext *C, const int mval[2], int extend)
/* When some metaelem was found, then it is necessary to select or
* deselect it. */
if (act) {
if (extend == 0) {
if (extend) {
act->flag |= SELECT;
}
else if (deselect) {
act->flag &= ~SELECT;
}
else if (toggle) {
if (act->flag & SELECT)
act->flag &= ~SELECT;
else
act->flag |= SELECT;
}
else {
/* Deselect all existing metaelems */
ml = mb->editelems->first;
while (ml) {
@ -477,12 +489,7 @@ int mouse_mball(bContext *C, const int mval[2], int extend)
/* Select only metaelem clicked on */
act->flag |= SELECT;
}
else {
if (act->flag & SELECT)
act->flag &= ~SELECT;
else
act->flag |= SELECT;
}
mb->lastelem = act;
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb);

View File

@ -335,7 +335,7 @@ static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel)
return data.bp;
}
int mouse_lattice(bContext *C, const int mval[2], int extend)
int mouse_lattice(bContext *C, const int mval[2], int extend, int deselect, int toggle)
{
ViewContext vc;
BPoint *bp = NULL;
@ -344,12 +344,20 @@ int mouse_lattice(bContext *C, const int mval[2], int extend)
bp = findnearestLattvert(&vc, mval, 1);
if (bp) {
if (extend == 0) {
ED_setflagsLatt(vc.obedit, 0);
bp->f1 |= SELECT;
if (extend) {
bp->f1 |= SELECT;
}
else if (deselect) {
bp->f1 &= ~SELECT;
}
else if (toggle) {
bp->f1 ^= SELECT; /* swap */
}
else
bp->f1 ^= SELECT; /* swap */
{
ED_setflagsLatt(vc.obedit, 0);
bp->f1 |= SELECT;
}
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);

View File

@ -1294,6 +1294,26 @@ static void select_keys(PEData *data, int point_index, int UNUSED(key_index))
point->flag |= PEP_EDIT_RECALC;
}
static void extend_key_select(PEData *data, int point_index, int key_index)
{
PTCacheEdit *edit = data->edit;
PTCacheEditPoint *point = edit->points + point_index;
PTCacheEditKey *key = point->keys + key_index;
key->flag |= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
}
static void deselect_key_select(PEData *data, int point_index, int key_index)
{
PTCacheEdit *edit = data->edit;
PTCacheEditPoint *point = edit->points + point_index;
PTCacheEditKey *key = point->keys + key_index;
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
}
static void toggle_key_select(PEData *data, int point_index, int key_index)
{
PTCacheEdit *edit = data->edit;
@ -1381,7 +1401,7 @@ void PARTICLE_OT_select_all(wmOperatorType *ot)
/************************ pick select operator ************************/
int PE_mouse_particles(bContext *C, const int mval[2], int extend)
int PE_mouse_particles(bContext *C, const int mval[2], int extend, int deselect, int toggle)
{
PEData data;
Scene *scene= CTX_data_scene(C);
@ -1392,7 +1412,7 @@ int PE_mouse_particles(bContext *C, const int mval[2], int extend)
if (!PE_start_edit(edit))
return OPERATOR_CANCELLED;
if (!extend) {
if (!extend && !deselect && !toggle) {
LOOP_VISIBLE_POINTS {
LOOP_SELECTED_KEYS {
key->flag &= ~PEK_SELECT;
@ -1405,7 +1425,13 @@ int PE_mouse_particles(bContext *C, const int mval[2], int extend)
data.mval= mval;
data.rad= 75.0f;
for_mouse_hit_keys(&data, toggle_key_select, 1); /* nearest only */
/* 1 = nearest only */
if (extend)
for_mouse_hit_keys(&data, extend_key_select, 1);
else if (deselect)
for_mouse_hit_keys(&data, deselect_key_select, 1);
else
for_mouse_hit_keys(&data, toggle_key_select, 1);
PE_update_selection(scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);

View File

@ -272,21 +272,29 @@ void view3d_keymap(wmKeyConfig *keyconf)
/* selection*/
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
RNA_boolean_set(kmi->ptr, "deselect", FALSE);
RNA_boolean_set(kmi->ptr, "toggle", FALSE);
RNA_boolean_set(kmi->ptr, "center", FALSE);
RNA_boolean_set(kmi->ptr, "object", FALSE);
RNA_boolean_set(kmi->ptr, "enumerate", FALSE);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", TRUE);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
RNA_boolean_set(kmi->ptr, "deselect", FALSE);
RNA_boolean_set(kmi->ptr, "toggle", TRUE);
RNA_boolean_set(kmi->ptr, "center", FALSE);
RNA_boolean_set(kmi->ptr, "object", FALSE);
RNA_boolean_set(kmi->ptr, "enumerate", FALSE);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
RNA_boolean_set(kmi->ptr, "deselect", FALSE);
RNA_boolean_set(kmi->ptr, "toggle", FALSE);
RNA_boolean_set(kmi->ptr, "center", TRUE);
RNA_boolean_set(kmi->ptr, "object", TRUE); /* use Ctrl+Select for 2 purposes */
RNA_boolean_set(kmi->ptr, "enumerate", FALSE);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
RNA_boolean_set(kmi->ptr, "deselect", FALSE);
RNA_boolean_set(kmi->ptr, "toggle", FALSE);
RNA_boolean_set(kmi->ptr, "center", FALSE);
RNA_boolean_set(kmi->ptr, "object", FALSE);
RNA_boolean_set(kmi->ptr, "enumerate", TRUE);
@ -294,21 +302,29 @@ void view3d_keymap(wmKeyConfig *keyconf)
/* selection key-combinations */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "extend", TRUE);
RNA_boolean_set(kmi->ptr, "deselect", FALSE);
RNA_boolean_set(kmi->ptr, "toggle", TRUE);
RNA_boolean_set(kmi->ptr, "center", TRUE);
RNA_boolean_set(kmi->ptr, "object", FALSE);
RNA_boolean_set(kmi->ptr, "enumerate", FALSE);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
RNA_boolean_set(kmi->ptr, "deselect", FALSE);
RNA_boolean_set(kmi->ptr, "toggle", FALSE);
RNA_boolean_set(kmi->ptr, "center", TRUE);
RNA_boolean_set(kmi->ptr, "object", FALSE);
RNA_boolean_set(kmi->ptr, "enumerate", TRUE);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "extend", TRUE);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
RNA_boolean_set(kmi->ptr, "deselect", FALSE);
RNA_boolean_set(kmi->ptr, "toggle", TRUE);
RNA_boolean_set(kmi->ptr, "center", FALSE);
RNA_boolean_set(kmi->ptr, "object", FALSE);
RNA_boolean_set(kmi->ptr, "enumerate", TRUE);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_CTRL | KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "extend", TRUE);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
RNA_boolean_set(kmi->ptr, "deselect", FALSE);
RNA_boolean_set(kmi->ptr, "toggle", TRUE);
RNA_boolean_set(kmi->ptr, "center", TRUE);
RNA_boolean_set(kmi->ptr, "object", FALSE);
RNA_boolean_set(kmi->ptr, "enumerate", TRUE);

View File

@ -1311,7 +1311,7 @@ static void deselect_all_tracks(MovieTracking *tracking)
}
/* mval is region coords */
static int mouse_select(bContext *C, const int mval[2], short extend, short obcenter, short enumerate)
static int mouse_select(bContext *C, const int mval[2], short extend, short deselect, short toggle, short obcenter, short enumerate)
{
ViewContext vc;
ARegion *ar = CTX_wm_region(C);
@ -1438,7 +1438,7 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short obce
}
}
}
else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend) ) { /* then bone is found */
else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) { /* then bone is found */
/* we make the armature selected:
* not-selected active object in posemode won't work well for tools */
@ -1477,20 +1477,23 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short obce
oldbasact = BASACT;
if (!extend) {
deselectall_except(scene, basact);
if (extend) {
ED_base_object_select(basact, BA_SELECT);
}
else if (0) {
// XXX select_all_from_groups(basact);
else if(deselect) {
ED_base_object_select(basact, BA_DESELECT);
}
else {
else if(toggle) {
if (basact->flag & SELECT) {
if (basact == oldbasact)
ED_base_object_select(basact, BA_DESELECT);
}
else ED_base_object_select(basact, BA_SELECT);
}
else {
deselectall_except(scene, basact);
ED_base_object_select(basact, BA_SELECT);
}
if (oldbasact != basact) {
ED_base_object_activate(C, basact); /* adds notifier */
@ -2043,7 +2046,7 @@ static int vertsel_vert_pick(struct bContext *C, Mesh *me, const int mval[2], un
/* mouse selection in weight paint */
/* gets called via generic mouse select operator */
static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], short extend, Object *obact)
static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], short extend, short deselect, short toggle, Object *obact)
{
Mesh *me = obact->data; /* already checked for NULL */
unsigned int index = 0;
@ -2052,6 +2055,12 @@ static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], shor
if (vertsel_vert_pick(C, me, mval, &index, 50)) {
mv = me->mvert + index;
if (extend) {
mv->flag |= SELECT;
}
else if (deselect) {
mv->flag &= ~SELECT;
}
else if (toggle) {
mv->flag ^= SELECT;
}
else {
@ -2073,6 +2082,8 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
Object *obedit = CTX_data_edit_object(C);
Object *obact = CTX_data_active_object(C);
short extend = RNA_boolean_get(op->ptr, "extend");
short deselect = RNA_boolean_get(op->ptr, "deselect");
short toggle = RNA_boolean_get(op->ptr, "toggle");
short center = RNA_boolean_get(op->ptr, "center");
short enumerate = RNA_boolean_get(op->ptr, "enumerate");
short object = RNA_boolean_get(op->ptr, "object");
@ -2092,27 +2103,27 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
if (obedit && object == FALSE) {
if (obedit->type == OB_MESH)
retval = mouse_mesh(C, event->mval, extend);
retval = mouse_mesh(C, event->mval, extend, deselect, toggle);
else if (obedit->type == OB_ARMATURE)
retval = mouse_armature(C, event->mval, extend);
retval = mouse_armature(C, event->mval, extend, deselect, toggle);
else if (obedit->type == OB_LATTICE)
retval = mouse_lattice(C, event->mval, extend);
retval = mouse_lattice(C, event->mval, extend, deselect, toggle);
else if (ELEM(obedit->type, OB_CURVE, OB_SURF))
retval = mouse_nurb(C, event->mval, extend);
retval = mouse_nurb(C, event->mval, extend, deselect, toggle);
else if (obedit->type == OB_MBALL)
retval = mouse_mball(C, event->mval, extend);
retval = mouse_mball(C, event->mval, extend, deselect, toggle);
}
else if (obact && obact->mode & OB_MODE_SCULPT)
return OPERATOR_CANCELLED;
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT)
return PE_mouse_particles(C, event->mval, extend);
return PE_mouse_particles(C, event->mval, extend, deselect, toggle);
else if (obact && paint_facesel_test(obact))
retval = paintface_mouse_select(C, obact, event->mval, extend);
retval = paintface_mouse_select(C, obact, event->mval, extend, deselect, toggle);
else if (paint_vertsel_test(obact))
retval = mouse_weight_paint_vertex_select(C, event->mval, extend, obact);
retval = mouse_weight_paint_vertex_select(C, event->mval, extend, deselect, toggle, obact);
else
retval = mouse_select(C, event->mval, extend, center, enumerate);
retval = mouse_select(C, event->mval, extend, deselect, toggle, center, enumerate);
/* passthrough allows tweaks
* FINISHED to signal one operator worked
@ -2139,6 +2150,8 @@ void VIEW3D_OT_select(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first");
RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from selection");
RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Selection", "Toggles selection");
RNA_def_boolean(ot->srna, "center", 0, "Center", "Use the object center when selecting, in editmode used to extend object selection");
RNA_def_boolean(ot->srna, "enumerate", 0, "Enumerate", "List objects under the mouse (object mode only)");
RNA_def_boolean(ot->srna, "object", 0, "Object", "Use object selection (editmode only)");