Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-06-16 01:20:27 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-06-16 01:20:27 +0300
commit400d3f85e13d6e6890098b948962b7abc7ae3f66 (patch)
tree197abb776be015f38de058fcd2393c818795d763 /source
parent4054914813e7ff72acabf6571742cbb0db3f682a (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')
-rw-r--r--source/blender/editors/manipulator_library/dial3d_manipulator.c15
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_api.h10
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_types.h3
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator.c7
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c28
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c41
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;