diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-06-16 01:20:27 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-06-16 01:20:27 +0300 |
commit | 400d3f85e13d6e6890098b948962b7abc7ae3f66 (patch) | |
tree | 197abb776be015f38de058fcd2393c818795d763 /source | |
parent | 4054914813e7ff72acabf6571742cbb0db3f682a (diff) |
Add support for delayed manipulator removal
This is needed so manipulators can tag themselves for removal
without causing problems from freeing data within a callback.
Also use properties within the dial manipulator and fix an error where
removing a wmManipulatorGroupType didn't remove its keymap.
Diffstat (limited to 'source')
6 files changed, 98 insertions, 6 deletions
diff --git a/source/blender/editors/manipulator_library/dial3d_manipulator.c b/source/blender/editors/manipulator_library/dial3d_manipulator.c index 1db87ac9a3d..55d5f257eb4 100644 --- a/source/blender/editors/manipulator_library/dial3d_manipulator.c +++ b/source/blender/editors/manipulator_library/dial3d_manipulator.c @@ -75,6 +75,9 @@ typedef struct DialManipulator { typedef struct DialInteraction { float init_mval[2]; + /* only for when using properties */ + float init_prop_angle; + /* cache the last angle to detect rotations bigger than -/+ PI */ float last_angle; /* number of full rotations */ @@ -348,8 +351,15 @@ static void manipulator_dial_modal(bContext *C, wmManipulator *mpr, const wmEven dial_ghostarc_get_angles(dial, event, CTX_wm_region(C), mat, co_outer, &angle_ofs, &angle_delta); DialInteraction *inter = dial->manipulator.interaction_data; + inter->output.angle_delta = angle_delta; inter->output.angle_ofs = angle_ofs; + + /* set the property for the operator and call its modal function */ + wmManipulatorProperty *mpr_prop = WM_manipulator_property_find(mpr, "offset"); + if (mpr_prop && WM_manipulator_property_is_valid(mpr_prop)) { + WM_manipulator_property_value_set(C, mpr, mpr_prop, inter->init_prop_angle + angle_delta); + } } static void manipulator_dial_invoke( @@ -360,6 +370,11 @@ static void manipulator_dial_invoke( inter->init_mval[0] = event->mval[0]; inter->init_mval[1] = event->mval[1]; + wmManipulatorProperty *mpr_prop = WM_manipulator_property_find(mpr, "offset"); + if (mpr_prop && WM_manipulator_property_is_valid(mpr_prop)) { + inter->init_prop_angle = WM_manipulator_property_value_get(mpr, mpr_prop); + } + mpr->interaction_data = inter; } diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h index c24d1db3ba2..076c0f89a88 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h @@ -104,7 +104,8 @@ struct wmManipulatorGroupTypeRef *WM_manipulatorgrouptype_append_and_link( /* Dynamic Updates (for RNA runtime registration) */ void WM_manipulatorconfig_update_tag_init(struct wmManipulatorMapType *mmap_type, struct wmManipulatorGroupType *wgt); -void WM_manipulatorconfig_update(const struct Main *bmain); +void WM_manipulatorconfig_update_tag_remove(struct wmManipulatorMapType *mmap_type, struct wmManipulatorGroupType *wgt); +void WM_manipulatorconfig_update(struct Main *bmain); /* wm_maniulator_property.c */ @@ -196,4 +197,11 @@ void WM_manipulator_group_remove_ptr( struct Main *bmain, struct wmManipulatorGroupType *wgt); void WM_manipulator_group_remove(struct Main *bmain, const char *idname); +void WM_manipulator_group_remove_ptr_delayed_ex( + struct wmManipulatorGroupType *wgt, + struct wmManipulatorMapType *mmap_type); +void WM_manipulator_group_remove_ptr_delayed( + struct wmManipulatorGroupType *wgt); +void WM_manipulator_group_remove_delayed(const char *idname); + #endif /* __WM_MANIPULATOR_API_H__ */ diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h index 15b00d0a7b0..cc487dadca2 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h @@ -239,6 +239,8 @@ typedef struct wmManipulatorGroupType { /* keymap created with callback from above */ struct wmKeyMap *keymap; + /* Only for convenient removal. */ + struct wmKeyConfig *keyconf; /* Disable for now, maybe some day we want properties. */ #if 0 @@ -282,6 +284,7 @@ typedef struct wmManipulatorGroup { enum eManipulatorMapTypeUpdateFlags { /* A new type has been added, needs to be initialized for all views. */ WM_MANIPULATORMAPTYPE_UPDATE_INIT = (1 << 0), + WM_MANIPULATORMAPTYPE_UPDATE_REMOVE = (1 << 1), }; /** diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c index ae7353971f0..b71cfdb15cf 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c @@ -172,8 +172,13 @@ void WM_manipulator_free(ListBase *manipulatorlist, wmManipulatorMap *mmap, wmMa } BLI_freelistN(&mpr->properties); - if (manipulatorlist) + if (manipulatorlist) { BLI_remlink(manipulatorlist, mpr); + } + + BLI_assert(mmap->mmap_context.highlight != mpr); + BLI_assert(mmap->mmap_context.active != mpr); + MEM_freeN(mpr); } diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c index 3deef0cee5c..bfbdfbe57df 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c @@ -608,6 +608,10 @@ void WM_manipulatormaptype_group_unlink( BLI_remlink(&mmap_type->grouptype_refs, wgt_ref); WM_manipulatormaptype_group_free(wgt_ref); } + + /* Note, we may want to keep this keymap for editing */ + WM_keymap_remove(wgt->keyconf, wgt->keymap); + BLI_assert(WM_manipulatormaptype_group_find_ptr(mmap_type, wgt) == NULL); } @@ -615,6 +619,7 @@ void wm_manipulatorgrouptype_setup_keymap( wmManipulatorGroupType *wgt, wmKeyConfig *keyconf) { wgt->keymap = wgt->setup_keymap(wgt, keyconf); + wgt->keyconf = keyconf; } /** \} */ /* wmManipulatorGroupType */ @@ -678,4 +683,27 @@ void WM_manipulator_group_remove(struct Main *bmain, const char *idname) WM_manipulator_group_remove_ptr(bmain, wgt); } +/* delayed versions */ + +void WM_manipulator_group_remove_ptr_delayed_ex( + wmManipulatorGroupType *wgt, + wmManipulatorMapType *mmap_type) +{ + WM_manipulatorconfig_update_tag_remove(mmap_type, wgt); +} + +void WM_manipulator_group_remove_ptr_delayed( + wmManipulatorGroupType *wgt) +{ + wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure(&wgt->mmap_params); + WM_manipulator_group_remove_ptr_delayed_ex(wgt, mmap_type); +} + +void WM_manipulator_group_remove_delayed(const char *idname) +{ + wmManipulatorGroupType *wgt = WM_manipulatorgrouptype_find(idname, false); + BLI_assert(wgt != NULL); + WM_manipulator_group_remove_ptr_delayed(wgt); +} + /** \} */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c index 123c46f9c50..4574a1eb2ce 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c @@ -66,6 +66,7 @@ static ListBase manipulatormaptypes = {NULL, NULL}; /* so operator removal can trigger update */ enum { WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT = (1 << 0), + WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE = (1 << 1), }; static char wm_mmap_type_update_flag = 0; @@ -239,9 +240,10 @@ static void manipulatormap_prepare_drawing( */ static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext *C, ListBase *draw_manipulators) { - if (!mmap) + /* Can be empty if we're dynamically added and removed. */ + if ((mmap == NULL) || BLI_listbase_is_empty(&mmap->groups)) { return; - BLI_assert(!BLI_listbase_is_empty(&mmap->groups)); + } const bool draw_multisample = (U.ogl_multisamples != USER_MULTISAMPLE_NONE); @@ -778,7 +780,8 @@ void wm_manipulators_keymap(wmKeyConfig *keyconf) * \{ */ -void WM_manipulatorconfig_update_tag_init(wmManipulatorMapType *mmap_type, wmManipulatorGroupType *wgt) +void WM_manipulatorconfig_update_tag_init( + wmManipulatorMapType *mmap_type, wmManipulatorGroupType *wgt) { /* tag for update on next use */ mmap_type->type_update_flag |= WM_MANIPULATORMAPTYPE_UPDATE_INIT; @@ -787,11 +790,21 @@ void WM_manipulatorconfig_update_tag_init(wmManipulatorMapType *mmap_type, wmMan wm_mmap_type_update_flag |= WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT; } +void WM_manipulatorconfig_update_tag_remove( + wmManipulatorMapType *mmap_type, wmManipulatorGroupType *wgt) +{ + /* tag for update on next use */ + mmap_type->type_update_flag |= WM_MANIPULATORMAPTYPE_UPDATE_REMOVE; + wgt->type_update_flag |= WM_MANIPULATORMAPTYPE_UPDATE_REMOVE; + + wm_mmap_type_update_flag |= WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE; +} + /** * Run incase new types have been added (runs often, early exit where possible). * Follows #WM_keyconfig_update concentions. */ -void WM_manipulatorconfig_update(const struct Main *bmain) +void WM_manipulatorconfig_update(struct Main *bmain) { if (G.background) return; @@ -799,6 +812,26 @@ void WM_manipulatorconfig_update(const struct Main *bmain) if (wm_mmap_type_update_flag == 0) return; + if (wm_mmap_type_update_flag & WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE) { + for (wmManipulatorMapType *mmap_type = manipulatormaptypes.first; + mmap_type; + mmap_type = mmap_type->next) + { + if (mmap_type->type_update_flag & WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE) { + mmap_type->type_update_flag &= ~WM_MANIPULATORMAPTYPE_UPDATE_REMOVE; + for (wmManipulatorGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first, *wgt_ref_next; + wgt_ref; + wgt_ref = wgt_ref_next) + { + wgt_ref_next = wgt_ref->next; + WM_manipulatormaptype_group_unlink(NULL, bmain, mmap_type, wgt_ref->type); + } + } + } + + wm_mmap_type_update_flag &= ~WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE; + } + if (wm_mmap_type_update_flag & WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT) { for (wmManipulatorMapType *mmap_type = manipulatormaptypes.first; mmap_type; |