diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index 5a54d4ca2d8..e0764bc990c 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -358,6 +358,10 @@ class OUTLINER_PT_filter(Panel): row.prop(space, "use_sync_select", text="Sync Selection") layout.separator() + row = layout.row(align=True) + row.prop(space, "show_mode_column", text="Show Mode Column") + layout.separator() + col = layout.column(align=True) col.label(text="Search:") col.prop(space, "use_filter_complete", text="Exact Match") diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index 73a4b1a9098..cf07e9acad3 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -585,6 +585,18 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) do_versions_point_attributes(&pointcloud->pdata); } + /* Show outliner mode column by default. */ + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) { + if (space->spacetype == SPACE_OUTLINER) { + SpaceOutliner *space_outliner = (SpaceOutliner *)space; + + space_outliner->flag |= SO_MODE_COLUMN; + } + } + } + } /* Keep this block, even when empty. */ } } diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h index 7b59d45b203..bbe66f7fd73 100644 --- a/source/blender/editors/include/UI_interface_icons.h +++ b/source/blender/editors/include/UI_interface_icons.h @@ -106,6 +106,7 @@ struct PreviewImage *UI_icon_to_preview(int icon_id); int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, const bool big); int UI_idcode_icon_get(const int idcode); int UI_library_icon_get(const struct ID *id); +int UI_mode_icon_get(const int mode); #ifdef __cplusplus } diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index b5f902adfb5..c91b4d826a7 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -2294,6 +2294,36 @@ int UI_idcode_icon_get(const int idcode) } } +int UI_mode_icon_get(const int mode) +{ + switch (mode) { + case OB_MODE_OBJECT: + return ICON_OBJECT_DATAMODE; + case OB_MODE_EDIT: + case OB_MODE_EDIT_GPENCIL: + return ICON_EDITMODE_HLT; + case OB_MODE_SCULPT: + case OB_MODE_SCULPT_GPENCIL: + return ICON_SCULPTMODE_HLT; + case OB_MODE_VERTEX_PAINT: + case OB_MODE_VERTEX_GPENCIL: + return ICON_VPAINT_HLT; + case OB_MODE_WEIGHT_PAINT: + case OB_MODE_WEIGHT_GPENCIL: + return ICON_WPAINT_HLT; + case OB_MODE_TEXTURE_PAINT: + return ICON_TPAINT_HLT; + case OB_MODE_PARTICLE_EDIT: + return ICON_PARTICLEMODE; + case OB_MODE_POSE: + return ICON_POSE_HLT; + case OB_MODE_PAINT_GPENCIL: + return ICON_GREASEPENCIL; + default: + return ICON_NONE; + } +} + /* draws icon with dpi scale factor */ void UI_icon_draw(float x, float y, int icon_id) { diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c index 94052223e39..46a5f90f6c2 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.c +++ b/source/blender/editors/space_outliner/outliner_dragdrop.c @@ -893,6 +893,9 @@ static int outliner_item_drag_drop_invoke(bContext *C, if (outliner_item_is_co_within_close_toggle(te, view_mval[0])) { return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); } + if (outliner_is_co_within_mode_column(space_outliner, view_mval)) { + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; + } /* Scroll the view when dragging near edges, but not * when the drag goes too far outside the region. */ diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index fbef3aa07d7..3de786ddd4d 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -53,6 +53,7 @@ #include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_particle.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -1884,6 +1885,109 @@ static void outliner_buttons(const bContext *C, } } +static void outliner_mode_toggle_fn(bContext *C, void *tselem_poin, void *UNUSED(arg2)) +{ + SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); + TreeStoreElem *tselem = (TreeStoreElem *)tselem_poin; + TreeViewContext tvc; + outliner_viewcontext_init(C, &tvc); + + TreeElement *te = outliner_find_tree_element(&space_outliner->tree, tselem); + if (!te) { + return; + } + + wmWindow *win = CTX_wm_window(C); + const bool do_extend = win->eventstate->ctrl != 0; + outliner_item_mode_toggle(C, &tvc, te, do_extend); +} + +/* Draw icons for adding and removing objects from the current interation mode. */ +static void outliner_draw_mode_column_toggle(uiBlock *block, + TreeViewContext *tvc, + TreeElement *te, + TreeStoreElem *tselem, + const bool lock_object_modes) +{ + const int active_mode = tvc->obact->mode; + bool draw_active_icon = true; + + if (tselem->type == 0 && te->idcode == ID_OB) { + Object *ob = (Object *)tselem->id; + + /* When not locking object modes, objects can remain in non-object modes. For modes that do not + * allow multi-object editing, these other objects should still show be viewed as not in the + * mode. Otherwise multiple objects show the same mode icon in the outliner even though only + * one object is actually editable in the mode. */ + if (!lock_object_modes && ob != tvc->obact && !(tvc->ob_edit || tvc->ob_pose)) { + draw_active_icon = false; + } + + if (ob->type == tvc->obact->type) { + int icon; + const char *tip; + + if (draw_active_icon && ob->mode == tvc->obact->mode) { + icon = UI_mode_icon_get(active_mode); + tip = TIP_("Remove from the current mode"); + } + else { + /* Not all objects support particle systems */ + if (active_mode == OB_MODE_PARTICLE_EDIT && !psys_get_current(ob)) { + return; + } + icon = ICON_DOT; + tip = TIP_( + "Change the object in the current mode\n" + "* Ctrl to add to the current mode"); + } + + uiBut *but = uiDefIconBut(block, + UI_BTYPE_ICON_TOGGLE, + 0, + icon, + 0, + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + NULL, + 0.0, + 0.0, + 0.0, + 0.0, + tip); + UI_but_func_set(but, outliner_mode_toggle_fn, tselem, NULL); + UI_but_flag_enable(but, UI_BUT_DRAG_LOCK); + + if (ID_IS_LINKED(&ob->id)) { + UI_but_disable(but, TIP_("Can't edit external library data")); + } + } + } +} + +static void outliner_draw_mode_column(const bContext *C, + uiBlock *block, + TreeViewContext *tvc, + SpaceOutliner *space_outliner, + ListBase *tree) +{ + TreeStoreElem *tselem; + const bool lock_object_modes = tvc->scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK; + + LISTBASE_FOREACH (TreeElement *, te, tree) { + tselem = TREESTORE(te); + + if (tvc->obact && tvc->obact->mode != OB_MODE_OBJECT) { + outliner_draw_mode_column_toggle(block, tvc, te, tselem, lock_object_modes); + } + + if (TSELEM_OPEN(tselem, space_outliner)) { + outliner_draw_mode_column(C, block, tvc, space_outliner, &te->subtree); + } + } +} + /* ****************************************************** */ /* Normal Drawing... */ @@ -3500,11 +3604,20 @@ static void outliner_draw_tree(bContext *C, ARegion *region, SpaceOutliner *space_outliner, const float restrict_column_width, + const bool use_mode_column, TreeElement **te_edit) { const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; int starty, startx; + /* Move the tree a unit left in view layer mode */ + short mode_column_offset = (use_mode_column && (space_outliner->outlinevis == SO_SCENES)) ? + UI_UNIT_X : + 0; + if (!use_mode_column && (space_outliner->outlinevis == SO_VIEW_LAYER)) { + mode_column_offset -= UI_UNIT_X; + } + GPU_blend(GPU_BLEND_ALPHA); /* Only once. */ if (space_outliner->outlinevis == SO_DATA_API) { @@ -3530,12 +3643,12 @@ static void outliner_draw_tree(bContext *C, /* Gray hierarchy lines. */ starty = (int)region->v2d.tot.ymax - UI_UNIT_Y / 2 - OL_Y_OFFSET; - startx = UI_UNIT_X / 2 - (U.pixelsize + 1) / 2; + startx = mode_column_offset + UI_UNIT_X / 2 - (U.pixelsize + 1) / 2; outliner_draw_hierarchy_lines(space_outliner, &space_outliner->tree, startx, &starty); /* Items themselves. */ starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET; - startx = 0; + startx = mode_column_offset; LISTBASE_FOREACH (TreeElement *, te, &space_outliner->tree) { outliner_draw_tree_element(C, block, @@ -3658,12 +3771,22 @@ void draw_outliner(const bContext *C) /* set matrix for 2d-view controls */ UI_view2d_view_ortho(v2d); + /* Only show mode column in View Layers and Scenes view */ + const bool use_mode_column = (space_outliner->flag & SO_MODE_COLUMN) && + (ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES)); + /* draw outliner stuff (background, hierarchy lines and names) */ const float restrict_column_width = outliner_restrict_columns_width(space_outliner); outliner_back(region); block = UI_block_begin(C, region, __func__, UI_EMBOSS); - outliner_draw_tree( - (bContext *)C, block, &tvc, region, space_outliner, restrict_column_width, &te_edit); + outliner_draw_tree((bContext *)C, + block, + &tvc, + region, + space_outliner, + restrict_column_width, + use_mode_column, + &te_edit); /* Compute outliner dimensions after it has been drawn. */ int tree_width, tree_height; @@ -3698,6 +3821,11 @@ void draw_outliner(const bContext *C) props_active); } + /* Draw mode icons */ + if (use_mode_column) { + outliner_draw_mode_column(C, block, &tvc, space_outliner, &space_outliner->tree); + } + UI_block_emboss_set(block, UI_EMBOSS); /* Draw edit buttons if necessary. */ diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 7e7fdf4bab2..e02e6118152 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -222,7 +222,6 @@ typedef enum TreeItemSelectAction { OL_ITEM_ACTIVATE = (1 << 2), /* Activate the item */ OL_ITEM_EXTEND = (1 << 3), /* Extend the current selection */ OL_ITEM_RECURSIVE = (1 << 4), /* Select recursively */ - OL_ITEM_TOGGLE_MODE = (1 << 5) /* Temporary */ } TreeItemSelectAction; /* outliner_tree.c ----------------------------------------------- */ @@ -289,6 +288,12 @@ void outliner_object_mode_toggle(struct bContext *C, bool outliner_item_is_co_over_name_icons(const TreeElement *te, float view_co_x); bool outliner_item_is_co_within_close_toggle(const TreeElement *te, float view_co_x); +bool outliner_is_co_within_mode_column(SpaceOutliner *space_outliner, const float view_mval[2]); + +void outliner_item_mode_toggle(struct bContext *C, + TreeViewContext *tvc, + TreeElement *te, + const bool do_extend); /* outliner_edit.c ---------------------------------------------- */ typedef void (*outliner_operation_fn)(struct bContext *C, diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 266ea293d43..fe40d4cfd36 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -64,6 +64,7 @@ #include "ED_undo.h" #include "WM_api.h" +#include "WM_toolsystem.h" #include "WM_types.h" #include "UI_interface.h" @@ -74,187 +75,99 @@ #include "outliner_intern.h" -static bool do_outliner_activate_common(bContext *C, - Main *bmain, - Depsgraph *depsgraph, - Scene *scene, - ViewLayer *view_layer, - Base *base, - const bool extend, - const bool do_exit) -{ - bool use_all = false; - - if (do_exit) { - FOREACH_OBJECT_BEGIN (view_layer, ob_iter) { - ED_object_mode_generic_exit(bmain, depsgraph, scene, ob_iter); - } - FOREACH_OBJECT_END; - } - - /* Just like clicking in the object changes the active object, - * clicking on the object data should change it as well. */ - ED_object_base_activate(C, base); - - if (extend) { - use_all = true; - } - else { - ED_object_base_deselect_all(view_layer, NULL, SEL_DESELECT); - } - - return use_all; -} - -/** - * Bring the newly selected object into edit mode. - * - * If extend is used, we try to have the other compatible selected objects in the new mode as well. - * Otherwise only the new object will be active, selected and in the edit mode. - */ -static void do_outliner_item_editmode_toggle( - bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend) +static void do_outliner_item_editmode_toggle(bContext *C, Scene *scene, Base *base) { Main *bmain = CTX_data_main(C); - Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - Object *obact = OBACT(view_layer); Object *ob = base->object; - bool use_all = false; - if (obact == NULL) { - ED_object_base_activate(C, base); - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - obact = ob; - use_all = true; - } - else if (obact->data == ob->data) { - use_all = true; - } - else if (obact->mode == OB_MODE_OBJECT) { - use_all = do_outliner_activate_common( - C, bmain, depsgraph, scene, view_layer, base, extend, false); - } - else if ((ob->type != obact->type) || ((obact->mode & OB_MODE_EDIT) == 0) || - ((obact->mode & OB_MODE_POSE) && ELEM(OB_ARMATURE, ob->type, obact->type)) || !extend) { - use_all = do_outliner_activate_common( - C, bmain, depsgraph, scene, view_layer, base, extend, true); - } - - if (use_all) { - WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); + if (BKE_object_is_in_editmode(ob)) { + ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA); + WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL); } else { - bool ok; - if (BKE_object_is_in_editmode(ob)) { - ok = ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA); - } - else { - ok = ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_NO_CONTEXT); - } - if (ok) { - ED_object_base_select(base, (ob->mode & OB_MODE_EDIT) ? BA_SELECT : BA_DESELECT); - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - } + ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_NO_CONTEXT); + WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL); } } -static void do_outliner_item_posemode_toggle( - bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend) +static void do_outliner_item_posemode_toggle(bContext *C, Base *base) +{ + Main *bmain = CTX_data_main(C); + Object *ob = base->object; + + if (ID_IS_LINKED(ob)) { + BKE_report(CTX_wm_reports(C), RPT_WARNING, "Cannot pose libdata"); + } + else if (ob->mode & OB_MODE_POSE) { + ED_object_posemode_exit_ex(bmain, ob); + WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL); + } + else { + ED_object_posemode_enter_ex(bmain, ob); + WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL); + } +} + +/* Swap the current active object from the interaction mode with the given base. */ +static void do_outliner_item_mode_toggle_generic(bContext *C, TreeViewContext *tvc, Base *base) { Main *bmain = CTX_data_main(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - Object *obact = OBACT(view_layer); - Object *ob = base->object; - bool use_all = false; + const int active_mode = tvc->obact->mode; - if (obact == NULL) { + /* Return all objects to object mode. */ + FOREACH_OBJECT_BEGIN (tvc->view_layer, ob_iter) { + ED_object_mode_generic_exit(bmain, depsgraph, tvc->scene, ob_iter); + } + FOREACH_OBJECT_END; + WM_toolsystem_update_from_context_view3d(C); + + Base *base_active = BKE_view_layer_base_find(tvc->view_layer, tvc->obact); + if (base_active != base) { + ED_object_base_select(base_active, BA_DESELECT); ED_object_base_activate(C, base); - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - obact = ob; - use_all = true; - } - else if (obact->data == ob->data) { - use_all = true; - } - else if (obact->mode == OB_MODE_OBJECT) { - use_all = do_outliner_activate_common( - C, bmain, depsgraph, scene, view_layer, base, extend, false); - } - else if ((!ELEM(ob->type, obact->type)) || - ((obact->mode & OB_MODE_EDIT) && ELEM(OB_ARMATURE, ob->type, obact->type))) { - use_all = do_outliner_activate_common( - C, bmain, depsgraph, scene, view_layer, base, extend, true); - } + ED_object_base_select(base, BA_SELECT); - if (use_all) { - WM_operator_name_call(C, "OBJECT_OT_posemode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); - } - else { - bool ok = false; - - if (ID_IS_LINKED(ob)) { - BKE_report(CTX_wm_reports(C), RPT_WARNING, "Cannot pose libdata"); - } - else if (ob->mode & OB_MODE_POSE) { - ok = ED_object_posemode_exit_ex(bmain, ob); - } - else { - ok = ED_object_posemode_enter_ex(bmain, ob); - } - - if (ok) { - ED_object_base_select(base, (ob->mode & OB_MODE_POSE) ? BA_SELECT : BA_DESELECT); - - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - } + /* XXX: Must add undo step between activation and setting mode to prevent an assert. */ + ED_undo_push(C, "outliner mode toggle"); + ED_object_mode_set(C, active_mode); + ED_outliner_select_sync_from_object_tag(C); } } /* For draw callback to run mode switching */ -void outliner_object_mode_toggle(bContext *C, Scene *scene, ViewLayer *view_layer, Base *base) +void outliner_object_mode_toggle(bContext *UNUSED(C), + Scene *UNUSED(scene), + ViewLayer *UNUSED(view_layer), + Base *UNUSED(base)) { - Object *obact = OBACT(view_layer); - if (obact->mode & OB_MODE_EDIT) { - do_outliner_item_editmode_toggle(C, scene, view_layer, base, true); - } - else if (obact->mode & OB_MODE_POSE) { - do_outliner_item_posemode_toggle(C, scene, view_layer, base, true); - } } /* Toggle the item's interaction mode if supported */ -static void outliner_item_mode_toggle(bContext *C, - TreeViewContext *tvc, - TreeElement *te, - const bool extend) +void outliner_item_mode_toggle(bContext *C, + TreeViewContext *tvc, + TreeElement *te, + const bool do_extend) { TreeStoreElem *tselem = TREESTORE(te); - if (tselem->type == 0) { - if (OB_DATA_SUPPORT_EDITMODE(te->idcode)) { - Object *ob = (Object *)outliner_search_back(te, ID_OB); - if ((ob != NULL) && (ob->data == tselem->id)) { - Base *base = BKE_view_layer_base_find(tvc->view_layer, ob); - if ((base != NULL) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) { - do_outliner_item_editmode_toggle(C, tvc->scene, tvc->view_layer, base, extend); - } - } - } - else if (ELEM(te->idcode, ID_GD)) { - /* set grease pencil to object mode */ - WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); - } - } - else if (tselem->type == TSE_POSE_BASE) { + if (tselem->type == 0 && te->idcode == ID_OB) { Object *ob = (Object *)tselem->id; Base *base = BKE_view_layer_base_find(tvc->view_layer, ob); - if (base != NULL) { - do_outliner_item_posemode_toggle(C, tvc->scene, tvc->view_layer, base, extend); + + /* Hidden objects can be removed from the mode. */ + if (!base || (!(base->flag & BASE_VISIBLE_DEPSGRAPH) && (ob->mode != tvc->obact->mode))) { + return; + } + + if (!do_extend) { + do_outliner_item_mode_toggle_generic(C, tvc, base); + } + else if (tvc->ob_edit && OB_TYPE_SUPPORT_EDITMODE(ob->type)) { + do_outliner_item_editmode_toggle(C, tvc->scene, base); + } + else if (tvc->ob_pose && ob->type == OB_ARMATURE) { + do_outliner_item_posemode_toggle(C, base); } } } @@ -1272,11 +1185,6 @@ void outliner_item_select(bContext *C, extend, select_flag & OL_ITEM_RECURSIVE, activate_data || space_outliner->flag & SO_SYNC_SELECT); - - /* Mode toggle on data activate for now, but move later */ - if (select_flag & OL_ITEM_TOGGLE_MODE) { - outliner_item_mode_toggle(C, &tvc, te, extend); - } } } @@ -1353,6 +1261,16 @@ static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *space_ou return (view_co_x > region->v2d.cur.xmax - outliner_restrict_columns_width(space_outliner)); } +bool outliner_is_co_within_mode_column(SpaceOutliner *space_outliner, const float view_mval[2]) +{ + /* Mode toggles only show in View Layer and Scenes modes. */ + if (!ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES)) { + return false; + } + + return space_outliner->flag & SO_MODE_COLUMN && view_mval[0] < UI_UNIT_X; +} + /** * Action to run when clicking in the outliner, * @@ -1375,6 +1293,9 @@ static int outliner_item_do_activate_from_cursor(bContext *C, if (outliner_is_co_within_restrict_columns(space_outliner, region, view_mval[0])) { return OPERATOR_CANCELLED; } + else if (outliner_is_co_within_mode_column(space_outliner, view_mval)) { + return OPERATOR_CANCELLED; + } if (!(te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_mval[1]))) { if (deselect_all) { @@ -1413,7 +1334,7 @@ static int outliner_item_do_activate_from_cursor(bContext *C, const short select_flag = OL_ITEM_ACTIVATE | (select ? OL_ITEM_SELECT : OL_ITEM_DESELECT) | (is_over_name_icons ? OL_ITEM_SELECT_DATA : 0) | - (extend ? OL_ITEM_EXTEND : 0) | OL_ITEM_TOGGLE_MODE; + (extend ? OL_ITEM_EXTEND : 0); outliner_item_select(C, space_outliner, activate_te, select_flag); } @@ -1542,6 +1463,10 @@ static int outliner_box_select_invoke(bContext *C, wmOperator *op, const wmEvent return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } + if (outliner_is_co_within_mode_column(space_outliner, view_mval)) { + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; + } + return WM_gesture_box_invoke(C, op, event); } diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 6a63c3c65c3..2ed834a15dd 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -314,7 +314,7 @@ static SpaceLink *outliner_create(const ScrArea *UNUSED(area), const Scene *UNUS space_outliner->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_HIDE; space_outliner->outlinevis = SO_VIEW_LAYER; space_outliner->sync_select_dirty |= WM_OUTLINER_SYNC_SELECT_FROM_ALL; - space_outliner->flag |= SO_SYNC_SELECT; + space_outliner->flag = SO_SYNC_SELECT | SO_MODE_COLUMN; /* header */ region = MEM_callocN(sizeof(ARegion), "header for outliner"); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 6fe6a5461e1..06ab01a9730 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -284,6 +284,7 @@ typedef enum eSpaceOutliner_Flag { /* SO_HIDE_KEYINGSETINFO = (1 << 3), */ /* UNUSED */ SO_SKIP_SORT_ALPHA = (1 << 4), SO_SYNC_SELECT = (1 << 5), + SO_MODE_COLUMN = (1 << 6), } eSpaceOutliner_Flag; /* SpaceOutliner.filter */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 99f81fd531a..66d7685b3a6 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -3041,6 +3041,12 @@ static void rna_def_space_outliner(BlenderRNA *brna) prop, "Sync Outliner Selection", "Sync outliner selection with other editors"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + prop = RNA_def_property(srna, "show_mode_column", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SO_MODE_COLUMN); + RNA_def_property_ui_text( + prop, "Show Mode Column", "Show the mode column for mode toggle and activation"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + /* Granular restriction column option. */ prop = RNA_def_property(srna, "show_restrict_column_enable", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_ENABLE);