added defAutoButR() and blockSetFlag() and some flags for the experimental python...
[blender-staging.git] / source / blender / python / intern / bpy_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): Campbell Barton
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include "bpy_ui.h"
26 #include "bpy_rna.h" /* for rna buttons */
27 #include "bpy_compat.h"
28
29 #include "BLI_dynstr.h"
30
31 #include "MEM_guardedalloc.h"
32 #include "BKE_global.h" /* evil G.* */
33 #include "BKE_context.h"
34
35 #include "DNA_screen_types.h"
36 #include "UI_interface.h"
37 #include "WM_api.h"
38
39 static PyObject *Method_pupMenuBegin( PyObject * self, PyObject * args )
40 {
41         char *title; int icon;
42         
43         if( !PyArg_ParseTuple( args, "si:pupMenuBegin", &title, &icon))
44                 return NULL;
45         
46         return PyCObject_FromVoidPtr( uiPupMenuBegin(title, icon), NULL );
47 }
48
49 static PyObject *Method_pupMenuEnd( PyObject * self, PyObject * args )
50 {
51         PyObject *py_context, *py_head;
52         
53         if( !PyArg_ParseTuple( args, "O!O!:pupMenuEnd", &PyCObject_Type, &py_context, &PyCObject_Type, &py_head))
54                 return NULL;
55         
56         uiPupMenuEnd(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_head));
57         
58         Py_RETURN_NONE;
59 }
60
61 static PyObject *Method_menuItemO( PyObject * self, PyObject * args )
62 {
63         PyObject *py_head;
64         char *opname;
65         int icon;
66         
67         if( !PyArg_ParseTuple( args, "O!is:menuItemO", &PyCObject_Type, &py_head, &icon, &opname))
68                 return NULL;
69         
70         uiMenuItemO(PyCObject_AsVoidPtr(py_head), icon, opname);
71         
72         Py_RETURN_NONE;
73 }
74
75 static PyObject *Method_defButO( PyObject * self, PyObject * args )
76 {
77         PyObject *py_block;
78         char *opname, *butname, *tip;
79         int exec, xco, yco, width, height;
80         
81         if( !PyArg_ParseTuple( args, "O!sisiiiis:defButO", &PyCObject_Type, &py_block, &opname, &exec, &butname, &xco, &yco, &width, &height, &tip))
82                 return NULL;
83         
84         return PyCObject_FromVoidPtr(uiDefButO(PyCObject_AsVoidPtr(py_block), BUT, opname, exec, butname, xco, yco, width, height, tip), NULL );
85 }
86
87 static PyObject *Method_defAutoButR( PyObject * self, PyObject * args )
88 {
89         PyObject *py_block;
90         BPy_StructRNA *py_rna;
91         char *propname, *butname;
92         int index, xco, yco, width, height;
93         PropertyRNA *prop;
94         
95         if( !PyArg_ParseTuple( args, "O!O!sisiiii:defAutoButR", &PyCObject_Type, &py_block, &pyrna_struct_Type, &py_rna, &propname, &index, &butname, &xco, &yco, &width, &height))
96                 return NULL;
97         
98         // XXX This isnt that nice api, but we dont always have the rna property from python since its converted immediately into a PyObject
99         prop = RNA_struct_find_property(&py_rna->ptr, propname);
100         if (prop==NULL) {
101                 PyErr_SetString(PyExc_ValueError, "rna property not found");
102                 return NULL;
103         }
104         
105         return PyCObject_FromVoidPtr(   uiDefAutoButR(PyCObject_AsVoidPtr(py_block), &py_rna->ptr, prop, index, butname, xco, yco, width, height), NULL);
106 }
107
108
109
110 static uiBlock *py_internal_uiBlockCreateFunc(struct bContext *C, struct ARegion *ar, void *arg1)
111 {
112         PyObject *ret, *args;
113         
114         args = Py_BuildValue("(NN)", PyCObject_FromVoidPtr(C, NULL), PyCObject_FromVoidPtr(ar, NULL));
115         ret = PyObject_CallObject( (PyObject *)arg1, args );
116         Py_DECREF(args);
117         
118         if (ret==NULL) {
119                 PyErr_Print();
120                 return NULL;
121         }
122         if (!PyCObject_Check(ret)) {
123                 printf("invalid return value, not a PyCObject block\n");
124                 return NULL;
125         }
126         
127         return (uiBlock *)PyCObject_AsVoidPtr(ret);
128 }
129
130 static PyObject *Method_pupBlock( PyObject * self, PyObject * args )
131 {
132         PyObject *py_context, *py_func;
133         
134         if( !PyArg_ParseTuple( args, "O!O:pupBlock", &PyCObject_Type, &py_context, &py_func) )
135                 return NULL;
136         
137         if (!PyCallable_Check(py_func)) {
138                 PyErr_SetString(PyExc_ValueError, "arg not callable");
139                 return NULL;
140         }
141         
142         uiPupBlock(PyCObject_AsVoidPtr(py_context), py_internal_uiBlockCreateFunc, (void *)py_func);
143         Py_RETURN_NONE;
144 }
145
146 static PyObject *Method_beginBlock( PyObject * self, PyObject * args ) // XXX missing 2 args - UI_EMBOSS, UI_HELV, do we care?
147 {
148         PyObject *py_context, *py_ar;
149         char *name;
150         
151         if( !PyArg_ParseTuple( args, "O!O!s:beginBlock", &PyCObject_Type, &py_context, &PyCObject_Type, &py_ar, &name) )
152                 return NULL;
153         
154         return PyCObject_FromVoidPtr(uiBeginBlock(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_ar), name, UI_EMBOSS, UI_HELV), NULL);
155 }
156
157 static PyObject *Method_endBlock( PyObject * self, PyObject * args )
158 {
159         PyObject *py_context, *py_block;
160         
161         if( !PyArg_ParseTuple( args, "O!O!:endBlock", &PyCObject_Type, &py_context, &PyCObject_Type, &py_block) )
162                 return NULL;
163         
164         uiEndBlock(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_block));
165         Py_RETURN_NONE;
166 }
167
168 static PyObject *Method_popupBoundsBlock( PyObject * self, PyObject * args )
169 {
170         PyObject *py_block;
171         int addval, mx, my;
172         
173         if( !PyArg_ParseTuple( args, "O!iii:popupBoundsBlock", &PyCObject_Type, &py_block, &addval, &mx, &my) )
174                 return NULL;
175         
176         uiPopupBoundsBlock(PyCObject_AsVoidPtr(py_block), addval, mx, my);
177         Py_RETURN_NONE;
178 }
179
180 static PyObject *Method_blockBeginAlign( PyObject * self, PyObject * args )
181 {
182         PyObject *py_block;
183         
184         if( !PyArg_ParseTuple( args, "O!:blockBeginAlign", &PyCObject_Type, &py_block) )
185                 return NULL;
186         
187         uiBlockBeginAlign(PyCObject_AsVoidPtr(py_block));
188         Py_RETURN_NONE;
189 }
190
191 static PyObject *Method_blockEndAlign( PyObject * self, PyObject * args )
192 {
193         PyObject *py_block;
194         
195         if( !PyArg_ParseTuple( args, "O!:blockEndAlign", &PyCObject_Type, &py_block))
196                 return NULL;
197         
198         uiBlockEndAlign(PyCObject_AsVoidPtr(py_block));
199         Py_RETURN_NONE;
200 }
201
202 static PyObject *Method_blockSetFlag( PyObject * self, PyObject * args )
203 {
204         PyObject *py_block;
205         int flag; /* Note new py api should not use flags, but for this low level UI api its ok. */
206         
207         if( !PyArg_ParseTuple( args, "O!i:blockSetFlag", &PyCObject_Type, &py_block, &flag))
208                 return NULL;
209         
210         uiBlockSetFlag(PyCObject_AsVoidPtr(py_block), flag);
211         Py_RETURN_NONE;
212 }
213
214 static PyObject *Method_newPanel( PyObject * self, PyObject * args )
215 {
216         PyObject *py_context, *py_area, *py_block;
217         char *panelname, *tabname;
218         int ofsx, ofsy, sizex, sizey;
219         
220         if( !PyArg_ParseTuple( args, "O!O!O!ssiiii:newPanel", &PyCObject_Type, &py_context, &PyCObject_Type, &py_area, &PyCObject_Type, &py_block, &panelname, &tabname, &ofsx, &ofsy, &sizex, &sizey))
221                 return NULL;
222         
223         return PyLong_FromSize_t(uiNewPanel(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_area), PyCObject_AsVoidPtr(py_block), panelname, tabname, ofsx, ofsy, sizex, sizey));
224 }
225
226 /* internal use only */
227 static bContext *get_py_context__internal(void)
228 {
229         PyObject *globals = PyEval_GetGlobals();
230         PyObject *val= PyDict_GetItemString(globals, "__bpy_context__");
231         return PyCObject_AsVoidPtr(val);
232 }
233
234 static PyObject *Method_getRegonPtr( PyObject * self )
235 {
236         bContext *C= get_py_context__internal();
237         
238         ARegion *ar = CTX_wm_region(C);
239         return PyCObject_FromVoidPtr(ar, NULL);
240 }
241
242 static PyObject *Method_getAreaPtr( PyObject * self )
243 {
244         bContext *C= get_py_context__internal();
245         
246         ScrArea *area = CTX_wm_area(C);
247         return PyCObject_FromVoidPtr(area, NULL);
248 }
249
250 static PyObject *Method_getScreenPtr( PyObject * self )
251 {
252         bContext *C= get_py_context__internal();
253         
254         bScreen *screen= CTX_wm_screen(C);
255         return PyCObject_FromVoidPtr(screen, NULL);
256 }
257
258 static PyObject *Method_getWindowPtr( PyObject * self )
259 {
260         bContext *C= get_py_context__internal();
261         
262         wmWindow *window= CTX_wm_window(C);
263         return PyCObject_FromVoidPtr(window, NULL);
264 }
265
266 static struct PyMethodDef ui_methods[] = {
267         {"pupMenuBegin", (PyCFunction)Method_pupMenuBegin, METH_VARARGS, ""},
268         {"pupMenuEnd", (PyCFunction)Method_pupMenuEnd, METH_VARARGS, ""},
269         {"menuItemO", (PyCFunction)Method_menuItemO, METH_VARARGS, ""},
270         {"defButO", (PyCFunction)Method_defButO, METH_VARARGS, ""},
271         {"defAutoButR", (PyCFunction)Method_defAutoButR, METH_VARARGS, ""},
272         {"pupBlock", (PyCFunction)Method_pupBlock, METH_VARARGS, ""},
273         {"beginBlock", (PyCFunction)Method_beginBlock, METH_VARARGS, ""},
274         {"endBlock", (PyCFunction)Method_endBlock, METH_VARARGS, ""},
275         {"popupBoundsBlock", (PyCFunction)Method_popupBoundsBlock, METH_VARARGS, ""},
276         {"blockBeginAlign", (PyCFunction)Method_blockBeginAlign, METH_VARARGS, ""},
277         {"blockEndAlign", (PyCFunction)Method_blockEndAlign, METH_VARARGS, ""},
278         {"blockSetFlag", (PyCFunction)Method_blockSetFlag, METH_VARARGS, ""},
279         {"newPanel", (PyCFunction)Method_newPanel, METH_VARARGS, ""},
280         
281         {"getRegonPtr", (PyCFunction)Method_getRegonPtr,        METH_NOARGS, ""}, // XXX Nasty, we really need to improve dealing with context!
282         {"getAreaPtr", (PyCFunction)Method_getAreaPtr,          METH_NOARGS, ""},
283         {"getScreenPtr", (PyCFunction)Method_getScreenPtr, METH_NOARGS, ""},
284         {"getWindowPtr", (PyCFunction)Method_getWindowPtr, METH_NOARGS, ""},
285         {NULL, NULL, 0, NULL}
286 };
287
288 static struct PyModuleDef ui_module = {
289         PyModuleDef_HEAD_INIT,
290         "bpyui",
291         "",
292         -1,/* multiple "initialization" just copies the module dict. */
293         ui_methods,
294         NULL, NULL, NULL, NULL
295 };
296
297 PyObject *BPY_ui_module( void )
298 {
299         PyObject *submodule, *dict;
300 #if PY_VERSION_HEX >= 0x03000000
301         submodule= PyModule_Create(&ui_module);
302 #else /* Py2.x */
303         submodule= Py_InitModule3( "bpyui", ui_methods, "" );
304 #endif
305         
306         /* uiBlock->flag (controls) */
307         PyModule_AddObject( submodule, "UI_BLOCK_LOOP", PyLong_FromSize_t(UI_BLOCK_LOOP) );
308         PyModule_AddObject( submodule, "UI_BLOCK_RET_1", PyLong_FromSize_t(UI_BLOCK_RET_1) );
309         PyModule_AddObject( submodule, "UI_BLOCK_NUMSELECT", PyLong_FromSize_t(UI_BLOCK_NUMSELECT) );
310         PyModule_AddObject( submodule, "UI_BLOCK_ENTER_OK", PyLong_FromSize_t(UI_BLOCK_ENTER_OK) );
311         PyModule_AddObject( submodule, "UI_BLOCK_NOSHADOW", PyLong_FromSize_t(UI_BLOCK_NOSHADOW) );
312         PyModule_AddObject( submodule, "UI_BLOCK_NO_HILITE", PyLong_FromSize_t(UI_BLOCK_NO_HILITE) );
313         PyModule_AddObject( submodule, "UI_BLOCK_MOVEMOUSE_QUIT", PyLong_FromSize_t(UI_BLOCK_MOVEMOUSE_QUIT) );
314         PyModule_AddObject( submodule, "UI_BLOCK_KEEP_OPEN", PyLong_FromSize_t(UI_BLOCK_KEEP_OPEN) );
315         PyModule_AddObject( submodule, "UI_BLOCK_POPUP", PyLong_FromSize_t(UI_BLOCK_POPUP) );
316         
317         return submodule;
318 }
319
320