Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py4
-rw-r--r--source/blender/blenloader/intern/versioning_290.c12
-rw-r--r--source/blender/editors/include/UI_interface_icons.h1
-rw-r--r--source/blender/editors/interface/interface_icons.c30
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c136
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h7
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c225
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c2
-rw-r--r--source/blender/makesdna/DNA_space_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_space.c6
11 files changed, 271 insertions, 156 deletions
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)
+static void do_outliner_item_editmode_toggle(bContext *C, Scene *scene, Base *base)
{
- 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);
+ Main *bmain = CTX_data_main(C);
+ Object *ob = base->object;
- if (extend) {
- use_all = true;
+ 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 {
- ED_object_base_deselect_all(view_layer, NULL, SEL_DESELECT);
+ ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_NO_CONTEXT);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
}
-
- 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_posemode_toggle(bContext *C, 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;
+ if (ID_IS_LINKED(ob)) {
+ BKE_report(CTX_wm_reports(C), RPT_WARNING, "Cannot pose libdata");
}
- 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);
+ 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 {
- 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_posemode_enter_ex(bmain, ob);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL);
}
}
-static void do_outliner_item_posemode_toggle(
- bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend)
+/* 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) {
- 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;
+ /* 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);
}
- 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);
- }
-
- 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);
- }
+ FOREACH_OBJECT_END;
+ WM_toolsystem_update_from_context_view3d(C);
- if (ok) {
- ED_object_base_select(base, (ob->mode & OB_MODE_POSE) ? BA_SELECT : BA_DESELECT);
+ 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);
+ ED_object_base_select(base, BA_SELECT);
- 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);