diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2018-04-20 18:14:03 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2018-04-20 18:14:52 +0300 |
commit | 5f6c45498c92b91a710a1317f6d41f73fbe83477 (patch) | |
tree | 93b136fb49c656c2c2a5463c91e8a6a38d518354 /source/blender/editors/space_topbar/space_topbar.c | |
parent | 4bfb6d21df96688187f6f1a5d95dd62bcbf85116 (diff) |
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
Diffstat (limited to 'source/blender/editors/space_topbar/space_topbar.c')
-rw-r--r-- | source/blender/editors/space_topbar/space_topbar.c | 265 |
1 files changed, 265 insertions, 0 deletions
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 <string.h> +#include <stdio.h> + +#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); +} |