diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_topbar.py | 16 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 8 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_context_menu.c | 9 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 12 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 37 | ||||
-rw-r--r-- | source/blender/editors/screen/workspace_edit.c | 40 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ui_api.c | 2 |
9 files changed, 75 insertions, 54 deletions
diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 881d3db8a4c..8bf8e40d74e 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -47,8 +47,8 @@ class TOPBAR_HT_upper_bar(Header): if not screen.show_fullscreen: layout.template_ID_tabs( window, "workspace", - new="workspace.workspace_add_menu", - unlink="workspace.workspace_delete", + new="workspace.add_menu", + menu="TOPBAR_MT_workspace_menu", ) else: layout.operator( @@ -622,11 +622,23 @@ class TOPBAR_MT_window_specials(Menu): layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES') +class TOPBAR_MT_workspace_menu(Menu): + bl_label = "Workspace" + + def draw(self, context): + layout = self.layout + + layout.operator("workspace.duplicate", text="Duplicate") + if len(bpy.data.workspaces) > 1: + layout.operator("workspace.delete", text="Delete") + + classes = ( TOPBAR_HT_upper_bar, TOPBAR_HT_lower_bar, TOPBAR_MT_file_specials, TOPBAR_MT_window_specials, + TOPBAR_MT_workspace_menu, INFO_MT_editor_menus, INFO_MT_file, INFO_MT_file_import, diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 5cc3e369439..c88470bd323 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1033,7 +1033,7 @@ void uiTemplateIDPreview( void uiTemplateIDTabs( uiLayout *layout, struct bContext *C, PointerRNA *ptr, const char *propname, - const char *newop, const char *openop, const char *unlinkop, + const char *newop, const char *openop, const char *menu, int filter); void uiTemplateAnyID( uiLayout *layout, struct PointerRNA *ptr, const char *propname, @@ -1221,6 +1221,7 @@ void UI_context_active_but_prop_get_filebrowser( void UI_context_active_but_prop_get_templateID( struct bContext *C, struct PointerRNA *r_ptr, struct PropertyRNA **r_prop); +struct ID *UI_context_active_but_get_tab_ID(struct bContext *C); uiBut *UI_region_active_but_get(struct ARegion *ar); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 37c56d454bb..edb0928c57e 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2075,7 +2075,7 @@ static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but) static bool ui_but_icon_extra_is_visible_search_unlink(const uiBut *but) { - BLI_assert(ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_TAB)); + BLI_assert(ELEM(but->type, UI_BTYPE_SEARCH_MENU)); return ((but->editstr == NULL) && (but->drawstr[0] != '\0') && (but->flag & UI_BUT_VALUE_CLEAR)); @@ -2118,11 +2118,6 @@ uiButExtraIconType ui_but_icon_extra_get(uiBut *but) return UI_BUT_ICONEXTRA_EYEDROPPER; } break; - case UI_BTYPE_TAB: - if (ui_but_icon_extra_is_visible_search_unlink(but)) { - return UI_BUT_ICONEXTRA_CLEAR; - } - break; default: break; } @@ -3095,7 +3090,6 @@ void ui_but_update_ex(uiBut *but, const bool validate) case UI_BTYPE_TEXT: case UI_BTYPE_SEARCH_MENU: - case UI_BTYPE_TAB: if (!but->editstr) { char str[UI_MAX_DRAW_STR]; diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index 8d4f8594a90..281c2fb7104 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -361,7 +361,14 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); } - if (but->rnapoin.data && but->rnaprop) { + if (but->type == UI_BTYPE_TAB) { + uiButTab *tab = (uiButTab *)but; + if (tab->menu) { + UI_menutype_draw(C, tab->menu, layout); + uiItemS(layout); + } + } + else if (but->rnapoin.data && but->rnaprop) { PointerRNA *ptr = &but->rnapoin; PropertyRNA *prop = but->rnaprop; const PropertyType type = RNA_property_type(prop); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 0ba9261c4bd..4b68be8fa3b 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3763,17 +3763,6 @@ static int ui_do_but_TAB(bContext *C, uiBlock *block, uiBut *but, uiHandleButton return WM_UI_HANDLER_BREAK; } else if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && (event->val == KM_CLICK)) { - const bool has_icon_extra = ui_but_icon_extra_get(but) == UI_BUT_ICONEXTRA_CLEAR; - - if (has_icon_extra && ui_but_is_mouse_over_icon_extra(data->region, but, &event->x)) { - uiButTab *tab = (uiButTab *)but; - wmOperatorType *ot_backup = but->optype; - - but->optype = tab->unlink_ot; - /* Force calling unlink/delete operator. */ - ui_apply_but(C, block, but, data, true); - but->optype = ot_backup; - } button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; } @@ -8910,7 +8899,6 @@ static int ui_handle_menu_event( else { /* check mouse moving outside of the menu */ - //printf("inside %d mm quit %d\n", inside, block->flag & (UI_BLOCK_MOVEMOUSE_QUIT); if (inside == 0 && (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER))) { uiSafetyRct *saferct; diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index f7507223f31..863e4b3762a 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -322,7 +322,7 @@ struct uiBut { typedef struct uiButTab { uiBut but; - struct wmOperatorType *unlink_ot; + struct MenuType *menu; } uiButTab; typedef struct ColorPicker { diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 820b34c1ac4..9c4e7faa73e 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -822,38 +822,45 @@ static void template_ID( UI_block_align_end(block); } + +ID *UI_context_active_but_get_tab_ID(bContext *C) +{ + uiBut *but = UI_context_active_but_get(C); + + if (but && but->type == UI_BTYPE_TAB) { + return but->custom_data; + } + else { + return NULL; + } +} + static void template_ID_tabs( bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, int flag, - const char *newop, const char *UNUSED(openop), const char *unlinkop) + const char *newop, const char *UNUSED(openop), const char *menu) { const ARegion *region = CTX_wm_region(C); const PointerRNA active_ptr = RNA_property_pointer_get(&template->ptr, template->prop); + MenuType *mt = WM_menutype_find(menu, false); + const int but_align = (region->alignment == RGN_ALIGN_TOP) ? UI_BUT_ALIGN_DOWN : UI_BUT_ALIGN_TOP; const int but_height = UI_UNIT_Y * 1.1; uiBlock *block = uiLayoutGetBlock(layout); uiStyle *style = UI_style_get_dpi(); - for (ID *id = template->idlb->first; id; id = id->next) { - wmOperatorType *unlink_ot = WM_operatortype_find(unlinkop, false); - const bool is_active = active_ptr.data == id; - const unsigned int but_width = ( - UI_fontstyle_string_width(&style->widgetlabel, id->name + 2) + UI_UNIT_X + - (is_active ? ICON_DEFAULT_WIDTH_SCALE : 0)); - uiButTab *tab; - - tab = (uiButTab *)uiDefButR_prop( - block, UI_BTYPE_TAB, 0, "", 0, 0, but_width, UI_UNIT_Y * 1.1, + const int name_width = UI_fontstyle_string_width(&style->widgetlabel, id->name + 2); + const int but_width = name_width + UI_UNIT_X; + + uiButTab *tab = (uiButTab *)uiDefButR_prop( + block, UI_BTYPE_TAB, 0, id->name + 2, 0, 0, but_width, but_height, &template->ptr, template->prop, 0, 0.0f, sizeof(id->name) - 2, 0.0f, 0.0f, ""); UI_but_funcN_set(&tab->but, template_ID_set_property_cb, MEM_dupallocN(template), id); tab->but.custom_data = (void *)id; - tab->unlink_ot = unlink_ot; + tab->menu = mt; - if (is_active) { - UI_but_flag_enable(&tab->but, UI_BUT_VALUE_CLEAR); - } UI_but_drawflag_enable(&tab->but, but_align); } diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index 4f8389d9f7d..246d2fed1a1 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -256,23 +256,36 @@ void ED_workspace_scene_data_sync( * * \{ */ +static WorkSpace *workspace_context_get(bContext *C) +{ + ID *id = UI_context_active_but_get_tab_ID(C); + if (id && GS(id->name) == ID_WS) { + return (WorkSpace *)id; + } + + wmWindow *win = CTX_wm_window(C); + return WM_window_get_active_workspace(win); +} + static int workspace_new_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); wmWindow *win = CTX_wm_window(C); - WorkSpace *workspace = ED_workspace_duplicate(WM_window_get_active_workspace(win), bmain, win); + WorkSpace *workspace = workspace_context_get(C); + + workspace = ED_workspace_duplicate(workspace, bmain, win); WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace); return OPERATOR_FINISHED; } -static void WORKSPACE_OT_workspace_duplicate(wmOperatorType *ot) +static void WORKSPACE_OT_duplicate(wmOperatorType *ot) { /* identifiers */ ot->name = "New Workspace"; ot->description = "Add a new workspace"; - ot->idname = "WORKSPACE_OT_workspace_duplicate"; + ot->idname = "WORKSPACE_OT_duplicate"; /* api callbacks */ ot->exec = workspace_new_exec; @@ -281,19 +294,18 @@ static void WORKSPACE_OT_workspace_duplicate(wmOperatorType *ot) static int workspace_delete_exec(bContext *C, wmOperator *UNUSED(op)) { - wmWindow *win = CTX_wm_window(C); - - WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_DELETE, WM_window_get_active_workspace(win)); + WorkSpace *workspace = workspace_context_get(C); + WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_DELETE, workspace); return OPERATOR_FINISHED; } -static void WORKSPACE_OT_workspace_delete(wmOperatorType *ot) +static void WORKSPACE_OT_delete(wmOperatorType *ot) { /* identifiers */ ot->name = "Delete Workspace"; ot->description = "Delete the active workspace"; - ot->idname = "WORKSPACE_OT_workspace_delete"; + ot->idname = "WORKSPACE_OT_delete"; /* api callbacks */ ot->exec = workspace_delete_exec; @@ -482,7 +494,7 @@ static int workspace_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS uiPopupMenu *pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE); uiLayout *layout = UI_popup_menu_layout(pup); - uiItemO(layout, "Duplicate Current", ICON_NONE, "WORKSPACE_OT_workspace_duplicate"); + uiItemO(layout, "Duplicate Current", ICON_NONE, "WORKSPACE_OT_duplicate"); workspace_config_file_append_buttons(layout, bmain, op->reports); UI_popup_menu_end(C, pup); @@ -490,13 +502,13 @@ static int workspace_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS return OPERATOR_INTERFACE; } -static void WORKSPACE_OT_workspace_add_menu(wmOperatorType *ot) +static void WORKSPACE_OT_add_menu(wmOperatorType *ot) { /* identifiers */ ot->name = "Add Workspace"; ot->description = "Add a new workspace by duplicating the current one or appending one " "from the user configuration"; - ot->idname = "WORKSPACE_OT_workspace_add_menu"; + ot->idname = "WORKSPACE_OT_add_menu"; /* api callbacks */ ot->invoke = workspace_add_invoke; @@ -504,9 +516,9 @@ static void WORKSPACE_OT_workspace_add_menu(wmOperatorType *ot) void ED_operatortypes_workspace(void) { - WM_operatortype_append(WORKSPACE_OT_workspace_duplicate); - WM_operatortype_append(WORKSPACE_OT_workspace_delete); - WM_operatortype_append(WORKSPACE_OT_workspace_add_menu); + WM_operatortype_append(WORKSPACE_OT_duplicate); + WM_operatortype_append(WORKSPACE_OT_delete); + WM_operatortype_append(WORKSPACE_OT_add_menu); WM_operatortype_append(WORKSPACE_OT_append_activate); } diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 6abd0002e3e..f4c4d8a7a44 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -787,7 +787,7 @@ void RNA_api_ui_layout(StructRNA *srna) api_ui_item_rna_common(func); RNA_def_string(func, "new", NULL, 0, "", "Operator identifier to create a new ID block"); RNA_def_string(func, "open", NULL, 0, "", "Operator identifier to open a file for creating a new ID block"); - RNA_def_string(func, "unlink", NULL, 0, "", "Operator identifier to unlink the ID block"); + RNA_def_string(func, "menu", NULL, 0, "", "Context menu identifier"); RNA_def_enum(func, "filter", id_template_filter_items, UI_TEMPLATE_ID_FILTER_ALL, "", "Optionally limit the items which can be selected"); |