Outliner: add object mode switching to RMB menu

This commit is contained in:
Campbell Barton
2018-06-20 10:04:43 +02:00
parent 9f9756ec35
commit df2d05b203
5 changed files with 96 additions and 0 deletions

View File

@@ -205,6 +205,8 @@ class OUTLINER_MT_object(Menu):
layout = self.layout
space = context.space_data
obj = context.active_object
object_mode = 'OBJECT' if obj is None else obj.mode
layout.operator("outliner.object_operation", text="Delete").type = 'DELETE'
if space.display_mode == 'VIEW_LAYER' and not space.use_filter_collection:
@@ -218,6 +220,14 @@ class OUTLINER_MT_object(Menu):
layout.separator()
if object_mode in {'EDIT', 'POSE'}:
name = bpy.types.Object.bl_rna.properties["mode"].enum_items[object_mode].name
layout.operator("outliner.object_operation", text=f"{name} Set").type = 'OBJECT_MODE_ENTER'
layout.operator("outliner.object_operation", text=f"{name} Clear").type = 'OBJECT_MODE_EXIT'
del name
layout.separator()
if not (space.display_mode == 'VIEW_LAYER' and not space.use_filter_collection):
layout.operator("outliner.id_operation", text="Unlink").type = 'UNLINK'
layout.separator()

View File

@@ -253,6 +253,55 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 1, "All", "Close or open all items");
}
/* -------------------------------------------------------------------- */
/** \name Object Mode Enter/Exit
* \{ */
static void item_object_mode_enter_exit(
bContext *C, ReportList *reports, Object *ob,
bool enter)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obact = OBACT(view_layer);
if ((ob->type != obact->type) || ID_IS_LINKED(ob->data)) {
return;
}
if (((ob->mode & obact->mode) != 0) == enter) {
return;
}
if (ob == obact) {
BKE_report(reports, RPT_WARNING, "Active object mode not changed");
return;
}
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base == NULL) {
return;
}
Scene *scene = CTX_data_scene(C);
outliner_object_mode_toggle(C, scene, view_layer, base);
}
void item_object_mode_enter_cb(
bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *UNUSED(te),
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
{
Object *ob = (Object *)tselem->id;
item_object_mode_enter_exit(C, reports, ob, true);
}
void item_object_mode_exit_cb(
bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *UNUSED(te),
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
{
Object *ob = (Object *)tselem->id;
item_object_mode_enter_exit(C, reports, ob, false);
}
/** \} */
/* Rename --------------------------------------------------- */
static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem,

View File

@@ -226,6 +226,10 @@ void outliner_item_select(
struct SpaceOops *soops, const struct TreeElement *te,
const bool extend, const bool toggle);
void outliner_object_mode_toggle(
struct bContext *C, Scene *scene, ViewLayer *view_layer,
Base *base);
/* outliner_edit.c ---------------------------------------------- */
typedef void (*outliner_operation_cb)(
struct bContext *C, struct ReportList *, struct Scene *scene,
@@ -271,6 +275,13 @@ void id_remap_cb(
struct bContext *C, struct ReportList *reports, struct Scene *scene, struct TreeElement *te,
struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
void item_object_mode_enter_cb(
struct bContext *C, struct ReportList *reports, struct Scene *scene,
TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
void item_object_mode_exit_cb(
struct bContext *C, struct ReportList *reports, struct Scene *scene,
TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
TreeElement *outliner_dropzone_find(const struct SpaceOops *soops, const float fmval[2], const bool children);
void outliner_set_coordinates(struct ARegion *ar, struct SpaceOops *soops);

View File

@@ -155,6 +155,20 @@ static void do_outliner_activate_pose(bContext *C, ViewLayer *view_layer, Base *
}
}
/* For draw callback to run mode switching */
void outliner_object_mode_toggle(
bContext *C, Scene *scene, ViewLayer *view_layer,
Base *base)
{
Object *obact = OBACT(view_layer);
if (obact->mode & OB_MODE_EDIT) {
do_outliner_activate_obdata(C, scene, view_layer, base);
}
else if (obact->mode & OB_MODE_POSE) {
do_outliner_activate_pose(C, view_layer, base);
}
}
/* ****************************************************** */
/* Outliner Element Selection/Activation on Click */

View File

@@ -911,6 +911,8 @@ enum {
OL_OP_TOGSEL,
OL_OP_TOGREN,
OL_OP_RENAME,
OL_OP_OBJECT_MODE_ENTER,
OL_OP_OBJECT_MODE_EXIT,
};
static const EnumPropertyItem prop_object_op_types[] = {
@@ -922,6 +924,8 @@ static const EnumPropertyItem prop_object_op_types[] = {
{OL_OP_REMAP, "REMAP", 0, "Remap Users",
"Make all users of selected data-blocks to use instead a new chosen one"},
{OL_OP_RENAME, "RENAME", 0, "Rename", ""},
{OL_OP_OBJECT_MODE_ENTER, "OBJECT_MODE_ENTER", 0, "Enter Mode", ""},
{OL_OP_OBJECT_MODE_EXIT, "OBJECT_MODE_EXIT", 0, "Exit Mode", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -1005,6 +1009,14 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_rename_cb);
str = "Rename Object";
}
else if (event == OL_OP_OBJECT_MODE_ENTER) {
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_object_mode_enter_cb);
str = "Enter Current Mode";
}
else if (event == OL_OP_OBJECT_MODE_EXIT) {
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_object_mode_exit_cb);
str = "Exit Current Mode";
}
else {
BLI_assert(0);
return OPERATOR_CANCELLED;