RNA: report error on struct naming collision
[blender.git] / source / blender / makesrna / intern / rna_ui.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  * Contributor(s): Blender Foundation (2009)
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/makesrna/intern/rna_ui.c
24  *  \ingroup RNA
25  */
26
27
28 #include <stdlib.h>
29
30 #include "DNA_screen_types.h"
31
32 #include "BLT_translation.h"
33
34 #include "BKE_idprop.h"
35
36 #include "RNA_define.h"
37
38 #include "rna_internal.h"
39 #include "RNA_enum_types.h"
40
41 #include "UI_interface.h"
42
43 #include "WM_types.h"
44
45 /* see WM_types.h */
46 EnumPropertyItem rna_enum_operator_context_items[] = {
47         {WM_OP_INVOKE_DEFAULT, "INVOKE_DEFAULT", 0, "Invoke Default", ""},
48         {WM_OP_INVOKE_REGION_WIN, "INVOKE_REGION_WIN", 0, "Invoke Region Window", ""},
49         {WM_OP_INVOKE_REGION_CHANNELS, "INVOKE_REGION_CHANNELS", 0, "Invoke Region Channels", ""},
50         {WM_OP_INVOKE_REGION_PREVIEW, "INVOKE_REGION_PREVIEW", 0, "Invoke Region Preview", ""},
51         {WM_OP_INVOKE_AREA, "INVOKE_AREA", 0, "Invoke Area", ""},
52         {WM_OP_INVOKE_SCREEN, "INVOKE_SCREEN", 0, "Invoke Screen", ""},
53         {WM_OP_EXEC_DEFAULT, "EXEC_DEFAULT", 0, "Exec Default", ""},
54         {WM_OP_EXEC_REGION_WIN, "EXEC_REGION_WIN", 0, "Exec Region Window", ""},
55         {WM_OP_EXEC_REGION_CHANNELS, "EXEC_REGION_CHANNELS", 0, "Exec Region Channels", ""},
56         {WM_OP_EXEC_REGION_PREVIEW, "EXEC_REGION_PREVIEW", 0, "Exec Region Preview", ""},
57         {WM_OP_EXEC_AREA, "EXEC_AREA", 0, "Exec Area", ""},
58         {WM_OP_EXEC_SCREEN, "EXEC_SCREEN", 0, "Exec Screen", ""},
59         {0, NULL, 0, NULL, NULL}
60 };
61
62 EnumPropertyItem rna_enum_uilist_layout_type_items[] = {
63         {UILST_LAYOUT_DEFAULT, "DEFAULT", 0, "Default Layout", "Use the default, multi-rows layout"},
64         {UILST_LAYOUT_COMPACT, "COMPACT", 0, "Compact Layout", "Use the compact, single-row layout"},
65         {UILST_LAYOUT_GRID, "GRID", 0, "Grid Layout", "Use the grid-based layout"},
66         {0, NULL, 0, NULL, NULL}
67 };
68
69 #ifdef RNA_RUNTIME
70
71 #include <assert.h>
72
73 #include "MEM_guardedalloc.h"
74
75 #include "RNA_access.h"
76
77 #include "BLI_dynstr.h"
78
79 #include "BKE_context.h"
80 #include "BKE_report.h"
81 #include "BKE_screen.h"
82
83 #include "WM_api.h"
84
85 static ARegionType *region_type_find(ReportList *reports, int space_type, int region_type)
86 {
87         SpaceType *st;
88         ARegionType *art;
89
90         st = BKE_spacetype_from_id(space_type);
91
92         for (art = (st) ? st->regiontypes.first : NULL; art; art = art->next) {
93                 if (art->regionid == region_type)
94                         break;
95         }
96         
97         /* region type not found? abort */
98         if (art == NULL) {
99                 BKE_report(reports, RPT_ERROR, "Region not found in space type");
100                 return NULL;
101         }
102
103         return art;
104 }
105
106 /* Panel */
107
108 static int panel_poll(const bContext *C, PanelType *pt)
109 {
110         extern FunctionRNA rna_Panel_poll_func;
111
112         PointerRNA ptr;
113         ParameterList list;
114         FunctionRNA *func;
115         void *ret;
116         int visible;
117
118         RNA_pointer_create(NULL, pt->ext.srna, NULL, &ptr); /* dummy */
119         func = &rna_Panel_poll_func; /* RNA_struct_find_function(&ptr, "poll"); */
120
121         RNA_parameter_list_create(&list, &ptr, func);
122         RNA_parameter_set_lookup(&list, "context", &C);
123         pt->ext.call((bContext *)C, &ptr, func, &list);
124
125         RNA_parameter_get_lookup(&list, "visible", &ret);
126         visible = *(int *)ret;
127
128         RNA_parameter_list_free(&list);
129
130         return visible;
131 }
132
133 static void panel_draw(const bContext *C, Panel *pnl)
134 {
135         extern FunctionRNA rna_Panel_draw_func;
136
137         PointerRNA ptr;
138         ParameterList list;
139         FunctionRNA *func;
140
141         RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->ext.srna, pnl, &ptr);
142         func = &rna_Panel_draw_func; /* RNA_struct_find_function(&ptr, "draw"); */
143
144         RNA_parameter_list_create(&list, &ptr, func);
145         RNA_parameter_set_lookup(&list, "context", &C);
146         pnl->type->ext.call((bContext *)C, &ptr, func, &list);
147
148         RNA_parameter_list_free(&list);
149 }
150
151 static void panel_draw_header(const bContext *C, Panel *pnl)
152 {
153         extern FunctionRNA rna_Panel_draw_header_func;
154
155         PointerRNA ptr;
156         ParameterList list;
157         FunctionRNA *func;
158
159         RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->ext.srna, pnl, &ptr);
160         func = &rna_Panel_draw_header_func; /* RNA_struct_find_function(&ptr, "draw_header"); */
161
162         RNA_parameter_list_create(&list, &ptr, func);
163         RNA_parameter_set_lookup(&list, "context", &C);
164         pnl->type->ext.call((bContext *)C, &ptr, func, &list);
165
166         RNA_parameter_list_free(&list);
167 }
168
169 static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
170 {
171         ARegionType *art;
172         PanelType *pt = RNA_struct_blender_type_get(type);
173
174         if (!pt)
175                 return;
176         if (!(art = region_type_find(NULL, pt->space_type, pt->region_type)))
177                 return;
178         
179         RNA_struct_free_extension(type, &pt->ext);
180         RNA_struct_free(&BLENDER_RNA, type);
181
182         BLI_freelinkN(&art->paneltypes, pt);
183
184         /* update while blender is running */
185         WM_main_add_notifier(NC_WINDOW, NULL);
186 }
187
188 static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
189                                      StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
190 {
191         ARegionType *art;
192         PanelType *pt, dummypt = {NULL};
193         Panel dummypanel = {NULL};
194         PointerRNA dummyptr;
195         int have_function[3];
196
197         /* setup dummy panel & panel type to store static properties in */
198         dummypanel.type = &dummypt;
199         RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr);
200
201         /* We have to set default context! Else we get a void string... */
202         strcpy(dummypt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
203
204         /* validate the python class */
205         if (validate(&dummyptr, data, have_function) != 0)
206                 return NULL;
207                 
208         if (strlen(identifier) >= sizeof(dummypt.idname)) {
209                 BKE_reportf(reports, RPT_ERROR, "Registering panel class: '%s' is too long, maximum length is %d",
210                             identifier, (int)sizeof(dummypt.idname));
211                 return NULL;
212         }
213
214         if ((dummypt.category[0] == '\0') && (dummypt.region_type == RGN_TYPE_TOOLS)) {
215                 /* Use a fallback, otherwise an empty value will draw the panel in every category. */
216                 strcpy(dummypt.category, PNL_CATEGORY_FALLBACK);
217         }
218
219         if (!(art = region_type_find(reports, dummypt.space_type, dummypt.region_type)))
220                 return NULL;
221
222         /* check if we have registered this panel type before, and remove it */
223         for (pt = art->paneltypes.first; pt; pt = pt->next) {
224                 if (STREQ(pt->idname, dummypt.idname)) {
225                         if (pt->ext.srna)
226                                 rna_Panel_unregister(bmain, pt->ext.srna);
227                         else
228                                 BLI_freelinkN(&art->paneltypes, pt);
229                         break;
230                 }
231         }
232         if (!RNA_struct_available_or_report(reports, identifier)) {
233                 return NULL;
234         }
235         
236         /* create a new panel type */
237         pt = MEM_callocN(sizeof(PanelType), "python buttons panel");
238         memcpy(pt, &dummypt, sizeof(dummypt));
239
240         pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel);
241         RNA_def_struct_translation_context(pt->ext.srna, pt->translation_context);
242         pt->ext.data = data;
243         pt->ext.call = call;
244         pt->ext.free = free;
245         RNA_struct_blender_type_set(pt->ext.srna, pt);
246         RNA_def_struct_flag(pt->ext.srna, STRUCT_NO_IDPROPERTIES);
247
248         pt->poll = (have_function[0]) ? panel_poll : NULL;
249         pt->draw = (have_function[1]) ? panel_draw : NULL;
250         pt->draw_header = (have_function[2]) ? panel_draw_header : NULL;
251
252         /* XXX use "no header" flag for some ordering of panels until we have real panel ordering */
253         if (pt->flag & PNL_NO_HEADER) {
254                 PanelType *pth = art->paneltypes.first;
255                 while (pth && pth->flag & PNL_NO_HEADER)
256                         pth = pth->next;
257
258                 if (pth)
259                         BLI_insertlinkbefore(&art->paneltypes, pth, pt);
260                 else
261                         BLI_addtail(&art->paneltypes, pt);
262         }
263         else
264                 BLI_addtail(&art->paneltypes, pt);
265
266         /* update while blender is running */
267         WM_main_add_notifier(NC_WINDOW, NULL);
268         
269         return pt->ext.srna;
270 }
271
272 static StructRNA *rna_Panel_refine(PointerRNA *ptr)
273 {
274         Panel *hdr = (Panel *)ptr->data;
275         return (hdr->type && hdr->type->ext.srna) ? hdr->type->ext.srna : &RNA_Panel;
276 }
277
278 /* UIList */
279 static unsigned int rna_UIList_filter_const_FILTER_ITEM_get(PointerRNA *UNUSED(ptr))
280 {
281         return UILST_FLT_ITEM;
282 }
283
284 static IDProperty *rna_UIList_idprops(PointerRNA *ptr, bool create)
285 {
286         uiList *ui_list = (uiList *)ptr->data;
287         if (create && !ui_list->properties) {
288                 IDPropertyTemplate val = {0};
289                 ui_list->properties = IDP_New(IDP_GROUP, &val, "RNA_UIList IDproperties group");
290         }
291
292         return ui_list->properties;
293 }
294
295 static void uilist_draw_item(uiList *ui_list, bContext *C, uiLayout *layout, PointerRNA *dataptr, PointerRNA *itemptr,
296                              int icon, PointerRNA *active_dataptr, const char *active_propname, int index, int flt_flag)
297 {
298         extern FunctionRNA rna_UIList_draw_item_func;
299
300         PointerRNA ul_ptr;
301         ParameterList list;
302         FunctionRNA *func;
303
304         RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->ext.srna, ui_list, &ul_ptr);
305         func = &rna_UIList_draw_item_func; /* RNA_struct_find_function(&ul_ptr, "draw_item"); */
306
307         RNA_parameter_list_create(&list, &ul_ptr, func);
308         RNA_parameter_set_lookup(&list, "context", &C);
309         RNA_parameter_set_lookup(&list, "layout", &layout);
310         RNA_parameter_set_lookup(&list, "data", dataptr);
311         RNA_parameter_set_lookup(&list, "item", itemptr);
312         RNA_parameter_set_lookup(&list, "icon", &icon);
313         RNA_parameter_set_lookup(&list, "active_data", active_dataptr);
314         RNA_parameter_set_lookup(&list, "active_property", &active_propname);
315         RNA_parameter_set_lookup(&list, "index", &index);
316         RNA_parameter_set_lookup(&list, "flt_flag", &flt_flag);
317         ui_list->type->ext.call((bContext *)C, &ul_ptr, func, &list);
318
319         RNA_parameter_list_free(&list);
320 }
321
322 static void uilist_draw_filter(uiList *ui_list, bContext *C, uiLayout *layout)
323 {
324         extern FunctionRNA rna_UIList_draw_filter_func;
325
326         PointerRNA ul_ptr;
327         ParameterList list;
328         FunctionRNA *func;
329
330         RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->ext.srna, ui_list, &ul_ptr);
331         func = &rna_UIList_draw_filter_func; /* RNA_struct_find_function(&ul_ptr, "draw_filter"); */
332
333         RNA_parameter_list_create(&list, &ul_ptr, func);
334         RNA_parameter_set_lookup(&list, "context", &C);
335         RNA_parameter_set_lookup(&list, "layout", &layout);
336         ui_list->type->ext.call((bContext *)C, &ul_ptr, func, &list);
337
338         RNA_parameter_list_free(&list);
339 }
340
341 static void uilist_filter_items(uiList *ui_list, bContext *C, PointerRNA *dataptr, const char *propname)
342 {
343         extern FunctionRNA rna_UIList_filter_items_func;
344
345         PointerRNA ul_ptr;
346         ParameterList list;
347         FunctionRNA *func;
348         PropertyRNA *parm;
349
350         uiListDyn *flt_data = ui_list->dyn_data;
351         int *filter_flags, *filter_neworder;
352         void *ret1, *ret2;
353         int ret_len;
354         int len = flt_data->items_len = RNA_collection_length(dataptr, propname);
355
356         RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->ext.srna, ui_list, &ul_ptr);
357         func = &rna_UIList_filter_items_func; /* RNA_struct_find_function(&ul_ptr, "filter_items"); */
358
359         RNA_parameter_list_create(&list, &ul_ptr, func);
360         RNA_parameter_set_lookup(&list, "context", &C);
361         RNA_parameter_set_lookup(&list, "data", dataptr);
362         RNA_parameter_set_lookup(&list, "property", &propname);
363
364         ui_list->type->ext.call((bContext *)C, &ul_ptr, func, &list);
365
366         parm = RNA_function_find_parameter(NULL, func, "filter_flags");
367         ret_len = RNA_parameter_dynamic_length_get(&list, parm);
368         if (ret_len != len && ret_len != 0) {
369                 printf("%s: Error, py func returned %d items in %s, %d or none were expected.\n", __func__,
370                        RNA_parameter_dynamic_length_get(&list, parm), "filter_flags", len);
371                 /* Note: we cannot return here, we would let flt_data in inconsistent state... see T38356. */
372                 filter_flags = NULL;
373         }
374         else {
375                 RNA_parameter_get(&list, parm, &ret1);
376                 filter_flags = (int *)ret1;
377         }
378
379         parm = RNA_function_find_parameter(NULL, func, "filter_neworder");
380         ret_len = RNA_parameter_dynamic_length_get(&list, parm);
381         if (ret_len != len && ret_len != 0) {
382                 printf("%s: Error, py func returned %d items in %s, %d or none were expected.\n", __func__,
383                        RNA_parameter_dynamic_length_get(&list, parm), "filter_neworder", len);
384                 /* Note: we cannot return here, we would let flt_data in inconsistent state... see T38356. */
385                 filter_neworder = NULL;
386         }
387         else {
388                 RNA_parameter_get(&list, parm, &ret2);
389                 filter_neworder = (int *)ret2;
390         }
391
392         /* We have to do some final checks and transforms... */
393         {
394                 int i, filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
395                 if (filter_flags) {
396                         flt_data->items_filter_flags = MEM_mallocN(sizeof(int) * len, __func__);
397                         memcpy(flt_data->items_filter_flags, filter_flags, sizeof(int) * len);
398
399                         if (filter_neworder) {
400                                 /* For sake of simplicity, py filtering is expected to filter all items, but we actually only want
401                                  * reordering data for shown items!
402                                  */
403                                 int items_shown, shown_idx;
404                                 int t_idx, t_ni, prev_ni;
405                                 flt_data->items_shown = 0;
406                                 for (i = 0, shown_idx = 0; i < len; i++) {
407                                         if ((filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude) {
408                                                 filter_neworder[shown_idx++] = filter_neworder[i];
409                                         }
410                                 }
411                                 items_shown = flt_data->items_shown = shown_idx;
412                                 flt_data->items_filter_neworder = MEM_mallocN(sizeof(int) * items_shown, __func__);
413                                 /* And now, bring back new indices into the [0, items_shown[ range!
414                                  * XXX This is O(N²)... :/
415                                  */
416                                 for (shown_idx = 0, prev_ni = -1; shown_idx < items_shown; shown_idx++) {
417                                         for (i = 0, t_ni = len, t_idx = -1; i < items_shown; i++) {
418                                                 int ni = filter_neworder[i];
419                                                 if (ni > prev_ni && ni < t_ni) {
420                                                         t_idx = i;
421                                                         t_ni = ni;
422                                                 }
423                                         }
424                                         if (t_idx >= 0) {
425                                                 prev_ni = t_ni;
426                                                 flt_data->items_filter_neworder[t_idx] = shown_idx;
427                                         }
428                                 }
429                         }
430                         else {
431                                 /* we still have to set flt_data->items_shown... */
432                                 flt_data->items_shown = 0;
433                                 for (i = 0; i < len; i++) {
434                                         if ((filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude) {
435                                                 flt_data->items_shown++;
436                                         }
437                                 }
438                         }
439                 }
440                 else {
441                         flt_data->items_shown = len;
442
443                         if (filter_neworder) {
444                                 flt_data->items_filter_neworder = MEM_mallocN(sizeof(int) * len, __func__);
445                                 memcpy(flt_data->items_filter_neworder, filter_neworder, sizeof(int) * len);
446                         }
447                 }
448         }
449
450         RNA_parameter_list_free(&list);
451 }
452
453 static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type)
454 {
455         uiListType *ult = RNA_struct_blender_type_get(type);
456
457         if (!ult)
458                 return;
459
460         RNA_struct_free_extension(type, &ult->ext);
461         RNA_struct_free(&BLENDER_RNA, type);
462
463         WM_uilisttype_freelink(ult);
464
465         /* update while blender is running */
466         WM_main_add_notifier(NC_WINDOW, NULL);
467 }
468
469 static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
470                                       StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
471 {
472         uiListType *ult, dummyult = {NULL};
473         uiList dummyuilist = {NULL};
474         PointerRNA dummyul_ptr;
475         int have_function[3];
476         size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
477
478         /* setup dummy menu & menu type to store static properties in */
479         dummyuilist.type = &dummyult;
480         RNA_pointer_create(NULL, &RNA_UIList, &dummyuilist, &dummyul_ptr);
481
482         /* validate the python class */
483         if (validate(&dummyul_ptr, data, have_function) != 0)
484                 return NULL;
485
486         if (strlen(identifier) >= sizeof(dummyult.idname)) {
487                 BKE_reportf(reports, RPT_ERROR, "Registering uilist class: '%s' is too long, maximum length is %d",
488                             identifier, (int)sizeof(dummyult.idname));
489                 return NULL;
490         }
491
492         /* check if we have registered this uilist type before, and remove it */
493         ult = WM_uilisttype_find(dummyult.idname, true);
494         if (ult && ult->ext.srna) {
495                 rna_UIList_unregister(bmain, ult->ext.srna);
496         }
497         if (!RNA_struct_available_or_report(reports, identifier)) {
498                 return NULL;
499         }
500
501         /* create a new menu type */
502         ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist");
503         memcpy(ult, &dummyult, sizeof(dummyult));
504
505         ult->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList);
506         ult->ext.data = data;
507         ult->ext.call = call;
508         ult->ext.free = free;
509         RNA_struct_blender_type_set(ult->ext.srna, ult);
510
511         ult->draw_item = (have_function[0]) ? uilist_draw_item : NULL;
512         ult->draw_filter = (have_function[1]) ? uilist_draw_filter : NULL;
513         ult->filter_items = (have_function[2]) ? uilist_filter_items : NULL;
514
515         WM_uilisttype_add(ult);
516
517         /* update while blender is running */
518         WM_main_add_notifier(NC_WINDOW, NULL);
519
520         return ult->ext.srna;
521 }
522
523 static StructRNA *rna_UIList_refine(PointerRNA *ptr)
524 {
525         uiList *ui_list = (uiList *)ptr->data;
526         return (ui_list->type && ui_list->type->ext.srna) ? ui_list->type->ext.srna : &RNA_UIList;
527 }
528
529 /* Header */
530
531 static void header_draw(const bContext *C, Header *hdr)
532 {
533         extern FunctionRNA rna_Header_draw_func;
534
535         PointerRNA htr;
536         ParameterList list;
537         FunctionRNA *func;
538
539         RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->ext.srna, hdr, &htr);
540         func = &rna_Header_draw_func; /* RNA_struct_find_function(&htr, "draw"); */
541
542         RNA_parameter_list_create(&list, &htr, func);
543         RNA_parameter_set_lookup(&list, "context", &C);
544         hdr->type->ext.call((bContext *)C, &htr, func, &list);
545
546         RNA_parameter_list_free(&list);
547 }
548
549 static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type)
550 {
551         ARegionType *art;
552         HeaderType *ht = RNA_struct_blender_type_get(type);
553
554         if (!ht)
555                 return;
556         if (!(art = region_type_find(NULL, ht->space_type, RGN_TYPE_HEADER)))
557                 return;
558         
559         RNA_struct_free_extension(type, &ht->ext);
560         RNA_struct_free(&BLENDER_RNA, type);
561
562         BLI_freelinkN(&art->headertypes, ht);
563
564         /* update while blender is running */
565         WM_main_add_notifier(NC_WINDOW, NULL);
566 }
567
568 static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
569                                       StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
570 {
571         ARegionType *art;
572         HeaderType *ht, dummyht = {NULL};
573         Header dummyheader = {NULL};
574         PointerRNA dummyhtr;
575         int have_function[1];
576
577         /* setup dummy header & header type to store static properties in */
578         dummyheader.type = &dummyht;
579         RNA_pointer_create(NULL, &RNA_Header, &dummyheader, &dummyhtr);
580
581         /* validate the python class */
582         if (validate(&dummyhtr, data, have_function) != 0)
583                 return NULL;
584
585         if (strlen(identifier) >= sizeof(dummyht.idname)) {
586                 BKE_reportf(reports, RPT_ERROR, "Registering header class: '%s' is too long, maximum length is %d",
587                             identifier, (int)sizeof(dummyht.idname));
588                 return NULL;
589         }
590
591         if (!(art = region_type_find(reports, dummyht.space_type, RGN_TYPE_HEADER)))
592                 return NULL;
593
594         /* check if we have registered this header type before, and remove it */
595         for (ht = art->headertypes.first; ht; ht = ht->next) {
596                 if (STREQ(ht->idname, dummyht.idname)) {
597                         if (ht->ext.srna)
598                                 rna_Header_unregister(bmain, ht->ext.srna);
599                         break;
600                 }
601         }
602         if (!RNA_struct_available_or_report(reports, identifier)) {
603                 return NULL;
604         }
605         
606         /* create a new header type */
607         ht = MEM_callocN(sizeof(HeaderType), "python buttons header");
608         memcpy(ht, &dummyht, sizeof(dummyht));
609
610         ht->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_Header);
611         ht->ext.data = data;
612         ht->ext.call = call;
613         ht->ext.free = free;
614         RNA_struct_blender_type_set(ht->ext.srna, ht);
615
616         ht->draw = (have_function[0]) ? header_draw : NULL;
617
618         BLI_addtail(&art->headertypes, ht);
619
620         /* update while blender is running */
621         WM_main_add_notifier(NC_WINDOW, NULL);
622         
623         return ht->ext.srna;
624 }
625
626 static StructRNA *rna_Header_refine(PointerRNA *htr)
627 {
628         Header *hdr = (Header *)htr->data;
629         return (hdr->type && hdr->type->ext.srna) ? hdr->type->ext.srna : &RNA_Header;
630 }
631
632 /* Menu */
633
634 static int menu_poll(const bContext *C, MenuType *pt)
635 {
636         extern FunctionRNA rna_Menu_poll_func;
637
638         PointerRNA ptr;
639         ParameterList list;
640         FunctionRNA *func;
641         void *ret;
642         int visible;
643
644         RNA_pointer_create(NULL, pt->ext.srna, NULL, &ptr); /* dummy */
645         func = &rna_Menu_poll_func; /* RNA_struct_find_function(&ptr, "poll"); */
646
647         RNA_parameter_list_create(&list, &ptr, func);
648         RNA_parameter_set_lookup(&list, "context", &C);
649         pt->ext.call((bContext *)C, &ptr, func, &list);
650
651         RNA_parameter_get_lookup(&list, "visible", &ret);
652         visible = *(int *)ret;
653
654         RNA_parameter_list_free(&list);
655
656         return visible;
657 }
658
659 static void menu_draw(const bContext *C, Menu *hdr)
660 {
661         extern FunctionRNA rna_Menu_draw_func;
662
663         PointerRNA mtr;
664         ParameterList list;
665         FunctionRNA *func;
666
667         RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->ext.srna, hdr, &mtr);
668         func = &rna_Menu_draw_func; /* RNA_struct_find_function(&mtr, "draw"); */
669
670         RNA_parameter_list_create(&list, &mtr, func);
671         RNA_parameter_set_lookup(&list, "context", &C);
672         hdr->type->ext.call((bContext *)C, &mtr, func, &list);
673
674         RNA_parameter_list_free(&list);
675 }
676
677 static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type)
678 {
679         MenuType *mt = RNA_struct_blender_type_get(type);
680
681         if (!mt)
682                 return;
683         
684         RNA_struct_free_extension(type, &mt->ext);
685         RNA_struct_free(&BLENDER_RNA, type);
686
687         WM_menutype_freelink(mt);
688
689         /* update while blender is running */
690         WM_main_add_notifier(NC_WINDOW, NULL);
691 }
692
693 static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
694                                     StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
695 {
696         MenuType *mt, dummymt = {NULL};
697         Menu dummymenu = {NULL};
698         PointerRNA dummymtr;
699         int have_function[2];
700         size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
701         size_t description_size = 0;
702         char _menu_descr[RNA_DYN_DESCR_MAX];
703
704         /* setup dummy menu & menu type to store static properties in */
705         dummymenu.type = &dummymt;
706         _menu_descr[0] = '\0';
707         dummymenu.type->description = _menu_descr;
708         RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr);
709
710         /* We have to set default context! Else we get a void string... */
711         strcpy(dummymt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
712
713         /* validate the python class */
714         if (validate(&dummymtr, data, have_function) != 0)
715                 return NULL;
716         
717         if (strlen(identifier) >= sizeof(dummymt.idname)) {
718                 BKE_reportf(reports, RPT_ERROR, "Registering menu class: '%s' is too long, maximum length is %d",
719                             identifier, (int)sizeof(dummymt.idname));
720                 return NULL;
721         }
722
723         /* check if we have registered this menu type before, and remove it */
724         mt = WM_menutype_find(dummymt.idname, true);
725         if (mt && mt->ext.srna) {
726                 rna_Menu_unregister(bmain, mt->ext.srna);
727         }
728         if (!RNA_struct_available_or_report(reports, identifier)) {
729                 return NULL;
730         }
731         
732         /* create a new menu type */
733         if (_menu_descr[0]) {
734                 description_size = strlen(_menu_descr) + 1;
735                 over_alloc += description_size;
736         }
737
738         mt = MEM_callocN(sizeof(MenuType) + over_alloc, "python buttons menu");
739         memcpy(mt, &dummymt, sizeof(dummymt));
740
741         if (_menu_descr[0]) {
742                 char *buf = (char *)(mt + 1);
743                 memcpy(buf, _menu_descr, description_size);
744                 mt->description = buf;
745         }
746         else
747                 mt->description = "";
748
749         mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu);
750         RNA_def_struct_translation_context(mt->ext.srna, mt->translation_context);
751         mt->ext.data = data;
752         mt->ext.call = call;
753         mt->ext.free = free;
754         RNA_struct_blender_type_set(mt->ext.srna, mt);
755         RNA_def_struct_flag(mt->ext.srna, STRUCT_NO_IDPROPERTIES);
756
757         mt->poll = (have_function[0]) ? menu_poll : NULL;
758         mt->draw = (have_function[1]) ? menu_draw : NULL;
759
760         WM_menutype_add(mt);
761
762         /* update while blender is running */
763         WM_main_add_notifier(NC_WINDOW, NULL);
764         
765         return mt->ext.srna;
766 }
767
768 static StructRNA *rna_Menu_refine(PointerRNA *mtr)
769 {
770         Menu *hdr = (Menu *)mtr->data;
771         return (hdr->type && hdr->type->ext.srna) ? hdr->type->ext.srna : &RNA_Menu;
772 }
773
774 static void rna_Menu_bl_description_set(PointerRNA *ptr, const char *value)
775 {
776         Menu *data = (Menu *)(ptr->data);
777         char *str = (char *)data->type->description;
778         if (!str[0]) BLI_strncpy(str, value, RNA_DYN_DESCR_MAX);     /* utf8 already ensured */
779         else assert(!"setting the bl_description on a non-builtin menu");
780 }
781
782 /* UILayout */
783
784 static int rna_UILayout_active_get(PointerRNA *ptr)
785 {
786         return uiLayoutGetActive(ptr->data);
787 }
788
789 static void rna_UILayout_active_set(PointerRNA *ptr, int value)
790 {
791         uiLayoutSetActive(ptr->data, value);
792 }
793
794 static int rna_UILayout_alert_get(PointerRNA *ptr)
795 {
796         return uiLayoutGetRedAlert(ptr->data);
797 }
798
799 static void rna_UILayout_alert_set(PointerRNA *ptr, int value)
800 {
801         uiLayoutSetRedAlert(ptr->data, value);
802 }
803
804 static void rna_UILayout_op_context_set(PointerRNA *ptr, int value)
805 {
806         uiLayoutSetOperatorContext(ptr->data, value);
807 }
808
809 static int rna_UILayout_op_context_get(PointerRNA *ptr)
810 {
811         return uiLayoutGetOperatorContext(ptr->data);
812 }
813
814 static int rna_UILayout_enabled_get(PointerRNA *ptr)
815 {
816         return uiLayoutGetEnabled(ptr->data);
817 }
818
819 static void rna_UILayout_enabled_set(PointerRNA *ptr, int value)
820 {
821         uiLayoutSetEnabled(ptr->data, value);
822 }
823
824 #if 0
825 static int rna_UILayout_red_alert_get(PointerRNA *ptr)
826 {
827         return uiLayoutGetRedAlert(ptr->data);
828 }
829
830 static void rna_UILayout_red_alert_set(PointerRNA *ptr, int value)
831 {
832         uiLayoutSetRedAlert(ptr->data, value);
833 }
834
835 static int rna_UILayout_keep_aspect_get(PointerRNA *ptr)
836 {
837         return uiLayoutGetKeepAspect(ptr->data);
838 }
839
840 static void rna_UILayout_keep_aspect_set(PointerRNA *ptr, int value)
841 {
842         uiLayoutSetKeepAspect(ptr->data, value);
843 }
844 #endif
845
846 static int rna_UILayout_alignment_get(PointerRNA *ptr)
847 {
848         return uiLayoutGetAlignment(ptr->data);
849 }
850
851 static void rna_UILayout_alignment_set(PointerRNA *ptr, int value)
852 {
853         uiLayoutSetAlignment(ptr->data, value);
854 }
855
856 static float rna_UILayout_scale_x_get(PointerRNA *ptr)
857 {
858         return uiLayoutGetScaleX(ptr->data);
859 }
860
861 static void rna_UILayout_scale_x_set(PointerRNA *ptr, float value)
862 {
863         uiLayoutSetScaleX(ptr->data, value);
864 }
865
866 static float rna_UILayout_scale_y_get(PointerRNA *ptr)
867 {
868         return uiLayoutGetScaleY(ptr->data);
869 }
870
871 static void rna_UILayout_scale_y_set(PointerRNA *ptr, float value)
872 {
873         uiLayoutSetScaleY(ptr->data, value);
874 }
875
876 #else /* RNA_RUNTIME */
877
878 static void rna_def_ui_layout(BlenderRNA *brna)
879 {
880         StructRNA *srna;
881         PropertyRNA *prop;
882
883         static EnumPropertyItem alignment_items[] = {
884                 {UI_LAYOUT_ALIGN_EXPAND, "EXPAND", 0, "Expand", ""},
885                 {UI_LAYOUT_ALIGN_LEFT, "LEFT", 0, "Left", ""},
886                 {UI_LAYOUT_ALIGN_CENTER, "CENTER", 0, "Center", ""},
887                 {UI_LAYOUT_ALIGN_RIGHT, "RIGHT", 0, "Right", ""},
888                 {0, NULL, 0, NULL, NULL}
889         };
890         
891         /* layout */
892
893         srna = RNA_def_struct(brna, "UILayout", NULL);
894         RNA_def_struct_sdna(srna, "uiLayout");
895         RNA_def_struct_ui_text(srna, "UI Layout", "User interface layout in a panel or header");
896
897         prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
898         RNA_def_property_boolean_funcs(prop, "rna_UILayout_active_get", "rna_UILayout_active_set");
899         
900         prop = RNA_def_property(srna, "operator_context", PROP_ENUM, PROP_NONE);
901         RNA_def_property_enum_items(prop, rna_enum_operator_context_items);
902         RNA_def_property_enum_funcs(prop, "rna_UILayout_op_context_get", "rna_UILayout_op_context_set", NULL);
903         
904         prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
905         RNA_def_property_boolean_funcs(prop, "rna_UILayout_enabled_get", "rna_UILayout_enabled_set");
906         RNA_def_property_ui_text(prop, "Enabled", "When false, this (sub)layout is grayed out");
907         
908         prop = RNA_def_property(srna, "alert", PROP_BOOLEAN, PROP_NONE);
909         RNA_def_property_boolean_funcs(prop, "rna_UILayout_alert_get", "rna_UILayout_alert_set");
910
911         prop = RNA_def_property(srna, "alignment", PROP_ENUM, PROP_NONE);
912         RNA_def_property_enum_items(prop, alignment_items);
913         RNA_def_property_enum_funcs(prop, "rna_UILayout_alignment_get", "rna_UILayout_alignment_set", NULL);
914
915 #if 0
916         prop = RNA_def_property(srna, "keep_aspect", PROP_BOOLEAN, PROP_NONE);
917         RNA_def_property_boolean_funcs(prop, "rna_UILayout_keep_aspect_get", "rna_UILayout_keep_aspect_set");
918 #endif
919
920         prop = RNA_def_property(srna, "scale_x", PROP_FLOAT, PROP_UNSIGNED);
921         RNA_def_property_float_funcs(prop, "rna_UILayout_scale_x_get", "rna_UILayout_scale_x_set", NULL);
922         RNA_def_property_ui_text(prop, "Scale X", "Scale factor along the X for items in this (sub)layout");
923         
924         prop = RNA_def_property(srna, "scale_y", PROP_FLOAT, PROP_UNSIGNED);
925         RNA_def_property_float_funcs(prop, "rna_UILayout_scale_y_get", "rna_UILayout_scale_y_set", NULL);
926         RNA_def_property_ui_text(prop, "Scale Y", "Scale factor along the Y for items in this (sub)layout");
927         RNA_api_ui_layout(srna);
928 }
929
930 static void rna_def_panel(BlenderRNA *brna)
931 {
932         StructRNA *srna;
933         PropertyRNA *prop;
934         PropertyRNA *parm;
935         FunctionRNA *func;
936         
937         static EnumPropertyItem panel_flag_items[] = {
938                 {PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed",
939                                      "Defines if the panel has to be open or collapsed at the time of its creation"},
940                 {PNL_NO_HEADER, "HIDE_HEADER", 0, "Hide Header",
941                                 "If set to False, the panel shows a header, which contains a clickable "
942                                 "arrow to collapse the panel and the label (see bl_label)"},
943                 {0, NULL, 0, NULL, NULL}
944         };
945         
946         srna = RNA_def_struct(brna, "Panel", NULL);
947         RNA_def_struct_ui_text(srna, "Panel", "Panel containing UI elements");
948         RNA_def_struct_sdna(srna, "Panel");
949         RNA_def_struct_refine_func(srna, "rna_Panel_refine");
950         RNA_def_struct_register_funcs(srna, "rna_Panel_register", "rna_Panel_unregister", NULL);
951         RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
952
953         /* poll */
954         func = RNA_def_function(srna, "poll", NULL);
955         RNA_def_function_ui_description(func, "If this method returns a non-null output, then the panel can be drawn");
956         RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
957         RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
958         parm = RNA_def_pointer(func, "context", "Context", "", "");
959         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
960
961         /* draw */
962         func = RNA_def_function(srna, "draw", NULL);
963         RNA_def_function_ui_description(func, "Draw UI elements into the panel UI layout");
964         RNA_def_function_flag(func, FUNC_REGISTER);
965         parm = RNA_def_pointer(func, "context", "Context", "", "");
966         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
967
968         func = RNA_def_function(srna, "draw_header", NULL);
969         RNA_def_function_ui_description(func, "Draw UI elements into the panel's header UI layout");
970         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
971         parm = RNA_def_pointer(func, "context", "Context", "", "");
972         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
973
974         prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
975         RNA_def_property_struct_type(prop, "UILayout");
976         RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the panel in the UI");
977         
978         prop = RNA_def_property(srna, "text", PROP_STRING, PROP_NONE);
979         RNA_def_property_string_sdna(prop, NULL, "drawname");
980         RNA_def_property_ui_text(prop, "Text", "XXX todo");
981         
982         /* registration */
983         prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
984         RNA_def_property_string_sdna(prop, NULL, "type->idname");
985         RNA_def_property_flag(prop, PROP_REGISTER);
986         RNA_def_property_ui_text(prop, "ID Name",
987                                  "If this is set, the panel gets a custom ID, otherwise it takes the "
988                                  "name of the class used to define the panel. For example, if the "
989                                  "class name is \"OBJECT_PT_hello\", and bl_idname is not set by the "
990                                  "script, then bl_idname = \"OBJECT_PT_hello\"");
991
992         prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
993         RNA_def_property_string_sdna(prop, NULL, "type->label");
994         RNA_def_property_flag(prop, PROP_REGISTER);
995         RNA_def_property_ui_text(prop, "Label",
996                                  "The panel label, shows up in the panel header at the right of the "
997                                  "triangle used to collapse the panel");
998
999         prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
1000         RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
1001         RNA_def_property_string_default(prop, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
1002         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1003         RNA_define_verify_sdna(true);
1004
1005         prop = RNA_def_property(srna, "bl_category", PROP_STRING, PROP_NONE);
1006         RNA_def_property_string_sdna(prop, NULL, "type->category");
1007         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1008
1009         prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
1010         RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
1011         RNA_def_property_enum_items(prop, rna_enum_space_type_items);
1012         RNA_def_property_flag(prop, PROP_REGISTER);
1013         RNA_def_property_ui_text(prop, "Space type", "The space where the panel is going to be used in");
1014         
1015         prop = RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE);
1016         RNA_def_property_enum_sdna(prop, NULL, "type->region_type");
1017         RNA_def_property_enum_items(prop, rna_enum_region_type_items);
1018         RNA_def_property_flag(prop, PROP_REGISTER);
1019         RNA_def_property_ui_text(prop, "Region Type", "The region where the panel is going to be used in");
1020
1021         prop = RNA_def_property(srna, "bl_context", PROP_STRING, PROP_NONE);
1022         RNA_def_property_string_sdna(prop, NULL, "type->context");
1023         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); /* Only used in Properties Editor and 3D View - Thomas */
1024         RNA_def_property_ui_text(prop, "Context",
1025                                  "The context in which the panel belongs to. (TODO: explain the "
1026                                  "possible combinations bl_context/bl_region_type/bl_space_type)");
1027         
1028         prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
1029         RNA_def_property_enum_sdna(prop, NULL, "type->flag");
1030         RNA_def_property_enum_items(prop, panel_flag_items);
1031         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
1032         RNA_def_property_ui_text(prop, "Options",  "Options for this panel type");
1033
1034         prop = RNA_def_property(srna, "use_pin", PROP_BOOLEAN, PROP_NONE);
1035         RNA_def_property_boolean_sdna(prop, NULL, "flag", PNL_PIN);
1036         RNA_def_property_ui_text(prop, "Pin",  "");
1037         /* XXX, should only tag region for redraw */
1038         RNA_def_property_update(prop, NC_WINDOW, NULL);
1039 }
1040
1041 static void rna_def_uilist(BlenderRNA *brna)
1042 {
1043         StructRNA *srna;
1044         PropertyRNA *prop;
1045         PropertyRNA *parm;
1046         FunctionRNA *func;
1047
1048         srna = RNA_def_struct(brna, "UIList", NULL);
1049         RNA_def_struct_ui_text(srna, "UIList", "UI list containing the elements of a collection");
1050         RNA_def_struct_sdna(srna, "uiList");
1051         RNA_def_struct_refine_func(srna, "rna_UIList_refine");
1052         RNA_def_struct_register_funcs(srna, "rna_UIList_register", "rna_UIList_unregister", NULL);
1053         RNA_def_struct_idprops_func(srna, "rna_UIList_idprops");
1054         RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES);
1055
1056         /* Registration */
1057         prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
1058         RNA_def_property_string_sdna(prop, NULL, "type->idname");
1059         RNA_def_property_flag(prop, PROP_REGISTER);
1060         RNA_def_property_ui_text(prop, "ID Name",
1061                                  "If this is set, the uilist gets a custom ID, otherwise it takes the "
1062                                  "name of the class used to define the uilist (for example, if the "
1063                                  "class name is \"OBJECT_UL_vgroups\", and bl_idname is not set by the "
1064                                  "script, then bl_idname = \"OBJECT_UL_vgroups\")");
1065
1066         /* Data */
1067         prop = RNA_def_property(srna, "layout_type", PROP_ENUM, PROP_NONE);
1068         RNA_def_property_enum_items(prop, rna_enum_uilist_layout_type_items);
1069         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1070
1071         /* Filter options */
1072         prop = RNA_def_property(srna, "use_filter_show", PROP_BOOLEAN, PROP_NONE);
1073         RNA_def_property_boolean_sdna(prop, NULL, "filter_flag", UILST_FLT_SHOW);
1074         RNA_def_property_ui_text(prop, "Show Filter", "Show filtering options");
1075
1076         prop = RNA_def_property(srna, "filter_name", PROP_STRING, PROP_NONE);
1077         RNA_def_property_string_sdna(prop, NULL, "filter_byname");
1078         RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
1079         RNA_def_property_ui_text(prop, "Filter by Name", "Only show items matching this name (use '*' as wildcard)");
1080
1081         prop = RNA_def_property(srna, "use_filter_invert", PROP_BOOLEAN, PROP_NONE);
1082         RNA_def_property_boolean_sdna(prop, NULL, "filter_flag", UILST_FLT_EXCLUDE);
1083         RNA_def_property_ui_text(prop, "Invert", "Invert filtering (show hidden items, and vice-versa)");
1084
1085         prop = RNA_def_property(srna, "use_filter_sort_alpha", PROP_BOOLEAN, PROP_NONE);
1086         RNA_def_property_boolean_sdna(prop, NULL, "filter_sort_flag", UILST_FLT_SORT_ALPHA);
1087         RNA_def_property_ui_icon(prop, ICON_SORTALPHA, 0);
1088         RNA_def_property_ui_text(prop, "Sort by Name", "Sort items by their name");
1089
1090         prop = RNA_def_property(srna, "use_filter_sort_reverse", PROP_BOOLEAN, PROP_NONE);
1091         RNA_def_property_boolean_sdna(prop, NULL, "filter_sort_flag", UILST_FLT_SORT_REVERSE);
1092         RNA_def_property_ui_text(prop, "Invert", "Invert the order of shown items");
1093
1094         /* draw_item */
1095         func = RNA_def_function(srna, "draw_item", NULL);
1096         RNA_def_function_ui_description(func, "Draw an item in the list (NOTE: when you define your own draw_item "
1097                                               "function, you may want to check given 'item' is of the right type...)");
1098         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
1099         parm = RNA_def_pointer(func, "context", "Context", "", "");
1100         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1101         parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item");
1102         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1103         parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take Collection property");
1104         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
1105         parm = RNA_def_pointer(func, "item", "AnyType", "", "Item of the collection property");
1106         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
1107         parm = RNA_def_int(func, "icon", 0, 0, INT_MAX, "", "Icon of the item in the collection", 0, INT_MAX);
1108         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1109         parm = RNA_def_pointer(func, "active_data", "AnyType", "",
1110                                "Data from which to take property for the active element");
1111         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1112         parm = RNA_def_string(func, "active_property", NULL, 0, "",
1113                               "Identifier of property in active_data, for the active element");
1114         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1115         RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of the item in the collection", 0, INT_MAX);
1116         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_PYFUNC_OPTIONAL);
1117         prop = RNA_def_property(func, "flt_flag", PROP_INT, PROP_UNSIGNED);
1118         RNA_def_property_ui_text(prop, "", "The filter-flag result for this item");
1119         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_PYFUNC_OPTIONAL);
1120
1121         /* draw_filter */
1122         func = RNA_def_function(srna, "draw_filter", NULL);
1123         RNA_def_function_ui_description(func, "Draw filtering options");
1124         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
1125         parm = RNA_def_pointer(func, "context", "Context", "", "");
1126         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1127         parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item");
1128         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1129
1130         /* filter */
1131         func = RNA_def_function(srna, "filter_items", NULL);
1132         RNA_def_function_ui_description(func, "Filter and/or re-order items of the collection (output filter results in "
1133                                               "filter_flags, and reorder results in filter_neworder arrays)");
1134         RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
1135         parm = RNA_def_pointer(func, "context", "Context", "", "");
1136         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1137         parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take Collection property");
1138         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
1139         parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in data, for the collection");
1140         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1141         prop = RNA_def_property(func, "filter_flags", PROP_INT, PROP_UNSIGNED);
1142         RNA_def_property_flag(prop, PARM_REQUIRED | PROP_DYNAMIC);
1143         RNA_def_property_array(prop, 1);  /* XXX Dummy value, default 0 does not work */
1144         RNA_def_property_ui_text(prop, "", "An array of filter flags, one for each item in the collection (NOTE: "
1145                                            "FILTER_ITEM bit is reserved, it defines whether the item is shown or not)");
1146         RNA_def_function_output(func, prop);
1147         prop = RNA_def_property(func, "filter_neworder", PROP_INT, PROP_UNSIGNED);
1148         RNA_def_property_flag(prop, PARM_REQUIRED | PROP_DYNAMIC);
1149         RNA_def_property_array(prop, 1);  /* XXX Dummy value, default 0 does not work */
1150         RNA_def_property_ui_text(prop, "", "An array of indices, one for each item in the collection, mapping the org "
1151                                            "index to the new one");
1152         RNA_def_function_output(func, prop);
1153
1154         /* "Constants"! */
1155         RNA_define_verify_sdna(0); /* not in sdna */
1156
1157         prop = RNA_def_property(srna, "bitflag_filter_item", PROP_INT, PROP_UNSIGNED);
1158         RNA_def_property_ui_text(prop, "FILTER_ITEM",
1159                                        "The value of the reserved bitflag 'FILTER_ITEM' (in filter_flags values)");
1160         RNA_def_property_int_funcs(prop, "rna_UIList_filter_const_FILTER_ITEM_get", NULL, NULL);
1161         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1162 }
1163
1164 static void rna_def_header(BlenderRNA *brna)
1165 {
1166         StructRNA *srna;
1167         PropertyRNA *prop;
1168         PropertyRNA *parm;
1169         FunctionRNA *func;
1170         
1171         srna = RNA_def_struct(brna, "Header", NULL);
1172         RNA_def_struct_ui_text(srna, "Header", "Editor header containing UI elements");
1173         RNA_def_struct_sdna(srna, "Header");
1174         RNA_def_struct_refine_func(srna, "rna_Header_refine");
1175         RNA_def_struct_register_funcs(srna, "rna_Header_register", "rna_Header_unregister", NULL);
1176
1177         /* draw */
1178         func = RNA_def_function(srna, "draw", NULL);
1179         RNA_def_function_ui_description(func, "Draw UI elements into the header UI layout");
1180         RNA_def_function_flag(func, FUNC_REGISTER);
1181         parm = RNA_def_pointer(func, "context", "Context", "", "");
1182         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1183
1184         RNA_define_verify_sdna(0); /* not in sdna */
1185
1186         prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
1187         RNA_def_property_pointer_sdna(prop, NULL, "layout");
1188         RNA_def_property_struct_type(prop, "UILayout");
1189         RNA_def_property_ui_text(prop, "Layout", "Structure of the header in the UI");
1190
1191         /* registration */
1192         prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
1193         RNA_def_property_string_sdna(prop, NULL, "type->idname");
1194         RNA_def_property_flag(prop, PROP_REGISTER);
1195         RNA_def_property_ui_text(prop, "ID Name",
1196                                  "If this is set, the header gets a custom ID, otherwise it takes the "
1197                                  "name of the class used to define the panel; for example, if the "
1198                                  "class name is \"OBJECT_HT_hello\", and bl_idname is not set by the "
1199                                  "script, then bl_idname = \"OBJECT_HT_hello\"");
1200
1201         prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
1202         RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
1203         RNA_def_property_enum_items(prop, rna_enum_space_type_items);
1204         RNA_def_property_flag(prop, PROP_REGISTER);
1205         RNA_def_property_ui_text(prop, "Space type", "The space where the header is going to be used in");
1206
1207         RNA_define_verify_sdna(1);
1208 }
1209
1210 static void rna_def_menu(BlenderRNA *brna)
1211 {
1212         StructRNA *srna;
1213         PropertyRNA *prop;
1214         PropertyRNA *parm;
1215         FunctionRNA *func;
1216         
1217         srna = RNA_def_struct(brna, "Menu", NULL);
1218         RNA_def_struct_ui_text(srna, "Menu", "Editor menu containing buttons");
1219         RNA_def_struct_sdna(srna, "Menu");
1220         RNA_def_struct_refine_func(srna, "rna_Menu_refine");
1221         RNA_def_struct_register_funcs(srna, "rna_Menu_register", "rna_Menu_unregister", NULL);
1222         RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
1223
1224         /* poll */
1225         func = RNA_def_function(srna, "poll", NULL);
1226         RNA_def_function_ui_description(func, "If this method returns a non-null output, then the menu can be drawn");
1227         RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
1228         RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
1229         parm = RNA_def_pointer(func, "context", "Context", "", "");
1230         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1231
1232         /* draw */
1233         func = RNA_def_function(srna, "draw", NULL);
1234         RNA_def_function_ui_description(func, "Draw UI elements into the menu UI layout");
1235         RNA_def_function_flag(func, FUNC_REGISTER);
1236         parm = RNA_def_pointer(func, "context", "Context", "", "");
1237         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1238
1239         RNA_define_verify_sdna(false); /* not in sdna */
1240
1241         prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
1242         RNA_def_property_pointer_sdna(prop, NULL, "layout");
1243         RNA_def_property_struct_type(prop, "UILayout");
1244         RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the menu in the UI");
1245
1246         /* registration */
1247         prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
1248         RNA_def_property_string_sdna(prop, NULL, "type->idname");
1249         RNA_def_property_flag(prop, PROP_REGISTER);
1250         RNA_def_property_ui_text(prop, "ID Name",
1251                                  "If this is set, the menu gets a custom ID, otherwise it takes the "
1252                                  "name of the class used to define the menu (for example, if the "
1253                                  "class name is \"OBJECT_MT_hello\", and bl_idname is not set by the "
1254                                  "script, then bl_idname = \"OBJECT_MT_hello\")");
1255
1256         prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
1257         RNA_def_property_string_sdna(prop, NULL, "type->label");
1258         RNA_def_property_flag(prop, PROP_REGISTER);
1259         RNA_def_property_ui_text(prop, "Label", "The menu label");
1260
1261         prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
1262         RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
1263         RNA_def_property_string_default(prop, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
1264         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1265
1266         prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
1267         RNA_def_property_string_sdna(prop, NULL, "type->description");
1268         RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
1269         RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Menu_bl_description_set");
1270         /* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
1271         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1272         RNA_def_property_clear_flag(prop, PROP_NEVER_NULL); /* check for NULL */
1273
1274         RNA_define_verify_sdna(1);
1275 }
1276
1277 void RNA_def_ui(BlenderRNA *brna)
1278 {
1279         rna_def_ui_layout(brna);
1280         rna_def_panel(brna);
1281         rna_def_uilist(brna);
1282         rna_def_header(brna);
1283         rna_def_menu(brna);
1284 }
1285
1286 #endif /* RNA_RUNTIME */
1287