WorkSpace: use existing mode data w/ scene-switch
authorCampbell Barton <ideasman42@gmail.com>
Sat, 3 Mar 2018 05:39:57 +0000 (16:39 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 3 Mar 2018 05:39:57 +0000 (16:39 +1100)
Check if mode data exists before attempting to change the modes.

source/blender/editors/include/ED_object.h
source/blender/editors/object/object_modes.c
source/blender/editors/scene/scene_edit.c
source/blender/editors/screen/workspace_edit.c

index 296b69ca20b8a4981df41f180527a164ca091380..2a3d5d144acab7785a784cd9d0e5bf5a7f2bddef 100644 (file)
@@ -57,6 +57,7 @@ struct PropertyRNA;
 struct EnumPropertyItem;
 struct EvaluationContext;
 struct WorkSpace;
+struct wmWindow;
 struct wmWindowManager;
 
 #include "DNA_object_enums.h"
@@ -211,7 +212,8 @@ bool ED_object_mode_compat_set(struct bContext *C, struct WorkSpace *workspace,
 void ED_object_mode_toggle(struct bContext *C, eObjectMode mode);
 
 bool ED_object_mode_generic_enter(
-        struct bContext *C, eObjectMode object_mode);
+        struct bContext *C,
+        eObjectMode object_mode);
 void ED_object_mode_generic_exit(
         const struct EvaluationContext *eval_ctx,
         struct WorkSpace *workspace, struct Scene *scene, struct Object *ob);
@@ -220,11 +222,16 @@ bool ED_object_mode_generic_has_data(
         struct Object *ob);
 
 bool ED_object_mode_generic_enter_or_other_window(
-        struct bContext *C, eObjectMode object_mode);
+        struct bContext *C, const struct wmWindow *win_compare,
+        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);
 
+bool ED_object_mode_generic_exists(
+        struct wmWindowManager *wm, struct Object *ob,
+        eObjectMode object_mode);
+
 /* object_modifier.c */
 enum {
        MODIFIER_APPLY_DATA = 1,
index 33867a9f33e453249736a7729a51187719784f3f..33b9ea49ec0852e15d6d50032542ebb8c11251f1 100644 (file)
@@ -255,7 +255,7 @@ bool ED_object_mode_generic_has_data(
  * has an active mode mode in another window we need to use another window first.
  */
 bool ED_object_mode_generic_enter_or_other_window(
-        struct bContext *C, eObjectMode object_mode)
+        struct bContext *C, const wmWindow *win_compare, eObjectMode object_mode)
 {
        WorkSpace *workspace = CTX_wm_workspace(C);
        ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -267,9 +267,7 @@ bool ED_object_mode_generic_enter_or_other_window(
 
        wmWindowManager *wm = CTX_wm_manager(C);
        eObjectMode object_mode_set = OB_MODE_OBJECT;
-       view_layer->basact = NULL;
-       bool use_object_mode = ED_workspace_object_mode_in_other_window(wm, NULL, basact->object, &object_mode_set);
-       view_layer->basact = basact;
+       bool use_object_mode = ED_workspace_object_mode_in_other_window(wm, win_compare, basact->object, &object_mode_set);
 
        if (use_object_mode) {
                workspace->object_mode = object_mode_set;
@@ -294,4 +292,27 @@ void ED_object_mode_generic_exit_or_other_window(
        }
 }
 
+/**
+ * Use to find if we need to create the mode-data.
+ *
+ * When the mode 'exists' it means we have a windowing showing an object with this mode.
+ * So it's data is already created.
+ * Used to check if we need to perform mode switching.
+ */
+bool ED_object_mode_generic_exists(
+        wmWindowManager *wm, struct Object *ob,
+        eObjectMode object_mode)
+{
+       if (ob == NULL) {
+               return false;
+       }
+       eObjectMode object_mode_test;
+       if (ED_workspace_object_mode_in_other_window(wm, NULL, ob, &object_mode_test)) {
+               if (object_mode == object_mode_test) {
+                       return true;
+               }
+       }
+       return false;
+}
+
 /** \} */
index ba7ad1505c3241c31c9491d1506937c71c7f0bd9..da720272f674e9fd26511fda78fa082668d4d999 100644 (file)
@@ -135,6 +135,8 @@ void ED_scene_change_update(
        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);
+       bool obact_new_mode_exists = ED_object_mode_generic_exists(bmain->wm.first, obact_new, workspace->object_mode);
+
 
        win->scene = scene_new;
        CTX_data_scene_set(C, scene_new);
@@ -148,7 +150,12 @@ void ED_scene_change_update(
        }
        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);
+               if (obact_new_mode_exists) {
+                       workspace->object_mode = object_mode_old;
+               }
+               else {
+                       ED_object_mode_generic_enter_or_other_window(C, win, object_mode_old);
+               }
        }
 
        ED_screen_update_after_scene_change(screen, scene_new, layer_new);
index 8a6c8e8628e2c36a894411d1dec9400bfe4f3033..2b28f61f901e6f472d777a1aadc51c323de30343 100644 (file)
@@ -212,14 +212,10 @@ bool ED_workspace_change(
                if (use_object_mode) {
                        /* weak, set it back so it's used when activating again. */
                        eObjectMode object_mode = workspace_old->object_mode;
-                       if (obact_old == obact_new) {
-                               ED_object_mode_generic_exit(&eval_ctx_old, workspace_old, scene, obact_old);
-                       }
-                       else {
-                               ED_object_mode_generic_exit_or_other_window(&eval_ctx_old, bmain->wm.first, workspace_old, scene, obact_old);
-                       }
+                       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);
+                       ED_workspace_object_mode_sync_from_object(bmain->wm.first, workspace_old, obact_old);
+                       ED_object_mode_generic_enter_or_other_window(C, NULL, workspace_new->object_mode);
                }
                else {
                        if (obact_new == NULL) {