changed some {} to {0}, these were causing errors on msvc. also got rid of some...
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Contributor(s): Blender Foundation (2009)
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include <stdlib.h>
26
27 #include "RNA_define.h"
28 #include "RNA_types.h"
29
30 #include "rna_internal.h"
31 #include "RNA_enum_types.h"
32
33 #ifdef RNA_RUNTIME
34
35 #include "MEM_guardedalloc.h"
36
37 #include "RNA_access.h"
38
39 #include "DNA_screen_types.h"
40
41 #include "BLI_dynstr.h"
42
43 #include "BKE_context.h"
44 #include "BKE_report.h"
45 #include "BKE_screen.h"
46
47 #include "UI_interface.h"
48
49 #include "WM_api.h"
50 #include "WM_types.h"
51
52 static ARegionType *region_type_find(ReportList *reports, int space_type, int region_type)
53 {
54         SpaceType *st;
55         ARegionType *art;
56
57         st= BKE_spacetype_from_id(space_type);
58
59         for(art= (st)? st->regiontypes.first: NULL; art; art= art->next) {
60                 if (art->regionid==region_type)
61                         break;
62         }
63         
64         /* region type not found? abort */
65         if (art==NULL) {
66                 BKE_report(reports, RPT_ERROR, "Region not found in spacetype.");
67                 return NULL;
68         }
69
70         return art;
71 }
72
73 /* Panel */
74
75 static int panel_poll(const bContext *C, PanelType *pt)
76 {
77         PointerRNA ptr;
78         ParameterList *list;
79         FunctionRNA *func;
80         void *ret;
81         int visible;
82
83         RNA_pointer_create(NULL, pt->py_srna, NULL, &ptr); /* dummy */
84         func= RNA_struct_find_function(&ptr, "poll");
85
86         list= RNA_parameter_list_create(&ptr, func);
87         RNA_parameter_set_lookup(list, "context", &C);
88         pt->py_call(&ptr, func, list);
89
90         RNA_parameter_get_lookup(list, "visible", &ret);
91         visible= *(int*)ret;
92
93         RNA_parameter_list_free(list);
94
95         return visible;
96 }
97
98 static void panel_draw(const bContext *C, Panel *pnl)
99 {
100         PointerRNA ptr;
101         ParameterList *list;
102         FunctionRNA *func;
103
104         RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->py_srna, pnl, &ptr);
105         func= RNA_struct_find_function(&ptr, "draw");
106
107         list= RNA_parameter_list_create(&ptr, func);
108         RNA_parameter_set_lookup(list, "context", &C);
109         pnl->type->py_call(&ptr, func, list);
110
111         RNA_parameter_list_free(list);
112 }
113
114 static void rna_Panel_unregister(const bContext *C, StructRNA *type)
115 {
116         ARegionType *art;
117         PanelType *pt= RNA_struct_blender_type_get(type);
118
119         if(!pt)
120                 return;
121         if(!(art=region_type_find(NULL, pt->space_type, pt->region_type)))
122                 return;
123         
124         BLI_freelinkN(&art->paneltypes, pt);
125         RNA_struct_free(&BLENDER_RNA, type);
126
127         /* update while blender is running */
128         if(C)
129                 WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
130 }
131
132 static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, void *data, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
133 {
134         ARegionType *art;
135         PanelType *pt, dummypt = {0};
136         Panel dummypanel= {0};
137         PointerRNA dummyptr;
138         int have_function[2];
139
140         /* setup dummy panel & panel type to store static properties in */
141         dummypanel.type= &dummypt;
142         RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr);
143
144         /* validate the python class */
145         if(validate(&dummyptr, data, have_function) != 0)
146                 return NULL;
147         
148         if(!(art=region_type_find(reports, dummypt.space_type, dummypt.region_type)))
149                 return NULL;
150
151         /* check if we have registered this panel type before, and remove it */
152         for(pt=art->paneltypes.first; pt; pt=pt->next) {
153                 if(strcmp(pt->idname, dummypt.idname) == 0) {
154                         if(pt->py_srna)
155                                 rna_Panel_unregister(C, pt->py_srna);
156                         break;
157                 }
158         }
159         
160         /* create a new panel type */
161         pt= MEM_callocN(sizeof(PanelType), "python buttons panel");
162         memcpy(pt, &dummypt, sizeof(dummypt));
163
164         pt->py_srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); 
165         pt->py_data= data;
166         pt->py_call= call;
167         pt->py_free= free;
168         RNA_struct_blender_type_set(pt->py_srna, pt);
169
170         pt->poll= (have_function[0])? panel_poll: NULL;
171         pt->draw= (have_function[1])? panel_draw: NULL;
172
173         BLI_addtail(&art->paneltypes, pt);
174
175         /* update while blender is running */
176         if(C)
177                 WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
178         
179         return pt->py_srna;
180 }
181
182 static StructRNA* rna_Panel_refine(struct PointerRNA *ptr)
183 {
184         Panel *hdr= (Panel*)ptr->data;
185         return (hdr->type)? hdr->type->py_srna: &RNA_Panel;
186 }
187
188 /* Header */
189
190 static void header_draw(const bContext *C, Header *hdr)
191 {
192         PointerRNA htr;
193         ParameterList *list;
194         FunctionRNA *func;
195
196         RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->py_srna, hdr, &htr);
197         func= RNA_struct_find_function(&htr, "draw");
198
199         list= RNA_parameter_list_create(&htr, func);
200         RNA_parameter_set_lookup(list, "context", &C);
201         hdr->type->py_call(&htr, func, list);
202
203         RNA_parameter_list_free(list);
204 }
205
206 static void rna_Header_unregister(const bContext *C, StructRNA *type)
207 {
208         ARegionType *art;
209         HeaderType *ht= RNA_struct_blender_type_get(type);
210
211         if(!ht)
212                 return;
213         if(!(art=region_type_find(NULL, ht->space_type, RGN_TYPE_HEADER)))
214                 return;
215         
216         BLI_freelinkN(&art->headertypes, ht);
217         RNA_struct_free(&BLENDER_RNA, type);
218
219         /* update while blender is running */
220         if(C)
221                 WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
222 }
223
224 static StructRNA *rna_Header_register(const bContext *C, ReportList *reports, void *data, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
225 {
226         ARegionType *art;
227         HeaderType *ht, dummyht = {0};
228         Header dummyheader= {0};
229         PointerRNA dummyhtr;
230         int have_function[1];
231
232         /* setup dummy header & header type to store static properties in */
233         dummyheader.type= &dummyht;
234         RNA_pointer_create(NULL, &RNA_Header, &dummyheader, &dummyhtr);
235
236         /* validate the python class */
237         if(validate(&dummyhtr, data, have_function) != 0)
238                 return NULL;
239         
240         if(!(art=region_type_find(reports, dummyht.space_type, RGN_TYPE_HEADER)))
241                 return NULL;
242
243         /* check if we have registered this header type before, and remove it */
244         for(ht=art->headertypes.first; ht; ht=ht->next) {
245                 if(strcmp(ht->idname, dummyht.idname) == 0) {
246                         if(ht->py_srna)
247                                 rna_Header_unregister(C, ht->py_srna);
248                         break;
249                 }
250         }
251         
252         /* create a new header type */
253         ht= MEM_callocN(sizeof(HeaderType), "python buttons header");
254         memcpy(ht, &dummyht, sizeof(dummyht));
255
256         ht->py_srna= RNA_def_struct(&BLENDER_RNA, ht->idname, "Header"); 
257         ht->py_data= data;
258         ht->py_call= call;
259         ht->py_free= free;
260         RNA_struct_blender_type_set(ht->py_srna, ht);
261
262         ht->draw= (have_function[0])? header_draw: NULL;
263
264         BLI_addtail(&art->headertypes, ht);
265
266         /* update while blender is running */
267         if(C)
268                 WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
269         
270         return ht->py_srna;
271 }
272
273 static StructRNA* rna_Header_refine(struct PointerRNA *htr)
274 {
275         Header *hdr= (Header*)htr->data;
276         return (hdr->type)? hdr->type->py_srna: &RNA_Header;
277 }
278
279 #else
280
281 static void rna_def_ui_layout(BlenderRNA *brna)
282 {
283         StructRNA *srna;
284
285         srna= RNA_def_struct(brna, "UILayout", NULL);
286         RNA_def_struct_sdna(srna, "uiLayout");
287         RNA_def_struct_ui_text(srna, "UI Layout", "User interface layout in a panel or header.");
288
289         RNA_api_ui_layout(srna);
290 }
291
292 static void rna_def_panel(BlenderRNA *brna)
293 {
294         StructRNA *srna;
295         PropertyRNA *prop;
296         FunctionRNA *func;
297         
298         srna= RNA_def_struct(brna, "Panel", NULL);
299         RNA_def_struct_ui_text(srna, "Panel", "Panel containing buttons.");
300         RNA_def_struct_sdna(srna, "Panel");
301         RNA_def_struct_refine_func(srna, "rna_Panel_refine");
302         RNA_def_struct_register_funcs(srna, "rna_Panel_register", "rna_Panel_unregister");
303
304         /* poll */
305         func= RNA_def_function(srna, "poll", NULL);
306         RNA_def_function_ui_description(func, "Test if the panel is visible or not.");
307         RNA_def_function_flag(func, FUNC_REGISTER|FUNC_REGISTER_OPTIONAL);
308         RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
309         RNA_def_pointer(func, "context", "Context", "", "");
310
311         /* draw */
312         func= RNA_def_function(srna, "draw", NULL);
313         RNA_def_function_ui_description(func, "Draw buttons into the panel UI layout.");
314         RNA_def_function_flag(func, FUNC_REGISTER);
315         RNA_def_pointer(func, "context", "Context", "", "");
316
317         prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
318         RNA_def_property_struct_type(prop, "UILayout");
319
320         /* registration */
321         prop= RNA_def_property(srna, "idname", PROP_STRING, PROP_NONE);
322         RNA_def_property_string_sdna(prop, NULL, "type->idname");
323         RNA_def_property_flag(prop, PROP_REGISTER);
324
325         prop= RNA_def_property(srna, "label", PROP_STRING, PROP_NONE);
326         RNA_def_property_string_sdna(prop, NULL, "type->label");
327         RNA_def_property_flag(prop, PROP_REGISTER);
328
329         prop= RNA_def_property(srna, "space_type", PROP_ENUM, PROP_NONE);
330         RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
331         RNA_def_property_enum_items(prop, space_type_items);
332         RNA_def_property_flag(prop, PROP_REGISTER);
333
334         prop= RNA_def_property(srna, "region_type", PROP_ENUM, PROP_NONE);
335         RNA_def_property_enum_sdna(prop, NULL, "type->region_type");
336         RNA_def_property_enum_items(prop, region_type_items);
337         RNA_def_property_flag(prop, PROP_REGISTER);
338
339         prop= RNA_def_property(srna, "context", PROP_STRING, PROP_NONE);
340         RNA_def_property_string_sdna(prop, NULL, "type->context");
341         RNA_def_property_flag(prop, PROP_REGISTER);
342 }
343
344 static void rna_def_header(BlenderRNA *brna)
345 {
346         StructRNA *srna;
347         PropertyRNA *prop;
348         FunctionRNA *func;
349         
350         srna= RNA_def_struct(brna, "Header", NULL);
351         RNA_def_struct_ui_text(srna, "Header", "Editor header containing buttons.");
352         RNA_def_struct_sdna(srna, "Header");
353         RNA_def_struct_refine_func(srna, "rna_Header_refine");
354         RNA_def_struct_register_funcs(srna, "rna_Header_register", "rna_Header_unregister");
355
356         /* draw */
357         func= RNA_def_function(srna, "draw", NULL);
358         RNA_def_function_ui_description(func, "Draw buttons into the header UI layout.");
359         RNA_def_function_flag(func, FUNC_REGISTER);
360         RNA_def_pointer(func, "context", "Context", "", "");
361
362         prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
363         RNA_def_property_struct_type(prop, "UILayout");
364
365         /* registration */
366         prop= RNA_def_property(srna, "idname", PROP_STRING, PROP_NONE);
367         RNA_def_property_string_sdna(prop, NULL, "type->idname");
368         RNA_def_property_flag(prop, PROP_REGISTER);
369
370         prop= RNA_def_property(srna, "space_type", PROP_ENUM, PROP_NONE);
371         RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
372         RNA_def_property_enum_items(prop, space_type_items);
373         RNA_def_property_flag(prop, PROP_REGISTER);
374 }
375
376 void RNA_def_ui(BlenderRNA *brna)
377 {
378         rna_def_ui_layout(brna);
379         rna_def_panel(brna);
380         rna_def_header(brna);
381 }
382
383 #endif
384