diff options
Diffstat (limited to 'source/blender/editors/object/object_modes.c')
-rw-r--r-- | source/blender/editors/object/object_modes.c | 133 |
1 files changed, 106 insertions, 27 deletions
diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c index d70a69e30f8..f074a56fb86 100644 --- a/source/blender/editors/object/object_modes.c +++ b/source/blender/editors/object/object_modes.c @@ -29,16 +29,30 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_workspace_types.h" #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_object.h" +#include "BKE_paint.h" #include "BKE_report.h" #include "WM_api.h" #include "WM_types.h" -#include "ED_object.h" +#include "RNA_access.h" + +#include "DEG_depsgraph.h" + +#include "ED_screen.h" + +#include "ED_object.h" /* own include */ + +/* -------------------------------------------------------------------- */ +/** \name High Level Mode Operations + * + * \{ */ static const char *object_mode_op_string(eObjectMode mode) { @@ -102,7 +116,6 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode) return false; } - /** * Sets the mode to a compatible state (use before entering the mode). * @@ -113,6 +126,7 @@ bool ED_object_mode_compat_set(bContext *C, Object *ob, eObjectMode mode, Report bool ok; if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) { const char *opstring = object_mode_op_string(ob->mode); + WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL); ok = ELEM(ob->mode, mode, OB_MODE_OBJECT); if (!ok) { @@ -131,48 +145,113 @@ void ED_object_mode_toggle(bContext *C, eObjectMode mode) { if (mode != OB_MODE_OBJECT) { const char *opstring = object_mode_op_string(mode); + if (opstring) { WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL); } } } + /* Wrapper for operator */ void ED_object_mode_set(bContext *C, eObjectMode mode) { -#if 0 + wmWindowManager *wm = CTX_wm_manager(C); + wm->op_undo_depth++; + /* needed so we don't do undo pushes. */ + ED_object_mode_generic_enter(C, mode); + wm->op_undo_depth--; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Generic Mode Enter/Exit + * + * Supports exiting a mode without it being in the current context. + * This could be done for entering modes too if it's needed. + * + * \{ */ + +bool ED_object_mode_generic_enter( + struct bContext *C, eObjectMode object_mode) +{ + Object *ob = CTX_data_active_object(C); + if (ob->mode == object_mode) { + return true; + } wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_mode_set", false); PointerRNA ptr; - WM_operator_properties_create_ptr(&ptr, ot); - RNA_enum_set(&ptr, "mode", mode); - RNA_boolean_set(&ptr, "toggle", false); - WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &ptr); + RNA_enum_set(&ptr, "mode", object_mode); + WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr); WM_operator_properties_free(&ptr); -#else - Object *ob = CTX_data_active_object(C); - if (ob == NULL) { - return; + return (ob->mode == object_mode); +} + +/** + * Use for changing works-paces or changing active object. + * Caller can check #OB_MODE_ALL_MODE_DATA to test if this needs to be run. + */ +static bool ed_object_mode_generic_exit_ex( + const struct EvaluationContext *eval_ctx, + struct Scene *scene, struct Object *ob, + bool only_test) +{ + if (ob->mode & OB_MODE_EDIT) { + if (BKE_object_is_in_editmode(ob)) { + if (only_test) { + return true; + } + ED_object_editmode_exit_ex(NULL, scene, ob, EM_FREEDATA); + } } - if (ob->mode == mode) { - /* pass */ + else if (ob->mode & OB_MODE_VERTEX_PAINT) { + if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_VERTEX_PAINT)) { + if (only_test) { + return true; + } + ED_object_vpaintmode_exit_ex(ob); + } } - else if (mode != OB_MODE_OBJECT) { - if (ob && (ob->mode & mode) == 0) { - /* needed so we don't do undo pushes. */ - wmWindowManager *wm = CTX_wm_manager(C); - wm->op_undo_depth++; - ED_object_mode_toggle(C, mode); - wm->op_undo_depth--; + else if (ob->mode & OB_MODE_WEIGHT_PAINT) { + if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_WEIGHT_PAINT)) { + if (only_test) { + return true; + } + ED_object_wpaintmode_exit_ex(ob); + } + } + else if (ob->mode & OB_MODE_SCULPT) { + if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_SCULPT)) { + if (only_test) { + return true; + } + ED_object_sculptmode_exit_ex(eval_ctx, scene, ob); } } else { - /* needed so we don't do undo pushes. */ - wmWindowManager *wm = CTX_wm_manager(C); - wm->op_undo_depth++; - ED_object_mode_toggle(C, ob->mode); - wm->op_undo_depth--; - + if (only_test) { + return false; + } + BLI_assert((ob->mode & OB_MODE_ALL_MODE_DATA) == 0); } -#endif + + return false; +} + +void ED_object_mode_generic_exit( + const struct EvaluationContext *eval_ctx, + struct Scene *scene, struct Object *ob) +{ + ed_object_mode_generic_exit_ex(eval_ctx, scene, ob, false); } + +bool ED_object_mode_generic_has_data( + const struct EvaluationContext *eval_ctx, + struct Object *ob) +{ + return ed_object_mode_generic_exit_ex(eval_ctx, NULL, ob, true); +} + +/** \} */ |