Workspaces: Store an active view-layer per scene

Instead of storing a single active view-layer in the workspace, one is
stored for each scene the workspace showed before.
With this, some things become possible:
* Multiple windows in the same workspace but showing different scenes.
* Toggling back and forth scene keeps same active view-layer for each scene.
* Activating workspace which didn't show current scene before, the current view-layer is kept.

A necessary evil for this is that accessing view-layer and object mode
from .py can't be done via workspace directly anymore. It has to be done
through the window, so RNA can use the correct scene.
So instead of `workspace.view_layer`, it's `window.view_layer` now (same
with mode) even though it's still workspace data.

Fixes T53432.
This commit is contained in:
Julian Eisel
2017-12-01 15:47:24 +01:00
parent 983b1a3478
commit e8c15e0ed1
16 changed files with 204 additions and 124 deletions

View File

@@ -48,15 +48,16 @@ class INFO_HT_header(Header):
layout.template_ID(window, "workspace", new="workspace.workspace_add_menu", unlink="workspace.workspace_delete")
layout.template_search_preview(window, "screen", workspace, "screens", new="screen.new", unlink="screen.delete", rows=2, cols=6)
if hasattr(workspace, 'object_mode'):
act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[workspace.object_mode]
if hasattr(window, 'object_mode'):
act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[window.object_mode]
else:
act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[layer.objects.active.mode]
layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon)
row = layout.row()
row.active = not workspace.use_scene_settings
row.template_search(workspace, "view_layer", scene, "view_layers")
# Active workspace view-layer is retrieved through window, not through workspace.
row.template_search(window, "view_layer", scene, "view_layers")
if view_render.has_multiple_engines:
row.prop(view_render, "engine", text="")

View File

@@ -32,6 +32,7 @@ struct EvaluationContext;
struct Main;
struct Scene;
struct TransformOrientation;
struct ViewLayer;
/**
* Plan is to store the object-mode per workspace, not per object anymore.
@@ -62,10 +63,17 @@ void BKE_workspace_layout_remove(
struct Main *bmain,
struct WorkSpace *workspace, struct WorkSpaceLayout *layout) ATTR_NONNULL();
void BKE_workspace_relations_free(
ListBase *relation_list);
/* -------------------------------------------------------------------- */
/* General Utils */
void BKE_workspace_view_layer_remove_references(
const struct Main *bmain,
const struct ViewLayer *view_layer) ATTR_NONNULL();
void BKE_workspace_transform_orientation_remove(
struct WorkSpace *workspace, struct TransformOrientation *orientation) ATTR_NONNULL();
struct TransformOrientation *BKE_workspace_transform_orientation_find(
@@ -98,14 +106,24 @@ void BKE_workspace_active_layout_set(struct WorkSpaceInstanceHook *h
struct bScreen *BKE_workspace_active_screen_get(const struct WorkSpaceInstanceHook *hook) GETTER_ATTRS;
void BKE_workspace_active_screen_set(
struct WorkSpaceInstanceHook *hook, struct WorkSpace *workspace, struct bScreen *screen) SETTER_ATTRS;
enum eObjectMode BKE_workspace_object_mode_get(const struct WorkSpace *workspace) GETTER_ATTRS;
#ifdef USE_WORKSPACE_MODE
void BKE_workspace_object_mode_set(struct WorkSpace *workspace, const enum eObjectMode mode) SETTER_ATTRS;
enum eObjectMode BKE_workspace_object_mode_get(
const struct WorkSpace *workspace,
const struct Scene *scene) GETTER_ATTRS;
void BKE_workspace_object_mode_set(
struct WorkSpace *workspace,
struct Scene *scene,
const enum eObjectMode mode) SETTER_ATTRS;
#endif
struct Base *BKE_workspace_active_base_get(const struct WorkSpace *workspace);
struct Base *BKE_workspace_active_base_get(const struct WorkSpace *workspace, const struct Scene *scene);
struct ListBase *BKE_workspace_transform_orientations_get(struct WorkSpace *workspace) GETTER_ATTRS;
struct ViewLayer *BKE_workspace_view_layer_get(const struct WorkSpace *workspace) GETTER_ATTRS;
void BKE_workspace_view_layer_set(struct WorkSpace *workspace, struct ViewLayer *layer) SETTER_ATTRS;
struct ViewLayer *BKE_workspace_view_layer_get(
const struct WorkSpace *workspace,
const struct Scene *scene) GETTER_ATTRS;
void BKE_workspace_view_layer_set(
struct WorkSpace *workspace,
struct ViewLayer *layer,
struct Scene *scene) SETTER_ATTRS;
struct ListBase *BKE_workspace_layouts_get(struct WorkSpace *workspace) GETTER_ATTRS;
const char *BKE_workspace_layout_name_get(const struct WorkSpaceLayout *layout) GETTER_ATTRS;

View File

@@ -89,7 +89,7 @@ ViewLayer *BKE_view_layer_from_workspace_get(const struct Scene *scene, const st
return BKE_view_layer_from_scene_get(scene);
}
else {
return BKE_workspace_view_layer_get(workspace);
return BKE_workspace_view_layer_get(workspace, scene);
}
}

View File

@@ -113,6 +113,18 @@ static void *workspace_relation_get_data_matching_parent(
}
}
static void workspace_relation_remove_from_value(
ListBase *relation_list, const void *value)
{
for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) {
relation_next = relation->next;
if (relation->value == value) {
workspace_relation_remove(relation_list, relation);
}
}
}
/**
* Checks if \a screen is already used within any workspace. A screen should never be assigned to multiple
* WorkSpaceLayouts, but that should be ensured outside of the BKE_workspace module and without such checks.
@@ -151,15 +163,12 @@ WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
*/
void BKE_workspace_free(WorkSpace *workspace)
{
for (WorkSpaceDataRelation *relation = workspace->hook_layout_relations.first, *relation_next;
relation;
relation = relation_next)
{
relation_next = relation->next;
workspace_relation_remove(&workspace->hook_layout_relations, relation);
}
BKE_workspace_relations_free(&workspace->hook_layout_relations);
BKE_workspace_relations_free(&workspace->scene_viewlayer_relations);
BLI_freelistN(&workspace->layouts);
BLI_freelistN(&workspace->transform_orientations);
BKE_viewrender_free(&workspace->view_render);
}
@@ -237,9 +246,28 @@ void BKE_workspace_layout_remove(
BLI_freelinkN(&workspace->layouts, layout);
}
void BKE_workspace_relations_free(
ListBase *relation_list)
{
for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) {
relation_next = relation->next;
workspace_relation_remove(relation_list, relation);
}
}
/* -------------------------------------------------------------------- */
/* General Utils */
void BKE_workspace_view_layer_remove_references(
const Main *bmain,
const ViewLayer *view_layer)
{
for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
workspace_relation_remove_from_value(&workspace->scene_viewlayer_relations, view_layer);
}
}
void BKE_workspace_transform_orientation_remove(
WorkSpace *workspace, TransformOrientation *orientation)
{
@@ -386,23 +414,24 @@ void BKE_workspace_active_screen_set(WorkSpaceInstanceHook *hook, WorkSpace *wor
}
#ifdef USE_WORKSPACE_MODE
eObjectMode BKE_workspace_object_mode_get(const WorkSpace *workspace)
eObjectMode BKE_workspace_object_mode_get(const WorkSpace *workspace, const Scene *scene)
{
Base *active_base = BKE_workspace_active_base_get(workspace);
Base *active_base = BKE_workspace_active_base_get(workspace, scene);
return active_base ? active_base->object->mode : OB_MODE_OBJECT;
}
void BKE_workspace_object_mode_set(WorkSpace *workspace, const eObjectMode mode)
void BKE_workspace_object_mode_set(WorkSpace *workspace, Scene *scene, const eObjectMode mode)
{
Base *active_base = BKE_workspace_active_base_get(workspace);
Base *active_base = BKE_workspace_active_base_get(workspace, scene);
if (active_base) {
active_base->object->mode = mode;
}
}
#endif
Base *BKE_workspace_active_base_get(const WorkSpace *workspace)
Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *scene)
{
return workspace->view_layer->basact;
ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
return view_layer->basact;
}
ListBase *BKE_workspace_transform_orientations_get(WorkSpace *workspace)
@@ -410,13 +439,14 @@ ListBase *BKE_workspace_transform_orientations_get(WorkSpace *workspace)
return &workspace->transform_orientations;
}
ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace)
ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace, const Scene *scene)
{
return workspace->view_layer;
return workspace_relation_get_data_matching_parent(&workspace->scene_viewlayer_relations, scene);
}
void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer)
void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer, Scene *scene)
{
workspace->view_layer = layer;
workspace_relation_ensure_updated(&workspace->scene_viewlayer_relations, scene, layer);
}
ListBase *BKE_workspace_layouts_get(WorkSpace *workspace)
@@ -486,7 +516,7 @@ void BKE_workspace_update_tagged(struct EvaluationContext *eval_ctx,
WorkSpace *workspace,
Scene *scene)
{
ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace);
ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
struct Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene,
view_layer,
true);

View File

@@ -2843,6 +2843,14 @@ static void lib_link_workspaces(FileData *fd, Main *bmain)
IDP_LibLinkProperty(id->properties, fd);
id_us_ensure_real(id);
for (WorkSpaceDataRelation *relation = workspace->scene_viewlayer_relations.first;
relation != NULL;
relation = relation->next)
{
relation->parent = newlibadr(fd, id->lib, relation->parent);
/* relation->value is set in direct_link_workspace_link_scene_data */
}
for (WorkSpaceLayout *layout = layouts->first, *layout_next; layout; layout = layout_next) {
bScreen *screen = newlibadr(fd, id->lib, BKE_workspace_layout_screen_get(layout));
@@ -2868,6 +2876,7 @@ static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main
{
link_list(fd, BKE_workspace_layouts_get(workspace));
link_list(fd, &workspace->hook_layout_relations);
link_list(fd, &workspace->scene_viewlayer_relations);
link_list(fd, BKE_workspace_transform_orientations_get(workspace));
for (WorkSpaceDataRelation *relation = workspace->hook_layout_relations.first;
@@ -2881,7 +2890,7 @@ static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main
if (ID_IS_LINKED(&workspace->id)) {
/* Appending workspace so render layer is likely from a different scene. Unset
* now, when activating workspace later we set a valid one from current scene. */
BKE_workspace_view_layer_set(workspace, NULL);
BKE_workspace_relations_free(&workspace->scene_viewlayer_relations);
}
/* Same issue/fix as in direct_link_workspace_link_scene_data: Can't read workspace data
@@ -6134,13 +6143,19 @@ static void direct_link_layer_collections(FileData *fd, ListBase *lb)
* Workspaces store a render layer pointer which can only be read after scene is read.
*/
static void direct_link_workspace_link_scene_data(
FileData *fd, const Scene *scene, const ListBase *workspaces)
FileData *fd, Scene *scene, const ListBase *workspaces)
{
for (WorkSpace *workspace = workspaces->first; workspace; workspace = workspace->id.next) {
ViewLayer *layer = newdataadr(fd, BKE_workspace_view_layer_get(workspace));
/* only set when layer is from the scene we read */
if (layer && (BLI_findindex(&scene->view_layers, layer) != -1)) {
BKE_workspace_view_layer_set(workspace, layer);
for (WorkSpaceDataRelation *relation = workspace->scene_viewlayer_relations.first;
relation != NULL;
relation = relation->next)
{
ViewLayer *layer = newdataadr(fd, relation->value);
if (layer) {
BLI_assert(BLI_findindex(&scene->view_layers, layer) != -1);
/* relation->parent is set in lib_link_workspaces */
relation->value = layer;
}
}
}
}
@@ -7175,7 +7190,7 @@ void blo_lib_link_restore(Main *newmain, wmWindowManager *curwm, Scene *curscene
for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) {
lib_link_workspace_layout_restore(id_map, newmain, layout);
}
BKE_workspace_view_layer_set(workspace, cur_view_layer);
BKE_workspace_view_layer_set(workspace, cur_view_layer, curscene);
}
for (wmWindow *win = curwm->windows.first; win; win = win->next) {

View File

@@ -86,8 +86,9 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
{
for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
const bScreen *screen_parent = screen_parent_find(screen);
Scene *scene = screen->scene;
WorkSpace *workspace;
ViewLayer *layer = BKE_view_layer_from_scene_get(screen->scene);
ViewLayer *layer = BKE_view_layer_from_scene_get(scene);
ListBase *transform_orientations;
if (screen_parent) {
@@ -100,7 +101,7 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
workspace = BKE_workspace_add(bmain, screen->id.name + 2);
}
BKE_workspace_layout_add(workspace, screen, screen->id.name + 2);
BKE_workspace_view_layer_set(workspace, layer);
BKE_workspace_view_layer_set(workspace, layer, scene);
#ifdef WITH_CLAY_ENGINE
BLI_strncpy(workspace->view_render.engine_id, RE_engine_id_BLENDER_CLAY,
@@ -111,7 +112,7 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
#endif
transform_orientations = BKE_workspace_transform_orientations_get(workspace);
BLI_duplicatelist(transform_orientations, &screen->scene->transform_spaces);
BLI_duplicatelist(transform_orientations, &scene->transform_spaces);
}
}

View File

@@ -1138,7 +1138,7 @@ static void current_screen_compat(
*r_screen = (window) ? BKE_workspace_active_screen_get(window->workspace_hook) : NULL;
*r_scene = (window) ? window->scene : NULL;
*r_render_layer = (window) ? BKE_workspace_view_layer_get(workspace) : NULL;
*r_render_layer = (window) ? BKE_workspace_view_layer_get(workspace, *r_scene) : NULL;
}
typedef struct RenderInfo {
@@ -3778,6 +3778,7 @@ static void write_workspace(WriteData *wd, WorkSpace *workspace)
writestruct(wd, ID_WS, WorkSpace, 1, workspace);
writelist(wd, DATA, WorkSpaceLayout, layouts);
writelist(wd, DATA, WorkSpaceDataRelation, &workspace->hook_layout_relations);
writelist(wd, DATA, WorkSpaceDataRelation, &workspace->scene_viewlayer_relations);
writelist(wd, DATA, TransformOrientation, transform_orientations);
}

View File

@@ -136,6 +136,7 @@ void ED_screen_preview_render(const struct bScreen *screen, int size_x, int s
struct WorkSpace *ED_workspace_add(
struct Main *bmain,
const char *name,
Scene *scene,
ViewLayer *act_render_layer,
struct ViewRender *view_render) ATTR_NONNULL();
bool ED_workspace_change(
@@ -152,7 +153,8 @@ bool ED_workspace_delete(
void ED_workspace_scene_data_sync(
struct WorkSpaceInstanceHook *hook, Scene *scene) ATTR_NONNULL();
void ED_workspace_view_layer_unset(
const struct Main *bmain, const ViewLayer *layer_unset, ViewLayer *layer_new) ATTR_NONNULL(1, 2);
const struct Main *bmain, struct Scene *scene,
const ViewLayer *layer_unset, ViewLayer *layer_new) ATTR_NONNULL(1, 2);
struct WorkSpaceLayout *ED_workspace_layout_add(
struct WorkSpace *workspace,
struct wmWindow *win,

View File

@@ -1516,15 +1516,13 @@ bool ED_object_mode_compat_set(bContext *C, Object *ob, int mode, ReportList *re
{
bool ok;
if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) {
WorkSpace *workspace = CTX_wm_workspace(C);
const char *opstring = object_mode_op_string(ob->mode);
WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL);
#ifdef USE_WORKSPACE_MODE
BKE_workspace_object_mode_set(workspace, ob->mode);
#else
UNUSED_VARS(workspace);
BKE_workspace_object_mode_set(CTX_wm_workspace(C), CTX_data_scene(C), ob->mode);
#endif
ok = ELEM(ob->mode, mode, OB_MODE_OBJECT);
if (!ok) {
wmOperatorType *ot = WM_operatortype_find(opstring, false);
@@ -1648,7 +1646,7 @@ void ED_object_toggle_modes(bContext *C, int mode)
#ifdef USE_WORKSPACE_MODE
Object *ob = CTX_data_active_object(C);
if (ob) {
BKE_workspace_object_mode_set(workspace, ob->mode);
BKE_workspace_object_mode_set(workspace, CTX_data_scene(C), ob->mode);
}
#endif
}

View File

@@ -123,8 +123,7 @@ void ED_object_base_activate(bContext *C, Base *base)
if (base) {
#ifdef USE_WORKSPACE_MODE
WorkSpace *workspace = CTX_wm_workspace(C);
BKE_workspace_object_mode_set(workspace, base->object->mode);
BKE_workspace_object_mode_set(CTX_wm_workspace(C), CTX_data_scene(C), base->object->mode);
#endif
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, view_layer);
}

View File

@@ -118,16 +118,20 @@ void ED_scene_exit(bContext *C)
ED_object_editmode_exit(C, EM_FREEDATA | EM_DO_UNDO);
}
static ViewLayer *scene_change_get_new_view_layer(const WorkSpace *workspace, const Scene *scene_new)
{
ViewLayer *layer_new = BKE_workspace_view_layer_get(workspace, scene_new);
return layer_new ? layer_new : BKE_view_layer_from_scene_get(scene_new);
}
void ED_scene_changed_update(Main *bmain, bContext *C, Scene *scene_new, const bScreen *active_screen)
{
/* XXX Just using active scene render-layer for workspace when switching,
* but workspace should remember the last one set. Could store render-layer
* per window-workspace combination (using WorkSpaceDataRelation) */
ViewLayer *layer_new = BLI_findlink(&scene_new->view_layers, scene_new->active_view_layer);
WorkSpace *workspace = CTX_wm_workspace(C);
ViewLayer *layer_new = scene_change_get_new_view_layer(workspace, scene_new);
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene_new, layer_new, true);
CTX_data_scene_set(C, scene_new);
BKE_workspace_view_layer_set(CTX_wm_workspace(C), layer_new);
BKE_workspace_view_layer_set(workspace, layer_new, scene_new);
BKE_scene_set_background(bmain, scene_new);
DEG_graph_relations_update(depsgraph, bmain, scene_new, layer_new);
DEG_on_visible_update(bmain, false);
@@ -186,7 +190,8 @@ bool ED_scene_view_layer_delete(
BLI_assert(BLI_listbase_is_empty(&scene->view_layers) == false);
scene->active_view_layer = 0;
ED_workspace_view_layer_unset(bmain, layer, scene->view_layers.first);
ED_workspace_view_layer_unset(bmain, scene, layer, scene->view_layers.first);
BKE_workspace_view_layer_remove_references(bmain, layer);
view_layer_remove_unset_nodetrees(bmain, scene, layer);
BKE_view_layer_free(layer);

View File

@@ -91,7 +91,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace);
Object *obedit = scene->obedit;
Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL;
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, screen_context_dir);

View File

@@ -71,15 +71,16 @@
* \{ */
WorkSpace *ED_workspace_add(
Main *bmain, const char *name, ViewLayer *act_view_layer, ViewRender *view_render)
Main *bmain, const char *name, Scene *scene,
ViewLayer *act_view_layer, ViewRender *view_render)
{
WorkSpace *workspace = BKE_workspace_add(bmain, name);
BKE_workspace_view_layer_set(workspace, act_view_layer);
BKE_workspace_view_layer_set(workspace, act_view_layer, scene);
BKE_viewrender_copy(&workspace->view_render, view_render);
#ifdef USE_WORKSPACE_MODE
BKE_workspace_object_mode_set(workspace, OB_MODE_OBJECT);
BKE_workspace_object_mode_set(workspace, scene, OB_MODE_OBJECT);
#endif
return workspace;
@@ -94,8 +95,9 @@ static void workspace_change_update_mode(
const WorkSpace *workspace_old, const WorkSpace *workspace_new,
bContext *C, Object *ob_act, ReportList *reports)
{
eObjectMode mode_old = BKE_workspace_object_mode_get(workspace_old);
eObjectMode mode_new = BKE_workspace_object_mode_get(workspace_new);
const Scene *scene = CTX_data_scene(C);
eObjectMode mode_old = BKE_workspace_object_mode_get(workspace_old, scene);
eObjectMode mode_new = BKE_workspace_object_mode_get(workspace_new, scene);
if (mode_old != mode_new) {
ED_object_mode_compat_set(C, ob_act, mode_new, reports);
@@ -105,10 +107,11 @@ static void workspace_change_update_mode(
#endif
static void workspace_change_update_view_layer(
WorkSpace *workspace_new, const WorkSpace *workspace_old)
WorkSpace *workspace_new, const WorkSpace *workspace_old,
Scene *scene)
{
if (!BKE_workspace_view_layer_get(workspace_new)) {
BKE_workspace_view_layer_set(workspace_new, BKE_workspace_view_layer_get(workspace_old));
if (!BKE_workspace_view_layer_get(workspace_new, scene)) {
BKE_workspace_view_layer_set(workspace_new, BKE_workspace_view_layer_get(workspace_old, scene), scene);
}
}
@@ -117,7 +120,7 @@ static void workspace_change_update(
bContext *C, wmWindowManager *wm)
{
/* needs to be done before changing mode! (to ensure right context) */
workspace_change_update_view_layer(workspace_new, workspace_old);
workspace_change_update_view_layer(workspace_new, workspace_old, CTX_data_scene(C));
#ifdef USE_WORKSPACE_MODE
workspace_change_update_mode(workspace_old, workspace_new, C, CTX_data_active_object(C), &wm->reports);
#else
@@ -199,7 +202,7 @@ bool ED_workspace_change(
screen_changed_update(C, win, screen_new);
workspace_change_update(workspace_new, workspace_old, C, wm);
BLI_assert(BKE_workspace_view_layer_get(workspace_new) != NULL);
BLI_assert(BKE_workspace_view_layer_get(workspace_new, CTX_data_scene(C)) != NULL);
BLI_assert(CTX_wm_workspace(C) == workspace_new);
WM_toolsystem_unlink(C, workspace_old);
@@ -220,15 +223,16 @@ WorkSpace *ED_workspace_duplicate(
{
WorkSpaceLayout *layout_active_old = BKE_workspace_active_layout_get(win->workspace_hook);
ListBase *layouts_old = BKE_workspace_layouts_get(workspace_old);
Scene *scene = WM_window_get_active_scene(win);
WorkSpace *workspace_new = ED_workspace_add(
bmain, workspace_old->id.name + 2,
BKE_workspace_view_layer_get(workspace_old),
bmain, workspace_old->id.name + 2, scene,
BKE_workspace_view_layer_get(workspace_old, scene),
&workspace_old->view_render);
ListBase *transform_orientations_old = BKE_workspace_transform_orientations_get(workspace_old);
ListBase *transform_orientations_new = BKE_workspace_transform_orientations_get(workspace_new);
#ifdef USE_WORKSPACE_MODE
BKE_workspace_object_mode_set(workspace_new, BKE_workspace_object_mode_get(workspace_old));
BKE_workspace_object_mode_set(workspace_new, scene, BKE_workspace_object_mode_get(workspace_old, scene));
#endif
BLI_duplicatelist(transform_orientations_new, transform_orientations_old);
@@ -279,11 +283,12 @@ void ED_workspace_scene_data_sync(
}
void ED_workspace_view_layer_unset(
const Main *bmain, const ViewLayer *layer_unset, ViewLayer *layer_new)
const Main *bmain, Scene *scene,
const ViewLayer *layer_unset, ViewLayer *layer_new)
{
for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
if (BKE_workspace_view_layer_get(workspace) == layer_unset) {
BKE_workspace_view_layer_set(workspace, layer_new);
if (BKE_workspace_view_layer_get(workspace, scene) == layer_unset) {
BKE_workspace_view_layer_set(workspace, layer_new, scene);
}
}
}

View File

@@ -84,6 +84,7 @@ typedef struct WorkSpace {
/* Store for each hook (so for each window) which layout has
* been activated the last time this workspace was visible. */
ListBase hook_layout_relations DNA_PRIVATE_WORKSPACE_READ_WRITE; /* WorkSpaceDataRelation */
ListBase scene_viewlayer_relations DNA_PRIVATE_WORKSPACE_READ_WRITE; /* WorkSpaceDataRelation */
/* Custom transform orientations */
ListBase transform_orientations DNA_PRIVATE_WORKSPACE;

View File

@@ -36,6 +36,8 @@
#include "BLT_translation.h"
#include "BKE_workspace.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -467,6 +469,7 @@ const EnumPropertyItem rna_enum_wm_report_items[] = {
#include "WM_api.h"
#include "DNA_object_types.h"
#include "DNA_workspace_types.h"
#include "ED_screen.h"
@@ -475,7 +478,6 @@ const EnumPropertyItem rna_enum_wm_report_items[] = {
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_workspace.h"
#include "MEM_guardedalloc.h"
@@ -755,6 +757,49 @@ static void rna_workspace_screen_update(bContext *C, PointerRNA *ptr)
}
}
static PointerRNA rna_Window_view_layer_get(PointerRNA *ptr)
{
wmWindow *win = ptr->data;
Scene *scene = WM_window_get_active_scene(win);
WorkSpace *workspace = WM_window_get_active_workspace(win);
ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
PointerRNA scene_ptr;
RNA_id_pointer_create(&scene->id, &scene_ptr);
return rna_pointer_inherit_refine(&scene_ptr, &RNA_ViewLayer, view_layer);
}
static void rna_Window_view_layer_set(PointerRNA *ptr, PointerRNA value)
{
wmWindow *win = ptr->data;
Scene *scene = WM_window_get_active_scene(win);
WorkSpace *workspace = WM_window_get_active_workspace(win);
BKE_workspace_view_layer_set(workspace, value.data, scene);
}
#ifdef USE_WORKSPACE_MODE
static int rna_Window_object_mode_get(PointerRNA *ptr)
{
wmWindow *win = ptr->data;
Scene *scene = WM_window_get_active_scene(win);
WorkSpace *workspace = WM_window_get_active_workspace(win);
return (int)BKE_workspace_object_mode_get(workspace, scene);
}
static void rna_Window_object_mode_set(PointerRNA *ptr, int value)
{
wmWindow *win = ptr->data;
Scene *scene = WM_window_get_active_scene(win);
WorkSpace *workspace = WM_window_get_active_workspace(win);
BKE_workspace_object_mode_set(workspace, scene, value);
}
#endif /* USE_WORKSPACE_MODE */
static PointerRNA rna_KeyMapItem_properties_get(PointerRNA *ptr)
{
wmKeyMapItem *kmi = ptr->data;
@@ -2024,6 +2069,20 @@ static void rna_def_window(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_NEVER_NULL | PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_workspace_screen_update");
prop = RNA_def_property(srna, "view_layer", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ViewLayer");
RNA_def_property_pointer_funcs(prop, "rna_Window_view_layer_get", "rna_Window_view_layer_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active View Layer", "The active workspace view layer showing in the window");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
RNA_def_property_update(prop, NC_SCREEN | ND_LAYER, NULL);
#ifdef USE_WORKSPACE_MODE
prop = RNA_def_property(srna, "object_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_object_mode_items);
RNA_def_property_enum_funcs(prop, "rna_Window_object_mode_get", "rna_Window_object_mode_set", NULL);
RNA_def_property_ui_text(prop, "Mode", "Object interaction mode used in this window");
#endif
prop = RNA_def_property(srna, "x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "posx");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);

View File

@@ -67,22 +67,6 @@ static PointerRNA rna_workspace_screens_item_get(CollectionPropertyIterator *ite
return rna_pointer_inherit_refine(&iter->parent, &RNA_Screen, screen);
}
#ifdef USE_WORKSPACE_MODE
static int rna_workspace_object_mode_get(PointerRNA *ptr)
{
WorkSpace *workspace = ptr->data;
return (int)BKE_workspace_object_mode_get(workspace);
}
static void rna_workspace_object_mode_set(PointerRNA *ptr, int value)
{
WorkSpace *workspace = ptr->data;
BKE_workspace_object_mode_set(workspace, value);
}
#endif /* USE_WORKSPACE_MODE */
void rna_workspace_transform_orientations_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
WorkSpace *workspace = ptr->id.data;
@@ -95,30 +79,6 @@ static PointerRNA rna_workspace_transform_orientations_item_get(CollectionProper
return rna_pointer_inherit_refine(&iter->parent, &RNA_TransformOrientation, transform_orientation);
}
static PointerRNA rna_workspace_view_layer_get(PointerRNA *ptr)
{
WorkSpace *workspace = ptr->data;
ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace);
/* XXX hmrf... lookup in getter... but how could we avoid it? */
for (Scene *scene = G.main->scene.first; scene; scene = scene->id.next) {
if (BLI_findindex(&scene->view_layers, view_layer) != -1) {
PointerRNA scene_ptr;
RNA_id_pointer_create(&scene->id, &scene_ptr);
return rna_pointer_inherit_refine(&scene_ptr, &RNA_ViewLayer, view_layer);
}
}
return PointerRNA_NULL;
}
static void rna_workspace_view_layer_set(PointerRNA *ptr, PointerRNA value)
{
WorkSpace *workspace = ptr->data;
BKE_workspace_view_layer_set(workspace, value.data);
}
#else /* RNA_RUNTIME */
static void rna_def_workspace(BlenderRNA *brna)
@@ -139,13 +99,6 @@ static void rna_def_workspace(BlenderRNA *brna)
"rna_workspace_screens_item_get", NULL, NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Screens", "Screen layouts of a workspace");
#ifdef USE_WORKSPACE_MODE
prop = RNA_def_property(srna, "object_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_object_mode_items);
RNA_def_property_enum_funcs(prop, "rna_workspace_object_mode_get", "rna_workspace_object_mode_set", NULL);
RNA_def_property_ui_text(prop, "Mode", "Object interaction mode");
#endif
prop = RNA_def_property(srna, "tool_keymap", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "tool.keymap");
RNA_def_property_ui_text(prop, "Active Tool", "Currently active tool keymap");
@@ -168,14 +121,6 @@ static void rna_def_workspace(BlenderRNA *brna)
"rna_workspace_transform_orientations_item_get", NULL, NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Transform Orientations", "");
prop = RNA_def_property(srna, "view_layer", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ViewLayer");
RNA_def_property_pointer_funcs(prop, "rna_workspace_view_layer_get", "rna_workspace_view_layer_set",
NULL, NULL);
RNA_def_property_ui_text(prop, "Active View Layer", "The active view layer used in this workspace");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
RNA_def_property_update(prop, NC_SCREEN | ND_LAYER, NULL);
/* View Render */
prop = RNA_def_property(srna, "view_render", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);