Patch #4980, by Joshua Leung (aligorith)
authorTon Roosendaal <ton@blender.org>
Tue, 7 Nov 2006 14:25:58 +0000 (14:25 +0000)
committerTon Roosendaal <ton@blender.org>
Tue, 7 Nov 2006 14:25:58 +0000 (14:25 +0000)
This enables finding data in the Outliner.
Usage: Fkey (partial strings), CTRL+Fkey (partial strings, case sensitive).
SHIFT+Fkey to repeat a search, this cycles around.

Extra changes:
- button popups to enter strings now starts activated.
- outliner either shows for Armature the Bones, or Posechannels or
  Editbones,  depending the mode. Was needed to make searches meaningful.

Although Joshua did very good work on the key functions, there were a couple
of issues in his code, and problems in Outliner code, that didn't make it
all work nicely. So, this is quite a revised patch. :)

Full review log can be found in the patch tracker.

source/blender/blenloader/intern/readfile.c
source/blender/include/BIF_outliner.h
source/blender/makesdna/DNA_oops_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/src/header_oops.c
source/blender/src/outliner.c
source/blender/src/space.c
source/blender/src/toolbox.c

index 1ce1f2c7237c6cec182657f15dd883814bc4873c..675a8f7f81e691a64a7ac6f738723b9e0dd86aa6 100644 (file)
 #include "BKE_texture.h" // for open_plugin_tex
 #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
 
-#include "BIF_butspace.h" // for do_versions, patching event codes
-#include "BIF_previewrender.h" // for struct RenderInfo
+#include "BIF_butspace.h" // badlevel, for do_versions, patching event codes
+#include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo
 #include "BLO_readfile.h"
 #include "BLO_undofile.h"
 #include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory
@@ -3143,6 +3143,7 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                }
                                                so->lockpoin= NULL;
                                                so->tree.first= so->tree.last= NULL;
+                                               so->search_tse.id= newlibadr(fd, NULL, so->search_tse.id);
                                                
                                                if(so->treestore) {
                                                        tselem= so->treestore->data;
@@ -3302,14 +3303,15 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                else if(sl->spacetype==SPACE_OOPS) {
                                        SpaceOops *so= (SpaceOops *)sl;
                                        Oops *oops;
-                                       
                                        int a;
+                                       
                                        oops= so->oops.first;
                                        while(oops) {
                                                oops->id= restore_pointer_by_name(newmain, (ID *)oops->id, 0);
                                                oops= oops->next;
                                        }
                                        so->lockpoin= NULL;
+                                       so->search_tse.id= restore_pointer_by_name(newmain, so->search_tse.id, 0);
                                        
                                        if(so->treestore) {
                                                TreeStore *ts= so->treestore;
index 539ee055dba4b099830f63229645b9eadb1f2c1b..78557796467d0904713386b69da716a146451f23 100644 (file)
@@ -38,7 +38,7 @@ struct TreeStoreElem;
 typedef struct TreeElement {
        struct TreeElement *next, *prev, *parent;
        ListBase subtree;
-       float xs, ys;           // doe selection
+       float xs, ys;           // do selection
        int store_index;        // offset in tree store
        short flag, index;      // flag for non-saved stuff, index for data arrays
        short idcode;           // from TreeStore id
@@ -72,6 +72,12 @@ typedef struct TreeElement {
 #define TSE_VERSE_GEOM_NODE    17
 /*#endif*/
 
+/* outliner search flags */
+#define OL_FIND                                        0
+#define OL_FIND_CASE                   1
+#define OL_FIND_COMPLETE               2
+#define OL_FIND_COMPLETE_CASE  3
+
 /* button events */
 #define OL_NAMEBUTTON          1
 
@@ -86,6 +92,7 @@ extern void outliner_select(struct ScrArea *sa);
 extern void outliner_toggle_selected(struct ScrArea *sa);
 extern void outliner_operation_menu(struct ScrArea *sa);
 extern void outliner_page_up_down(struct ScrArea *sa, int up);
+extern void outliner_find_panel(struct ScrArea *sa, int again, int flags);
 
 #endif
 
index 0f49ed23b4707746d8b57a7238809ea2d65a4c16..aaee18e3249a1b3e6725d2851c0c9f155c75862a 100644 (file)
@@ -43,7 +43,7 @@ struct ID;
 
 typedef struct TreeStoreElem {
        short type, nr, flag, used;
-       ID *id;
+       struct ID *id;
 } TreeStoreElem;
 
 typedef struct TreeStore {
@@ -65,7 +65,7 @@ typedef struct Oops {
 typedef struct OopsLink {
        struct OopsLink *next, *prev;
        short type, flag;
-       ID **idfrom;
+       struct ID **idfrom;
        Oops *to, *from;        /* from is for temp */
        float xof, yof;
        char name[12];
index f89f67529a618e74e1a1e0af1508afb2bc5dfcca..731823a090628093410602a40df2f1eea6418ed8 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "DNA_listBase.h"
 #include "DNA_vec_types.h"
+#include "DNA_oops_types.h"    /* for TreeStoreElem */
 /* Hum ... Not really nice... but needed for spacebuts. */
 #include "DNA_view2d_types.h"
 
@@ -47,7 +48,6 @@ struct ImBuf;
 struct Image;
 struct SpaceIpo;
 struct BlendHandle;
-struct TreeStore;
 struct RenderInfo;
 struct bNodeTree;
 struct uiBlock;
@@ -206,6 +206,12 @@ typedef struct SpaceOops {
        
        ListBase tree;
        struct TreeStore *treestore;
+       
+       /* search stuff */
+       char search_string[32];
+       struct TreeStoreElem search_tse;
+       int search_flags, pad;
+       
        short type, outlinevis, storeflag;
        short deps_flags;
        
index c4ebda76eae1a1c7ad7118fd842792198dd66199..fe1e3b8964433ba64a54ca80e16a0d0dd32b457a 100644 (file)
@@ -348,7 +348,67 @@ static uiBlock *oops_blockmenu(void *arg_unused)
        return block;
 }
 
+static void do_oops_searchmenu(void *arg, int event)
+{      
+       int search_flags = OL_FIND, again = 0;
+       
+       switch(event)
+       {
+       case 0: /* plain new find */    
+               search_flags = OL_FIND;
+               break;
+       case 1: /* case sensitive */
+               search_flags = OL_FIND_CASE;
+               break;
+       case 2: /* full search */
+               search_flags = OL_FIND_COMPLETE;
+               break;
+       case 3: /* full case sensitive */
+               search_flags = OL_FIND_COMPLETE_CASE;
+               break;
+       case 4: /* again */
+               again = 1;
+               break;
+       default: /* nothing valid */
+               return;
+       }
+       
+       /* run search */
+       outliner_find_panel(curarea, again, search_flags);
+}
+
+static uiBlock *oops_searchmenu(void *arg_unused)
+{
+       uiBlock *block;
+       short yco= 0, menuwidth=120;
+
+       block= uiNewBlock(&curarea->uiblocks, "oops_searchmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
+       uiBlockSetButmFunc(block, do_oops_searchmenu, NULL);
+
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find (Case Sensitive)|Ctrl F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+       
+       uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");  
+       
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Complete|Alt F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Complete (Case Sensitive)|Ctrl Alt F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+       
+       uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");  
+       
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Again|Shift F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
 
+       if(curarea->headertype==HEADERTOP) {
+               uiBlockSetDirection(block, UI_DOWN);
+       }
+       else {
+               uiBlockSetDirection(block, UI_TOP);
+               uiBlockFlipOrder(block);
+       }
+
+       uiTextBoundsBlock(block, 50);
+
+       return block;
+}
 
 void oops_buttons(void)
 {      
@@ -405,6 +465,11 @@ void oops_buttons(void)
                        xco+= xmax;
                        
                }
+               else {
+                       xmax= GetButStringLength("Search");
+                       uiDefPulldownBut(block, oops_searchmenu, NULL, "Search", xco, -2, xmax-3, 24, "");
+                       xco+= xmax;
+               }
        }
 
        uiBlockSetEmboss(block, UI_EMBOSS);
index 45e84c6b735575c95c6807b5f0ee2fe7750a6b6a..640958bd3eded2cfec7768d074e66daca770739b 100644 (file)
@@ -127,6 +127,7 @@ extern ListBase session_list;
 extern ListBase server_list;
 #endif
 
+
 /* ******************** PERSISTANT DATA ***************** */
 
 static void outliner_storage_cleanup(SpaceOops *soops)
@@ -229,7 +230,7 @@ void outliner_free_tree(ListBase *lb)
        
        while(lb->first) {
                TreeElement *te= lb->first;
-
+               
                outliner_free_tree(&te->subtree);
                BLI_remlink(lb, te);
                MEM_freeN(te);
@@ -440,8 +441,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                        
                                        tenla->name= "Pose";
                                        
-                                       if(ob!=G.obedit) {      // channels undefined in editmode, but we want the 'tenla' pose icon itself
-                                               int a= 0;
+                                       if(ob!=G.obedit && (ob->flag & OB_POSEMODE)) {  // channels undefined in editmode, but we want the 'tenla' pose icon itself
+                                               int a= 0, const_index= 1000;    /* ensure unique id for bone constraints */
+                                               
                                                for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next, a++) {
                                                        ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a);
                                                        ten->name= pchan->name;
@@ -453,12 +455,11 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                                                bConstraint *con;
                                                                TreeElement *ten1;
                                                                TreeElement *tenla1= outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
-                                                               int a= 0;
                                                                char *str;
                                                                
                                                                tenla1->name= "Constraints";
-                                                               for(con= pchan->constraints.first; con; con= con->next, a++) {
-                                                                       ten1= outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, a);
+                                                               for(con= pchan->constraints.first; con; con= con->next, const_index++) {
+                                                                       ten1= outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
                                                                        target= get_constraint_target(con, &str);
                                                                        if(str && str[0]) ten1->name= str;
                                                                        else if(target) ten1->name= target->id.name+2;
@@ -479,6 +480,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                                                        BLI_remlink(&tenla->subtree, ten);
                                                                        par= (TreeElement *)pchan->parent->prev;
                                                                        BLI_addtail(&par->subtree, ten);
+                                                                       ten->parent= par;
                                                                }
                                                        }
                                                        ten= nten;
@@ -704,14 +706,20 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                                        BLI_remlink(&te->subtree, ten);
                                                        par= ebone->parent->temp;
                                                        BLI_addtail(&par->subtree, ten);
+                                                       ten->parent= par;
                                                }
                                                ten= nten;
                                        }
                                }
                                else {
-                                       Bone *curBone;
-                                       for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
-                                               outliner_add_bone(soops, &te->subtree, id, curBone, te, &a);
+                                       /* do not extend Armature when we have posemode */
+                                       tselem= TREESTORE(te->parent);
+                                       if( GS(tselem->id->name)==ID_OB && ((Object *)tselem->id)->flag & OB_POSEMODE);
+                                       else {
+                                               Bone *curBone;
+                                               for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
+                                                       outliner_add_bone(soops, &te->subtree, id, curBone, te, &a);
+                                               }
                                        }
                                }
                        }
@@ -1031,6 +1039,46 @@ static void outliner_openclose_level(SpaceOops *soops, ListBase *lb, int curleve
        }
 }
 
+/* return 1 when levels were opened */
+static int outliner_open_back(SpaceOops *soops, TreeElement *te)
+{
+       TreeStoreElem *tselem;
+       int retval= 0;
+       
+       for (te= te->parent; te; te= te->parent) {
+               tselem= TREESTORE(te);
+               if (tselem->flag & TSE_CLOSED) { 
+                       tselem->flag &= ~TSE_CLOSED;
+                       retval= 1;
+               }
+       }
+       return retval;
+}
+
+static void outliner_open_reveal(SpaceOops *soops, ListBase *lb, TreeElement *teFind, int *found)
+{
+       TreeElement *te;
+       TreeStoreElem *tselem;
+       
+       for (te= lb->first; te; te= te->next) {
+               /* check if this tree-element was the one we're seeking */
+               if (te == teFind) {
+                       *found= 1;
+                       return;
+               }
+               
+               /* try to see if sub-tree contains it then */
+               outliner_open_reveal(soops, &te->subtree, teFind, found);
+               if (*found) {
+                       tselem= TREESTORE(te);
+                       if (tselem->flag & TSE_CLOSED) 
+                               tselem->flag &= ~TSE_CLOSED;
+                       return;
+               }
+       }
+}
+
+
 void outliner_one_level(struct ScrArea *sa, int add)
 {
        SpaceOops *soops= sa->spacedata.first;
@@ -1767,6 +1815,36 @@ void outliner_mouse_event(ScrArea *sa, short event)
                outliner_select(sa);
 
 }
+/* recursive helper for function below */
+static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te, int startx, int *starty)
+{
+       TreeStoreElem *tselem= TREESTORE(te);
+       
+       /* store coord and continue, we need coordinates for elements outside view too */
+       te->xs= startx;
+       te->ys= *starty;
+       *starty-= OL_H;
+       
+       if((tselem->flag & TSE_CLOSED)==0) {
+               TreeElement *ten;
+               for(ten= te->subtree.first; ten; ten= ten->next) {
+                       outliner_set_coordinates_element(soops, ten, startx+OL_X, starty);
+               }
+       }
+       
+}
+
+/* to retrieve coordinates with redrawing the entire tree */
+static void outliner_set_coordinates(SpaceOops *soops)
+{
+       TreeElement *te;
+       int starty= soops->v2d.tot.ymax-OL_H;
+       int startx= 0;
+       
+       for(te= soops->tree.first; te; te= te->next) {
+               outliner_set_coordinates_element(soops, te, startx, &starty);
+       }
+}
 
 static TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id)
 {
@@ -1804,6 +1882,158 @@ void outliner_show_active(struct ScrArea *sa)
        }
 }
 
+void outliner_show_selected(struct ScrArea *sa)
+{
+       SpaceOops *so= sa->spacedata.first;
+       TreeElement *te;
+       int ytop;
+       
+       te= outliner_find_id(so, &so->tree, (ID *)OBACT);
+       if(te) {
+               /* make te->ys center of view */
+               ytop= te->ys + (so->v2d.mask.ymax-so->v2d.mask.ymin)/2;
+               if(ytop>0) ytop= 0;
+               so->v2d.cur.ymax= ytop;
+               so->v2d.cur.ymin= ytop-(so->v2d.mask.ymax-so->v2d.mask.ymin);
+               scrarea_queue_redraw(sa);
+       }
+}
+
+
+/* find next element that has this name */
+static TreeElement *outliner_find_named(SpaceOops *soops, ListBase *lb, char *name, int flags, TreeElement *prev, int *prevFound)
+{
+       TreeElement *te, *tes;
+       
+       for (te= lb->first; te; te= te->next) {
+               int found;
+               
+               /* determine if match */
+               if(flags==OL_FIND)
+                       found= strcasestr(te->name, name)!=NULL;
+               else if(flags==OL_FIND_CASE)
+                       found= strstr(te->name, name)!=NULL;
+               else if(flags==OL_FIND_COMPLETE)
+                       found= strcasecmp(te->name, name)==0;
+               else
+                       found= strcmp(te->name, name)==0;
+               
+               if(found) {
+                       /* name is right, but is element the previous one? */
+                       if (prev) {
+                               if ((te != prev) && (*prevFound)) 
+                                       return te;
+                               if (te == prev) {
+                                       *prevFound = 1;
+                               }
+                       }
+                       else
+                               return te;
+               }
+               
+               tes= outliner_find_named(soops, &te->subtree, name, flags, prev, prevFound);
+               if(tes) return tes;
+       }
+
+       /* nothing valid found */
+       return NULL;
+}
+
+/* tse is not in the treestore, we use its contents to find a match */
+static TreeElement *outliner_find_tse(SpaceOops *soops, TreeStoreElem *tse)
+{
+       TreeStore *ts= soops->treestore;
+       TreeStoreElem *tselem;
+       int a;
+       
+       if(tse->id==NULL) return NULL;
+       
+       /* check if 'tse' is in treestore */
+       tselem= ts->data;
+       for(a=0; a<ts->usedelem; a++, tselem++) {
+               if(tselem->id==tse->id) {
+                       if((tse->type==0 && tselem->type==0) || (tselem->type==tse->type && tselem->nr==tse->nr)) {
+                               break;
+                       }
+               }
+       }
+       if(tselem) 
+               return outliner_find_tree_element(&soops->tree, a);
+       
+       return NULL;
+}
+
+
+/* Called to find an item based on name.
+ */
+void outliner_find_panel(struct ScrArea *sa, int again, int flags) 
+{
+       SpaceOops *soops= sa->spacedata.first;
+       TreeElement *te= NULL;
+       TreeElement *last_find;
+       TreeStoreElem *tselem;
+       int ytop, prevFound=0;
+       char name[33];
+       
+       /* get last found tree-element based on stored search_tse */
+       last_find= outliner_find_tse(soops, &soops->search_tse);
+       
+       /* determine which type of search to do */
+       if (again && last_find) {
+               /* no popup panel - previous + user wanted to search for next after previous */         
+               BLI_strncpy(name, soops->search_string, 33);
+               flags= soops->search_flags;
+               
+               /* try to find matching element */
+               te= outliner_find_named(soops, &soops->tree, name, flags, last_find, &prevFound);
+               if (te==NULL) {
+                       /* no more matches after previous, start from beginning again */
+                       prevFound= 1;
+                       te= outliner_find_named(soops, &soops->tree, name, flags, last_find, &prevFound);
+               }
+       }
+       else {
+               /* pop up panel - no previous, or user didn't want search after previous */
+               strcpy(name, "");
+               if (sbutton(name, 0, sizeof(name)-1, "Find: ") && name[0]) {
+                       te= outliner_find_named(soops, &soops->tree, name, flags, NULL, &prevFound);
+               }
+               else return; /* XXX RETURN! XXX */
+       }
+
+       /* do selection and reveil */
+       if (te) {
+               tselem= TREESTORE(te);
+               if (tselem) {
+                       /* expand branches so that it will be visible, we need to get correct coordinates */
+                       if( outliner_open_back(soops, te))
+                               outliner_set_coordinates(soops);
+                       
+                       /* deselect all visible, and select found element */
+                       outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 0);
+                       tselem->flag |= TSE_SELECTED;
+                       
+                       /* make te->ys center of view */
+                       ytop= te->ys + (soops->v2d.mask.ymax-soops->v2d.mask.ymin)/2;
+                       if(ytop>0) ytop= 0;
+                       soops->v2d.cur.ymax= ytop;
+                       soops->v2d.cur.ymin= ytop-(soops->v2d.mask.ymax-soops->v2d.mask.ymin);
+                       
+                       /* store selection */
+                       soops->search_tse= *tselem;
+                       
+                       BLI_strncpy(soops->search_string, name, 33);
+                       soops->search_flags= flags;
+                       
+                       /* redraw */
+                       scrarea_queue_redraw(sa);
+               }
+       }
+       else {
+               if (name) error("Not found: %s", name);
+       }
+}
+
 static int subtree_has_objects(SpaceOops *soops, ListBase *lb)
 {
        TreeElement *te;
@@ -2678,7 +2908,7 @@ static void outliner_draw_tree_element(SpaceOops *soops, TreeElement *te, int st
                        }
                }
        }       
-       /* store coord and continue */
+       /* store coord and continue, we need coordinates for elements outside view too */
        te->xs= startx;
        te->ys= *starty;
        te->xend= startx+offsx;
@@ -2774,9 +3004,9 @@ static void outliner_draw_tree(SpaceOops *soops)
        for(te= soops->tree.first; te; te= te->next) {
                outliner_draw_tree_element(soops, te, startx, &starty);
        }
-       
 }
 
+
 static void outliner_back(SpaceOops *soops)
 {
        int ystart;
@@ -2881,6 +3111,7 @@ static void outliner_buttons(uiBlock *block, SpaceOops *soops, ListBase *lb)
        for(te= lb->first; te; te= te->next) {
                tselem= TREESTORE(te);
                if(tselem->flag & TSE_TEXTBUT) {
+                       if(tselem->type == TSE_POSE_BASE) continue; // prevent crash when trying to rename 'pose' entry of armature
                        
                        if(tselem->type==TSE_EBONE) len = sizeof(((EditBone*) 0)->name);
                        else if (tselem->type==TSE_MODIFIER) len = sizeof(((ModifierData*) 0)->name);
index d0e0e337e198956b0a41c4ddb9a55c14881df65f..ed80eb96eb7371771f4e1bc7f20bec71cf0ffe70 100644 (file)
@@ -4495,6 +4495,19 @@ static void winqreadoopsspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        else
                                outliner_toggle_visible(sa);
                        break;
+               case FKEY: 
+                       {
+                               /* search */
+                               int search_flags=0, again=0;
+                               
+                               /* CTRL=case sensitive, SHIFT=find again, ALT=complete */
+                               if (G.qual & LR_CTRLKEY) search_flags |= 1;
+                               if (G.qual & LR_ALTKEY) search_flags |= 8;
+                               if (G.qual & LR_SHIFTKEY) again = 1;
+                               
+                               outliner_find_panel(sa, again, search_flags);                           
+                       }
+                       break;
                case WKEY:
                        outliner_operation_menu(sa);
                        break;
@@ -5045,7 +5058,8 @@ void freespacelist(ScrArea *sa)
                        }
                }
                else if(sl->spacetype==SPACE_OOPS) {
-                       free_oopspace((SpaceOops *)sl);
+                       SpaceOops *so= (SpaceOops *) sl;
+                       free_oopspace(so);
                }
                else if(sl->spacetype==SPACE_IMASEL) {
                        free_imasel((SpaceImaSel *)sl);
index df01e6e7346c8deb2d8790b04391e342cb4d37d3..70e5012b9c6a7556d7d9560adcb35a1f7f61f50d 100644 (file)
@@ -306,11 +306,12 @@ short sbutton(char *var, float min, float max, char *str)
        x1=mval[0]-150; 
        y1=mval[1]-20; 
        
-       uiDefButC(block, TEX, 0, str,   x1+5,y1+10,125,20, var,(float)min,(float)max, 0, 0, "");
+       uiDefButC(block, TEX, 2, str,   x1+5,y1+10,125,20, var,(float)min,(float)max, 0, 0, "");
        uiDefBut(block, BUT, 1, "OK",   x1+136,y1+10,25,20, NULL, 0, 0, 0, 0, "");
 
        uiBoundsBlock(block, 5);
-
+       
+       mainqenter_ext(BUT_ACTIVATE, 2, 0);     /* note, button id '2' is asking for errors some day! */
        ret= uiDoBlocks(&listb, 0);
 
        if(ret==UI_RETURN_OK) return 1;