Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2008-02-15 19:08:41 +0300
committerCampbell Barton <ideasman42@gmail.com>2008-02-15 19:08:41 +0300
commit11c926b57501d37dd7ac5fe1a313d598912962ca (patch)
treec048fe4d0b8f79e4811514ad3ffbee1aa92a711e
parent5e9457b5e2450a6d45393b88454ac51710d12cf5 (diff)
Python api addition PupTreeMenu() - for apricot
-rw-r--r--source/blender/include/BIF_toolbox.h8
-rw-r--r--source/blender/python/api2_2x/Draw.c100
-rw-r--r--source/blender/python/api2_2x/doc/Draw.py17
-rw-r--r--source/blender/src/interface.c6
-rw-r--r--source/blender/src/toolbox.c54
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, &current_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);
+}