Merge branch 'master' into blender2.8
[blender.git] / source / blender / makesrna / intern / rna_wm_manipulator.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/makesrna/intern/rna_wm_manipulator.c
22  *  \ingroup RNA
23  */
24
25 #include <stdlib.h>
26
27 #include "DNA_screen_types.h"
28 #include "DNA_space_types.h"
29 #include "DNA_userdef_types.h"
30 #include "DNA_view3d_types.h"
31 #include "DNA_windowmanager_types.h"
32
33 #include "BLI_utildefines.h"
34 #include "BLI_string_utils.h"
35
36 #include "BLT_translation.h"
37
38 #include "RNA_access.h"
39 #include "RNA_define.h"
40 #include "RNA_enum_types.h"
41
42 #include "rna_internal.h"
43
44 #include "WM_api.h"
45 #include "WM_types.h"
46
47 #ifdef RNA_RUNTIME
48 /* enum definitions */
49 #endif /* RNA_RUNTIME */
50
51 #ifdef RNA_RUNTIME
52
53 #include <assert.h>
54
55 #include "WM_api.h"
56 #include "WM_types.h"
57
58 #include "DNA_workspace_types.h"
59
60 #include "ED_screen.h"
61
62 #include "UI_interface.h"
63
64 #include "BKE_global.h"
65 #include "BKE_idprop.h"
66 #include "BKE_workspace.h"
67 #include "BKE_utildefines.h"
68
69 #include "MEM_guardedalloc.h"
70
71 #ifdef WITH_PYTHON
72 #  include "BPY_extern.h"
73 #endif
74
75 /* -------------------------------------------------------------------- */
76
77 /** \name Manipulator API
78  * \{ */
79
80 static void rna_manipulator_draw_cb(
81         const struct bContext *C, struct wmManipulator *mpr)
82 {
83         extern FunctionRNA rna_Manipulator_draw_func;
84         wmManipulatorGroup *mgroup = mpr->parent_mgroup;
85         PointerRNA mpr_ptr;
86         ParameterList list;
87         FunctionRNA *func;
88         RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr);
89         /* RNA_struct_find_function(&mpr_ptr, "draw"); */
90         func = &rna_Manipulator_draw_func;
91         RNA_parameter_list_create(&list, &mpr_ptr, func);
92         RNA_parameter_set_lookup(&list, "context", &C);
93         mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list);
94         RNA_parameter_list_free(&list);
95 }
96
97 static void rna_manipulator_draw_select_cb(
98         const struct bContext *C, struct wmManipulator *mpr, int select_id)
99 {
100         extern FunctionRNA rna_Manipulator_draw_select_func;
101         wmManipulatorGroup *mgroup = mpr->parent_mgroup;
102         PointerRNA mpr_ptr;
103         ParameterList list;
104         FunctionRNA *func;
105         RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr);
106         /* RNA_struct_find_function(&mpr_ptr, "draw_select"); */
107         func = &rna_Manipulator_draw_select_func;
108         RNA_parameter_list_create(&list, &mpr_ptr, func);
109         RNA_parameter_set_lookup(&list, "context", &C);
110         RNA_parameter_set_lookup(&list, "select_id", &select_id);
111         mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list);
112         RNA_parameter_list_free(&list);
113 }
114
115 static int rna_manipulator_test_select_cb(
116         struct bContext *C, struct wmManipulator *mpr, const struct wmEvent *event)
117 {
118         extern FunctionRNA rna_Manipulator_test_select_func;
119         wmManipulatorGroup *mgroup = mpr->parent_mgroup;
120         PointerRNA mpr_ptr;
121         ParameterList list;
122         FunctionRNA *func;
123         RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr);
124         /* RNA_struct_find_function(&mpr_ptr, "test_select"); */
125         func = &rna_Manipulator_test_select_func;
126         RNA_parameter_list_create(&list, &mpr_ptr, func);
127         RNA_parameter_set_lookup(&list, "context", &C);
128         RNA_parameter_set_lookup(&list, "event", &event);
129         mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list);
130
131         void *ret;
132         RNA_parameter_get_lookup(&list, "intersect_id", &ret);
133         int intersect_id = *(int *)ret;
134
135         RNA_parameter_list_free(&list);
136         return intersect_id;
137 }
138
139 static int rna_manipulator_modal_cb(
140         struct bContext *C, struct wmManipulator *mpr, const struct wmEvent *event,
141         eWM_ManipulatorTweak tweak_flag)
142 {
143         extern FunctionRNA rna_Manipulator_modal_func;
144         wmManipulatorGroup *mgroup = mpr->parent_mgroup;
145         PointerRNA mpr_ptr;
146         ParameterList list;
147         FunctionRNA *func;
148         const int tweak_flag_int = tweak_flag;
149         RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr);
150         /* RNA_struct_find_function(&mpr_ptr, "modal"); */
151         func = &rna_Manipulator_modal_func;
152         RNA_parameter_list_create(&list, &mpr_ptr, func);
153         RNA_parameter_set_lookup(&list, "context", &C);
154         RNA_parameter_set_lookup(&list, "event", &event);
155         RNA_parameter_set_lookup(&list, "tweak", &tweak_flag_int);
156         mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list);
157
158         void *ret;
159         RNA_parameter_get_lookup(&list, "result", &ret);
160         int ret_enum = *(int *)ret;
161
162         RNA_parameter_list_free(&list);
163         return ret_enum;
164 }
165
166 static void rna_manipulator_setup_cb(
167         struct wmManipulator *mpr)
168 {
169         extern FunctionRNA rna_Manipulator_setup_func;
170         wmManipulatorGroup *mgroup = mpr->parent_mgroup;
171         PointerRNA mpr_ptr;
172         ParameterList list;
173         FunctionRNA *func;
174         RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr);
175         /* RNA_struct_find_function(&mpr_ptr, "setup"); */
176         func = &rna_Manipulator_setup_func;
177         RNA_parameter_list_create(&list, &mpr_ptr, func);
178         mgroup->type->ext.call((bContext *)NULL, &mpr_ptr, func, &list);
179         RNA_parameter_list_free(&list);
180 }
181
182
183 static int rna_manipulator_invoke_cb(
184         struct bContext *C, struct wmManipulator *mpr, const struct wmEvent *event)
185 {
186         extern FunctionRNA rna_Manipulator_invoke_func;
187         wmManipulatorGroup *mgroup = mpr->parent_mgroup;
188         PointerRNA mpr_ptr;
189         ParameterList list;
190         FunctionRNA *func;
191         RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr);
192         /* RNA_struct_find_function(&mpr_ptr, "invoke"); */
193         func = &rna_Manipulator_invoke_func;
194         RNA_parameter_list_create(&list, &mpr_ptr, func);
195         RNA_parameter_set_lookup(&list, "context", &C);
196         RNA_parameter_set_lookup(&list, "event", &event);
197         mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list);
198
199         void *ret;
200         RNA_parameter_get_lookup(&list, "result", &ret);
201         int ret_enum = *(int *)ret;
202
203         RNA_parameter_list_free(&list);
204         return ret_enum;
205 }
206
207 static void rna_manipulator_exit_cb(
208         struct bContext *C, struct wmManipulator *mpr, bool cancel)
209 {
210         extern FunctionRNA rna_Manipulator_exit_func;
211         wmManipulatorGroup *mgroup = mpr->parent_mgroup;
212         PointerRNA mpr_ptr;
213         ParameterList list;
214         FunctionRNA *func;
215         RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr);
216         /* RNA_struct_find_function(&mpr_ptr, "exit"); */
217         func = &rna_Manipulator_exit_func;
218         RNA_parameter_list_create(&list, &mpr_ptr, func);
219         RNA_parameter_set_lookup(&list, "context", &C);
220         {
221                 int cancel_i = cancel;
222                 RNA_parameter_set_lookup(&list, "cancel", &cancel_i);
223         }
224         mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list);
225         RNA_parameter_list_free(&list);
226 }
227
228 static void rna_manipulator_select_refresh_cb(
229         struct wmManipulator *mpr)
230 {
231         extern FunctionRNA rna_Manipulator_select_refresh_func;
232         wmManipulatorGroup *mgroup = mpr->parent_mgroup;
233         PointerRNA mpr_ptr;
234         ParameterList list;
235         FunctionRNA *func;
236         RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr);
237         /* RNA_struct_find_function(&mpr_ptr, "select_refresh"); */
238         func = &rna_Manipulator_select_refresh_func;
239         RNA_parameter_list_create(&list, &mpr_ptr, func);
240         mgroup->type->ext.call((bContext *)NULL, &mpr_ptr, func, &list);
241         RNA_parameter_list_free(&list);
242 }
243
244 /* just to work around 'const char *' warning and to ensure this is a python op */
245 static void rna_Manipulator_bl_idname_set(PointerRNA *ptr, const char *value)
246 {
247         wmManipulator *data = ptr->data;
248         char *str = (char *)data->type->idname;
249         if (!str[0]) {
250                 BLI_strncpy(str, value, MAX_NAME);    /* utf8 already ensured */
251         }
252         else {
253                 assert(!"setting the bl_idname on a non-builtin operator");
254         }
255 }
256
257 static wmManipulator *rna_ManipulatorProperties_find_operator(PointerRNA *ptr)
258 {
259 #if 0
260         wmWindowManager *wm = ptr->id.data;
261 #endif
262
263         /* We could try workaruond this lookup, but not trivial. */
264         for (bScreen *screen = G.main->screen.first; screen; screen = screen->id.next) {
265                 IDProperty *properties = ptr->data;
266                 for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
267                         for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
268                                 if (ar->manipulator_map) {
269                                         wmManipulatorMap *mmap = ar->manipulator_map;
270                                         for (wmManipulatorGroup *mgroup = WM_manipulatormap_group_list(mmap)->first;
271                                              mgroup;
272                                              mgroup = mgroup->next)
273                                         {
274                                                 for (wmManipulator *mpr = mgroup->manipulators.first; mpr; mpr = mpr->next) {
275                                                         if (mpr->properties == properties) {
276                                                                 return mpr;
277                                                         }
278                                                 }
279                                         }
280                                 }
281                         }
282                 }
283         }
284         return NULL;
285 }
286
287 static StructRNA *rna_ManipulatorProperties_refine(PointerRNA *ptr)
288 {
289         wmManipulator *mpr = rna_ManipulatorProperties_find_operator(ptr);
290
291         if (mpr)
292                 return mpr->type->srna;
293         else
294                 return ptr->type;
295 }
296
297 static IDProperty *rna_ManipulatorProperties_idprops(PointerRNA *ptr, bool create)
298 {
299         if (create && !ptr->data) {
300                 IDPropertyTemplate val = {0};
301                 ptr->data = IDP_New(IDP_GROUP, &val, "RNA_ManipulatorProperties group");
302         }
303
304         return ptr->data;
305 }
306
307 static PointerRNA rna_Manipulator_properties_get(PointerRNA *ptr)
308 {
309         wmManipulator *mpr = ptr->data;
310         return rna_pointer_inherit_refine(ptr, mpr->type->srna, mpr->properties);
311 }
312
313 /* wmManipulator.float */
314 #define RNA_MANIPULATOR_GENERIC_FLOAT_RW_DEF(func_id, member_id) \
315 static float rna_Manipulator_##func_id##_get(PointerRNA *ptr) \
316 { \
317         wmManipulator *mpr = ptr->data; \
318         return mpr->member_id; \
319 } \
320 static void rna_Manipulator_##func_id##_set(PointerRNA *ptr, float value) \
321 { \
322         wmManipulator *mpr = ptr->data; \
323         mpr->member_id = value; \
324 }
325 #define RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_INDEX_RW_DEF(func_id, member_id, index) \
326 static float rna_Manipulator_##func_id##_get(PointerRNA *ptr) \
327 { \
328         wmManipulator *mpr = ptr->data; \
329         return mpr->member_id[index]; \
330 } \
331 static void rna_Manipulator_##func_id##_set(PointerRNA *ptr, float value) \
332 { \
333         wmManipulator *mpr = ptr->data; \
334         mpr->member_id[index] = value; \
335 }
336 /* wmManipulator.float[len] */
337 #define RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(func_id, member_id, len) \
338 static void rna_Manipulator_##func_id##_get(PointerRNA *ptr, float value[len]) \
339 { \
340         wmManipulator *mpr = ptr->data; \
341         memcpy(value, mpr->member_id, sizeof(float[len])); \
342 } \
343 static void rna_Manipulator_##func_id##_set(PointerRNA *ptr, const float value[len]) \
344 { \
345         wmManipulator *mpr = ptr->data; \
346         memcpy(mpr->member_id, value, sizeof(float[len])); \
347 }
348
349 /* wmManipulator.flag */
350 #define RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(func_id, member_id, flag_value) \
351 static int rna_Manipulator_##func_id##_get(PointerRNA *ptr) \
352 { \
353         wmManipulator *mpr = ptr->data; \
354         return (mpr->member_id & flag_value) != 0; \
355 } \
356 static void rna_Manipulator_##func_id##_set(PointerRNA *ptr, int value) \
357 { \
358         wmManipulator *mpr = ptr->data; \
359         BKE_BIT_TEST_SET(mpr->member_id, value, flag_value); \
360 }
361
362 /* wmManipulator.flag (negative) */
363 #define RNA_MANIPULATOR_GENERIC_FLAG_NEG_RW_DEF(func_id, member_id, flag_value) \
364 static int rna_Manipulator_##func_id##_get(PointerRNA *ptr) \
365 { \
366         wmManipulator *mpr = ptr->data; \
367         return (mpr->member_id & flag_value) == 0; \
368 } \
369 static void rna_Manipulator_##func_id##_set(PointerRNA *ptr, int value) \
370 { \
371         wmManipulator *mpr = ptr->data; \
372         BKE_BIT_TEST_SET(mpr->member_id, !value, flag_value); \
373 }
374
375 #define RNA_MANIPULATOR_FLAG_RO_DEF(func_id, member_id, flag_value) \
376 static int rna_Manipulator_##func_id##_get(PointerRNA *ptr) \
377 { \
378         wmManipulator *mpr = ptr->data; \
379         return (mpr->member_id & flag_value) != 0; \
380 }
381
382 RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(color, color, 3);
383 RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(color_hi, color_hi, 3);
384
385 RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_INDEX_RW_DEF(alpha, color, 3);
386 RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_INDEX_RW_DEF(alpha_hi, color_hi, 3);
387
388 RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(matrix_space, matrix_space, 16);
389 RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(matrix_basis, matrix_basis, 16);
390 RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(matrix_offset, matrix_offset, 16);
391
392 static void rna_Manipulator_matrix_world_get(PointerRNA *ptr, float value[16])
393 {
394         wmManipulator *mpr = ptr->data;
395         WM_manipulator_calc_matrix_final(mpr, (float (*)[4])value);
396 }
397
398 RNA_MANIPULATOR_GENERIC_FLOAT_RW_DEF(scale_basis, scale_basis);
399 RNA_MANIPULATOR_GENERIC_FLOAT_RW_DEF(line_width, line_width);
400
401 RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_hover, flag, WM_MANIPULATOR_DRAW_HOVER);
402 RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_modal, flag, WM_MANIPULATOR_DRAW_MODAL);
403 RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_value, flag, WM_MANIPULATOR_DRAW_VALUE);
404 RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_offset_scale, flag, WM_MANIPULATOR_DRAW_OFFSET_SCALE);
405 RNA_MANIPULATOR_GENERIC_FLAG_NEG_RW_DEF(flag_use_draw_scale, flag, WM_MANIPULATOR_DRAW_OFFSET_SCALE);
406 RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_hide, flag, WM_MANIPULATOR_HIDDEN);
407
408 /* wmManipulator.state */
409 RNA_MANIPULATOR_FLAG_RO_DEF(state_is_highlight, state, WM_MANIPULATOR_STATE_HIGHLIGHT);
410 RNA_MANIPULATOR_FLAG_RO_DEF(state_is_modal, state, WM_MANIPULATOR_STATE_MODAL);
411 RNA_MANIPULATOR_FLAG_RO_DEF(state_select, state, WM_MANIPULATOR_STATE_SELECT);
412
413 static void rna_Manipulator_state_select_set(struct PointerRNA *ptr, int value)
414 {
415         wmManipulator *mpr = ptr->data;
416         wmManipulatorGroup *mgroup = mpr->parent_mgroup;
417         WM_manipulator_select_set(mgroup->parent_mmap, mpr, value);
418 }
419
420 static PointerRNA rna_Manipulator_group_get(PointerRNA *ptr)
421 {
422         wmManipulator *mpr = ptr->data;
423         return rna_pointer_inherit_refine(ptr, &RNA_ManipulatorGroup, mpr->parent_mgroup);
424 }
425
426 #ifdef WITH_PYTHON
427
428 static void rna_Manipulator_unregister(struct Main *bmain, StructRNA *type);
429 void BPY_RNA_manipulator_wrapper(wmManipulatorType *wgt, void *userdata);
430
431 static StructRNA *rna_Manipulator_register(
432         Main *bmain, ReportList *reports, void *data, const char *identifier,
433         StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
434 {
435         struct {
436                 char idname[MAX_NAME];
437         } temp_buffers;
438
439         wmManipulatorType dummywt = {NULL};
440         wmManipulator dummymnp = {NULL};
441         PointerRNA mnp_ptr;
442
443         /* Two sets of functions. */
444         int have_function[8];
445
446         /* setup dummy manipulator & manipulator type to store static properties in */
447         dummymnp.type = &dummywt;
448         dummywt.idname = temp_buffers.idname;
449         RNA_pointer_create(NULL, &RNA_Manipulator, &dummymnp, &mnp_ptr);
450
451         /* Clear so we can detect if it's left unset. */
452         temp_buffers.idname[0] = '\0';
453
454         /* validate the python class */
455         if (validate(&mnp_ptr, data, have_function) != 0)
456                 return NULL;
457
458         if (strlen(identifier) >= sizeof(temp_buffers.idname)) {
459                 BKE_reportf(reports, RPT_ERROR, "Registering manipulator class: '%s' is too long, maximum length is %d",
460                             identifier, (int)sizeof(temp_buffers.idname));
461                 return NULL;
462         }
463
464         /* check if we have registered this manipulator type before, and remove it */
465         {
466                 const wmManipulatorType *wt = WM_manipulatortype_find(dummywt.idname, true);
467                 if (wt && wt->ext.srna) {
468                         rna_Manipulator_unregister(bmain, wt->ext.srna);
469                 }
470         }
471         if (!RNA_struct_available_or_report(reports, dummywt.idname)) {
472                 return NULL;
473         }
474
475         {   /* allocate the idname */
476                 /* For multiple strings see ManipulatorGroup. */
477                 dummywt.idname = BLI_strdup(temp_buffers.idname);
478         }
479
480         /* create a new manipulator type */
481         dummywt.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummywt.idname, &RNA_Manipulator);
482         /* manipulator properties are registered separately */
483         RNA_def_struct_flag(dummywt.ext.srna, STRUCT_NO_IDPROPERTIES);
484         dummywt.ext.data = data;
485         dummywt.ext.call = call;
486         dummywt.ext.free = free;
487
488         {
489                 int i = 0;
490                 dummywt.draw = (have_function[i++]) ? rna_manipulator_draw_cb : NULL;
491                 dummywt.draw_select = (have_function[i++]) ? rna_manipulator_draw_select_cb : NULL;
492                 dummywt.test_select = (have_function[i++]) ? rna_manipulator_test_select_cb : NULL;
493                 dummywt.modal = (have_function[i++]) ? rna_manipulator_modal_cb : NULL;
494 //              dummywt.property_update = (have_function[i++]) ? rna_manipulator_property_update : NULL;
495 //              dummywt.position_get = (have_function[i++]) ? rna_manipulator_position_get : NULL;
496                 dummywt.setup = (have_function[i++]) ? rna_manipulator_setup_cb : NULL;
497                 dummywt.invoke = (have_function[i++]) ? rna_manipulator_invoke_cb : NULL;
498                 dummywt.exit = (have_function[i++]) ? rna_manipulator_exit_cb : NULL;
499                 dummywt.select_refresh = (have_function[i++]) ? rna_manipulator_select_refresh_cb : NULL;
500
501                 BLI_assert(i == ARRAY_SIZE(have_function));
502         }
503
504         WM_manipulatortype_append_ptr(BPY_RNA_manipulator_wrapper, (void *)&dummywt);
505
506         /* update while blender is running */
507         WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
508
509         return dummywt.ext.srna;
510 }
511
512 static void rna_Manipulator_unregister(struct Main *bmain, StructRNA *type)
513 {
514         wmManipulatorType *wt = RNA_struct_blender_type_get(type);
515
516         if (!wt)
517                 return;
518
519         RNA_struct_free_extension(type, &wt->ext);
520         RNA_struct_free(&BLENDER_RNA, type);
521
522         WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
523
524         WM_manipulatortype_remove_ptr(NULL, bmain, wt);
525 }
526
527 static void **rna_Manipulator_instance(PointerRNA *ptr)
528 {
529         wmManipulator *mpr = ptr->data;
530         return &mpr->py_instance;
531 }
532
533 #endif  /* WITH_PYTHON */
534
535
536 static StructRNA *rna_Manipulator_refine(PointerRNA *mnp_ptr)
537 {
538         wmManipulator *mpr = mnp_ptr->data;
539         return (mpr->type && mpr->type->ext.srna) ? mpr->type->ext.srna : &RNA_Manipulator;
540 }
541
542 /** \} */
543
544 /** \name Manipulator Group API
545  * \{ */
546
547 static wmManipulator *rna_ManipulatorGroup_manipulator_new(
548         wmManipulatorGroup *mgroup, ReportList *reports, const char *idname)
549 {
550         const wmManipulatorType *wt = WM_manipulatortype_find(idname, true);
551         if (wt == NULL) {
552                 BKE_reportf(reports, RPT_ERROR, "ManipulatorType '%s' not known", idname);
553                 return NULL;
554         }
555         wmManipulator *mpr = WM_manipulator_new_ptr(wt, mgroup, NULL);
556         return mpr;
557 }
558
559 static void rna_ManipulatorGroup_manipulator_remove(
560         wmManipulatorGroup *mgroup, bContext *C, wmManipulator *mpr)
561 {
562         WM_manipulator_unlink(&mgroup->manipulators, mgroup->parent_mmap, mpr, C);
563 }
564
565 static void rna_ManipulatorGroup_manipulator_clear(
566         wmManipulatorGroup *mgroup, bContext *C)
567 {
568         while (mgroup->manipulators.first) {
569                 WM_manipulator_unlink(&mgroup->manipulators, mgroup->parent_mmap, mgroup->manipulators.first, C);
570         }
571 }
572
573 static void rna_ManipulatorGroup_name_get(PointerRNA *ptr, char *value)
574 {
575         wmManipulatorGroup *mgroup = ptr->data;
576         strcpy(value, mgroup->type->name);
577 }
578
579 static int rna_ManipulatorGroup_name_length(PointerRNA *ptr)
580 {
581         wmManipulatorGroup *mgroup = ptr->data;
582         return strlen(mgroup->type->name);
583 }
584
585 /* just to work around 'const char *' warning and to ensure this is a python op */
586 static void rna_ManipulatorGroup_bl_idname_set(PointerRNA *ptr, const char *value)
587 {
588         wmManipulatorGroup *data = ptr->data;
589         char *str = (char *)data->type->idname;
590         if (!str[0])
591                 BLI_strncpy(str, value, MAX_NAME);    /* utf8 already ensured */
592         else
593                 assert(!"setting the bl_idname on a non-builtin operator");
594 }
595
596 static void rna_ManipulatorGroup_bl_label_set(PointerRNA *ptr, const char *value)
597 {
598         wmManipulatorGroup *data = ptr->data;
599         char *str = (char *)data->type->name;
600         if (!str[0])
601                 BLI_strncpy(str, value, MAX_NAME);    /* utf8 already ensured */
602         else
603                 assert(!"setting the bl_label on a non-builtin operator");
604 }
605
606 static int rna_ManipulatorGroup_has_reports_get(PointerRNA *ptr)
607 {
608         wmManipulatorGroup *mgroup = ptr->data;
609         return (mgroup->reports && mgroup->reports->list.first);
610 }
611
612 #ifdef WITH_PYTHON
613
614 static bool rna_manipulatorgroup_poll_cb(const bContext *C, wmManipulatorGroupType *wgt)
615 {
616
617         extern FunctionRNA rna_ManipulatorGroup_poll_func;
618
619         PointerRNA ptr;
620         ParameterList list;
621         FunctionRNA *func;
622         void *ret;
623         int visible;
624
625         RNA_pointer_create(NULL, wgt->ext.srna, NULL, &ptr); /* dummy */
626         func = &rna_ManipulatorGroup_poll_func; /* RNA_struct_find_function(&ptr, "poll"); */
627
628         RNA_parameter_list_create(&list, &ptr, func);
629         RNA_parameter_set_lookup(&list, "context", &C);
630         wgt->ext.call((bContext *)C, &ptr, func, &list);
631
632         RNA_parameter_get_lookup(&list, "visible", &ret);
633         visible = *(int *)ret;
634
635         RNA_parameter_list_free(&list);
636
637         return visible;
638 }
639
640 static void rna_manipulatorgroup_setup_cb(const bContext *C, wmManipulatorGroup *mgroup)
641 {
642         extern FunctionRNA rna_ManipulatorGroup_setup_func;
643
644         PointerRNA mgroup_ptr;
645         ParameterList list;
646         FunctionRNA *func;
647
648         RNA_pointer_create(NULL, mgroup->type->ext.srna, mgroup, &mgroup_ptr);
649         func = &rna_ManipulatorGroup_setup_func; /* RNA_struct_find_function(&wgroupr, "setup"); */
650
651         RNA_parameter_list_create(&list, &mgroup_ptr, func);
652         RNA_parameter_set_lookup(&list, "context", &C);
653         mgroup->type->ext.call((bContext *)C, &mgroup_ptr, func, &list);
654
655         RNA_parameter_list_free(&list);
656 }
657
658 static wmKeyMap *rna_manipulatorgroup_setup_keymap_cb(const wmManipulatorGroupType *wgt, wmKeyConfig *config)
659 {
660         extern FunctionRNA rna_ManipulatorGroup_setup_keymap_func;
661         void *ret;
662
663         PointerRNA ptr;
664         ParameterList list;
665         FunctionRNA *func;
666
667         RNA_pointer_create(NULL, wgt->ext.srna, NULL, &ptr); /* dummy */
668         func = &rna_ManipulatorGroup_setup_keymap_func; /* RNA_struct_find_function(&wgroupr, "setup_keymap"); */
669
670         RNA_parameter_list_create(&list, &ptr, func);
671         RNA_parameter_set_lookup(&list, "keyconfig", &config);
672         wgt->ext.call(NULL, &ptr, func, &list);
673
674         RNA_parameter_get_lookup(&list, "keymap", &ret);
675         wmKeyMap *keymap = *(wmKeyMap **)ret;
676
677         RNA_parameter_list_free(&list);
678
679         return keymap;
680 }
681
682 static void rna_manipulatorgroup_refresh_cb(const bContext *C, wmManipulatorGroup *mgroup)
683 {
684         extern FunctionRNA rna_ManipulatorGroup_refresh_func;
685
686         PointerRNA mgroup_ptr;
687         ParameterList list;
688         FunctionRNA *func;
689
690         RNA_pointer_create(NULL, mgroup->type->ext.srna, mgroup, &mgroup_ptr);
691         func = &rna_ManipulatorGroup_refresh_func; /* RNA_struct_find_function(&wgroupr, "refresh"); */
692
693         RNA_parameter_list_create(&list, &mgroup_ptr, func);
694         RNA_parameter_set_lookup(&list, "context", &C);
695         mgroup->type->ext.call((bContext *)C, &mgroup_ptr, func, &list);
696
697         RNA_parameter_list_free(&list);
698 }
699
700 static void rna_manipulatorgroup_draw_prepare_cb(const bContext *C, wmManipulatorGroup *mgroup)
701 {
702         extern FunctionRNA rna_ManipulatorGroup_draw_prepare_func;
703
704         PointerRNA mgroup_ptr;
705         ParameterList list;
706         FunctionRNA *func;
707
708         RNA_pointer_create(NULL, mgroup->type->ext.srna, mgroup, &mgroup_ptr);
709         func = &rna_ManipulatorGroup_draw_prepare_func; /* RNA_struct_find_function(&wgroupr, "draw_prepare"); */
710
711         RNA_parameter_list_create(&list, &mgroup_ptr, func);
712         RNA_parameter_set_lookup(&list, "context", &C);
713         mgroup->type->ext.call((bContext *)C, &mgroup_ptr, func, &list);
714
715         RNA_parameter_list_free(&list);
716 }
717
718 void BPY_RNA_manipulatorgroup_wrapper(wmManipulatorGroupType *wgt, void *userdata);
719 static void rna_ManipulatorGroup_unregister(struct Main *bmain, StructRNA *type);
720
721 static StructRNA *rna_ManipulatorGroup_register(
722         Main *bmain, ReportList *reports, void *data, const char *identifier,
723         StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
724 {
725         struct {
726                 char name[MAX_NAME];
727                 char idname[MAX_NAME];
728         } temp_buffers;
729
730         wmManipulatorGroupType dummywgt = {NULL};
731         wmManipulatorGroup dummywg = {NULL};
732         PointerRNA wgptr;
733
734         /* Two sets of functions. */
735         int have_function[5];
736
737         /* setup dummy manipulatorgroup & manipulatorgroup type to store static properties in */
738         dummywg.type = &dummywgt;
739         dummywgt.name = temp_buffers.name;
740         dummywgt.idname = temp_buffers.idname;
741
742         RNA_pointer_create(NULL, &RNA_ManipulatorGroup, &dummywg, &wgptr);
743
744         /* Clear so we can detect if it's left unset. */
745         temp_buffers.idname[0] = temp_buffers.name[0] = '\0';
746
747         /* validate the python class */
748         if (validate(&wgptr, data, have_function) != 0)
749                 return NULL;
750
751         if (strlen(identifier) >= sizeof(temp_buffers.idname)) {
752                 BKE_reportf(reports, RPT_ERROR, "Registering manipulatorgroup class: '%s' is too long, maximum length is %d",
753                             identifier, (int)sizeof(temp_buffers.idname));
754                 return NULL;
755         }
756
757         /* check if the area supports widgets */
758         const struct wmManipulatorMapType_Params wmap_params = {
759                 .spaceid = dummywgt.mmap_params.spaceid,
760                 .regionid = dummywgt.mmap_params.regionid,
761         };
762
763         wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure(&wmap_params);
764         if (mmap_type == NULL) {
765                 BKE_reportf(reports, RPT_ERROR, "Area type does not support manipulators");
766                 return NULL;
767         }
768
769         /* check if we have registered this manipulatorgroup type before, and remove it */
770         {
771                 wmManipulatorGroupType *wgt = WM_manipulatorgrouptype_find(dummywgt.idname, true);
772                 if (wgt && wgt->ext.srna) {
773                         rna_ManipulatorGroup_unregister(bmain, wgt->ext.srna);
774                 }
775         }
776         if (!RNA_struct_available_or_report(reports, dummywgt.idname)) {
777                 return NULL;
778         }
779
780         {   /* allocate the idname */
781                 const char *strings[] = {
782                         temp_buffers.idname,
783                         temp_buffers.name,
784                 };
785                 char *strings_table[ARRAY_SIZE(strings)];
786                 BLI_string_join_array_by_sep_char_with_tableN('\0', strings_table, strings, ARRAY_SIZE(strings));
787
788                 dummywgt.idname = strings_table[0];  /* allocated string stored here */
789                 dummywgt.name = strings_table[1];
790                 BLI_assert(ARRAY_SIZE(strings) == 2);
791         }
792
793         /* create a new manipulatorgroup type */
794         dummywgt.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummywgt.idname, &RNA_ManipulatorGroup);
795         RNA_def_struct_flag(dummywgt.ext.srna, STRUCT_NO_IDPROPERTIES); /* manipulatorgroup properties are registered separately */
796         dummywgt.ext.data = data;
797         dummywgt.ext.call = call;
798         dummywgt.ext.free = free;
799
800         /* We used to register widget group types like this, now we do it similar to
801          * operator types. Thus we should be able to do the same as operator types now. */
802         dummywgt.poll = (have_function[0]) ? rna_manipulatorgroup_poll_cb : NULL;
803         dummywgt.setup_keymap =     (have_function[1]) ? rna_manipulatorgroup_setup_keymap_cb : NULL;
804         dummywgt.setup =            (have_function[2]) ? rna_manipulatorgroup_setup_cb : NULL;
805         dummywgt.refresh =          (have_function[3]) ? rna_manipulatorgroup_refresh_cb : NULL;
806         dummywgt.draw_prepare =     (have_function[4]) ? rna_manipulatorgroup_draw_prepare_cb : NULL;
807
808         wmManipulatorGroupType *wgt = WM_manipulatorgrouptype_append_ptr(
809                 BPY_RNA_manipulatorgroup_wrapper, (void *)&dummywgt);
810
811         if (wgt->flag & WM_MANIPULATORGROUPTYPE_PERSISTENT) {
812                 WM_manipulator_group_type_add_ptr_ex(wgt, mmap_type);
813
814                 /* update while blender is running */
815                 WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
816         }
817
818         return dummywgt.ext.srna;
819 }
820
821 static void rna_ManipulatorGroup_unregister(struct Main *bmain, StructRNA *type)
822 {
823         wmManipulatorGroupType *wgt = RNA_struct_blender_type_get(type);
824
825         if (!wgt)
826                 return;
827
828         RNA_struct_free_extension(type, &wgt->ext);
829         RNA_struct_free(&BLENDER_RNA, type);
830
831         WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
832
833         WM_manipulator_group_type_remove_ptr(bmain, wgt);
834 }
835
836 static void **rna_ManipulatorGroup_instance(PointerRNA *ptr)
837 {
838         wmManipulatorGroup *mgroup = ptr->data;
839         return &mgroup->py_instance;
840 }
841
842 #endif  /* WITH_PYTHON */
843
844 static StructRNA *rna_ManipulatorGroup_refine(PointerRNA *mgroup_ptr)
845 {
846         wmManipulatorGroup *mgroup = mgroup_ptr->data;
847         return (mgroup->type && mgroup->type->ext.srna) ? mgroup->type->ext.srna : &RNA_ManipulatorGroup;
848 }
849
850 static void rna_ManipulatorGroup_manipulators_begin(CollectionPropertyIterator *iter, PointerRNA *mgroup_ptr)
851 {
852         wmManipulatorGroup *mgroup = mgroup_ptr->data;
853         rna_iterator_listbase_begin(iter, &mgroup->manipulators, NULL);
854 }
855
856 /** \} */
857
858
859 #else /* RNA_RUNTIME */
860
861
862 /* ManipulatorGroup.manipulators */
863 static void rna_def_manipulators(BlenderRNA *brna, PropertyRNA *cprop)
864 {
865         StructRNA *srna;
866
867         FunctionRNA *func;
868         PropertyRNA *parm;
869
870         RNA_def_property_srna(cprop, "Manipulators");
871         srna = RNA_def_struct(brna, "Manipulators", NULL);
872         RNA_def_struct_sdna(srna, "wmManipulatorGroup");
873         RNA_def_struct_ui_text(srna, "Manipulators", "Collection of manipulators");
874
875         func = RNA_def_function(srna, "new", "rna_ManipulatorGroup_manipulator_new");
876         RNA_def_function_ui_description(func, "Add manipulator");
877         RNA_def_function_flag(func, FUNC_USE_REPORTS);
878         RNA_def_string(func, "type", "Type", 0, "", "Manipulator identifier"); /* optional */
879         parm = RNA_def_pointer(func, "manipulator", "Manipulator", "", "New manipulator");
880         RNA_def_function_return(func, parm);
881
882         func = RNA_def_function(srna, "remove", "rna_ManipulatorGroup_manipulator_remove");
883         RNA_def_function_flag(func, FUNC_USE_CONTEXT);
884         RNA_def_function_ui_description(func, "Delete manipulator");
885         parm = RNA_def_pointer(func, "manipulator", "Manipulator", "", "New manipulator");
886         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
887         RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
888
889         func = RNA_def_function(srna, "clear", "rna_ManipulatorGroup_manipulator_clear");
890         RNA_def_function_flag(func, FUNC_USE_CONTEXT);
891         RNA_def_function_ui_description(func, "Delete all manipulators");
892 }
893
894
895 static void rna_def_manipulator(BlenderRNA *brna, PropertyRNA *cprop)
896 {
897         StructRNA *srna;
898         PropertyRNA *prop;
899
900         FunctionRNA *func;
901         PropertyRNA *parm;
902
903         RNA_def_property_srna(cprop, "Manipulator");
904         srna = RNA_def_struct(brna, "Manipulator", NULL);
905         RNA_def_struct_sdna(srna, "wmManipulator");
906         RNA_def_struct_ui_text(srna, "Manipulator", "Collection of manipulators");
907         RNA_def_struct_refine_func(srna, "rna_Manipulator_refine");
908
909 #ifdef WITH_PYTHON
910         RNA_def_struct_register_funcs(
911                 srna,
912                 "rna_Manipulator_register",
913                 "rna_Manipulator_unregister",
914                 "rna_Manipulator_instance");
915 #endif
916         RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
917
918         prop = RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE);
919         RNA_def_property_flag(prop, PROP_NEVER_NULL);
920         RNA_def_property_struct_type(prop, "ManipulatorProperties");
921         RNA_def_property_ui_text(prop, "Properties", "");
922         RNA_def_property_pointer_funcs(prop, "rna_Manipulator_properties_get", NULL, NULL, NULL);
923
924         /* -------------------------------------------------------------------- */
925         /* Registerable Variables */
926
927         RNA_define_verify_sdna(0); /* not in sdna */
928
929         prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
930         RNA_def_property_string_sdna(prop, NULL, "type->idname");
931         RNA_def_property_string_maxlength(prop, MAX_NAME);
932         RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Manipulator_bl_idname_set");
933         /* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
934         RNA_def_property_flag(prop, PROP_REGISTER);
935
936         RNA_define_verify_sdna(1); /* not in sdna */
937
938         /* wmManipulator.draw */
939         func = RNA_def_function(srna, "draw", NULL);
940         RNA_def_function_ui_description(func, "");
941         RNA_def_function_flag(func, FUNC_REGISTER);
942         parm = RNA_def_pointer(func, "context", "Context", "", "");
943         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
944
945         /* wmManipulator.draw_select */
946         func = RNA_def_function(srna, "draw_select", NULL);
947         RNA_def_function_ui_description(func, "");
948         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
949         parm = RNA_def_pointer(func, "context", "Context", "", "");
950         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
951         parm = RNA_def_int(func, "select_id", 0, 0, INT_MAX, "", "", 0, INT_MAX);
952
953         /* wmManipulator.test_select */
954         func = RNA_def_function(srna, "test_select", NULL);
955         RNA_def_function_ui_description(func, "");
956         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
957         parm = RNA_def_pointer(func, "context", "Context", "", "");
958         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
959         parm = RNA_def_pointer(func, "event", "Event", "", "");
960         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
961         parm = RNA_def_int(func, "intersect_id", 0, 0, INT_MAX, "", "", 0, INT_MAX);
962         RNA_def_function_return(func, parm);
963
964         /* wmManipulator.handler */
965         static EnumPropertyItem tweak_actions[] = {
966                 {WM_MANIPULATOR_TWEAK_PRECISE, "PRECISE", 0, "Precise", ""},
967                 {WM_MANIPULATOR_TWEAK_SNAP, "SNAP", 0, "Snap", ""},
968                 {0, NULL, 0, NULL, NULL}
969         };
970         func = RNA_def_function(srna, "modal", NULL);
971         RNA_def_function_ui_description(func, "");
972         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
973         parm = RNA_def_pointer(func, "context", "Context", "", "");
974         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
975         parm = RNA_def_pointer(func, "event", "Event", "", "");
976         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
977         /* TODO, shuold be a enum-flag */
978         parm = RNA_def_enum_flag(func, "tweak", tweak_actions, 0, "Tweak", "");
979         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
980         parm = RNA_def_enum_flag(func, "result", rna_enum_operator_return_items, OPERATOR_CANCELLED, "result", "");
981         RNA_def_function_return(func, parm);
982         /* wmManipulator.property_update */
983         /* TODO */
984
985         /* wmManipulator.setup */
986         func = RNA_def_function(srna, "setup", NULL);
987         RNA_def_function_ui_description(func, "");
988         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
989
990         /* wmManipulator.invoke */
991         func = RNA_def_function(srna, "invoke", NULL);
992         RNA_def_function_ui_description(func, "");
993         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
994         parm = RNA_def_pointer(func, "context", "Context", "", "");
995         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
996         parm = RNA_def_pointer(func, "event", "Event", "", "");
997         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
998         parm = RNA_def_enum_flag(func, "result", rna_enum_operator_return_items, OPERATOR_CANCELLED, "result", "");
999         RNA_def_function_return(func, parm);
1000
1001         /* wmManipulator.exit */
1002         func = RNA_def_function(srna, "exit", NULL);
1003         RNA_def_function_ui_description(func, "");
1004         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
1005         parm = RNA_def_pointer(func, "context", "Context", "", "");
1006         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1007         parm = RNA_def_boolean(func, "cancel", 0, "Cancel, otherwise confirm", "");
1008         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1009
1010         /* wmManipulator.cursor_get */
1011         /* TODO */
1012
1013         /* wmManipulator.select_refresh */
1014         func = RNA_def_function(srna, "select_refresh", NULL);
1015         RNA_def_function_ui_description(func, "");
1016         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
1017
1018
1019         /* -------------------------------------------------------------------- */
1020         /* Instance Variables */
1021
1022         prop = RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
1023         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1024         RNA_def_property_struct_type(prop, "ManipulatorGroup");
1025         RNA_def_property_pointer_funcs(prop, "rna_Manipulator_group_get", NULL, NULL, NULL);
1026         RNA_def_property_ui_text(prop, "", "Manipulator group this manipulator is a member of");
1027
1028         /* Color & Alpha */
1029         prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
1030         RNA_def_property_array(prop, 3);
1031         RNA_def_property_float_funcs(prop, "rna_Manipulator_color_get", "rna_Manipulator_color_set", NULL);
1032
1033         prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE);
1034         RNA_def_property_ui_text(prop, "Alpha", "");
1035         RNA_def_property_float_funcs(prop, "rna_Manipulator_alpha_get", "rna_Manipulator_alpha_set", NULL);
1036         RNA_def_property_range(prop, 0.0f, 1.0f);
1037         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1038
1039         /* Color & Alpha (highlight) */
1040         prop = RNA_def_property(srna, "color_highlight", PROP_FLOAT, PROP_COLOR);
1041         RNA_def_property_array(prop, 3);
1042         RNA_def_property_float_funcs(prop, "rna_Manipulator_color_hi_get", "rna_Manipulator_color_hi_set", NULL);
1043
1044         prop = RNA_def_property(srna, "alpha_highlight", PROP_FLOAT, PROP_NONE);
1045         RNA_def_property_ui_text(prop, "Alpha", "");
1046         RNA_def_property_float_funcs(prop, "rna_Manipulator_alpha_hi_get", "rna_Manipulator_alpha_hi_set", NULL);
1047         RNA_def_property_range(prop, 0.0f, 1.0f);
1048         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1049
1050         prop = RNA_def_property(srna, "matrix_space", PROP_FLOAT, PROP_MATRIX);
1051         RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
1052         RNA_def_property_ui_text(prop, "Space Matrix", "");
1053         RNA_def_property_float_funcs(prop, "rna_Manipulator_matrix_space_get", "rna_Manipulator_matrix_space_set", NULL);
1054         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1055
1056         prop = RNA_def_property(srna, "matrix_basis", PROP_FLOAT, PROP_MATRIX);
1057         RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
1058         RNA_def_property_ui_text(prop, "Basis Matrix", "");
1059         RNA_def_property_float_funcs(prop, "rna_Manipulator_matrix_basis_get", "rna_Manipulator_matrix_basis_set", NULL);
1060         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1061
1062         prop = RNA_def_property(srna, "matrix_offset", PROP_FLOAT, PROP_MATRIX);
1063         RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
1064         RNA_def_property_ui_text(prop, "Offset Matrix", "");
1065         RNA_def_property_float_funcs(prop, "rna_Manipulator_matrix_offset_get", "rna_Manipulator_matrix_offset_set", NULL);
1066         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1067
1068         prop = RNA_def_property(srna, "matrix_world", PROP_FLOAT, PROP_MATRIX);
1069         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1070         RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
1071         RNA_def_property_ui_text(prop, "Final World Matrix", "");
1072         RNA_def_property_float_funcs(prop, "rna_Manipulator_matrix_world_get", NULL, NULL);
1073
1074         prop = RNA_def_property(srna, "scale_basis", PROP_FLOAT, PROP_NONE);
1075         RNA_def_property_ui_text(prop, "Scale Basis", "");
1076         RNA_def_property_float_funcs(prop, "rna_Manipulator_scale_basis_get", "rna_Manipulator_scale_basis_set", NULL);
1077         RNA_def_property_range(prop, 0.0f, FLT_MAX);
1078         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1079
1080         prop = RNA_def_property(srna, "line_width", PROP_FLOAT, PROP_PIXEL);
1081         RNA_def_property_ui_text(prop, "Line Width", "");
1082         RNA_def_property_float_funcs(prop, "rna_Manipulator_line_width_get", "rna_Manipulator_line_width_set", NULL);
1083         RNA_def_property_range(prop, 0.0f, FLT_MAX);
1084         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1085
1086         /* wmManipulator.flag */
1087         /* WM_MANIPULATOR_HIDDEN */
1088         prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
1089         RNA_def_property_boolean_funcs(
1090                 prop, "rna_Manipulator_flag_hide_get", "rna_Manipulator_flag_hide_set");
1091         RNA_def_property_ui_text(prop, "Hide", "");
1092         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1093         /* WM_MANIPULATOR_DRAW_HOVER */
1094         prop = RNA_def_property(srna, "use_draw_hover", PROP_BOOLEAN, PROP_NONE);
1095         RNA_def_property_boolean_funcs(
1096                 prop, "rna_Manipulator_flag_use_draw_hover_get", "rna_Manipulator_flag_use_draw_hover_set");
1097         RNA_def_property_ui_text(prop, "Draw Hover", "");
1098         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1099         /* WM_MANIPULATOR_DRAW_MODAL */
1100         prop = RNA_def_property(srna, "use_draw_modal", PROP_BOOLEAN, PROP_NONE);
1101         RNA_def_property_boolean_funcs(
1102                 prop, "rna_Manipulator_flag_use_draw_modal_get", "rna_Manipulator_flag_use_draw_modal_set");
1103         RNA_def_property_ui_text(prop, "Draw Active", "Draw while dragging");
1104         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1105         /* WM_MANIPULATOR_DRAW_VALUE */
1106         prop = RNA_def_property(srna, "use_draw_value", PROP_BOOLEAN, PROP_NONE);
1107         RNA_def_property_boolean_funcs(
1108                 prop, "rna_Manipulator_flag_use_draw_value_get", "rna_Manipulator_flag_use_draw_value_set");
1109         RNA_def_property_ui_text(prop, "Draw Value", "Show an indicator for the current value while dragging");
1110         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1111         /* WM_MANIPULATOR_DRAW_OFFSET_SCALE */
1112         prop = RNA_def_property(srna, "use_draw_offset_scale", PROP_BOOLEAN, PROP_NONE);
1113         RNA_def_property_boolean_funcs(
1114                 prop, "rna_Manipulator_flag_use_draw_offset_scale_get", "rna_Manipulator_flag_use_draw_offset_scale_set");
1115         RNA_def_property_ui_text(prop, "Scale Offset", "Scale the offset matrix (use to apply screen-space offset)");
1116         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1117         /* WM_MANIPULATOR_DRAW_NO_SCALE (negated) */
1118         prop = RNA_def_property(srna, "use_draw_scale", PROP_BOOLEAN, PROP_NONE);
1119         RNA_def_property_boolean_funcs(
1120                 prop, "rna_Manipulator_flag_use_draw_scale_get", "rna_Manipulator_flag_use_draw_scale_set");
1121         RNA_def_property_ui_text(prop, "Scale", "Use scale when calculating the matrix");
1122         RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
1123
1124         /* wmManipulator.state (readonly) */
1125         /* WM_MANIPULATOR_STATE_HIGHLIGHT */
1126         prop = RNA_def_property(srna, "is_highlight", PROP_BOOLEAN, PROP_NONE);
1127         RNA_def_property_boolean_funcs(prop, "rna_Manipulator_state_is_highlight_get", NULL);
1128         RNA_def_property_ui_text(prop, "Highlight", "");
1129         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1130         /* WM_MANIPULATOR_STATE_MODAL */
1131         prop = RNA_def_property(srna, "is_modal", PROP_BOOLEAN, PROP_NONE);
1132         RNA_def_property_boolean_funcs(prop, "rna_Manipulator_state_is_modal_get", NULL);
1133         RNA_def_property_ui_text(prop, "Highlight", "");
1134         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1135         /* WM_MANIPULATOR_STATE_SELECT */
1136         /* (note that setting is involved, needs to handle array) */
1137         prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
1138         RNA_def_property_boolean_funcs(prop, "rna_Manipulator_state_select_get", "rna_Manipulator_state_select_set");
1139         RNA_def_property_ui_text(prop, "Select", "");
1140
1141         RNA_api_manipulator(srna);
1142
1143         srna = RNA_def_struct(brna, "ManipulatorProperties", NULL);
1144         RNA_def_struct_ui_text(srna, "Manipulator Properties", "Input properties of an Manipulator");
1145         RNA_def_struct_refine_func(srna, "rna_ManipulatorProperties_refine");
1146         RNA_def_struct_idprops_func(srna, "rna_ManipulatorProperties_idprops");
1147         RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES);
1148 }
1149
1150 static void rna_def_manipulatorgroup(BlenderRNA *brna)
1151 {
1152         StructRNA *srna;
1153         PropertyRNA *prop;
1154
1155         FunctionRNA *func;
1156         PropertyRNA *parm;
1157
1158         srna = RNA_def_struct(brna, "ManipulatorGroup", NULL);
1159         RNA_def_struct_ui_text(srna, "ManipulatorGroup", "Storage of an operator being executed, or registered after execution");
1160         RNA_def_struct_sdna(srna, "wmManipulatorGroup");
1161         RNA_def_struct_refine_func(srna, "rna_ManipulatorGroup_refine");
1162 #ifdef WITH_PYTHON
1163         RNA_def_struct_register_funcs(
1164                 srna,
1165                 "rna_ManipulatorGroup_register",
1166                 "rna_ManipulatorGroup_unregister",
1167                 "rna_ManipulatorGroup_instance");
1168 #endif
1169         RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
1170
1171         /* -------------------------------------------------------------------- */
1172         /* Registration */
1173
1174         RNA_define_verify_sdna(0); /* not in sdna */
1175
1176         prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
1177         RNA_def_property_string_sdna(prop, NULL, "type->idname");
1178         RNA_def_property_string_maxlength(prop, MAX_NAME);
1179         RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ManipulatorGroup_bl_idname_set");
1180         RNA_def_property_flag(prop, PROP_REGISTER);
1181         RNA_def_struct_name_property(srna, prop);
1182
1183         prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
1184         RNA_def_property_string_sdna(prop, NULL, "type->name");
1185         RNA_def_property_string_maxlength(prop, MAX_NAME); /* else it uses the pointer size! */
1186         RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ManipulatorGroup_bl_label_set");
1187         /* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
1188         RNA_def_property_flag(prop, PROP_REGISTER);
1189
1190         prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
1191         RNA_def_property_enum_sdna(prop, NULL, "type->mmap_params.spaceid");
1192         RNA_def_property_enum_items(prop, rna_enum_space_type_items);
1193         RNA_def_property_flag(prop, PROP_REGISTER);
1194         RNA_def_property_ui_text(prop, "Space type", "The space where the panel is going to be used in");
1195
1196         prop = RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE);
1197         RNA_def_property_enum_sdna(prop, NULL, "type->mmap_params.regionid");
1198         RNA_def_property_enum_items(prop, rna_enum_region_type_items);
1199         RNA_def_property_flag(prop, PROP_REGISTER);
1200         RNA_def_property_ui_text(prop, "Region Type", "The region where the panel is going to be used in");
1201
1202         /* bl_options */
1203         static EnumPropertyItem manipulatorgroup_flag_items[] = {
1204                 {WM_MANIPULATORGROUPTYPE_3D, "3D", 0, "3D",
1205                  "Use in 3D viewport"},
1206                 {WM_MANIPULATORGROUPTYPE_SCALE, "SCALE", 0, "Scale",
1207                  "Scale to respect zoom (otherwise zoom independent draw size)"},
1208                 {WM_MANIPULATORGROUPTYPE_DEPTH_3D, "DEPTH_3D", 0, "Depth 3D",
1209                  "Supports culled depth by other objects in the view"},
1210                 {WM_MANIPULATORGROUPTYPE_SELECT, "SELECT", 0, "Select",
1211                  "Supports selection"},
1212                 {WM_MANIPULATORGROUPTYPE_PERSISTENT, "PERSISTENT", 0, "Persistent",
1213                  ""},
1214                 {WM_MANIPULATORGROUPTYPE_DRAW_MODAL_ALL, "SHOW_MODAL_ALL", 0, "Show Modal All",
1215                  "Show all while interacting"},
1216                 {0, NULL, 0, NULL, NULL}
1217         };
1218         prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
1219         RNA_def_property_enum_sdna(prop, NULL, "type->flag");
1220         RNA_def_property_enum_items(prop, manipulatorgroup_flag_items);
1221         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
1222         RNA_def_property_ui_text(prop, "Options",  "Options for this operator type");
1223
1224         RNA_define_verify_sdna(1); /* not in sdna */
1225
1226
1227         /* Functions */
1228
1229         /* poll */
1230         func = RNA_def_function(srna, "poll", NULL);
1231         RNA_def_function_ui_description(func, "Test if the manipulator group can be called or not");
1232         RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
1233         RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
1234         parm = RNA_def_pointer(func, "context", "Context", "", "");
1235         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1236
1237         /* setup_keymap */
1238         func = RNA_def_function(srna, "setup_keymap", NULL);
1239         RNA_def_function_ui_description(
1240                 func,
1241                 "Initialize keymaps for this manipulator group, use fallback keymap when not present");
1242         RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
1243         parm = RNA_def_pointer(func, "keyconfig", "KeyConfig", "", "");
1244         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1245         /* return */
1246         parm = RNA_def_pointer(func, "keymap", "KeyMap", "", "");
1247         RNA_def_property_flag(parm, PROP_NEVER_NULL);
1248         RNA_def_function_return(func, parm);
1249
1250         /* setup */
1251         func = RNA_def_function(srna, "setup", NULL);
1252         RNA_def_function_ui_description(func, "Create manipulators function for the manipulator group");
1253         RNA_def_function_flag(func, FUNC_REGISTER);
1254         parm = RNA_def_pointer(func, "context", "Context", "", "");
1255         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1256
1257         /* refresh */
1258         func = RNA_def_function(srna, "refresh", NULL);
1259         RNA_def_function_ui_description(func, "Refresh data (called on common state changes such as selection)");
1260         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
1261         parm = RNA_def_pointer(func, "context", "Context", "", "");
1262         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1263
1264         func = RNA_def_function(srna, "draw_prepare", NULL);
1265         RNA_def_function_ui_description(func, "Run before each redraw");
1266         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
1267         parm = RNA_def_pointer(func, "context", "Context", "", "");
1268         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1269
1270         /* -------------------------------------------------------------------- */
1271         /* Instance Variables */
1272
1273         prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
1274         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1275         RNA_def_property_string_funcs(prop, "rna_ManipulatorGroup_name_get", "rna_ManipulatorGroup_name_length", NULL);
1276         RNA_def_property_ui_text(prop, "Name", "");
1277
1278         prop = RNA_def_property(srna, "has_reports", PROP_BOOLEAN, PROP_NONE);
1279         RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* this is 'virtual' property */
1280         RNA_def_property_boolean_funcs(prop, "rna_ManipulatorGroup_has_reports_get", NULL);
1281         RNA_def_property_ui_text(prop, "Has Reports",
1282                                  "ManipulatorGroup has a set of reports (warnings and errors) from last execution");
1283
1284
1285         RNA_define_verify_sdna(0); /* not in sdna */
1286
1287         prop = RNA_def_property(srna, "manipulators", PROP_COLLECTION, PROP_NONE);
1288         RNA_def_property_collection_sdna(prop, NULL, "manipulators", NULL);
1289         RNA_def_property_struct_type(prop, "Manipulator");
1290         RNA_def_property_collection_funcs(
1291                 prop, "rna_ManipulatorGroup_manipulators_begin", "rna_iterator_listbase_next",
1292                 "rna_iterator_listbase_end", "rna_iterator_listbase_get",
1293                 NULL, NULL, NULL, NULL);
1294
1295         RNA_def_property_ui_text(prop, "Manipulators", "List of manipulators in the Manipulator Map");
1296         rna_def_manipulator(brna, prop);
1297         rna_def_manipulators(brna, prop);
1298
1299         RNA_define_verify_sdna(1); /* not in sdna */
1300
1301         RNA_api_manipulatorgroup(srna);
1302 }
1303
1304 void RNA_def_wm_manipulator(BlenderRNA *brna)
1305 {
1306         rna_def_manipulatorgroup(brna);
1307 }
1308
1309 #endif /* RNA_RUNTIME */