Blender V4.3
space_topbar.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2017 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstdio>
10#include <cstring>
11
12#include "MEM_guardedalloc.h"
13
14#include "BLI_blenlib.h"
15#include "BLI_utildefines.h"
16
17#include "BLT_translation.hh"
18
19#include "BKE_context.hh"
20#include "BKE_screen.hh"
21#include "BKE_undo_system.hh"
22
23#include "ED_screen.hh"
24#include "ED_space_api.hh"
25
26#include "UI_interface.hh"
27#include "UI_resources.hh"
28#include "UI_view2d.hh"
29
30#include "BLO_read_write.hh"
31
32#include "RNA_access.hh"
33
34#include "WM_api.hh"
35#include "WM_message.hh"
36#include "WM_types.hh"
37
38/* ******************** default callbacks for topbar space ***************** */
39
40static SpaceLink *topbar_create(const ScrArea * /*area*/, const Scene * /*scene*/)
41{
42 ARegion *region;
43 SpaceTopBar *stopbar;
44
45 stopbar = static_cast<SpaceTopBar *>(MEM_callocN(sizeof(*stopbar), "init topbar"));
46 stopbar->spacetype = SPACE_TOPBAR;
47
48 /* header */
49 region = static_cast<ARegion *>(MEM_callocN(sizeof(ARegion), "left aligned header for topbar"));
50 BLI_addtail(&stopbar->regionbase, region);
51 region->regiontype = RGN_TYPE_HEADER;
52 region->alignment = RGN_ALIGN_TOP;
53 region = static_cast<ARegion *>(MEM_callocN(sizeof(ARegion), "right aligned header for topbar"));
54 BLI_addtail(&stopbar->regionbase, region);
55 region->regiontype = RGN_TYPE_HEADER;
56 region->alignment = RGN_ALIGN_RIGHT | RGN_SPLIT_PREV;
57
58 /* main regions */
59 region = static_cast<ARegion *>(MEM_callocN(sizeof(ARegion), "main region of topbar"));
60 BLI_addtail(&stopbar->regionbase, region);
61 region->regiontype = RGN_TYPE_WINDOW;
62
63 return (SpaceLink *)stopbar;
64}
65
66/* Doesn't free the space-link itself. */
67static void topbar_free(SpaceLink * /*sl*/) {}
68
69/* spacetype; init callback */
70static void topbar_init(wmWindowManager * /*wm*/, ScrArea * /*area*/) {}
71
73{
74 SpaceTopBar *stopbarn = static_cast<SpaceTopBar *>(MEM_dupallocN(sl));
75
76 /* clear or remove stuff from old */
77
78 return (SpaceLink *)stopbarn;
79}
80
81/* add handlers, stuff you only do once or on area/region changes */
83{
84 wmKeyMap *keymap;
85
86 /* force delayed UI_view2d_region_reinit call */
87 if (ELEM(RGN_ALIGN_ENUM_FROM_MASK(region->alignment), RGN_ALIGN_RIGHT)) {
88 region->flag |= RGN_FLAG_DYNAMIC_SIZE;
89 }
90 UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_HEADER, region->winx, region->winy);
91
92 keymap = WM_keymap_ensure(wm->defaultconf, "View2D Buttons List", SPACE_EMPTY, RGN_TYPE_WINDOW);
93 WM_event_add_keymap_handler(&region->handlers, keymap);
94}
95
96static void topbar_operatortypes() {}
97
98static void topbar_keymap(wmKeyConfig * /*keyconf*/) {}
99
100/* add handlers, stuff you only do once or on area/region changes */
102{
103 if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_RIGHT) {
104 region->flag |= RGN_FLAG_DYNAMIC_SIZE;
105 }
106 ED_region_header_init(region);
107}
108
110{
111 ARegion *region = params->region;
112 const wmNotifier *wmn = params->notifier;
113
114 /* context changes */
115 switch (wmn->category) {
116 case NC_WM:
117 if (wmn->data == ND_HISTORY) {
118 ED_region_tag_redraw(region);
119 }
120 break;
121 case NC_SCENE:
122 if (wmn->data == ND_MODE) {
123 ED_region_tag_redraw(region);
124 }
125 break;
126 case NC_SPACE:
127 if (wmn->data == ND_SPACE_VIEW3D) {
128 ED_region_tag_redraw(region);
129 }
130 break;
131 case NC_GPENCIL:
132 if (wmn->data == ND_DATA) {
133 ED_region_tag_redraw(region);
134 }
135 break;
136 }
137}
138
140{
141 ARegion *region = params->region;
142 const wmNotifier *wmn = params->notifier;
143
144 /* context changes */
145 switch (wmn->category) {
146 case NC_WM:
147 if (wmn->data == ND_JOB) {
148 ED_region_tag_redraw(region);
149 }
150 break;
151 case NC_WORKSPACE:
152 ED_region_tag_redraw(region);
153 break;
154 case NC_SPACE:
155 if (wmn->data == ND_SPACE_INFO) {
156 ED_region_tag_redraw(region);
157 }
158 break;
159 case NC_SCREEN:
160 if (wmn->data == ND_LAYER) {
161 ED_region_tag_redraw(region);
162 }
163 break;
164 case NC_SCENE:
165 if (wmn->data == ND_SCENEBROWSE) {
166 ED_region_tag_redraw(region);
167 }
168 break;
169 }
170}
171
173{
174 wmMsgBus *mbus = params->message_bus;
175 WorkSpace *workspace = params->workspace;
176 ARegion *region = params->region;
177
178 wmMsgSubscribeValue msg_sub_value_region_tag_redraw{};
179 msg_sub_value_region_tag_redraw.owner = region;
180 msg_sub_value_region_tag_redraw.user_data = region;
181 msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;
182
184 mbus, &workspace->id, workspace, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
185}
186
187static void recent_files_menu_draw(const bContext * /*C*/, Menu *menu)
188{
189 uiLayout *layout = menu->layout;
191 if (uiTemplateRecentFiles(layout, U.recent_files) != 0) {
192 uiItemS(layout);
193 uiItemO(layout, IFACE_("Clear Recent Files List..."), ICON_TRASH, "WM_OT_clear_recent_files");
194 }
195 else {
196 uiItemL(layout, IFACE_("No Recent Files"), ICON_NONE);
197 }
198}
199
201{
202 MenuType *mt;
203
204 mt = static_cast<MenuType *>(MEM_callocN(sizeof(MenuType), "spacetype info menu recent files"));
205 STRNCPY(mt->idname, "TOPBAR_MT_file_open_recent");
206 STRNCPY(mt->label, N_("Open Recent"));
209 WM_menutype_add(mt);
210}
211
212static void undo_history_draw_menu(const bContext *C, Menu *menu)
213{
215 if (wm->undo_stack == nullptr) {
216 return;
217 }
218
219 int undo_step_count = 0;
220 int undo_step_count_all = 0;
222 undo_step_count_all += 1;
223 if (us->skip) {
224 continue;
225 }
226 undo_step_count += 1;
227 }
228
229 uiLayout *split = uiLayoutSplit(menu->layout, 0.0f, false);
230 uiLayout *column = nullptr;
231
232 const int col_size = 20 + (undo_step_count / 12);
233
234 undo_step_count = 0;
235
236 /* Reverse the order so the most recent state is first in the menu. */
237 int i = undo_step_count_all - 1;
238 for (UndoStep *us = static_cast<UndoStep *>(wm->undo_stack->steps.last); us; us = us->prev, i--)
239 {
240 if (us->skip) {
241 continue;
242 }
243 if (!(undo_step_count % col_size)) {
244 column = uiLayoutColumn(split, false);
245 }
246 const bool is_active = (us == wm->undo_stack->step_active);
247 uiLayout *row = uiLayoutRow(column, false);
248 uiLayoutSetEnabled(row, !is_active);
249 uiItemIntO(row,
251 is_active ? ICON_LAYER_ACTIVE : ICON_NONE,
252 "ED_OT_undo_history",
253 "item",
254 i);
255 undo_step_count += 1;
256 }
257}
258
260{
261 MenuType *mt;
262
263 mt = static_cast<MenuType *>(MEM_callocN(sizeof(MenuType), __func__));
264 STRNCPY(mt->idname, "TOPBAR_MT_undo_history");
265 STRNCPY(mt->label, N_("Undo History"));
268 WM_menutype_add(mt);
269}
270
272{
273 BLO_write_struct(writer, SpaceTopBar, sl);
274}
275
277{
278 std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
279 ARegionType *art;
280
281 st->spaceid = SPACE_TOPBAR;
282 STRNCPY(st->name, "Top Bar");
283
284 st->create = topbar_create;
285 st->free = topbar_free;
286 st->init = topbar_init;
287 st->duplicate = topbar_duplicate;
288 st->operatortypes = topbar_operatortypes;
289 st->keymap = topbar_keymap;
290 st->blend_write = topbar_space_blend_write;
291
292 /* regions: main window */
293 art = static_cast<ARegionType *>(
294 MEM_callocN(sizeof(ARegionType), "spacetype topbar main region"));
300 art->prefsizex = UI_UNIT_X * 5; /* Mainly to avoid glitches */
302
303 BLI_addhead(&st->regiontypes, art);
304
305 /* regions: header */
306 art = static_cast<ARegionType *>(
307 MEM_callocN(sizeof(ARegionType), "spacetype topbar header region"));
309 art->prefsizey = HEADERY;
310 art->prefsizex = UI_UNIT_X * 5; /* Mainly to avoid glitches */
317
318 BLI_addhead(&st->regiontypes, art);
319
322
323 BKE_spacetype_register(std::move(st));
324}
wmWindowManager * CTX_wm_manager(const bContext *C)
void BKE_spacetype_register(std::unique_ptr< SpaceType > st)
Definition screen.cc:268
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:90
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define ELEM(...)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
#define HEADERY
#define RGN_ALIGN_ENUM_FROM_MASK(align)
@ RGN_ALIGN_TOP
@ RGN_ALIGN_RIGHT
@ RGN_SPLIT_PREV
@ RGN_TYPE_WINDOW
@ RGN_TYPE_HEADER
@ RGN_FLAG_DYNAMIC_SIZE
@ SPACE_TOPBAR
@ SPACE_EMPTY
void ED_region_header_init(ARegion *region)
Definition area.cc:3661
void ED_region_header_draw(const bContext *C, ARegion *region)
Definition area.cc:3621
void ED_region_tag_redraw(ARegion *region)
Definition area.cc:634
@ ED_KEYMAP_UI
Definition ED_screen.hh:725
@ ED_KEYMAP_HEADER
Definition ED_screen.hh:731
@ ED_KEYMAP_VIEW2D
Definition ED_screen.hh:728
void ED_region_do_msg_notify_tag_redraw(bContext *C, wmMsgSubscribeKey *msg_key, wmMsgSubscribeValue *msg_val)
Definition area.cc:381
void ED_region_header_layout(const bContext *C, ARegion *region)
Definition area.cc:3522
Read Guarded memory(de)allocation.
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
void uiItemL(uiLayout *layout, const char *name, int icon)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiItemS(uiLayout *layout)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
int uiTemplateRecentFiles(uiLayout *layout, int rows)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
uiLayout * uiLayoutSplit(uiLayout *layout, float percentage, bool align)
#define UI_UNIT_X
void uiLayoutSetOperatorContext(uiLayout *layout, wmOperatorCallContext opcontext)
void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
Definition view2d.cc:212
@ V2D_COMMONVIEW_HEADER
Definition UI_view2d.hh:39
#define ND_SPACE_INFO
Definition WM_types.hh:487
#define ND_JOB
Definition WM_types.hh:383
#define NC_WM
Definition WM_types.hh:341
#define ND_DATA
Definition WM_types.hh:475
#define NC_SCREEN
Definition WM_types.hh:344
#define ND_MODE
Definition WM_types.hh:412
#define NC_SCENE
Definition WM_types.hh:345
#define NC_WORKSPACE
Definition WM_types.hh:343
#define NC_GPENCIL
Definition WM_types.hh:366
#define ND_LAYER
Definition WM_types.hh:417
@ WM_OP_INVOKE_DEFAULT
Definition WM_types.hh:218
#define ND_HISTORY
Definition WM_types.hh:382
#define ND_SPACE_VIEW3D
Definition WM_types.hh:494
#define ND_SCENEBROWSE
Definition WM_types.hh:399
#define NC_SPACE
Definition WM_types.hh:359
unsigned int U
Definition btGjkEpa3.h:78
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
void ED_spacetype_topbar()
static void topbar_init(wmWindowManager *, ScrArea *)
static void recent_files_menu_register()
static SpaceLink * topbar_create(const ScrArea *, const Scene *)
static void topbar_free(SpaceLink *)
static void topbar_keymap(wmKeyConfig *)
static SpaceLink * topbar_duplicate(SpaceLink *sl)
static void topbar_header_listener(const wmRegionListenerParams *params)
static void topbar_space_blend_write(BlendWriter *writer, SpaceLink *sl)
static void undo_history_menu_register()
static void recent_files_menu_draw(const bContext *, Menu *menu)
static void topbar_header_region_init(wmWindowManager *, ARegion *region)
static void undo_history_draw_menu(const bContext *C, Menu *menu)
static void topbar_main_region_init(wmWindowManager *wm, ARegion *region)
static void topbar_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
static void topbar_operatortypes()
static void topbar_main_region_listener(const wmRegionListenerParams *params)
void(* message_subscribe)(const wmRegionMessageSubscribeParams *params)
void(* listener)(const wmRegionListenerParams *params)
void(* draw)(const bContext *C, ARegion *region)
void(* layout)(const bContext *C, ARegion *region)
void(* init)(wmWindowManager *wm, ARegion *region)
void * last
char label[BKE_ST_MAXNAME]
char idname[BKE_ST_MAXNAME]
void(* draw)(const bContext *C, Menu *menu)
char translation_context[BKE_ST_MAXNAME]
uiLayout * layout
ListBase regionbase
UndoStep * step_active
ListBase steps
UndoStep * prev
unsigned int data
Definition WM_types.hh:325
unsigned int category
Definition WM_types.hh:325
struct wmKeyConfig * defaultconf
struct UndoStack * undo_stack
#define N_(msgid)
wmEventHandler_Keymap * WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition wm_keymap.cc:897
bool WM_menutype_add(MenuType *mt)
#define WM_msg_subscribe_rna_prop(mbus, id_, data_, type_, prop_, value)