[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--