This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/editors/space_topbar/space_topbar.c

286 lines
8.0 KiB
C

/*
* 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.
*/
/** \file
* \ingroup sptopbar
*/
#include <stdio.h>
#include <string.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 "ED_undo.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
#include "RNA_access.h"
#include "WM_api.h"
#include "WM_message.h"
#include "WM_types.h"
/* ******************** default callbacks for topbar space ***************** */
static SpaceLink *topbar_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceTopBar *stopbar;
stopbar = MEM_callocN(sizeof(*stopbar), "init topbar");
stopbar->spacetype = SPACE_TOPBAR;
/* header */
region = MEM_callocN(sizeof(ARegion), "left aligned header for topbar");
BLI_addtail(&stopbar->regionbase, region);
region->regiontype = RGN_TYPE_HEADER;
region->alignment = RGN_ALIGN_TOP;
region = MEM_callocN(sizeof(ARegion), "right aligned header for topbar");
BLI_addtail(&stopbar->regionbase, region);
region->regiontype = RGN_TYPE_HEADER;
region->alignment = RGN_ALIGN_RIGHT | RGN_SPLIT_PREV;
/* main regions */
region = MEM_callocN(sizeof(ARegion), "main region of topbar");
BLI_addtail(&stopbar->regionbase, region);
region->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(area))
{
}
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(RGN_ALIGN_ENUM_FROM_MASK(region->alignment), RGN_ALIGN_RIGHT)) {
region->flag |= RGN_FLAG_DYNAMIC_SIZE;
}
UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_HEADER, region->winx, region->winy);
keymap = WM_keymap_ensure(wm->defaultconf, "View2D Buttons List", 0, 0);
WM_event_add_keymap_handler(&region->handlers, keymap);
}
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 *region)
{
if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_RIGHT) {
region->flag |= RGN_FLAG_DYNAMIC_SIZE;
}
ED_region_header_init(region);
}
static void topbar_main_region_listener(const wmRegionListenerParams *params)
{
ARegion *region = params->region;
wmNotifier *wmn = params->notifier;
/* context changes */
switch (wmn->category) {
case NC_WM:
if (wmn->data == ND_HISTORY) {
ED_region_tag_redraw(region);
}
break;
case NC_SCENE:
if (wmn->data == ND_MODE) {
ED_region_tag_redraw(region);
}
break;
case NC_SPACE:
if (wmn->data == ND_SPACE_VIEW3D) {
ED_region_tag_redraw(region);
}
break;
case NC_GPENCIL:
if (wmn->data == ND_DATA) {
ED_region_tag_redraw(region);
}
break;
}
}
static void topbar_header_listener(const wmRegionListenerParams *params)
{
ARegion *region = params->region;
wmNotifier *wmn = params->notifier;
/* context changes */
switch (wmn->category) {
case NC_WM:
if (wmn->data == ND_JOB) {
ED_region_tag_redraw(region);
}
break;
case NC_SPACE:
if (wmn->data == ND_SPACE_INFO) {
ED_region_tag_redraw(region);
}
break;
case NC_SCREEN:
if (wmn->data == ND_LAYER) {
ED_region_tag_redraw(region);
}
break;
case NC_SCENE:
if (wmn->data == ND_SCENEBROWSE) {
ED_region_tag_redraw(region);
}
break;
}
}
static void topbar_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
struct wmMsgBus *mbus = params->message_bus;
WorkSpace *workspace = params->workspace;
ARegion *region = params->region;
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
.notify = ED_region_do_msg_notify_tag_redraw,
};
WM_msg_subscribe_rna_prop(
mbus, &workspace->id, workspace, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
}
static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu)
{
struct RecentFile *recent;
uiLayout *layout = menu->layout;
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
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;
PointerRNA ptr;
uiItemFullO(layout, "WM_OT_open_mainfile", file, icon, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr);
RNA_string_set(&ptr, "filepath", recent->filepath);
RNA_boolean_set(&ptr, "display_file_selector", false);
}
}
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->create = topbar_create;
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->layout = ED_region_header_layout;
art->draw = ED_region_header_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->message_subscribe = topbar_header_region_message_subscribe;
art->init = topbar_header_region_init;
art->layout = ED_region_header_layout;
art->draw = ED_region_header_draw;
BLI_addhead(&st->regiontypes, art);
recent_files_menu_register();
BKE_spacetype_register(st);
}