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-06-15 13:48:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-06-15 13:56:22 +0300
commit830df9b33d3e2afdf3bb23b469378899c34fda78 (patch)
tree4f2fad8cdd48937e28d2c45115476c9045e4525b /source/blender/windowmanager
parent1a7099f3ecf52fa8a54c2ba3f652d5827ca9103c (diff)
Updates to manipulator API
While this is work-in-progress from custom-manipulators branch its stable so adding into 2.8 so we don't get too much out of sync. - ManipulatorGroupType's are moved out of the manipulator-map and are now global (like operators, panels etc) and added into spaces as needed. Without this all operators that might ever use a manipulator in the 3D view would be polling the viewport. - Add optional get/set callbacks for non-RNA properties Needed so re-usable manipulators can control values that don't correspond to a single properly or need conversion. - Fix divide by zero bug in arrow manipulator (when moving zero pixels).
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r--source/blender/windowmanager/CMakeLists.txt3
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c5
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c2
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_api.h130
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_types.h71
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator.c156
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h13
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_property.c175
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c156
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c223
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup_type.c185
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c141
-rw-r--r--source/blender/windowmanager/manipulators/wm_manipulator_fn.h34
-rw-r--r--source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h14
14 files changed, 946 insertions, 362 deletions
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index a0efe7502c4..a4eefc5b15d 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -72,7 +72,10 @@ set(SRC
intern/wm_window.c
intern/wm_stereo.c
manipulators/intern/wm_manipulator.c
+ manipulators/intern/wm_manipulator_property.c
+ manipulators/intern/wm_manipulator_type.c
manipulators/intern/wm_manipulatorgroup.c
+ manipulators/intern/wm_manipulatorgroup_type.c
manipulators/intern/wm_manipulatormap.c
WM_api.h
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index b7fb757fc5c..06bf6ff2482 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -36,7 +36,6 @@
#include <string.h>
#include "DNA_listBase.h"
-#include "DNA_manipulator_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_windowmanager_types.h"
@@ -2165,7 +2164,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
/* handle user configurable manipulator-map keymap */
else if (mpr) {
/* get user customized keymap from default one */
- const wmManipulatorGroup *highlightgroup = wm_manipulator_get_parent_group(mpr);
+ const wmManipulatorGroup *highlightgroup = mpr->parent_mgroup;
const wmKeyMap *keymap = WM_keymap_active(wm, highlightgroup->type->keymap);
wmKeyMapItem *kmi;
@@ -2452,6 +2451,7 @@ void wm_event_do_handlers(bContext *C)
/* update key configuration before handling events */
WM_keyconfig_update(wm);
+ WM_manipulatorconfig_update(CTX_data_main(C));
for (win = wm->windows.first; win; win = win->next) {
bScreen *screen = WM_window_get_active_screen(win);
@@ -2664,6 +2664,7 @@ void wm_event_do_handlers(bContext *C)
/* update key configuration after handling events */
WM_keyconfig_update(wm);
+ WM_manipulatorconfig_update(CTX_data_main(C));
}
/* ********** filesector handling ************ */
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 7d729f22cfe..4c54eacaf26 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -166,6 +166,7 @@ void WM_init(bContext *C, int argc, const char **argv)
WM_menutype_init();
WM_uilisttype_init();
wm_manipulatortype_init();
+ wm_manipulatorgrouptype_init();
BKE_undo_callback_wm_kill_jobs_set(wm_undo_kill_callback);
@@ -488,6 +489,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
wm_dropbox_free();
WM_menutype_free();
WM_uilisttype_free();
+ wm_manipulatorgrouptype_free();
wm_manipulatortype_free();
/* all non-screen and non-space stuff editors did, like editmode */
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h
index a72830e19d4..c24d1db3ba2 100644
--- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h
@@ -63,13 +63,6 @@ struct wmManipulator *WM_manipulator_new(
void WM_manipulator_free(
ListBase *manipulatorlist, struct wmManipulatorMap *mmap, struct wmManipulator *mpr,
struct bContext *C);
-struct wmManipulatorGroup *WM_manipulator_get_parent_group(struct wmManipulator *mpr);
-
-struct wmManipulatorProperty *WM_manipulator_get_property(
- struct wmManipulator *mpr, const char *idname);
-void WM_manipulator_def_property(
- struct wmManipulator *mpr, const char *idname,
- struct PointerRNA *ptr, const char *propname, int index);
struct PointerRNA *WM_manipulator_set_operator(struct wmManipulator *, const char *opname);
@@ -87,7 +80,7 @@ void WM_manipulator_set_color(struct wmManipulator *mpr, const float col[4]);
void WM_manipulator_get_color_highlight(const struct wmManipulator *mpr, float col_hi[4]);
void WM_manipulator_set_color_highlight(struct wmManipulator *mpr, const float col[4]);
-/* wm_manipulator.c */
+/* wm_manipulator_type.c */
const struct wmManipulatorType *WM_manipulatortype_find(const char *idname, bool quiet);
void WM_manipulatortype_append(void (*wtfunc)(struct wmManipulatorType *));
void WM_manipulatortype_append_ptr(void (*mnpfunc)(struct wmManipulatorType *, void *), void *userdata);
@@ -95,48 +88,59 @@ bool WM_manipulatortype_remove(const char *idname);
void WM_manipulatortype_remove_ptr(struct wmManipulatorType *wt);
void WM_manipulatortype_iter(struct GHashIterator *ghi);
+/* wm_manipulatorgroup_type.c */
+struct wmManipulatorGroupType *WM_manipulatorgrouptype_find(const char *idname, bool quiet);
+struct wmManipulatorGroupType *WM_manipulatorgrouptype_append(void (*wtfunc)(struct wmManipulatorGroupType *));
+struct wmManipulatorGroupType *WM_manipulatorgrouptype_append_ptr(void (*mnpfunc)(struct wmManipulatorGroupType *, void *), void *userdata);
+bool WM_manipulatorgrouptype_remove(const char *idname);
+void WM_manipulatorgrouptype_remove_ptr(struct wmManipulatorGroupType *wt);
+void WM_manipulatorgrouptype_iter(struct GHashIterator *ghi);
+
+struct wmManipulatorGroupTypeRef *WM_manipulatorgrouptype_append_and_link(
+ struct wmManipulatorMapType *mmap_type,
+ void (*wtfunc)(struct wmManipulatorGroupType *));
+
+/* wm_manipulatormap.c */
+
+/* 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);
+
+
+/* wm_maniulator_property.c */
+struct wmManipulatorProperty *WM_manipulator_property_find(
+ struct wmManipulator *mpr, const char *idname);
+
+void WM_manipulator_property_def_rna(
+ struct wmManipulator *mpr, const char *idname,
+ struct PointerRNA *ptr, const char *propname, int index);
+void WM_manipulator_property_def_func(
+ struct wmManipulator *mpr, const char *idname,
+ const struct wmManipulatorPropertyFnParams *params);
+
+bool WM_manipulator_property_is_valid(
+ const struct wmManipulatorProperty *mpr_prop);
+void WM_manipulator_property_value_set(
+ struct bContext *C, const struct wmManipulator *mpr, struct wmManipulatorProperty *mpr_prop, const float value);
+float WM_manipulator_property_value_get(
+ const struct wmManipulator *mpr, struct wmManipulatorProperty *mpr_prop);
+void WM_manipulator_property_range_get(
+ const struct wmManipulator *mpr, struct wmManipulatorProperty *mpr_prop,
+ float range[2]);
+
/* -------------------------------------------------------------------- */
/* wmManipulatorGroup */
-struct wmManipulatorGroupType *WM_manipulatorgrouptype_find(
- struct wmManipulatorMapType *mmaptype,
- const char *idname);
-struct wmManipulatorGroupType *WM_manipulatorgrouptype_append(
- struct wmManipulatorMapType *mmaptype,
- void (*mgrouptype_func)(struct wmManipulatorGroupType *));
-struct wmManipulatorGroupType *WM_manipulatorgrouptype_append_ptr(
- struct wmManipulatorMapType *mmaptype,
- void (*mgrouptype_func)(struct wmManipulatorGroupType *, void *),
- void *userdata);
-struct wmManipulatorGroupType *WM_manipulatorgrouptype_append_runtime(
- const struct Main *main, struct wmManipulatorMapType *mmaptype,
- void (*mgrouptype_func)(struct wmManipulatorGroupType *));
-struct wmManipulatorGroupType *WM_manipulatorgrouptype_append_ptr_runtime(
- const struct Main *main, struct wmManipulatorMapType *mmaptype,
- void (*mgrouptype_func)(struct wmManipulatorGroupType *, void *),
- void *userdata);
-
-void WM_manipulatorgrouptype_init_runtime(
- const struct Main *bmain, struct wmManipulatorMapType *mmaptype,
- struct wmManipulatorGroupType *wgt);
-void WM_manipulatorgrouptype_free(struct wmManipulatorGroupType *wgt);
-void WM_manipulatorgrouptype_remove_ptr(
- struct bContext *C, struct Main *bmain, struct wmManipulatorGroupType *mgroup);
-
+/* Callbacks for 'wmManipulatorGroupType.setup_keymap' */
struct wmKeyMap *WM_manipulatorgroup_keymap_common(
const struct wmManipulatorGroupType *wgt, struct wmKeyConfig *config);
-struct wmKeyMap *WM_manipulatorgroup_keymap_common_sel(
+struct wmKeyMap *WM_manipulatorgroup_keymap_common_select(
const struct wmManipulatorGroupType *wgt, struct wmKeyConfig *config);
/* -------------------------------------------------------------------- */
/* wmManipulatorMap */
-struct wmManipulatorMapType *WM_manipulatormaptype_find(
- const struct wmManipulatorMapType_Params *mmap_params);
-struct wmManipulatorMapType *WM_manipulatormaptype_ensure(
- const struct wmManipulatorMapType_Params *mmap_params);
-
struct wmManipulatorMap *WM_manipulatormap_new_from_type(
const struct wmManipulatorMapType_Params *mmap_params);
void WM_manipulatormap_tag_refresh(struct wmManipulatorMap *mmap);
@@ -145,5 +149,51 @@ void WM_manipulatormap_add_handlers(struct ARegion *ar, struct wmManipulatorMap
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);
-#endif /* __WM_MANIPULATOR_API_H__ */
+/* -------------------------------------------------------------------- */
+/* wmManipulatorMapType */
+struct wmManipulatorMapType *WM_manipulatormaptype_find(
+ const struct wmManipulatorMapType_Params *mmap_params);
+struct wmManipulatorMapType *WM_manipulatormaptype_ensure(
+ const struct wmManipulatorMapType_Params *mmap_params);
+
+struct wmManipulatorGroupTypeRef *WM_manipulatormaptype_group_find(
+ struct wmManipulatorMapType *mmap_type,
+ const char *idname);
+struct wmManipulatorGroupTypeRef *WM_manipulatormaptype_group_find_ptr(
+ struct wmManipulatorMapType *mmap_type,
+ const struct wmManipulatorGroupType *wgt);
+struct wmManipulatorGroupTypeRef *WM_manipulatormaptype_group_link(
+ struct wmManipulatorMapType *mmap_type,
+ const char *idname);
+struct wmManipulatorGroupTypeRef *WM_manipulatormaptype_group_link_ptr(
+ struct wmManipulatorMapType *mmap_type,
+ struct wmManipulatorGroupType *wgt);
+
+void WM_manipulatormaptype_group_init_runtime(
+ const struct Main *bmain, struct wmManipulatorMapType *mmap_type,
+ struct wmManipulatorGroupType *wgt);
+void WM_manipulatormaptype_group_unlink(
+ struct bContext *C, struct Main *bmain, struct wmManipulatorMapType *mmap_type,
+ const struct wmManipulatorGroupType *wgt);
+
+void WM_manipulatormaptype_group_free(struct wmManipulatorGroupTypeRef *wgt);
+
+/* -------------------------------------------------------------------- */
+/* Manipulator Add/Remove (High level API) */
+
+void WM_manipulator_group_add_ptr_ex(
+ struct wmManipulatorGroupType *wgt,
+ struct wmManipulatorMapType *mmap_type);
+void WM_manipulator_group_add_ptr(
+ struct wmManipulatorGroupType *wgt);
+void WM_manipulator_group_add(const char *idname);
+
+void WM_manipulator_group_remove_ptr_ex(
+ struct Main *bmain, struct wmManipulatorGroupType *wgt,
+ struct wmManipulatorMapType *mmap_type);
+void WM_manipulator_group_remove_ptr(
+ struct Main *bmain, struct wmManipulatorGroupType *wgt);
+void WM_manipulator_group_remove(struct Main *bmain, 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 cd6fdcd8a4d..15b00d0a7b0 100644
--- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
@@ -38,6 +38,7 @@
#include "BLI_compiler_attrs.h"
+struct wmManipulatorMapType;
struct wmManipulatorGroupType;
struct wmManipulatorGroup;
struct wmManipulator;
@@ -104,12 +105,25 @@ struct wmManipulator {
ListBase properties;
};
+typedef void (*wmManipulatorGroupFnInit)(
+ const struct bContext *, struct wmManipulatorGroup *);
+
/* Similar to PropertyElemRNA, but has an identifier. */
typedef struct wmManipulatorProperty {
struct wmManipulatorProperty *next, *prev;
PointerRNA ptr;
PropertyRNA *prop;
int index;
+
+ /* Optional functions for converting to/from RNA */
+ struct {
+ wmManipulatorPropertyFnGet value_get_fn;
+ wmManipulatorPropertyFnSet value_set_fn;
+ wmManipulatorPropertyFnRangeGet range_get_fn;
+ const struct bContext *context;
+ void *user_data;
+ } custom_func;
+
/* over alloc */
char idname[0];
} wmManipulatorProperty;
@@ -121,6 +135,12 @@ typedef struct wmManipulatorWrapper {
struct wmManipulator *manipulator;
} wmManipulatorWrapper;
+struct wmManipulatorMapType_Params {
+ short spaceid;
+ short regionid;
+};
+
+
/* wmManipulator.flag
* Flags for individual manipulators. */
enum {
@@ -194,9 +214,13 @@ typedef struct wmManipulatorType {
/* wmManipulatorGroup */
/* factory class for a manipulator-group type, gets called every time a new area is spawned */
-typedef struct wmManipulatorGroupType {
- struct wmManipulatorGroupType *next, *prev;
+typedef struct wmManipulatorGroupTypeRef {
+ struct wmManipulatorGroupTypeRef *next, *prev;
+ struct wmManipulatorGroupType *type;
+} wmManipulatorGroupTypeRef;
+/* factory class for a manipulator-group type, gets called every time a new area is spawned */
+typedef struct wmManipulatorGroupType {
const char *idname; /* MAX_NAME */
const char *name; /* manipulator-group name - displayed in UI (keymap editor) */
@@ -211,7 +235,8 @@ typedef struct wmManipulatorGroupType {
/* Keymap init callback for this manipulator-group (optional),
* will fall back to default tweak keymap when left NULL. */
- struct wmKeyMap *(*setup_keymap)(const struct wmManipulatorGroupType *, struct wmKeyConfig *);
+ wmManipulatorGroupFnSetupKeymap setup_keymap;
+
/* keymap created with callback from above */
struct wmKeyMap *keymap;
@@ -226,11 +251,39 @@ typedef struct wmManipulatorGroupType {
int flag;
+ /* eManipulatorMapTypeUpdateFlags (so we know which group type to update) */
+ uchar type_update_flag;
+
/* same as manipulator-maps, so registering/unregistering goes to the correct region */
- short spaceid, regionid;
- char mapidname[64];
+ struct wmManipulatorMapType_Params mmap_params;
+
} wmManipulatorGroupType;
+typedef struct wmManipulatorGroup {
+ struct wmManipulatorGroup *next, *prev;
+
+ struct wmManipulatorGroupType *type;
+ ListBase manipulators;
+
+ struct wmManipulatorMap *parent_mmap;
+
+ void *py_instance; /* python stores the class instance here */
+ struct ReportList *reports; /* errors and warnings storage */
+
+ void *customdata;
+ void (*customdata_free)(void *); /* for freeing customdata from above */
+ int flag; /* private */
+ int pad;
+} wmManipulatorGroup;
+
+/**
+ * Manipulator-map type update flag: `wmManipulatorMapType.type_update_flag`
+ */
+enum eManipulatorMapTypeUpdateFlags {
+ /* A new type has been added, needs to be initialized for all views. */
+ WM_MANIPULATORMAPTYPE_UPDATE_INIT = (1 << 0),
+};
+
/**
* wmManipulatorGroupType.flag
* Flags that influence the behavior of all manipulators in the group.
@@ -244,18 +297,14 @@ enum {
WM_MANIPULATORGROUPTYPE_DEPTH_3D = (1 << 2),
/* Manipulators can be selected */
WM_MANIPULATORGROUPTYPE_SELECT = (1 << 3),
+ /* The manipulator group is to be kept (not removed on loading a new file for eg). */
+ WM_MANIPULATORGROUPTYPE_PERSISTENT = (1 << 4),
};
/* -------------------------------------------------------------------- */
/* wmManipulatorMap */
-struct wmManipulatorMapType_Params {
- const char *idname;
- const int spaceid;
- const int regionid;
-};
-
/**
* Pass a value of this enum to #WM_manipulatormap_draw to tell it what to draw.
*/
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
index 3dba5ab55e2..ae7353971f0 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
@@ -30,13 +30,10 @@
#include "BKE_context.h"
#include "BLI_listbase.h"
-#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_string_utils.h"
-#include "DNA_manipulator_types.h"
-
#include "ED_screen.h"
#include "ED_view3d.h"
@@ -65,118 +62,6 @@
static void wm_manipulator_register(
wmManipulatorGroup *mgroup, wmManipulator *mpr, const char *name);
-/** \name Manipulator Type Append
- *
- * \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends.
- * \{ */
-
-static GHash *global_manipulatortype_hash = NULL;
-
-const wmManipulatorType *WM_manipulatortype_find(const char *idname, bool quiet)
-{
- if (idname[0]) {
- wmManipulatorType *wt;
-
- wt = BLI_ghash_lookup(global_manipulatortype_hash, idname);
- if (wt) {
- return wt;
- }
-
- if (!quiet) {
- printf("search for unknown manipulator '%s'\n", idname);
- }
- }
- else {
- if (!quiet) {
- printf("search for empty manipulator\n");
- }
- }
-
- return NULL;
-}
-
-/* caller must free */
-void WM_manipulatortype_iter(GHashIterator *ghi)
-{
- BLI_ghashIterator_init(ghi, global_manipulatortype_hash);
-}
-
-static wmManipulatorType *wm_manipulatortype_append__begin(void)
-{
- wmManipulatorType *wt = MEM_callocN(sizeof(wmManipulatorType), "manipulatortype");
- return wt;
-}
-static void wm_manipulatortype_append__end(wmManipulatorType *wt)
-{
- BLI_assert(wt->struct_size >= sizeof(wmManipulator));
-
- BLI_ghash_insert(global_manipulatortype_hash, (void *)wt->idname, wt);
-}
-
-void WM_manipulatortype_append(void (*wtfunc)(struct wmManipulatorType *))
-{
- wmManipulatorType *wt = wm_manipulatortype_append__begin();
- wtfunc(wt);
- wm_manipulatortype_append__end(wt);
-}
-
-void WM_manipulatortype_append_ptr(void (*wtfunc)(struct wmManipulatorType *, void *), void *userdata)
-{
- wmManipulatorType *mt = wm_manipulatortype_append__begin();
- wtfunc(mt, userdata);
- wm_manipulatortype_append__end(mt);
-}
-
-/**
- * Free but don't remove from ghash.
- */
-static void manipulatortype_free(wmManipulatorType *wt)
-{
- MEM_freeN(wt);
-}
-
-void WM_manipulatortype_remove_ptr(wmManipulatorType *wt)
-{
- BLI_assert(wt == WM_manipulatortype_find(wt->idname, false));
-
- BLI_ghash_remove(global_manipulatortype_hash, wt->idname, NULL, NULL);
-
- manipulatortype_free(wt);
-}
-
-bool WM_manipulatortype_remove(const char *idname)
-{
- wmManipulatorType *wt = BLI_ghash_lookup(global_manipulatortype_hash, idname);
-
- if (wt == NULL) {
- return false;
- }
-
- WM_manipulatortype_remove_ptr(wt);
-
- return true;
-}
-
-static void wm_manipulatortype_ghash_free_cb(wmManipulatorType *mt)
-{
- manipulatortype_free(mt);
-}
-
-void wm_manipulatortype_free(void)
-{
- BLI_ghash_free(global_manipulatortype_hash, NULL, (GHashValFreeFP)wm_manipulatortype_ghash_free_cb);
- global_manipulatortype_hash = NULL;
-}
-
-/* called on initialize WM_init() */
-void wm_manipulatortype_init(void)
-{
- /* reserve size is set based on blender default setup */
- global_manipulatortype_hash = BLI_ghash_str_new_ex("wm_manipulatortype_init gh", 128);
-}
-
-/** \} */
-
/**
* \note Follow #wm_operator_create convention.
*/
@@ -215,11 +100,6 @@ wmManipulator *WM_manipulator_new(const char *idname, wmManipulatorGroup *mgroup
return mpr;
}
-wmManipulatorGroup *WM_manipulator_get_parent_group(wmManipulator *mpr)
-{
- return mpr->parent_mgroup;
-}
-
/**
* Assign an idname that is unique in \a mgroup to \a manipulator.
*
@@ -297,12 +177,6 @@ void WM_manipulator_free(ListBase *manipulatorlist, wmManipulatorMap *mmap, wmMa
MEM_freeN(mpr);
}
-wmManipulatorGroup *wm_manipulator_get_parent_group(const wmManipulator *mpr)
-{
- return mpr->parent_mgroup;
-}
-
-
/* -------------------------------------------------------------------- */
/** \name Manipulator Creation API
*
@@ -310,34 +184,6 @@ wmManipulatorGroup *wm_manipulator_get_parent_group(const wmManipulator *mpr)
*
* \{ */
-struct wmManipulatorProperty *WM_manipulator_get_property(wmManipulator *mpr, const char *idname)
-{
- return BLI_findstring(&mpr->properties, idname, offsetof(wmManipulatorProperty, idname));
-}
-
-void WM_manipulator_def_property(
- wmManipulator *mpr, const char *idname,
- PointerRNA *ptr, const char *propname, int index)
-{
- wmManipulatorProperty *mpr_prop = WM_manipulator_get_property(mpr, idname);
-
- if (mpr_prop == NULL) {
- const uint idname_size = strlen(idname) + 1;
- mpr_prop = MEM_callocN(sizeof(wmManipulatorProperty) + idname_size, __func__);
- memcpy(mpr_prop->idname, idname, idname_size);
- BLI_addtail(&mpr->properties, mpr_prop);
- }
-
- /* if manipulator evokes an operator we cannot use it for property manipulation */
- mpr->opname = NULL;
- mpr_prop->ptr = *ptr;
- mpr_prop->prop = RNA_struct_find_property(ptr, propname);
- mpr_prop->index = index;
-
- if (mpr->type->property_update) {
- mpr->type->property_update(mpr, mpr_prop);
- }
-}
PointerRNA *WM_manipulator_set_operator(wmManipulator *mpr, const char *opname)
{
@@ -533,7 +379,7 @@ static void manipulator_update_prop_data(wmManipulator *mpr)
/* manipulator property might have been changed, so update manipulator */
if (mpr->type->property_update && !BLI_listbase_is_empty(&mpr->properties)) {
for (wmManipulatorProperty *mpr_prop = mpr->properties.first; mpr_prop; mpr_prop = mpr_prop->next) {
- if (mpr_prop->prop != NULL) {
+ if (WM_manipulator_property_is_valid(mpr_prop)) {
mpr->type->property_update(mpr, mpr_prop);
}
}
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
index 0692b1830db..52c47f74a29 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
@@ -56,7 +56,7 @@ enum {
};
struct wmManipulatorGroup *wm_manipulatorgroup_new_from_type(
- struct wmManipulatorMap *mmap, struct wmManipulatorGroupType *mgroup_type);
+ struct wmManipulatorMap *mmap, struct wmManipulatorGroupType *wgt);
void wm_manipulatorgroup_free(bContext *C, struct wmManipulatorGroup *mgroup);
void wm_manipulatorgroup_manipulator_register(struct wmManipulatorGroup *mgroup, struct wmManipulator *mpr);
struct wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator(
@@ -68,7 +68,8 @@ void wm_manipulatorgroup_ensure_initialized(struct wmManipulatorGroup *mgroup, c
bool wm_manipulatorgroup_is_visible(const struct wmManipulatorGroup *mgroup, const struct bContext *C);
bool wm_manipulatorgroup_is_visible_in_drawstep(const struct wmManipulatorGroup *mgroup, const int drawstep);
-void wm_manipulatorgrouptype_setup_keymap(struct wmManipulatorGroupType *wgt, struct wmKeyConfig *keyconf);
+void wm_manipulatorgrouptype_setup_keymap(
+ struct wmManipulatorGroupType *wgt, struct wmKeyConfig *keyconf);
/* -------------------------------------------------------------------- */
@@ -78,7 +79,7 @@ struct wmManipulatorMap {
struct wmManipulatorMap *next, *prev;
struct wmManipulatorMapType *type;
- ListBase manipulator_groups;
+ ListBase groups; /* wmManipulatorGroup */
char update_flag; /* private, update tagging */
@@ -108,10 +109,12 @@ struct wmManipulatorMap {
*/
struct wmManipulatorMapType {
struct wmManipulatorMapType *next, *prev;
- char idname[64];
short spaceid, regionid;
/* types of manipulator-groups for this manipulator-map type */
- ListBase manipulator_grouptypes;
+ ListBase grouptype_refs;
+
+ /* eManipulatorMapTypeUpdateFlags */
+ uchar type_update_flag;
};
void wm_manipulatormap_selected_clear(struct wmManipulatorMap *mmap);
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_property.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_property.c
new file mode 100644
index 00000000000..5a8eb1d68dc
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_property.c
@@ -0,0 +1,175 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/wm_manipulator_property.c
+ * \ingroup wm
+ */
+
+#include "BKE_context.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "wm.h"
+
+/* own includes */
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+
+/* factor for precision tweaking */
+#define MANIPULATOR_PRECISION_FAC 0.05f
+
+/* -------------------------------------------------------------------- */
+
+/** \name Property Definition
+ * \{ */
+
+wmManipulatorProperty *WM_manipulator_property_find(wmManipulator *mpr, const char *idname)
+{
+ return BLI_findstring(&mpr->properties, idname, offsetof(wmManipulatorProperty, idname));
+}
+
+static wmManipulatorProperty *wm_manipulator_property_def_internal(
+ wmManipulator *mpr, const char *idname)
+{
+ wmManipulatorProperty *mpr_prop = WM_manipulator_property_find(mpr, idname);
+
+ if (mpr_prop == NULL) {
+ const uint idname_size = strlen(idname) + 1;
+ mpr_prop = MEM_callocN(sizeof(wmManipulatorProperty) + idname_size, __func__);
+ memcpy(mpr_prop->idname, idname, idname_size);
+ BLI_addtail(&mpr->properties, mpr_prop);
+ }
+ return mpr_prop;
+}
+
+void WM_manipulator_property_def_rna(
+ wmManipulator *mpr, const char *idname,
+ PointerRNA *ptr, const char *propname, int index)
+{
+ wmManipulatorProperty *mpr_prop = wm_manipulator_property_def_internal(mpr, idname);
+
+ /* if manipulator evokes an operator we cannot use it for property manipulation */
+ mpr->opname = NULL;
+
+ mpr_prop->ptr = *ptr;
+ mpr_prop->prop = RNA_struct_find_property(ptr, propname);
+ mpr_prop->index = index;
+
+ if (mpr->type->property_update) {
+ mpr->type->property_update(mpr, mpr_prop);
+ }
+}
+
+void WM_manipulator_property_def_func(
+ wmManipulator *mpr, const char *idname,
+ const wmManipulatorPropertyFnParams *params)
+{
+ wmManipulatorProperty *mpr_prop = wm_manipulator_property_def_internal(mpr, idname);
+
+ /* if manipulator evokes an operator we cannot use it for property manipulation */
+ mpr->opname = NULL;
+
+ mpr_prop->custom_func.value_get_fn = params->value_get_fn;
+ mpr_prop->custom_func.value_set_fn = params->value_set_fn;
+ mpr_prop->custom_func.range_get_fn = params->range_get_fn;
+ mpr_prop->custom_func.user_data = params->user_data;
+
+ if (mpr->type->property_update) {
+ mpr->type->property_update(mpr, mpr_prop);
+ }
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Property Access
+ * \{ */
+
+bool WM_manipulator_property_is_valid(const wmManipulatorProperty *mpr_prop)
+{
+ return ((mpr_prop->prop != NULL) ||
+ (mpr_prop->custom_func.value_get_fn && mpr_prop->custom_func.value_set_fn));
+}
+
+void WM_manipulator_property_value_set(
+ bContext *C, const wmManipulator *mpr,
+ wmManipulatorProperty *mpr_prop, const float value)
+{
+ if (mpr_prop->custom_func.value_set_fn) {
+ mpr_prop->custom_func.value_set_fn(mpr, mpr_prop, mpr_prop->custom_func.user_data, &value, 1);
+ return;
+ }
+
+ /* reset property */
+ if (mpr_prop->index == -1) {
+ RNA_property_float_set(&mpr_prop->ptr, mpr_prop->prop, value);
+ }
+ else {
+ RNA_property_float_set_index(&mpr_prop->ptr, mpr_prop->prop, mpr_prop->index, value);
+ }
+ RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop);
+}
+
+float WM_manipulator_property_value_get(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop)
+{
+ if (mpr_prop->custom_func.value_get_fn) {
+ float value = 0.0f;
+ mpr_prop->custom_func.value_get_fn(mpr, mpr_prop, mpr_prop->custom_func.user_data, &value, 1);
+ return value;
+ }
+
+ if (mpr_prop->index == -1) {
+ return RNA_property_float_get(&mpr_prop->ptr, mpr_prop->prop);
+ }
+ else {
+ return RNA_property_float_get_index(&mpr_prop->ptr, mpr_prop->prop, mpr_prop->index);
+ }
+}
+
+void WM_manipulator_property_range_get(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+ float range[2])
+{
+ if (mpr_prop->custom_func.range_get_fn) {
+ mpr_prop->custom_func.range_get_fn(mpr, mpr_prop, mpr_prop->custom_func.user_data, range);
+ return;
+ }
+
+ float step, precision;
+ RNA_property_float_ui_range(&mpr_prop->ptr, mpr_prop->prop, &range[0], &range[1], &step, &precision);
+}
+
+/** \} */
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c
new file mode 100644
index 00000000000..e89d4cc6e81
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c
@@ -0,0 +1,156 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/wm_manipulator_type.c
+ * \ingroup wm
+ */
+
+#include "BKE_context.h"
+
+#include "BLI_ghash.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* only for own init/exit calls (wm_manipulatortype_init/wm_manipulatortype_free) */
+#include "wm.h"
+
+/* own includes */
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+
+
+/** \name Manipulator Type Append
+ *
+ * \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends.
+ * \{ */
+
+static GHash *global_manipulatortype_hash = NULL;
+
+const wmManipulatorType *WM_manipulatortype_find(const char *idname, bool quiet)
+{
+ if (idname[0]) {
+ wmManipulatorType *wt;
+
+ wt = BLI_ghash_lookup(global_manipulatortype_hash, idname);
+ if (wt) {
+ return wt;
+ }
+
+ if (!quiet) {
+ printf("search for unknown manipulator '%s'\n", idname);
+ }
+ }
+ else {
+ if (!quiet) {
+ printf("search for empty manipulator\n");
+ }
+ }
+
+ return NULL;
+}
+
+/* caller must free */
+void WM_manipulatortype_iter(GHashIterator *ghi)
+{
+ BLI_ghashIterator_init(ghi, global_manipulatortype_hash);
+}
+
+static wmManipulatorType *wm_manipulatortype_append__begin(void)
+{
+ wmManipulatorType *wt = MEM_callocN(sizeof(wmManipulatorType), "manipulatortype");
+ return wt;
+}
+static void wm_manipulatortype_append__end(wmManipulatorType *wt)
+{
+ BLI_assert(wt->struct_size >= sizeof(wmManipulator));
+
+ BLI_ghash_insert(global_manipulatortype_hash, (void *)wt->idname, wt);
+}
+
+void WM_manipulatortype_append(void (*wtfunc)(struct wmManipulatorType *))
+{
+ wmManipulatorType *wt = wm_manipulatortype_append__begin();
+ wtfunc(wt);
+ wm_manipulatortype_append__end(wt);
+}
+
+void WM_manipulatortype_append_ptr(void (*wtfunc)(struct wmManipulatorType *, void *), void *userdata)
+{
+ wmManipulatorType *mt = wm_manipulatortype_append__begin();
+ wtfunc(mt, userdata);
+ wm_manipulatortype_append__end(mt);
+}
+
+/**
+ * Free but don't remove from ghash.
+ */
+static void manipulatortype_free(wmManipulatorType *wt)
+{
+ MEM_freeN(wt);
+}
+
+void WM_manipulatortype_remove_ptr(wmManipulatorType *wt)
+{
+ BLI_assert(wt == WM_manipulatortype_find(wt->idname, false));
+
+ BLI_ghash_remove(global_manipulatortype_hash, wt->idname, NULL, NULL);
+
+ manipulatortype_free(wt);
+}
+
+bool WM_manipulatortype_remove(const char *idname)
+{
+ wmManipulatorType *wt = BLI_ghash_lookup(global_manipulatortype_hash, idname);
+
+ if (wt == NULL) {
+ return false;
+ }
+
+ WM_manipulatortype_remove_ptr(wt);
+
+ return true;
+}
+
+static void wm_manipulatortype_ghash_free_cb(wmManipulatorType *mt)
+{
+ manipulatortype_free(mt);
+}
+
+void wm_manipulatortype_free(void)
+{
+ BLI_ghash_free(global_manipulatortype_hash, NULL, (GHashValFreeFP)wm_manipulatortype_ghash_free_cb);
+ global_manipulatortype_hash = NULL;
+}
+
+/* called on initialize WM_init() */
+void wm_manipulatortype_init(void)
+{
+ /* reserve size is set based on blender default setup */
+ global_manipulatortype_hash = BLI_ghash_str_new_ex("wm_manipulatortype_init gh", 128);
+}
+
+/** \} */ \ No newline at end of file
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
index ac478fe5e95..3deef0cee5c 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
@@ -44,8 +44,6 @@
#include "BPY_extern.h"
-#include "DNA_manipulator_types.h"
-
#include "ED_screen.h"
#include "MEM_guardedalloc.h"
@@ -84,7 +82,7 @@ wmManipulatorGroup *wm_manipulatorgroup_new_from_type(
/* keep back-link */
mgroup->parent_mmap = mmap;
- BLI_addtail(&mmap->manipulator_groups, mgroup);
+ BLI_addtail(&mmap->groups, mgroup);
return mgroup;
}
@@ -118,7 +116,7 @@ void wm_manipulatorgroup_free(bContext *C, wmManipulatorGroup *mgroup)
MEM_SAFE_FREE(mgroup->customdata);
}
- BLI_remlink(&mmap->manipulator_groups, mgroup);
+ BLI_remlink(&mmap->groups, mgroup);
MEM_freeN(mgroup);
}
@@ -391,7 +389,11 @@ void MANIPULATORGROUP_OT_manipulator_tweak(wmOperatorType *ot)
ot->invoke = manipulator_tweak_invoke;
ot->modal = manipulator_tweak_modal;
+ /* TODO(campbell) This causes problems tweaking settings for operators,
+ * need to find a way to support this. */
+#if 0
ot->flag = OPTYPE_UNDO;
+#endif
}
/** \} */ // Manipulator operators
@@ -442,10 +444,11 @@ static wmKeyMap *manipulatorgroup_tweak_modal_keymap(wmKeyConfig *keyconf, const
/**
* Common default keymap for manipulator groups
*/
-wmKeyMap *WM_manipulatorgroup_keymap_common(const struct wmManipulatorGroupType *wgt, wmKeyConfig *config)
+wmKeyMap *WM_manipulatorgroup_keymap_common(
+ const wmManipulatorGroupType *wgt, wmKeyConfig *config)
{
/* Use area and region id since we might have multiple manipulators with the same name in different areas/regions */
- wmKeyMap *km = WM_keymap_find(config, wgt->name, wgt->spaceid, wgt->regionid);
+ wmKeyMap *km = WM_keymap_find(config, wgt->name, wgt->mmap_params.spaceid, wgt->mmap_params.regionid);
WM_keymap_add_item(km, "MANIPULATORGROUP_OT_manipulator_tweak", ACTIONMOUSE, KM_PRESS, KM_ANY, 0);
manipulatorgroup_tweak_modal_keymap(config, wgt->name);
@@ -456,10 +459,11 @@ wmKeyMap *WM_manipulatorgroup_keymap_common(const struct wmManipulatorGroupType
/**
* Variation of #WM_manipulatorgroup_keymap_common but with keymap items for selection
*/
-wmKeyMap *WM_manipulatorgroup_keymap_common_sel(const struct wmManipulatorGroupType *wgt, wmKeyConfig *config)
+wmKeyMap *WM_manipulatorgroup_keymap_common_select(
+ const wmManipulatorGroupType *wgt, wmKeyConfig *config)
{
/* Use area and region id since we might have multiple manipulators with the same name in different areas/regions */
- wmKeyMap *km = WM_keymap_find(config, wgt->name, wgt->spaceid, wgt->regionid);
+ wmKeyMap *km = WM_keymap_find(config, wgt->name, wgt->mmap_params.spaceid, wgt->mmap_params.regionid);
WM_keymap_add_item(km, "MANIPULATORGROUP_OT_manipulator_tweak", ACTIONMOUSE, KM_PRESS, KM_ANY, 0);
manipulatorgroup_tweak_modal_keymap(config, wgt->name);
@@ -483,99 +487,60 @@ wmKeyMap *WM_manipulatorgroup_keymap_common_sel(const struct wmManipulatorGroupT
*
* \{ */
-struct wmManipulatorGroupType *WM_manipulatorgrouptype_find(
- struct wmManipulatorMapType *mmaptype,
- const char *idname)
+struct wmManipulatorGroupTypeRef *WM_manipulatormaptype_group_find_ptr(
+ struct wmManipulatorMapType *mmap_type,
+ const wmManipulatorGroupType *wgt)
{
/* could use hash lookups as operator types do, for now simple search. */
- for (wmManipulatorGroupType *wgt = mmaptype->manipulator_grouptypes.first;
- wgt;
- wgt = wgt->next)
+ for (wmManipulatorGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first;
+ wgt_ref;
+ wgt_ref = wgt_ref->next)
{
- if (STREQ(idname, wgt->idname)) {
- return wgt;
+ if (wgt_ref->type == wgt) {
+ return wgt_ref;
}
}
return NULL;
}
-
-static wmManipulatorGroupType *wm_manipulatorgrouptype_append__begin(void)
-{
- wmManipulatorGroupType *wgt = MEM_callocN(sizeof(wmManipulatorGroupType), "manipulator-group");
- return wgt;
-}
-static void wm_manipulatorgrouptype_append__end(
- wmManipulatorMapType *mmaptype, wmManipulatorGroupType *wgt)
+struct wmManipulatorGroupTypeRef *WM_manipulatormaptype_group_find(
+ struct wmManipulatorMapType *mmap_type,
+ const char *idname)
{
- BLI_assert(wgt->name != NULL);
- BLI_assert(wgt->idname != NULL);
-
- wgt->spaceid = mmaptype->spaceid;
- wgt->regionid = mmaptype->regionid;
- BLI_strncpy(wgt->mapidname, mmaptype->idname, MAX_NAME);
- /* if not set, use default */
- if (!wgt->setup_keymap) {
- wgt->setup_keymap = WM_manipulatorgroup_keymap_common;
+ /* could use hash lookups as operator types do, for now simple search. */
+ for (wmManipulatorGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first;
+ wgt_ref;
+ wgt_ref = wgt_ref->next)
+ {
+ if (STREQ(idname, wgt_ref->type->idname)) {
+ return wgt_ref;
+ }
}
-
- /* add the type for future created areas of the same type */
- BLI_addtail(&mmaptype->manipulator_grouptypes, wgt);
+ return NULL;
}
/**
- * Use this for registering manipulators on startup. For runtime, use #WM_manipulatorgrouptype_append_runtime.
+ * Use this for registering manipulators on startup. For runtime, use #WM_manipulatormaptype_group_link_runtime.
*/
-wmManipulatorGroupType *WM_manipulatorgrouptype_append(
- wmManipulatorMapType *mmaptype, void (*wgt_func)(wmManipulatorGroupType *))
+wmManipulatorGroupTypeRef *WM_manipulatormaptype_group_link(
+ wmManipulatorMapType *mmap_type, const char *idname)
{
- wmManipulatorGroupType *wgt = wm_manipulatorgrouptype_append__begin();
- wgt_func(wgt);
- wm_manipulatorgrouptype_append__end(mmaptype, wgt);
- return wgt;
+ wmManipulatorGroupType *wgt = WM_manipulatorgrouptype_find(idname, false);
+ BLI_assert(wgt != NULL);
+ return WM_manipulatormaptype_group_link_ptr(mmap_type, wgt);
}
-wmManipulatorGroupType *WM_manipulatorgrouptype_append_ptr(
- wmManipulatorMapType *mmaptype, void (*wgt_func)(wmManipulatorGroupType *, void *),
- void *userdata)
+wmManipulatorGroupTypeRef *WM_manipulatormaptype_group_link_ptr(
+ wmManipulatorMapType *mmap_type, wmManipulatorGroupType *wgt)
{
- wmManipulatorGroupType *wgt = wm_manipulatorgrouptype_append__begin();
- wgt_func(wgt, userdata);
- wm_manipulatorgrouptype_append__end(mmaptype, wgt);
- return wgt;
+ wmManipulatorGroupTypeRef *wgt_ref = MEM_callocN(sizeof(wmManipulatorGroupTypeRef), "manipulator-group-ref");
+ wgt_ref->type = wgt;
+ BLI_addtail(&mmap_type->grouptype_refs, wgt_ref);
+ return wgt_ref;
}
-/**
- * Use this for registering manipulators on runtime.
- */
-wmManipulatorGroupType *WM_manipulatorgrouptype_append_runtime(
- const Main *main, wmManipulatorMapType *mmaptype,
- void (*wgt_func)(wmManipulatorGroupType *))
-{
- wmManipulatorGroupType *wgt = WM_manipulatorgrouptype_append(mmaptype, wgt_func);
-
- /* Main is missing on startup when we create new areas.
- * So this is only called for manipulators initialized on runtime */
- WM_manipulatorgrouptype_init_runtime(main, mmaptype, wgt);
-
- return wgt;
-}
-wmManipulatorGroupType *WM_manipulatorgrouptype_append_ptr_runtime(
- const Main *main, wmManipulatorMapType *mmaptype,
- void (*wgt_func)(wmManipulatorGroupType *, void *),
- void *userdata)
-{
- wmManipulatorGroupType *wgt = WM_manipulatorgrouptype_append_ptr(mmaptype, wgt_func, userdata);
-
- /* Main is missing on startup when we create new areas.
- * So this is only called for manipulators initialized on runtime */
- WM_manipulatorgrouptype_init_runtime(main, mmaptype, wgt);
-
- return wgt;
-}
-
-void WM_manipulatorgrouptype_init_runtime(
- const Main *bmain, wmManipulatorMapType *mmaptype,
+void WM_manipulatormaptype_group_init_runtime(
+ const Main *bmain, wmManipulatorMapType *mmap_type,
wmManipulatorGroupType *wgt)
{
/* init keymap - on startup there's an extra call to init keymaps for 'permanent' manipulator-groups */
@@ -588,7 +553,7 @@ void WM_manipulatorgrouptype_init_runtime(
ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
for (ARegion *ar = lb->first; ar; ar = ar->next) {
wmManipulatorMap *mmap = ar->manipulator_map;
- if (mmap && mmap->type == mmaptype) {
+ if (mmap && mmap->type == mmap_type) {
wm_manipulatorgroup_new_from_type(mmap, wgt);
/* just add here, drawing will occur on next update */
@@ -603,24 +568,27 @@ void WM_manipulatorgrouptype_init_runtime(
/**
- * Unlike #WM_manipulatorgrouptype_remove_ptr this doesn't maintain correct state, simply free.
+ * Unlike #WM_manipulatormaptype_group_unlink this doesn't maintain correct state, simply free.
*/
-void WM_manipulatorgrouptype_free(wmManipulatorGroupType *wgt)
+void WM_manipulatormaptype_group_free(wmManipulatorGroupTypeRef *wgt_ref)
{
- MEM_freeN(wgt);
+ MEM_freeN(wgt_ref);
}
-void WM_manipulatorgrouptype_remove_ptr(bContext *C, Main *bmain, wmManipulatorGroupType *wgt)
+void WM_manipulatormaptype_group_unlink(
+ bContext *C, Main *bmain, wmManipulatorMapType *mmap_type,
+ const wmManipulatorGroupType *wgt)
{
+ /* Free instances. */
for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) {
for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
for (ARegion *ar = lb->first; ar; ar = ar->next) {
wmManipulatorMap *mmap = ar->manipulator_map;
- if (mmap) {
+ if (mmap && mmap->type == mmap_type) {
wmManipulatorGroup *mgroup, *mgroup_next;
- for (mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup_next) {
+ for (mgroup = mmap->groups.first; mgroup; mgroup = mgroup_next) {
mgroup_next = mgroup->next;
if (mgroup->type == wgt) {
BLI_assert(mgroup->parent_mmap == mmap);
@@ -634,19 +602,80 @@ void WM_manipulatorgrouptype_remove_ptr(bContext *C, Main *bmain, wmManipulatorG
}
}
- wmManipulatorMapType *mmaptype = WM_manipulatormaptype_find(&(const struct wmManipulatorMapType_Params) {
- wgt->mapidname, wgt->spaceid,
- wgt->regionid});
-
- BLI_remlink(&mmaptype->manipulator_grouptypes, wgt);
- wgt->prev = wgt->next = NULL;
-
- WM_manipulatorgrouptype_free(wgt);
+ /* Free types. */
+ wmManipulatorGroupTypeRef *wgt_ref = WM_manipulatormaptype_group_find_ptr(mmap_type, wgt);
+ if (wgt_ref) {
+ BLI_remlink(&mmap_type->grouptype_refs, wgt_ref);
+ WM_manipulatormaptype_group_free(wgt_ref);
+ }
+ BLI_assert(WM_manipulatormaptype_group_find_ptr(mmap_type, wgt) == NULL);
}
-void wm_manipulatorgrouptype_setup_keymap(wmManipulatorGroupType *wgt, wmKeyConfig *keyconf)
+void wm_manipulatorgrouptype_setup_keymap(
+ wmManipulatorGroupType *wgt, wmKeyConfig *keyconf)
{
wgt->keymap = wgt->setup_keymap(wgt, keyconf);
}
/** \} */ /* wmManipulatorGroupType */
+
+/* -------------------------------------------------------------------- */
+/** \name High Level Add/Remove API
+ *
+ * For use directly from operators & RNA registration.
+ *
+ * \note In context of manipulator API these names are a bit misleading,
+ * but for general use terms its OK.
+ * `WM_manipulator_group_add` would be more correctly called:
+ * `WM_manipulatormaptype_grouptype_reference_link`
+ * but for general purpose API this is too detailed & annoying.
+ *
+ * \note We may want to return a value if there is nothing to remove.
+ *
+ * \{ */
+
+void WM_manipulator_group_add_ptr_ex(
+ wmManipulatorGroupType *wgt,
+ wmManipulatorMapType *mmap_type)
+{
+ WM_manipulatormaptype_group_link_ptr(mmap_type, wgt);
+
+ WM_manipulatorconfig_update_tag_init(mmap_type, wgt);
+}
+
+void WM_manipulator_group_add_ptr(
+ wmManipulatorGroupType *wgt)
+{
+ wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure(&wgt->mmap_params);
+ WM_manipulator_group_add_ptr_ex(wgt, mmap_type);
+}
+
+void WM_manipulator_group_add(const char *idname)
+{
+ wmManipulatorGroupType *wgt = WM_manipulatorgrouptype_find(idname, false);
+ BLI_assert(wgt != NULL);
+ WM_manipulator_group_add_ptr(wgt);
+}
+
+void WM_manipulator_group_remove_ptr_ex(
+ struct Main *bmain, wmManipulatorGroupType *wgt,
+ wmManipulatorMapType *mmap_type)
+{
+ WM_manipulatormaptype_group_unlink(NULL, bmain, mmap_type, wgt);
+}
+
+void WM_manipulator_group_remove_ptr(
+ struct Main *bmain, wmManipulatorGroupType *wgt)
+{
+ wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure(&wgt->mmap_params);
+ WM_manipulator_group_remove_ptr_ex(bmain, wgt, mmap_type);
+}
+
+void WM_manipulator_group_remove(struct Main *bmain, const char *idname)
+{
+ wmManipulatorGroupType *wgt = WM_manipulatorgrouptype_find(idname, false);
+ BLI_assert(wgt != NULL);
+ WM_manipulator_group_remove_ptr(bmain, wgt);
+}
+
+/** \} */
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup_type.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup_type.c
new file mode 100644
index 00000000000..a20aa0ec15f
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup_type.c
@@ -0,0 +1,185 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/wm_manipulatorgroup_type.c
+ * \ingroup wm
+ */
+
+#include "BKE_context.h"
+
+#include "BLI_ghash.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* only for own init/exit calls (wm_manipulatorgrouptype_init/wm_manipulatorgrouptype_free) */
+#include "wm.h"
+
+/* own includes */
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+
+
+/** \name ManipulatorGroup Type Append
+ *
+ * \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends.
+ * \{ */
+
+static GHash *global_manipulatorgrouptype_hash = NULL;
+
+wmManipulatorGroupType *WM_manipulatorgrouptype_find(const char *idname, bool quiet)
+{
+ if (idname[0]) {
+ wmManipulatorGroupType *wgt;
+
+ wgt = BLI_ghash_lookup(global_manipulatorgrouptype_hash, idname);
+ if (wgt) {
+ return wgt;
+ }
+
+ if (!quiet) {
+ printf("search for unknown manipulator group '%s'\n", idname);
+ }
+ }
+ else {
+ if (!quiet) {
+ printf("search for empty manipulator group\n");
+ }
+ }
+
+ return NULL;
+}
+
+/* caller must free */
+void WM_manipulatorgrouptype_iter(GHashIterator *ghi)
+{
+ BLI_ghashIterator_init(ghi, global_manipulatorgrouptype_hash);
+}
+
+static wmManipulatorGroupType *wm_manipulatorgrouptype_append__begin(void)
+{
+ wmManipulatorGroupType *wgt = MEM_callocN(sizeof(wmManipulatorGroupType), "manipulatorgrouptype");
+
+ return wgt;
+}
+static void wm_manipulatorgrouptype_append__end(wmManipulatorGroupType *wgt)
+{
+ BLI_assert(wgt->name != NULL);
+ BLI_assert(wgt->idname != NULL);
+
+ /* if not set, use default */
+ if (wgt->setup_keymap == NULL) {
+ wgt->setup_keymap = WM_manipulatorgroup_keymap_common;
+ }
+
+ BLI_ghash_insert(global_manipulatorgrouptype_hash, (void *)wgt->idname, wgt);
+}
+
+wmManipulatorGroupType *WM_manipulatorgrouptype_append(
+ void (*wtfunc)(struct wmManipulatorGroupType *))
+{
+ wmManipulatorGroupType *wgt = wm_manipulatorgrouptype_append__begin();
+ wtfunc(wgt);
+ wm_manipulatorgrouptype_append__end(wgt);
+ return wgt;
+}
+
+wmManipulatorGroupType *WM_manipulatorgrouptype_append_ptr(
+ void (*wtfunc)(struct wmManipulatorGroupType *, void *), void *userdata)
+{
+ wmManipulatorGroupType *wgt = wm_manipulatorgrouptype_append__begin();
+ wtfunc(wgt, userdata);
+ wm_manipulatorgrouptype_append__end(wgt);
+ return wgt;
+}
+
+/**
+ * Append and insert into a manipulator typemap.
+ * This is most common for C manipulators which are enabled by default.
+ */
+wmManipulatorGroupTypeRef *WM_manipulatorgrouptype_append_and_link(
+ wmManipulatorMapType *mmap_type,
+ void (*wtfunc)(struct wmManipulatorGroupType *))
+{
+ wmManipulatorGroupType *wgt = WM_manipulatorgrouptype_append(wtfunc);
+
+ wgt->mmap_params.spaceid = mmap_type->spaceid;
+ wgt->mmap_params.regionid = mmap_type->regionid;
+
+ return WM_manipulatormaptype_group_link_ptr(mmap_type, wgt);
+}
+
+/**
+ * Free but don't remove from ghash.
+ */
+static void manipulatorgrouptype_free(wmManipulatorGroupType *wgt)
+{
+ MEM_freeN(wgt);
+}
+
+void WM_manipulatorgrouptype_remove_ptr(wmManipulatorGroupType *wgt)
+{
+ BLI_assert(wgt == WM_manipulatorgrouptype_find(wgt->idname, false));
+
+ BLI_ghash_remove(global_manipulatorgrouptype_hash, wgt->idname, NULL, NULL);
+
+ manipulatorgrouptype_free(wgt);
+
+ /* XXX, TODO, update the world! */
+}
+
+bool WM_manipulatorgrouptype_remove(const char *idname)
+{
+ wmManipulatorGroupType *wgt = BLI_ghash_lookup(global_manipulatorgrouptype_hash, idname);
+
+ if (wgt == NULL) {
+ return false;
+ }
+
+ WM_manipulatorgrouptype_remove_ptr(wgt);
+
+ return true;
+}
+
+static void wm_manipulatorgrouptype_ghash_free_cb(wmManipulatorGroupType *mt)
+{
+ manipulatorgrouptype_free(mt);
+}
+
+void wm_manipulatorgrouptype_free(void)
+{
+ BLI_ghash_free(global_manipulatorgrouptype_hash, NULL, (GHashValFreeFP)wm_manipulatorgrouptype_ghash_free_cb);
+ global_manipulatorgrouptype_hash = NULL;
+}
+
+/* called on initialize WM_init() */
+void wm_manipulatorgrouptype_init(void)
+{
+ /* reserve size is set based on blender default setup */
+ global_manipulatorgrouptype_hash = BLI_ghash_str_new_ex("wm_manipulatorgrouptype_init gh", 128);
+}
+
+/** \} */ \ No newline at end of file
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
index 51466426d79..123c46f9c50 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
@@ -29,14 +29,13 @@
#include <string.h>
-#include "BKE_context.h"
-
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_ghash.h"
-#include "DNA_manipulator_types.h"
+#include "BKE_context.h"
+#include "BKE_global.h"
#include "ED_screen.h"
#include "ED_view3d.h"
@@ -62,6 +61,16 @@
static ListBase manipulatormaptypes = {NULL, NULL};
/**
+ * Update when manipulator-map types change.
+ */
+/* so operator removal can trigger update */
+enum {
+ WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT = (1 << 0),
+};
+
+static char wm_mmap_type_update_flag = 0;
+
+/**
* Manipulator-map update tagging.
*/
enum eManipulatorMapUpdateFlags {
@@ -80,17 +89,17 @@ enum eManipulatorMapUpdateFlags {
*/
wmManipulatorMap *WM_manipulatormap_new_from_type(const struct wmManipulatorMapType_Params *mmap_params)
{
- wmManipulatorMapType *mmaptype = WM_manipulatormaptype_ensure(mmap_params);
+ wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure(mmap_params);
wmManipulatorMap *mmap;
mmap = MEM_callocN(sizeof(wmManipulatorMap), "ManipulatorMap");
- mmap->type = mmaptype;
+ mmap->type = mmap_type;
mmap->update_flag = MANIPULATORMAP_REFRESH;
/* create all manipulator-groups for this manipulator-map. We may create an empty one
* too in anticipation of manipulators from operators etc */
- for (wmManipulatorGroupType *wgt = mmaptype->manipulator_grouptypes.first; wgt; wgt = wgt->next) {
- wm_manipulatorgroup_new_from_type(mmap, wgt);
+ for (wmManipulatorGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first; wgt_ref; wgt_ref = wgt_ref->next) {
+ wm_manipulatorgroup_new_from_type(mmap, wgt_ref->type);
}
return mmap;
@@ -107,12 +116,12 @@ void wm_manipulatormap_remove(wmManipulatorMap *mmap)
if (!mmap)
return;
- for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first, *mgroup_next; mgroup; mgroup = mgroup_next) {
+ for (wmManipulatorGroup *mgroup = mmap->groups.first, *mgroup_next; mgroup; mgroup = mgroup_next) {
mgroup_next = mgroup->next;
BLI_assert(mgroup->parent_mmap == mmap);
wm_manipulatorgroup_free(NULL, mgroup);
}
- BLI_assert(BLI_listbase_is_empty(&mmap->manipulator_groups));
+ BLI_assert(BLI_listbase_is_empty(&mmap->groups));
wm_manipulatormap_selected_clear(mmap);
@@ -133,7 +142,7 @@ static GHash *WM_manipulatormap_manipulator_hash_new(
GHash *hash = BLI_ghash_str_new(__func__);
/* collect manipulators */
- for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup->next) {
+ for (wmManipulatorGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) {
if (!mgroup->type->poll || mgroup->type->poll(C, mgroup->type)) {
for (wmManipulator *mpr = mgroup->manipulators.first; mpr; mpr = mpr->next) {
if ((include_hidden || (mpr->flag & WM_MANIPULATOR_HIDDEN) == 0) &&
@@ -183,7 +192,7 @@ static bool manipulator_prepare_drawing(
static void manipulatormap_prepare_drawing(
wmManipulatorMap *mmap, const bContext *C, ListBase *draw_manipulators, const int drawstep)
{
- if (!mmap || BLI_listbase_is_empty(&mmap->manipulator_groups))
+ if (!mmap || BLI_listbase_is_empty(&mmap->groups))
return;
wmManipulator *active_manipulator = mmap->mmap_context.active;
@@ -196,7 +205,7 @@ static void manipulatormap_prepare_drawing(
return;
}
- for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup->next) {
+ for (wmManipulatorGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) {
/* check group visibility - drawstep first to avoid unnecessary call of group poll callback */
if (!wm_manipulatorgroup_is_visible_in_drawstep(mgroup, drawstep) ||
!wm_manipulatorgroup_is_visible(mgroup, C))
@@ -232,7 +241,7 @@ static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext
{
if (!mmap)
return;
- BLI_assert(!BLI_listbase_is_empty(&mmap->manipulator_groups));
+ BLI_assert(!BLI_listbase_is_empty(&mmap->groups));
const bool draw_multisample = (U.ogl_multisamples != USER_MULTISAMPLE_NONE);
@@ -366,7 +375,7 @@ wmManipulator *wm_manipulatormap_highlight_find(
wmManipulator *mpr = NULL;
ListBase visible_3d_manipulators = {NULL};
- for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup->next) {
+ for (wmManipulatorGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) {
if (wm_manipulatorgroup_is_visible(mgroup, C)) {
if (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) {
wm_manipulatorgroup_intersectable_manipulators_to_list(mgroup, &visible_3d_manipulators);
@@ -700,12 +709,11 @@ wmManipulator *wm_manipulatormap_active_get(wmManipulatorMap *mmap)
wmManipulatorMapType *WM_manipulatormaptype_find(
const struct wmManipulatorMapType_Params *mmap_params)
{
- for (wmManipulatorMapType *mmaptype = manipulatormaptypes.first; mmaptype; mmaptype = mmaptype->next) {
- if (mmaptype->spaceid == mmap_params->spaceid &&
- mmaptype->regionid == mmap_params->regionid &&
- STREQ(mmaptype->idname, mmap_params->idname))
+ for (wmManipulatorMapType *mmap_type = manipulatormaptypes.first; mmap_type; mmap_type = mmap_type->next) {
+ if (mmap_type->spaceid == mmap_params->spaceid &&
+ mmap_type->regionid == mmap_params->regionid)
{
- return mmaptype;
+ return mmap_type;
}
}
@@ -715,36 +723,35 @@ wmManipulatorMapType *WM_manipulatormaptype_find(
wmManipulatorMapType *WM_manipulatormaptype_ensure(
const struct wmManipulatorMapType_Params *mmap_params)
{
- wmManipulatorMapType *mmaptype = WM_manipulatormaptype_find(mmap_params);
+ wmManipulatorMapType *mmap_type = WM_manipulatormaptype_find(mmap_params);
- if (mmaptype) {
- return mmaptype;
+ if (mmap_type) {
+ return mmap_type;
}
- mmaptype = MEM_callocN(sizeof(wmManipulatorMapType), "manipulatortype list");
- mmaptype->spaceid = mmap_params->spaceid;
- mmaptype->regionid = mmap_params->regionid;
- BLI_strncpy(mmaptype->idname, mmap_params->idname, sizeof(mmaptype->idname));
- BLI_addhead(&manipulatormaptypes, mmaptype);
+ mmap_type = MEM_callocN(sizeof(wmManipulatorMapType), "manipulatortype list");
+ mmap_type->spaceid = mmap_params->spaceid;
+ mmap_type->regionid = mmap_params->regionid;
+ BLI_addhead(&manipulatormaptypes, mmap_type);
- return mmaptype;
+ return mmap_type;
}
void wm_manipulatormaptypes_free(void)
{
- for (wmManipulatorMapType *mmaptype = manipulatormaptypes.first, *mmaptype_next;
- mmaptype;
- mmaptype = mmaptype_next)
+ for (wmManipulatorMapType *mmap_type = manipulatormaptypes.first, *mmap_type_next;
+ mmap_type;
+ mmap_type = mmap_type_next)
{
- mmaptype_next = mmaptype->next;
- for (wmManipulatorGroupType *wgt = mmaptype->manipulator_grouptypes.first, *wgt_next;
- wgt;
- wgt = wgt_next)
+ mmap_type_next = mmap_type->next;
+ for (wmManipulatorGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first, *wgt_next;
+ wgt_ref;
+ wgt_ref = wgt_next)
{
- wgt_next = wgt->next;
- WM_manipulatorgrouptype_free(wgt);
+ wgt_next = wgt_ref->next;
+ WM_manipulatormaptype_group_free(wgt_ref);
}
- MEM_freeN(mmaptype);
+ MEM_freeN(mmap_type);
}
}
@@ -753,18 +760,64 @@ void wm_manipulatormaptypes_free(void)
*/
void wm_manipulators_keymap(wmKeyConfig *keyconf)
{
- wmManipulatorMapType *mmaptype;
- wmManipulatorGroupType *wgt;
-
/* we add this item-less keymap once and use it to group manipulator-group keymaps into it */
WM_keymap_find(keyconf, "Manipulators", 0, 0);
- for (mmaptype = manipulatormaptypes.first; mmaptype; mmaptype = mmaptype->next) {
- for (wgt = mmaptype->manipulator_grouptypes.first; wgt; wgt = wgt->next) {
- wm_manipulatorgrouptype_setup_keymap(wgt, keyconf);
+ for (wmManipulatorMapType *mmap_type = manipulatormaptypes.first; mmap_type; mmap_type = mmap_type->next) {
+ for (wmManipulatorGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first; wgt_ref; wgt_ref = wgt_ref->next) {
+ wm_manipulatorgrouptype_setup_keymap(wgt_ref->type, keyconf);
}
}
}
/** \} */ /* wmManipulatorMapType */
+/* -------------------------------------------------------------------- */
+/** \name Updates for Dynamic Type Registraion
+ *
+ * \{ */
+
+
+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;
+ wgt->type_update_flag |= WM_MANIPULATORMAPTYPE_UPDATE_INIT;
+
+ wm_mmap_type_update_flag |= WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT;
+}
+
+/**
+ * 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)
+{
+ if (G.background)
+ return;
+
+ if (wm_mmap_type_update_flag == 0)
+ return;
+
+ if (wm_mmap_type_update_flag & WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT) {
+ for (wmManipulatorMapType *mmap_type = manipulatormaptypes.first;
+ mmap_type;
+ mmap_type = mmap_type->next)
+ {
+ if (mmap_type->type_update_flag & WM_MANIPULATORMAPTYPE_UPDATE_INIT) {
+ mmap_type->type_update_flag &= ~WM_MANIPULATORMAPTYPE_UPDATE_INIT;
+ for (wmManipulatorGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first;
+ wgt_ref;
+ wgt_ref = wgt_ref->next)
+ {
+ wgt_ref->type->type_update_flag &= ~WM_MANIPULATORMAPTYPE_UPDATE_INIT;
+ WM_manipulatormaptype_group_init_runtime(bmain, mmap_type, wgt_ref->type);
+ }
+ }
+ }
+
+ wm_mmap_type_update_flag &= ~WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT;
+ }
+}
+
+/** \} */
diff --git a/source/blender/windowmanager/manipulators/wm_manipulator_fn.h b/source/blender/windowmanager/manipulators/wm_manipulator_fn.h
index ce21c90195d..41e603fc521 100644
--- a/source/blender/windowmanager/manipulators/wm_manipulator_fn.h
+++ b/source/blender/windowmanager/manipulators/wm_manipulator_fn.h
@@ -30,10 +30,18 @@
#include "BLI_compiler_attrs.h"
/* wmManipulatorGroup */
-typedef bool (*wmManipulatorGroupFnPoll)(const struct bContext *, struct wmManipulatorGroupType *) ATTR_WARN_UNUSED_RESULT;
-typedef void (*wmManipulatorGroupFnInit)(const struct bContext *, struct wmManipulatorGroup *);
-typedef void (*wmManipulatorGroupFnRefresh)(const struct bContext *, struct wmManipulatorGroup *);
-typedef void (*wmManipulatorGroupFnDrawPrepare)(const struct bContext *, struct wmManipulatorGroup *);
+typedef bool (*wmManipulatorGroupFnPoll)(
+ const struct bContext *, struct wmManipulatorGroupType *)
+ ATTR_WARN_UNUSED_RESULT;
+typedef void (*wmManipulatorGroupFnInit)(
+ const struct bContext *, struct wmManipulatorGroup *);
+typedef void (*wmManipulatorGroupFnRefresh)(
+ const struct bContext *, struct wmManipulatorGroup *);
+typedef void (*wmManipulatorGroupFnDrawPrepare)(
+ const struct bContext *, struct wmManipulatorGroup *);
+typedef struct wmKeyMap *(*wmManipulatorGroupFnSetupKeymap)(
+ const struct wmManipulatorGroupType *, struct wmKeyConfig *)
+ ATTR_WARN_UNUSED_RESULT;
/* wmManipulator */
/* See: wmManipulatorType for docs on each type. */
@@ -48,4 +56,22 @@ typedef void (*wmManipulatorFnExit)(struct bContext *, struct wmManipulator *
typedef int (*wmManipulatorFnCursorGet)(struct wmManipulator *);
typedef void (*wmManipulatorFnSelect)(struct bContext *, struct wmManipulator *, const int);
+/* wmManipulatorProperty */
+typedef void (*wmManipulatorPropertyFnGet)(
+ const struct wmManipulator *, struct wmManipulatorProperty *, void *user_data,
+ float *value, uint value_len);
+typedef void (*wmManipulatorPropertyFnSet)(
+ const struct wmManipulator *, struct wmManipulatorProperty *, void *user_data,
+ const float *value, uint value_len);
+typedef void (*wmManipulatorPropertyFnRangeGet)(
+ const struct wmManipulator *, struct wmManipulatorProperty *, void *user_data,
+ float range[2]);
+
+typedef struct wmManipulatorPropertyFnParams {
+ wmManipulatorPropertyFnGet value_get_fn;
+ wmManipulatorPropertyFnSet value_set_fn;
+ wmManipulatorPropertyFnRangeGet range_get_fn;
+ void *user_data;
+} wmManipulatorPropertyFnParams;
+
#endif /* __WM_MANIPULATOR_FN_H__ */
diff --git a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h
index d14d4e169b1..61489b6a730 100644
--- a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h
+++ b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h
@@ -47,12 +47,14 @@ struct wmOperator;
/* -------------------------------------------------------------------- */
/* wmManipulator */
-struct wmManipulatorGroup *wm_manipulator_get_parent_group(const struct wmManipulator *mpr);
-
-/* wm_manipulator.c, for init/exit */
+/* wm_manipulator_type.c, for init/exit */
void wm_manipulatortype_free(void);
void wm_manipulatortype_init(void);
+/* wm_manipulatorgroup_type.c, for init/exit */
+void wm_manipulatorgrouptype_free(void);
+void wm_manipulatorgrouptype_init(void);
+
/* -------------------------------------------------------------------- */
/* wmManipulatorGroup */
@@ -63,7 +65,6 @@ void MANIPULATORGROUP_OT_manipulator_tweak(struct wmOperatorType *ot);
/* wmManipulatorMap */
void wm_manipulatormap_remove(struct wmManipulatorMap *mmap);
-void wm_manipulatormaptypes_free(void);
void wm_manipulators_keymap(struct wmKeyConfig *keyconf);
@@ -83,5 +84,10 @@ void wm_manipulatormap_active_set(
const struct wmEvent *event, struct wmManipulator *mpr);
struct wmManipulator *wm_manipulatormap_active_get(struct wmManipulatorMap *mmap);
+/* -------------------------------------------------------------------- */
+/* wmManipulatorMapType */
+
+void wm_manipulatormaptypes_free(void);
+
#endif /* __WM_MANIPULATOR_WMAPI_H__ */