From 1672ac25ca9b828d5e3d3fc2a69b1c346304036c Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Mon, 11 Mar 2013 16:02:16 +0000 Subject: Ouliner: Added recursive select of (visible) bones (Edit- and Object-mode) --- .../blender/editors/space_outliner/outliner_draw.c | 4 +- .../editors/space_outliner/outliner_intern.h | 2 +- .../editors/space_outliner/outliner_select.c | 95 ++++++++++++++++------ 3 files changed, 74 insertions(+), 27 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 30e3f6bbf0e..0d6f316b7e7 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1322,7 +1322,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa } } else { - active = tree_element_type_active(NULL, scene, soops, te, tselem, 0); + active = tree_element_type_active(NULL, scene, soops, te, tselem, 0, false); } if (active) { @@ -1461,7 +1461,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene } } else { - if (tree_element_type_active(NULL, scene, soops, te, tselem, 0) ) active = 2; + if (tree_element_type_active(NULL, scene, soops, te, tselem, 0, false) ) active = 2; glColor4ub(220, 220, 255, alpha); } diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 0b71629df20..2ca0f1382ef 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -165,7 +165,7 @@ void draw_outliner(const struct bContext *C); void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag); /* outliner_select.c -------------------------------------------- */ -int tree_element_type_active(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set); +int tree_element_type_active(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set, bool recursive); int tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops, TreeElement *te, int set); int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, bool recursive); diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 03fc7954e3e..6dff3aaf152 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -51,6 +51,7 @@ #include "BKE_object.h" #include "BKE_scene.h" #include "BKE_sequencer.h" +#include "BKE_armature.h" #include "ED_armature.h" #include "ED_object.h" @@ -159,6 +160,39 @@ static void do_outliner_object_select_recursive(Scene *scene, Object *ob_parent, } } +static void do_outliner_bone_select_recursive(Scene *scene, bArmature *arm, Bone *bone_parent, bool select) +{ + Bone *bone; + for (bone = bone_parent->childbase.first; bone; bone = bone->next) { + if(select && PBONE_VISIBLE(arm, bone)) + bone->flag |= BONE_SELECTED; + else + bone->flag &= ~BONE_SELECTED; + do_outliner_bone_select_recursive(scene, arm, bone, select); + } +} + +static bool is_child_of(EditBone *ebone, EditBone *ebone_parent) { + for (ebone = ebone->parent; ebone; ebone=ebone->parent) { + if (ebone == ebone_parent) + return true; + } + return false; +} + +static void do_outliner_ebone_select_recursive(Scene *scene, bArmature *arm, EditBone *ebone_parent, bool select) +{ + EditBone *ebone; + for (ebone = ebone_parent->next; ebone; ebone=ebone->next) { + if (is_child_of(ebone, ebone_parent)) { + if(select && EBONE_VISIBLE(arm, ebone)) + ebone->flag |= BONE_SELECTED; + else + ebone->flag &= ~BONE_SELECTED; + } + } +} + static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set, bool recursive) { @@ -457,7 +491,7 @@ static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElemen return 0; } -static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set) +static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set, bool recursive) { bArmature *arm = (bArmature *)tselem->id; Bone *bone = te->directdata; @@ -477,6 +511,12 @@ static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te, bone->flag |= BONE_SELECTED; arm->act_bone = bone; } + + if (recursive) { + /* Recursive select/deselect */ + do_outliner_bone_select_recursive(scene, arm, bone, (bone->flag & BONE_SELECTED) != 0); + } + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob); } @@ -509,35 +549,42 @@ static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, scene->obedit); } -static int tree_element_active_ebone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), int set) +static int tree_element_active_ebone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), int set, bool recursive) { bArmature *arm = scene->obedit->data; EditBone *ebone = te->directdata; - - if (set == 1) { - if (!(ebone->flag & BONE_HIDDEN_A)) { - ED_armature_deselect_all(scene->obedit, 0); // deselect - tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE); - return 1; - } - } - else if (set == 2) { - if (!(ebone->flag & BONE_HIDDEN_A)) { - if (!(ebone->flag & BONE_SELECTED)) { + int status = 0; + if (set) { + if (set == 1) { + if (!(ebone->flag & BONE_HIDDEN_A)) { + ED_armature_deselect_all(scene->obedit, 0); // deselect tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE); - return 1; + status = 1; } - else { - /* entirely selected, so de-select */ - tree_element_active_ebone__sel(C, scene, arm, ebone, FALSE); - return 0; + } + else if (set == 2) { + if (!(ebone->flag & BONE_HIDDEN_A)) { + if (!(ebone->flag & BONE_SELECTED)) { + tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE); + status = 1; + } + else { + /* entirely selected, so de-select */ + tree_element_active_ebone__sel(C, scene, arm, ebone, FALSE); + status = 0; + } } } + + if (recursive) { + /* Recursive select/deselect */ + do_outliner_ebone_select_recursive(scene, arm, ebone, (ebone->flag & BONE_SELECTED) != 0); + } } else if (ebone->flag & BONE_SELECTED) { - return 1; + status = 1; } - return 0; + return status; } static int tree_element_active_modifier(bContext *C, TreeElement *UNUSED(te), TreeStoreElem *tselem, int set) @@ -705,15 +752,15 @@ int tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement /* generic call for non-id data to make/check active in UI */ /* Context can be NULL when set==0 */ int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops, - TreeElement *te, TreeStoreElem *tselem, int set) + TreeElement *te, TreeStoreElem *tselem, int set, bool recursive) { switch (tselem->type) { case TSE_DEFGROUP: return tree_element_active_defgroup(C, scene, te, tselem, set); case TSE_BONE: - return tree_element_active_bone(C, scene, te, tselem, set); + return tree_element_active_bone(C, scene, te, tselem, set, recursive); case TSE_EBONE: - return tree_element_active_ebone(C, scene, te, tselem, set); + return tree_element_active_ebone(C, scene, te, tselem, set, recursive); case TSE_MODIFIER: return tree_element_active_modifier(C, te, tselem, set); case TSE_LINKED_OB: @@ -824,7 +871,7 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa } else { - tree_element_type_active(C, scene, soops, te, tselem, 1 + (extend != 0)); + tree_element_type_active(C, scene, soops, te, tselem, 1 + (extend != 0), recursive); } return 1; -- cgit v1.2.3