Blender  V3.3
space_topbar.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2017 Blender Foundation. All rights reserved. */
3 
8 #include <stdio.h>
9 #include <string.h>
10 
11 #include "MEM_guardedalloc.h"
12 
13 #include "BLI_blenlib.h"
14 #include "BLI_utildefines.h"
15 
16 #include "BLO_readfile.h"
17 #include "BLT_translation.h"
18 
19 #include "BKE_context.h"
20 #include "BKE_global.h"
21 #include "BKE_screen.h"
22 #include "BKE_undo_system.h"
23 
24 #include "ED_screen.h"
25 #include "ED_space_api.h"
26 
27 #include "UI_interface.h"
28 #include "UI_resources.h"
29 #include "UI_view2d.h"
30 
31 #include "RNA_access.h"
32 
33 #include "WM_api.h"
34 #include "WM_message.h"
35 #include "WM_types.h"
36 
37 /* ******************** default callbacks for topbar space ***************** */
38 
40 {
41  ARegion *region;
42  SpaceTopBar *stopbar;
43 
44  stopbar = MEM_callocN(sizeof(*stopbar), "init topbar");
45  stopbar->spacetype = SPACE_TOPBAR;
46 
47  /* header */
48  region = MEM_callocN(sizeof(ARegion), "left aligned header for topbar");
49  BLI_addtail(&stopbar->regionbase, region);
50  region->regiontype = RGN_TYPE_HEADER;
51  region->alignment = RGN_ALIGN_TOP;
52  region = MEM_callocN(sizeof(ARegion), "right aligned header for topbar");
53  BLI_addtail(&stopbar->regionbase, region);
54  region->regiontype = RGN_TYPE_HEADER;
56 
57  /* main regions */
58  region = MEM_callocN(sizeof(ARegion), "main region of topbar");
59  BLI_addtail(&stopbar->regionbase, region);
60  region->regiontype = RGN_TYPE_WINDOW;
61 
62  return (SpaceLink *)stopbar;
63 }
64 
65 /* not spacelink itself */
66 static void topbar_free(SpaceLink *UNUSED(sl))
67 {
68 }
69 
70 /* spacetype; init callback */
71 static void topbar_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
72 {
73 }
74 
76 {
77  SpaceTopBar *stopbarn = MEM_dupallocN(sl);
78 
79  /* clear or remove stuff from old */
80 
81  return (SpaceLink *)stopbarn;
82 }
83 
84 /* add handlers, stuff you only do once or on area/region changes */
86 {
87  wmKeyMap *keymap;
88 
89  /* force delayed UI_view2d_region_reinit call */
91  region->flag |= RGN_FLAG_DYNAMIC_SIZE;
92  }
93  UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_HEADER, region->winx, region->winy);
94 
95  keymap = WM_keymap_ensure(wm->defaultconf, "View2D Buttons List", 0, 0);
96  WM_event_add_keymap_handler(&region->handlers, keymap);
97 }
98 
99 static void topbar_operatortypes(void)
100 {
101 }
102 
103 static void topbar_keymap(struct wmKeyConfig *UNUSED(keyconf))
104 {
105 }
106 
107 /* add handlers, stuff you only do once or on area/region changes */
109 {
111  region->flag |= RGN_FLAG_DYNAMIC_SIZE;
112  }
113  ED_region_header_init(region);
114 }
115 
117 {
118  ARegion *region = params->region;
119  wmNotifier *wmn = params->notifier;
120 
121  /* context changes */
122  switch (wmn->category) {
123  case NC_WM:
124  if (wmn->data == ND_HISTORY) {
125  ED_region_tag_redraw(region);
126  }
127  break;
128  case NC_SCENE:
129  if (wmn->data == ND_MODE) {
130  ED_region_tag_redraw(region);
131  }
132  break;
133  case NC_SPACE:
134  if (wmn->data == ND_SPACE_VIEW3D) {
135  ED_region_tag_redraw(region);
136  }
137  break;
138  case NC_GPENCIL:
139  if (wmn->data == ND_DATA) {
140  ED_region_tag_redraw(region);
141  }
142  break;
143  }
144 }
145 
147 {
148  ARegion *region = params->region;
149  wmNotifier *wmn = params->notifier;
150 
151  /* context changes */
152  switch (wmn->category) {
153  case NC_WM:
154  if (wmn->data == ND_JOB) {
155  ED_region_tag_redraw(region);
156  }
157  break;
158  case NC_WORKSPACE:
159  ED_region_tag_redraw(region);
160  break;
161  case NC_SPACE:
162  if (wmn->data == ND_SPACE_INFO) {
163  ED_region_tag_redraw(region);
164  }
165  break;
166  case NC_SCREEN:
167  if (wmn->data == ND_LAYER) {
168  ED_region_tag_redraw(region);
169  }
170  break;
171  case NC_SCENE:
172  if (wmn->data == ND_SCENEBROWSE) {
173  ED_region_tag_redraw(region);
174  }
175  break;
176  }
177 }
178 
180 {
181  struct wmMsgBus *mbus = params->message_bus;
182  WorkSpace *workspace = params->workspace;
183  ARegion *region = params->region;
184 
185  wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
186  .owner = region,
187  .user_data = region,
189  };
190 
192  mbus, &workspace->id, workspace, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
193 }
194 
195 static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu)
196 {
197  struct RecentFile *recent;
198  uiLayout *layout = menu->layout;
200  if (!BLI_listbase_is_empty(&G.recent_files)) {
201  for (recent = G.recent_files.first; (recent); recent = recent->next) {
202  const char *file = BLI_path_basename(recent->filepath);
203  const int icon = BLO_has_bfile_extension(file) ? ICON_FILE_BLEND : ICON_FILE_BACKUP;
204  PointerRNA ptr;
205  uiItemFullO(layout, "WM_OT_open_mainfile", file, icon, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr);
206  RNA_string_set(&ptr, "filepath", recent->filepath);
207  RNA_boolean_set(&ptr, "display_file_selector", false);
208  }
209  }
210  else {
211  uiItemL(layout, IFACE_("No Recent Files"), ICON_NONE);
212  }
213 }
214 
215 static void recent_files_menu_register(void)
216 {
217  MenuType *mt;
218 
219  mt = MEM_callocN(sizeof(MenuType), "spacetype info menu recent files");
220  strcpy(mt->idname, "TOPBAR_MT_file_open_recent");
221  strcpy(mt->label, N_("Open Recent"));
224  WM_menutype_add(mt);
225 }
226 
227 static void undo_history_draw_menu(const bContext *C, Menu *menu)
228 {
230  if (wm->undo_stack == NULL) {
231  return;
232  }
233 
234  int undo_step_count = 0;
235  int undo_step_count_all = 0;
236  for (UndoStep *us = wm->undo_stack->steps.last; us; us = us->prev) {
237  undo_step_count_all += 1;
238  if (us->skip) {
239  continue;
240  }
241  undo_step_count += 1;
242  }
243 
244  uiLayout *split = uiLayoutSplit(menu->layout, 0.0f, false);
245  uiLayout *column = NULL;
246 
247  const int col_size = 20 + (undo_step_count / 12);
248 
249  undo_step_count = 0;
250 
251  /* Reverse the order so the most recent state is first in the menu. */
252  int i = undo_step_count_all - 1;
253  for (UndoStep *us = wm->undo_stack->steps.last; us; us = us->prev, i--) {
254  if (us->skip) {
255  continue;
256  }
257  if (!(undo_step_count % col_size)) {
258  column = uiLayoutColumn(split, false);
259  }
260  const bool is_active = (us == wm->undo_stack->step_active);
261  uiLayout *row = uiLayoutRow(column, false);
262  uiLayoutSetEnabled(row, !is_active);
263  uiItemIntO(row,
264  IFACE_(us->name),
265  is_active ? ICON_LAYER_ACTIVE : ICON_NONE,
266  "ED_OT_undo_history",
267  "item",
268  i);
269  undo_step_count += 1;
270  }
271 }
272 
273 static void undo_history_menu_register(void)
274 {
275  MenuType *mt;
276 
277  mt = MEM_callocN(sizeof(MenuType), __func__);
278  strcpy(mt->idname, "TOPBAR_MT_undo_history");
279  strcpy(mt->label, N_("Undo History"));
282  WM_menutype_add(mt);
283 }
284 
286 {
287  SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype topbar");
288  ARegionType *art;
289 
290  st->spaceid = SPACE_TOPBAR;
291  strncpy(st->name, "Top Bar", BKE_ST_MAXNAME);
292 
293  st->create = topbar_create;
294  st->free = topbar_free;
295  st->init = topbar_init;
296  st->duplicate = topbar_duplicate;
297  st->operatortypes = topbar_operatortypes;
298  st->keymap = topbar_keymap;
299 
300  /* regions: main window */
301  art = MEM_callocN(sizeof(ARegionType), "spacetype topbar main region");
302  art->regionid = RGN_TYPE_WINDOW;
307  art->prefsizex = UI_UNIT_X * 5; /* Mainly to avoid glitches */
309 
310  BLI_addhead(&st->regiontypes, art);
311 
312  /* regions: header */
313  art = MEM_callocN(sizeof(ARegionType), "spacetype topbar header region");
314  art->regionid = RGN_TYPE_HEADER;
315  art->prefsizey = HEADERY;
316  art->prefsizex = UI_UNIT_X * 5; /* Mainly to avoid glitches */
323 
324  BLI_addhead(&st->regiontypes, art);
325 
328 
330 }
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
#define BKE_ST_MAXNAME
Definition: BKE_screen.h:53
void BKE_spacetype_register(struct SpaceType *st)
Definition: screen.c:391
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:60
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
const char * BLI_path_basename(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:1653
#define UNUSED(x)
#define ELEM(...)
external readfile function prototypes.
bool BLO_has_bfile_extension(const char *str)
Definition: readfile.c:1497
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
#define HEADERY
#define RGN_ALIGN_ENUM_FROM_MASK(align)
@ RGN_FLAG_DYNAMIC_SIZE
@ RGN_TYPE_WINDOW
@ RGN_TYPE_HEADER
@ RGN_ALIGN_TOP
@ RGN_ALIGN_RIGHT
@ RGN_SPLIT_PREV
@ SPACE_TOPBAR
@ ED_KEYMAP_UI
Definition: ED_screen.h:691
@ ED_KEYMAP_HEADER
Definition: ED_screen.h:697
@ ED_KEYMAP_VIEW2D
Definition: ED_screen.h:694
void ED_region_do_msg_notify_tag_redraw(struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val)
void ED_region_header_layout(const struct bContext *C, struct ARegion *region)
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
void ED_region_header_init(struct ARegion *region)
Definition: area.c:3417
void ED_region_header_draw(const struct bContext *C, struct ARegion *region)
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
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)
uiLayout * uiLayoutSplit(uiLayout *layout, float percentage, bool align)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, struct IDProperty *properties, wmOperatorCallContext context, int flag, struct PointerRNA *r_opptr)
#define UI_UNIT_X
void uiLayoutSetOperatorContext(uiLayout *layout, wmOperatorCallContext opcontext)
void UI_view2d_region_reinit(struct View2D *v2d, short type, int winx, int winy)
Definition: view2d.cc:217
@ V2D_COMMONVIEW_HEADER
Definition: UI_view2d.h:42
#define ND_SPACE_INFO
Definition: WM_types.h:464
#define ND_JOB
Definition: WM_types.h:364
#define NC_WM
Definition: WM_types.h:324
#define ND_DATA
Definition: WM_types.h:456
#define NC_SCREEN
Definition: WM_types.h:327
#define ND_MODE
Definition: WM_types.h:393
#define NC_SCENE
Definition: WM_types.h:328
#define NC_WORKSPACE
Definition: WM_types.h:326
#define NC_GPENCIL
Definition: WM_types.h:349
#define ND_LAYER
Definition: WM_types.h:398
@ WM_OP_INVOKE_DEFAULT
Definition: WM_types.h:201
#define ND_HISTORY
Definition: WM_types.h:363
#define ND_SPACE_VIEW3D
Definition: WM_types.h:471
#define ND_SCENEBROWSE
Definition: WM_types.h:380
#define NC_SPACE
Definition: WM_types.h:342
FILE * file
Scene scene
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define G(x, y, z)
static void area(int d1, int d2, int e1, int e2, float weights[2])
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:92
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:5155
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:4874
static void topbar_free(SpaceLink *UNUSED(sl))
Definition: space_topbar.c:66
static void topbar_keymap(struct wmKeyConfig *UNUSED(keyconf))
Definition: space_topbar.c:103
static void recent_files_menu_register(void)
Definition: space_topbar.c:215
void ED_spacetype_topbar(void)
Definition: space_topbar.c:285
static void topbar_operatortypes(void)
Definition: space_topbar.c:99
static void topbar_header_listener(const wmRegionListenerParams *params)
Definition: space_topbar.c:146
static SpaceLink * topbar_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
Definition: space_topbar.c:39
static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu)
Definition: space_topbar.c:195
static void undo_history_draw_menu(const bContext *C, Menu *menu)
Definition: space_topbar.c:227
static void topbar_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
Definition: space_topbar.c:71
static void topbar_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
Definition: space_topbar.c:108
static void undo_history_menu_register(void)
Definition: space_topbar.c:273
static void topbar_main_region_init(wmWindowManager *wm, ARegion *region)
Definition: space_topbar.c:85
static void topbar_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
Definition: space_topbar.c:179
static SpaceLink * topbar_duplicate(SpaceLink *sl)
Definition: space_topbar.c:75
static void topbar_main_region_listener(const wmRegionListenerParams *params)
Definition: space_topbar.c:116
void(* draw)(const struct bContext *C, struct ARegion *region)
Definition: BKE_screen.h:151
void(* message_subscribe)(const wmRegionMessageSubscribeParams *params)
Definition: BKE_screen.h:167
void(* listener)(const wmRegionListenerParams *params)
Definition: BKE_screen.h:165
int keymapflag
Definition: BKE_screen.h:208
void(* layout)(const struct bContext *C, struct ARegion *region)
Definition: BKE_screen.h:161
void(* init)(struct wmWindowManager *wm, struct ARegion *region)
Definition: BKE_screen.h:147
ListBase handlers
short alignment
short regiontype
void * last
Definition: DNA_listBase.h:31
char label[BKE_ST_MAXNAME]
Definition: BKE_screen.h:362
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:361
void(* draw)(const struct bContext *C, struct Menu *menu)
Definition: BKE_screen.h:370
char translation_context[BKE_ST_MAXNAME]
Definition: BKE_screen.h:363
struct uiLayout * layout
Definition: BKE_screen.h:378
struct RecentFile * next
Definition: WM_types.h:1270
char * filepath
Definition: WM_types.h:1271
ListBase regionbase
struct UndoStep * step_active
ListBase steps
unsigned int data
Definition: WM_types.h:308
unsigned int category
Definition: WM_types.h:308
struct wmKeyConfig * defaultconf
struct UndoStack * undo_stack
#define N_(msgid)
wmEventHandler_Keymap * WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
PointerRNA * ptr
Definition: wm_files.c:3480
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:852
bool WM_menutype_add(MenuType *mt)
Definition: wm_menu_type.c:51
#define WM_msg_subscribe_rna_prop(mbus, id_, data_, type_, prop_, value)