5fe4d21c1ae8fd377662b5c546e2b51043e3ad33
[blender-staging.git] / source / blender / makesrna / intern / rna_ui.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributor(s): Blender Foundation (2009)
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 /** \file blender/makesrna/intern/rna_ui.c
26  *  \ingroup RNA
27  */
28
29
30 #include <stdlib.h>
31
32 #include "DNA_screen_types.h"
33
34 #include "RNA_define.h"
35
36 #include "rna_internal.h"
37 #include "RNA_enum_types.h"
38
39 #include "UI_interface.h"
40
41 #include "WM_types.h"
42
43 /* see WM_types.h */
44 EnumPropertyItem operator_context_items[] = {
45         {WM_OP_INVOKE_DEFAULT, "INVOKE_DEFAULT", 0, "Invoke Default", ""},
46         {WM_OP_INVOKE_REGION_WIN, "INVOKE_REGION_WIN", 0, "Invoke Region Window", ""},
47         {WM_OP_INVOKE_REGION_CHANNELS, "INVOKE_REGION_CHANNELS", 0, "Invoke Region Channels", ""},
48         {WM_OP_INVOKE_REGION_PREVIEW, "INVOKE_REGION_PREVIEW", 0, "Invoke Region Preview", ""},
49         {WM_OP_INVOKE_AREA, "INVOKE_AREA", 0, "Invoke Area", ""},
50         {WM_OP_INVOKE_SCREEN, "INVOKE_SCREEN", 0, "Invoke Screen", ""},
51         {WM_OP_EXEC_DEFAULT, "EXEC_DEFAULT", 0, "Exec Default", ""},
52         {WM_OP_EXEC_REGION_WIN, "EXEC_REGION_WIN", 0, "Exec Region Window", ""},
53         {WM_OP_EXEC_REGION_CHANNELS, "EXEC_REGION_CHANNELS", 0, "Exec Region Channels", ""},
54         {WM_OP_EXEC_REGION_PREVIEW, "EXEC_REGION_PREVIEW", 0, "Exec Region Preview", ""},
55         {WM_OP_EXEC_AREA, "EXEC_AREA", 0, "Exec Area", ""},
56         {WM_OP_EXEC_SCREEN, "EXEC_SCREEN", 0, "Exec Screen", ""},
57         {0, NULL, 0, NULL, NULL}};
58
59 #ifdef RNA_RUNTIME
60
61 #include "MEM_guardedalloc.h"
62
63 #include "RNA_access.h"
64
65 #include "BLI_dynstr.h"
66
67 #include "BKE_context.h"
68 #include "BKE_report.h"
69 #include "BKE_screen.h"
70
71 #include "WM_api.h"
72
73 static ARegionType *region_type_find(ReportList *reports, int space_type, int region_type)
74 {
75         SpaceType *st;
76         ARegionType *art;
77
78         st= BKE_spacetype_from_id(space_type);
79
80         for(art= (st)? st->regiontypes.first: NULL; art; art= art->next) {
81                 if (art->regionid==region_type)
82                         break;
83         }
84         
85         /* region type not found? abort */
86         if (art==NULL) {
87                 BKE_report(reports, RPT_ERROR, "Region not found in spacetype.");
88                 return NULL;
89         }
90
91         return art;
92 }
93
94 /* Panel */
95
96 static int panel_poll(const bContext *C, PanelType *pt)
97 {
98         PointerRNA ptr;
99         ParameterList list;
100         FunctionRNA *func;
101         void *ret;
102         int visible;
103
104         RNA_pointer_create(NULL, pt->ext.srna, NULL, &ptr); /* dummy */
105         func= RNA_struct_find_function(&ptr, "poll");
106
107         RNA_parameter_list_create(&list, &ptr, func);
108         RNA_parameter_set_lookup(&list, "context", &C);
109         pt->ext.call((bContext *)C, &ptr, func, &list);
110
111         RNA_parameter_get_lookup(&list, "visible", &ret);
112         visible= *(int*)ret;
113
114         RNA_parameter_list_free(&list);
115
116         return visible;
117 }
118
119 static void panel_draw(const bContext *C, Panel *pnl)
120 {
121         PointerRNA ptr;
122         ParameterList list;
123         FunctionRNA *func;
124
125         RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->ext.srna, pnl, &ptr);
126         func= RNA_struct_find_function(&ptr, "draw");
127
128         RNA_parameter_list_create(&list, &ptr, func);
129         RNA_parameter_set_lookup(&list, "context", &C);
130         pnl->type->ext.call((bContext *)C, &ptr, func, &list);
131
132         RNA_parameter_list_free(&list);
133 }
134
135 static void panel_draw_header(const bContext *C, Panel *pnl)
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_struct_find_function(&ptr, "draw_header");
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 rna_Panel_unregister(Main *bmain, StructRNA *type)
152 {
153         ARegionType *art;
154         PanelType *pt= RNA_struct_blender_type_get(type);
155
156         if(!pt)
157                 return;
158         if(!(art=region_type_find(NULL, pt->space_type, pt->region_type)))
159                 return;
160         
161         RNA_struct_free_extension(type, &pt->ext);
162
163         BLI_freelinkN(&art->paneltypes, pt);
164         RNA_struct_free(&BLENDER_RNA, type);
165
166         /* update while blender is running */
167         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
168 }
169
170 static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
171 {
172         ARegionType *art;
173         PanelType *pt, dummypt = {NULL};
174         Panel dummypanel= {NULL};
175         PointerRNA dummyptr;
176         int have_function[3];
177
178         /* setup dummy panel & panel type to store static properties in */
179         dummypanel.type= &dummypt;
180         RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr);
181
182         /* validate the python class */
183         if(validate(&dummyptr, data, have_function) != 0)
184                 return NULL;
185                 
186         if(strlen(identifier) >= sizeof(dummypt.idname)) {
187                 BKE_reportf(reports, RPT_ERROR, "registering panel class: '%s' is too long, maximum length is %d.", identifier, (int)sizeof(dummypt.idname));
188                 return NULL;
189         }
190         
191         if(!(art=region_type_find(reports, dummypt.space_type, dummypt.region_type)))
192                 return NULL;
193
194         /* check if we have registered this panel type before, and remove it */
195         for(pt=art->paneltypes.first; pt; pt=pt->next) {
196                 if(strcmp(pt->idname, dummypt.idname) == 0) {
197                         if(pt->ext.srna)
198                                 rna_Panel_unregister(bmain, pt->ext.srna);
199                         else
200                                 BLI_freelinkN(&art->paneltypes, pt);
201                         break;
202                 }
203         }
204         
205         /* create a new panel type */
206         pt= MEM_callocN(sizeof(PanelType), "python buttons panel");
207         memcpy(pt, &dummypt, sizeof(dummypt));
208
209         pt->ext.srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); 
210         pt->ext.data= data;
211         pt->ext.call= call;
212         pt->ext.free= free;
213         RNA_struct_blender_type_set(pt->ext.srna, pt);
214         RNA_def_struct_flag(pt->ext.srna, STRUCT_NO_IDPROPERTIES);
215
216         pt->poll= (have_function[0])? panel_poll: NULL;
217         pt->draw= (have_function[1])? panel_draw: NULL;
218         pt->draw_header= (have_function[2])? panel_draw_header: NULL;
219
220         /* XXX use "no header" flag for some ordering of panels until we have real panel ordering */
221         if(pt->flag & PNL_NO_HEADER) {
222                 PanelType *pth = art->paneltypes.first;
223                 while(pth && pth->flag & PNL_NO_HEADER)
224                         pth=pth->next;
225
226                 if(pth)
227                         BLI_insertlinkbefore(&art->paneltypes, pth, pt);
228                 else
229                         BLI_addtail(&art->paneltypes, pt);
230         }
231         else
232                 BLI_addtail(&art->paneltypes, pt);
233
234         /* update while blender is running */
235         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
236         
237         return pt->ext.srna;
238 }
239
240 static StructRNA* rna_Panel_refine(PointerRNA *ptr)
241 {
242         Panel *hdr= (Panel*)ptr->data;
243         return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Panel;
244 }
245
246 /* Header */
247
248 static void header_draw(const bContext *C, Header *hdr)
249 {
250         PointerRNA htr;
251         ParameterList list;
252         FunctionRNA *func;
253
254         RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->ext.srna, hdr, &htr);
255         func= RNA_struct_find_function(&htr, "draw");
256
257         RNA_parameter_list_create(&list, &htr, func);
258         RNA_parameter_set_lookup(&list, "context", &C);
259         hdr->type->ext.call((bContext *)C, &htr, func, &list);
260
261         RNA_parameter_list_free(&list);
262 }
263
264 static void rna_Header_unregister(Main *bmain, StructRNA *type)
265 {
266         ARegionType *art;
267         HeaderType *ht= RNA_struct_blender_type_get(type);
268
269         if(!ht)
270                 return;
271         if(!(art=region_type_find(NULL, ht->space_type, RGN_TYPE_HEADER)))
272                 return;
273         
274         RNA_struct_free_extension(type, &ht->ext);
275
276         BLI_freelinkN(&art->headertypes, ht);
277         RNA_struct_free(&BLENDER_RNA, type);
278
279         /* update while blender is running */
280         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
281 }
282
283 static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
284 {
285         ARegionType *art;
286         HeaderType *ht, dummyht = {NULL};
287         Header dummyheader= {NULL};
288         PointerRNA dummyhtr;
289         int have_function[1];
290
291         /* setup dummy header & header type to store static properties in */
292         dummyheader.type= &dummyht;
293         RNA_pointer_create(NULL, &RNA_Header, &dummyheader, &dummyhtr);
294
295         /* validate the python class */
296         if(validate(&dummyhtr, data, have_function) != 0)
297                 return NULL;
298
299         if(strlen(identifier) >= sizeof(dummyht.idname)) {
300                 BKE_reportf(reports, RPT_ERROR, "registering header class: '%s' is too long, maximum length is %d.", identifier, (int)sizeof(dummyht.idname));
301                 return NULL;
302         }
303
304         if(!(art=region_type_find(reports, dummyht.space_type, RGN_TYPE_HEADER)))
305                 return NULL;
306
307         /* check if we have registered this header type before, and remove it */
308         for(ht=art->headertypes.first; ht; ht=ht->next) {
309                 if(strcmp(ht->idname, dummyht.idname) == 0) {
310                         if(ht->ext.srna)
311                                 rna_Header_unregister(bmain, ht->ext.srna);
312                         break;
313                 }
314         }
315         
316         /* create a new header type */
317         ht= MEM_callocN(sizeof(HeaderType), "python buttons header");
318         memcpy(ht, &dummyht, sizeof(dummyht));
319
320         ht->ext.srna= RNA_def_struct(&BLENDER_RNA, ht->idname, "Header"); 
321         ht->ext.data= data;
322         ht->ext.call= call;
323         ht->ext.free= free;
324         RNA_struct_blender_type_set(ht->ext.srna, ht);
325
326         ht->draw= (have_function[0])? header_draw: NULL;
327
328         BLI_addtail(&art->headertypes, ht);
329
330         /* update while blender is running */
331         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
332         
333         return ht->ext.srna;
334 }
335
336 static StructRNA* rna_Header_refine(PointerRNA *htr)
337 {
338         Header *hdr= (Header*)htr->data;
339         return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Header;
340 }
341
342 /* Menu */
343
344 static int menu_poll(const bContext *C, MenuType *pt)
345 {
346         PointerRNA ptr;
347         ParameterList list;
348         FunctionRNA *func;
349         void *ret;
350         int visible;
351
352         RNA_pointer_create(NULL, pt->ext.srna, NULL, &ptr); /* dummy */
353         func= RNA_struct_find_function(&ptr, "poll");
354
355         RNA_parameter_list_create(&list, &ptr, func);
356         RNA_parameter_set_lookup(&list, "context", &C);
357         pt->ext.call((bContext *)C, &ptr, func, &list);
358
359         RNA_parameter_get_lookup(&list, "visible", &ret);
360         visible= *(int*)ret;
361
362         RNA_parameter_list_free(&list);
363
364         return visible;
365 }
366
367 static void menu_draw(const bContext *C, Menu *hdr)
368 {
369         PointerRNA mtr;
370         ParameterList list;
371         FunctionRNA *func;
372
373         RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->ext.srna, hdr, &mtr);
374         func= RNA_struct_find_function(&mtr, "draw");
375
376         RNA_parameter_list_create(&list, &mtr, func);
377         RNA_parameter_set_lookup(&list, "context", &C);
378         hdr->type->ext.call((bContext *)C, &mtr, func, &list);
379
380         RNA_parameter_list_free(&list);
381 }
382
383 static void rna_Menu_unregister(Main *bmain, StructRNA *type)
384 {
385         MenuType *mt= RNA_struct_blender_type_get(type);
386
387         if(!mt)
388                 return;
389         
390         RNA_struct_free_extension(type, &mt->ext);
391
392         WM_menutype_freelink(mt);
393
394         RNA_struct_free(&BLENDER_RNA, type);
395
396         /* update while blender is running */
397         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
398 }
399
400 static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
401 {
402         MenuType *mt, dummymt = {NULL};
403         Menu dummymenu= {NULL};
404         PointerRNA dummymtr;
405         int have_function[2];
406
407         /* setup dummy menu & menu type to store static properties in */
408         dummymenu.type= &dummymt;
409         RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr);
410
411         /* validate the python class */
412         if(validate(&dummymtr, data, have_function) != 0)
413                 return NULL;
414         
415         if(strlen(identifier) >= sizeof(dummymt.idname)) {
416                 BKE_reportf(reports, RPT_ERROR, "registering menu class: '%s' is too long, maximum length is %d.", identifier, (int)sizeof(dummymt.idname));
417                 return NULL;
418         }
419
420         /* check if we have registered this menu type before, and remove it */
421         mt= WM_menutype_find(dummymt.idname, TRUE);
422         if(mt && mt->ext.srna)
423                 rna_Menu_unregister(bmain, mt->ext.srna);
424         
425         /* create a new menu type */
426         mt= MEM_callocN(sizeof(MenuType), "python buttons menu");
427         memcpy(mt, &dummymt, sizeof(dummymt));
428
429         mt->ext.srna= RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu"); 
430         mt->ext.data= data;
431         mt->ext.call= call;
432         mt->ext.free= free;
433         RNA_struct_blender_type_set(mt->ext.srna, mt);
434         RNA_def_struct_flag(mt->ext.srna, STRUCT_NO_IDPROPERTIES);
435
436         mt->poll= (have_function[0])? menu_poll: NULL;
437         mt->draw= (have_function[1])? menu_draw: NULL;
438
439         WM_menutype_add(mt);
440
441         /* update while blender is running */
442         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
443         
444         return mt->ext.srna;
445 }
446
447 static StructRNA* rna_Menu_refine(PointerRNA *mtr)
448 {
449         Menu *hdr= (Menu*)mtr->data;
450         return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Menu;
451 }
452
453 static int rna_UILayout_active_get(PointerRNA *ptr)
454 {
455         return uiLayoutGetActive(ptr->data);
456 }
457
458 static void rna_UILayout_active_set(PointerRNA *ptr, int value)
459 {
460         uiLayoutSetActive(ptr->data, value);
461 }
462
463 static int rna_UILayout_alert_get(PointerRNA *ptr)
464 {
465         return uiLayoutGetRedAlert(ptr->data);
466 }
467
468 static void rna_UILayout_alert_set(PointerRNA *ptr, int value)
469 {
470         uiLayoutSetRedAlert(ptr->data, value);
471 }
472
473 static void rna_UILayout_op_context_set(PointerRNA *ptr, int value)
474 {
475         uiLayoutSetOperatorContext(ptr->data, value);
476 }
477
478 static int rna_UILayout_op_context_get(PointerRNA *ptr)
479 {
480         return uiLayoutGetOperatorContext(ptr->data);
481 }
482
483 static int rna_UILayout_enabled_get(PointerRNA *ptr)
484 {
485         return uiLayoutGetEnabled(ptr->data);
486 }
487
488 static void rna_UILayout_enabled_set(PointerRNA *ptr, int value)
489 {
490         uiLayoutSetEnabled(ptr->data, value);
491 }
492
493 #if 0
494 static int rna_UILayout_red_alert_get(PointerRNA *ptr)
495 {
496         return uiLayoutGetRedAlert(ptr->data);
497 }
498
499 static void rna_UILayout_red_alert_set(PointerRNA *ptr, int value)
500 {
501         uiLayoutSetRedAlert(ptr->data, value);
502 }
503
504 static int rna_UILayout_keep_aspect_get(PointerRNA *ptr)
505 {
506         return uiLayoutGetKeepAspect(ptr->data);
507 }
508
509 static void rna_UILayout_keep_aspect_set(PointerRNA *ptr, int value)
510 {
511         uiLayoutSetKeepAspect(ptr->data, value);
512 }
513 #endif
514
515 static int rna_UILayout_alignment_get(PointerRNA *ptr)
516 {
517         return uiLayoutGetAlignment(ptr->data);
518 }
519
520 static void rna_UILayout_alignment_set(PointerRNA *ptr, int value)
521 {
522         uiLayoutSetAlignment(ptr->data, value);
523 }
524
525 static float rna_UILayout_scale_x_get(PointerRNA *ptr)
526 {
527         return uiLayoutGetScaleX(ptr->data);
528 }
529
530 static void rna_UILayout_scale_x_set(PointerRNA *ptr, float value)
531 {
532         uiLayoutSetScaleX(ptr->data, value);
533 }
534
535 static float rna_UILayout_scale_y_get(PointerRNA *ptr)
536 {
537         return uiLayoutGetScaleY(ptr->data);
538 }
539
540 static void rna_UILayout_scale_y_set(PointerRNA *ptr, float value)
541 {
542         uiLayoutSetScaleY(ptr->data, value);
543 }
544
545 #else // RNA_RUNTIME
546
547 static void rna_def_ui_layout(BlenderRNA *brna)
548 {
549         StructRNA *srna;
550         PropertyRNA *prop;
551
552         static EnumPropertyItem alignment_items[] = {
553                 {UI_LAYOUT_ALIGN_EXPAND, "EXPAND", 0, "Expand", ""},
554                 {UI_LAYOUT_ALIGN_LEFT, "LEFT", 0, "Left", ""},
555                 {UI_LAYOUT_ALIGN_CENTER, "CENTER", 0, "Center", ""},
556                 {UI_LAYOUT_ALIGN_RIGHT, "RIGHT", 0, "Right", ""},
557                 {0, NULL, 0, NULL, NULL}};
558         
559         /* layout */
560
561         srna= RNA_def_struct(brna, "UILayout", NULL);
562         RNA_def_struct_sdna(srna, "uiLayout");
563         RNA_def_struct_ui_text(srna, "UI Layout", "User interface layout in a panel or header");
564
565         prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
566         RNA_def_property_boolean_funcs(prop, "rna_UILayout_active_get", "rna_UILayout_active_set");
567         
568         prop= RNA_def_property(srna, "operator_context", PROP_ENUM, PROP_NONE);
569         RNA_def_property_enum_items(prop, operator_context_items);
570         RNA_def_property_enum_funcs(prop, "rna_UILayout_op_context_get", "rna_UILayout_op_context_set", NULL);
571         
572         prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
573         RNA_def_property_boolean_funcs(prop, "rna_UILayout_enabled_get", "rna_UILayout_enabled_set");
574         RNA_def_property_ui_text(prop, "Enabled", "When false, this (sub)layout is greyed out.");
575         
576         prop= RNA_def_property(srna, "alert", PROP_BOOLEAN, PROP_NONE);
577         RNA_def_property_boolean_funcs(prop, "rna_UILayout_alert_get", "rna_UILayout_alert_set");
578
579         prop= RNA_def_property(srna, "alignment", PROP_ENUM, PROP_NONE);
580         RNA_def_property_enum_items(prop, alignment_items);
581         RNA_def_property_enum_funcs(prop, "rna_UILayout_alignment_get", "rna_UILayout_alignment_set", NULL);
582
583 #if 0
584         prop= RNA_def_property(srna, "keep_aspect", PROP_BOOLEAN, PROP_NONE);
585         RNA_def_property_boolean_funcs(prop, "rna_UILayout_keep_aspect_get", "rna_UILayout_keep_aspect_set");
586 #endif
587
588         prop= RNA_def_property(srna, "scale_x", PROP_FLOAT, PROP_UNSIGNED);
589         RNA_def_property_float_funcs(prop, "rna_UILayout_scale_x_get", "rna_UILayout_scale_x_set", NULL);
590         RNA_def_property_ui_text(prop, "Scale X", "Scale factor along the X for items in this (sub)layout.");
591         
592         prop= RNA_def_property(srna, "scale_y", PROP_FLOAT, PROP_UNSIGNED);
593         RNA_def_property_float_funcs(prop, "rna_UILayout_scale_y_get", "rna_UILayout_scale_y_set", NULL);
594         RNA_def_property_ui_text(prop, "Scale Y", "Scale factor along the Y for items in this (sub)layout.");
595         RNA_api_ui_layout(srna);
596 }
597
598 static void rna_def_panel(BlenderRNA *brna)
599 {
600         StructRNA *srna;
601         PropertyRNA *prop;
602         PropertyRNA *parm;
603         FunctionRNA *func;
604         
605         static EnumPropertyItem panel_flag_items[] = {
606                         {PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed", "Defines if the panel has to be open or collapsed at the time of its creation."},
607                         {PNL_NO_HEADER, "HIDE_HEADER", 0, "Show Header", "If set to True, the panel shows a header, which contains a clickable arrow to collapse the panel and the label (see bl_label)."},
608                         {0, NULL, 0, NULL, NULL}};
609         
610         srna= RNA_def_struct(brna, "Panel", NULL);
611         RNA_def_struct_ui_text(srna, "Panel", "Panel containing UI elements");
612         RNA_def_struct_sdna(srna, "Panel");
613         RNA_def_struct_refine_func(srna, "rna_Panel_refine");
614         RNA_def_struct_register_funcs(srna, "rna_Panel_register", "rna_Panel_unregister");
615
616         /* poll */
617         func= RNA_def_function(srna, "poll", NULL);
618         RNA_def_function_ui_description(func, "If this method returns a non-null output, then the panel can be drawn.");
619         RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_REGISTER_OPTIONAL);
620         RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
621         parm= RNA_def_pointer(func, "context", "Context", "", "");
622         RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
623
624         /* draw */
625         func= RNA_def_function(srna, "draw", NULL);
626         RNA_def_function_ui_description(func, "Draw UI elements into the panel UI layout.");
627         RNA_def_function_flag(func, FUNC_REGISTER);
628         parm= RNA_def_pointer(func, "context", "Context", "", "");
629         RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
630
631         func= RNA_def_function(srna, "draw_header", NULL);
632         RNA_def_function_ui_description(func, "Draw UI elements into the panel's header UI layout.");
633         RNA_def_function_flag(func, FUNC_REGISTER);
634         parm= RNA_def_pointer(func, "context", "Context", "", "");
635         RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
636
637         prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
638         RNA_def_property_struct_type(prop, "UILayout");
639         RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the panel in the UI.");
640         
641         prop= RNA_def_property(srna, "text", PROP_STRING, PROP_NONE);
642         RNA_def_property_string_sdna(prop, NULL, "drawname");
643         RNA_def_property_ui_text(prop, "Text", "XXX todo");
644         
645         /* registration */
646         prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
647         RNA_def_property_string_sdna(prop, NULL, "type->idname");
648         RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
649         RNA_def_property_ui_text(prop, "ID Name", "If this is set, the panel gets a custom ID, otherwise it takes the name of the class used to define the panel. For example, if the class name is \"OBJECT_PT_hello\", and bl_idname is not set by the script, then bl_idname = \"OBJECT_PT_hello\"");
650         
651         prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
652         RNA_def_property_string_sdna(prop, NULL, "type->label");
653         RNA_def_property_flag(prop, PROP_REGISTER);
654         RNA_def_property_ui_text(prop, "Label", "The panel label, shows up in the panel header at the right of the triangle used to collapse the panel.");
655         
656         prop= RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
657         RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
658         RNA_def_property_enum_items(prop, space_type_items);
659         RNA_def_property_flag(prop, PROP_REGISTER);
660         RNA_def_property_ui_text(prop, "Space type", "The space where the panel is going to be used in.");
661         
662         prop= RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE);
663         RNA_def_property_enum_sdna(prop, NULL, "type->region_type");
664         RNA_def_property_enum_items(prop, region_type_items);
665         RNA_def_property_flag(prop, PROP_REGISTER);
666         RNA_def_property_ui_text(prop, "Region Type", "The region where the panel is going to be used in.");
667
668         prop= RNA_def_property(srna, "bl_context", PROP_STRING, PROP_NONE);
669         RNA_def_property_string_sdna(prop, NULL, "type->context");
670         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); /* should this be optional? - Campbell */
671         RNA_def_property_ui_text(prop, "Context", "The context in which the panel belongs to. (TODO: explain the possible combinations bl_context/bl_region_type/bl_space_type)");
672         
673         prop= RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
674         RNA_def_property_enum_sdna(prop, NULL, "type->flag");
675         RNA_def_property_enum_items(prop, panel_flag_items);
676         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL|PROP_ENUM_FLAG);
677         RNA_def_property_ui_text(prop, "Options",  "Options for this panel type");
678 }
679
680 static void rna_def_header(BlenderRNA *brna)
681 {
682         StructRNA *srna;
683         PropertyRNA *prop;
684         PropertyRNA *parm;
685         FunctionRNA *func;
686         
687         srna= RNA_def_struct(brna, "Header", NULL);
688         RNA_def_struct_ui_text(srna, "Header", "Editor header containing UI elements.");
689         RNA_def_struct_sdna(srna, "Header");
690         RNA_def_struct_refine_func(srna, "rna_Header_refine");
691         RNA_def_struct_register_funcs(srna, "rna_Header_register", "rna_Header_unregister");
692
693         /* draw */
694         func= RNA_def_function(srna, "draw", NULL);
695         RNA_def_function_ui_description(func, "Draw UI elements into the header UI layout.");
696         RNA_def_function_flag(func, FUNC_REGISTER);
697         parm= RNA_def_pointer(func, "context", "Context", "", "");
698         RNA_def_property_flag(parm, PROP_REQUIRED);
699
700         RNA_define_verify_sdna(0); // not in sdna
701
702         prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
703         RNA_def_property_pointer_sdna(prop, NULL, "layout");
704         RNA_def_property_struct_type(prop, "UILayout");
705         RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the header in the UI.");
706
707         /* registration */
708         prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
709         RNA_def_property_string_sdna(prop, NULL, "type->idname");
710         RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
711         RNA_def_property_ui_text(prop, "ID Name", "If this is set, the header gets a custom ID, otherwise it takes the name of the class used to define the panel. For example, if the class name is \"OBJECT_HT_hello\", and bl_idname is not set by the script, then bl_idname = \"OBJECT_HT_hello\"");
712
713         prop= RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
714         RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
715         RNA_def_property_enum_items(prop, space_type_items);
716         RNA_def_property_flag(prop, PROP_REGISTER);
717         RNA_def_property_ui_text(prop, "Space type", "The space where the header is going to be used in.");
718
719         RNA_define_verify_sdna(1);
720 }
721
722 static void rna_def_menu(BlenderRNA *brna)
723 {
724         StructRNA *srna;
725         PropertyRNA *prop;
726         PropertyRNA *parm;
727         FunctionRNA *func;
728         
729         srna= RNA_def_struct(brna, "Menu", NULL);
730         RNA_def_struct_ui_text(srna, "Menu", "Editor menu containing buttons");
731         RNA_def_struct_sdna(srna, "Menu");
732         RNA_def_struct_refine_func(srna, "rna_Menu_refine");
733         RNA_def_struct_register_funcs(srna, "rna_Menu_register", "rna_Menu_unregister");
734
735         /* poll */
736         func= RNA_def_function(srna, "poll", NULL);
737         RNA_def_function_ui_description(func, "If this method returns a non-null output, then the menu can be drawn.");
738         RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_REGISTER_OPTIONAL);
739         RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
740         parm= RNA_def_pointer(func, "context", "Context", "", "");
741         RNA_def_property_flag(parm, PROP_REQUIRED);
742
743         /* draw */
744         func= RNA_def_function(srna, "draw", NULL);
745         RNA_def_function_ui_description(func, "Draw UI elements into the menu UI layout.");
746         RNA_def_function_flag(func, FUNC_REGISTER);
747         parm= RNA_def_pointer(func, "context", "Context", "", "");
748         RNA_def_property_flag(parm, PROP_REQUIRED);
749
750         RNA_define_verify_sdna(0); // not in sdna
751
752         prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
753         RNA_def_property_pointer_sdna(prop, NULL, "layout");
754         RNA_def_property_struct_type(prop, "UILayout");
755         RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the menu in the UI.");
756
757         /* registration */
758         prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
759         RNA_def_property_string_sdna(prop, NULL, "type->idname");
760         RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
761         RNA_def_property_ui_text(prop, "ID Name", "If this is set, the menu gets a custom ID, otherwise it takes the name of the class used to define the panel. For example, if the class name is \"OBJECT_MT_hello\", and bl_idname is not set by the script, then bl_idname = \"OBJECT_MT_hello\"");
762
763         prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
764         RNA_def_property_string_sdna(prop, NULL, "type->label");
765         RNA_def_property_flag(prop, PROP_REGISTER);
766         RNA_def_property_ui_text(prop, "Label", "The menu label");
767
768         RNA_define_verify_sdna(1);
769 }
770
771 void RNA_def_ui(BlenderRNA *brna)
772 {
773         rna_def_ui_layout(brna);
774         rna_def_panel(brna);
775         rna_def_header(brna);
776         rna_def_menu(brna);
777 }
778
779 #endif // RNA_RUNTIME
780