Blender V4.5
workspace_edit.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10#include <cstring>
11
12#include "BLI_fileops.h"
13#include "BLI_listbase.h"
14#include "BLI_path_utils.hh"
15#include "BLI_utildefines.h"
16
17#include "BKE_appdir.hh"
18#include "BKE_blendfile.hh"
19#include "BKE_context.hh"
20#include "BKE_lib_id.hh"
21#include "BKE_main.hh"
22#include "BKE_screen.hh"
23#include "BKE_workspace.hh"
24
25#include "BLO_readfile.hh"
26
27#include "DNA_screen_types.h"
29#include "DNA_workspace_types.h"
30
31#include "ED_datafiles.h"
32#include "ED_object.hh"
33#include "ED_screen.hh"
34
35#include "RNA_access.hh"
36#include "RNA_define.hh"
37
38#include "UI_interface.hh"
39#include "UI_resources.hh"
40
41#include "BLT_translation.hh"
42
43#include "WM_api.hh"
44#include "WM_types.hh"
45
46#include "screen_intern.hh"
47
48using blender::Vector;
49
50/* -------------------------------------------------------------------- */
55
56WorkSpace *ED_workspace_add(Main *bmain, const char *name)
57{
58 return BKE_workspace_add(bmain, name);
59}
60
61static void workspace_exit(WorkSpace *workspace, wmWindow *win)
62{
63 /* Scene pinning: Store whatever scene was active when leaving the workspace. It's reactivated
64 * when the workspace gets reactivated as well. */
65 if (workspace->flags & WORKSPACE_USE_PIN_SCENE) {
66 workspace->pin_scene = WM_window_get_active_scene(win);
67 }
68 else {
69 /* The active scene may have been changed. So also always update the unpinned scene to the
70 * latest when leaving a workspace that has no scene pinning. */
72 }
73}
74
90static void workspace_scene_pinning_update(WorkSpace *workspace_new,
91 const WorkSpace *workspace_old,
92 bContext *C)
93{
94 wmWindow *win = CTX_wm_window(C);
95 Main *bmain = CTX_data_main(C);
96 Scene *active_scene = WM_window_get_active_scene(win);
97
98 const bool is_new_pinned = (workspace_new->flags & WORKSPACE_USE_PIN_SCENE);
99 const bool is_old_pinned = (workspace_old->flags & WORKSPACE_USE_PIN_SCENE);
100
101 /* State changes 1 and 2. */
102 if (is_new_pinned) {
103 if (workspace_new->pin_scene && (workspace_new->pin_scene != active_scene)) {
104 WM_window_set_active_scene(bmain, C, win, workspace_new->pin_scene);
105 workspace_new->pin_scene = nullptr;
106 }
107 }
108 /* State change 3 - Changing from workspace with pinned scene to unpinned scene. */
109 else if (is_old_pinned) {
110 if (win->unpinned_scene) {
112 }
113 else {
114 /* When leaving a workspace where the pinning was just enabled, the unpinned scene wasn't set
115 * yet. */
116 win->unpinned_scene = active_scene;
117 }
118 }
119 else {
120 /* When leaving a workspace where the pinning was just disabled, we still want to restore the
121 * unpinned scene. */
122 if (win->unpinned_scene) {
124 }
125 }
126
128}
129
134static void workspace_change_update(WorkSpace *workspace_new,
135 WorkSpace *workspace_old,
136 bContext *C,
137 wmWindowManager *wm)
138{
139 workspace_scene_pinning_update(workspace_new, workspace_old, C);
140 /* needs to be done before changing mode! (to ensure right context) */
141 UNUSED_VARS(wm);
142#if 0
144 eObjectMode mode_old = workspace_old->object_mode;
145 eObjectMode mode_new = workspace_new->object_mode;
146
147 if (mode_old != mode_new) {
149 }
150#endif
151}
152
154 WorkSpace *workspace_new,
155 wmWindow *win)
156{
158 WorkSpaceLayout *layout_new;
159
160 /* ED_workspace_duplicate may have stored a layout to activate
161 * once the workspace gets activated. */
163 layout_new = win->workspace_hook->temp_layout_store;
164 }
165 else {
166 layout_new = BKE_workspace_active_layout_for_workspace_get(win->workspace_hook, workspace_new);
167 if (!layout_new) {
168 layout_new = static_cast<WorkSpaceLayout *>(workspace_new->layouts.first);
169 }
170 }
171
173 bmain, workspace_new, layout_new, layout_old, win);
174}
175
177{
178 Main *bmain = CTX_data_main(C);
179 WorkSpace *workspace_old = WM_window_get_active_workspace(win);
180 WorkSpaceLayout *layout_new = workspace_change_get_new_layout(bmain, workspace_new, win);
181 bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new);
183
184 win->workspace_hook->temp_layout_store = nullptr;
185 if (workspace_old == workspace_new) {
186 /* Could also return true, everything that needs to be done was done (nothing :P),
187 * but nothing changed */
188 return false;
189 }
190
191 workspace_exit(workspace_old, win);
192
193 screen_change_prepare(screen_old, screen_new, bmain, C, win);
194
195 if (screen_new == nullptr) {
196 return false;
197 }
198
199 BKE_workspace_active_layout_set(win->workspace_hook, win->winid, workspace_new, layout_new);
200 BKE_workspace_active_set(win->workspace_hook, workspace_new);
201
202 /* update screen *after* changing workspace - which also causes the
203 * actual screen change and updates context (including CTX_wm_workspace) */
204 screen_change_update(C, win, screen_new);
205 workspace_change_update(workspace_new, workspace_old, C, wm);
206
207 BLI_assert(CTX_wm_workspace(C) == workspace_new);
208
209 /* Automatic mode switching. */
210 if (workspace_new->object_mode != workspace_old->object_mode) {
212 }
213
214 return true;
215}
216
218{
220 WorkSpace *workspace_new = ED_workspace_add(bmain, workspace_old->id.name + 2);
221
222 workspace_new->flags = workspace_old->flags;
223 workspace_new->pin_scene = workspace_old->pin_scene;
224 workspace_new->object_mode = workspace_old->object_mode;
225 workspace_new->order = workspace_old->order;
226 BLI_duplicatelist(&workspace_new->owner_ids, &workspace_old->owner_ids);
227
228 /* TODO(@ideasman42): tools */
229
230 LISTBASE_FOREACH (WorkSpaceLayout *, layout_old, &workspace_old->layouts) {
232 bmain, workspace_new, layout_old, win);
233
234 if (layout_active_old == layout_old) {
235 win->workspace_hook->temp_layout_store = layout_new;
236 }
237 }
238 return workspace_new;
239}
240
242{
243 if (BLI_listbase_is_single(&bmain->workspaces)) {
244 return false;
245 }
246
248 const int index = ordered.first_index_of(&workspace->id);
249
250 WorkSpace *new_active = reinterpret_cast<WorkSpace *>(index == 0 ? ordered[1] :
251 ordered[index - 1]);
252
253 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
254 WorkSpace *workspace_active = WM_window_get_active_workspace(win);
255 if (workspace_active == workspace) {
256 ED_workspace_change(new_active, C, wm, win);
257 }
258 }
259
260 /* Also delete managed screens if they have no other users. */
261 LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) {
262 BKE_id_free_us(bmain, layout->screen);
263 layout->screen = nullptr;
264 }
265
266 BKE_id_free(bmain, &workspace->id);
267 return true;
268}
269
275
277
278/* -------------------------------------------------------------------- */
281
283{
285 if (id && GS(id->name) == ID_WS) {
286 return (WorkSpace *)id;
287 }
288
289 return CTX_wm_workspace(C);
290}
291
293{
294 return workspace_context_get(C) != nullptr;
295}
296
298{
299 Main *bmain = CTX_data_main(C);
300 wmWindow *win = CTX_wm_window(C);
301 WorkSpace *workspace = workspace_context_get(C);
302
303 workspace = ED_workspace_duplicate(workspace, bmain, win);
304
306
307 return OPERATOR_FINISHED;
308}
309
311{
312 /* identifiers */
313 ot->name = "New Workspace";
314 ot->description = "Add a new workspace";
315 ot->idname = "WORKSPACE_OT_duplicate";
316
317 /* API callbacks. */
319 ot->exec = workspace_new_exec;
320}
321
330
332{
333 /* identifiers */
334 ot->name = "Delete Workspace";
335 ot->description = "Delete the active workspace";
336 ot->idname = "WORKSPACE_OT_delete";
337
338 /* API callbacks. */
341}
342
344{
345 Main *bmain = CTX_data_main(C);
346 char idname[MAX_ID_NAME - 2], filepath[FILE_MAX];
347
348 if (!RNA_struct_property_is_set(op->ptr, "idname") ||
349 !RNA_struct_property_is_set(op->ptr, "filepath"))
350 {
351 return OPERATOR_CANCELLED;
352 }
353 RNA_string_get(op->ptr, "idname", idname);
354 RNA_string_get(op->ptr, "filepath", filepath);
355
356 WorkSpace *appended_workspace = (WorkSpace *)WM_file_append_datablock(
357 bmain,
361 filepath,
362 ID_WS,
363 idname,
365
366 if (appended_workspace) {
368 /* Translate workspace name */
370 *bmain, appended_workspace->id, CTX_DATA_(BLT_I18NCONTEXT_ID_WORKSPACE, idname));
371 }
372
373 /* Set defaults. */
374 BLO_update_defaults_workspace(appended_workspace, nullptr);
375
376 /* Reorder to last position. */
377 BKE_id_reorder(&bmain->workspaces, &appended_workspace->id, nullptr, true);
378
379 /* Changing workspace changes context. Do delayed! */
380 WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, appended_workspace);
381
382 return OPERATOR_FINISHED;
383 }
384
385 return OPERATOR_CANCELLED;
386}
387
389{
390 /* identifiers */
391 ot->name = "Append and Activate Workspace";
392 ot->description = "Append a workspace and make it the active one in the current window";
393 ot->idname = "WORKSPACE_OT_append_activate";
394
395 /* API callbacks. */
397
398 PropertyRNA *prop;
399 RNA_def_string(ot->srna,
400 "idname",
401 nullptr,
402 MAX_ID_NAME - 2,
403 "Identifier",
404 "Name of the workspace to append and activate");
405 prop = RNA_def_string(
406 ot->srna, "filepath", nullptr, FILE_MAX, "Filepath", "Path to the library");
409}
410
412{
413 const std::optional<std::string> cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG,
415 char startup_file_path[FILE_MAX] = {0};
416
417 if (cfgdir.has_value()) {
419 startup_file_path, sizeof(startup_file_path), cfgdir->c_str(), BLENDER_STARTUP_FILE);
420 }
421
422 bool has_path = BLI_exists(startup_file_path);
423 return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, nullptr, 0, nullptr) :
424 nullptr;
425}
426
428{
429 if (app_template == nullptr) {
432 }
433
434 char template_dir[FILE_MAX];
435 if (!BKE_appdir_app_template_id_search(app_template, template_dir, sizeof(template_dir))) {
436 return nullptr;
437 }
438
439 char startup_file_path[FILE_MAX];
440 BLI_path_join(startup_file_path, sizeof(startup_file_path), template_dir, BLENDER_STARTUP_FILE);
441
442 bool has_path = BLI_exists(startup_file_path);
443 return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, nullptr, 0, nullptr) :
444 nullptr;
445}
446
448 wmOperatorType *ot_append,
449 const WorkSpace *workspace,
450 const Main *from_main)
451{
452 const ID *id = (ID *)workspace;
453 const char *filepath = from_main->filepath;
454
455 if (strlen(filepath) == 0) {
457 }
458
459 BLI_assert(STREQ(ot_append->idname, "WORKSPACE_OT_append_activate"));
460
461 PointerRNA opptr;
462 opptr = layout->op(ot_append,
464 ICON_NONE,
467 RNA_string_set(&opptr, "idname", id->name + 2);
468 RNA_string_set(&opptr, "filepath", filepath);
469}
470
471static void workspace_add_menu(bContext * /*C*/, uiLayout *layout, void *template_v)
472{
473 const char *app_template = static_cast<const char *>(template_v);
474 bool has_startup_items = false;
475
476 wmOperatorType *ot_append = WM_operatortype_find("WORKSPACE_OT_append_activate", true);
479
480 if (startup_config) {
481 LISTBASE_FOREACH (WorkSpace *, workspace, &startup_config->workspaces) {
482 uiLayout *row = &layout->row(false);
483 workspace_append_button(row, ot_append, workspace, startup_config->main);
484 has_startup_items = true;
485 }
486 }
487
488 if (builtin_config) {
489 bool has_title = false;
490
491 LISTBASE_FOREACH (WorkSpace *, workspace, &builtin_config->workspaces) {
492 if (startup_config &&
493 BLI_findstring(&startup_config->workspaces, workspace->id.name, offsetof(ID, name)))
494 {
495 continue;
496 }
497
498 if (!has_title) {
499 if (has_startup_items) {
500 layout->separator();
501 }
502 has_title = true;
503 }
504
505 uiLayout *row = &layout->row(false);
506 workspace_append_button(row, ot_append, workspace, builtin_config->main);
507 }
508 }
509
510 if (startup_config) {
512 }
513 if (builtin_config) {
515 }
516}
517
519 wmOperator *op,
520 const wmEvent * /*event*/)
521{
524 uiLayout *layout = UI_popup_menu_layout(pup);
525
526 layout->menu_fn(IFACE_("General"), ICON_NONE, workspace_add_menu, nullptr);
527
528 ListBase templates;
529 BKE_appdir_app_templates(&templates);
530
531 LISTBASE_FOREACH (LinkData *, link, &templates) {
532 char *app_template = static_cast<char *>(link->data);
533 char display_name[FILE_MAX];
534
535 BLI_path_to_display_name(display_name, sizeof(display_name), IFACE_(app_template));
536
537 /* Steals ownership of link data string. */
538 layout->menu_fn_argN_free(display_name, ICON_NONE, workspace_add_menu, app_template);
539 }
540
541 BLI_freelistN(&templates);
542
543 layout->separator();
544 layout->op("WORKSPACE_OT_duplicate",
545 CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Duplicate Current"),
546 ICON_DUPLICATE);
547
548 UI_popup_menu_end(C, pup);
549
550 return OPERATOR_INTERFACE;
551}
552
554{
555 /* identifiers */
556 ot->name = "Add Workspace";
557 ot->description =
558 "Add a new workspace by duplicating the current one or appending one "
559 "from the user configuration";
560 ot->idname = "WORKSPACE_OT_add";
561
562 /* API callbacks. */
563 ot->invoke = workspace_add_invoke;
564}
565
567{
568 Main *bmain = CTX_data_main(C);
569 WorkSpace *workspace = workspace_context_get(C);
570
571 BKE_id_reorder(&bmain->workspaces, &workspace->id, nullptr, true);
573
574 return OPERATOR_INTERFACE;
575}
576
578{
579 /* identifiers */
580 ot->name = "Workspace Reorder to Back";
581 ot->description = "Reorder workspace to be last in the list";
582 ot->idname = "WORKSPACE_OT_reorder_to_back";
583
584 /* API callbacks. */
587}
588
590{
591 Main *bmain = CTX_data_main(C);
592 WorkSpace *workspace = workspace_context_get(C);
593
594 BKE_id_reorder(&bmain->workspaces, &workspace->id, nullptr, false);
596
597 return OPERATOR_INTERFACE;
598}
599
601{
602 /* identifiers */
603 ot->name = "Workspace Reorder to Front";
604 ot->description = "Reorder workspace to be first in the list";
605 ot->idname = "WORKSPACE_OT_reorder_to_front";
606
607 /* API callbacks. */
610}
611
613{
614 WorkSpace *workspace = workspace_context_get(C);
615
616 /* Trivial. The operator is only needed to display a superimposed extra icon, which
617 * requires an operator. */
618 workspace->flags ^= WORKSPACE_USE_PIN_SCENE;
619
621
622 return OPERATOR_FINISHED;
623}
624
626{
627 /* identifiers */
628 ot->name = "Pin Scene to Workspace";
629 ot->description =
630 "Remember the last used scene for the current workspace and switch to it whenever this "
631 "workspace is activated again";
632 ot->idname = "WORKSPACE_OT_scene_pin_toggle";
633
634 /* API callbacks. */
637
638 ot->flag = OPTYPE_INTERNAL;
639}
640
651
bool BKE_appdir_app_template_id_search(const char *app_template, char *path, size_t path_maxncpy) ATTR_NONNULL(1)
Definition appdir.cc:1078
@ BLENDER_USER_CONFIG
void BKE_appdir_app_templates(ListBase *templates) ATTR_NONNULL(1)
Definition appdir.cc:1112
std::optional< std::string > BKE_appdir_folder_id(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT
Definition appdir.cc:717
#define BLENDER_STARTUP_FILE
WorkspaceConfigFileData * BKE_blendfile_workspace_config_read(const char *filepath, const void *file_buf, int file_buf_size, ReportList *reports)
void BKE_blendfile_workspace_config_data_free(WorkspaceConfigFileData *workspace_config)
WorkSpace * CTX_wm_workspace(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
void BKE_id_free_us(Main *bmain, void *idv) ATTR_NONNULL()
void BKE_id_free(Main *bmain, void *idv)
void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
Definition lib_id.cc:2575
blender::Vector< ID * > BKE_id_ordered_list(const ListBase *lb)
Definition lib_id.cc:2556
IDNewNameResult BKE_libblock_rename(Main &bmain, ID &id, blender::StringRefNull name, const IDNewNameMode mode=IDNewNameMode::RenameExistingNever)
Definition lib_id.cc:2350
void BKE_screen_view3d_scene_sync(bScreen *screen, Scene *scene)
Definition screen.cc:998
WorkSpace * BKE_workspace_add(Main *bmain, const char *name)
Definition workspace.cc:317
bScreen * BKE_workspace_layout_screen_get(const WorkSpaceLayout *layout) GETTER_ATTRS
Definition workspace.cc:637
void BKE_workspace_active_layout_set(WorkSpaceInstanceHook *hook, int winid, WorkSpace *workspace, WorkSpaceLayout *layout) SETTER_ATTRS
Activate a layout.
Definition workspace.cc:603
bScreen * BKE_workspace_active_screen_get(const WorkSpaceInstanceHook *hook) GETTER_ATTRS
Definition workspace.cc:612
WorkSpaceLayout * BKE_workspace_active_layout_for_workspace_get(const WorkSpaceInstanceHook *hook, const WorkSpace *workspace) GETTER_ATTRS
Definition workspace.cc:590
void BKE_workspace_active_set(WorkSpaceInstanceHook *hook, WorkSpace *workspace) SETTER_ATTRS
Definition workspace.cc:565
WorkSpaceLayout * BKE_workspace_active_layout_get(const WorkSpaceInstanceHook *hook) GETTER_ATTRS
Definition workspace.cc:585
#define BLI_assert(a)
Definition BLI_assert.h:46
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:373
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:608
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void void void void void void BLI_duplicatelist(ListBase *dst, const ListBase *src) ATTR_NONNULL(1
void void BLI_INLINE bool BLI_listbase_is_single(const ListBase *lb)
void BLI_path_to_display_name(char *display_name, int display_name_maxncpy, const char *name) ATTR_NONNULL(1
#define FILE_MAX
#define BLI_path_join(...)
#define UNUSED_VARS(...)
#define STREQ(a, b)
external readfile function prototypes.
void BLO_update_defaults_workspace(WorkSpace *workspace, const char *app_template)
@ BLO_LIBLINK_APPEND_RECURSIVE
#define BLO_EMBEDDED_STARTUP_BLEND
bool BLT_translate_new_dataname()
#define BLT_I18NCONTEXT_ID_WORKSPACE
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
#define CTX_DATA_(context, msgid)
#define IFACE_(msgid)
@ ID_WS
eObjectMode
@ OPERATOR_CANCELLED
@ OPERATOR_INTERFACE
@ OPERATOR_FINISHED
@ WORKSPACE_USE_PIN_SCENE
int datatoc_startup_blend_size
const char datatoc_startup_blend[]
WorkSpaceLayout * ED_workspace_screen_change_ensure_unused_layout(Main *bmain, WorkSpace *workspace, WorkSpaceLayout *layout_new, const WorkSpaceLayout *layout_fallback_base, wmWindow *win) ATTR_NONNULL()
WorkSpaceLayout * ED_workspace_layout_duplicate(Main *bmain, WorkSpace *workspace, const WorkSpaceLayout *layout_old, wmWindow *win) ATTR_NONNULL()
@ PROP_PATH_SUPPORTS_BLEND_RELATIVE
Definition RNA_types.hh:430
@ PROP_FILEPATH
Definition RNA_types.hh:224
#define C
Definition RandGen.cpp:29
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
ID * UI_context_active_but_get_tab_ID(bContext *C)
uiPopupMenu * UI_popup_menu_begin(bContext *C, const char *title, int icon) ATTR_NONNULL()
uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
#define UI_ITEM_NONE
#define NC_WINDOW
Definition WM_types.hh:372
#define NC_SCREEN
Definition WM_types.hh:374
#define ND_WORKSPACE_DELETE
Definition WM_types.hh:426
#define NC_WORKSPACE
Definition WM_types.hh:373
@ WM_OP_EXEC_DEFAULT
Definition WM_types.hh:245
#define ND_WORKSPACE_SET
Definition WM_types.hh:425
@ OPTYPE_INTERNAL
Definition WM_types.hh:202
int64_t first_index_of(const T &value) const
#define offsetof(t, d)
#define MAX_ID_NAME
#define GS(a)
bool mode_set(bContext *C, eObjectMode mode)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
void screen_change_prepare(bScreen *screen_old, bScreen *screen_new, Main *bmain, bContext *C, wmWindow *win)
void screen_change_update(bContext *C, wmWindow *win, bScreen *screen)
Definition DNA_ID.h:404
char name[66]
Definition DNA_ID.h:415
void * first
char filepath[1024]
Definition BKE_main.hh:155
ListBase workspaces
Definition BKE_main.hh:284
struct WorkSpaceLayout * temp_layout_store
Wrapper for bScreen.
struct Scene * pin_scene
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, wmOperatorCallContext context, eUI_Item_Flag flag)
void menu_fn_argN_free(blender::StringRefNull name, int icon, uiMenuCreateFunc func, void *argN)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
void menu_fn(blender::StringRefNull name, int icon, uiMenuCreateFunc func, void *arg)
uiLayout & row(bool align)
const char * name
Definition WM_types.hh:1030
const char * idname
Definition WM_types.hh:1032
struct wmOperatorType * type
struct PointerRNA * ptr
struct Scene * unpinned_scene
struct WorkSpaceInstanceHook * workspace_hook
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
char app_template[64]
Definition wm_files.cc:1183
wmOperatorType * ot
Definition wm_files.cc:4226
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_window_set_active_scene(Main *bmain, bContext *C, wmWindow *win, Scene *scene)
WorkSpaceLayout * WM_window_get_active_layout(const wmWindow *win)
Scene * WM_window_get_active_scene(const wmWindow *win)
WorkSpace * WM_window_get_active_workspace(const wmWindow *win)
static void workspace_append_button(uiLayout *layout, wmOperatorType *ot_append, const WorkSpace *workspace, const Main *from_main)
static wmOperatorStatus workspace_reorder_to_front_exec(bContext *C, wmOperator *)
static wmOperatorStatus workspace_new_exec(bContext *C, wmOperator *)
static WorkSpace * workspace_context_get(bContext *C)
static void WORKSPACE_OT_add(wmOperatorType *ot)
static void WORKSPACE_OT_scene_pin_toggle(wmOperatorType *ot)
static void workspace_scene_pinning_update(WorkSpace *workspace_new, const WorkSpace *workspace_old, bContext *C)
static wmOperatorStatus workspace_add_invoke(bContext *C, wmOperator *op, const wmEvent *)
WorkSpace * ED_workspace_duplicate(WorkSpace *workspace_old, Main *bmain, wmWindow *win)
static void workspace_change_update(WorkSpace *workspace_new, WorkSpace *workspace_old, bContext *C, wmWindowManager *wm)
static void workspace_exit(WorkSpace *workspace, wmWindow *win)
static WorkspaceConfigFileData * workspace_config_file_read(const char *app_template)
static wmOperatorStatus workspace_delete_exec(bContext *C, wmOperator *)
static void WORKSPACE_OT_delete(wmOperatorType *ot)
static void WORKSPACE_OT_append_activate(wmOperatorType *ot)
static void workspace_add_menu(bContext *, uiLayout *layout, void *template_v)
static void WORKSPACE_OT_reorder_to_back(wmOperatorType *ot)
bool ED_workspace_change(WorkSpace *workspace_new, bContext *C, wmWindowManager *wm, wmWindow *win)
Change the active workspace.
static void WORKSPACE_OT_duplicate(wmOperatorType *ot)
void ED_workspace_scene_data_sync(WorkSpaceInstanceHook *hook, Scene *scene)
bool ED_workspace_delete(WorkSpace *workspace, Main *bmain, bContext *C, wmWindowManager *wm)
static wmOperatorStatus workspace_append_activate_exec(bContext *C, wmOperator *op)
void ED_operatortypes_workspace()
static void WORKSPACE_OT_reorder_to_front(wmOperatorType *ot)
static wmOperatorStatus workspace_scene_pin_toggle_exec(bContext *C, wmOperator *)
static WorkspaceConfigFileData * workspace_system_file_read(const char *app_template)
static WorkSpaceLayout * workspace_change_get_new_layout(Main *bmain, WorkSpace *workspace_new, wmWindow *win)
static bool workspace_context_poll(bContext *C)
static wmOperatorStatus workspace_reorder_to_back_exec(bContext *C, wmOperator *)
WorkSpace * ED_workspace_add(Main *bmain, const char *name)