Blender  V2.93
workspace.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include "BLI_listbase.h"
26 #include "BLI_string.h"
27 #include "BLI_string_utils.h"
28 #include "BLI_utildefines.h"
29 
30 #include "BLT_translation.h"
31 
32 #include "BKE_global.h"
33 #include "BKE_idprop.h"
34 #include "BKE_idtype.h"
35 #include "BKE_lib_id.h"
36 #include "BKE_lib_query.h"
37 #include "BKE_main.h"
38 #include "BKE_object.h"
39 #include "BKE_scene.h"
40 #include "BKE_workspace.h"
41 
42 #include "DNA_object_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_screen_types.h"
46 #include "DNA_workspace_types.h"
47 
48 #include "DEG_depsgraph.h"
49 
50 #include "MEM_guardedalloc.h"
51 
52 #include "BLO_read_write.h"
53 
54 /* -------------------------------------------------------------------- */
55 
56 static void workspace_free_data(ID *id)
57 {
58  WorkSpace *workspace = (WorkSpace *)id;
59 
61 
62  BLI_freelistN(&workspace->owner_ids);
63  BLI_freelistN(&workspace->layouts);
64 
65  while (!BLI_listbase_is_empty(&workspace->tools)) {
66  BKE_workspace_tool_remove(workspace, workspace->tools.first);
67  }
68 
69  MEM_SAFE_FREE(workspace->status_text);
70 }
71 
73 {
74  WorkSpace *workspace = (WorkSpace *)id;
75 
76  LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) {
78  }
79 }
80 
81 static void workspace_blend_write(BlendWriter *writer, ID *id, const void *id_address)
82 {
83  WorkSpace *workspace = (WorkSpace *)id;
84 
85  BLO_write_id_struct(writer, WorkSpace, id_address, &workspace->id);
86  BKE_id_blend_write(writer, &workspace->id);
87  BLO_write_struct_list(writer, WorkSpaceLayout, &workspace->layouts);
89  BLO_write_struct_list(writer, wmOwnerID, &workspace->owner_ids);
90  BLO_write_struct_list(writer, bToolRef, &workspace->tools);
91  LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
92  if (tref->properties) {
93  IDP_BlendWrite(writer, tref->properties);
94  }
95  }
96 }
97 
98 static void workspace_blend_read_data(BlendDataReader *reader, ID *id)
99 {
100  WorkSpace *workspace = (WorkSpace *)id;
101 
102  BLO_read_list(reader, &workspace->layouts);
103  BLO_read_list(reader, &workspace->hook_layout_relations);
104  BLO_read_list(reader, &workspace->owner_ids);
105  BLO_read_list(reader, &workspace->tools);
106 
108  /* parent pointer does not belong to workspace data and is therefore restored in lib_link step
109  * of window manager.*/
110  BLO_read_data_address(reader, &relation->value);
111  }
112 
113  LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
114  tref->runtime = NULL;
115  BLO_read_data_address(reader, &tref->properties);
116  IDP_BlendDataRead(reader, &tref->properties);
117  }
118 
119  workspace->status_text = NULL;
120 
121  id_us_ensure_real(&workspace->id);
122 }
123 
124 static void workspace_blend_read_lib(BlendLibReader *reader, ID *id)
125 {
126  WorkSpace *workspace = (WorkSpace *)id;
127  Main *bmain = BLO_read_lib_get_main(reader);
128 
129  /* Restore proper 'parent' pointers to relevant data, and clean up unused/invalid entries. */
131  relation->parent = NULL;
132  LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
133  LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
134  if (win->winid == relation->parentid) {
135  relation->parent = win->workspace_hook;
136  }
137  }
138  }
139  if (relation->parent == NULL) {
140  BLI_freelinkN(&workspace->hook_layout_relations, relation);
141  }
142  }
143 
144  LISTBASE_FOREACH_MUTABLE (WorkSpaceLayout *, layout, &workspace->layouts) {
145  BLO_read_id_address(reader, id->lib, &layout->screen);
146 
147  if (layout->screen) {
148  if (ID_IS_LINKED(id)) {
149  layout->screen->winid = 0;
150  if (layout->screen->temp) {
151  /* delete temp layouts when appending */
152  BKE_workspace_layout_remove(bmain, workspace, layout);
153  }
154  }
155  }
156  else {
157  /* If we're reading a layout without screen stored, it's useless and we shouldn't keep it
158  * around. */
159  BKE_workspace_layout_remove(bmain, workspace, layout);
160  }
161  }
162 }
163 
164 static void workspace_blend_read_expand(BlendExpander *expander, ID *id)
165 {
166  WorkSpace *workspace = (WorkSpace *)id;
167 
168  LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) {
169  BLO_expand(expander, BKE_workspace_layout_screen_get(layout));
170  }
171 }
172 
174  .id_code = ID_WS,
175  .id_filter = FILTER_ID_WS,
176  .main_listbase_index = INDEX_ID_WS,
177  .struct_size = sizeof(WorkSpace),
178  .name = "WorkSpace",
179  .name_plural = "workspaces",
180  .translation_context = BLT_I18NCONTEXT_ID_WORKSPACE,
182 
183  .init_data = NULL,
184  .copy_data = NULL,
185  .free_data = workspace_free_data,
186  .make_local = NULL,
187  .foreach_id = workspace_foreach_id,
188  .foreach_cache = NULL,
189  .owner_get = NULL,
190 
191  .blend_write = workspace_blend_write,
192  .blend_read_data = workspace_blend_read_data,
193  .blend_read_lib = workspace_blend_read_lib,
194  .blend_read_expand = workspace_blend_read_expand,
195 
196  .blend_read_undo_preserve = NULL,
197 
198  .lib_override_apply_post = NULL,
199 };
200 
201 /* -------------------------------------------------------------------- */
205 static void workspace_layout_name_set(WorkSpace *workspace,
206  WorkSpaceLayout *layout,
207  const char *new_name)
208 {
209  BLI_strncpy(layout->name, new_name, sizeof(layout->name));
210  BLI_uniquename(&workspace->layouts,
211  layout,
212  "Layout",
213  '.',
214  offsetof(WorkSpaceLayout, name),
215  sizeof(layout->name));
216 }
217 
224  const bScreen *screen)
225 {
226  return BLI_findptr(&workspace->layouts, screen, offsetof(WorkSpaceLayout, screen));
227 }
228 
229 static void workspace_relation_add(ListBase *relation_list,
230  void *parent,
231  const int parentid,
232  void *data)
233 {
234  WorkSpaceDataRelation *relation = MEM_callocN(sizeof(*relation), __func__);
235  relation->parent = parent;
236  relation->parentid = parentid;
237  relation->value = data;
238  /* add to head, if we switch back to it soon we find it faster. */
239  BLI_addhead(relation_list, relation);
240 }
241 static void workspace_relation_remove(ListBase *relation_list, WorkSpaceDataRelation *relation)
242 {
243  BLI_remlink(relation_list, relation);
244  MEM_freeN(relation);
245 }
246 
247 static void workspace_relation_ensure_updated(ListBase *relation_list,
248  void *parent,
249  const int parentid,
250  void *data)
251 {
253  relation_list, &parentid, sizeof(parentid), offsetof(WorkSpaceDataRelation, parentid));
254  if (relation != NULL) {
255  relation->parent = parent;
256  relation->value = data;
257  /* reinsert at the head of the list, so that more commonly used relations are found faster. */
258  BLI_remlink(relation_list, relation);
259  BLI_addhead(relation_list, relation);
260  }
261  else {
262  /* no matching relation found, add new one */
263  workspace_relation_add(relation_list, parent, parentid, data);
264  }
265 }
266 
267 static void *workspace_relation_get_data_matching_parent(const ListBase *relation_list,
268  const void *parent)
269 {
271  relation_list, parent, offsetof(WorkSpaceDataRelation, parent));
272  if (relation != NULL) {
273  return relation->value;
274  }
275 
276  return NULL;
277 }
278 
285 #ifndef NDEBUG
287 #else
289 #endif
290  (const Main *bmain, bScreen *screen)
291 {
292  for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
293  if (workspace_layout_find_exec(workspace, screen)) {
294  return true;
295  }
296  }
297 
298  return false;
299 }
300 
303 /* -------------------------------------------------------------------- */
307 WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
308 {
309  WorkSpace *new_workspace = BKE_id_new(bmain, ID_WS, name);
310  id_us_ensure_real(&new_workspace->id);
311  return new_workspace;
312 }
313 
321 void BKE_workspace_remove(Main *bmain, WorkSpace *workspace)
322 {
323  for (WorkSpaceLayout *layout = workspace->layouts.first, *layout_next; layout;
324  layout = layout_next) {
325  layout_next = layout->next;
326  BKE_workspace_layout_remove(bmain, workspace, layout);
327  }
328  BKE_id_free(bmain, workspace);
329 }
330 
332 {
333  WorkSpaceInstanceHook *hook = MEM_callocN(sizeof(WorkSpaceInstanceHook), __func__);
334 
335  /* set an active screen-layout for each possible window/workspace combination */
336  for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
337  BKE_workspace_active_layout_set(hook, winid, workspace, workspace->layouts.first);
338  }
339 
340  return hook;
341 }
343 {
344  /* workspaces should never be freed before wm (during which we call this function).
345  * However, when running in background mode, loading a blend file may allocate windows (that need
346  * to be freed) without creating workspaces. This happens in BlendfileLoadingBaseTest. */
347  BLI_assert(!BLI_listbase_is_empty(&bmain->workspaces) || G.background);
348 
349  /* Free relations for this hook */
350  for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
351  for (WorkSpaceDataRelation *relation = workspace->hook_layout_relations.first, *relation_next;
352  relation;
353  relation = relation_next) {
354  relation_next = relation->next;
355  if (relation->parent == hook) {
356  workspace_relation_remove(&workspace->hook_layout_relations, relation);
357  }
358  }
359  }
360 
361  MEM_freeN(hook);
362 }
363 
368  WorkSpace *workspace,
369  bScreen *screen,
370  const char *name)
371 {
372  WorkSpaceLayout *layout = MEM_callocN(sizeof(*layout), __func__);
373 
374  BLI_assert(!workspaces_is_screen_used(bmain, screen));
375 #ifndef DEBUG
376  UNUSED_VARS(bmain);
377 #endif
378  layout->screen = screen;
379  id_us_plus(&layout->screen->id);
380  workspace_layout_name_set(workspace, layout, name);
381  BLI_addtail(&workspace->layouts, layout);
382 
383  return layout;
384 }
385 
387 {
388  /* Screen should usually be set, but we call this from file reading to get rid of invalid
389  * layouts. */
390  if (layout->screen) {
391  id_us_min(&layout->screen->id);
392  BKE_id_free(bmain, layout->screen);
393  }
394  BLI_freelinkN(&workspace->layouts, layout);
395 }
396 
398 {
399  for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation;
400  relation = relation_next) {
401  relation_next = relation->next;
402  workspace_relation_remove(relation_list, relation);
403  }
404 }
405 
408 /* -------------------------------------------------------------------- */
413 {
414  WorkSpaceLayout *layout = workspace_layout_find_exec(workspace, screen);
415  if (layout) {
416  return layout;
417  }
418 
419  printf(
420  "%s: Couldn't find layout in this workspace: '%s' screen: '%s'. "
421  "This should not happen!\n",
422  __func__,
423  workspace->id.name + 2,
424  screen->id.name + 2);
425 
426  return NULL;
427 }
428 
437  const bScreen *screen,
438  WorkSpace **r_workspace)
439 {
440  WorkSpaceLayout *layout;
441 
442  if (r_workspace) {
443  *r_workspace = NULL;
444  }
445 
446  for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
447  if ((layout = workspace_layout_find_exec(workspace, screen))) {
448  if (r_workspace) {
449  *r_workspace = workspace;
450  }
451 
452  return layout;
453  }
454  }
455 
456  return NULL;
457 }
458 
469  WorkSpaceLayout *start,
470  bool (*callback)(const WorkSpaceLayout *layout,
471  void *arg),
472  void *arg,
473  const bool iter_backward)
474 {
475  WorkSpaceLayout *iter_layout;
476 
477  if (iter_backward) {
478  LISTBASE_CIRCULAR_BACKWARD_BEGIN (&workspace->layouts, iter_layout, start) {
479  if (!callback(iter_layout, arg)) {
480  return iter_layout;
481  }
482  }
483  LISTBASE_CIRCULAR_BACKWARD_END(&workspace->layouts, iter_layout, start);
484  }
485  else {
486  LISTBASE_CIRCULAR_FORWARD_BEGIN (&workspace->layouts, iter_layout, start) {
487  if (!callback(iter_layout, arg)) {
488  return iter_layout;
489  }
490  }
491  LISTBASE_CIRCULAR_FORWARD_END(&workspace->layouts, iter_layout, start);
492  }
493 
494  return NULL;
495 }
496 
497 void BKE_workspace_tool_remove(struct WorkSpace *workspace, struct bToolRef *tref)
498 {
499  if (tref->runtime) {
500  MEM_freeN(tref->runtime);
501  }
502  if (tref->properties) {
504  }
505  BLI_remlink(&workspace->tools, tref);
506  MEM_freeN(tref);
507 }
508 
509 bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_id)
510 {
511  if ((*owner_id == '\0') || ((workspace->flags & WORKSPACE_USE_FILTER_BY_ORIGIN) == 0)) {
512  return true;
513  }
514 
515  /* We could use hash lookup, for now this list is highly likely under < ~16 items. */
516  return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL;
517 }
518 
520 {
521  BKE_main_id_tag_listbase(&bmain->workspaces, tag, false);
522  wmWindowManager *wm = bmain->wm.first;
523  LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
524  WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
525  workspace->id.tag |= tag;
526  }
527 }
528 
531 /* -------------------------------------------------------------------- */
536 {
537  return hook->active;
538 }
540 {
541  /* DO NOT check for `hook->active == workspace` here. Caller code is supposed to do it if
542  * that optimization is possible and needed.
543  * This code can be called from places where we might have this equality, but still want to
544  * ensure/update the active layout below.
545  * Known case where this is buggy and will crash later due to NULL active layout: reading
546  * a blend file, when the new read workspace ID happens to have the exact same memory address
547  * as when it was saved in the blend file (extremely unlikely, but possible). */
548 
549  hook->active = workspace;
550  if (workspace) {
552  &workspace->hook_layout_relations, hook);
553  if (layout) {
554  hook->act_layout = layout;
555  }
556  }
557 }
558 
564 {
565  return hook->act_layout;
566 }
567 
572  const WorkSpace *workspace)
573 {
574  /* If the workspace is active, the active layout can be returned, no need for a lookup. */
575  if (hook->active == workspace) {
576  return hook->act_layout;
577  }
578 
579  /* Inactive workspace */
581 }
582 
595  const int winid,
596  WorkSpace *workspace,
597  WorkSpaceLayout *layout)
598 {
599  hook->act_layout = layout;
600  workspace_relation_ensure_updated(&workspace->hook_layout_relations, hook, winid, layout);
601 }
602 
604 {
605  return hook->act_layout->screen;
606 }
608  const int winid,
609  WorkSpace *workspace,
610  bScreen *screen)
611 {
612  /* we need to find the WorkspaceLayout that wraps this screen */
613  WorkSpaceLayout *layout = BKE_workspace_layout_find(hook->active, screen);
614  BKE_workspace_active_layout_set(hook, winid, workspace, layout);
615 }
616 
618 {
619  return layout->name;
620 }
622  WorkSpaceLayout *layout,
623  const char *new_name)
624 {
625  workspace_layout_name_set(workspace, layout, new_name);
626 }
627 
629 {
630  return layout->screen;
631 }
632 
void IDP_BlendWrite(struct BlendWriter *writer, const struct IDProperty *prop)
#define IDP_BlendDataRead(reader, prop)
Definition: BKE_idprop.h:208
void IDP_FreeProperty(struct IDProperty *prop)
Definition: idprop.c:1040
@ IDTYPE_FLAGS_NO_MAKELOCAL
Definition: BKE_idtype.h:49
@ IDTYPE_FLAGS_NO_ANIMDATA
Definition: BKE_idtype.h:51
@ IDTYPE_FLAGS_NO_COPY
Definition: BKE_idtype.h:45
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void BKE_id_free(struct Main *bmain, void *idv)
void id_us_ensure_real(struct ID *id)
Definition: lib_id.c:238
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
Definition: lib_id.c:2395
void BKE_main_id_tag_listbase(struct ListBase *lb, const int tag, const bool value)
Definition: lib_id.c:891
void * BKE_id_new(struct Main *bmain, const short type, const char *name)
Definition: lib_id.c:1177
#define BKE_LIB_FOREACHID_PROCESS(_data, _id_super, _cb_flag)
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
General operations, lookup, etc. for blender objects.
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:87
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
#define LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init)
Definition: BLI_listbase.h:150
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:188
#define LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init)
Definition: BLI_listbase.h:154
void * BLI_listbase_bytes_find(const ListBase *listbase, const void *bytes, const size_t bytes_size, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
#define LISTBASE_CIRCULAR_BACKWARD_BEGIN(lb, lb_iter, lb_init)
Definition: BLI_listbase.h:161
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
#define LISTBASE_CIRCULAR_BACKWARD_END(lb, lb_iter, lb_init)
Definition: BLI_listbase.h:165
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t len)
Definition: string_utils.c:381
#define UNUSED_FUNCTION(x)
#define UNUSED_VARS(...)
#define BLO_read_data_address(reader, ptr_p)
struct Main * BLO_read_lib_get_main(BlendLibReader *reader)
Definition: readfile.c:5795
#define BLO_write_id_struct(writer, struct_name, id_address, id)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5654
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define BLO_expand(expander, id)
#define BLO_write_struct_list(writer, struct_name, list_ptr)
#define BLT_I18NCONTEXT_ID_WORKSPACE
#define FILTER_ID_WS
Definition: DNA_ID.h:734
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
@ INDEX_ID_WS
Definition: DNA_ID.h:854
@ ID_WS
Definition: DNA_ID_enums.h:91
Object is a sort of wrapper for general info.
@ WORKSPACE_USE_FILTER_BY_ORIGIN
struct WorkSpace WorkSpace
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static void init_data(ModifierData *md)
DEGForeachIDComponentCallback callback
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
short id_code
Definition: BKE_idtype.h:120
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
struct Library * lib
Definition: DNA_ID.h:277
void * next
Definition: DNA_ID.h:274
char name[66]
Definition: DNA_ID.h:283
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase wm
Definition: BKE_main.h:175
ListBase workspaces
Definition: BKE_main.h:181
struct WorkSpaceLayout * act_layout
Wrapper for bScreen.
struct bScreen * screen
ListBase owner_ids
ListBase hook_layout_relations
IDProperty * properties
bToolRef_Runtime * runtime
#define G(x, y, z)
bScreen * BKE_workspace_layout_screen_get(const WorkSpaceLayout *layout)
Definition: workspace.c:628
bScreen * BKE_workspace_active_screen_get(const WorkSpaceInstanceHook *hook)
Definition: workspace.c:603
static void workspace_relation_ensure_updated(ListBase *relation_list, void *parent, const int parentid, void *data)
Definition: workspace.c:247
void BKE_workspace_tool_remove(struct WorkSpace *workspace, struct bToolRef *tref)
Definition: workspace.c:497
IDTypeInfo IDType_ID_WS
Definition: workspace.c:173
static void workspace_relation_remove(ListBase *relation_list, WorkSpaceDataRelation *relation)
Definition: workspace.c:241
static void workspace_blend_read_expand(BlendExpander *expander, ID *id)
Definition: workspace.c:164
static void workspace_free_data(ID *id)
Definition: workspace.c:56
static void workspace_layout_name_set(WorkSpace *workspace, WorkSpaceLayout *layout, const char *new_name)
Definition: workspace.c:205
static void workspace_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition: workspace.c:81
static bool workspaces_is_screen_used(const Main *bmain, bScreen *screen)
Definition: workspace.c:290
WorkSpaceLayout * BKE_workspace_layout_add(Main *bmain, WorkSpace *workspace, bScreen *screen, const char *name)
Definition: workspace.c:367
void BKE_workspace_layout_remove(Main *bmain, WorkSpace *workspace, WorkSpaceLayout *layout)
Definition: workspace.c:386
static void workspace_foreach_id(ID *id, LibraryForeachIDData *data)
Definition: workspace.c:72
WorkSpace * BKE_workspace_active_get(WorkSpaceInstanceHook *hook)
Definition: workspace.c:535
bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_id)
Definition: workspace.c:509
WorkSpaceLayout * BKE_workspace_layout_iter_circular(const WorkSpace *workspace, WorkSpaceLayout *start, bool(*callback)(const WorkSpaceLayout *layout, void *arg), void *arg, const bool iter_backward)
Definition: workspace.c:468
void BKE_workspace_active_screen_set(WorkSpaceInstanceHook *hook, const int winid, WorkSpace *workspace, bScreen *screen)
Definition: workspace.c:607
static void * workspace_relation_get_data_matching_parent(const ListBase *relation_list, const void *parent)
Definition: workspace.c:267
WorkSpaceLayout * BKE_workspace_layout_find(const WorkSpace *workspace, const bScreen *screen)
Definition: workspace.c:412
WorkSpaceLayout * BKE_workspace_active_layout_for_workspace_get(const WorkSpaceInstanceHook *hook, const WorkSpace *workspace)
Definition: workspace.c:571
static void workspace_relation_add(ListBase *relation_list, void *parent, const int parentid, void *data)
Definition: workspace.c:229
void BKE_workspace_instance_hook_free(const Main *bmain, WorkSpaceInstanceHook *hook)
Definition: workspace.c:342
static WorkSpaceLayout * workspace_layout_find_exec(const WorkSpace *workspace, const bScreen *screen)
Definition: workspace.c:223
void BKE_workspace_active_set(WorkSpaceInstanceHook *hook, WorkSpace *workspace)
Definition: workspace.c:539
WorkSpaceLayout * BKE_workspace_active_layout_get(const WorkSpaceInstanceHook *hook)
Definition: workspace.c:563
void BKE_workspace_id_tag_all_visible(Main *bmain, int tag)
Definition: workspace.c:519
WorkSpaceInstanceHook * BKE_workspace_instance_hook_create(const Main *bmain, const int winid)
Definition: workspace.c:331
void BKE_workspace_relations_free(ListBase *relation_list)
Definition: workspace.c:397
void BKE_workspace_remove(Main *bmain, WorkSpace *workspace)
Definition: workspace.c:321
void BKE_workspace_active_layout_set(WorkSpaceInstanceHook *hook, const int winid, WorkSpace *workspace, WorkSpaceLayout *layout)
Activate a layout.
Definition: workspace.c:594
const char * BKE_workspace_layout_name_get(const WorkSpaceLayout *layout)
Definition: workspace.c:617
static void workspace_blend_read_data(BlendDataReader *reader, ID *id)
Definition: workspace.c:98
WorkSpaceLayout * BKE_workspace_layout_find_global(const Main *bmain, const bScreen *screen, WorkSpace **r_workspace)
Definition: workspace.c:436
static void workspace_blend_read_lib(BlendLibReader *reader, ID *id)
Definition: workspace.c:124
void BKE_workspace_layout_name_set(WorkSpace *workspace, WorkSpaceLayout *layout, const char *new_name)
Definition: workspace.c:621
WorkSpace * BKE_workspace_add(Main *bmain, const char *name)
Definition: workspace.c:307