From f9f559a05fc16e66031210e62bd7bc51d26208a3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 3 Mar 2018 00:19:49 +1100 Subject: WorkSpace: Simplify exiting mode after changes It was too tricky to know ahead of time if an object would still be visible in the new window/workspace/scene/layer combination, especially since other windows may share some of these data-blocks. So store the context, make the change, then check if the object is still visible, freeing mode data of it's not. --- source/blender/editors/include/ED_object.h | 3 +++ source/blender/editors/object/object_modes.c | 13 +++++++++++ source/blender/editors/scene/scene_edit.c | 16 +++----------- source/blender/editors/screen/workspace_edit.c | 30 ++++++++++---------------- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 80f230fd868..296b69ca20b 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -221,6 +221,9 @@ bool ED_object_mode_generic_has_data( bool ED_object_mode_generic_enter_or_other_window( struct bContext *C, eObjectMode object_mode); +void ED_object_mode_generic_exit_or_other_window( + const struct EvaluationContext *eval_ctx, struct wmWindowManager *wm, + struct WorkSpace *workspace, struct Scene *scene, struct Object *ob); /* object_modifier.c */ enum { diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c index 47cbf782e07..33867a9f33e 100644 --- a/source/blender/editors/object/object_modes.c +++ b/source/blender/editors/object/object_modes.c @@ -281,4 +281,17 @@ bool ED_object_mode_generic_enter_or_other_window( } } +void ED_object_mode_generic_exit_or_other_window( + const struct EvaluationContext *eval_ctx, wmWindowManager *wm, + struct WorkSpace *workspace, struct Scene *scene, struct Object *ob) +{ + if (ob == NULL) { + return; + } + bool is_active = ED_workspace_object_mode_in_other_window(wm, NULL, ob, NULL); + if (is_active == false) { + ED_object_mode_generic_exit(eval_ctx, workspace, scene, ob); + } +} + /** \} */ diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c index 462820c93c0..ba7ad1505c3 100644 --- a/source/blender/editors/scene/scene_edit.c +++ b/source/blender/editors/scene/scene_edit.c @@ -130,18 +130,11 @@ void ED_scene_change_update( Object *obact_new = OBACT(layer_new); /* mode syncing */ + EvaluationContext eval_ctx_old; + CTX_data_eval_ctx(C, &eval_ctx_old); eObjectMode object_mode_old = workspace->object_mode; ViewLayer *layer_old = BKE_view_layer_from_workspace_get(scene_old, workspace); Object *obact_old = OBACT(layer_old); - if (obact_old && (obact_new != obact_old)) { - bool obact_old_is_active = - ED_workspace_object_mode_in_other_window(bmain->wm.first, win, obact_old, NULL); - if (obact_old && (obact_old_is_active == false)) { - EvaluationContext eval_ctx; - CTX_data_eval_ctx(C, &eval_ctx); - ED_object_mode_generic_exit(&eval_ctx, workspace, scene_old, obact_old); - } - } win->scene = scene_new; CTX_data_scene_set(C, scene_new); @@ -150,17 +143,14 @@ void ED_scene_change_update( DEG_graph_relations_update(depsgraph, bmain, scene_new, layer_new); DEG_on_visible_update(bmain, false); - - /* TODO(campbell) Syncing duplicates some logic without being 100% identical, - * keep and eye on this to see if we can generalize in the future. */ if (obact_new == obact_old) { /* pass */ } else { + ED_object_mode_generic_exit_or_other_window(&eval_ctx_old, bmain->wm.first, workspace, scene_old, obact_old); ED_object_mode_generic_enter_or_other_window(C, object_mode_old); } - ED_screen_update_after_scene_change(screen, scene_new, layer_new); ED_render_engine_changed(bmain); ED_update_for_newframe(bmain, scene_new, layer_new, depsgraph); diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index 23715f667fe..864cbbf5b05 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -171,10 +171,14 @@ bool ED_workspace_change( if (screen_new) { bool use_object_mode = false; + /* Store old context for exiting edit-mode. */ + EvaluationContext eval_ctx_old; + CTX_data_eval_ctx(C, &eval_ctx_old); Scene *scene = WM_window_get_active_scene(win); ViewLayer *view_layer_old = BKE_workspace_view_layer_get(workspace_old, scene); - ViewLayer *view_layer_new = BKE_workspace_view_layer_get(workspace_new, scene); Object *obact_old = OBACT(view_layer_old); + + ViewLayer *view_layer_new = BKE_workspace_view_layer_get(workspace_new, scene); Object *obact_new = OBACT(view_layer_new); /* Handle object mode switching */ @@ -187,27 +191,11 @@ bool ED_workspace_change( /* pass */ } else { - if (workspace_old->object_mode & OB_MODE_ALL_MODE_DATA) { - if (obact_old) { - bool obact_old_is_active = - ED_workspace_object_mode_in_other_window(bmain->wm.first, win, obact_old, NULL); - if (obact_old_is_active == false) { - eObjectMode object_mode = workspace_old->object_mode; - EvaluationContext eval_ctx; - CTX_data_eval_ctx(C, &eval_ctx); - ED_object_mode_generic_exit(&eval_ctx, workspace_old, scene, obact_old); - /* weak, set it back so it's used when activating again. */ - workspace_old->object_mode = object_mode; - } - } - } - - if (workspace_new->object_mode != OB_MODE_OBJECT) { - use_object_mode = true; - } + use_object_mode = true; } } + WM_window_set_active_layout(win, workspace_new, layout_new); WM_window_set_active_workspace(win, workspace_new); @@ -222,6 +210,10 @@ bool ED_workspace_change( WM_toolsystem_link(C, workspace_new); if (use_object_mode) { + /* weak, set it back so it's used when activating again. */ + eObjectMode object_mode = workspace_old->object_mode; + ED_object_mode_generic_exit_or_other_window(&eval_ctx_old, bmain->wm.first, workspace_old, scene, obact_old); + workspace_old->object_mode = object_mode; ED_object_mode_generic_enter_or_other_window(C, workspace_new->object_mode); } else { -- cgit v1.2.3