[Bf-committers] Object Sel menu in 3d view patch

Campbell Barton bf-committers@blender.org
Sun, 27 Jun 2004 22:14:51 +1000


This is a multi-part message in MIME format.
--------------050000040609000506010606
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit


Hi, heres a patch that makes ALT+RMB Bring a menu up in the 3d view with 
a list of object names under the mouse.
The user can then choose the object by name.

Its quite nice for to speed up the workflow with a large scene, or with 
many objects close together.

I have accounted for all psooible user interaction as far as I can see.

Its commited to Tuhoppu now but its simple and stable so this could be 
added to bf-blender.

- Cam

-- 
Campbell J Barton

133 Hope Street
Geelong West, Victoria 3218 Australia

URL:    http://www.metavr.com
e-mail: cbarton@metavr.com
phone: AU (03) 5229 0241


--------------050000040609000506010606
Content-Type: text/plain;
 name="obj_sel_menu.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="obj_sel_menu.txt"

Index: source/blender/src/editview.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/editview.c,v
retrieving revision 1.24
diff -u -r1.24 editview.c
--- source/blender/src/editview.c	19 Jun 2004 17:35:37 -0000	1.24
+++ source/blender/src/editview.c	27 Jun 2004 11:59:38 -0000
@@ -536,33 +536,65 @@
 	}
 }
 
+/* The max number of menu items in an object select menu */
+#define SEL_MENU_SIZE 22
+
 void mouse_select(void)
 {
 	Base *base, *startbase=NULL, *basact=NULL, *oldbasact=NULL;
+	
+	/* Vars for object selection menu */
+	Base  *baseList[SEL_MENU_SIZE]; /*baseList is used to store all possible bases to bring up a menu */
+	short baseCount = 0;
+	/* menuText should be the initial size of text (18 atm) + ( SEL_MENU_SIZE * 26)  
+	26 being the longest possible length for a menu item */
+	char menuText[512] = "Select Object%t"; 
+	char menuIndexChar[2];
+	/*end object select menu */
+	
 	unsigned int buffer[MAXPICKBUF];
-	int temp, a, dist=100;
+	int temp, a, dist=1000;
 	short hits, mval[2];
 
+	
 	/* always start list from basact */
 	startbase=  FIRSTBASE;
 	if(BASACT && BASACT->next) startbase= BASACT->next;
 
 	getmouseco_areawin(mval);
-
+	
+	/* This block uses the controle key to make the object selected by its centre point rather then its contentse*/
 	if(G.obedit==0 && (G.qual & LR_CTRLKEY)) {
 
 		base= startbase;
 		while(base) {
-			
 			if(base->lay & G.vd->lay) {
-				
 				project_short(base->object->obmat[3], &base->sx);
 				
 				temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
 				if(base==BASACT) temp+=10;
 				if(temp<dist ) {
-					basact= base;
+					
 					dist= temp;
+					
+					/* Generate menu text */
+					if (G.qual & LR_ALTKEY) {
+						if (baseCount < SEL_MENU_SIZE) {
+							baseList[baseCount] = base;
+							strcat(menuText, "|"); /* Seperate menu items */
+							sprintf(menuIndexChar, "%d", baseCount+1); /* Turn Base count into a string */
+							strcat(menuText, base->object->id.name+2); /*Object name*/
+							strcat(menuText, "%x");
+							strcat(menuText, menuIndexChar);						
+						
+							baseCount++;
+						} /* end generating menu*/
+					} else { /* no altkey, no menu */
+						basact= base; /*  No menu so we need to do this now */
+					}
+					
+					
+					
 				}
 			}
 			base= base->next;
@@ -570,7 +602,25 @@
 			if(base==0) base= FIRSTBASE;
 			if(base==startbase) break;
 		}
-
+		
+		if (G.qual & LR_ALTKEY) {
+			/* USE MENU IF MORE THEN 1 ITEM ARE UNDER THE MOUSE*/
+			if (baseCount == 1) { /* Only 1 item, dont bother with a menu */
+				base = baseList[0];
+				basact = base;			
+			} else { /* We have more then 1 item under the mouse cursor */
+		
+				baseCount = pupmenu(menuText);
+		
+				if (baseCount != -1) { /* If nothing is selected then dont do anything */
+					base = baseList[baseCount-1];
+					basact = base;
+					} else {
+						return; /* No menu item selected so give up now */
+					}
+			}
+		} /*end altkey/menu option*/
+		
 		/* complete redraw when: */
 		if(G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) allqueue(REDRAWVIEW3D, 0);
 		
@@ -578,23 +628,61 @@
 	else {
 		hits= selectprojektie(buffer, mval[0]-7, mval[1]-7, mval[0]+7, mval[1]+7);
 		if(hits==0) hits= selectprojektie(buffer, mval[0]-21, mval[1]-21, mval[0]+21, mval[1]+21);
-
 		if(hits>0) {
-
 			base= startbase;
 			while(base) {
 				if(base->lay & G.vd->lay) {
 					for(a=0; a<hits; a++) {
 						/* index was converted */
-						if(base->selcol==buffer[ (4 * a) + 3 ]) basact= base;
+						if(base->selcol==buffer[ (4 * a) + 3 ]) {
+							
+							/* Generate menu text */
+							if (G.qual & LR_ALTKEY) {
+								if (baseCount < SEL_MENU_SIZE) {
+									baseList[baseCount] = base;
+									strcat(menuText, "|"); /* Seperate menu items */
+									sprintf(menuIndexChar, "%d", baseCount+1); /* Turn Base count into a string */
+									strcat(menuText, base->object->id.name+2); /*Object name*/
+									strcat(menuText, "%x");
+									strcat(menuText, menuIndexChar);						
+									baseCount++;
+								} /* end generating menu*/
+							} else { /* no altkey, no menu */
+								basact= base;  /*  No menu so we need to do this now */
+							}
+						}
 					}
 				}
-				if(basact) break;
+				
+				/* Act normaly if Menu isnt being used */
+				if (!(G.qual & LR_ALTKEY)) {
+					if(basact) break; /*  No menu so we need to do this now */
+				}
 				
 				base= base->next;
 				if(base==0) base= FIRSTBASE;
 				if(base==startbase) break;
 			}
+			
+			
+			/* Menu only if the altkey is pressed */
+			if (G.qual & LR_ALTKEY) {
+				/* USE MENU IF MORE THEN 1 ITEM ARE UNDER THE MOUSE*/
+				if (baseCount == 1) { /* Only 1 item, dont bother with a menu */
+				base = baseList[0];
+				basact = base;			
+				} else { /* We have more then 1 item under the mouse cursor */
+					baseCount = pupmenu(menuText);
+				
+					if (baseCount != -1) { /* If nothing is selected then dont do anything */
+						base = baseList[baseCount-1];
+						basact = base;
+					} else {
+						return; /* No menu item selected so give up now */
+					}
+				}
+			} /*end altkey/menu option*/
+			
 		}
 	}
 	

--------------050000040609000506010606--