Outliner: Move mode toggling to left column

Add a column of icons in the left gutter of the outliner for controlling
the interaction modes of objects. When an object is in a mode other than
object mode, the mode icon will draw to the left of that object. Any
other objects that are valid to be added or swapped into the mode are
drawn with a dot to the left of the object.

Clicking the dot to the left of an object will swap that object with the
current active object in the interaction mode. For edit and pose modes,
ctrl clicking the dot will add that object to the current mode.

Clicking the mode icon next to the active object removes it and all
other objects from the current mode.

The behavior is nearly identical to the previous edit/pose mode toggling
by selecting the mesh and armature datablocks, with additional support
for all interaction modes.

Currently two undo steps are pushed to prevent an assert.

Part of T77408

Manifest Task: https://developer.blender.org/T68498

Differential Revision: https://developer.blender.org/D8641
This commit is contained in:
Nathan Craddock 2020-09-10 08:35:58 -06:00
parent 0649e63716
commit 2110af20f5
Notes: blender-bot 2023-02-14 06:17:14 +01:00
Referenced by commit 8953485f56, Fix: Selection not possible from outliner gutter
Referenced by issue #83374, pose mode not working
Referenced by issue #77408, Continued Outliner Improvements Design
Referenced by issue #68498, Outliner: Mode Toggling
11 changed files with 280 additions and 165 deletions

View File

@ -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")

View File

@ -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. */
}
}

View File

@ -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
}

View File

@ -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)
{

View File

@ -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. */

View File

@ -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. */

View File

@ -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,

View File

@ -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);
}

View File

@ -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");

View File

@ -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 */

View File

@ -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);