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.
This commit is contained in:
Campbell Barton 2018-03-03 00:19:49 +11:00
parent 35bd1bb957
commit f9f559a05f
4 changed files with 30 additions and 32 deletions

View File

@ -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 {

View File

@ -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);
}
}
/** \} */

View File

@ -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);

View File

@ -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 {