Silenced a few compiler warnings
[blender-staging.git] / source / blender / python / api2_2x / Draw.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): Willian P. Germano, Campbell Barton, Ken Hughes
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31 */
32
33 /* This file is the Blender.Draw part of opy_draw.c, from the old
34  * bpython/intern dir, with minor changes to adapt it to the new Python
35  * implementation.      Non-trivial original comments are marked with an
36  * @ symbol at their beginning. */
37
38 #include "Draw.h" /*This must come first*/
39
40 #include "BLI_blenlib.h"
41 #include "MEM_guardedalloc.h"
42 #include "BMF_Api.h"
43 #include "DNA_screen_types.h"
44 #include "BKE_global.h"
45 #include "BKE_image.h"
46 #include "BKE_object.h"
47 #include "BKE_main.h"
48 #include "BKE_utildefines.h"
49 #include "BIF_gl.h"
50 #include "BIF_mywindow.h"
51 #include "BIF_screen.h"
52 #include "BIF_space.h"
53 #include "BIF_interface.h"
54 #include "BIF_toolbox.h"
55 #include "BPI_script.h"         /* script struct */
56 #include "Image.h"              /* for accessing Blender.Image objects */
57 #include "IMB_imbuf_types.h"    /* for the IB_rect define */
58 #include "interface.h"
59 #include "mydevice.h"           /*@ for all the event constants */
60 #include "gen_utils.h"
61 #include "Window.h"
62 #include "../BPY_extern.h"
63
64 /* used so we can get G.scene->r.cfra for getting the
65 current image frame, some images change frame if they are a sequence */
66 #include "DNA_scene_types.h"
67
68 /* these delimit the free range for button events */
69 #define EXPP_BUTTON_EVENTS_OFFSET 1001
70 #define EXPP_BUTTON_EVENTS_MIN 0
71 #define EXPP_BUTTON_EVENTS_MAX 15382 /* 16384 - 1 - OFFSET */
72
73 #define ButtonObject_Check(v) ((v)->ob_type == &Button_Type)
74
75 #define UI_METHOD_ERRORCHECK \
76         if (check_button_event(&event) == -1)\
77                 return EXPP_ReturnPyObjError( PyExc_AttributeError,\
78                         "button event argument must be in the range [0, 16382]");\
79         if (callback && !PyCallable_Check(callback))\
80                 return EXPP_ReturnPyObjError( PyExc_ValueError,\
81                         "callback is not a python function");\
82
83 /* pointer to main dictionary defined in Blender.c */
84 extern PyObject *g_blenderdict;
85
86 /*@ hack to flag that window redraw has happened inside slider callback: */
87 int EXPP_disable_force_draw = 0;
88
89 /* forward declarations for internal functions */
90 static void Button_dealloc( PyObject * self );
91 static PyObject *Button_getattr( PyObject * self, char *name );
92 static PyObject *Button_repr( PyObject * self );
93 static PyObject *Button_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type);
94 static int Button_setattr( PyObject * self, char *name, PyObject * v );
95
96 static Button *newbutton( void );
97
98 /* GUI interface routines */
99
100 static void exit_pydraw( SpaceScript * sc, short error );
101 static void exec_callback( SpaceScript * sc, PyObject * callback,
102                            PyObject * args );
103 static void spacescript_do_pywin_buttons( SpaceScript * sc,
104                                           unsigned short event );
105
106 static PyObject *Method_Exit( PyObject * self, PyObject * args );
107 static PyObject *Method_Register( PyObject * self, PyObject * args );
108 static PyObject *Method_Redraw( PyObject * self, PyObject * args );
109 static PyObject *Method_Draw( PyObject * self, PyObject * args );
110 static PyObject *Method_Create( PyObject * self, PyObject * args );
111 static PyObject *Method_UIBlock( PyObject * self, PyObject * args );
112
113 static PyObject *Method_Button( PyObject * self, PyObject * args );
114 static PyObject *Method_Menu( PyObject * self, PyObject * args );
115 static PyObject *Method_Toggle( PyObject * self, PyObject * args );
116 static PyObject *Method_Slider( PyObject * self, PyObject * args );
117 static PyObject *Method_Scrollbar( PyObject * self, PyObject * args );
118 static PyObject *Method_ColorPicker( PyObject * self, PyObject * args );
119 static PyObject *Method_Normal( PyObject * self, PyObject * args );
120 static PyObject *Method_Number( PyObject * self, PyObject * args );
121 static PyObject *Method_String( PyObject * self, PyObject * args );
122 static PyObject *Method_GetStringWidth( PyObject * self, PyObject * args );
123 static PyObject *Method_Text( PyObject * self, PyObject * args );
124 static PyObject *Method_Label( PyObject * self, PyObject * args );
125 /* by Campbell: */
126 static PyObject *Method_PupMenu( PyObject * self, PyObject * args );
127 static PyObject *Method_PupIntInput( PyObject * self, PyObject * args );
128 static PyObject *Method_PupFloatInput( PyObject * self, PyObject * args );
129 static PyObject *Method_PupStrInput( PyObject * self, PyObject * args );
130 static PyObject *Method_BeginAlign( PyObject * self, PyObject * args  );
131 static PyObject *Method_EndAlign( PyObject * self, PyObject * args  );
132 /* next by Jonathan Merritt (lancelet): */
133 static PyObject *Method_Image( PyObject * self, PyObject * args);
134 /* CLEVER NUMBUT */
135 static PyObject *Method_PupBlock( PyObject * self, PyObject * args );
136
137 static uiBlock *Get_uiBlock( void );
138 static void py_slider_update( void *butv, void *data2_unused );
139
140 /* hack to get 1 block for the UIBlock, only ever 1 at a time */
141 static uiBlock *uiblock=NULL;
142
143 static char Draw_doc[] = "The Blender.Draw submodule";
144
145 static char Method_UIBlock_doc[] = "(drawfunc, x,y) - Popup dialog where buttons can be drawn (expemental)";
146
147 static char Method_Register_doc[] =
148         "(draw, event, button) - Register callbacks for windowing\n\n\
149 (draw) A function to draw the screen, taking no arguments\n\
150 (event) A function to handle events, taking 2 arguments (evt, val)\n\
151         (evt) The event number\n\
152         (val) The value modifier (for key and mouse press/release)\n\
153 (button) A function to handle button events, taking 1 argument (evt)\n\
154         (evt) The button number\n\n\
155 A None object can be passed if a callback is unused.";
156
157
158 static char Method_Redraw_doc[] = "([after]) - Queue a redraw event\n\n\
159 [after=0] Determines whether the redraw is processed before\n\
160 or after other input events.\n\n\
161 Redraw events are buffered so that regardless of how many events\n\
162 are queued the window only receives one redraw event.";
163
164 static char Method_Draw_doc[] = "() - Force an immediate redraw\n\n\
165 Forced redraws are not buffered, in other words the window is redrawn\n\
166 exactly once for everytime this function is called.";
167
168
169 static char Method_Create_doc[] =
170         "(value) - Create a default Button object\n\n\
171  (value) - The value to store in the button\n\n\
172  Valid values are ints, floats, and strings";
173
174 static char Method_Button_doc[] =
175         "(name, event, x, y, width, height, [tooltip]) - Create a new Button \
176 (push) button\n\n\
177 (name) A string to display on the button\n\
178 (event) The event number to pass to the button event function when activated\n\
179 (x, y) The lower left coordinate of the button\n\
180 (width, height) The button width and height\n\
181 [tooltip=] The button's tooltip\n\n\
182 This function can be called as Button() or PushButton().";
183
184 static char Method_BeginAlign_doc[] =
185         "Buttons after this function will draw aligned (button layout only)";
186
187 static char Method_EndAlign_doc[] =
188         "Use after BeginAlign() to stop aligning the buttons (button layout only).";
189
190 static char Method_Menu_doc[] =
191         "(name, event, x, y, width, height, default, [tooltip]) - Create a new Menu \
192 button\n\n\
193 (name) A string to display on the button\n\
194 (event) The event number to pass to the button event function when activated\n\
195 (x, y) The lower left coordinate of the button\n\
196 (width, height) The button width and height\n\
197 (default) The number of the option to be selected by default\n\
198 [tooltip=" "] The button's tooltip\n\n\
199 The menu options are specified through the name of the\n\
200 button. Options are followed by a format code and separated\n\
201 by the '|' (pipe) character.\n\
202 Valid format codes are\n\
203         %t - The option should be used as the title\n\
204         %xN - The option should set the integer N in the button value.";
205
206 static char Method_Toggle_doc[] =
207         "(name, event, x, y, width, height, default, [tooltip]) - Create a new Toggle \
208 button\n\n\
209 (name) A string to display on the button\n\
210 (event) The event number to pass to the button event function when activated\n\
211 (x, y) The lower left coordinate of the button\n\
212 (width, height) The button width and height\n\
213 (default) An integer (0 or 1) specifying the default state\n\
214 [tooltip=] The button's tooltip";
215
216
217 static char Method_Slider_doc[] =
218         "(name, event, x, y, width, height, initial, min, max, [update, tooltip]) - \
219 Create a new Slider button\n\n\
220 (name) A string to display on the button\n\
221 (event) The event number to pass to the button event function when activated\n\
222 (x, y) The lower left coordinate of the button\n\
223 (width, height) The button width and height\n\
224 (initial, min, max) Three values (int or float) specifying the initial \
225                                 and limit values.\n\
226 [update=1] A value controlling whether the slider will emit events as it \
227 is edited.\n\
228         A non-zero value (default) enables the events. A zero value supresses them.\n\
229 [tooltip=] The button's tooltip";
230
231
232 static char Method_Scrollbar_doc[] =
233         "(event, x, y, width, height, initial, min, max, [update, tooltip]) - Create a \
234 new Scrollbar\n\n\
235 (event) The event number to pass to the button event function when activated\n\
236 (x, y) The lower left coordinate of the button\n\
237 (width, height) The button width and height\n\
238 (initial, min, max) Three values (int or float) specifying the initial and limit values.\n\
239 [update=1] A value controlling whether the slider will emit events as it is edited.\n\
240         A non-zero value (default) enables the events. A zero value supresses them.\n\
241 [tooltip=] The button's tooltip";
242
243 static char Method_ColorPicker_doc[] = 
244         "(event, x, y, width, height, initial, [tooltip]) - Create a new Button \
245 Color picker button\n\n\
246 (event) The event number to pass to the button event function when the color changes\n\
247 (x, y) The lower left coordinate of the button\n\
248 (width, height) The button width and height\n\
249 (initial) 3-Float tuple of the color (values between 0 and 1)\
250 [tooltip=] The button's tooltip";
251
252 static char Method_Normal_doc[] = 
253         "(event, x, y, width, height, initial, [tooltip]) - Create a new Button \
254 Normal button (a sphere that you can roll to change the normal)\n\n\
255 (event) The event number to pass to the button event function when the color changes\n\
256 (x, y) The lower left coordinate of the button\n\
257 (width, height) The button width and height - non square will gave odd results\n\
258 (initial) 3-Float tuple of the normal vector (values between -1 and 1)\
259 [tooltip=] The button's tooltip";
260
261 static char Method_Number_doc[] =
262         "(name, event, x, y, width, height, initial, min, max, [tooltip]) - Create a \
263 new Number button\n\n\
264 (name) A string to display on the button\n\
265 (event) The event number to pass to the button event function when activated\n\
266 (x, y) The lower left coordinate of the button\n\
267 (width, height) The button width and height\n\
268 (initial, min, max) Three values (int or float) specifying the initial and \
269 limit values.\n\
270 [tooltip=] The button's tooltip";
271
272 static char Method_String_doc[] =
273         "(name, event, x, y, width, height, initial, length, [tooltip]) - Create a \
274 new String button\n\n\
275 (name) A string to display on the button\n\
276 (event) The event number to pass to the button event function when activated\n\
277 (x, y) The lower left coordinate of the button\n\
278 (width, height) The button width and height\n\
279 (initial) The string to display initially\n\
280 (length) The maximum input length\n\
281 [tooltip=] The button's tooltip";
282
283 static char Method_GetStringWidth_doc[] =
284         "(text, font = 'normal') - Return the width in pixels of the given string\n\
285 (font) The font size: 'normal' (default), 'small' or 'tiny'.";
286
287 static char Method_Text_doc[] =
288         "(text, font = 'normal') - Draw text onscreen\n\n\
289 (text) The text to draw\n\
290 (font) The font size: 'normal' (default), 'small' or 'tiny'.\n\n\
291 This function returns the width of the drawn string.";
292
293 static char Method_Label_doc[] =
294         "(text, x, y) - Draw a text label onscreen\n\n\
295 (text) The text to draw\n\
296 (x, y) The lower left coordinate of the lable";
297
298 static char Method_PupMenu_doc[] =
299         "(string, maxrow = None) - Display a pop-up menu at the screen.\n\
300 The contents of the pop-up are specified through the 'string' argument,\n\
301 like with Draw.Menu.\n\
302 'maxrow' is an optional int to control how many rows the pop-up should have.\n\
303 Options are followed by a format code and separated\n\
304 by the '|' (pipe) character.\n\
305 Valid format codes are\n\
306         %t - The option should be used as the title\n\
307         %xN - The option should set the integer N in the button value.\n\n\
308 Ex: Draw.PupMenu('OK?%t|QUIT BLENDER') # should be familiar ...";
309
310 static char Method_PupIntInput_doc[] =
311         "(text, default, min, max) - Display an int pop-up input.\n\
312 (text) - text string to display on the button;\n\
313 (default, min, max) - the default, min and max int values for the button;\n\
314 Return the user input value or None on user exit";
315
316 static char Method_PupFloatInput_doc[] =
317         "(text, default, min, max, clickStep, floatLen) - Display a float pop-up input.\n\
318 (text) - text string to display on the button;\n\
319 (default, min, max) - the default, min and max float values for the button;\n\
320 (clickStep) - float increment/decrement for each click on the button arrows;\n\
321 (floatLen) - an integer defining the precision (number of decimal places) of \n\
322 the float value show.\n\
323 Return the user input value or None on user exit";
324
325 static char Method_Image_doc[] =
326         "(image, x, y, zoomx = 1.0, zoomy = 1.0, [clipx, clipy, clipw, cliph])) \n\
327     - Draw an image.\n\
328 (image) - Blender.Image to draw.\n\
329 (x, y) - floats specifying the location of the image.\n\
330 (zoomx, zoomy) - float zoom factors in horizontal and vertical directions.\n\
331 (clipx, clipy, clipw, cliph) - integers specifying a clipping rectangle within the original image.";
332
333 static char Method_PupStrInput_doc[] =
334         "(text, default, max = 20) - Display a float pop-up input.\n\
335 (text) - text string to display on the button;\n\
336 (default) - the initial string to display (truncated to 'max' chars);\n\
337 (max = 20) - The maximum number of chars the user can input;\n\
338 Return the user input value or None on user exit";
339
340 static char Method_PupBlock_doc[] =
341         "(title, sequence) - Display a pop-up block.\n\
342 (title) - The title of the block.\n\
343 (sequence) - A sequence defining what the block contains. \
344 The order of the list is the order of appearance, from top down.\n\
345 Possible format for sequence items:\n\
346 [value is an object created with Create]\n\
347 \ttext: Defines a label in the block\n\
348 \t(text, value, tooltip = ''): Defines a toggle button \n\
349 \t(text, value, min, max, tooltip = ''): Defines a num or string button \n\
350 \t\t\tdepending on the value.\n\
351 \t\tFor string, max is the maximum length of the text and min is unused.\n\
352 Return 1 if the pop-up is confirmed, 0 otherwise. \n\
353 Warning: On cancel, the value objects are brought back to there previous values, \
354 \texcept for string values which will still contain the modified values.\n";
355
356 static char Method_Exit_doc[] = "() - Exit the windowing interface";
357
358 /*
359 * here we engage in some macro trickery to define the PyMethodDef table
360 */
361
362 #define _MethodDef(func, prefix) \
363         {#func, prefix##_##func, METH_VARARGS, prefix##_##func##_doc}
364
365 /* So that _MethodDef(delete, Scene) expands to:
366  * {"delete", Scene_delete, METH_VARARGS, Scene_delete_doc} */
367
368 #undef MethodDef
369 #define MethodDef(func) _MethodDef(func, Method)
370
371 static struct PyMethodDef Draw_methods[] = {
372         MethodDef( Create ),
373         MethodDef( UIBlock ),
374         MethodDef( Button ),
375         MethodDef( Toggle ),
376         MethodDef( Menu ),
377         MethodDef( Slider ),
378         MethodDef( Scrollbar ),
379         MethodDef( ColorPicker ),
380         MethodDef( Normal ),
381         MethodDef( Number ),
382         MethodDef( String ),
383         MethodDef( GetStringWidth ),
384         MethodDef( Text ),
385         MethodDef( Label ),
386         MethodDef( PupMenu ),
387         MethodDef( PupIntInput ),
388         MethodDef( PupFloatInput ),
389         MethodDef( PupStrInput ),
390         MethodDef( PupBlock ),
391         MethodDef( Image ),
392         MethodDef( Exit ),
393         MethodDef( Redraw ),
394         MethodDef( Draw ),
395         MethodDef( Register ),
396         {"PushButton", Method_Button, METH_VARARGS, Method_Button_doc},
397         MethodDef( BeginAlign ),
398         MethodDef( EndAlign),
399         {NULL, NULL, 0, NULL}
400 };
401
402 PyTypeObject Button_Type = {
403         PyObject_HEAD_INIT( NULL ) 0,   /*ob_size */
404         "Button",               /*tp_name */
405         sizeof( Button ),       /*tp_basicsize */
406         0,                      /*tp_itemsize */
407         ( destructor ) Button_dealloc,  /*tp_dealloc */
408         ( printfunc ) 0,        /*tp_print */
409         ( getattrfunc ) Button_getattr, /*tp_getattr */
410         ( setattrfunc ) Button_setattr, /*tp_setattr */
411         NULL,           /*tp_cmp */
412         ( reprfunc ) Button_repr,       /*tp_repr */
413
414         /* Method suites for standard classes */
415
416         NULL,                       /* PyNumberMethods *tp_as_number; */
417         NULL,                       /* PySequenceMethods *tp_as_sequence; */
418         NULL,                       /* PyMappingMethods *tp_as_mapping; */
419
420         /* More standard operations (here for binary compatibility) */
421
422         NULL,                       /* hashfunc tp_hash; */
423         NULL,                       /* ternaryfunc tp_call; */
424         NULL,                       /* reprfunc tp_str; */
425         NULL,                       /* getattrofunc tp_getattro; */
426         NULL,                       /* setattrofunc tp_setattro; */
427
428         /* Functions to access object as input/output buffer */
429         NULL,                       /* PyBufferProcs *tp_as_buffer; */
430
431   /*** Flags to define presence of optional/expanded features ***/
432         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
433
434         NULL,                       /*  char *tp_doc;  Documentation string */
435   /*** Assigned meaning in release 2.0 ***/
436         /* call function for all accessible objects */
437         NULL,                       /* traverseproc tp_traverse; */
438
439         /* delete references to contained objects */
440         NULL,                       /* inquiry tp_clear; */
441
442   /***  Assigned meaning in release 2.1 ***/
443   /*** rich comparisons ***/
444         (richcmpfunc)Button_richcmpr,                       /* richcmpfunc tp_richcompare; */
445
446   /***  weak reference enabler ***/
447         0,                          /* long tp_weaklistoffset; */
448
449   /*** Added in release 2.2 ***/
450         /*   Iterators */
451         NULL,                       /* getiterfunc tp_iter; */
452         NULL,                       /* iternextfunc tp_iternext; */
453
454   /*** Attribute descriptor and subclassing stuff ***/
455         NULL,           /* struct PyMethodDef *tp_methods; */
456         NULL,                       /* struct PyMemberDef *tp_members; */
457         NULL,         /* struct PyGetSetDef *tp_getset; */
458         NULL,                       /* struct _typeobject *tp_base; */
459         NULL,                       /* PyObject *tp_dict; */
460         NULL,                       /* descrgetfunc tp_descr_get; */
461         NULL,                       /* descrsetfunc tp_descr_set; */
462         0,                          /* long tp_dictoffset; */
463         NULL,                       /* initproc tp_init; */
464         NULL,                       /* allocfunc tp_alloc; */
465         NULL,                       /* newfunc tp_new; */
466         /*  Low-level free-memory routine */
467         NULL,                       /* freefunc tp_free;  */
468         /* For PyObject_IS_GC */
469         NULL,                       /* inquiry tp_is_gc;  */
470         NULL,                       /* PyObject *tp_bases; */
471         /* method resolution order */
472         NULL,                       /* PyObject *tp_mro;  */
473         NULL,                       /* PyObject *tp_cache; */
474         NULL,                       /* PyObject *tp_subclasses; */
475         NULL,                       /* PyObject *tp_weaklist; */
476         NULL
477 };
478
479 static void Button_dealloc( PyObject * self )
480 {
481         Button *but = ( Button * ) self;
482
483         if( but->type == BSTRING_TYPE ) {
484                 if( but->val.asstr )
485                         MEM_freeN( but->val.asstr );
486         }
487
488         PyObject_DEL( self );
489 }
490
491 static PyObject *Button_getattr( PyObject * self, char *name )
492 {
493         Button *but = ( Button * ) self;
494         
495         if( strcmp( name, "val" ) == 0 ) {
496                 if( but->type == BINT_TYPE )
497                         return PyInt_FromLong( but->val.asint );
498                 else if( but->type == BFLOAT_TYPE )
499                         return PyFloat_FromDouble( but->val.asfloat );
500                 else if( but->type == BSTRING_TYPE )
501                         return PyString_FromString( but->val.asstr );
502                 else if( but->type == BVECTOR_TYPE )
503                         return Py_BuildValue( "fff", but->val.asvec[0], but->val.asvec[1], but->val.asvec[2] );
504         }
505
506         PyErr_SetString( PyExc_AttributeError, name );
507         return NULL;
508 }
509
510 static int Button_setattr( PyObject * self, char *name, PyObject * v )
511 {
512         Button *but = ( Button * ) self;
513
514         if( strcmp( name, "val" ) == 0 ) {
515                 if( but->type == BINT_TYPE && PyNumber_Check(v) ) {
516                         PyObject *pyVal = PyNumber_Int( v );
517                         if (pyVal) {
518                                 but->val.asint = (int)PyInt_AS_LONG( pyVal );
519                                 Py_DECREF(pyVal);
520                                 return 0;
521                         }
522                 }
523                 else if( but->type == BFLOAT_TYPE && PyNumber_Check(v) ) {
524                         PyObject *pyVal = PyNumber_Float( v );
525                         if (pyVal) {
526                                 but->val.asfloat = (float)PyFloat_AS_DOUBLE( pyVal );
527                                 Py_DECREF(pyVal);
528                                 return 0;
529                         }
530                 }
531                 else if( but->type == BVECTOR_TYPE ) {
532                         if ( PyArg_ParseTuple( v, "fff", but->val.asvec, but->val.asvec+1, but->val.asvec+2 ) )
533                                 return 0;
534                 }
535                 else if( but->type == BSTRING_TYPE && PyString_Check(v) ) {
536                         char *newstr;
537                         unsigned int newlen;
538
539                         PyString_AsStringAndSize( v, &newstr, (int *)&newlen );
540                         
541                         if (newlen+1> UI_MAX_DRAW_STR)
542                                 return EXPP_ReturnIntError( PyExc_ValueError, "Error: button string length exceeded max limit (399 chars).");
543
544                         /* if the length of the new string is the same as */
545                         /* the old one, just copy, else delete and realloc. */
546                         if( but->slen == newlen ) {
547                                 BLI_strncpy( but->val.asstr, newstr,
548                                              but->slen + 1 );
549
550                                 return 0;
551
552                         } else {
553                                 MEM_freeN( but->val.asstr );
554                                 but->slen = newlen;
555                                 but->val.asstr =
556                                         MEM_mallocN( but->slen + 1,
557                                                      "button setattr" );
558                                 BLI_strncpy( but->val.asstr, newstr,
559                                              but->slen + 1 );
560
561                                 return 0;
562                         }
563                 }
564         } else {
565                 /*
566                  * Accessing the wrong attribute.
567                  */
568                 return EXPP_ReturnIntError( PyExc_AttributeError, name );
569         }
570
571         /*
572          * Correct attribute but value is incompatible with current button value.
573          */
574         return EXPP_ReturnIntError( PyExc_ValueError, "value incompatible with current button type" );
575 }
576
577 static PyObject *Button_repr( PyObject * self )
578 {
579         return PyObject_Repr( Button_getattr( self, "val" ) );
580 }
581
582 static PyObject *Button_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
583 {
584         if (ButtonObject_Check(objectA))
585                 objectA = Button_getattr( objectA, "val" );
586         if (ButtonObject_Check(objectB))
587                 objectB = Button_getattr( objectB, "val" );
588         return PyObject_RichCompare(objectA, objectB, comparison_type);
589 }
590
591
592 static Button *newbutton( void )
593 {
594         Button *but = NULL;
595         
596         but = ( Button * ) PyObject_NEW( Button, &Button_Type );
597
598         return but;
599 }
600
601 /* GUI interface routines */
602
603 static void exit_pydraw( SpaceScript * sc, short err )
604 {
605         Script *script = NULL;
606
607         if( !sc || !sc->script )
608                 return;
609
610         script = sc->script;
611
612         if( err ) {
613                 PyErr_Print(  );
614                 script->flags = 0;      /* mark script struct for deletion */
615                 error( "Python script error: check console" );
616                 scrarea_queue_redraw( sc->area );
617         }
618
619         Py_XDECREF( ( PyObject * ) script->py_draw );
620         Py_XDECREF( ( PyObject * ) script->py_event );
621         Py_XDECREF( ( PyObject * ) script->py_button );
622
623         script->py_draw = script->py_event = script->py_button = NULL;
624 }
625
626 static void exec_callback( SpaceScript * sc, PyObject * callback,
627                            PyObject * args )
628 {
629         PyObject *result = PyObject_CallObject( callback, args );
630
631         if( result == NULL && sc->script ) {    /* errors in the script */
632
633                 if( sc->script->lastspace == SPACE_TEXT ) {     /*if it can be an ALT+P script */
634                         Text *text = G.main->text.first;
635
636                         while( text ) { /* find it and free its compiled code */
637
638                                 if( !strcmp
639                                     ( text->id.name + 2,
640                                       sc->script->id.name + 2 ) ) {
641                                         BPY_free_compiled_text( text );
642                                         break;
643                                 }
644
645                                 text = text->id.next;
646                         }
647                 }
648                 exit_pydraw( sc, 1 );
649         }
650
651         Py_XDECREF( result );
652         Py_DECREF( args );
653 }
654
655 /* BPY_spacescript_do_pywin_draw, the static spacescript_do_pywin_buttons and
656  * BPY_spacescript_do_pywin_event are the three functions responsible for
657  * calling the draw, buttons and event callbacks registered with Draw.Register
658  * (see Method_Register below).  They are called (only the two BPY_ ones)
659  * from blender/src/drawscript.c */
660
661 void BPY_spacescript_do_pywin_draw( SpaceScript * sc )
662 {
663         uiBlock *block;
664         char butblock[20];
665         Script *script = sc->script;
666
667         sprintf( butblock, "win %d", curarea->win );
668         block = uiNewBlock( &curarea->uiblocks, butblock, UI_EMBOSSX,
669                             UI_HELV, curarea->win );
670
671         if( script->py_draw ) {
672                 glPushAttrib( GL_ALL_ATTRIB_BITS );
673                 exec_callback( sc, script->py_draw, Py_BuildValue( "()" ) );
674                 glPopAttrib(  );
675         } else {
676                 glClearColor( 0.4375, 0.4375, 0.4375, 0.0 );
677                 glClear( GL_COLOR_BUFFER_BIT );
678         }
679
680         uiDrawBlock( block );
681
682         curarea->win_swap = WIN_BACK_OK;
683 }
684
685 static void spacescript_do_pywin_buttons( SpaceScript * sc,
686                                           unsigned short event )
687 {
688         if( sc->script->py_button )
689                 exec_callback( sc, sc->script->py_button,
690                                Py_BuildValue( "(i)", event ) );
691 }
692
693 void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
694         short val, char ascii )
695 {
696         if( event == QKEY && G.qual & ( LR_ALTKEY | LR_CTRLKEY ) ) {
697                 /* finish script: user pressed ALT+Q or CONTROL+Q */
698                 Script *script = sc->script;
699
700                 exit_pydraw( sc, 0 );
701
702                 script->flags &= ~SCRIPT_GUI;   /* we're done with this script */
703
704                 return;
705         }
706
707         if (val) {
708
709                 if (uiDoBlocks( &curarea->uiblocks, event ) != UI_NOTHING) event = 0;
710
711                 if (event == UI_BUT_EVENT) {
712                         /* check that event is in free range for script button events;
713                          * read the comment before check_button_event() below to understand */
714                         if (val >= EXPP_BUTTON_EVENTS_OFFSET && val < 0x4000)
715                                 spacescript_do_pywin_buttons(sc, val - EXPP_BUTTON_EVENTS_OFFSET);
716                         return;
717                 }
718         }
719
720         /* We use the "event" main module var, used by scriptlinks, to pass the ascii
721          * value to event callbacks (gui/event/button callbacks are not allowed
722          * inside scriptlinks, so this is ok) */
723         if( sc->script->py_event ) {
724                 int pass_ascii = 0;
725                 if (ascii > 31 && ascii != 127) {
726                         pass_ascii = 1;
727                         EXPP_dict_set_item_str(g_blenderdict, "event",
728                                         PyInt_FromLong((long)ascii));
729                 }
730                 exec_callback( sc, sc->script->py_event,
731                         Py_BuildValue( "(ii)", event, val ) );
732                 if (pass_ascii)
733                         EXPP_dict_set_item_str(g_blenderdict, "event",
734                                         PyString_FromString(""));
735         }
736 }
737
738 static void exec_but_callback(void *pyobj, void *data)
739 {
740         PyObject *result;
741         PyObject *pyvalue = NULL;
742         uiBut *but = (uiBut *)data;
743         PyObject *arg;
744         PyObject *callback = (PyObject *)pyobj;
745         
746         double value = ui_get_but_val(but);
747         
748         if (callback==NULL || callback == Py_None)
749                 return;
750         
751         /* Button types support
752         case MENU:      
753         case TEX:
754         case TOG:
755         case NUMSLI:
756         case NUM:
757         case COL:
758         case BUT_NORMAL:
759         case BUT */
760         switch (but->type) {
761         case TEX:
762                 /*printf("TEX\n");*/
763                 pyvalue = PyString_FromString( (char *)but->poin );
764                 break;
765         case NUM:
766         case NUMSLI:
767         case TOG:
768         case MENU:
769                 if (but->pointype==FLO) {
770                         /*printf("FLO\n");*/
771                         pyvalue = PyFloat_FromDouble( (float)value );
772                 } else if (but->pointype==INT) {
773                         /*printf("INT\n");*/
774                         pyvalue = PyInt_FromLong( (int)value );
775                 } else if (but->pointype==SHO) {
776                         /*printf("SHO\n");*/
777                         pyvalue = PyInt_FromLong( (short)value );
778                 }       
779                 break;
780         case COL:
781         case BUT_NORMAL:
782         {
783                 float vec[3];
784                 VECCOPY(vec, (float *)but->poin);
785                 pyvalue = Py_BuildValue("(fff)", vec[0], vec[1], vec[2]);
786                 break;
787         }
788         case BUT:
789                 pyvalue = Py_None;
790                 Py_INCREF(pyvalue);
791                 break;
792         default:
793                 pyvalue = Py_None;
794                 Py_INCREF(pyvalue);
795                 printf("Error, no button type matched.");
796         }
797         
798         arg = PyTuple_New( 2 );
799         if (uiblock==NULL)
800                 PyTuple_SetItem( arg, 0, PyInt_FromLong(but->retval - EXPP_BUTTON_EVENTS_OFFSET) );
801         else
802                 PyTuple_SetItem( arg, 0, PyInt_FromLong(but->retval) );
803         
804         PyTuple_SetItem( arg, 1, pyvalue );
805         
806         result = PyObject_CallObject( callback, arg );
807         Py_DECREF(arg);
808         
809         if (!result) {
810                 Py_DECREF(pyvalue);
811                 PyErr_Print(  );
812                 error( "Python script error: check console" );
813         }
814         Py_XDECREF( result );
815 }
816
817 static void set_pycallback(uiBut *ubut, PyObject *callback)
818 {
819         if (!callback || !PyCallable_Check(callback)) return;
820         uiButSetFunc(ubut, exec_but_callback, callback, ubut);
821 }
822
823 static PyObject *Method_Exit( PyObject * self, PyObject * args )
824 {
825         SpaceScript *sc;
826         Script *script;
827
828         /* if users call Draw.Exit when we are already out of the SPACE_SCRIPT, we
829          * simply return, for compatibility */
830         if( curarea->spacetype == SPACE_SCRIPT )
831                 sc = curarea->spacedata.first;
832         else
833                 Py_RETURN_NONE;
834
835         if( PyTuple_Size(args) )
836                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
837                                               "expected empty argument list" );
838
839         exit_pydraw( sc, 0 );
840
841         script = sc->script;
842
843         /* remove our lock to the current namespace */
844         script->flags &= ~SCRIPT_GUI;
845
846         Py_RETURN_NONE;
847 }
848
849 /* Method_Register (Draw.Register) registers callbacks for drawing, events
850  * and gui button events, so a script can continue executing after the
851  * interpreter reached its end and returned control to Blender.  Everytime
852  * the SPACE_SCRIPT window with this script is redrawn, the registered
853  * callbacks are executed. */
854 static PyObject *Method_Register( PyObject * self, PyObject * args )
855 {
856         PyObject *newdrawc = NULL, *neweventc = NULL, *newbuttonc = NULL;
857         SpaceScript *sc;
858         Script *script;
859         int startspace = 0;
860
861         if( !PyArg_ParseTuple
862             ( args, "O|OO", &newdrawc, &neweventc, &newbuttonc ) )
863                 return EXPP_ReturnPyObjError( PyExc_TypeError,
864                                               "expected one or three PyObjects" );
865
866         if( !PyCallable_Check( newdrawc ) )
867                 newdrawc = NULL;
868         if( !PyCallable_Check( neweventc ) )
869                 neweventc = NULL;
870         if( !PyCallable_Check( newbuttonc ) )
871                 newbuttonc = NULL;
872
873         if( !( newdrawc || neweventc || newbuttonc ) )
874                 Py_RETURN_NONE;
875
876         startspace = curarea->spacetype;
877
878         /* first make sure the current area is of type SPACE_SCRIPT */
879         if( startspace != SPACE_SCRIPT )
880                 newspace( curarea, SPACE_SCRIPT );
881
882         sc = curarea->spacedata.first;
883
884         /* There are two kinds of scripts:
885          * a) those that simply run, finish and return control to Blender;
886          * b) those that do like 'a)' above but leave callbacks for drawing,
887          * events and button events, with this Method_Register (Draw.Register
888          * in Python).  These callbacks are called by scriptspaces (Scripts windows).
889          *
890          * We need to flag scripts that leave callbacks so their namespaces are
891          * not deleted when they 'finish' execution, because the callbacks will
892          * still need the namespace.
893          */
894
895         /* Let's see if this is a new script */
896         script = G.main->script.first;
897         while (script) {
898                 if (script->flags & SCRIPT_RUNNING) break;
899                 script = script->id.next;
900         }
901
902         if( !script ) {
903                 /* not new, it's a left callback calling Register again */
904                 script = sc->script;
905                 if( !script ) {
906                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
907                                 "Draw.Register can't be used inside script links" );
908                 }
909         }
910         else sc->script = script;
911
912         /* Now we have the right script and can set a lock so its namespace can't be
913          * deleted for as long as we need it */
914         script->flags |= SCRIPT_GUI;
915
916         /* save the last space so we can go back to it upon finishing */
917         if( !script->lastspace )
918                 script->lastspace = startspace;
919
920         /* clean the old callbacks */
921         exit_pydraw( sc, 0 );
922
923         /* prepare the new ones and insert them */
924         Py_XINCREF( newdrawc );
925         Py_XINCREF( neweventc );
926         Py_XINCREF( newbuttonc );
927
928         script->py_draw = newdrawc;
929         script->py_event = neweventc;
930         script->py_button = newbuttonc;
931
932         scrarea_queue_redraw( sc->area );
933
934         Py_RETURN_NONE;
935 }
936
937 static PyObject *Method_Redraw( PyObject * self, PyObject * args )
938 {
939         int after = 0;
940
941         if( !PyArg_ParseTuple( args, "|i", &after ) )
942                 return EXPP_ReturnPyObjError( PyExc_TypeError,
943                                               "expected int argument (or nothing)" );
944
945         if( after )
946                 addafterqueue( curarea->win, REDRAW, 1 );
947         else
948                 scrarea_queue_winredraw( curarea );
949
950         Py_RETURN_NONE;
951 }
952
953 static PyObject *Method_Draw( PyObject * self, PyObject * args )
954 {
955         /*@ If forced drawing is disable queue a redraw event instead */
956         if( EXPP_disable_force_draw ) {
957                 scrarea_queue_winredraw( curarea );
958                 Py_RETURN_NONE;
959         }
960
961         if( PyTuple_Size(args) )
962                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
963                                               "expected empty argument list" );
964
965         scrarea_do_windraw( curarea );
966
967         screen_swapbuffers(  );
968
969         Py_RETURN_NONE;
970 }
971
972 static PyObject *Method_Create( PyObject * self, PyObject * args )
973 {
974         Button *but = NULL;
975         PyObject *val;
976         char *newstr;
977
978         but = newbutton();
979
980         if ( PyArg_ParseTuple( args, "fff", but->val.asvec, but->val.asvec+1, but->val.asvec+2 ) ) {
981                 but->type = BVECTOR_TYPE;
982         }
983         else if ( PyArg_ParseTuple( args, "O!", &PyFloat_Type, &val ) ) {
984                 but->val.asfloat = (float)PyFloat_AS_DOUBLE(val);
985                 but->type = BFLOAT_TYPE;
986         }
987         else if ( PyArg_ParseTuple( args, "O!", &PyInt_Type, &val ) ) {
988                 but->val.asint = (int)PyInt_AS_LONG(val);
989                 but->type = BINT_TYPE;
990         }
991         else if ( PyArg_ParseTuple( args, "s#", &newstr, &but->slen ) ) {
992                 if (but->slen + 1 > UI_MAX_DRAW_STR) {
993                         PyObject_DEL( (PyObject *) but );
994                         but = NULL;
995                         PyErr_SetString( PyExc_TypeError, "string is longer then 399 chars");
996                 } else {
997                         but->type = BSTRING_TYPE;
998                         but->val.asstr = MEM_mallocN( but->slen + 1, "button string" );
999                         BLI_strncpy( but->val.asstr, newstr, but->slen+1 );
1000                 }
1001         }
1002         else {
1003                 PyObject_DEL( (PyObject *) but );
1004                 but = NULL;
1005                 PyErr_SetString( PyExc_TypeError, "expected string, float, int or 3-float tuple argument" );
1006         }
1007         
1008         if (but != NULL) {
1009                 PyErr_Clear();
1010         }
1011
1012         return (PyObject*) but;
1013 }
1014
1015 static PyObject *Method_UIBlock( PyObject * self, PyObject * args )
1016 {
1017         PyObject *val = NULL;
1018         PyObject *result = NULL;
1019         ListBase listb= {NULL, NULL};
1020
1021         if ( !PyArg_ParseTuple( args, "O", &val ) || !PyCallable_Check( val ) ) 
1022                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1023                                               "expected 1 python function and 2 ints" );
1024
1025         if (uiblock)
1026                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1027               "cannot run more then 1 UIBlock at a time" );
1028         
1029         mywinset(G.curscreen->mainwin);
1030         uiblock= uiNewBlock(&listb, "numbuts", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
1031         
1032         uiBlockSetFlag(uiblock, UI_BLOCK_LOOP|UI_BLOCK_REDRAW);
1033         result = PyObject_CallObject( val, Py_BuildValue( "()" ) );
1034
1035         if (!result) {
1036                 PyErr_Print(  );
1037                 error( "Python script error: check console" );
1038         } else {
1039                 uiBoundsBlock(uiblock, 5);
1040                 uiDoBlocks(&listb, 0);
1041         }
1042         uiFreeBlocks(&listb);
1043         uiblock = NULL;
1044         
1045         Py_XDECREF( result );
1046         Py_RETURN_NONE;
1047 }
1048
1049 static uiBlock *Get_uiBlock( void )
1050 {
1051         char butblock[32];
1052         /* Global, used now for UIBlock */
1053         if (uiblock) {
1054                 return uiblock;
1055         }
1056         /* Local */
1057         sprintf( butblock, "win %d", curarea->win );
1058
1059         return uiGetBlock( butblock, curarea );
1060 }
1061
1062
1063 /* We restrict the acceptable event numbers to a proper "free" range
1064  * according to other spaces in Blender.
1065  * winqread***space() (space events callbacks) use short for events
1066  * (called 'val' there) and we also translate by EXPP_BUTTON_EVENTS_OFFSET
1067  * to get rid of unwanted events (check BPY_do_pywin_events above for
1068  * explanation). This function takes care of that and proper checking: */
1069 static int check_button_event(int *event) {
1070         if ((*event < EXPP_BUTTON_EVENTS_MIN) ||
1071                         (*event > EXPP_BUTTON_EVENTS_MAX)) {
1072                 return -1;
1073         }
1074         if (uiblock==NULL) /* For UIBlock we need non offset UI elements */
1075                 *event += EXPP_BUTTON_EVENTS_OFFSET;
1076         return 0;
1077 }
1078
1079 static PyObject *Method_BeginAlign( PyObject * self, PyObject * args )
1080 {
1081         uiBlock *block = Get_uiBlock(  );
1082         
1083         if (block)
1084                 uiBlockBeginAlign(block);
1085         
1086         Py_RETURN_NONE;
1087 }
1088
1089 static PyObject *Method_EndAlign( PyObject * self, PyObject * args )
1090 {
1091         uiBlock *block = Get_uiBlock(  );
1092         
1093         if (block)
1094                 uiBlockEndAlign(block);
1095         
1096         Py_RETURN_NONE;
1097 }
1098
1099 static PyObject *Method_Button( PyObject * self, PyObject * args )
1100 {
1101         uiBlock *block;
1102         char *name, *tip = NULL;
1103         int event;
1104         int x, y, w, h;
1105         PyObject *callback=NULL;
1106
1107         if( !PyArg_ParseTuple( args, "siiiii|sO", &name, &event,
1108                                &x, &y, &w, &h, &tip, &callback ) )
1109                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1110                                               "expected a string, five ints and optionally string and callback arguments" );
1111
1112         UI_METHOD_ERRORCHECK;
1113
1114         block = Get_uiBlock(  );
1115         if( block ) {
1116                 uiBut *ubut = uiDefBut( block, BUT, event, name, (short)x, (short)y, (short)w, (short)h, 0, 0, 0, 0, 0, tip );
1117                 set_pycallback(ubut, callback);
1118         }
1119         Py_RETURN_NONE;
1120 }
1121
1122 static PyObject *Method_Menu( PyObject * self, PyObject * args )
1123 {
1124         uiBlock *block;
1125         char *name, *tip = NULL;
1126         int event, def;
1127         int x, y, w, h;
1128         Button *but;
1129         PyObject *callback=NULL;
1130
1131         if( !PyArg_ParseTuple( args, "siiiiii|sO", &name, &event,
1132                                &x, &y, &w, &h, &def, &tip, &callback ) )
1133                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1134                                               "expected a string, six ints and optionally string and callback arguments" );
1135
1136         UI_METHOD_ERRORCHECK;
1137         
1138         but = newbutton(  );
1139         but->type = BINT_TYPE;
1140         but->val.asint = def;
1141
1142         block = Get_uiBlock(  );
1143         if( block ) {
1144                 uiBut *ubut = uiDefButI( block, MENU, event, name, (short)x, (short)y, (short)w, (short)h,
1145                            &but->val.asint, 0, 0, 0, 0, tip );
1146                 set_pycallback(ubut, callback);
1147         }
1148         return ( PyObject * ) but;
1149 }
1150
1151 static PyObject *Method_Toggle( PyObject * self, PyObject * args )
1152 {
1153         uiBlock *block;
1154         char *name, *tip = NULL;
1155         int event;
1156         int x, y, w, h, def;
1157         Button *but;
1158         PyObject *callback=NULL;
1159
1160         if( !PyArg_ParseTuple( args, "siiiiii|sO", &name, &event,
1161                                &x, &y, &w, &h, &def, &tip, &callback ) )
1162                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1163                                               "expected a string, six ints and optionally string and callback arguments" );
1164
1165         UI_METHOD_ERRORCHECK;
1166         
1167         but = newbutton(  );
1168         but->type = BINT_TYPE;
1169         but->val.asint = def;
1170
1171         block = Get_uiBlock(  );
1172         if( block ) {
1173                 uiBut *ubut = uiDefButI( block, TOG, event, name, (short)x, (short)y, (short)w, (short)h,
1174                            &but->val.asint, 0, 0, 0, 0, tip );
1175                 set_pycallback(ubut, callback);
1176         }
1177         return ( PyObject * ) but;
1178 }
1179
1180 /*@DO NOT TOUCH THIS FUNCTION !
1181          Redrawing a slider inside its own callback routine is actually forbidden
1182          with the current toolkit architecture (button routines are not reentrant).
1183          But it works anyway.
1184          XXX This is condemned to be dinosource in future - it's a hack.
1185          */
1186
1187 static void py_slider_update( void *butv, void *data2_unused )
1188 {
1189         uiBut *but = butv;
1190         PyObject *ref = Py_BuildValue( "(i)", SPACE_VIEW3D );
1191         PyObject *ret = NULL;
1192
1193         EXPP_disable_force_draw = 1;
1194         /*@ Disable forced drawing, otherwise the button object which
1195          * is still being used might be deleted */
1196
1197         curarea->win_swap = WIN_BACK_OK;
1198         /* removed global uiFrontBuf (contact ton when this goes wrong here) */
1199
1200         disable_where_script( 1 );
1201
1202         spacescript_do_pywin_buttons( curarea->spacedata.first,
1203                 (unsigned short)uiButGetRetVal( but ) );
1204
1205         /* XXX useless right now, investigate better before a bcon 5 */
1206         ret = M_Window_Redraw( 0, ref );
1207
1208         Py_DECREF(ref);
1209         if (ret) { Py_DECREF(ret); }
1210
1211         disable_where_script( 0 );
1212
1213         EXPP_disable_force_draw = 0;
1214 }
1215
1216 static PyObject *Method_Slider( PyObject * self, PyObject * args )
1217 {
1218         uiBlock *block;
1219         char *name, *tip = NULL;
1220         int event;
1221         int x, y, w, h, realtime = 1;
1222         Button *but;
1223         PyObject *mino, *maxo, *inio;
1224         PyObject *callback=NULL;
1225
1226         if( !PyArg_ParseTuple( args, "siiiiiOOO|isO", &name, &event,
1227                                &x, &y, &w, &h, &inio, &mino, &maxo, &realtime,
1228                                &tip, &callback ) )
1229                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1230                                               "expected a string, five ints, three PyObjects\n\
1231                         and optionally int, string and callback arguments" );
1232
1233         UI_METHOD_ERRORCHECK;
1234         
1235         but = newbutton(  );
1236
1237         if( PyFloat_Check( inio ) ) {
1238                 float ini, min, max;
1239
1240                 ini = (float)PyFloat_AsDouble( inio );
1241                 min = (float)PyFloat_AsDouble( mino );
1242                 max = (float)PyFloat_AsDouble( maxo );
1243
1244                 but->type = BFLOAT_TYPE;
1245                 but->val.asfloat = ini;
1246
1247                 block = Get_uiBlock(  );
1248                 if( block ) {
1249                         uiBut *ubut;
1250                         ubut = uiDefButF( block, NUMSLI, event, name, (short)x, (short)y, (short)w,
1251                                           (short)h, &but->val.asfloat, min, max, 0, 0,
1252                                           tip );
1253                         if( realtime )
1254                                 uiButSetFunc( ubut, py_slider_update, ubut, NULL );
1255                         else
1256                                 set_pycallback(ubut, callback);
1257                 }
1258         } else {
1259                 int ini, min, max;
1260
1261                 ini = PyInt_AsLong( inio );
1262                 min = PyInt_AsLong( mino );
1263                 max = PyInt_AsLong( maxo );
1264
1265                 but->type = BINT_TYPE;
1266                 but->val.asint = ini;
1267
1268                 block = Get_uiBlock(  );
1269                 if( block ) {
1270                         uiBut *ubut;
1271                         ubut = uiDefButI( block, NUMSLI, event, name, (short)x, (short)y, (short)w,
1272                                           (short)h, &but->val.asint, (float)min, (float)max, 0, 0,
1273                                           tip );
1274                         if( realtime )
1275                                 uiButSetFunc( ubut, py_slider_update, ubut, NULL );
1276                         else
1277                                 set_pycallback(ubut, callback);
1278                 }
1279         }
1280         return ( PyObject * ) but;
1281 }
1282
1283 static PyObject *Method_Scrollbar( PyObject * self, PyObject * args )
1284 {
1285         char *tip = NULL;
1286         uiBlock *block;
1287         int event;
1288         int x, y, w, h, realtime = 1;
1289         Button *but;
1290         PyObject *mino, *maxo, *inio;
1291         float ini, min, max;
1292         uiBut *ubut;
1293         
1294         if( !PyArg_ParseTuple( args, "iiiiiOOO|isO", &event, &x, &y, &w, &h,
1295                                &inio, &mino, &maxo, &realtime, &tip ) )
1296                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1297                         "expected five ints, three PyObjects and optionally\n\
1298 another int and string as arguments" );
1299
1300         if( !PyNumber_Check( inio ) || !PyNumber_Check( inio )
1301             || !PyNumber_Check( inio ) )
1302                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1303                                               "expected numbers for initial, min, and max" );
1304
1305         if (check_button_event(&event) == -1)
1306         return EXPP_ReturnPyObjError( PyExc_AttributeError,
1307                 "button event argument must be in the range [0, 16382]");
1308
1309         but = newbutton(  );
1310
1311         if( PyFloat_Check( inio ) )
1312                 but->type = BFLOAT_TYPE;
1313         else
1314                 but->type = BINT_TYPE;
1315
1316         ini = (float)PyFloat_AsDouble( inio );
1317         min = (float)PyFloat_AsDouble( mino );
1318         max = (float)PyFloat_AsDouble( maxo );
1319         
1320         block = Get_uiBlock(  );
1321
1322         if( block ) {
1323                 if( but->type == BFLOAT_TYPE ) {
1324                         but->val.asfloat = ini;
1325                         ubut = uiDefButF( block, SCROLL, event, "", (short)x, (short)y, (short)w, (short)h,
1326                                           &but->val.asfloat, min, max, 0, 0, tip );
1327                         if( realtime )
1328                                 uiButSetFunc( ubut, py_slider_update, ubut, NULL );
1329                 } else {
1330                         but->val.asint = (int)ini;
1331                         ubut = uiDefButI( block, SCROLL, event, "", (short)x, (short)y, (short)w, (short)h,
1332                                           &but->val.asint, min, max, 0, 0, tip );
1333                         if( realtime )
1334                                 uiButSetFunc( ubut, py_slider_update, ubut, NULL );
1335                 }
1336         }
1337         return ( PyObject * ) but;
1338 }
1339
1340 static PyObject *Method_ColorPicker( PyObject * self, PyObject * args )
1341 {
1342         char USAGE_ERROR[] = "expected a 3-float tuple of values between 0 and 1";
1343         Button *but;
1344         PyObject *inio;
1345         uiBlock *block;
1346         char *tip = NULL;
1347         float col[3];
1348         int event;
1349         short x, y, w, h;
1350         PyObject *callback=NULL;
1351         
1352         if( !PyArg_ParseTuple( args, "ihhhhO!|sO", &event,
1353                                &x, &y, &w, &h, &PyTuple_Type, &inio, &tip, &callback ) )
1354                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1355                                               "expected five ints, one tuple and optionally string and callback arguments" );
1356  
1357         UI_METHOD_ERRORCHECK;
1358  
1359         if ( !PyArg_ParseTuple( inio, "fff", col, col+1, col+2 ) )
1360                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1361
1362         if      (       col[0] < 0 || col[0] > 1
1363                 ||      col[1] < 0 || col[1] > 1
1364                 ||      col[2] < 0 || col[2] > 1 )
1365                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1366
1367         if ( EXPP_check_sequence_consistency( inio, &PyFloat_Type ) != 1 )
1368                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1369  
1370         but = newbutton();
1371  
1372         but->type = BVECTOR_TYPE;
1373         but->val.asvec[0] = col[0];
1374         but->val.asvec[1] = col[1];
1375         but->val.asvec[2] = col[2];
1376         
1377         block = Get_uiBlock(  );
1378         if( block ) {
1379                 uiBut *ubut;
1380                 ubut = uiDefButF( block, COL, event, "", x, y, w, h, but->val.asvec, 0, 0, 0, 0, tip);
1381                 set_pycallback(ubut, callback);
1382         }
1383
1384         return ( PyObject * ) but;
1385 }
1386
1387
1388
1389 static PyObject *Method_Normal( PyObject * self, PyObject * args )
1390 {
1391         char USAGE_ERROR[] = "expected a 3-float tuple of values between -1 and 1";
1392         Button *but;
1393         PyObject *inio;
1394         uiBlock *block;
1395         char *tip = NULL;
1396         float nor[3];
1397         int event;
1398         short x, y, w, h;
1399         PyObject *callback=NULL;
1400         
1401         if( !PyArg_ParseTuple( args, "ihhhhO!|sO", &event,
1402                                &x, &y, &w, &h, &PyTuple_Type, &inio, &tip, &callback ) )
1403                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1404                                               "expected five ints, one tuple and optionally string and callback arguments" );
1405  
1406         UI_METHOD_ERRORCHECK;
1407  
1408         if ( !PyArg_ParseTuple( inio, "fff", nor, nor+1, nor+2 ) )
1409                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1410
1411         if ( EXPP_check_sequence_consistency( inio, &PyFloat_Type ) != 1 )
1412                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1413  
1414         but = newbutton();
1415  
1416         but->type = BVECTOR_TYPE;
1417         but->val.asvec[0] = nor[0];
1418         but->val.asvec[1] = nor[1];
1419         but->val.asvec[2] = nor[2];
1420         
1421         block = Get_uiBlock(  );
1422         if( block ) {
1423                 uiBut *ubut;
1424                 ubut = uiDefButF( block, BUT_NORMAL, event, "", x, y, w, h, but->val.asvec, 0.0f, 1.0f, 0, 0, tip);
1425                 set_pycallback(ubut, callback);
1426         }
1427         
1428         return ( PyObject * ) but;
1429 }
1430
1431 static PyObject *Method_Number( PyObject * self, PyObject * args )
1432 {
1433         uiBlock *block;
1434         char *name, *tip = NULL;
1435         int event;
1436         int x, y, w, h;
1437         Button *but;
1438         PyObject *mino, *maxo, *inio;
1439         PyObject *callback=NULL;
1440         uiBut *ubut= NULL;
1441         
1442         if( !PyArg_ParseTuple( args, "siiiiiOOO|sO", &name, &event,
1443                                &x, &y, &w, &h, &inio, &mino, &maxo, &tip, &callback ) )
1444                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1445                                               "expected a string, five ints, three PyObjects and\n\
1446                         optionally string and callback arguments" );
1447
1448         UI_METHOD_ERRORCHECK;
1449
1450         but = newbutton(  );
1451         block = Get_uiBlock(  );
1452         
1453         if( PyFloat_Check( inio ) ) {
1454                 float ini, min, max, range, precission=0;
1455
1456                 ini = (float)PyFloat_AsDouble( inio );
1457                 min = (float)PyFloat_AsDouble( mino );
1458                 max = (float)PyFloat_AsDouble( maxo );
1459                 
1460                 range= (float)fabs(max-min); /* Click step will be a 10th of the range. */
1461                 if (!range) range= 1.0f; /* avoid any odd errors */
1462                 
1463                 /* set the precission to display*/
1464                 if      (range>=1000.0f) precission=1.0f;
1465                 else if (range>=100.0f) precission=2.0f;
1466                 else if (range>=10.0f) precission=3.0f;
1467                 else precission=4.0f;
1468                 
1469                 but->type = BFLOAT_TYPE;
1470                 but->val.asfloat = ini;
1471
1472                 
1473                 if( block )
1474                         ubut= uiDefButF( block, NUM, event, name, (short)x, (short)y, (short)w, (short)h,
1475                                    &but->val.asfloat, min, max, 10*range, precission, tip );
1476         } else {
1477                 int ini, min, max;
1478
1479                 ini = PyInt_AsLong( inio );
1480                 min = PyInt_AsLong( mino );
1481                 max = PyInt_AsLong( maxo );
1482
1483                 but->type = BINT_TYPE;
1484                 but->val.asint = ini;
1485
1486                 if( block )
1487                         ubut= uiDefButI( block, NUM, event, name, (short)x, (short)y, (short)w, (short)h,
1488                                    &but->val.asint, (float)min, (float)max, 0, 0, tip );
1489         }
1490         
1491         if (ubut) set_pycallback(ubut, callback);
1492         
1493         return ( PyObject * ) but;
1494 }
1495
1496 static PyObject *Method_String( PyObject * self, PyObject * args )
1497 {
1498         uiBlock *block;
1499         char *info_arg = NULL, *tip = NULL, *newstr = NULL;
1500         char *info_str = NULL, *info_str0 = " ";
1501         int event;
1502         int x, y, w, h, len, real_len = 0;
1503         Button *but;
1504         PyObject *callback=NULL;
1505
1506         if( !PyArg_ParseTuple( args, "siiiiisi|sO", &info_arg, &event,
1507                         &x, &y, &w, &h, &newstr, &len, &tip, &callback ) )
1508                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1509                         "expected a string, five ints, a string, an int and\n\
1510         optionally string and callback arguments" );
1511
1512         UI_METHOD_ERRORCHECK;
1513
1514         if (len > (UI_MAX_DRAW_STR - 1))
1515                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1516                         "The maximum length of a string is 399, your value is too high.");
1517
1518         real_len = strlen(newstr);
1519         if (real_len > len) real_len = len;
1520
1521         but = newbutton(  );
1522         but->type = BSTRING_TYPE;
1523         but->slen = len;
1524         but->val.asstr = MEM_mallocN( len + 1, "pybutton str" );
1525
1526         BLI_strncpy( but->val.asstr, newstr, len + 1); /* adds '\0' */
1527         but->val.asstr[real_len] = '\0';
1528
1529         if (info_arg[0] == '\0') info_str = info_str0;
1530         else info_str = info_arg;
1531
1532         block = Get_uiBlock(  );
1533         if( block ) {
1534                 uiBut *ubut = uiDefBut( block, TEX, event, info_str, (short)x, (short)y, (short)w, (short)h,
1535                           but->val.asstr, 0, (float)len, 0, 0, tip );
1536                 set_pycallback(ubut, callback);
1537         }
1538         return ( PyObject * ) but;
1539 }
1540
1541 static PyObject *Method_GetStringWidth( PyObject * self, PyObject * args )
1542 {
1543         char *text;
1544         char *font_str = "normal";
1545         struct BMF_Font *font;
1546         PyObject *width;
1547
1548         if( !PyArg_ParseTuple( args, "s|s", &text, &font_str ) )
1549                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1550                                               "expected one or two string arguments" );
1551
1552         if( !strcmp( font_str, "normal" ) )
1553                 font = ( &G )->font;
1554         else if( !strcmp( font_str, "large" ) )
1555                 font = BMF_GetFont(BMF_kScreen15);
1556         else if( !strcmp( font_str, "small" ) )
1557                 font = ( &G )->fonts;
1558         else if( !strcmp( font_str, "tiny" ) )
1559                 font = ( &G )->fontss;
1560         else
1561                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1562                                               "\"font\" must be: 'large', 'normal' (default), 'small' or 'tiny'." );
1563
1564         width = PyInt_FromLong( BMF_GetStringWidth( font, text ) );
1565
1566         if( !width )
1567                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
1568                                               "couldn't create PyInt" );
1569
1570         return width;
1571 }
1572
1573 static PyObject *Method_Text( PyObject * self, PyObject * args )
1574 {
1575         char *text;
1576         char *font_str = NULL;
1577         struct BMF_Font *font;
1578
1579         if( !PyArg_ParseTuple( args, "s|s", &text, &font_str ) )
1580                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1581                                               "expected one or two string arguments" );
1582
1583         if( !font_str )
1584                 font = ( &G )->font;
1585         else if( !strcmp( font_str, "large" ) )
1586                 font = BMF_GetFont(BMF_kScreen15);
1587         else if( !strcmp( font_str, "normal" ) )
1588                 font = ( &G )->font;
1589         else if( !strcmp( font_str, "small" ) )
1590                 font = ( &G )->fonts;
1591         else if( !strcmp( font_str, "tiny" ) )
1592                 font = ( &G )->fontss;
1593         else
1594                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1595                                               "\"font\" must be: 'normal' (default), 'large', 'small' or 'tiny'." );
1596
1597         BMF_DrawString( font, text );
1598
1599         return PyInt_FromLong( BMF_GetStringWidth( font, text ) );
1600 }
1601
1602 static PyObject *Method_Label( PyObject * self, PyObject * args )
1603 {
1604         uiBlock *block;
1605         char *text;
1606         int x, y, w, h;
1607
1608         if( !PyArg_ParseTuple( args, "siiii", &text, &x, &y, &w, &h ) )
1609                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1610                         "expected a string and four ints" );
1611
1612         block = Get_uiBlock(  );
1613         uiDefBut(block, LABEL, 0, text, x, y, w, h, 0, 0, 0, 0, 0, "");
1614         
1615         Py_RETURN_NONE;
1616 }
1617
1618
1619 static PyObject *Method_PupMenu( PyObject * self, PyObject * args )
1620 {
1621         char *text;
1622         int maxrow = -1;
1623         PyObject *ret;
1624
1625         if( !PyArg_ParseTuple( args, "s|i", &text, &maxrow ) )
1626                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1627                                               "expected a string and optionally an int as arguments" );
1628
1629         if( maxrow >= 0 )
1630                 ret = PyInt_FromLong( pupmenu_col( text, maxrow ) );
1631         else
1632                 ret = PyInt_FromLong( pupmenu( text ) );
1633
1634         if( ret )
1635                 return ret;
1636
1637         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1638                                       "couldn't create a PyInt" );
1639 }
1640
1641 static PyObject *Method_PupIntInput( PyObject * self, PyObject * args )
1642 {
1643         char *text = NULL;
1644         int min = 0, max = 1;
1645         short var = 0;
1646         PyObject *ret = NULL;
1647
1648         if( !PyArg_ParseTuple( args, "s|hii", &text, &var, &min, &max ) )
1649                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1650                                               "expected 1 string and 3 int arguments" );
1651
1652         if( button( &var, (short)min, (short)max, text ) == 0 ) {
1653                 Py_INCREF( Py_None );
1654                 return Py_None;
1655         }
1656         ret = PyInt_FromLong( var );
1657         if( ret )
1658                 return ret;
1659
1660         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1661                                       "couldn't create a PyInt" );
1662 }
1663
1664 static PyObject *Method_PupFloatInput( PyObject * self, PyObject * args )
1665 {
1666         char *text = NULL;
1667         float min = 0, max = 1, var = 0, a1 = 10, a2 = 2;
1668         PyObject *ret = NULL;
1669
1670         if( !PyArg_ParseTuple
1671             ( args, "s|fffff", &text, &var, &min, &max, &a1, &a2 ) )
1672                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1673                                               "expected 1 string and 5 float arguments" );
1674
1675         if( fbutton( &var, min, max, a1, a2, text ) == 0 ) {
1676                 Py_INCREF( Py_None );
1677                 return Py_None;
1678         }
1679         ret = PyFloat_FromDouble( var );
1680         if( ret )
1681                 return ret;
1682
1683         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1684                                       "couldn't create a PyFloat" );
1685 }
1686
1687 static PyObject *Method_PupStrInput( PyObject * self, PyObject * args )
1688 {
1689         char *text = NULL, *textMsg = NULL;
1690         char tmp[101];
1691         char max = 20;
1692         PyObject *ret = NULL;
1693
1694         if( !PyArg_ParseTuple( args, "ss|b", &textMsg, &text, &max ) )
1695                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1696                                               "expected 2 strings and 1 int" );
1697
1698         if( ( max <= 0 ) || ( max > 100 ) )
1699                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1700                                               "max string length value must be in the range [1, 100]." );
1701
1702         /* copying the text string handles both cases:
1703          * max < strlen(text) (by truncating) and
1704          * max > strlen(text) (by expanding to strlen(tmp)) */
1705         BLI_strncpy( tmp, text, max + 1 );
1706
1707         if( sbutton( tmp, 0, max, textMsg ) == 0 ) {
1708                 Py_INCREF( Py_None );
1709                 return Py_None;
1710         }
1711
1712         ret = PyString_FromString( tmp );
1713
1714         if( ret )
1715                 return ret;
1716
1717         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1718                                       "couldn't create a PyString" );
1719 }
1720
1721 static PyObject *Method_PupBlock( PyObject * self, PyObject * args )
1722 {
1723         PyObject *pyList, *pyItem;
1724         float min, max;
1725         int len, i;
1726         char *title;
1727
1728         if (!PyArg_ParseTuple( args, "sO", &title, &pyList ) || !PySequence_Check( pyList ))
1729                 return EXPP_ReturnPyObjError( PyExc_TypeError, "expected a string and a sequence" );
1730
1731
1732         len = PySequence_Length(pyList);
1733
1734         if (len == 0)
1735                 return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string and a non-empty sequence." );
1736
1737         if (len > 120) /* LIMIT DEFINED IN toolbox.c    */
1738                 return EXPP_ReturnPyObjError( PyExc_ValueError, "sequence cannot have more than 120 elements" );
1739
1740         for ( i=0 ; i<len ; i++ ) {
1741                 PyObject *pyMin = NULL, *pyMax = NULL;
1742                 PyObject *f1, *f2;
1743                 Button *but = NULL;
1744                 int tlen;
1745                 char *text, *tip = NULL;
1746
1747                 pyItem = PySequence_GetItem( pyList, i );
1748                 if (!pyItem)
1749                         return NULL;
1750
1751                 if (PyString_Check( pyItem )) {
1752                         tlen = -2;      /* single string for label, giving it a special len for later */
1753                 }
1754                 else if (PyTuple_Check( pyItem )) {
1755                         /* tuple for other button, get the length for later */
1756                         tlen = PyTuple_Size( pyItem );
1757                 }
1758                 else {
1759                         /* Neither a string or a tuple, error */
1760                         Py_DECREF( pyItem );
1761                         return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string or a tuple containing 2 to 5 values." );
1762                 }
1763
1764                 switch (tlen) {
1765                 case -2:                /*      LABEL   */
1766                         text = PyString_AsString( pyItem );
1767                         add_numbut(i, LABEL, text, 0, 0, NULL, NULL);
1768                         break;
1769                 case 2:         /*      TOGGLE  (no tooltip)    */
1770                 case 3:         /*      TOGGLE  */
1771                         if (!PyArg_ParseTuple( pyItem, "sO!|s", &text, &Button_Type, &but, &tip )) {
1772                                 Py_DECREF( pyItem );
1773                                 return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a tuple containing a string, a Button object and optionally a string for toggles" );
1774                         }
1775
1776                         if (but->type != BINT_TYPE) {
1777                                 Py_DECREF( pyItem );
1778                                 return EXPP_ReturnPyObjError( PyExc_ValueError, "Button object for toggles should hold an integer" );
1779                         }
1780
1781                         add_numbut(i, TOG|INT, text, 0, 0, &but->val.asint, tip);
1782                         break;
1783                 case 4:         /*      TEX and NUM (no tooltip)        */
1784                 case 5:         /*      TEX and NUM     */
1785                         if (!PyArg_ParseTuple( pyItem, "sO!OO|s", &text, &Button_Type, &but, &pyMin, &pyMax, &tip )) {
1786                                 Py_DECREF( pyItem );
1787                                 return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a tuple containing a string, a Button object, two numerical values and optionally a string for Text and Num buttons" );
1788                         }
1789
1790                         f1 = PyNumber_Float(pyMin);
1791                         f2 = PyNumber_Float(pyMax);
1792
1793                         if (!f1 || !f2) {
1794                                 Py_DECREF( pyItem );
1795                                 return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a tuple containing a string, a Button object, two numerical values and optionally a string for Text and Num buttons" );
1796                         }
1797
1798                         min = (float)PyFloat_AS_DOUBLE(f1);
1799                         max = (float)PyFloat_AS_DOUBLE(f2);
1800                         Py_DECREF( f1 );
1801                         Py_DECREF( f2 );
1802
1803                         switch ( but->type ) {
1804                         case BINT_TYPE:
1805                                 add_numbut(i, NUM|INT, text, min, max, &but->val.asint, tip);
1806                                 break;
1807                         case BFLOAT_TYPE:
1808                                 add_numbut(i, NUM|FLO, text, min, max, &but->val.asfloat, tip);
1809                                 break;
1810                         case BSTRING_TYPE:
1811                                 if (max+1>UI_MAX_DRAW_STR) {
1812                                         Py_DECREF( pyItem );
1813                                         return EXPP_ReturnPyObjError( PyExc_ValueError, "length of a string buttons must be less then 400" );
1814                                 }
1815                                 max = (float)floor(max);
1816
1817                                 if (max > but->slen) {
1818                                         int old_len = but->slen;
1819                                         char *old_str = but->val.asstr;
1820                                         but->slen = (int)max;
1821                                         but->val.asstr = MEM_callocN( but->slen + 1, "button pupblock");
1822                                         BLI_strncpy( but->val.asstr, old_str, old_len + 1 );
1823                                         MEM_freeN(old_str);
1824                                 }
1825
1826                                 add_numbut(i, TEX, text, 0.0f, max, but->val.asstr, tip);
1827                         }
1828
1829                         break;
1830                 default:
1831                         Py_DECREF( pyItem );
1832                         return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string or a tuple containing 2 to 5 values." );
1833                 }
1834                 Py_DECREF( pyItem );
1835         }
1836
1837         if (do_clever_numbuts(title, len, REDRAW))
1838                 return EXPP_incr_ret_True();
1839         else
1840                 return EXPP_incr_ret_False();
1841 }
1842
1843
1844 /*****************************************************************************
1845  * Function:            Method_Image                                         *
1846  * Python equivalent:   Blender.Draw.Image                                   *
1847  *                                                                           *
1848  * @author Jonathan Merritt <j.merritt@pgrad.unimelb.edu.au>                 *
1849  ****************************************************************************/
1850 static PyObject *Method_Image( PyObject * self, PyObject * args )
1851 {
1852         PyObject *pyObjImage;
1853         BPy_Image *py_img;
1854         Image *image;
1855         ImBuf *ibuf;
1856         float originX, originY;
1857         float zoomX = 1.0, zoomY = 1.0;
1858         int clipX = 0, clipY = 0, clipW = -1, clipH = -1;
1859         /*GLfloat scissorBox[4];*/
1860
1861         /* parse the arguments passed-in from Python */
1862         if( !PyArg_ParseTuple( args, "Off|ffiiii", &pyObjImage, 
1863                 &originX, &originY, &zoomX, &zoomY, 
1864                 &clipX, &clipY, &clipW, &clipH ) )
1865                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1866                         "expected a Blender.Image and 2 floats, and " \
1867                         "optionally 2 floats and 4 ints as arguments" );
1868         /* check that the first PyObject is actually a Blender.Image */
1869         if( !BPy_Image_Check( pyObjImage ) )
1870                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1871                         "expected a Blender.Image and 2 floats, and " \
1872                         "optionally 2 floats and 4 ints as arguments" );
1873         /* check that the zoom factors are valid */
1874         if( ( zoomX <= 0.0 ) || ( zoomY <= 0.0 ) )
1875                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1876                         "invalid zoom factors - they must be >= 0.0" );
1877
1878         /* fetch a C Image pointer from the passed-in Python object */
1879         py_img = ( BPy_Image * ) pyObjImage;
1880         image = py_img->image;
1881         ibuf = BKE_image_get_ibuf( image, NULL );
1882                 
1883         if( !ibuf )      /* if failed to load the image */
1884                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1885                                                                           "couldn't load image data in Blender" );
1886         if( !ibuf->rect )      /* no float yet */
1887                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1888                                                                           "Image has no byte rect" );
1889         
1890         /* Update the time tag of the image */
1891         tag_image_time(image);
1892
1893         /* set up a valid clipping rectangle.  if no clip rectangle was
1894          * given, this results in inclusion of the entire image.  otherwise,
1895          * the clipping is just checked against the bounds of the image.
1896          * if clipW or clipH are less than zero then they include as much of
1897          * the image as they can. */
1898         clipX = EXPP_ClampInt( clipX, 0, ibuf->x );
1899         clipY = EXPP_ClampInt( clipY, 0, ibuf->y );
1900         if( ( clipW < 0 ) || ( clipW > ( ibuf->x - clipW ) ) )
1901                 clipW = ibuf->x - clipX;
1902         if( ( clipH < 0 ) || ( clipH > ( ibuf->y - clipH ) ) )
1903                 clipH = ibuf->y - clipY;
1904
1905         /* -- we are "Go" to Draw! -- */
1906
1907         /* set the raster position.
1908          *
1909          * If the raster position is negative, then using glRasterPos2i() 
1910          * directly would cause it to be clipped.  Instead, we first establish 
1911          * a valid raster position within the clipping rectangle of the 
1912          * window and then use glBitmap() with a NULL image pointer to offset 
1913          * it to the true position we require.  To pick an initial valid 
1914          * raster position within the viewport, we query the clipping rectangle
1915          * and use its lower-left pixel.
1916          *
1917          * This particular technique is documented in the glRasterPos() man
1918          * page, although I haven't seen it used elsewhere in Blender.
1919          */
1920
1921         /* update (W): to fix a bug where images wouldn't get drawn if the bottom
1922          * left corner of the Scripts win were above a given height or to the right
1923          * of a given width, the code below is being commented out.  It should not
1924          * be needed anyway, because spaces in Blender are projected to lie inside
1925          * their areas, see src/drawscript.c for example.  Note: the
1926          * glaRasterPosSafe2i function in src/glutil.c does use the commented out
1927          * technique, but with 0,0 instead of scissorBox.  This function can be
1928          * a little optimized, based on glaDrawPixelsSafe in that same fine, but
1929          * we're too close to release 2.37 right now. */
1930         /*
1931         glGetFloatv( GL_SCISSOR_BOX, scissorBox );
1932         glRasterPos2i( scissorBox[0], scissorBox[1] );
1933         glBitmap( 0, 0, 0.0, 0.0, 
1934                 originX-scissorBox[0], originY-scissorBox[1], NULL );
1935         */
1936
1937         /* update (cont.): using these two lines instead:
1938          * (based on glaRasterPosSafe2i, but Ken Hughes deserves credit
1939          * for suggesting this exact fix in the bug tracker) */
1940         glRasterPos2i(0, 0);
1941         glBitmap( 0, 0, 0.0, 0.0, originX, originY, NULL );
1942
1943         /* set the zoom */
1944         glPixelZoom( zoomX, zoomY );
1945
1946         /* set the width of the image (ROW_LENGTH), and the offset to the
1947          * clip origin within the image in x (SKIP_PIXELS) and 
1948          * y (SKIP_ROWS) */
1949         glPixelStorei( GL_UNPACK_ROW_LENGTH,  ibuf->x );
1950         glPixelStorei( GL_UNPACK_SKIP_PIXELS, clipX );
1951         glPixelStorei( GL_UNPACK_SKIP_ROWS,   clipY );
1952
1953         /* draw the image */
1954         glDrawPixels( clipW, clipH, GL_RGBA, GL_UNSIGNED_BYTE, 
1955                 ibuf->rect );
1956
1957         /* restore the defaults for some parameters (we could also use a
1958          * glPushClientAttrib() and glPopClientAttrib() pair). */
1959         glPixelZoom( 1.0, 1.0 );
1960         glPixelStorei( GL_UNPACK_SKIP_ROWS,   0 );
1961         glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
1962         glPixelStorei( GL_UNPACK_ROW_LENGTH,  0 );
1963
1964         Py_INCREF( Py_None );
1965         return Py_None;
1966
1967 }
1968
1969 PyObject *Draw_Init( void )
1970 {
1971         PyObject *submodule, *dict;
1972
1973         if( PyType_Ready( &Button_Type) < 0)
1974                 Py_RETURN_NONE;
1975
1976         submodule = Py_InitModule3( "Blender.Draw", Draw_methods, Draw_doc );
1977
1978         dict = PyModule_GetDict( submodule );
1979
1980 #define EXPP_ADDCONST(x) \
1981         EXPP_dict_set_item_str(dict, #x, PyInt_FromLong(x))
1982
1983         /* So, for example:
1984          * EXPP_ADDCONST(LEFTMOUSE) becomes
1985          * EXPP_dict_set_item_str(dict, "LEFTMOUSE", PyInt_FromLong(LEFTMOUSE)) 
1986          */
1987
1988         EXPP_ADDCONST( LEFTMOUSE );
1989         EXPP_ADDCONST( MIDDLEMOUSE );
1990         EXPP_ADDCONST( RIGHTMOUSE );
1991         EXPP_ADDCONST( WHEELUPMOUSE );
1992         EXPP_ADDCONST( WHEELDOWNMOUSE );
1993         EXPP_ADDCONST( MOUSEX );
1994         EXPP_ADDCONST( MOUSEY );
1995         EXPP_ADDCONST( TIMER0 );
1996         EXPP_ADDCONST( TIMER1 );
1997         EXPP_ADDCONST( TIMER2 );
1998         EXPP_ADDCONST( TIMER3 );
1999         EXPP_ADDCONST( KEYBD );
2000         EXPP_ADDCONST( RAWKEYBD );
2001         EXPP_ADDCONST( REDRAW );
2002         EXPP_ADDCONST( INPUTCHANGE );
2003         EXPP_ADDCONST( QFULL );
2004         EXPP_ADDCONST( WINFREEZE );
2005         EXPP_ADDCONST( WINTHAW );
2006         EXPP_ADDCONST( WINCLOSE );
2007         EXPP_ADDCONST( WINQUIT );
2008 #ifndef IRISGL
2009         EXPP_ADDCONST( Q_FIRSTTIME );
2010 #endif
2011         EXPP_ADDCONST( AKEY );
2012         EXPP_ADDCONST( BKEY );
2013         EXPP_ADDCONST( CKEY );
2014         EXPP_ADDCONST( DKEY );
2015         EXPP_ADDCONST( EKEY );
2016         EXPP_ADDCONST( FKEY );
2017         EXPP_ADDCONST( GKEY );
2018         EXPP_ADDCONST( HKEY );
2019         EXPP_ADDCONST( IKEY );
2020         EXPP_ADDCONST( JKEY );
2021         EXPP_ADDCONST( KKEY );
2022         EXPP_ADDCONST( LKEY );
2023         EXPP_ADDCONST( MKEY );
2024         EXPP_ADDCONST( NKEY );
2025         EXPP_ADDCONST( OKEY );
2026         EXPP_ADDCONST( PKEY );
2027         EXPP_ADDCONST( QKEY );
2028         EXPP_ADDCONST( RKEY );
2029         EXPP_ADDCONST( SKEY );
2030         EXPP_ADDCONST( TKEY );
2031         EXPP_ADDCONST( UKEY );
2032         EXPP_ADDCONST( VKEY );
2033         EXPP_ADDCONST( WKEY );
2034         EXPP_ADDCONST( XKEY );
2035         EXPP_ADDCONST( YKEY );
2036         EXPP_ADDCONST( ZKEY );
2037         EXPP_ADDCONST( ZEROKEY );
2038         EXPP_ADDCONST( ONEKEY );
2039         EXPP_ADDCONST( TWOKEY );
2040         EXPP_ADDCONST( THREEKEY );
2041         EXPP_ADDCONST( FOURKEY );
2042         EXPP_ADDCONST( FIVEKEY );
2043         EXPP_ADDCONST( SIXKEY );
2044         EXPP_ADDCONST( SEVENKEY );
2045         EXPP_ADDCONST( EIGHTKEY );
2046         EXPP_ADDCONST( NINEKEY );
2047         EXPP_ADDCONST( CAPSLOCKKEY );
2048         EXPP_ADDCONST( LEFTCTRLKEY );
2049         EXPP_ADDCONST( LEFTALTKEY );
2050         EXPP_ADDCONST( RIGHTALTKEY );
2051         EXPP_ADDCONST( RIGHTCTRLKEY );
2052         EXPP_ADDCONST( RIGHTSHIFTKEY );
2053         EXPP_ADDCONST( LEFTSHIFTKEY );
2054         EXPP_ADDCONST( ESCKEY );
2055         EXPP_ADDCONST( TABKEY );
2056         EXPP_ADDCONST( RETKEY );
2057         EXPP_ADDCONST( SPACEKEY );
2058         EXPP_ADDCONST( LINEFEEDKEY );
2059         EXPP_ADDCONST( BACKSPACEKEY );
2060         EXPP_ADDCONST( DELKEY );
2061         EXPP_ADDCONST( SEMICOLONKEY );
2062         EXPP_ADDCONST( PERIODKEY );
2063         EXPP_ADDCONST( COMMAKEY );
2064         EXPP_ADDCONST( QUOTEKEY );
2065         EXPP_ADDCONST( ACCENTGRAVEKEY );
2066         EXPP_ADDCONST( MINUSKEY );
2067         EXPP_ADDCONST( SLASHKEY );
2068         EXPP_ADDCONST( BACKSLASHKEY );
2069         EXPP_ADDCONST( EQUALKEY );
2070         EXPP_ADDCONST( LEFTBRACKETKEY );
2071         EXPP_ADDCONST( RIGHTBRACKETKEY );
2072         EXPP_ADDCONST( LEFTARROWKEY );
2073         EXPP_ADDCONST( DOWNARROWKEY );
2074         EXPP_ADDCONST( RIGHTARROWKEY );
2075         EXPP_ADDCONST( UPARROWKEY );
2076         EXPP_ADDCONST( PAD2 );
2077         EXPP_ADDCONST( PAD4 );
2078         EXPP_ADDCONST( PAD6 );
2079         EXPP_ADDCONST( PAD8 );
2080         EXPP_ADDCONST( PAD1 );
2081         EXPP_ADDCONST( PAD3 );
2082         EXPP_ADDCONST( PAD5 );
2083         EXPP_ADDCONST( PAD7 );
2084         EXPP_ADDCONST( PAD9 );
2085         EXPP_ADDCONST( PADPERIOD );
2086         EXPP_ADDCONST( PADSLASHKEY );
2087         EXPP_ADDCONST( PADASTERKEY );
2088         EXPP_ADDCONST( PAD0 );
2089         EXPP_ADDCONST( PADMINUS );
2090         EXPP_ADDCONST( PADENTER );
2091         EXPP_ADDCONST( PADPLUSKEY );
2092         EXPP_ADDCONST( F1KEY );
2093         EXPP_ADDCONST( F2KEY );
2094         EXPP_ADDCONST( F3KEY );
2095         EXPP_ADDCONST( F4KEY );
2096         EXPP_ADDCONST( F5KEY );
2097         EXPP_ADDCONST( F6KEY );
2098         EXPP_ADDCONST( F7KEY );
2099         EXPP_ADDCONST( F8KEY );
2100         EXPP_ADDCONST( F9KEY );
2101         EXPP_ADDCONST( F10KEY );
2102         EXPP_ADDCONST( F11KEY );
2103         EXPP_ADDCONST( F12KEY );
2104         EXPP_ADDCONST( PAUSEKEY );
2105         EXPP_ADDCONST( INSERTKEY );
2106         EXPP_ADDCONST( HOMEKEY );
2107         EXPP_ADDCONST( PAGEUPKEY );
2108         EXPP_ADDCONST( PAGEDOWNKEY );
2109         EXPP_ADDCONST( ENDKEY );
2110
2111         return submodule;
2112 }