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