From 0dd9e55d211453a6571fb5d3838c7d736434c8ee Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 2 Nov 2019 03:11:56 +1100 Subject: Fix T71247: Outliner pose toggle looses bone selection The outliner didn't account for weight-paint + pose-mode, making it consider all pose bones unselected. When syncing selection, bones were unselected. This adds a context argument to passed to drawing functions since finding the weight-paint pose-object in the drawing loop isn't efficient. --- .../blender/editors/space_outliner/outliner_draw.c | 77 ++++++-------- .../editors/space_outliner/outliner_intern.h | 27 ++++- .../editors/space_outliner/outliner_select.c | 115 +++++++++------------ .../blender/editors/space_outliner/outliner_sync.c | 17 +-- .../editors/space_outliner/outliner_utils.c | 30 ++++++ 5 files changed, 147 insertions(+), 119 deletions(-) diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 3b86e04308e..d7a7d57b100 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -756,14 +756,15 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) } case TSE_BONE: { - ViewLayer *view_layer = CTX_data_view_layer(C); - Scene *scene = CTX_data_scene(C); + TreeViewContext tvc; + outliner_viewcontext_init(C, &tvc); + bArmature *arm = (bArmature *)tselem->id; Bone *bone = te->directdata; char newname[sizeof(bone->name)]; /* always make current object active */ - tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, true); + tree_element_active(C, &tvc, soops, te, OL_SETSEL_NORMAL, true); /* restore bone name */ BLI_strncpy(newname, bone->name, sizeof(bone->name)); @@ -773,14 +774,15 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) break; } case TSE_POSE_CHANNEL: { - Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); + TreeViewContext tvc; + outliner_viewcontext_init(C, &tvc); + Object *ob = (Object *)tselem->id; bPoseChannel *pchan = te->directdata; char newname[sizeof(pchan->name)]; /* always make current pose-bone active */ - tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, true); + tree_element_active(C, &tvc, soops, te, OL_SETSEL_NORMAL, true); BLI_assert(ob->type == OB_ARMATURE); @@ -2815,8 +2817,7 @@ typedef struct MergedIconRow { static void outliner_draw_iconrow(bContext *C, uiBlock *block, const uiFontStyle *fstyle, - Scene *scene, - ViewLayer *view_layer, + const TreeViewContext *tvc, SpaceOutliner *soops, ListBase *lb, int level, @@ -2827,7 +2828,6 @@ static void outliner_draw_iconrow(bContext *C, MergedIconRow *merged) { eOLDrawState active = OL_DRAWSEL_NONE; - const Object *obact = OBACT(view_layer); for (TreeElement *te = lb->first; te; te = te->next) { TreeStoreElem *tselem = TREESTORE(te); @@ -2837,14 +2837,13 @@ static void outliner_draw_iconrow(bContext *C, /* active blocks get white circle */ if (tselem->type == 0) { if (te->idcode == ID_OB) { - active = (OBACT(view_layer) == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : - OL_DRAWSEL_NONE; + active = (tvc->obact == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE; } - else if (is_object_data_in_editmode(tselem->id, obact)) { + else if (is_object_data_in_editmode(tselem->id, tvc->obact)) { active = OL_DRAWSEL_ACTIVE; } else { - active = tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NONE, false); + active = tree_element_active(C, tvc, soops, te, OL_SETSEL_NONE, false); } } else if (tselem->type == TSE_GP_LAYER) { @@ -2852,8 +2851,7 @@ static void outliner_draw_iconrow(bContext *C, active = (gpl->flag & GP_LAYER_ACTIVE) ? OL_DRAWSEL_ACTIVE : OL_DRAWSEL_NONE; } else { - active = tree_element_type_active( - C, scene, view_layer, soops, te, tselem, OL_SETSEL_NONE, false); + active = tree_element_type_active(C, tvc, soops, te, tselem, OL_SETSEL_NONE, false); } if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION, TSE_R_LAYER, TSE_GP_LAYER)) { @@ -2874,8 +2872,7 @@ static void outliner_draw_iconrow(bContext *C, outliner_draw_iconrow(C, block, fstyle, - scene, - view_layer, + tvc, soops, &te->subtree, level + 1, @@ -2933,8 +2930,7 @@ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int sta static void outliner_draw_tree_element(bContext *C, uiBlock *block, const uiFontStyle *fstyle, - Scene *scene, - ViewLayer *view_layer, + const TreeViewContext *tvc, ARegion *ar, SpaceOutliner *soops, TreeElement *te, @@ -2973,9 +2969,8 @@ static void outliner_draw_tree_element(bContext *C, /* colors for active/selected data */ if (tselem->type == 0) { - const Object *obact = OBACT(view_layer); if (te->idcode == ID_SCE) { - if (tselem->id == (ID *)scene) { + if (tselem->id == (ID *)tvc->scene) { /* active scene */ icon_bgcolor[3] = 0.2f; active = OL_DRAWSEL_ACTIVE; @@ -2984,15 +2979,15 @@ static void outliner_draw_tree_element(bContext *C, else if (te->idcode == ID_OB) { Object *ob = (Object *)tselem->id; Base *base = (te->directdata) ? (Base *)te->directdata : - BKE_view_layer_base_find(view_layer, ob); + BKE_view_layer_base_find(tvc->view_layer, ob); const bool is_selected = (base != NULL) && ((base->flag & BASE_SELECTED) != 0); - if (ob == obact) { + if (ob == tvc->obact) { active = OL_DRAWSEL_ACTIVE; } if (is_selected) { - if (ob == obact) { + if (ob == tvc->obact) { /* active selected object */ UI_GetThemeColor3ubv(TH_ACTIVE_OBJECT, text_color); text_color[3] = 255; @@ -3004,14 +2999,14 @@ static void outliner_draw_tree_element(bContext *C, } } } - else if (is_object_data_in_editmode(tselem->id, obact)) { + else if (is_object_data_in_editmode(tselem->id, tvc->obact)) { /* objects being edited */ UI_GetThemeColor4fv(TH_EDITED_OBJECT, icon_bgcolor); icon_border[3] = 0.3f; active = OL_DRAWSEL_ACTIVE; } else { - if (tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NONE, false)) { + if (tree_element_active(C, tvc, soops, te, OL_SETSEL_NONE, false)) { /* active items like camera or material */ icon_bgcolor[3] = 0.2f; active = OL_DRAWSEL_ACTIVE; @@ -3026,8 +3021,7 @@ static void outliner_draw_tree_element(bContext *C, } } else { - active = tree_element_type_active( - C, scene, view_layer, soops, te, tselem, OL_SETSEL_NONE, false); + active = tree_element_type_active(C, tvc, soops, te, tselem, OL_SETSEL_NONE, false); /* active collection*/ icon_bgcolor[3] = 0.2f; } @@ -3036,7 +3030,7 @@ static void outliner_draw_tree_element(bContext *C, if ((tselem->type == TSE_LAYER_COLLECTION) && (soops->show_restrict_flags & SO_RESTRICT_ENABLE)) { tselem_draw_layer_collection_enable_icon( - scene, block, xmax, (float)startx + offsx + UI_UNIT_X, (float)*starty, te, 0.8f); + tvc->scene, block, xmax, (float)startx + offsx + UI_UNIT_X, (float)*starty, te, 0.8f); offsx += UI_UNIT_X; } @@ -3155,8 +3149,7 @@ static void outliner_draw_tree_element(bContext *C, outliner_draw_iconrow(C, block, fstyle, - scene, - view_layer, + tvc, soops, &te->subtree, 0, @@ -3186,8 +3179,7 @@ static void outliner_draw_tree_element(bContext *C, outliner_draw_tree_element(C, block, fstyle, - scene, - view_layer, + tvc, ar, soops, ten, @@ -3486,8 +3478,7 @@ static void outliner_draw_highlights(ARegion *ar, SpaceOutliner *soops, int star static void outliner_draw_tree(bContext *C, uiBlock *block, - Scene *scene, - ViewLayer *view_layer, + const TreeViewContext *tvc, ARegion *ar, SpaceOutliner *soops, const float restrict_column_width, @@ -3533,8 +3524,7 @@ static void outliner_draw_tree(bContext *C, outliner_draw_tree_element(C, block, fstyle, - scene, - view_layer, + tvc, ar, soops, te, @@ -3625,15 +3615,16 @@ static void outliner_update_viewable_area(ARegion *ar, void draw_outliner(const bContext *C) { Main *mainvar = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); ARegion *ar = CTX_wm_region(C); View2D *v2d = &ar->v2d; SpaceOutliner *soops = CTX_wm_space_outliner(C); uiBlock *block; TreeElement *te_edit = NULL; - outliner_build_tree(mainvar, scene, view_layer, soops, ar); // always + TreeViewContext tvc; + outliner_viewcontext_init(C, &tvc); + + outliner_build_tree(mainvar, tvc.scene, tvc.view_layer, soops, ar); // always /* If global sync select is dirty, flag other outliners */ if (ED_outliner_select_sync_is_dirty(C)) { @@ -3655,8 +3646,7 @@ void draw_outliner(const bContext *C) const float restrict_column_width = outliner_restrict_columns_width(soops); outliner_back(ar); block = UI_block_begin(C, ar, __func__, UI_EMBOSS); - outliner_draw_tree( - (bContext *)C, block, scene, view_layer, ar, soops, restrict_column_width, &te_edit); + outliner_draw_tree((bContext *)C, block, &tvc, ar, soops, restrict_column_width, &te_edit); /* Compute outliner dimensions after it has been drawn. */ int tree_width, tree_height; @@ -3682,7 +3672,8 @@ void draw_outliner(const bContext *C) /* draw restriction columns */ RestrictPropertiesActive props_active; memset(&props_active, 1, sizeof(RestrictPropertiesActive)); - outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &soops->tree, props_active); + outliner_draw_restrictbuts( + block, tvc.scene, tvc.view_layer, ar, soops, &soops->tree, props_active); } UI_block_emboss_set(block, UI_EMBOSS); diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index ec85d05a1ff..23c883c0db3 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -200,6 +200,25 @@ typedef enum { #define TSELEM_OPEN(telm, sv) \ ((telm->flag & TSE_CLOSED) == 0 || (SEARCHING_OUTLINER(sv) && (telm->flag & TSE_CHILDSEARCH))) +/** + * Container to avoid passing around these variables to many functions. + * Also so we can have one place to assing these variables. + */ +typedef struct TreeViewContext { + /* Scene level. */ + struct Scene *scene; + struct ViewLayer *view_layer; + + /* Object level. */ + /** Avoid OBACT macro everywhere. */ + Object *obact; + Object *ob_edit; + /** + * The pose object may not be the active object (when in weight paint mode). + * Checking this in draw loops isn't efficient, so set only once. */ + Object *ob_pose; +} TreeViewContext; + /* outliner_tree.c ----------------------------------------------- */ void outliner_free_tree(ListBase *tree); @@ -237,16 +256,14 @@ int tree_element_id_type_to_index(TreeElement *te); /* outliner_select.c -------------------------------------------- */ eOLDrawState tree_element_type_active(struct bContext *C, - struct Scene *scene, - struct ViewLayer *view_layer, + const TreeViewContext *tvc, struct SpaceOutliner *soops, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive); eOLDrawState tree_element_active(struct bContext *C, - struct Scene *scene, - struct ViewLayer *view_layer, + const TreeViewContext *tvc, SpaceOutliner *soops, TreeElement *te, const eOLSetState set, @@ -458,6 +475,8 @@ void OUTLINER_OT_unhide_all(struct wmOperatorType *ot); /* outliner_utils.c ---------------------------------------------- */ +void outliner_viewcontext_init(const struct bContext *C, TreeViewContext *tvc); + TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops, const ListBase *tree, float view_co_y); diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 15223ca4f8b..c96f2f9956f 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -595,6 +595,7 @@ static eOLDrawState tree_element_active_posegroup(bContext *C, static eOLDrawState tree_element_active_posechannel(bContext *C, Scene *UNUSED(scene), ViewLayer *view_layer, + Object *ob_pose, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, @@ -651,7 +652,7 @@ static eOLDrawState tree_element_active_posechannel(bContext *C, } } else { - if (ob == OBACT(view_layer) && ob->pose) { + if (ob == ob_pose && ob->pose) { if (pchan->bone->flag & BONE_SELECTED) { return OL_DRAWSEL_NORMAL; } @@ -1007,8 +1008,7 @@ static eOLDrawState tree_element_active_layer_collection(bContext *C, /* generic call for ID data check or make/check active in UI */ eOLDrawState tree_element_active(bContext *C, - Scene *scene, - ViewLayer *view_layer, + const TreeViewContext *tvc, SpaceOutliner *soops, TreeElement *te, const eOLSetState set, @@ -1020,17 +1020,18 @@ eOLDrawState tree_element_active(bContext *C, * See #do_outliner_item_activate. */ case ID_OB: if (handle_all_types) { - return tree_element_set_active_object(C, scene, view_layer, soops, te, set, false); + return tree_element_set_active_object( + C, tvc->scene, tvc->view_layer, soops, te, set, false); } break; case ID_MA: - return tree_element_active_material(C, scene, view_layer, soops, te, set); + return tree_element_active_material(C, tvc->scene, tvc->view_layer, soops, te, set); case ID_WO: - return tree_element_active_world(C, scene, view_layer, soops, te, set); + return tree_element_active_world(C, tvc->scene, tvc->view_layer, soops, te, set); case ID_TXT: - return tree_element_active_text(C, scene, view_layer, soops, te, set); + return tree_element_active_text(C, tvc->scene, tvc->view_layer, soops, te, set); case ID_CA: - return tree_element_active_camera(C, scene, view_layer, soops, te, set); + return tree_element_active_camera(C, tvc->scene, tvc->view_layer, soops, te, set); } return OL_DRAWSEL_NONE; } @@ -1039,8 +1040,7 @@ eOLDrawState tree_element_active(bContext *C, * Generic call for non-id data to make/check active in UI */ eOLDrawState tree_element_type_active(bContext *C, - Scene *scene, - ViewLayer *view_layer, + const TreeViewContext *tvc, SpaceOutliner *soops, TreeElement *te, TreeStoreElem *tselem, @@ -1049,41 +1049,42 @@ eOLDrawState tree_element_type_active(bContext *C, { switch (tselem->type) { case TSE_DEFGROUP: - return tree_element_active_defgroup(C, view_layer, te, tselem, set); + return tree_element_active_defgroup(C, tvc->view_layer, te, tselem, set); case TSE_BONE: - return tree_element_active_bone(C, view_layer, te, tselem, set, recursive); + return tree_element_active_bone(C, tvc->view_layer, te, tselem, set, recursive); case TSE_EBONE: - return tree_element_active_ebone(C, view_layer, te, tselem, set, recursive); + return tree_element_active_ebone(C, tvc->view_layer, te, tselem, set, recursive); case TSE_MODIFIER: - return tree_element_active_modifier(C, scene, view_layer, te, tselem, set); + return tree_element_active_modifier(C, tvc->scene, tvc->view_layer, te, tselem, set); case TSE_LINKED_OB: if (set != OL_SETSEL_NONE) { - tree_element_set_active_object(C, scene, view_layer, soops, te, set, false); + tree_element_set_active_object(C, tvc->scene, tvc->view_layer, soops, te, set, false); } - else if (tselem->id == (ID *)OBACT(view_layer)) { + else if (tselem->id == (ID *)tvc->obact) { return OL_DRAWSEL_NORMAL; } break; case TSE_LINKED_PSYS: - return tree_element_active_psys(C, scene, te, tselem, set); + return tree_element_active_psys(C, tvc->scene, te, tselem, set); case TSE_POSE_BASE: - return tree_element_active_pose(C, scene, view_layer, te, tselem, set); + return tree_element_active_pose(C, tvc->scene, tvc->view_layer, te, tselem, set); case TSE_POSE_CHANNEL: - return tree_element_active_posechannel(C, scene, view_layer, te, tselem, set, recursive); + return tree_element_active_posechannel( + C, tvc->scene, tvc->view_layer, tvc->ob_pose, te, tselem, set, recursive); case TSE_CONSTRAINT: - return tree_element_active_constraint(C, scene, view_layer, te, tselem, set); + return tree_element_active_constraint(C, tvc->scene, tvc->view_layer, te, tselem, set); case TSE_R_LAYER: - return active_viewlayer(C, scene, view_layer, te, set); + return active_viewlayer(C, tvc->scene, tvc->view_layer, te, set); case TSE_POSEGRP: - return tree_element_active_posegroup(C, scene, view_layer, te, tselem, set); + return tree_element_active_posegroup(C, tvc->scene, tvc->view_layer, te, tselem, set); case TSE_SEQUENCE: - return tree_element_active_sequence(C, scene, te, tselem, set); + return tree_element_active_sequence(C, tvc->scene, te, tselem, set); case TSE_SEQUENCE_DUP: - return tree_element_active_sequence_dup(scene, te, tselem, set); + return tree_element_active_sequence_dup(tvc->scene, te, tselem, set); case TSE_KEYMAP_ITEM: - return tree_element_active_keymap_item(C, scene, view_layer, te, tselem, set); + return tree_element_active_keymap_item(C, tvc->scene, tvc->view_layer, te, tselem, set); case TSE_GP_LAYER: - return tree_element_active_gplayer(C, scene, te, tselem, set); + return tree_element_active_gplayer(C, tvc->scene, te, tselem, set); break; case TSE_VIEW_COLLECTION_BASE: return tree_element_active_master_collection(C, te, set); @@ -1109,8 +1110,7 @@ void outliner_element_activate(SpaceOutliner *soops, TreeStoreElem *tselem) * Needed to run from operators accessed from a menu. */ static void do_outliner_item_activate_tree_element(bContext *C, - Scene *scene, - ViewLayer *view_layer, + const TreeViewContext *tvc, SpaceOutliner *soops, TreeElement *te, TreeStoreElem *tselem, @@ -1138,8 +1138,8 @@ static void do_outliner_item_activate_tree_element(bContext *C, else if (do_activate_data) { /* Only activate when synced selection is enabled */ tree_element_set_active_object(C, - scene, - view_layer, + tvc->scene, + tvc->view_layer, soops, te, (extend && tselem->type == 0) ? OL_SETSEL_EXTEND : @@ -1155,7 +1155,7 @@ static void do_outliner_item_activate_tree_element(bContext *C, /* Only select in outliner. */ } else if (te->idcode == ID_SCE) { - if (scene != (Scene *)tselem->id) { + if (tvc->scene != (Scene *)tselem->id) { WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), (Scene *)tselem->id); } } @@ -1165,7 +1165,7 @@ static void do_outliner_item_activate_tree_element(bContext *C, if (extend) { int sel = BA_SELECT; FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (gr, object) { - Base *base = BKE_view_layer_base_find(view_layer, object); + Base *base = BKE_view_layer_base_find(tvc->view_layer, object); if (base && (base->flag & BASE_SELECTED)) { sel = BA_DESELECT; break; @@ -1174,7 +1174,7 @@ static void do_outliner_item_activate_tree_element(bContext *C, FOREACH_COLLECTION_OBJECT_RECURSIVE_END; FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (gr, object) { - Base *base = BKE_view_layer_base_find(view_layer, object); + Base *base = BKE_view_layer_base_find(tvc->view_layer, object); if (base) { ED_object_base_select(base, sel); } @@ -1182,10 +1182,10 @@ static void do_outliner_item_activate_tree_element(bContext *C, FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } else { - BKE_view_layer_base_deselect_all(view_layer); + BKE_view_layer_base_deselect_all(tvc->view_layer); FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (gr, object) { - Base *base = BKE_view_layer_base_find(view_layer, object); + Base *base = BKE_view_layer_base_find(tvc->view_layer, object); /* Object may not be in this scene */ if (base != NULL) { if ((base->flag & BASE_SELECTED) == 0) { @@ -1196,15 +1196,15 @@ static void do_outliner_item_activate_tree_element(bContext *C, FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); + DEG_id_tag_update(&tvc->scene->id, ID_RECALC_SELECT); + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, tvc->scene); } else if (OB_DATA_SUPPORT_EDITMODE(te->idcode)) { Object *ob = (Object *)outliner_search_back(soops, te, ID_OB); if ((ob != NULL) && (ob->data == tselem->id)) { - Base *base = BKE_view_layer_base_find(view_layer, ob); + Base *base = BKE_view_layer_base_find(tvc->view_layer, ob); if ((base != NULL) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) { - do_outliner_activate_obdata(C, scene, view_layer, base, extend); + do_outliner_activate_obdata(C, tvc->scene, tvc->view_layer, base, extend); } } } @@ -1213,18 +1213,12 @@ static void do_outliner_item_activate_tree_element(bContext *C, WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); } else { // rest of types - tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, false); + tree_element_active(C, tvc, soops, te, OL_SETSEL_NORMAL, false); } } else if (do_activate_data) { - tree_element_type_active(C, - scene, - view_layer, - soops, - te, - tselem, - extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL, - recursive); + tree_element_type_active( + C, tvc, soops, te, tselem, extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL, recursive); } } @@ -1331,12 +1325,12 @@ static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *soops, void outliner_item_do_activate_from_tree_element( bContext *C, TreeElement *te, TreeStoreElem *tselem, bool extend, bool recursive) { - Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); SpaceOutliner *soops = CTX_wm_space_outliner(C); - do_outliner_item_activate_tree_element( - C, scene, view_layer, soops, te, tselem, extend, recursive, false); + TreeViewContext tvc; + outliner_viewcontext_init(C, &tvc); + + do_outliner_item_activate_tree_element(C, &tvc, soops, te, tselem, extend, recursive, false); } /** @@ -1351,7 +1345,6 @@ static int outliner_item_do_activate_from_cursor(bContext *C, const bool deselect_all) { ARegion *ar = CTX_wm_region(C); - Scene *scene = CTX_data_scene(C); SpaceOutliner *soops = CTX_wm_space_outliner(C); TreeElement *te; float view_mval[2]; @@ -1375,8 +1368,6 @@ static int outliner_item_do_activate_from_cursor(bContext *C, return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } else { - ViewLayer *view_layer = CTX_data_view_layer(C); - /* The row may also contain children, if one is hovered we want this instead of current te */ bool merged_elements = false; TreeElement *activate_te = outliner_find_item_at_x_in_row( @@ -1394,18 +1385,14 @@ static int outliner_item_do_activate_from_cursor(bContext *C, do_outliner_range_select(C, soops, activate_te, extend); } else { + TreeViewContext tvc; + outliner_viewcontext_init(C, &tvc); + const bool is_over_name_icons = outliner_item_is_co_over_name_icons(activate_te, view_mval[0]); outliner_item_select(soops, activate_te, extend, extend); - do_outliner_item_activate_tree_element(C, - scene, - view_layer, - soops, - activate_te, - activate_tselem, - extend, - false, - is_over_name_icons); + do_outliner_item_activate_tree_element( + C, &tvc, soops, activate_te, activate_tselem, extend, false, is_over_name_icons); } changed = true; diff --git a/source/blender/editors/space_outliner/outliner_sync.c b/source/blender/editors/space_outliner/outliner_sync.c index 29c820bce92..745a527cc15 100644 --- a/source/blender/editors/space_outliner/outliner_sync.c +++ b/source/blender/editors/space_outliner/outliner_sync.c @@ -37,6 +37,7 @@ #include "BKE_context.h" #include "BKE_layer.h" #include "BKE_main.h" +#include "BKE_object.h" #include "BKE_sequencer.h" #include "DEG_depsgraph.h" @@ -129,14 +130,14 @@ static void outliner_sync_select_from_outliner_set_types(bContext *C, SpaceOutliner *soops, SyncSelectTypes *sync_types) { - Object *obact = CTX_data_active_object(C); - Object *obedit = CTX_data_edit_object(C); + TreeViewContext tvc; + outliner_viewcontext_init(C, &tvc); const bool sequence_view = soops->outlinevis == SO_SEQUENCE; sync_types->object = !sequence_view; - sync_types->edit_bone = !sequence_view && (obedit && obedit->type == OB_ARMATURE); - sync_types->pose_bone = !sequence_view && (obact && obact->mode == OB_MODE_POSE); + sync_types->edit_bone = !sequence_view && (tvc.ob_edit && tvc.ob_edit->type == OB_ARMATURE); + sync_types->pose_bone = !sequence_view && (tvc.ob_pose && tvc.ob_pose->mode == OB_MODE_POSE); sync_types->sequence = sequence_view; } @@ -149,16 +150,16 @@ static bool outliner_sync_select_to_outliner_set_types(const bContext *C, SpaceOutliner *soops, SyncSelectTypes *sync_types) { - Object *obact = CTX_data_active_object(C); - Object *obedit = CTX_data_edit_object(C); + TreeViewContext tvc; + outliner_viewcontext_init(C, &tvc); const bool sequence_view = soops->outlinevis == SO_SEQUENCE; sync_types->object = !sequence_view && (soops->sync_select_dirty & WM_OUTLINER_SYNC_SELECT_FROM_OBJECT); - sync_types->edit_bone = !sequence_view && (obedit && obedit->type == OB_ARMATURE) && + sync_types->edit_bone = !sequence_view && (tvc.ob_edit && tvc.ob_edit->type == OB_ARMATURE) && (soops->sync_select_dirty & WM_OUTLINER_SYNC_SELECT_FROM_EDIT_BONE); - sync_types->pose_bone = !sequence_view && (obact && obact->mode == OB_MODE_POSE) && + sync_types->pose_bone = !sequence_view && (tvc.ob_pose && tvc.ob_pose->mode == OB_MODE_POSE) && (soops->sync_select_dirty & WM_OUTLINER_SYNC_SELECT_FROM_POSE_BONE); sync_types->sequence = sequence_view && (soops->sync_select_dirty & WM_OUTLINER_SYNC_SELECT_FROM_SEQUENCE); diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c index 31d930ce2e6..c3984ab16fa 100644 --- a/source/blender/editors/space_outliner/outliner_utils.c +++ b/source/blender/editors/space_outliner/outliner_utils.c @@ -21,6 +21,8 @@ * \ingroup spoutliner */ +#include + #include "BLI_utildefines.h" #include "DNA_action_types.h" @@ -30,6 +32,7 @@ #include "BKE_context.h" #include "BKE_outliner_treehash.h" #include "BKE_layer.h" +#include "BKE_object.h" #include "ED_armature.h" #include "ED_outliner.h" @@ -39,6 +42,33 @@ #include "outliner_intern.h" +/* -------------------------------------------------------------------- */ +/** \name Tree View Context + * \{ */ + +void outliner_viewcontext_init(const bContext *C, TreeViewContext *tvc) +{ + memset(tvc, 0, sizeof(*tvc)); + + /* Scene level. */ + tvc->scene = CTX_data_scene(C); + tvc->view_layer = CTX_data_view_layer(C); + + /* Objects. */ + tvc->obact = OBACT(tvc->view_layer); + if (tvc->obact != NULL) { + tvc->ob_edit = OBEDIT_FROM_OBACT(tvc->obact); + + if ((tvc->obact->type == OB_ARMATURE) || + /* This could be made into it's own function. */ + ((tvc->obact->type == OB_MESH) && tvc->obact->mode & OB_MODE_WEIGHT_PAINT)) { + tvc->ob_pose = BKE_object_pose_armature_get(tvc->obact); + } + } +} + +/** \} */ + /** * Try to find an item under y-coordinate \a view_co_y (view-space). * \note Recursive -- cgit v1.2.3