Outliner: add outliner wide RMB context menu.

All right click menus in the outliner now include OUTLINER_MT_context.
This commit is contained in:
Brecht Van Lommel 2018-07-02 14:47:30 +02:00
parent b3098c30a6
commit 34678388f3
2 changed files with 74 additions and 24 deletions

View File

@ -101,6 +101,15 @@ class OUTLINER_MT_editor_menus(Menu):
layout.menu("OUTLINER_MT_edit_orphan_data")
class OUTLINER_MT_context(Menu):
bl_label = "Outliner"
def draw(self, context):
layout = self.layout
layout.menu("INFO_MT_area")
class OUTLINER_MT_view(Menu):
bl_label = "View"
@ -126,10 +135,6 @@ class OUTLINER_MT_view(Menu):
layout.operator("outliner.show_one_level", text="Hide One Level").open = False
layout.operator("outliner.show_hierarchy")
layout.separator()
layout.menu("INFO_MT_area")
class OUTLINER_MT_edit_datablocks(Menu):
bl_label = "Edit"
@ -198,6 +203,10 @@ class OUTLINER_MT_collection(Menu):
layout.separator()
layout.operator_menu_enum("outliner.id_operation", "type", text="ID Data")
layout.separator()
OUTLINER_MT_context.draw(self, context)
class OUTLINER_MT_collection_new(Menu):
bl_label = "Collection"
@ -207,6 +216,10 @@ class OUTLINER_MT_collection_new(Menu):
layout.operator("outliner.collection_new", text="New").nested = False
layout.separator()
OUTLINER_MT_context.draw(self, context)
class OUTLINER_MT_object(Menu):
bl_label = "Object"
@ -244,6 +257,10 @@ class OUTLINER_MT_object(Menu):
layout.operator_menu_enum("outliner.id_operation", "type", text="ID Data")
layout.separator()
OUTLINER_MT_context.draw(self, context)
class OUTLINER_PT_filter(Panel):
bl_space_type = 'OUTLINER'
@ -304,6 +321,7 @@ classes = (
OUTLINER_MT_collection_new,
OUTLINER_MT_collection_view_layer,
OUTLINER_MT_object,
OUTLINER_MT_context,
OUTLINER_PT_filter,
)

View File

@ -63,6 +63,7 @@
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
#include "DEG_depsgraph.h"
@ -1783,6 +1784,26 @@ void OUTLINER_OT_data_operation(wmOperatorType *ot)
/* ******************** */
static int outliner_operator_menu(bContext *C, const char *opname)
{
wmOperatorType *ot = WM_operatortype_find(opname, false);
uiPopupMenu *pup = UI_popup_menu_begin(C, RNA_struct_ui_name(ot->srna), ICON_NONE);
uiLayout *layout = UI_popup_menu_layout(pup);
/* set this so the default execution context is the same as submenus */
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
uiItemsEnumO(layout, ot->idname, RNA_property_identifier(ot->prop));
MenuType *mt = WM_menutype_find("OUTLINER_MT_context", false);
if (mt) {
uiItemS(layout);
UI_menutype_draw(C, mt, layout);
}
UI_popup_menu_end(C, pup);
return OPERATOR_INTERFACE;
}
static int do_outliner_operation_event(bContext *C, ARegion *ar, SpaceOops *soops,
TreeElement *te, const float mval[2])
@ -1811,28 +1832,32 @@ static int do_outliner_operation_event(bContext *C, ARegion *ar, SpaceOops *soop
if (scenelevel) {
if (objectlevel || datalevel || idlevel) {
BKE_report(reports, RPT_WARNING, "Mixed selection");
return OPERATOR_CANCELLED;
}
else {
WM_operator_name_call(C, "OUTLINER_OT_scene_operation", WM_OP_INVOKE_REGION_WIN, NULL);
return outliner_operator_menu(C, "OUTLINER_OT_scene_operation");
}
}
else if (objectlevel) {
WM_menu_name_call(C, "OUTLINER_MT_object", WM_OP_INVOKE_REGION_WIN);
return OPERATOR_FINISHED;
}
else if (idlevel) {
if (idlevel == -1 || datalevel) {
BKE_report(reports, RPT_WARNING, "Mixed selection");
return OPERATOR_CANCELLED;
}
else {
switch (idlevel) {
case ID_GR:
WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
return OPERATOR_FINISHED;
break;
case ID_LI:
WM_operator_name_call(C, "OUTLINER_OT_lib_operation", WM_OP_INVOKE_REGION_WIN, NULL);
return outliner_operator_menu(C, "OUTLINER_OT_lib_operation");
break;
default:
WM_operator_name_call(C, "OUTLINER_OT_id_operation", WM_OP_INVOKE_REGION_WIN, NULL);
return outliner_operator_menu(C, "OUTLINER_OT_id_operation");
break;
}
}
@ -1840,41 +1865,49 @@ static int do_outliner_operation_event(bContext *C, ARegion *ar, SpaceOops *soop
else if (datalevel) {
if (datalevel == -1) {
BKE_report(reports, RPT_WARNING, "Mixed selection");
return OPERATOR_CANCELLED;
}
else {
if (datalevel == TSE_ANIM_DATA)
WM_operator_name_call(C, "OUTLINER_OT_animdata_operation", WM_OP_INVOKE_REGION_WIN, NULL);
if (datalevel == TSE_ANIM_DATA) {
return outliner_operator_menu(C, "OUTLINER_OT_animdata_operation");
}
else if (datalevel == TSE_DRIVER_BASE) {
/* do nothing... no special ops needed yet */
return OPERATOR_CANCELLED;
}
else if (datalevel == TSE_LAYER_COLLECTION) {
WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
return OPERATOR_FINISHED;
}
else if (ELEM(datalevel, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
return OPERATOR_FINISHED;
}
else if (datalevel == TSE_ID_BASE) {
/* do nothing... there are no ops needed here yet */
}
else if (datalevel == TSE_CONSTRAINT) {
WM_operator_name_call(C, "OUTLINER_OT_constraint_operation", WM_OP_INVOKE_REGION_WIN, NULL);
return outliner_operator_menu(C, "OUTLINER_OT_constraint_operation");
}
else if (datalevel == TSE_MODIFIER) {
WM_operator_name_call(C, "OUTLINER_OT_modifier_operation", WM_OP_INVOKE_REGION_WIN, NULL);
return outliner_operator_menu(C, "OUTLINER_OT_modifier_operation");
}
else {
WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL);
return outliner_operator_menu(C, "OUTLINER_OT_data_operation");
}
}
}
return 1;
return OPERATOR_CANCELLED;
}
for (te = te->subtree.first; te; te = te->next) {
if (do_outliner_operation_event(C, ar, soops, te, mval))
return 1;
int retval = do_outliner_operation_event(C, ar, soops, te, mval);
if (retval) {
return retval;
}
}
return 0;
}
@ -1886,7 +1919,6 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent
uiBut *but = UI_context_active_but_get(C);
TreeElement *te;
float fmval[2];
bool found = false;
if (but) {
UI_but_tooltip_timer_remove(C, but);
@ -1895,19 +1927,19 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
for (te = soops->tree.first; te; te = te->next) {
if (do_outliner_operation_event(C, ar, soops, te, fmval)) {
found = true;
break;
int retval = do_outliner_operation_event(C, ar, soops, te, fmval);
if (retval) {
return retval;
}
}
if (!found) {
/* Menus for clicking in empty space. */
if (soops->outlinevis == SO_VIEW_LAYER) {
WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
}
/* Menus for clicking in empty space. */
if (soops->outlinevis == SO_VIEW_LAYER) {
WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
return OPERATOR_FINISHED;
}
WM_menu_name_call(C, "OUTLINER_MT_context", WM_OP_INVOKE_REGION_WIN);
return OPERATOR_FINISHED;
}