[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26023] trunk/blender/source/blender: a new generic invoke function - WM_enum_search_invoke()

Campbell Barton ideasman42 at gmail.com
Fri Jan 15 18:23:16 CET 2010


Revision: 26023
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26023
Author:   campbellbarton
Date:     2010-01-15 18:23:16 +0100 (Fri, 15 Jan 2010)

Log Message:
-----------
a new generic invoke function - WM_enum_search_invoke()
This can search operators enum property.

Make proxy menu could easily get too big. use the new search popup.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/object/object_relations.c
    trunk/blender/source/blender/windowmanager/WM_api.h
    trunk/blender/source/blender/windowmanager/intern/wm_operators.c

Modified: trunk/blender/source/blender/editors/object/object_relations.c
===================================================================
--- trunk/blender/source/blender/editors/object/object_relations.c	2010-01-15 17:19:01 UTC (rev 26022)
+++ trunk/blender/source/blender/editors/object/object_relations.c	2010-01-15 17:23:16 UTC (rev 26023)
@@ -261,39 +261,6 @@
 
 /********************** Make Proxy Operator *************************/
 
-/* present menu listing the possible objects within the group to proxify */
-static void proxy_group_objects_menu (bContext *C, wmOperator *op, Object *ob, Group *group)
-{
-	uiPopupMenu *pup;
-	uiLayout *layout;
-	GroupObject *go;
-	int len=0;
-	
-	/* check if there are any objects within the group to assign for */
-	for (go= group->gobject.first; go; go= go->next) {
-		if (go->ob) len++;
-	}
-	if (len==0) return;
-	
-	/* now create the menu to draw */
-	pup= uiPupMenuBegin(C, "Make Proxy For:", 0);
-	layout= uiPupMenuLayout(pup);
-	
-	for (go= group->gobject.first; go; go= go->next) {
-		if (go->ob) {
-			PointerRNA props_ptr;
-			
-			/* create operator menu item with relevant properties filled in */
-			props_ptr= uiItemFullO(layout, go->ob->id.name+2, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
-			RNA_string_set(&props_ptr, "object", go->ob->id.name+2);
-			RNA_string_set(&props_ptr, "group_object", go->ob->id.name+2);
-		}
-	}
-	
-	/* display the menu, and be done */
-	uiPupMenuEnd(C, pup);
-}
-
 /* set the object to proxify */
 static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt)
 {
@@ -307,7 +274,10 @@
 	/* Get object to work on - use a menu if we need to... */
 	if (ob->dup_group && ob->dup_group->id.lib) {
 		/* gives menu with list of objects in group */
-		proxy_group_objects_menu(C, op, ob, ob->dup_group);
+		//proxy_group_objects_menu(C, op, ob, ob->dup_group);
+		WM_enum_search_invoke(C, op, evt);
+		return OPERATOR_CANCELLED;
+
 	}
 	else if (ob->id.lib) {
 		uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION);
@@ -332,40 +302,11 @@
 
 static int make_proxy_exec (bContext *C, wmOperator *op)
 {
-	Object *ob=NULL, *gob=NULL;
+	Object *ob, *gob= CTX_data_active_object(C);
+	GroupObject *go= BLI_findlink(&gob->dup_group->gobject, RNA_enum_get(op->ptr, "type"));
 	Scene *scene= CTX_data_scene(C);
-	char ob_name[21], gob_name[21];
+	ob= go->ob;
 	
-	/* get object and group object
-	 *	- firstly names
-	 *	- then pointers from context 
-	 */
-	RNA_string_get(op->ptr, "object", ob_name);
-	RNA_string_get(op->ptr, "group_object", gob_name);
-	
-	if (gob_name[0]) {
-		Group *group;
-		GroupObject *go;
-		
-		/* active object is group object... */
-		// FIXME: we should get the nominated name instead
-		gob= CTX_data_active_object(C);
-		group= gob->dup_group;
-		
-		/* find the object to affect */
-		for (go= group->gobject.first; go; go= go->next) {
-			if ((go->ob) && strcmp(go->ob->id.name+2, gob_name)==0) {
-				ob= go->ob;
-				break;
-			}
-		}
-	}
-	else {
-		/* just use the active object for now */
-		// FIXME: we should get the nominated name instead
-		ob= CTX_data_active_object(C);
-	}
-	
 	if (ob) {
 		Object *newob;
 		Base *newbase, *oldbase= BASACT;
@@ -407,8 +348,37 @@
 	return OPERATOR_FINISHED;
 }
 
+/* Generic itemf's for operators that take library args */
+static EnumPropertyItem *proxy_group_object_itemf(bContext *C, PointerRNA *ptr, int *free)
+{
+	EnumPropertyItem *item= NULL, item_tmp;
+	int totitem= 0;
+	int i= 0;
+	Object *ob= CTX_data_active_object(C);
+	GroupObject *go;
+
+	if(!ob || !ob->dup_group)
+		return &DummyRNA_NULL_items;
+
+	memset(&item_tmp, 0, sizeof(item_tmp));
+
+	/* find the object to affect */
+	for (go= ob->dup_group->gobject.first; go; go= go->next) {
+		item_tmp.identifier= item_tmp.name= go->ob->id.name+2;
+		item_tmp.value= i++;
+		RNA_enum_item_add(&item, &totitem, &item_tmp);
+	}
+
+	RNA_enum_item_end(&item, &totitem);
+	*free= 1;
+
+	return item;
+}
+
 void OBJECT_OT_proxy_make (wmOperatorType *ot)
 {
+	PropertyRNA *prop;
+
 	/* identifiers */
 	ot->name= "Make Proxy";
 	ot->idname= "OBJECT_OT_proxy_make";
@@ -424,7 +394,8 @@
 	
 	/* properties */
 	RNA_def_string(ot->srna, "object", "", 19, "Proxy Object", "Name of lib-linked/grouped object to make a proxy for.");
-	RNA_def_string(ot->srna, "group_object", "", 19, "Group Object", "Name of group instancer (if applicable).");
+	prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Type", "Group object"); /* XXX, relies on hard coded ID at the moment */
+	RNA_def_enum_funcs(prop, proxy_group_object_itemf);
 }
 
 /********************** Clear Parent Operator ******************* */

Modified: trunk/blender/source/blender/windowmanager/WM_api.h
===================================================================
--- trunk/blender/source/blender/windowmanager/WM_api.h	2010-01-15 17:19:01 UTC (rev 26022)
+++ trunk/blender/source/blender/windowmanager/WM_api.h	2010-01-15 17:23:16 UTC (rev 26023)
@@ -171,6 +171,7 @@
 		/* operator api, default callbacks */
 			/* invoke callback, uses enum property named "type" */
 int			WM_menu_invoke			(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int			WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
 			/* invoke callback, confirm menu + exec */
 int			WM_operator_confirm		(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
 		/* invoke callback, file selector "path" unset + exec */

Modified: trunk/blender/source/blender/windowmanager/intern/wm_operators.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_operators.c	2010-01-15 17:19:01 UTC (rev 26022)
+++ trunk/blender/source/blender/windowmanager/intern/wm_operators.c	2010-01-15 17:23:16 UTC (rev 26023)
@@ -632,6 +632,88 @@
 	return OPERATOR_CANCELLED;
 }
 
+
+/* ENUM Search popup */
+static void operator_enum_search_cb(const struct bContext *C, void *arg_ot, char *str, uiSearchItems *items)
+{
+	wmOperatorType *ot = (wmOperatorType *)arg_ot;
+	PointerRNA ptr;
+	PropertyRNA *prop;
+
+	/* enum */
+	EnumPropertyItem *item, *item_array;
+	int free, found;
+
+	RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
+	prop = RNA_struct_find_property(&ptr, "type"); // XXX, SHOULD NOT USE HARD CODED VALUE
+
+	RNA_property_enum_items((bContext *)C, &ptr, prop, &item_array, NULL, &free);
+
+	for(item= item_array; item->identifier; item++) {
+		/* note: need to give the intex rather then the dientifier because the enum can be freed */
+		if(BLI_strcasestr(item->name, str))
+			if(0==uiSearchItemAdd(items, item->name, SET_INT_IN_POINTER(item->value), 0))
+				break;
+	}
+
+	found= (item->identifier != NULL); /* could be alloc'd, assign before free */
+
+	if(free)
+		MEM_freeN(item_array);
+
+}
+
+static void operator_enum_call_cb(struct bContext *C, void *arg1, void *arg2)
+{
+	wmOperatorType *ot= arg1;
+	int enum_value= GET_INT_FROM_POINTER(arg2);
+
+	if(ot) {
+		PointerRNA props_ptr;
+		WM_operator_properties_create_ptr(&props_ptr, ot);
+		RNA_enum_set(&props_ptr, "type", enum_value); // XXX, SHOULD NOT USE HARD CODED VALUE
+		WM_operator_name_call(C, ot->idname, WM_OP_EXEC_DEFAULT, &props_ptr);
+		WM_operator_properties_free(&props_ptr);
+	}
+}
+
+static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
+{
+	static char search[256]= "";
+	wmEvent event;
+	wmWindow *win= CTX_wm_window(C);
+	uiBlock *block;
+	uiBut *but;
+
+	block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+	uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT);
+
+	but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, 0, 0, "");
+	uiButSetSearchFunc(but, operator_enum_search_cb, ((wmOperator *)arg_op)->type, operator_enum_call_cb, NULL);
+
+	/* fake button, it holds space for search items */
+	uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 180, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+
+	uiPopupBoundsBlock(block, 6.0f, 0, -20); /* move it downwards, mouse over button */
+	uiEndBlock(C, block);
+
+	event= *(win->eventstate);	/* XXX huh huh? make api call */
+	event.type= EVT_BUT_OPEN;
+	event.val= KM_PRESS;
+	event.customdata= but;
+	event.customdatafree= FALSE;
+	wm_event_add(win, &event);
+
+	return block;
+}
+
+
+int WM_enum_search_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	uiPupBlock(C, wm_enum_search_menu, op);
+	return OPERATOR_CANCELLED;
+}
+
 /* Can't be used as an invoke directly, needs message arg (can be NULL) */
 int WM_operator_confirm_message(bContext *C, wmOperator *op, char *message)
 {





More information about the Bf-blender-cvs mailing list