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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-11-13 11:43:34 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-12-04 12:42:34 +0300
commit7a8ac1b09b1cf321f259b8eb9b832424d2c7bf5b (patch)
tree5f9a861e234799149fc99f25e5df7bd96fb46cae /source/blender/windowmanager/manipulators
parent5b6cfa705cb180d042f6f27e45331c12972be7ae (diff)
WM: message bus replacement for property notifiers
Use dynamically generated message publish/subscribe so buttons and manipulators update properly. This resolves common glitches where manipulators weren't updating as well as the UI when add-ons exposed properties which hard coded listeners weren't checking for. Python can also publish/scribe changes via `bpy.msgbus`. See D2917
Diffstat (limited to 'source/blender/windowmanager/manipulators')
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_api.h9
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_types.h5
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c20
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c51
-rw-r--r--source/blender/windowmanager/manipulators/wm_manipulator_fn.h2
5 files changed, 87 insertions, 0 deletions
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h
index a3875c50348..9214bccb6a0 100644
--- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h
@@ -51,6 +51,8 @@ struct wmManipulatorGroupType;
struct wmManipulatorMap;
struct wmManipulatorMapType;
struct wmManipulatorMapType_Params;
+struct wmMsgSubscribeKey;
+struct wmMsgSubscribeValue;
#include "wm_manipulator_fn.h"
@@ -216,6 +218,11 @@ const struct wmManipulatorPropertyType *WM_manipulatortype_target_property_find(
void WM_manipulatortype_target_property_def(
struct wmManipulatorType *wt, const char *idname, int data_type, int array_length);
+/* utilities */
+void WM_manipulator_do_msg_notify_tag_refresh(
+ struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val);
+void WM_manipulator_target_property_subscribe_all(
+ struct wmManipulator *mpr, struct wmMsgBus *mbus, struct ARegion *ar);
/* -------------------------------------------------------------------- */
/* wmManipulatorGroup */
@@ -245,6 +252,8 @@ void WM_manipulatormap_draw(
void WM_manipulatormap_add_handlers(struct ARegion *ar, struct wmManipulatorMap *mmap);
bool WM_manipulatormap_select_all(struct bContext *C, struct wmManipulatorMap *mmap, const int action);
bool WM_manipulatormap_cursor_set(const struct wmManipulatorMap *mmap, struct wmWindow *win);
+void WM_manipulatormap_message_subscribe(
+ struct bContext *C, struct wmManipulatorMap *mmap, struct ARegion *ar, struct wmMsgBus *mbus);
bool WM_manipulatormap_is_any_selected(const struct wmManipulatorMap *mmap);
bool WM_manipulatormap_minmax(
const struct wmManipulatorMap *mmap, bool use_hidden, bool use_select,
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
index d4477b8e508..5fa89b8d35f 100644
--- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
@@ -346,6 +346,11 @@ typedef struct wmManipulatorGroupType {
* will fall back to default tweak keymap when left NULL. */
wmManipulatorGroupFnSetupKeymap setup_keymap;
+ /* Optionally subscribe to wmMsgBus events,
+ * these are calculated automatically from RNA properties,
+ * only needed if manipulators depend indirectly on properties. */
+ wmManipulatorGroupFnMsgBusSubscribe message_subscribe;
+
/* keymap created with callback from above */
struct wmKeyMap *keymap;
/* Only for convenient removal. */
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
index a174d7720e3..5d9810272cc 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
@@ -305,6 +305,7 @@ static bool manipulator_prepare_drawing(
/* skip */
}
else {
+ /* Ensure we get RNA updates */
if (do_draw & WM_MANIPULATOR_IS_VISIBLE_UPDATE) {
/* hover manipulators need updating, even if we don't draw them */
wm_manipulator_update(mpr, C, (mmap->update_flag[drawstep] & MANIPULATORMAP_IS_PREPARE_DRAW) != 0);
@@ -953,6 +954,25 @@ ListBase *wm_manipulatormap_groups_get(wmManipulatorMap *mmap)
return &mmap->groups;
}
+void WM_manipulatormap_message_subscribe(
+ bContext *C, wmManipulatorMap *mmap, ARegion *ar, struct wmMsgBus *mbus)
+{
+ for (wmManipulatorGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) {
+ if (!wm_manipulatorgroup_is_visible(mgroup, C)) {
+ continue;
+ }
+ for (wmManipulator *mpr = mgroup->manipulators.first; mpr; mpr = mpr->next) {
+ if (mpr->flag & WM_MANIPULATOR_HIDDEN) {
+ continue;
+ }
+ WM_manipulator_target_property_subscribe_all(mpr, mbus, ar);
+ }
+ if (mgroup->type->message_subscribe != NULL) {
+ mgroup->type->message_subscribe(C, mgroup, mbus);
+ }
+ }
+}
+
/** \} */ /* wmManipulatorMap */
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c
index 836376f1c54..137e8f5639d 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c
@@ -35,6 +35,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "WM_message.h"
#include "wm.h"
@@ -311,3 +312,53 @@ void WM_manipulatortype_target_property_def(
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Property Utilities
+ * \{ */
+
+void WM_manipulator_do_msg_notify_tag_refresh(
+ bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val)
+{
+ ARegion *ar = msg_val->owner;
+ wmManipulatorMap *mmap = msg_val->user_data;
+
+ ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
+}
+
+/**
+ * Runs on the "prepare draw" pass,
+ * drawing the region clears.
+ */
+void WM_manipulator_target_property_subscribe_all(
+ wmManipulator *mpr, struct wmMsgBus *mbus, ARegion *ar)
+{
+ if (mpr->type->target_property_defs_len) {
+ wmManipulatorProperty *mpr_prop_array = WM_manipulator_target_property_array(mpr);
+ for (int i = 0; i < mpr->type->target_property_defs_len; i++) {
+ wmManipulatorProperty *mpr_prop = &mpr_prop_array[i];
+ if (WM_manipulator_target_property_is_valid(mpr_prop)) {
+ if (mpr_prop->prop) {
+ WM_msg_subscribe_rna(
+ mbus, &mpr_prop->ptr, mpr_prop->prop,
+ &(const wmMsgSubscribeValue){
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ }, __func__);
+ WM_msg_subscribe_rna(
+ mbus, &mpr_prop->ptr, mpr_prop->prop,
+ &(const wmMsgSubscribeValue){
+ .owner = ar,
+ .user_data = mpr->parent_mgroup->parent_mmap,
+ .notify = WM_manipulator_do_msg_notify_tag_refresh,
+ }, __func__);
+ }
+ }
+ }
+ }
+}
+
+/** \} */
diff --git a/source/blender/windowmanager/manipulators/wm_manipulator_fn.h b/source/blender/windowmanager/manipulators/wm_manipulator_fn.h
index c54024529c3..7e163f8a785 100644
--- a/source/blender/windowmanager/manipulators/wm_manipulator_fn.h
+++ b/source/blender/windowmanager/manipulators/wm_manipulator_fn.h
@@ -42,6 +42,8 @@ typedef void (*wmManipulatorGroupFnDrawPrepare)(
typedef struct wmKeyMap *(*wmManipulatorGroupFnSetupKeymap)(
const struct wmManipulatorGroupType *, struct wmKeyConfig *)
ATTR_WARN_UNUSED_RESULT;
+typedef void (*wmManipulatorGroupFnMsgBusSubscribe)(
+ const struct bContext *, struct wmManipulatorGroup *, struct wmMsgBus *);
/* wmManipulator */
/* See: wmManipulatorType for docs on each type. */