[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13705] trunk/blender/source/blender: Python api addition PupTreeMenu() - for apricot

Campbell Barton ideasman42 at gmail.com
Fri Feb 15 17:08:41 CET 2008


Revision: 13705
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13705
Author:   campbellbarton
Date:     2008-02-15 17:08:41 +0100 (Fri, 15 Feb 2008)

Log Message:
-----------
Python api addition PupTreeMenu() - for apricot

Modified Paths:
--------------
    trunk/blender/source/blender/include/BIF_toolbox.h
    trunk/blender/source/blender/python/api2_2x/Draw.c
    trunk/blender/source/blender/python/api2_2x/doc/Draw.py
    trunk/blender/source/blender/src/interface.c
    trunk/blender/source/blender/src/toolbox.c

Modified: trunk/blender/source/blender/include/BIF_toolbox.h
===================================================================
--- trunk/blender/source/blender/include/BIF_toolbox.h	2008-02-15 15:29:43 UTC (rev 13704)
+++ trunk/blender/source/blender/include/BIF_toolbox.h	2008-02-15 16:08:41 UTC (rev 13705)
@@ -65,4 +65,12 @@
 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

Modified: trunk/blender/source/blender/python/api2_2x/Draw.c
===================================================================
--- trunk/blender/source/blender/python/api2_2x/Draw.c	2008-02-15 15:29:43 UTC (rev 13704)
+++ trunk/blender/source/blender/python/api2_2x/Draw.c	2008-02-15 16:08:41 UTC (rev 13705)
@@ -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_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 @@
 	%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 @@
 	{"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 @@
 				      "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;

Modified: trunk/blender/source/blender/python/api2_2x/doc/Draw.py
===================================================================
--- trunk/blender/source/blender/python/api2_2x/doc/Draw.py	2008-02-15 15:29:43 UTC (rev 13704)
+++ trunk/blender/source/blender/python/api2_2x/doc/Draw.py	2008-02-15 16:08:41 UTC (rev 13705)
@@ -353,6 +353,23 @@
 	@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.

Modified: trunk/blender/source/blender/src/interface.c
===================================================================
--- trunk/blender/source/blender/src/interface.c	2008-02-15 15:29:43 UTC (rev 13704)
+++ trunk/blender/source/blender/src/interface.c	2008-02-15 16:08:41 UTC (rev 13705)
@@ -637,7 +637,7 @@
 			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 @@
 	UIafterfunc_arg1= but->butm_func_arg;
 	UIafterval= but->a2;
 	
+	uibut_do_func(but);
+	
 	return but->retval;
 }
 
@@ -6277,7 +6279,7 @@
 	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;

Modified: trunk/blender/source/blender/src/toolbox.c
===================================================================
--- trunk/blender/source/blender/src/toolbox.c	2008-02-15 15:29:43 UTC (rev 13704)
+++ trunk/blender/source/blender/src/toolbox.c	2008-02-15 16:08:41 UTC (rev 13705)
@@ -764,13 +764,6 @@
 #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 @@
 		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);
+}





More information about the Bf-blender-cvs mailing list