4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * This is a new part of Blender.
28 * Contributor(s): Willian P. Germano, Campbell Barton
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
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. */
45 #include "BLI_winstuff.h"
48 #include "BLI_blenlib.h"
49 #include "MEM_guardedalloc.h"
53 #include "DNA_screen_types.h"
55 #include "DNA_text_types.h"
57 #include "BKE_global.h"
58 #include "BKE_library.h"
59 #include "BKE_object.h"
62 #include "BIF_screen.h"
63 #include "BIF_space.h"
64 #include "BIF_interface.h"
65 #include "BIF_mywindow.h"
66 #include "BIF_toolbox.h"
68 #include "BPI_script.h" /* script struct */
70 #include "interface.h"
71 #include "mydevice.h" /*@ for all the event constants */
73 /* This one was an extern in BPY_main.h, but only opy_draw.c was using it */
76 /*@ hack to flag that window redraw has happened inside slider callback: */
77 int EXPP_disable_force_draw = 0;
79 /* forward declarations for internal functions */
80 static void Button_dealloc (PyObject *self);
81 static PyObject *Button_getattr (PyObject *self, char *name);
82 static PyObject *Button_repr (PyObject *self);
83 static int Button_setattr (PyObject *self, char *name, PyObject *v);
85 static Button *newbutton (void);
87 /* GUI interface routines */
89 static void exit_pydraw (SpaceScript *sc, short error);
90 static void exec_callback (SpaceScript *sc, PyObject *callback,
92 static void spacescript_do_pywin_buttons (SpaceScript *sc,
93 unsigned short event);
95 static PyObject *Method_Exit (PyObject * self, PyObject * args);
96 static PyObject *Method_Register (PyObject * self, PyObject * args);
97 static PyObject *Method_Redraw (PyObject * self, PyObject * args);
98 static PyObject *Method_Draw (PyObject * self, PyObject * args);
99 static PyObject *Method_Create (PyObject * self, PyObject * args);
101 static PyObject *Method_Button (PyObject * self, PyObject * args);
102 static PyObject *Method_Menu (PyObject * self, PyObject * args);
103 static PyObject *Method_Toggle (PyObject * self, PyObject * args);
104 static PyObject *Method_Slider (PyObject * self, PyObject * args);
105 static PyObject *Method_Scrollbar (PyObject * self, PyObject * args);
106 static PyObject *Method_Number (PyObject * self, PyObject * args);
107 static PyObject *Method_String (PyObject * self, PyObject * args);
108 static PyObject *Method_GetStringWidth (PyObject * self, PyObject * args);
109 static PyObject *Method_Text (PyObject * self, PyObject * args);
110 static PyObject *Method_PupMenu (PyObject * self, PyObject * args);
111 /* next three by Campbell: */
112 static PyObject *Method_PupIntInput (PyObject * self, PyObject * args);
113 static PyObject *Method_PupFloatInput (PyObject * self, PyObject * args);
114 static PyObject *Method_PupStrInput (PyObject * self, PyObject * args);
116 static uiBlock *Get_uiBlock (void);
117 static void py_slider_update (void *butv, void *data2_unused);
119 static char Draw_doc[] = "The Blender.Draw submodule";
121 static char Method_Register_doc[] =
122 "(draw, event, button) - Register callbacks for windowing\n\n\
123 (draw) A function to draw the screen, taking no arguments\n\
124 (event) A function to handle events, taking 2 arguments (evt, val)\n\
125 (evt) The event number\n\
126 (val) The value modifier (for key and mouse press/release)\n\
127 (button) A function to handle button events, taking 1 argument (evt)\n\
128 (evt) The button number\n\n\
129 A None object can be passed if a callback is unused.";
132 static char Method_Redraw_doc[] = "([after]) - Queue a redraw event\n\n\
133 [after=0] Determines whether the redraw is processed before\n\
134 or after other input events.\n\n\
135 Redraw events are buffered so that regardless of how many events\n\
136 are queued the window only receives one redraw event.";
138 static char Method_Draw_doc[] = "() - Force an immediate redraw\n\n\
139 Forced redraws are not buffered, in other words the window is redrawn\n\
140 exactly once for everytime this function is called.";
143 static char Method_Create_doc[] =
144 "(value) - Create a default Button object\n\n\
145 (value) - The value to store in the button\n\n\
146 Valid values are ints, floats, and strings";
148 static char Method_Button_doc[] =
149 "(name, event, x, y, width, height, [tooltip]) - Create a new Button \
151 (name) A string to display on the button\n\
152 (event) The event number to pass to the button event function when activated\n\
153 (x, y) The lower left coordinate of the button\n\
154 (width, height) The button width and height\n\
155 [tooltip=] The button's tooltip\n\n\
156 This function can be called as Button() or PushButton().";
158 static char Method_Menu_doc[] =
159 "(name, event, x, y, width, height, default, [tooltip]) - Create a new Menu \
161 (name) A string to display on the button\n\
162 (event) The event number to pass to the button event function when activated\n\
163 (x, y) The lower left coordinate of the button\n\
164 (width, height) The button width and height\n\
165 (default) The number of the option to be selected by default\n\
166 [tooltip=" "] The button's tooltip\n\n\
167 The menu options are specified through the name of the\n\
168 button. Options are followed by a format code and separated\n\
169 by the '|' (pipe) character.\n\
170 Valid format codes are\n\
171 %t - The option should be used as the title\n\
172 %xN - The option should set the integer N in the button value.";
174 static char Method_Toggle_doc[] =
175 "(name, event, x, y, width, height, default, [tooltip]) - Create a new Toggle \
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 (default) An integer (0 or 1) specifying the default state\n\
182 [tooltip=] The button's tooltip";
185 static char Method_Slider_doc[] =
186 "(name, event, x, y, width, height, initial, min, max, [update, tooltip]) - \
187 Create a new Slider button\n\n\
188 (name) A string to display on the button\n\
189 (event) The event number to pass to the button event function when activated\n\
190 (x, y) The lower left coordinate of the button\n\
191 (width, height) The button width and height\n\
192 (initial, min, max) Three values (int or float) specifying the initial \
194 [update=1] A value controlling whether the slider will emit events as it \
196 A non-zero value (default) enables the events. A zero value supresses them.\n\
197 [tooltip=] The button's tooltip";
200 static char Method_Scrollbar_doc[] =
201 "(event, x, y, width, height, initial, min, max, [update, tooltip]) - Create a \
203 (event) The event number to pass to the button event function when activated\n\
204 (x, y) The lower left coordinate of the button\n\
205 (width, height) The button width and height\n\
206 (initial, min, max) Three values (int or float) specifying the initial and limit values.\n\
207 [update=1] A value controlling whether the slider will emit events as it is edited.\n\
208 A non-zero value (default) enables the events. A zero value supresses them.\n\
209 [tooltip=] The button's tooltip";
211 static char Method_Number_doc[] =
212 "(name, event, x, y, width, height, initial, min, max, [tooltip]) - Create a \
213 new Number button\n\n\
214 (name) A string to display on the button\n\
215 (event) The event number to pass to the button event function when activated\n\
216 (x, y) The lower left coordinate of the button\n\
217 (width, height) The button width and height\n\
218 (initial, min, max) Three values (int or float) specifying the initial and \
220 [tooltip=] The button's tooltip";
222 static char Method_String_doc[] =
223 "(name, event, x, y, width, height, initial, length, [tooltip]) - Create a \
224 new String button\n\n\
225 (name) A string to display on the button\n\
226 (event) The event number to pass to the button event function when activated\n\
227 (x, y) The lower left coordinate of the button\n\
228 (width, height) The button width and height\n\
229 (initial) The string to display initially\n\
230 (length) The maximum input length\n\
231 [tooltip=] The button's tooltip";
233 static char Method_GetStringWidth_doc[] =
234 "(text, font = 'normal') - Return the width in pixels of the given string\n\
235 (font) The font size: 'normal' (default), 'small' or 'tiny'.";
237 static char Method_Text_doc[] =
238 "(text, font = 'normal') - Draw text onscreen\n\n\
239 (text) The text to draw\n\
240 (font) The font size: 'normal' (default), 'small' or 'tiny'.\n\n\
241 This function returns the width of the drawn string.";
243 static char Method_PupMenu_doc[] =
244 "(string, maxrow = None) - Display a pop-up menu at the screen.\n\
245 The contents of the pop-up are specified through the 'string' argument,\n\
246 like with Draw.Menu.\n\
247 'maxrow' is an optional int to control how many rows the pop-up should have.\n\
248 Options are followed by a format code and separated\n\
249 by the '|' (pipe) character.\n\
250 Valid format codes are\n\
251 %t - The option should be used as the title\n\
252 %xN - The option should set the integer N in the button value.\n\n\
253 Ex: Draw.PupMenu('OK?%t|QUIT BLENDER') # should be familiar ...";
255 static char Method_PupIntInput_doc[] =
256 "(text, default, min, max) - Display an int pop-up input.\n\
257 (text) - text string to display on the button;\n\
258 (default, min, max) - the default, min and max int values for the button;\n\
259 Return the user input value or None on user exit";
261 static char Method_PupFloatInput_doc[] =
262 "(text, default, min, max, clickStep, floatLen) - Display a float pop-up input.\n\
263 (text) - text string to display on the button;\n\
264 (default, min, max) - the default, min and max float values for the button;\n\
265 (clickStep) - float increment/decrement for each click on the button arrows;\n\
266 (floatLen) - an integer defining the precision (number of decimal places) of \n\
267 the float value show.\n\
268 Return the user input value or None on user exit";
270 static char Method_PupStrInput_doc[] =
271 "(text, default, max = 20) - Display a float pop-up input.\n\
272 (text) - text string to display on the button;\n\
273 (default) - the initial string to display (truncated to 'max' chars);\n\
274 (max = 20) - The maximum number of chars the user can input;\n\
275 Return the user input value or None on user exit";
277 static char Method_Exit_doc[] = "() - Exit the windowing interface";
280 * here we engage in some macro trickery to define the PyMethodDef table
283 #define _MethodDef(func, prefix) \
284 {#func, prefix##_##func, METH_VARARGS, prefix##_##func##_doc}
286 /* So that _MethodDef(delete, Scene) expands to:
287 * {"delete", Scene_delete, METH_VARARGS, Scene_delete_doc} */
290 #define MethodDef(func) _MethodDef(func, Method)
292 static struct PyMethodDef Draw_methods[] = {
298 MethodDef (Scrollbar),
301 MethodDef (GetStringWidth),
304 MethodDef (PupIntInput),
305 MethodDef (PupFloatInput),
306 MethodDef (PupStrInput),
310 MethodDef (Register),
311 {"PushButton", Method_Button, METH_VARARGS, Method_Button_doc},
315 PyTypeObject Button_Type = {
316 PyObject_HEAD_INIT (NULL) 0, /*ob_size */
317 "Button", /*tp_name */
318 sizeof (Button), /*tp_basicsize */
320 (destructor) Button_dealloc, /*tp_dealloc */
321 (printfunc) 0, /*tp_print */
322 (getattrfunc) Button_getattr, /*tp_getattr */
323 (setattrfunc) Button_setattr, /*tp_setattr */
324 (cmpfunc) 0, /*tp_cmp */
325 (reprfunc) Button_repr, /*tp_repr */
329 static void Button_dealloc (PyObject *self)
331 Button *but = (Button *) self;
333 if (but->type == 3) MEM_freeN (but->val.asstr);
338 static PyObject *Button_getattr (PyObject *self, char *name)
340 Button *but = (Button *) self;
342 if (strcmp (name, "val") == 0) {
344 return Py_BuildValue ("i", but->val.asint);
345 else if (but->type == 2)
346 return Py_BuildValue ("f", but->val.asfloat);
347 else if (but->type == 3)
348 return Py_BuildValue ("s", but->val.asstr);
351 PyErr_SetString (PyExc_AttributeError, name);
355 static int Button_setattr (PyObject *self, char *name, PyObject *v)
357 Button *but = (Button *) self;
359 if (strcmp (name, "val") == 0) {
361 PyArg_Parse (v, "i", &but->val.asint);
362 else if (but->type == 2)
363 PyArg_Parse (v, "f", &but->val.asfloat);
364 else if (but->type == 3) {
366 PyArg_Parse (v, "s", &newstr);
368 /* if the length of the new string is the same as */
369 /* the old one, just copy, else delete and realloc. */
370 if (but->slen == strlen (newstr)) {
371 BLI_strncpy (but->val.asstr, newstr, but->slen);
374 MEM_freeN (but->val.asstr);
375 but->slen = strlen (newstr);
376 but->val.asstr = MEM_mallocN (but->slen + 1, "button setattr");
377 strcpy (but->val.asstr, newstr);
382 PyErr_SetString (PyExc_AttributeError, name);
389 static PyObject *Button_repr (PyObject * self)
391 return PyObject_Repr (Button_getattr (self, "val"));
394 static Button *newbutton (void)
396 Button *but = (Button *) PyObject_NEW (Button, &Button_Type);
401 /* GUI interface routines */
403 static void exit_pydraw (SpaceScript *sc, short err)
405 Script *script = NULL;
407 if (!sc || !sc->script) return;
413 script->flags = 0; /* mark script struct for deletion */
414 error ("Python script error: check console");
415 scrarea_queue_redraw (sc->area);
418 Py_XDECREF ((PyObject *) script->py_draw);
419 Py_XDECREF ((PyObject *) script->py_event);
420 Py_XDECREF ((PyObject *) script->py_button);
422 script->py_draw = script->py_event = script->py_button = NULL;
425 static void exec_callback (SpaceScript *sc, PyObject *callback, PyObject *args)
427 PyObject *result = PyObject_CallObject (callback, args);
429 if (result == NULL && sc->script) {/* errors in the script */
431 if (sc->script->lastspace == SPACE_TEXT) {/*if it can be an ALT+P script */
432 Text *text = G.main->text.first;
434 while (text) {/* find it and free its compiled code */
436 if (!strcmp (text->id.name + 2, sc->script->id.name + 2)) {
437 BPY_free_compiled_text (text);
441 text = text->id.next;
451 /* BPY_spacescript_do_pywin_draw, the static spacescript_do_pywin_buttons and
452 * BPY_spacescript_do_pywin_event are the three functions responsible for
453 * calling the draw, buttons and event callbacks registered with Draw.Register
454 * (see Method_Register below). They are called (only the two BPY_ ones)
455 * from blender/src/drawscript.c */
457 void BPY_spacescript_do_pywin_draw (SpaceScript *sc)
461 Script *script = sc->script;
463 sprintf (butblock, "win %d", curarea->win);
464 block = uiNewBlock (&curarea->uiblocks, butblock, UI_EMBOSSX,
465 UI_HELV, curarea->win);
467 if (script->py_draw) {
468 glPushAttrib (GL_ALL_ATTRIB_BITS);
469 exec_callback (sc, script->py_draw, Py_BuildValue ("()"));
473 glClearColor (0.4375, 0.4375, 0.4375, 0.0);
474 glClear (GL_COLOR_BUFFER_BIT);
479 curarea->win_swap = WIN_BACK_OK;
482 static void spacescript_do_pywin_buttons (SpaceScript *sc, unsigned short event)
484 if (sc->script->py_button)
485 exec_callback (sc, sc->script->py_button, Py_BuildValue ("(i)", event));
488 void BPY_spacescript_do_pywin_event (SpaceScript *sc, unsigned short event,
491 static int menu_hack = 0;
493 /* about menu_hack above: when a menu returns after an entry is chosen,
494 * two events are generated, the second one with val = 4. We don't want
495 * this second one to be passed to Python, because it can be confused with
496 * some event with same number defined by the script.
497 * What we do is set menu_hack to 1 if a button event occurs.
498 * Then if the next one is also a button event, w/ val = 4, we discard it. */
500 if (event != UI_BUT_EVENT || !val) menu_hack = 0;
502 if (event == QKEY && G.qual & (LR_ALTKEY | LR_CTRLKEY)) {
503 /* finish script: user pressed ALT+Q or CONTROL+Q */
504 Script *script = sc->script;
508 script->flags &= ~SCRIPT_GUI; /* we're done with this script */
514 if (uiDoBlocks (&curarea->uiblocks, event) != UI_NOTHING) event = 0;
516 if (event == UI_BUT_EVENT) {
518 if (menu_hack && (val == 4)) { /* "false" event? */
519 menu_hack = 0; /* if so, discard it and clear menu_hack */
523 spacescript_do_pywin_buttons (sc, val);
529 if (sc->script->py_event)
530 exec_callback (sc, sc->script->py_event, Py_BuildValue("(ii)", event, val));
533 static PyObject *Method_Exit (PyObject *self, PyObject *args)
538 /* if users call Draw.Exit when we are already out of the SPACE_SCRIPT, we
539 * simply return, for compatibility */
540 if (curarea->spacetype == SPACE_SCRIPT)
541 sc = curarea->spacedata.first;
543 return EXPP_incr_ret (Py_None);
545 if (!PyArg_ParseTuple (args, ""))
546 return EXPP_ReturnPyObjError (PyExc_AttributeError,
547 "expected empty argument list");
553 /* remove our lock to the current namespace */
554 script->flags &= ~SCRIPT_GUI;
556 return EXPP_incr_ret (Py_None);
559 /* Method_Register (Draw.Register) registers callbacks for drawing, events
560 * and gui button events, so a script can continue executing after the
561 * interpreter reached its end and returned control to Blender. Everytime
562 * the SPACE_SCRIPT window with this script is redrawn, the registered
563 * callbacks are executed. */
564 static PyObject *Method_Register (PyObject *self, PyObject *args)
566 PyObject *newdrawc = NULL, *neweventc = NULL, *newbuttonc = NULL;
571 if (!PyArg_ParseTuple (args, "O|OO", &newdrawc, &neweventc, &newbuttonc))
572 return EXPP_ReturnPyObjError (PyExc_TypeError,
573 "expected one or three PyObjects");
575 if (!PyCallable_Check (newdrawc))
577 if (!PyCallable_Check (neweventc))
579 if (!PyCallable_Check (newbuttonc))
582 if (!(newdrawc || neweventc || newbuttonc))
583 return EXPP_incr_ret (Py_None);
585 startspace = curarea->spacetype;
587 /* first make sure the current area is of type SPACE_SCRIPT */
588 if (startspace != SPACE_SCRIPT)
589 newspace (curarea, SPACE_SCRIPT);
591 sc = curarea->spacedata.first;
593 /* this is a little confusing: we need to know which script is being executed
594 * now, so we can preserve its namespace from being deleted.
595 * There are two possibilities:
596 * a) One new script was created and the interpreter still hasn't returned
598 * b) Any number of scripts were executed but left registered callbacks and
599 * so were not deleted yet. */
601 /* To find out if we're dealing with a) or b), we start with the last
603 script = G.main->script.last;
606 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
607 "Draw.Register: couldn't get pointer to script struct");
610 /* if the flag SCRIPT_RUNNING is set, this script is case a): */
611 if (!(script->flags & SCRIPT_RUNNING)) {
614 /* otherwise it's case b) and the script we want is here: */
618 /* Now we have the right script and can set a lock so its namespace can't be
619 * deleted for as long as we need it */
620 script->flags |= SCRIPT_GUI;
622 /* save the last space so we can go back to it upon finishing */
623 if (!script->lastspace)
624 script->lastspace = startspace;
626 /* clean the old callbacks */
629 /* prepare the new ones and insert them */
630 Py_XINCREF (newdrawc);
631 Py_XINCREF (neweventc);
632 Py_XINCREF (newbuttonc);
634 script->py_draw = newdrawc;
635 script->py_event = neweventc;
636 script->py_button = newbuttonc;
638 scrarea_queue_redraw (sc->area);
640 return EXPP_incr_ret (Py_None);
643 static PyObject *Method_Redraw (PyObject *self, PyObject *args)
647 if (!PyArg_ParseTuple (args, "|i", &after))
648 return EXPP_ReturnPyObjError (PyExc_TypeError,
649 "expected int argument (or nothing)");
651 /* XXX shouldn't we redraw all spacescript wins with this script on ? */
653 addafterqueue (curarea->win, REDRAW, 1);
655 scrarea_queue_winredraw (curarea);
657 return EXPP_incr_ret (Py_None);
660 static PyObject *Method_Draw (PyObject * self, PyObject * args)
662 /*@ If forced drawing is disable queue a redraw event instead */
663 if (EXPP_disable_force_draw) {
664 scrarea_queue_winredraw (curarea);
665 return EXPP_incr_ret (Py_None);
668 if (!PyArg_ParseTuple (args, ""))
669 return EXPP_ReturnPyObjError (PyExc_AttributeError,
670 "expected empty argument list");
672 scrarea_do_windraw (curarea);
674 screen_swapbuffers ();
676 return EXPP_incr_ret (Py_None);
679 static PyObject *Method_Create (PyObject *self, PyObject *args)
684 if (!PyArg_ParseTuple (args, "O", &in))
685 return EXPP_ReturnPyObjError (PyExc_TypeError,
686 "expected PyObject argument");
689 if (PyFloat_Check (in)) {
691 but->val.asfloat = PyFloat_AsDouble (in);
693 else if (PyInt_Check (in)) {
695 but->val.asint = PyInt_AsLong (in);
697 else if (PyString_Check (in)) {
698 char *newstr = PyString_AsString (in);
701 but->slen = strlen (newstr);
702 but->val.asstr = MEM_mallocN (but->slen + 1, "button string");
704 strcpy (but->val.asstr, newstr);
707 return (PyObject *) but;
710 static uiBlock *Get_uiBlock (void)
714 sprintf (butblock, "win %d", curarea->win);
716 return uiGetBlock (butblock, curarea);
719 static PyObject *Method_Button (PyObject *self, PyObject *args)
722 char *name, *tip = NULL;
726 if (!PyArg_ParseTuple (args, "siiiii|s", &name, &event,
727 &x, &y, &w, &h, &tip))
728 return EXPP_ReturnPyObjError (PyExc_TypeError,
729 "expected a string, five ints and optionally another string as arguments");
731 block = Get_uiBlock ();
734 uiDefBut (block, BUT, event, name, x, y, w, h, 0, 0, 0, 0, 0, tip);
736 return EXPP_incr_ret (Py_None);
739 static PyObject *Method_Menu (PyObject *self, PyObject *args)
742 char *name, *tip = NULL;
747 if (!PyArg_ParseTuple (args, "siiiiii|s", &name, &event,
748 &x, &y, &w, &h, &def, &tip))
749 return EXPP_ReturnPyObjError (PyExc_TypeError,
750 "expected a string, six ints and optionally another string as arguments");
754 but->val.asint = def;
756 block = Get_uiBlock ();
758 uiDefButI (block, MENU, event, name, x, y, w, h,
759 &but->val.asint, 0, 0, 0, 0, tip);
761 return (PyObject *) but;
764 static PyObject *Method_Toggle (PyObject *self, PyObject *args)
767 char *name, *tip = NULL;
772 if (!PyArg_ParseTuple (args, "siiiiii|s", &name, &event,
773 &x, &y, &w, &h, &def, &tip))
774 return EXPP_ReturnPyObjError (PyExc_TypeError,
775 "expected a string, six ints and optionally another string as arguments");
779 but->val.asint = def;
781 block = Get_uiBlock ();
783 uiDefButI (block, TOG, event, name, x, y, w, h,
784 &but->val.asint, 0, 0, 0, 0, tip);
786 return (PyObject *) but;
789 /*@DO NOT TOUCH THIS FUNCTION !
790 Redrawing a slider inside its own callback routine is actually forbidden
791 with the current toolkit architecture (button routines are not reentrant).
793 XXX This is condemned to be dinosource in future - it's a hack.
796 static void py_slider_update (void *butv, void *data2_unused)
800 EXPP_disable_force_draw = 1;
802 Disable forced drawing, otherwise the button object which
803 is still being used might be deleted
807 spacetext_do_pywin_buttons(curarea->spacedata.first, but->retval); */
809 g_window_redrawn = 0;
810 curarea->win_swap = WIN_BACK_OK;
811 /* removed global uiFrontBuf (contact ton when this goes wrong here) */
812 spacescript_do_pywin_buttons (curarea->spacedata.first,
813 uiButGetRetVal (but));
815 if (!g_window_redrawn) { /*@ if Redraw already called */
816 disable_where_script (1);
817 M_Window_Redraw (0, Py_BuildValue ("(i)", SPACE_VIEW3D));
818 disable_where_script (0);
821 EXPP_disable_force_draw = 0;
824 static PyObject *Method_Slider (PyObject *self, PyObject *args)
827 char *name, *tip = NULL;
829 int x, y, w, h, realtime = 1;
831 PyObject *mino, *maxo, *inio;
833 if (!PyArg_ParseTuple (args, "siiiiiOOO|is", &name, &event,
834 &x, &y, &w, &h, &inio, &mino, &maxo, &realtime, &tip))
835 return EXPP_ReturnPyObjError (PyExc_TypeError,
836 "expected a string, five ints, three PyObjects\n\
837 and optionally another int and string as arguments");
841 if (PyFloat_Check (inio)) {
844 ini = PyFloat_AsDouble (inio);
845 min = PyFloat_AsDouble (mino);
846 max = PyFloat_AsDouble (maxo);
849 but->val.asfloat = ini;
851 block = Get_uiBlock ();
854 ubut = uiDefButF (block, NUMSLI, event, name, x, y, w, h,
855 &but->val.asfloat, min, max, 0, 0, tip);
857 uiButSetFunc (ubut, py_slider_update, ubut, NULL);
863 ini = PyInt_AsLong (inio);
864 min = PyInt_AsLong (mino);
865 max = PyInt_AsLong (maxo);
868 but->val.asint = ini;
870 block = Get_uiBlock ();
873 ubut = uiDefButI (block, NUMSLI, event, name, x, y, w, h,
874 &but->val.asint, min, max, 0, 0, tip);
876 uiButSetFunc (ubut, py_slider_update, ubut, NULL);
879 return (PyObject *) but;
882 static PyObject *Method_Scrollbar (PyObject *self, PyObject *args)
887 int x, y, w, h, realtime = 1;
889 PyObject *mino, *maxo, *inio;
892 if (!PyArg_ParseTuple (args, "iiiiiOOO|is", &event, &x, &y, &w, &h,
893 &inio, &mino, &maxo, &realtime, &tip))
894 return EXPP_ReturnPyObjError (PyExc_TypeError,
895 "expected five ints, three PyObjects and optionally\n\
896 another int and string as arguments");
898 if (!PyNumber_Check (inio) || !PyNumber_Check (inio)
899 || !PyNumber_Check (inio))
900 return EXPP_ReturnPyObjError (PyExc_AttributeError,
901 "expected numbers for initial, min, and max");
905 if (PyFloat_Check (inio))
910 ini = PyFloat_AsDouble (inio);
911 min = PyFloat_AsDouble (mino);
912 max = PyFloat_AsDouble (maxo);
914 if (but->type == 2) {
915 but->val.asfloat = ini;
916 block = Get_uiBlock ();
919 ubut = uiDefButF (block, SCROLL, event, "", x, y, w, h,
920 &but->val.asfloat, min, max, 0, 0, tip);
922 uiButSetFunc (ubut, py_slider_update, ubut, NULL);
926 but->val.asint = ini;
927 block = Get_uiBlock ();
930 ubut = uiDefButI (block, SCROLL, event, "", x, y, w, h,
931 &but->val.asint, min, max, 0, 0, tip);
933 uiButSetFunc (ubut, py_slider_update, ubut, NULL);
937 return (PyObject *) but;
940 static PyObject *Method_Number (PyObject *self, PyObject *args)
943 char *name, *tip = NULL;
947 PyObject *mino, *maxo, *inio;
949 if (!PyArg_ParseTuple (args, "siiiiiOOO|s", &name, &event,
950 &x, &y, &w, &h, &inio, &mino, &maxo, &tip))
951 return EXPP_ReturnPyObjError (PyExc_TypeError,
952 "expected a string, five ints, three PyObjects and\n\
953 optionally another string as arguments");
957 if (PyFloat_Check (inio)) {
960 ini = PyFloat_AsDouble (inio);
961 min = PyFloat_AsDouble (mino);
962 max = PyFloat_AsDouble (maxo);
965 but->val.asfloat = ini;
967 block = Get_uiBlock ();
969 uiDefButF (block, NUM, event, name, x, y, w, h,
970 &but->val.asfloat, min, max, 0, 0, tip);
975 ini = PyInt_AsLong (inio);
976 min = PyInt_AsLong (mino);
977 max = PyInt_AsLong (maxo);
980 but->val.asint = ini;
982 block = Get_uiBlock ();
984 uiDefButI (block, NUM, event, name, x, y, w, h,
985 &but->val.asint, min, max, 0, 0, tip);
988 return (PyObject *) but;
991 static PyObject *Method_String (PyObject *self, PyObject *args)
994 char *name, *tip = NULL, *newstr;
999 if (!PyArg_ParseTuple (args, "siiiiisi|s", &name, &event,
1000 &x, &y, &w, &h, &newstr, &len, &tip))
1001 return EXPP_ReturnPyObjError (PyExc_TypeError,
1002 "expected a string, five ints, a string, an int and\n\
1003 optionally another string as arguments");
1008 but->val.asstr = MEM_mallocN (len + 1, "button string");
1010 strncpy (but->val.asstr, newstr, len);
1011 but->val.asstr[len] = 0;
1013 block = Get_uiBlock ();
1015 uiDefBut (block, TEX, event, name, x, y, w, h,
1016 but->val.asstr, 0, len, 0, 0, tip);
1018 return (PyObject *) but;
1021 static PyObject *Method_GetStringWidth (PyObject *self, PyObject *args)
1024 char *font_str = "normal";
1025 struct BMF_Font *font;
1028 if (!PyArg_ParseTuple (args, "s|s", &text, &font_str))
1029 return EXPP_ReturnPyObjError (PyExc_TypeError,
1030 "expected one or two string arguments");
1032 if (!strcmp (font_str, "normal"))
1034 else if (!strcmp (font_str, "small"))
1036 else if (!strcmp (font_str, "tiny"))
1037 font = (&G)->fontss;
1039 return EXPP_ReturnPyObjError (PyExc_AttributeError,
1040 "\"font\" must be: 'normal' (default), 'small' or 'tiny'.");
1042 width = PyInt_FromLong (BMF_GetStringWidth (font, text));
1045 return EXPP_ReturnPyObjError (PyExc_MemoryError, "couldn't create PyInt");
1050 static PyObject *Method_Text (PyObject *self, PyObject *args)
1053 char *font_str = NULL;
1054 struct BMF_Font *font;
1056 if (!PyArg_ParseTuple (args, "s|s", &text, &font_str))
1057 return EXPP_ReturnPyObjError (PyExc_TypeError,
1058 "expected one or two string arguments");
1062 else if (!strcmp (font_str, "normal"))
1064 else if (!strcmp (font_str, "small"))
1066 else if (!strcmp (font_str, "tiny"))
1067 font = (&G)->fontss;
1069 return EXPP_ReturnPyObjError (PyExc_AttributeError,
1070 "\"font\" must be: 'normal' (default), 'small' or 'tiny'.");
1072 BMF_DrawString (font, text);
1074 return PyInt_FromLong (BMF_GetStringWidth (font, text));
1077 static PyObject *Method_PupMenu (PyObject *self, PyObject *args)
1083 if (!PyArg_ParseTuple (args, "s|i", &text, &maxrow))
1084 return EXPP_ReturnPyObjError (PyExc_TypeError,
1085 "expected a string and optionally an int as arguments");
1088 ret = PyInt_FromLong (pupmenu_col (text, maxrow));
1090 ret = PyInt_FromLong (pupmenu (text));
1092 if (ret) return ret;
1094 return EXPP_ReturnPyObjError (PyExc_MemoryError, "couldn't create a PyInt");
1097 static PyObject *Method_PupIntInput (PyObject *self, PyObject *args)
1100 int min = 0, max = 1;
1102 PyObject *ret = NULL;
1104 if (!PyArg_ParseTuple (args, "s|hii", &text, &var, &min, &max))
1105 return EXPP_ReturnPyObjError (PyExc_TypeError,
1106 "expected 1 string and 3 int arguments");
1108 if (button(&var, min, max, text) == 0) {
1112 ret = PyInt_FromLong (var);
1113 if (ret) return ret;
1115 return EXPP_ReturnPyObjError (PyExc_MemoryError, "couldn't create a PyInt");
1118 static PyObject *Method_PupFloatInput (PyObject *self, PyObject *args)
1121 float min = 0, max = 1, var = 0, a1 = 10, a2 = 2;
1122 PyObject *ret = NULL;
1124 if (!PyArg_ParseTuple (args, "s|fffff", &text, &var, &min, &max, &a1, &a2))
1125 return EXPP_ReturnPyObjError (PyExc_TypeError,
1126 "expected 1 string and 5 float arguments");
1128 if(fbutton(&var, min, max, a1, a2, text)==0) {
1132 ret = PyFloat_FromDouble (var);
1133 if (ret) return ret;
1135 return EXPP_ReturnPyObjError (PyExc_MemoryError, "couldn't create a PyFloat");
1138 static PyObject *Method_PupStrInput (PyObject *self, PyObject *args)
1140 char *text = NULL, *textMsg = NULL;
1143 PyObject *ret = NULL;
1145 if (!PyArg_ParseTuple (args, "ss|b", &textMsg, &text, &max))
1146 return EXPP_ReturnPyObjError (PyExc_TypeError,
1147 "expected 2 strings and 1 int");
1149 if ((max <= 0) || (max > 100))
1150 return EXPP_ReturnPyObjError (PyExc_AttributeError,
1151 "max string length value must be in the range [1, 100].");
1153 /* copying the text string handles both cases:
1154 * max < strlen(text) (by truncating) and
1155 * max > strlen(text) (by expanding to strlen(tmp)) */
1156 BLI_strncpy(tmp, text, max);
1158 if (sbutton (tmp, 0, max, textMsg) == 0) {
1159 Py_INCREF (Py_None);
1163 ret = Py_BuildValue ("s", tmp);
1165 if (ret) return ret;
1167 return EXPP_ReturnPyObjError(PyExc_MemoryError, "couldn't create a PyString");
1171 PyObject *Draw_Init (void)
1173 PyObject *submodule, *dict;
1175 Button_Type.ob_type = &PyType_Type;
1177 submodule = Py_InitModule3 ("Blender.Draw", Draw_methods, Draw_doc);
1179 dict = PyModule_GetDict (submodule);
1181 #define EXPP_ADDCONST(x) \
1182 PyDict_SetItemString(dict, #x, PyInt_FromLong(x))
1185 * EXPP_ADDCONST(LEFTMOUSE) becomes
1186 * PyDict_SetItemString(dict, "LEFTMOUSE", PyInt_FromLong(LEFTMOUSE))
1189 EXPP_ADDCONST (LEFTMOUSE);
1190 EXPP_ADDCONST (MIDDLEMOUSE);
1191 EXPP_ADDCONST (RIGHTMOUSE);
1192 EXPP_ADDCONST (MOUSEX);
1193 EXPP_ADDCONST (MOUSEY);
1194 EXPP_ADDCONST (TIMER0);
1195 EXPP_ADDCONST (TIMER1);
1196 EXPP_ADDCONST (TIMER2);
1197 EXPP_ADDCONST (TIMER3);
1198 EXPP_ADDCONST (KEYBD);
1199 EXPP_ADDCONST (RAWKEYBD);
1200 EXPP_ADDCONST (REDRAW);
1201 EXPP_ADDCONST (INPUTCHANGE);
1202 EXPP_ADDCONST (QFULL);
1203 EXPP_ADDCONST (WINFREEZE);
1204 EXPP_ADDCONST (WINTHAW);
1205 EXPP_ADDCONST (WINCLOSE);
1206 EXPP_ADDCONST (WINQUIT);
1208 EXPP_ADDCONST (Q_FIRSTTIME);
1210 EXPP_ADDCONST (AKEY);
1211 EXPP_ADDCONST (BKEY);
1212 EXPP_ADDCONST (CKEY);
1213 EXPP_ADDCONST (DKEY);
1214 EXPP_ADDCONST (EKEY);
1215 EXPP_ADDCONST (FKEY);
1216 EXPP_ADDCONST (GKEY);
1217 EXPP_ADDCONST (HKEY);
1218 EXPP_ADDCONST (IKEY);
1219 EXPP_ADDCONST (JKEY);
1220 EXPP_ADDCONST (KKEY);
1221 EXPP_ADDCONST (LKEY);
1222 EXPP_ADDCONST (MKEY);
1223 EXPP_ADDCONST (NKEY);
1224 EXPP_ADDCONST (OKEY);
1225 EXPP_ADDCONST (PKEY);
1226 EXPP_ADDCONST (QKEY);
1227 EXPP_ADDCONST (RKEY);
1228 EXPP_ADDCONST (SKEY);
1229 EXPP_ADDCONST (TKEY);
1230 EXPP_ADDCONST (UKEY);
1231 EXPP_ADDCONST (VKEY);
1232 EXPP_ADDCONST (WKEY);
1233 EXPP_ADDCONST (XKEY);
1234 EXPP_ADDCONST (YKEY);
1235 EXPP_ADDCONST (ZKEY);
1236 EXPP_ADDCONST (ZEROKEY);
1237 EXPP_ADDCONST (ONEKEY);
1238 EXPP_ADDCONST (TWOKEY);
1239 EXPP_ADDCONST (THREEKEY);
1240 EXPP_ADDCONST (FOURKEY);
1241 EXPP_ADDCONST (FIVEKEY);
1242 EXPP_ADDCONST (SIXKEY);
1243 EXPP_ADDCONST (SEVENKEY);
1244 EXPP_ADDCONST (EIGHTKEY);
1245 EXPP_ADDCONST (NINEKEY);
1246 EXPP_ADDCONST (CAPSLOCKKEY);
1247 EXPP_ADDCONST (LEFTCTRLKEY);
1248 EXPP_ADDCONST (LEFTALTKEY);
1249 EXPP_ADDCONST (RIGHTALTKEY);
1250 EXPP_ADDCONST (RIGHTCTRLKEY);
1251 EXPP_ADDCONST (RIGHTSHIFTKEY);
1252 EXPP_ADDCONST (LEFTSHIFTKEY);
1253 EXPP_ADDCONST (ESCKEY);
1254 EXPP_ADDCONST (TABKEY);
1255 EXPP_ADDCONST (RETKEY);
1256 EXPP_ADDCONST (SPACEKEY);
1257 EXPP_ADDCONST (LINEFEEDKEY);
1258 EXPP_ADDCONST (BACKSPACEKEY);
1259 EXPP_ADDCONST (DELKEY);
1260 EXPP_ADDCONST (SEMICOLONKEY);
1261 EXPP_ADDCONST (PERIODKEY);
1262 EXPP_ADDCONST (COMMAKEY);
1263 EXPP_ADDCONST (QUOTEKEY);
1264 EXPP_ADDCONST (ACCENTGRAVEKEY);
1265 EXPP_ADDCONST (MINUSKEY);
1266 EXPP_ADDCONST (SLASHKEY);
1267 EXPP_ADDCONST (BACKSLASHKEY);
1268 EXPP_ADDCONST (EQUALKEY);
1269 EXPP_ADDCONST (LEFTBRACKETKEY);
1270 EXPP_ADDCONST (RIGHTBRACKETKEY);
1271 EXPP_ADDCONST (LEFTARROWKEY);
1272 EXPP_ADDCONST (DOWNARROWKEY);
1273 EXPP_ADDCONST (RIGHTARROWKEY);
1274 EXPP_ADDCONST (UPARROWKEY);
1275 EXPP_ADDCONST (PAD2);
1276 EXPP_ADDCONST (PAD4);
1277 EXPP_ADDCONST (PAD6);
1278 EXPP_ADDCONST (PAD8);
1279 EXPP_ADDCONST (PAD1);
1280 EXPP_ADDCONST (PAD3);
1281 EXPP_ADDCONST (PAD5);
1282 EXPP_ADDCONST (PAD7);
1283 EXPP_ADDCONST (PAD9);
1284 EXPP_ADDCONST (PADPERIOD);
1285 EXPP_ADDCONST (PADSLASHKEY);
1286 EXPP_ADDCONST (PADASTERKEY);
1287 EXPP_ADDCONST (PAD0);
1288 EXPP_ADDCONST (PADMINUS);
1289 EXPP_ADDCONST (PADENTER);
1290 EXPP_ADDCONST (PADPLUSKEY);
1291 EXPP_ADDCONST (F1KEY);
1292 EXPP_ADDCONST (F2KEY);
1293 EXPP_ADDCONST (F3KEY);
1294 EXPP_ADDCONST (F4KEY);
1295 EXPP_ADDCONST (F5KEY);
1296 EXPP_ADDCONST (F6KEY);
1297 EXPP_ADDCONST (F7KEY);
1298 EXPP_ADDCONST (F8KEY);
1299 EXPP_ADDCONST (F9KEY);
1300 EXPP_ADDCONST (F10KEY);
1301 EXPP_ADDCONST (F11KEY);
1302 EXPP_ADDCONST (F12KEY);
1303 EXPP_ADDCONST (PAUSEKEY);
1304 EXPP_ADDCONST (INSERTKEY);
1305 EXPP_ADDCONST (HOMEKEY);
1306 EXPP_ADDCONST (PAGEUPKEY);
1307 EXPP_ADDCONST (PAGEDOWNKEY);
1308 EXPP_ADDCONST (ENDKEY);