From 5f6c45498c92b91a710a1317f6d41f73fbe83477 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 20 Apr 2018 17:14:03 +0200 Subject: UI: New Global Top-Bar (WIP) == Main Features/Changes for Users * Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars. * Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector. * Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here. * Individual sections of the topbar are individually scrollable. * Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting. * Top-bar should scale nicely with DPI. * The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes). * Info editors at the top of the window and using the full window width with be replaced by the top-bar. * In fullscreen modes, no more info editor is added on top, the top-bar replaces it. == Technical Features/Changes * Adds initial support for global areas A global area is part of the window, not part of the regular screen-layout. I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas. * Adds a TOPBAR editor type The editor type is hidden in the UI editor type menu. * Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY) * Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar. * Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds. The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved. * Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code. Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being. NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility. == ToDo's It's a bit hard to predict all the ToDo's here are the known main ones: * Add options for the new active-tool system and for operator redo to the topbar. * Automatically hide the top-bar in fullscreen modes. * General visual polish. * Top-bar drag & drop support (WIP in temp-tab_drag_drop). * Improve dynamic regions (should also fix some layout glitches). * Make internal terminology consistent. * Enable topbar file writing once design is more advanced. * Address TODO's and XXX's in code :) Thanks @brecht for the review! And @sergey for the complaining ;) Differential Revision: D2758 --- source/blender/editors/space_topbar/CMakeLists.txt | 45 ++++ source/blender/editors/space_topbar/space_topbar.c | 265 +++++++++++++++++++++ 2 files changed, 310 insertions(+) create mode 100644 source/blender/editors/space_topbar/CMakeLists.txt create mode 100644 source/blender/editors/space_topbar/space_topbar.c (limited to 'source/blender/editors/space_topbar') diff --git a/source/blender/editors/space_topbar/CMakeLists.txt b/source/blender/editors/space_topbar/CMakeLists.txt new file mode 100644 index 00000000000..9559c28de0a --- /dev/null +++ b/source/blender/editors/space_topbar/CMakeLists.txt @@ -0,0 +1,45 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributor(s): Jacques Beaurain. +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + ../include + ../../blenkernel + ../../blenlib + ../../blenloader + ../../blentranslation + ../../gpu + ../../makesdna + ../../makesrna + ../../windowmanager + ../../../../intern/guardedalloc + ../../../../intern/glew-mx +) + +set(INC_SYS + ${GLEW_INCLUDE_PATH} +) + +set(SRC + space_topbar.c +) + +add_definitions(${GL_DEFINITIONS}) + +blender_add_lib(bf_editor_space_topbar "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c new file mode 100644 index 00000000000..35858a927fe --- /dev/null +++ b/source/blender/editors/space_topbar/space_topbar.c @@ -0,0 +1,265 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2017 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_topbar/space_topbar.c + * \ingroup sptopbar + */ + + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "BLO_readfile.h" +#include "BLT_translation.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_screen.h" + +#include "ED_screen.h" +#include "ED_space_api.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "WM_api.h" +#include "WM_types.h" + + +/* ******************** default callbacks for topbar space ***************** */ + +static SpaceLink *topbar_new(const bContext *UNUSED(C)) +{ + ARegion *ar; + SpaceTopBar *stopbar; + + stopbar = MEM_callocN(sizeof(*stopbar), "init topbar"); + stopbar->spacetype = SPACE_TOPBAR; + + /* header */ + ar = MEM_callocN(sizeof(ARegion), "left aligned header for topbar"); + BLI_addtail(&stopbar->regionbase, ar); + ar->regiontype = RGN_TYPE_HEADER; + ar->alignment = RGN_ALIGN_TOP; + ar = MEM_callocN(sizeof(ARegion), "right aligned header for topbar"); + BLI_addtail(&stopbar->regionbase, ar); + ar->regiontype = RGN_TYPE_HEADER; + ar->alignment = RGN_ALIGN_RIGHT | RGN_SPLIT_PREV; + + /* main regions */ + ar = MEM_callocN(sizeof(ARegion), "left aligned main region for topbar"); + BLI_addtail(&stopbar->regionbase, ar); + ar->regiontype = RGN_TYPE_WINDOW; + ar->alignment = RGN_ALIGN_LEFT; + ar = MEM_callocN(sizeof(ARegion), "right aligned main region for topbar"); + BLI_addtail(&stopbar->regionbase, ar); + ar->regiontype = RGN_TYPE_WINDOW; + ar->alignment = RGN_ALIGN_RIGHT; + ar = MEM_callocN(sizeof(ARegion), "center main region for topbar"); + BLI_addtail(&stopbar->regionbase, ar); + ar->regiontype = RGN_TYPE_WINDOW; + + return (SpaceLink *)stopbar; +} + +/* not spacelink itself */ +static void topbar_free(SpaceLink *UNUSED(sl)) +{ + +} + + +/* spacetype; init callback */ +static void topbar_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) +{ + +} + +static SpaceLink *topbar_duplicate(SpaceLink *sl) +{ + SpaceTopBar *stopbarn = MEM_dupallocN(sl); + + /* clear or remove stuff from old */ + + return (SpaceLink *)stopbarn; +} + + + +/* add handlers, stuff you only do once or on area/region changes */ +static void topbar_main_region_init(wmWindowManager *wm, ARegion *region) +{ + wmKeyMap *keymap; + + /* force delayed UI_view2d_region_reinit call */ + if (ELEM(region->alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { + region->flag |= RGN_FLAG_DYNAMIC_SIZE; + } + UI_view2d_region_reinit(®ion->v2d, V2D_COMMONVIEW_HEADER, region->winx, region->winy); + + keymap = WM_keymap_find(wm->defaultconf, "View2D Buttons List", 0, 0); + WM_event_add_keymap_handler(®ion->handlers, keymap); +} + +static void topbar_main_region_draw(const bContext *C, ARegion *region) +{ + ED_region_header(C, region); +} + +static void topbar_operatortypes(void) +{ + +} + +static void topbar_keymap(struct wmKeyConfig *UNUSED(keyconf)) +{ + +} + +/* add handlers, stuff you only do once or on area/region changes */ +static void topbar_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar) +{ + if ((ar->alignment & ~RGN_SPLIT_PREV) == RGN_ALIGN_RIGHT) { + ar->flag |= RGN_FLAG_DYNAMIC_SIZE; + } + ED_region_header_init(ar); +} + +static void topbar_header_region_draw(const bContext *C, ARegion *ar) +{ + ED_region_header(C, ar); +} + +static void topbar_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, + wmNotifier *wmn, const Scene *UNUSED(scene)) +{ + /* context changes */ + switch (wmn->category) { + case NC_WM: + if (wmn->data == ND_HISTORY) + ED_region_tag_redraw(ar); + break; + case NC_SCENE: + if (wmn->data == ND_MODE) + ED_region_tag_redraw(ar); + break; + case NC_SPACE: + if (wmn->data == ND_SPACE_VIEW3D) + ED_region_tag_redraw(ar); + break; + } +} + +static void topbar_header_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), + wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene)) +{ + /* context changes */ +#if 0 + switch (wmn->category) { + default: + break; + } +#endif +} + +static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu) +{ + struct RecentFile *recent; + uiLayout *layout = menu->layout; + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN); + if (!BLI_listbase_is_empty(&G.recent_files)) { + for (recent = G.recent_files.first; (recent); recent = recent->next) { + const char *file = BLI_path_basename(recent->filepath); + const int icon = BLO_has_bfile_extension(file) ? ICON_FILE_BLEND : ICON_FILE_BACKUP; + uiItemStringO(layout, file, icon, "WM_OT_open_mainfile", "filepath", recent->filepath); + } + } + else { + uiItemL(layout, IFACE_("No Recent Files"), ICON_NONE); + } +} + +static void recent_files_menu_register(void) +{ + MenuType *mt; + + mt = MEM_callocN(sizeof(MenuType), "spacetype info menu recent files"); + strcpy(mt->idname, "TOPBAR_MT_file_open_recent"); + strcpy(mt->label, N_("Open Recent...")); + strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); + mt->draw = recent_files_menu_draw; + WM_menutype_add(mt); +} + + +/* only called once, from space/spacetypes.c */ +void ED_spacetype_topbar(void) +{ + SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype topbar"); + ARegionType *art; + + st->spaceid = SPACE_TOPBAR; + strncpy(st->name, "Top Bar", BKE_ST_MAXNAME); + + st->new = topbar_new; + st->free = topbar_free; + st->init = topbar_init; + st->duplicate = topbar_duplicate; + st->operatortypes = topbar_operatortypes; + st->keymap = topbar_keymap; + + /* regions: main window */ + art = MEM_callocN(sizeof(ARegionType), "spacetype topbar main region"); + art->regionid = RGN_TYPE_WINDOW; + art->init = topbar_main_region_init; + art->draw = topbar_main_region_draw; + art->listener = topbar_main_region_listener; + art->prefsizex = UI_UNIT_X * 5; /* Mainly to avoid glitches */ + art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER; + + BLI_addhead(&st->regiontypes, art); + + /* regions: header */ + art = MEM_callocN(sizeof(ARegionType), "spacetype topbar header region"); + art->regionid = RGN_TYPE_HEADER; + art->prefsizey = HEADERY; + art->prefsizex = UI_UNIT_X * 5; /* Mainly to avoid glitches */ + art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER; + art->listener = topbar_header_listener; + art->init = topbar_header_region_init; + art->draw = topbar_header_region_draw; + + BLI_addhead(&st->regiontypes, art); + + recent_files_menu_register(); + + BKE_spacetype_register(st); +} -- cgit v1.2.3