svn merge ^/trunk/blender -r40720:40872
[blender.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 *UNUSED(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,
171                                      StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
172 {
173         ARegionType *art;
174         PanelType *pt, dummypt = {NULL};
175         Panel dummypanel= {NULL};
176         PointerRNA dummyptr;
177         int have_function[3];
178
179         /* setup dummy panel & panel type to store static properties in */
180         dummypanel.type= &dummypt;
181         RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr);
182
183         /* validate the python class */
184         if(validate(&dummyptr, data, have_function) != 0)
185                 return NULL;
186                 
187         if(strlen(identifier) >= sizeof(dummypt.idname)) {
188                 BKE_reportf(reports, RPT_ERROR, "registering panel class: '%s' is too long, maximum length is %d",
189                             identifier, (int)sizeof(dummypt.idname));
190                 return NULL;
191         }
192         
193         if(!(art=region_type_find(reports, dummypt.space_type, dummypt.region_type)))
194                 return NULL;
195
196         /* check if we have registered this panel type before, and remove it */
197         for(pt=art->paneltypes.first; pt; pt=pt->next) {
198                 if(strcmp(pt->idname, dummypt.idname) == 0) {
199                         if(pt->ext.srna)
200                                 rna_Panel_unregister(bmain, pt->ext.srna);
201                         else
202                                 BLI_freelinkN(&art->paneltypes, pt);
203                         break;
204                 }
205         }
206         
207         /* create a new panel type */
208         pt= MEM_callocN(sizeof(PanelType), "python buttons panel");
209         memcpy(pt, &dummypt, sizeof(dummypt));
210
211         pt->ext.srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); 
212         pt->ext.data= data;
213         pt->ext.call= call;
214         pt->ext.free= free;
215         RNA_struct_blender_type_set(pt->ext.srna, pt);
216         RNA_def_struct_flag(pt->ext.srna, STRUCT_NO_IDPROPERTIES);
217
218         pt->poll= (have_function[0])? panel_poll: NULL;
219         pt->draw= (have_function[1])? panel_draw: NULL;
220         pt->draw_header= (have_function[2])? panel_draw_header: NULL;
221
222         /* XXX use "no header" flag for some ordering of panels until we have real panel ordering */
223         if(pt->flag & PNL_NO_HEADER) {
224                 PanelType *pth = art->paneltypes.first;
225                 while(pth && pth->flag & PNL_NO_HEADER)
226                         pth=pth->next;
227
228                 if(pth)
229                         BLI_insertlinkbefore(&art->paneltypes, pth, pt);
230                 else
231                         BLI_addtail(&art->paneltypes, pt);
232         }
233         else
234                 BLI_addtail(&art->paneltypes, pt);
235
236         /* update while blender is running */
237         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
238         
239         return pt->ext.srna;
240 }
241
242 static StructRNA* rna_Panel_refine(PointerRNA *ptr)
243 {
244         Panel *hdr= (Panel*)ptr->data;
245         return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Panel;
246 }
247
248 /* Header */
249
250 static void header_draw(const bContext *C, Header *hdr)
251 {
252         PointerRNA htr;
253         ParameterList list;
254         FunctionRNA *func;
255
256         RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->ext.srna, hdr, &htr);
257         func= RNA_struct_find_function(&htr, "draw");
258
259         RNA_parameter_list_create(&list, &htr, func);
260         RNA_parameter_set_lookup(&list, "context", &C);
261         hdr->type->ext.call((bContext *)C, &htr, func, &list);
262
263         RNA_parameter_list_free(&list);
264 }
265
266 static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type)
267 {
268         ARegionType *art;
269         HeaderType *ht= RNA_struct_blender_type_get(type);
270
271         if(!ht)
272                 return;
273         if(!(art=region_type_find(NULL, ht->space_type, RGN_TYPE_HEADER)))
274                 return;
275         
276         RNA_struct_free_extension(type, &ht->ext);
277
278         BLI_freelinkN(&art->headertypes, ht);
279         RNA_struct_free(&BLENDER_RNA, type);
280
281         /* update while blender is running */
282         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
283 }
284
285 static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
286                                       StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
287 {
288         ARegionType *art;
289         HeaderType *ht, dummyht = {NULL};
290         Header dummyheader= {NULL};
291         PointerRNA dummyhtr;
292         int have_function[1];
293
294         /* setup dummy header & header type to store static properties in */
295         dummyheader.type= &dummyht;
296         RNA_pointer_create(NULL, &RNA_Header, &dummyheader, &dummyhtr);
297
298         /* validate the python class */
299         if(validate(&dummyhtr, data, have_function) != 0)
300                 return NULL;
301
302         if(strlen(identifier) >= sizeof(dummyht.idname)) {
303                 BKE_reportf(reports, RPT_ERROR, "registering header class: '%s' is too long, maximum length is %d",
304                             identifier, (int)sizeof(dummyht.idname));
305                 return NULL;
306         }
307
308         if(!(art=region_type_find(reports, dummyht.space_type, RGN_TYPE_HEADER)))
309                 return NULL;
310
311         /* check if we have registered this header type before, and remove it */
312         for(ht=art->headertypes.first; ht; ht=ht->next) {
313                 if(strcmp(ht->idname, dummyht.idname) == 0) {
314                         if(ht->ext.srna)
315                                 rna_Header_unregister(bmain, ht->ext.srna);
316                         break;
317                 }
318         }
319         
320         /* create a new header type */
321         ht= MEM_callocN(sizeof(HeaderType), "python buttons header");
322         memcpy(ht, &dummyht, sizeof(dummyht));
323
324         ht->ext.srna= RNA_def_struct(&BLENDER_RNA, ht->idname, "Header"); 
325         ht->ext.data= data;
326         ht->ext.call= call;
327         ht->ext.free= free;
328         RNA_struct_blender_type_set(ht->ext.srna, ht);
329
330         ht->draw= (have_function[0])? header_draw: NULL;
331
332         BLI_addtail(&art->headertypes, ht);
333
334         /* update while blender is running */
335         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
336         
337         return ht->ext.srna;
338 }
339
340 static StructRNA* rna_Header_refine(PointerRNA *htr)
341 {
342         Header *hdr= (Header*)htr->data;
343         return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Header;
344 }
345
346 /* Menu */
347
348 static int menu_poll(const bContext *C, MenuType *pt)
349 {
350         PointerRNA ptr;
351         ParameterList list;
352         FunctionRNA *func;
353         void *ret;
354         int visible;
355
356         RNA_pointer_create(NULL, pt->ext.srna, NULL, &ptr); /* dummy */
357         func= RNA_struct_find_function(&ptr, "poll");
358
359         RNA_parameter_list_create(&list, &ptr, func);
360         RNA_parameter_set_lookup(&list, "context", &C);
361         pt->ext.call((bContext *)C, &ptr, func, &list);
362
363         RNA_parameter_get_lookup(&list, "visible", &ret);
364         visible= *(int*)ret;
365
366         RNA_parameter_list_free(&list);
367
368         return visible;
369 }
370
371 static void menu_draw(const bContext *C, Menu *hdr)
372 {
373         PointerRNA mtr;
374         ParameterList list;
375         FunctionRNA *func;
376
377         RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->ext.srna, hdr, &mtr);
378         func= RNA_struct_find_function(&mtr, "draw");
379
380         RNA_parameter_list_create(&list, &mtr, func);
381         RNA_parameter_set_lookup(&list, "context", &C);
382         hdr->type->ext.call((bContext *)C, &mtr, func, &list);
383
384         RNA_parameter_list_free(&list);
385 }
386
387 static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type)
388 {
389         MenuType *mt= RNA_struct_blender_type_get(type);
390
391         if(!mt)
392                 return;
393         
394         RNA_struct_free_extension(type, &mt->ext);
395
396         WM_menutype_freelink(mt);
397
398         RNA_struct_free(&BLENDER_RNA, type);
399
400         /* update while blender is running */
401         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
402 }
403
404 static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
405                                     StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
406 {
407         MenuType *mt, dummymt = {NULL};
408         Menu dummymenu= {NULL};
409         PointerRNA dummymtr;
410         int have_function[2];
411
412         /* setup dummy menu & menu type to store static properties in */
413         dummymenu.type= &dummymt;
414         RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr);
415
416         /* validate the python class */
417         if(validate(&dummymtr, data, have_function) != 0)
418                 return NULL;
419         
420         if(strlen(identifier) >= sizeof(dummymt.idname)) {
421                 BKE_reportf(reports, RPT_ERROR, "registering menu class: '%s' is too long, maximum length is %d",
422                             identifier, (int)sizeof(dummymt.idname));
423                 return NULL;
424         }
425
426         /* check if we have registered this menu type before, and remove it */
427         mt= WM_menutype_find(dummymt.idname, TRUE);
428         if(mt && mt->ext.srna)
429                 rna_Menu_unregister(bmain, mt->ext.srna);
430         
431         /* create a new menu type */
432         mt= MEM_callocN(sizeof(MenuType), "python buttons menu");
433         memcpy(mt, &dummymt, sizeof(dummymt));
434
435         mt->ext.srna= RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu"); 
436         mt->ext.data= data;
437         mt->ext.call= call;
438         mt->ext.free= free;
439         RNA_struct_blender_type_set(mt->ext.srna, mt);
440         RNA_def_struct_flag(mt->ext.srna, STRUCT_NO_IDPROPERTIES);
441
442         mt->poll= (have_function[0])? menu_poll: NULL;
443         mt->draw= (have_function[1])? menu_draw: NULL;
444
445         WM_menutype_add(mt);
446
447         /* update while blender is running */
448         WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
449         
450         return mt->ext.srna;
451 }
452
453 static StructRNA* rna_Menu_refine(PointerRNA *mtr)
454 {
455         Menu *hdr= (Menu*)mtr->data;
456         return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Menu;
457 }
458
459 static int rna_UILayout_active_get(PointerRNA *ptr)
460 {
461         return uiLayoutGetActive(ptr->data);
462 }
463
464 static void rna_UILayout_active_set(PointerRNA *ptr, int value)
465 {
466         uiLayoutSetActive(ptr->data, value);
467 }
468
469 static int rna_UILayout_alert_get(PointerRNA *ptr)
470 {
471         return uiLayoutGetRedAlert(ptr->data);
472 }
473
474 static void rna_UILayout_alert_set(PointerRNA *ptr, int value)
475 {
476         uiLayoutSetRedAlert(ptr->data, value);
477 }
478
479 static void rna_UILayout_op_context_set(PointerRNA *ptr, int value)
480 {
481         uiLayoutSetOperatorContext(ptr->data, value);
482 }
483
484 static int rna_UILayout_op_context_get(PointerRNA *ptr)
485 {
486         return uiLayoutGetOperatorContext(ptr->data);
487 }
488
489 static int rna_UILayout_enabled_get(PointerRNA *ptr)
490 {
491         return uiLayoutGetEnabled(ptr->data);
492 }
493
494 static void rna_UILayout_enabled_set(PointerRNA *ptr, int value)
495 {
496         uiLayoutSetEnabled(ptr->data, value);
497 }
498
499 #if 0
500 static int rna_UILayout_red_alert_get(PointerRNA *ptr)
501 {
502         return uiLayoutGetRedAlert(ptr->data);
503 }
504
505 static void rna_UILayout_red_alert_set(PointerRNA *ptr, int value)
506 {
507         uiLayoutSetRedAlert(ptr->data, value);
508 }
509
510 static int rna_UILayout_keep_aspect_get(PointerRNA *ptr)
511 {
512         return uiLayoutGetKeepAspect(ptr->data);
513 }
514
515 static void rna_UILayout_keep_aspect_set(PointerRNA *ptr, int value)
516 {
517         uiLayoutSetKeepAspect(ptr->data, value);
518 }
519 #endif
520
521 static int rna_UILayout_alignment_get(PointerRNA *ptr)
522 {
523         return uiLayoutGetAlignment(ptr->data);
524 }
525
526 static void rna_UILayout_alignment_set(PointerRNA *ptr, int value)
527 {
528         uiLayoutSetAlignment(ptr->data, value);
529 }
530
531 static float rna_UILayout_scale_x_get(PointerRNA *ptr)
532 {
533         return uiLayoutGetScaleX(ptr->data);
534 }
535
536 static void rna_UILayout_scale_x_set(PointerRNA *ptr, float value)
537 {
538         uiLayoutSetScaleX(ptr->data, value);
539 }
540
541 static float rna_UILayout_scale_y_get(PointerRNA *ptr)
542 {
543         return uiLayoutGetScaleY(ptr->data);
544 }
545
546 static void rna_UILayout_scale_y_set(PointerRNA *ptr, float value)
547 {
548         uiLayoutSetScaleY(ptr->data, value);
549 }
550
551 #else // RNA_RUNTIME
552
553 static void rna_def_ui_layout(BlenderRNA *brna)
554 {
555         StructRNA *srna;
556         PropertyRNA *prop;
557
558         static EnumPropertyItem alignment_items[] = {
559                 {UI_LAYOUT_ALIGN_EXPAND, "EXPAND", 0, "Expand", ""},
560                 {UI_LAYOUT_ALIGN_LEFT, "LEFT", 0, "Left", ""},
561                 {UI_LAYOUT_ALIGN_CENTER, "CENTER", 0, "Center", ""},
562                 {UI_LAYOUT_ALIGN_RIGHT, "RIGHT", 0, "Right", ""},
563                 {0, NULL, 0, NULL, NULL}};
564         
565         /* layout */
566
567         srna= RNA_def_struct(brna, "UILayout", NULL);
568         RNA_def_struct_sdna(srna, "uiLayout");
569         RNA_def_struct_ui_text(srna, "UI Layout", "User interface layout in a panel or header");
570
571         prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
572         RNA_def_property_boolean_funcs(prop, "rna_UILayout_active_get", "rna_UILayout_active_set");
573         
574         prop= RNA_def_property(srna, "operator_context", PROP_ENUM, PROP_NONE);
575         RNA_def_property_enum_items(prop, operator_context_items);
576         RNA_def_property_enum_funcs(prop, "rna_UILayout_op_context_get", "rna_UILayout_op_context_set", NULL);
577         
578         prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
579         RNA_def_property_boolean_funcs(prop, "rna_UILayout_enabled_get", "rna_UILayout_enabled_set");
580         RNA_def_property_ui_text(prop, "Enabled", "When false, this (sub)layout is greyed out");
581         
582         prop= RNA_def_property(srna, "alert", PROP_BOOLEAN, PROP_NONE);
583         RNA_def_property_boolean_funcs(prop, "rna_UILayout_alert_get", "rna_UILayout_alert_set");
584
585         prop= RNA_def_property(srna, "alignment", PROP_ENUM, PROP_NONE);
586         RNA_def_property_enum_items(prop, alignment_items);
587         RNA_def_property_enum_funcs(prop, "rna_UILayout_alignment_get", "rna_UILayout_alignment_set", NULL);
588
589 #if 0
590         prop= RNA_def_property(srna, "keep_aspect", PROP_BOOLEAN, PROP_NONE);
591         RNA_def_property_boolean_funcs(prop, "rna_UILayout_keep_aspect_get", "rna_UILayout_keep_aspect_set");
592 #endif
593
594         prop= RNA_def_property(srna, "scale_x", PROP_FLOAT, PROP_UNSIGNED);
595         RNA_def_property_float_funcs(prop, "rna_UILayout_scale_x_get", "rna_UILayout_scale_x_set", NULL);
596         RNA_def_property_ui_text(prop, "Scale X", "Scale factor along the X for items in this (sub)layout");
597         
598         prop= RNA_def_property(srna, "scale_y", PROP_FLOAT, PROP_UNSIGNED);
599         RNA_def_property_float_funcs(prop, "rna_UILayout_scale_y_get", "rna_UILayout_scale_y_set", NULL);
600         RNA_def_property_ui_text(prop, "Scale Y", "Scale factor along the Y for items in this (sub)layout");
601         RNA_api_ui_layout(srna);
602 }
603
604 static void rna_def_panel(BlenderRNA *brna)
605 {
606         StructRNA *srna;
607         PropertyRNA *prop;
608         PropertyRNA *parm;
609         FunctionRNA *func;
610         
611         static EnumPropertyItem panel_flag_items[] = {
612                         {PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed",
613                                              "Defines if the panel has to be open or collapsed at the time of its creation"},
614                         {PNL_NO_HEADER, "HIDE_HEADER", 0, "Show Header",
615                                         "If set to True, the panel shows a header, which contains a clickable "
616                                         "arrow to collapse the panel and the label (see bl_label)"},
617                         {0, NULL, 0, NULL, NULL}};
618         
619         srna= RNA_def_struct(brna, "Panel", NULL);
620         RNA_def_struct_ui_text(srna, "Panel", "Panel containing UI elements");
621         RNA_def_struct_sdna(srna, "Panel");
622         RNA_def_struct_refine_func(srna, "rna_Panel_refine");
623         RNA_def_struct_register_funcs(srna, "rna_Panel_register", "rna_Panel_unregister", NULL);
624
625         /* poll */
626         func= RNA_def_function(srna, "poll", NULL);
627         RNA_def_function_ui_description(func, "If this method returns a non-null output, then the panel can be drawn");
628         RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_REGISTER_OPTIONAL);
629         RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
630         parm= RNA_def_pointer(func, "context", "Context", "", "");
631         RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
632
633         /* draw */
634         func= RNA_def_function(srna, "draw", NULL);
635         RNA_def_function_ui_description(func, "Draw UI elements into the panel UI layout");
636         RNA_def_function_flag(func, FUNC_REGISTER);
637         parm= RNA_def_pointer(func, "context", "Context", "", "");
638         RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
639
640         func= RNA_def_function(srna, "draw_header", NULL);
641         RNA_def_function_ui_description(func, "Draw UI elements into the panel's header UI layout");
642         RNA_def_function_flag(func, FUNC_REGISTER);
643         parm= RNA_def_pointer(func, "context", "Context", "", "");
644         RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
645
646         prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
647         RNA_def_property_struct_type(prop, "UILayout");
648         RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the panel in the UI");
649         
650         prop= RNA_def_property(srna, "text", PROP_STRING, PROP_NONE);
651         RNA_def_property_string_sdna(prop, NULL, "drawname");
652         RNA_def_property_ui_text(prop, "Text", "XXX todo");
653         
654         /* registration */
655         prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
656         RNA_def_property_string_sdna(prop, NULL, "type->idname");
657         RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
658         RNA_def_property_ui_text(prop, "ID Name",
659                                  "If this is set, the panel gets a custom ID, otherwise it takes the "
660                                  "name of the class used to define the panel. For example, if the "
661                                  "class name is \"OBJECT_PT_hello\", and bl_idname is not set by the "
662                                  "script, then bl_idname = \"OBJECT_PT_hello\"");
663         
664         prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
665         RNA_def_property_string_sdna(prop, NULL, "type->label");
666         RNA_def_property_flag(prop, PROP_REGISTER);
667         RNA_def_property_ui_text(prop, "Label",
668                                  "The panel label, shows up in the panel header at the right of the "
669                                  "triangle used to collapse the panel");
670         
671         prop= RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
672         RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
673         RNA_def_property_enum_items(prop, space_type_items);
674         RNA_def_property_flag(prop, PROP_REGISTER);
675         RNA_def_property_ui_text(prop, "Space type", "The space where the panel is going to be used in");
676         
677         prop= RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE);
678         RNA_def_property_enum_sdna(prop, NULL, "type->region_type");
679         RNA_def_property_enum_items(prop, region_type_items);
680         RNA_def_property_flag(prop, PROP_REGISTER);
681         RNA_def_property_ui_text(prop, "Region Type", "The region where the panel is going to be used in");
682
683         prop= RNA_def_property(srna, "bl_context", PROP_STRING, PROP_NONE);
684         RNA_def_property_string_sdna(prop, NULL, "type->context");
685         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); /* should this be optional? - Campbell */
686         RNA_def_property_ui_text(prop, "Context",
687                                  "The context in which the panel belongs to. (TODO: explain the "
688                                  "possible combinations bl_context/bl_region_type/bl_space_type)");
689         
690         prop= RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
691         RNA_def_property_enum_sdna(prop, NULL, "type->flag");
692         RNA_def_property_enum_items(prop, panel_flag_items);
693         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL|PROP_ENUM_FLAG);
694         RNA_def_property_ui_text(prop, "Options",  "Options for this panel type");
695 }
696
697 static void rna_def_header(BlenderRNA *brna)
698 {
699         StructRNA *srna;
700         PropertyRNA *prop;
701         PropertyRNA *parm;
702         FunctionRNA *func;
703         
704         srna= RNA_def_struct(brna, "Header", NULL);
705         RNA_def_struct_ui_text(srna, "Header", "Editor header containing UI elements");
706         RNA_def_struct_sdna(srna, "Header");
707         RNA_def_struct_refine_func(srna, "rna_Header_refine");
708         RNA_def_struct_register_funcs(srna, "rna_Header_register", "rna_Header_unregister", NULL);
709
710         /* draw */
711         func= RNA_def_function(srna, "draw", NULL);
712         RNA_def_function_ui_description(func, "Draw UI elements into the header UI layout");
713         RNA_def_function_flag(func, FUNC_REGISTER);
714         parm= RNA_def_pointer(func, "context", "Context", "", "");
715         RNA_def_property_flag(parm, PROP_REQUIRED);
716
717         RNA_define_verify_sdna(0); // not in sdna
718
719         prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
720         RNA_def_property_pointer_sdna(prop, NULL, "layout");
721         RNA_def_property_struct_type(prop, "UILayout");
722         RNA_def_property_ui_text(prop, "Layout", "Structure of the header in the UI");
723
724         /* registration */
725         prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
726         RNA_def_property_string_sdna(prop, NULL, "type->idname");
727         RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
728         RNA_def_property_ui_text(prop, "ID Name",
729                                  "If this is set, the header gets a custom ID, otherwise it takes the "
730                                  "name of the class used to define the panel; for example, if the "
731                                  "class name is \"OBJECT_HT_hello\", and bl_idname is not set by the "
732                                  "script, then bl_idname = \"OBJECT_HT_hello\"");
733
734         prop= RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
735         RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
736         RNA_def_property_enum_items(prop, space_type_items);
737         RNA_def_property_flag(prop, PROP_REGISTER);
738         RNA_def_property_ui_text(prop, "Space type", "The space where the header is going to be used in");
739
740         RNA_define_verify_sdna(1);
741 }
742
743 static void rna_def_menu(BlenderRNA *brna)
744 {
745         StructRNA *srna;
746         PropertyRNA *prop;
747         PropertyRNA *parm;
748         FunctionRNA *func;
749         
750         srna= RNA_def_struct(brna, "Menu", NULL);
751         RNA_def_struct_ui_text(srna, "Menu", "Editor menu containing buttons");
752         RNA_def_struct_sdna(srna, "Menu");
753         RNA_def_struct_refine_func(srna, "rna_Menu_refine");
754         RNA_def_struct_register_funcs(srna, "rna_Menu_register", "rna_Menu_unregister", NULL);
755
756         /* poll */
757         func= RNA_def_function(srna, "poll", NULL);
758         RNA_def_function_ui_description(func, "If this method returns a non-null output, then the menu can be drawn");
759         RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_REGISTER_OPTIONAL);
760         RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
761         parm= RNA_def_pointer(func, "context", "Context", "", "");
762         RNA_def_property_flag(parm, PROP_REQUIRED);
763
764         /* draw */
765         func= RNA_def_function(srna, "draw", NULL);
766         RNA_def_function_ui_description(func, "Draw UI elements into the menu UI layout");
767         RNA_def_function_flag(func, FUNC_REGISTER);
768         parm= RNA_def_pointer(func, "context", "Context", "", "");
769         RNA_def_property_flag(parm, PROP_REQUIRED);
770
771         RNA_define_verify_sdna(0); // not in sdna
772
773         prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
774         RNA_def_property_pointer_sdna(prop, NULL, "layout");
775         RNA_def_property_struct_type(prop, "UILayout");
776         RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the menu in the UI");
777
778         /* registration */
779         prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
780         RNA_def_property_string_sdna(prop, NULL, "type->idname");
781         RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
782         RNA_def_property_ui_text(prop, "ID Name",
783                                  "If this is set, the menu gets a custom ID, otherwise it takes the "
784                                  "name of the class used to define the menu (for example, if the "
785                                  "class name is \"OBJECT_MT_hello\", and bl_idname is not set by the "
786                                  "script, then bl_idname = \"OBJECT_MT_hello\")");
787
788         prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
789         RNA_def_property_string_sdna(prop, NULL, "type->label");
790         RNA_def_property_flag(prop, PROP_REGISTER);
791         RNA_def_property_ui_text(prop, "Label", "The menu label");
792
793         RNA_define_verify_sdna(1);
794 }
795
796 void RNA_def_ui(BlenderRNA *brna)
797 {
798         rna_def_ui_layout(brna);
799         rna_def_panel(brna);
800         rna_def_header(brna);
801         rna_def_menu(brna);
802 }
803
804 #endif // RNA_RUNTIME
805