[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [18672] branches/blender2.5/blender/source /blender: 2.5

Ton Roosendaal ton at blender.org
Sun Jan 25 21:22:07 CET 2009


Revision: 18672
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=18672
Author:   ton
Date:     2009-01-25 21:22:05 +0100 (Sun, 25 Jan 2009)

Log Message:
-----------
2.5

Simple toolbox-style menu system. Brecht will review it
though, and/or check on way to use it for menus.
I tried to avoid uiBlock and rna stuff all over. :)

Quick image test:
http://www.blender.org/bf/rt.jpg

Examples you can read in:
- editors/screen/screen_ops.c:testing123() (press F5)
- editors/object/object_edit.c:object_add_primitive_invoke()
  (press SHIFT+A)

Concept is simple:

uiMenuBegin(): returns a handle.
uiMenuEnd(): puts it all to work.

In between you can add items like:

uiMenuItemVal(): a name, icon, retval (use uiMenuFunc()) 
uiMenuItemO(): an operator + icon
uiMenuItemEnumO(): an operator, property name, value

Sublevels go easy too:

uiMenuLevel(): creates item for sublevel, with function pointer.
     Inside that function you can use all menu calls again.
     Levels can go as deep you want.

uiMenuLevelEnumO(): creates operator sublevel for an enum

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/blenkernel/intern/screen.c
    branches/blender2.5/blender/source/blender/editors/include/UI_interface.h
    branches/blender2.5/blender/source/blender/editors/interface/interface.c
    branches/blender2.5/blender/source/blender/editors/interface/interface_handlers.c
    branches/blender2.5/blender/source/blender/editors/interface/interface_regions.c
    branches/blender2.5/blender/source/blender/editors/mesh/mesh_ops.c
    branches/blender2.5/blender/source/blender/editors/object/object_edit.c
    branches/blender2.5/blender/source/blender/editors/object/object_intern.h
    branches/blender2.5/blender/source/blender/editors/object/object_ops.c
    branches/blender2.5/blender/source/blender/editors/screen/screen_ops.c

Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/screen.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/screen.c	2009-01-25 17:49:39 UTC (rev 18671)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/screen.c	2009-01-25 20:22:05 UTC (rev 18672)
@@ -222,13 +222,14 @@
 		
 		if(art && art->free)
 			art->free(ar);
+		
+		if(ar->regiondata)
+			printf("regiondata free error\n");
 	}
 	else if(ar->type && ar->type->free)
 		ar->type->free(ar);
 
 	if(ar) {
-		if(ar->regiondata)
-			printf("regiondata free error\n");
 		BLI_freelistN(&ar->panels);
 	}
 }

Modified: branches/blender2.5/blender/source/blender/editors/include/UI_interface.h
===================================================================
--- branches/blender2.5/blender/source/blender/editors/include/UI_interface.h	2009-01-25 17:49:39 UTC (rev 18671)
+++ branches/blender2.5/blender/source/blender/editors/include/UI_interface.h	2009-01-25 20:22:05 UTC (rev 18672)
@@ -219,6 +219,23 @@
 void uiPupmenuError(struct bContext *C, char *str, ...);
 void uiPupmenuReports(struct bContext *C, struct ReportList *reports);
 
+/* Custom popup menus and toolbox */
+typedef struct uiMenuItem uiMenuItem;
+
+uiMenuItem *uiMenuBegin(const char *title);
+
+void uiMenuFunc(uiMenuItem *head, void (*eventfunc)(struct bContext *, void *, int), void *argv);
+void uiMenuContext(uiMenuItem *head, int opcontext);
+
+void uiMenuItemVal(uiMenuItem *head, const char *name, int icon, int argval);
+void uiMenuItemEnumO(uiMenuItem *head, char *opname, char *propname, int value);
+void uiMenuItemsEnumO(uiMenuItem *head, char *opname, char *propname);
+void uiMenuItemO(uiMenuItem *head, char *name, int icon);
+void uiMenuLevel(uiMenuItem *head, const char *name, void (*newlevel)(uiMenuItem *));
+void uiMenuLevelEnumO(uiMenuItem *head, char *opname, char *propname);
+
+void uiMenuEnd(struct bContext *C, struct uiMenuItem *head);
+
 /* Block */
 
 uiBlock *uiBeginBlock(const struct bContext *C, struct ARegion *region, char *name, short dt, short font);

Modified: branches/blender2.5/blender/source/blender/editors/interface/interface.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/interface/interface.c	2009-01-25 17:49:39 UTC (rev 18671)
+++ branches/blender2.5/blender/source/blender/editors/interface/interface.c	2009-01-25 20:22:05 UTC (rev 18672)
@@ -486,7 +486,8 @@
 
 	/* XXX bounds? */
 	for(but=block->buttons.first; but; but=but->next) {
-		if(but->opname) {
+		/* only hotkey for menus without properties */
+		if(but->opname && but->opptr==NULL) {
 			if(WM_key_event_operator_string(C, but->opname, but->opcontext, buf, sizeof(buf))) {
 				butstr= MEM_mallocN(strlen(but->str)+strlen(buf)+2, "menu_block_set_keymaps");
 				strcpy(butstr, but->str);

Modified: branches/blender2.5/blender/source/blender/editors/interface/interface_handlers.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/interface/interface_handlers.c	2009-01-25 17:49:39 UTC (rev 18671)
+++ branches/blender2.5/blender/source/blender/editors/interface/interface_handlers.c	2009-01-25 20:22:05 UTC (rev 18672)
@@ -3340,12 +3340,12 @@
 						but= ui_but_find_activated(ar);
 						if(but) {
 							if(ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) {
-								if(block->direction & UI_DOWN) but= ui_but_next(but);
-								else but= ui_but_prev(but);
+								if(block->direction & UI_TOP) but= ui_but_prev(but);
+								else but= ui_but_next(but);
 							}
 							else {
-								if(block->direction & UI_DOWN) but= ui_but_prev(but);
-								else but= ui_but_next(but);
+								if(block->direction & UI_TOP) but= ui_but_next(but);
+								else but= ui_but_prev(but);
 							}
 
 							if(but)

Modified: branches/blender2.5/blender/source/blender/editors/interface/interface_regions.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/interface/interface_regions.c	2009-01-25 17:49:39 UTC (rev 18671)
+++ branches/blender2.5/blender/source/blender/editors/interface/interface_regions.c	2009-01-25 20:22:05 UTC (rev 18672)
@@ -49,6 +49,8 @@
 #include "wm_subwindow.h"
 #include "wm_window.h"
 
+#include "RNA_access.h"
+
 #include "BIF_gl.h"
 
 #include "UI_interface.h"
@@ -1796,3 +1798,432 @@
 	BLI_dynstr_free(ds);
 }
 
+/* ******************* customize own menus, toolbox *************** */
+
+/* prototype */
+static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiMenuBlockHandle *handle, void *arg_info);
+
+#define MAX_MENU_STR	64
+
+/* type, internal */
+#define MENU_ITEM_TITLE			0
+#define MENU_ITEM_ITEM			1
+#define MENU_ITEM_OPNAME		2
+#define MENU_ITEM_OPNAME_ENUM	3
+#define MENU_ITEM_LEVEL			4
+#define MENU_ITEM_LEVEL_ENUM	5
+
+struct uiMenuItem {
+	struct uiMenuItem *next, *prev;
+	
+	int type;
+	int icon;
+	char name[MAX_MENU_STR];
+	
+	char *opname;	/* static string */
+	char *propname;	/* static string */
+	
+	int retval;
+	int opcontext;
+	void (*eventfunc)(bContext *, void *, int);
+	void *argv;
+	void (*newlevel)(uiMenuItem *);
+	
+	ListBase items;
+};
+
+typedef struct uiMenuInfo {
+	uiMenuItem *head;
+	int mx, my;
+	int startx, starty;
+} uiMenuInfo;
+
+/* internal add func */
+static uiMenuItem *ui_menu_add_item(uiMenuItem *head, const char *name, int icon, int argval)
+{
+	uiMenuItem *item= MEM_callocN(sizeof(uiMenuItem), "menu item");
+	
+	BLI_strncpy(item->name, name, MAX_MENU_STR);
+	if(icon)
+		item->icon= icon;
+	else
+		item->icon= ICON_BLANK1;
+	item->retval= argval;
+	item->opcontext= WM_OP_EXEC_REGION_WIN; 
+	
+	BLI_addtail(&head->items, item);
+	
+	return item;
+}
+
+
+/* only return handler, and set optional title */
+uiMenuItem *uiMenuBegin(const char *title)
+{
+	uiMenuItem *item= MEM_callocN(sizeof(uiMenuItem), "menu start");
+	
+	item->type = MENU_ITEM_TITLE;
+	item->opcontext= WM_OP_EXEC_REGION_WIN; 
+	
+	/* NULL is no title */
+	if(title)
+		BLI_strncpy(item->name, title, MAX_MENU_STR);
+	
+	return item;
+}
+
+/* set callback for regular items */
+void uiMenuFunc(uiMenuItem *head, void (*eventfunc)(bContext *, void *, int), void *argv)
+{
+	head->eventfunc= eventfunc;
+	head->argv= argv;
+}
+
+/* optionally set different context for all items in one level */
+void uiMenuContext(uiMenuItem *head, int opcontext)
+{
+	head->opcontext= opcontext;
+}
+
+
+/* regular item, with retval */
+void uiMenuItemVal(uiMenuItem *head, const char *name, int icon, int argval)
+{
+	uiMenuItem *item= ui_menu_add_item(head, name, icon, argval);
+	
+	item->type = MENU_ITEM_ITEM;
+}
+
+/* regular operator item */
+void uiMenuItemO(uiMenuItem *head, char *name, int icon)
+{
+	uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
+	
+	item->opname= name; // static!
+	item->type = MENU_ITEM_OPNAME;
+}
+
+/* Single operator item with property */
+void uiMenuItemEnumO(uiMenuItem *head, char *opname, char *propname, int value)
+{
+	uiMenuItem *item= ui_menu_add_item(head, "", 0, 0);
+	
+	item->opname= opname; // static!
+	item->propname= propname; // static!
+	item->retval= value;
+	item->type = MENU_ITEM_OPNAME_ENUM;
+}
+
+/* Add all operator items with property */
+void uiMenuItemsEnumO(uiMenuItem *head, char *opname, char *propname)
+{
+	wmOperatorType *ot;
+	
+	ot= WM_operatortype_find(opname);
+	if(ot) {
+		PointerRNA *opptr= MEM_callocN(sizeof(PointerRNA), "uiButOpPtr");
+		PropertyRNA *prop;
+		
+		WM_operator_properties_create(opptr, opname);
+		prop= RNA_struct_find_property(opptr, propname);
+		
+		if(prop) {
+			const EnumPropertyItem *item;
+			int totitem, i;
+			
+			RNA_property_enum_items(opptr, prop, &item, &totitem);
+			
+			for (i=0; i<totitem; i++) {
+				uiMenuItemEnumO(head, opname, propname, item[i].value);
+			}
+		}
+		WM_operator_properties_free(opptr);
+		MEM_freeN(opptr);
+	}
+}
+
+
+/* generic new menu level */
+void uiMenuLevel(uiMenuItem *head, const char *name, void (*newlevel)(uiMenuItem *))
+{
+	uiMenuItem *item= ui_menu_add_item(head, name, 0, 0);
+	
+	item->type = MENU_ITEM_LEVEL;
+	item->newlevel= newlevel;
+}
+
+/* make a new level from enum properties */
+void uiMenuLevelEnumO(uiMenuItem *head, char *opname, char *propname)
+{
+	uiMenuItem *item= ui_menu_add_item(head, "", 0, 0);
+	wmOperatorType *ot;
+	
+	item->type = MENU_ITEM_LEVEL_ENUM;
+	ot= WM_operatortype_find(opname);
+	if(ot)
+		BLI_strncpy(item->name, ot->name, MAX_MENU_STR);
+
+	item->opname= opname; // static!
+	item->propname= propname; // static!
+	
+	BLI_addtail(&head->items, item);
+}
+
+/* set the whole structure to work */
+void uiMenuEnd(bContext *C, uiMenuItem *head)
+{
+	wmWindow *window= CTX_wm_window(C);
+	uiMenuInfo info;
+	uiMenuBlockHandle *menu;
+	
+	memset(&info, 0, sizeof(info));
+	info.mx= window->eventstate->x;
+	info.my= window->eventstate->y;
+	info.head= head;
+	
+	menu= ui_menu_block_create(C, NULL, NULL, ui_block_func_MENU_ITEM, &info);
+	menu->popup= 1;
+	
+	UI_add_popup_handlers(&window->handlers, menu);
+	WM_event_add_mousemove(C);
+	
+	BLI_freelistN(&head->items);
+	MEM_freeN(head);
+}
+
+/* *********** internal code for menu/toolbox system */
+
+const char *ui_menu_enumpropname(PointerRNA *opptr, const char *propname, int retval)
+{
+	PropertyRNA *prop;
+	
+	prop= RNA_struct_find_property(opptr, propname);
+	
+	if(prop) {
+		const EnumPropertyItem *item;
+		int totitem, i;
+		
+		RNA_property_enum_items(opptr, prop, &item, &totitem);
+		
+		for (i=0; i<totitem; i++) {
+			if(item[i].value==retval)
+				return item[i].name;
+		}
+	}
+	return "";
+}
+
+/* make a menu level from uiMenuItems */
+static uiBlock *menu_item_makemenu(bContext *C, uiMenuBlockHandle *handle, void *arg)
+{
+	uiBlock *block;
+	uiMenuInfo info;
+	uiMenuItem *head;
+	void (*newlevel)(uiMenuItem *)= arg;
+	
+	if(arg==NULL) return NULL;
+	
+	head= MEM_callocN(sizeof(uiMenuItem), "sub level item");
+	head->opcontext= WM_OP_EXEC_REGION_WIN; 
+
+	newlevel(head);
+	
+	memset(&info, 0, sizeof(info));
+	info.head= head;
+	
+	block= ui_block_func_MENU_ITEM(C, handle, &info);
+	block->direction= UI_RIGHT;
+	
+	BLI_freelistN(&head->items);
+	MEM_freeN(head);
+	
+	return block;
+}
+
+/* make a menu level from enum properties */
+static uiBlock *menu_item_enum_menu(bContext *C, uiMenuBlockHandle *handle, void *arg)
+{
+	uiBlock *block;
+	uiBut *but= arg;	/* parent caller */
+	wmOperatorType *ot;
+	uiMenuInfo info;
+	uiMenuItem *head;
+	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list