diff options
author | Campbell Barton <ideasman42@gmail.com> | 2008-02-15 19:08:41 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2008-02-15 19:08:41 +0300 |
commit | 11c926b57501d37dd7ac5fe1a313d598912962ca (patch) | |
tree | c048fe4d0b8f79e4811514ad3ffbee1aa92a711e /source | |
parent | 5e9457b5e2450a6d45393b88454ac51710d12cf5 (diff) |
Python api addition PupTreeMenu() - for apricot
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/include/BIF_toolbox.h | 8 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Draw.c | 100 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Draw.py | 17 | ||||
-rw-r--r-- | source/blender/src/interface.c | 6 | ||||
-rw-r--r-- | source/blender/src/toolbox.c | 54 |
5 files changed, 175 insertions, 10 deletions
diff --git a/source/blender/include/BIF_toolbox.h b/source/blender/include/BIF_toolbox.h index 72867cbfa05..523345a115d 100644 --- a/source/blender/include/BIF_toolbox.h +++ b/source/blender/include/BIF_toolbox.h @@ -65,4 +65,12 @@ void replace_names_but (void); void BIF_screendump(int fscreen); void write_screendump(char *name); +typedef struct TBitem { + int icon; + char *name; + int retval; + void *poin; +} TBitem; +void toolbox_generic( struct TBitem *generic_menu ); /* for external toolbox - python only for now */ + #endif diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c index 621c72efc2a..8f79d63ddb6 100644 --- a/source/blender/python/api2_2x/Draw.c +++ b/source/blender/python/api2_2x/Draw.c @@ -1,5 +1,5 @@ /* - * $Id: Draw.c 12893 2007-12-15 18:24:16Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -124,6 +124,7 @@ static PyObject *Method_Text( PyObject * self, PyObject * args ); static PyObject *Method_Label( PyObject * self, PyObject * args ); /* by Campbell: */ static PyObject *Method_PupMenu( PyObject * self, PyObject * args ); +static PyObject *Method_PupTreeMenu( PyObject * self, PyObject * args ); static PyObject *Method_PupIntInput( PyObject * self, PyObject * args ); static PyObject *Method_PupFloatInput( PyObject * self, PyObject * args ); static PyObject *Method_PupStrInput( PyObject * self, PyObject * args ); @@ -308,6 +309,9 @@ Valid format codes are\n\ %xN - The option should set the integer N in the button value.\n\n\ Ex: Draw.PupMenu('OK?%t|QUIT BLENDER') # should be familiar ..."; +static char Method_PupTreeMenu_doc[] = +"each item in the menu list should be - (str, event), separator - None or submenu - (str, [...])."; + static char Method_PupIntInput_doc[] = "(text, default, min, max) - Display an int pop-up input.\n\ (text) - text string to display on the button;\n\ @@ -378,6 +382,7 @@ static struct PyMethodDef Draw_methods[] = { {"Text", (PyCFunction)Method_Text, METH_VARARGS, Method_Text_doc}, {"Label", (PyCFunction)Method_Label, METH_VARARGS, Method_Label_doc}, {"PupMenu", (PyCFunction)Method_PupMenu, METH_VARARGS, Method_PupMenu_doc}, + {"PupTreeMenu", (PyCFunction)Method_PupTreeMenu, METH_VARARGS, Method_PupTreeMenu_doc}, {"PupIntInput", (PyCFunction)Method_PupIntInput, METH_VARARGS, Method_PupIntInput_doc}, {"PupFloatInput", (PyCFunction)Method_PupFloatInput, METH_VARARGS, Method_PupFloatInput_doc}, {"PupStrInput", (PyCFunction)Method_PupStrInput, METH_VARARGS, Method_PupStrInput_doc}, @@ -1723,6 +1728,99 @@ static PyObject *Method_PupMenu( PyObject * self, PyObject * args ) "couldn't create a PyInt" ); } +static int current_menu_ret; +static void toolbox_event(void *arg, int event) +{ + current_menu_ret = event; +} + +static TBitem * menu_from_pylist( PyObject * current_menu, ListBase *storage ) +{ + TBitem *tbarray, *tbitem; + Link *link; + PyObject *item, *submenu; + int size, i; + + char *menutext; + int event; + + size = PyList_Size( current_menu ); + + link= MEM_callocN(sizeof(Link) + sizeof(TBitem)*(size+1), "python menu"); + + if (link==NULL) { + PyErr_SetString( PyExc_MemoryError, "Could not allocate enough memory for the menu" ); + BLI_freelistN(storage); + return NULL; + } + + BLI_addtail(storage, link); + + tbarray = tbitem = (TBitem *)(link+1); + + for (i=0; i<size; i++, tbitem++) { + /* need to get these in */ + item = PyList_GET_ITEM( current_menu, i); + + if (item == Py_None) { + tbitem->name = "SEPR"; + } else if( PyArg_ParseTuple( item, "si", &menutext, &event ) ) { + tbitem->name = menutext; + tbitem->retval = event; + //current_menu_index + } else if( PyArg_ParseTuple( item, "sO!", &menutext, &PyList_Type, &submenu ) ) { + PyErr_Clear(); /* from PyArg_ParseTuple above */ + tbitem->name = menutext; + tbitem->poin = menu_from_pylist(submenu, storage); + if (tbitem->poin == NULL) { + BLI_freelistN(storage); + return NULL; /* error should be set */ + } + } else { + PyErr_Clear(); /* from PyArg_ParseTuple above */ + + PyErr_SetString( PyExc_TypeError, "Expected a list of name,event tuples, None, or lists for submenus" ); + BLI_freelistN(storage); + return NULL; + } + } + tbitem->icon= -1; /* end signal */ + tbitem->name= ""; + tbitem->retval= 0; + tbitem->poin= toolbox_event; + + return tbarray; +} + +static PyObject *Method_PupTreeMenu( PyObject * self, PyObject * args ) +{ + PyObject * current_menu; + ListBase storage = {NULL, NULL}; + TBitem *tb; + + if( !PyArg_ParseTuple( args, "O!", &PyList_Type, ¤t_menu ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "Expected a list" ); + + mywinset(G.curscreen->mainwin); // we go to screenspace + + tb = menu_from_pylist(current_menu, &storage); + + if (!tb) { + /* Error is set */ + return NULL; + } + + current_menu_ret = -1; + toolbox_generic(tb); + + /* free all dynamic entries... */ + BLI_freelistN(&storage); + + mywinset(curarea->win); + return PyInt_FromLong( current_menu_ret ); /* current_menu_ret is set by toolbox_event callback */ +} + static PyObject *Method_PupIntInput( PyObject * self, PyObject * args ) { char *text = NULL; diff --git a/source/blender/python/api2_2x/doc/Draw.py b/source/blender/python/api2_2x/doc/Draw.py index 9b6f29b6b51..9d4f2372462 100644 --- a/source/blender/python/api2_2x/doc/Draw.py +++ b/source/blender/python/api2_2x/doc/Draw.py @@ -353,6 +353,23 @@ def PupMenu(name, maxrow = None): @return: the chosen entry number or -1 if none was chosen. """ +def PupTreeMenu( menu ): + """ + Create a popup menu tree. + + Each item in the list is a menu item - (str, event), separator - None or submenu - (str, [...]). + + Submenus list uses the same syntax as the menu list. + + Example:: + result = Draw.PupTreeMenu( [ ("Menu Item 1", 10), ("Menu Item 2", 12), ("SubMenu", [("Menu Item 3", 100), ("MenuItem4", 101) ] ) ] ) + + @type menu: string + @param menu: A menu list + @rtype: int + @return: the chosen entry number or -1 if none was chosen. + """ + def PupIntInput(text, default, min, max): """ Create an integer number input pop-up. diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index a17e488ef13..daff1a29011 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -637,7 +637,7 @@ void uiBoundsBlock(uiBlock *block, int addval) if(bt->x1 < block->minx) block->minx= bt->x1; if(bt->y1 < block->miny) block->miny= bt->y1; - if(bt->x2 > block->maxx) block->maxx= bt->x2; + if(bt->x2 > block->maxx) block->maxx= bt->x2; if(bt->y2 > block->maxy) block->maxy= bt->y2; bt= bt->next; @@ -2693,6 +2693,8 @@ static int ui_do_but_BUTM(uiBut *but) UIafterfunc_arg1= but->butm_func_arg; UIafterval= but->a2; + uibut_do_func(but); + return but->retval; } @@ -6277,7 +6279,7 @@ int uiButGetRetVal(uiBut *but) return but->retval; } - +/* Call this function BEFORE adding buttons to the block */ void uiBlockSetButmFunc(uiBlock *block, void (*menufunc)(void *arg, int event), void *arg) { block->butm_func= menufunc; diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c index 1ad355b5e81..0db63c787ae 100644 --- a/source/blender/src/toolbox.c +++ b/source/blender/src/toolbox.c @@ -764,13 +764,6 @@ ListBase tb_listb= {NULL, NULL}; #define TB_PAD 2048 #define TB_SHIFT 4096 -typedef struct TBitem { - int icon; - char *name; - int retval; - void *poin; -} TBitem; - static void tb_do_hotkey(void *arg, int event) { unsigned short i, key=0; @@ -2267,3 +2260,50 @@ void reset_toolbox(void) tb_mainy= -5; } } + +/* general toolbox for python access */ +void toolbox_generic( TBitem *generic_menu ) +{ + uiBlock *block; + uiBut *but; + TBitem *menu; + int dx=96; + short event, mval[2], tot=0; + long ypos = -5; + + tb_mainx= -32; + tb_mainy= -5; + + mywinset(G.curscreen->mainwin); // we go to screenspace + + block= uiNewBlock(&tb_listb, "toolbox", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1); + uiBlockSetCol(block, TH_MENU_ITEM); + + getmouseco_sc(mval); + + menu= generic_menu; + while(menu->icon != -1) menu++; + uiBlockSetButmFunc(block, menu->poin, NULL); + + /* Add the menu */ + for (menu = generic_menu; menu->icon != -1; menu++) { + if (menu->poin) { + but=uiDefIconTextBlockBut(block, tb_makemenu, menu->poin, ICON_RIGHTARROW_THIN, menu->name, mval[0]+tb_mainx,mval[1]+tb_mainy+ypos+5, dx, 19, ""); + uiButSetFlag(but, UI_MAKE_RIGHT); + + uiButSetFunc(but, store_main, (void *)+32, (void *)ypos); + } else { + /* TODO - add icon support */ + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, menu->name, mval[0]+tb_mainx,mval[1]+tb_mainy+ypos+5, dx, 19, NULL, 0.0, 0.0, 0, menu->retval, ""); + } + ypos-=20; + } + + uiBlockSetButmFunc(block, menu->poin, NULL); + + uiBoundsBlock(block, 2); + event= uiDoBlocks(&tb_listb, 0, 1); + + mywinset(curarea->win); +} |