2.5
authorTon Roosendaal <ton@blender.org>
Wed, 3 Jun 2009 18:31:37 +0000 (18:31 +0000)
committerTon Roosendaal <ton@blender.org>
Wed, 3 Jun 2009 18:31:37 +0000 (18:31 +0000)
Further work on new "text search" button.

- Now allows to browse items (mouse, arrow key)
- Assigns active value
- Uses different backdrop to distinguish from popup menus
- Cleaned API for it, so it can be used nicely generic

Also added a search menu, which shows all currently working
operators: CTRL+ALT+F. (mind the looks, it needs some tweaks!)

To make a menu activating a button I've added a new event...
could use some tweaks.

Important note: the callback to pass on "old string" for text
button (bone rename) couldn't work yet, added first code for new
callback, but has to be worked on further. When bone rename gets
added it can be tested.

source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/screen/area.c
source/blender/editors/space_info/info_header.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/wm_event_types.h

index 4c2634e2a751940874786f20cfb519714afb1733..feca59bca3054cbe371a4badc4ad8116bb3d6f07 100644 (file)
@@ -436,31 +436,30 @@ uiBut *uiFindInlink(uiBlock *block, void *poin);
  *
  * uiButSetNFunc will free the argument with MEM_freeN. */
 
-typedef struct uiSearchItems {
-       int maxitem, totitem, maxstrlen;
-       
-       char **names;
-       void **pointers;
-       
-} uiSearchItems;
-
+typedef struct uiSearchItems uiSearchItems;
 
 typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2);
+typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origstr);
 typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
 typedef void (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
 typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, char *str, uiSearchItems *items);
 typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
+               
+               /* use inside searchfunc to add items */
+int            uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin);
+               /* bfunc gets search item *poin as arg2, or if NULL the old string */
+void   uiButSetSearchFunc      (uiBut *but,            uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc);
 
 
 void   uiBlockSetHandleFunc(uiBlock *block,    uiBlockHandleFunc func, void *arg);
 void   uiBlockSetButmFunc      (uiBlock *block,        uiMenuHandleFunc func, void *arg);
 
 void   uiBlockSetFunc          (uiBlock *block,        uiButHandleFunc func, void *arg1, void *arg2);
+void   uiBlockSetRenameFunc(uiBlock *block,    uiButHandleRenameFunc func, void *arg1);
 void   uiButSetFunc            (uiBut *but,            uiButHandleFunc func, void *arg1, void *arg2);
 void   uiButSetNFunc           (uiBut *but,            uiButHandleNFunc func, void *argN, void *arg2);
 
 void   uiButSetCompleteFunc(uiBut *but,                uiButCompleteFunc func, void *arg);
-void   uiButSetSearchFunc      (uiBut *but,            uiButSearchFunc func, void *arg);
 
 void   uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(struct bContext *C, uiBlock *block));
 
index 69ee0d470d05b8e2f58d960ca028b6e3bda845d9..68973fe540c6620db4c6418cb8a9dea89eee3c23 100644 (file)
@@ -2963,6 +2963,11 @@ void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2
        block->func_arg2= arg2;
 }
 
+void uiBlockSetRenameFunc(uiBlock *block, uiButHandleRenameFunc func, void *arg1)
+{
+       
+}
+
 void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)())
 {
        block->drawextra= func;
@@ -3083,7 +3088,7 @@ void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1,
        ui_check_but(but);
 }
 
-/* arg is pointer to string/name, use callbacks below to make this work */
+/* arg is pointer to string/name, use uiButSetSearchFunc() below to make this work */
 uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, char *tip)
 {
        uiBut *but= ui_def_but(block, SEARCH_MENU, retval, "", x1, y1, x2, y2, arg, 0.0, maxlen, 0.0, 0.0, tip);
@@ -3099,10 +3104,13 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle
        return but;
 }
 
-void uiButSetSearchFunc(uiBut *but, uiButSearchFunc func, void *arg)
+/* arg is user value, searchfunc and handlefunc both get it as arg */
+void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc)
 {
-       but->search_func= func;
+       but->search_func= sfunc;
        but->search_arg= arg;
+       
+       uiButSetFunc(but, bfunc, arg, NULL);
 }
 
 
index 5617874ab0e5c87c746908966dce8a4b11b9d267..c009c5cfc7baf9a97b2fd6054a90628a95d2f145 100644 (file)
@@ -142,7 +142,8 @@ typedef struct uiAfterFunc {
        uiButHandleFunc func;
        void *func_arg1;
        void *func_arg2;
-
+       void *func_arg3;
+       
        uiButHandleNFunc funcN;
        void *func_argN;
 
@@ -233,6 +234,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
                after->func= but->func;
                after->func_arg1= but->func_arg1;
                after->func_arg2= but->func_arg2;
+               after->func_arg3= but->func_arg3;
 
                after->funcN= but->funcN;
                after->func_argN= but->func_argN;
@@ -418,9 +420,10 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data)
 
        /* give butfunc the original text too */
        /* feature used for bone renaming, channels, etc */
-       if(but->func_arg2==NULL) but->func_arg2= data->origstr;
+       /* XXX goes via uiButHandleRenameFunc now */
+//     if(but->func_arg2==NULL) but->func_arg2= data->origstr;
        ui_apply_but_func(C, but);
-       if(but->func_arg2==data->origstr) but->func_arg2= NULL;
+//     if(but->func_arg2==data->origstr) but->func_arg2= NULL;
 
        data->retval= but->retval;
        data->applied= 1;
@@ -888,7 +891,7 @@ static int ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char asc
                }
        }
 
-       return WM_UI_HANDLER_BREAK;
+       return changed;
 }
 
 void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction, int select, int jump)
@@ -1047,7 +1050,7 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio
        else { /* backspace */
                if(len!=0) {
                        if ((but->selend - but->selsta) > 0) {
-                               ui_textedit_delete_selection(but, data);
+                               changed= ui_textedit_delete_selection(but, data);
                        }
                        else if(but->pos>0) {
                                for(x=but->pos; x<len; x++)
@@ -1175,12 +1178,16 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
 static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data)
 {
        if(but) {
-               but->editstr= 0;
-               but->pos= -1;
-               
-               if(data->searchbox)
+               if(data->searchbox) {
+                       if(data->cancel==0)
+                               ui_searchbox_apply(but, data->searchbox);
+
                        ui_searchbox_free(C, data->searchbox);
-               data->searchbox= NULL;
+                       data->searchbox= NULL;
+               }
+               
+               but->editstr= NULL;
+               but->pos= -1;
        }
 }
 
@@ -1232,11 +1239,17 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
        }
 }
 
+
 static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
 {
-       int mx, my, changed= 0, retval= WM_UI_HANDLER_CONTINUE;
+       int mx, my, changed= 0, inbox=0, retval= WM_UI_HANDLER_CONTINUE;
 
        switch(event->type) {
+               case MOUSEMOVE:
+                       if(data->searchbox)
+                               ui_searchbox_event(data->searchbox, event);
+                       
+                       break;
                case RIGHTMOUSE:
                case ESCKEY:
                        data->cancel= 1;
@@ -1244,6 +1257,11 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                        retval= WM_UI_HANDLER_BREAK;
                        break;
                case LEFTMOUSE: {
+                       
+                       /* exit on LMB only on RELEASE for searchbox, to mimic other popups, and allow multiple menu levels */
+                       if(data->searchbox)
+                               inbox= BLI_in_rcti(&data->searchbox->winrct, event->x, event->y);
+
                        if(event->val==KM_PRESS) {
                                mx= event->x;
                                my= event->y;
@@ -1257,11 +1275,15 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                        button_activate_state(C, but, BUTTON_STATE_TEXT_SELECTING);
                                        retval= WM_UI_HANDLER_BREAK;
                                }
-                               else {
+                               else if(inbox==0) {
                                        button_activate_state(C, but, BUTTON_STATE_EXIT);
                                        retval= WM_UI_HANDLER_BREAK;
                                }
                        }
+                       else if(inbox) {
+                               button_activate_state(C, but, BUTTON_STATE_EXIT);
+                               retval= WM_UI_HANDLER_BREAK;
+                       }
                        break;
                }
        }
@@ -1291,11 +1313,21 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case DOWNARROWKEY:
+                               if(data->searchbox) {
+                                       ui_searchbox_event(data->searchbox, event);
+                                       break;
+                               }
+                               /* pass on purposedly */
                        case ENDKEY:
                                ui_textedit_move_end(but, data, 1, event->shift);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case UPARROWKEY:
+                               if(data->searchbox) {
+                                       ui_searchbox_event(data->searchbox, event);
+                                       break;
+                               }
+                               /* pass on purposedly */
                        case HOMEKEY:
                                ui_textedit_move_end(but, data, 0, event->shift);
                                retval= WM_UI_HANDLER_BREAK;
@@ -1579,7 +1611,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, w
 static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
 {
        if(data->state == BUTTON_STATE_HIGHLIGHT) {
-               if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val==KM_PRESS) {
+               if(ELEM4(event->type, LEFTMOUSE, PADENTER, RETKEY, EVT_BUT_OPEN) && event->val==KM_PRESS) {
                        button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
                        return WM_UI_HANDLER_BREAK;
                }
@@ -3013,7 +3045,9 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
        data= MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData");
        data->window= CTX_wm_window(C);
        data->region= ar;
-       data->interactive= but->type==BUT_CURVE?0:1; // XXX temp
+       if( ELEM(but->type, BUT_CURVE, SEARCH_MENU) );  // XXX curve is temp
+       else data->interactive= 1;
+       
        data->state = BUTTON_STATE_INIT;
 
        /* activate button */
@@ -3115,16 +3149,35 @@ void ui_button_active_cancel(const bContext *C, uiBut *but)
 
 /************** handle activating a button *************/
 
+static uiBut *uit_but_find_open_event(ARegion *ar, wmEvent *event)
+{
+       uiBlock *block;
+       uiBut *but;
+       
+       for(block=ar->uiblocks.first; block; block=block->next) {
+               for(but=block->buttons.first; but; but= but->next)
+                       if(but==event->customdata)
+                               return but;
+       }
+       return NULL;
+}
+
 static int ui_handle_button_over(bContext *C, wmEvent *event, ARegion *ar)
 {
        uiBut *but;
 
        if(event->type == MOUSEMOVE) {
                but= ui_but_find_mouse_over(ar, event->x, event->y);
-
                if(but)
                        button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
        }
+       else if(event->type == EVT_BUT_OPEN) {
+               but= uit_but_find_open_event(ar, event);
+               if(but) {
+                       button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+                       ui_do_button(C, but->block, but, event);
+               }
+       }
 
        return WM_UI_HANDLER_CONTINUE;
 }
index f4483a0540dbf9255b77256bc3af4cd376ef87cf..db100d8cf86432c5364dcfb04c845a0a1033ecc9 100644 (file)
@@ -164,6 +164,7 @@ struct uiBut {
        uiButHandleFunc func;
        void *func_arg1;
        void *func_arg2;
+       void *func_arg3;
 
        uiButHandleNFunc funcN;
        void *func_argN;
@@ -354,8 +355,11 @@ uiBlock *ui_block_func_COL(struct bContext *C, uiPopupBlockHandle *handle, void
 struct ARegion *ui_tooltip_create(struct bContext *C, struct ARegion *butregion, uiBut *but);
 void ui_tooltip_free(struct bContext *C, struct ARegion *ar);
 
+/* searchbox for string button */
 ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBut *but);
 void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but);
+void ui_searchbox_event(struct ARegion *ar, struct wmEvent *event);
+void ui_searchbox_apply(uiBut *but, struct ARegion *ar);
 void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
 
 typedef uiBlock* (*uiBlockHandleCreateFunc)(struct bContext *C, struct uiPopupBlockHandle *handle, void *arg1);
@@ -396,6 +400,8 @@ extern int ui_button_is_active(struct ARegion *ar);
 /* interface_widgets.c */
 void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3);
 void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect);
+void ui_draw_search_back(struct uiStyle *style, uiBlock *block, rcti *rect);
+
 extern void ui_draw_but(ARegion *ar, struct uiStyle *style, uiBut *but, rcti *rect);
                /* theme color init */
 struct ThemeUI;
index 3441abc94bdc8d22f51e1b5aad07e4afaa0810c2..0bde1be21075ef4d34719b8d35fe372024692381 100644 (file)
@@ -386,15 +386,121 @@ void ui_tooltip_free(bContext *C, ARegion *ar)
 
 /************************* Creating Search Box **********************/
 
+struct uiSearchItems {
+       int maxitem, totitem, maxstrlen;
+       
+       char **names;
+       void **pointers;
+       
+};
 
 typedef struct uiSearchboxData {
        rcti bbox;
        uiFontStyle fstyle;
        uiSearchItems items;
+       int active;
 } uiSearchboxData;
 
 #define SEARCH_ITEMS   10
 
+/* exported for use by search callbacks */
+/* returns zero if nothing to add */
+int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin)
+{
+       
+       if(items->totitem>=items->maxitem)
+               return 0;
+       
+       BLI_strncpy(items->names[items->totitem], name, items->maxstrlen);
+       items->pointers[items->totitem]= poin;
+       
+       items->totitem++;
+       
+       return items->totitem<items->maxitem;
+}
+
+
+/* ar is the search box itself */
+static void ui_searchbox_select(ARegion *ar, int step)
+{
+       uiSearchboxData *data= ar->regiondata;
+       
+       /* apply step */
+       data->active+= step;
+       
+       if(data->items.totitem==0)
+               data->active= 0;
+       else if(data->active> data->items.totitem)
+               data->active= 1;
+       else if(data->active < 0)
+               data->active= data->items.totitem;
+       
+       ED_region_tag_redraw(ar);
+}
+
+static void ui_searchbox_butrect(rcti *rect, uiSearchboxData *data, int itemnr)
+{
+       int buth= (data->bbox.ymax-data->bbox.ymin - 2*MENU_SEPR_HEIGHT)/SEARCH_ITEMS;
+       
+       *rect= data->bbox;
+       rect->xmin= data->bbox.xmin + 3.0f;
+       rect->xmax= data->bbox.xmax - 3.0f;
+       
+       rect->ymax= data->bbox.ymax - MENU_SEPR_HEIGHT - itemnr*buth;
+       rect->ymin= rect->ymax - buth;
+       
+}
+
+/* string validated to be of correct length (but->hardmax) */
+void ui_searchbox_apply(uiBut *but, ARegion *ar)
+{
+       uiSearchboxData *data= ar->regiondata;
+
+       but->func_arg2= NULL;
+       
+       if(data->active) {
+               char *name= data->items.names[data->active-1];
+               char *cpoin= strchr(name, '|');
+               
+               if(cpoin) cpoin[0]= 0;
+               BLI_strncpy(but->editstr, name, data->items.maxstrlen);
+               if(cpoin) cpoin[0]= '|';
+               
+               but->func_arg2= data->items.pointers[data->active-1];
+       }
+}
+
+void ui_searchbox_event(ARegion *ar, wmEvent *event)
+{
+       uiSearchboxData *data= ar->regiondata;
+       
+       switch(event->type) {
+               case UPARROWKEY:
+                       ui_searchbox_select(ar, -1);
+                       break;
+               case DOWNARROWKEY:
+                       ui_searchbox_select(ar, 1);
+                       break;
+               case MOUSEMOVE:
+                       if(BLI_in_rcti(&ar->winrct, event->x, event->y)) {
+                               rcti rect;
+                               int a;
+                               
+                               for(a=0; a<data->items.totitem; a++) {
+                                       ui_searchbox_butrect(&rect, data, a);
+                                       if(BLI_in_rcti(&rect, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin)) {
+                                               if( data->active!= a+1) {
+                                                       data->active= a+1;
+                                                       ui_searchbox_select(ar, 0);
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       break;
+       }
+}
+
 /* ar is the search box itself */
 void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but)
 {
@@ -402,7 +508,12 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but)
        
        /* callback */
        data->items.totitem= 0;
-       but->search_func(C, but->search_arg, but->editstr, &data->items);
+       data->active= 0;
+       if(but->search_func)
+               but->search_func(C, but->search_arg, but->editstr, &data->items);
+       
+       /* validate selected item */
+       ui_searchbox_select(ar, 0);
        
        ED_region_tag_redraw(ar);
 }
@@ -411,25 +522,21 @@ static void ui_searchbox_region_draw(const bContext *C, ARegion *ar)
 {
        uiSearchboxData *data= ar->regiondata;
        
-       ui_draw_menu_back(U.uistyles.first, NULL, &data->bbox);
+       /* pixel space */
+       wmOrtho2(-0.01f, ar->winx-0.01f, -0.01f, ar->winy-0.01f);
+
+       ui_draw_search_back(U.uistyles.first, NULL, &data->bbox);
        
        /* draw text */
        if(data->items.totitem) {
                rcti rect;
-               int a, buth;
+               int a;
                                
                /* draw items */
-               buth= (data->bbox.ymax-data->bbox.ymin - 2*MENU_SEPR_HEIGHT)/SEARCH_ITEMS;
-               rect= data->bbox;
-               rect.xmin= data->bbox.xmin + 3.0f;
-               rect.xmax= data->bbox.xmax - 3.0f;
-               rect.ymax= data->bbox.ymax - MENU_SEPR_HEIGHT;
-               rect.ymin= rect.ymax - buth;
-               
                for(a=0; a<data->items.totitem; a++) {
-                       ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], a==0?UI_ACTIVE:0);
-                       rect.ymax -= buth;
-                       rect.ymin -= buth;
+                       ui_searchbox_butrect(&rect, data, a);
+                       
+                       ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], (a+1)==data->active?UI_ACTIVE:0);
                }
        }
 }
@@ -533,7 +640,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
        ar->winrct.xmin= x1 - MENU_SHADOW_SIDE;
        ar->winrct.xmax= x2 + MENU_SHADOW_SIDE;
        ar->winrct.ymin= y1 - MENU_SHADOW_BOTTOM;
-       ar->winrct.ymax= y2 + MENU_TOP;
+       ar->winrct.ymax= y2;
        
        /* adds subwindow */
        ED_region_init(C, ar);
@@ -879,8 +986,6 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
 
        /* get winmat now that we actually have the subwindow */
        wmSubWindowSet(window, ar->swinid);
-                       // XXX ton, AA pixel space...
-       wmOrtho2(0.0, (float)ar->winrct.xmax-ar->winrct.xmin+1, 0.0, (float)ar->winrct.ymax-ar->winrct.ymin+1);
        
        wm_subwindow_getmatrix(window, ar->swinid, block->winmat);
        
@@ -892,7 +997,9 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
 
 void ui_popup_block_free(bContext *C, uiPopupBlockHandle *handle)
 {
-       ui_remove_temporary_region(C, CTX_wm_screen(C), handle->region);
+       /* XXX ton added, chrash on load file with popup open... need investigate */
+       if(CTX_wm_screen(C))
+               ui_remove_temporary_region(C, CTX_wm_screen(C), handle->region);
        MEM_freeN(handle);
 }
 
index 82bfb898f99171977e24f79077a858f3ddcc11d7..47c4a7299567c27c24e088e49957df4019537084 100644 (file)
@@ -1913,6 +1913,23 @@ void ui_draw_menu_back(uiStyle *style, uiBlock *block, rcti *rect)
        
 }
 
+void ui_draw_search_back(uiStyle *style, uiBlock *block, rcti *rect)
+{
+       uiWidgetType *wt= widget_type(UI_WTYPE_BOX);
+       
+       glEnable(GL_BLEND);
+       widget_softshadow(rect, 15, 5.0f, 8.0f);
+       glDisable(GL_BLEND);
+
+       wt->state(wt, 0);
+       if(block)
+               wt->draw(&wt->wcol, rect, block->flag, 15);
+       else
+               wt->draw(&wt->wcol, rect, 0, 15);
+       
+}
+
+
 /* helper call to draw a menu item without button */
 /* state: UI_ACTIVE or 0 */
 void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
@@ -1932,7 +1949,10 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
 
        /* cut string in 2 parts? */
        cpoin= strchr(name, '|');
-       if(cpoin) *cpoin= 0;            
+       if(cpoin) {
+               *cpoin= 0;
+               rect->xmax -= BLF_width(cpoin+1) -10;
+       }
        
        glColor3ubv(wt->wcol.text);
        uiStyleFontDraw(fstyle, rect, name);
@@ -1940,7 +1960,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
        /* part text right aligned */
        if(cpoin) {
                fstyle->align= UI_STYLE_TEXT_RIGHT;
-               rect->xmax-=5;
+               rect->xmax= _rect.xmax - 5;
                uiStyleFontDraw(fstyle, rect, cpoin+1);
                *cpoin= '|';
        }
index ad6b6e04b8e8e579176a5a8f4072c5bf8a3c216e..7d9cc748d0571622cc1518ec52d02cef67e095d3 100644 (file)
@@ -837,6 +837,11 @@ void ED_region_init(bContext *C, ARegion *ar)
        
        ar->winx= ar->winrct.xmax - ar->winrct.xmin + 1;
        ar->winy= ar->winrct.ymax - ar->winrct.ymin + 1;
+       
+       /* UI convention */
+       wmLoadIdentity();
+       wmOrtho2(-0.01f, ar->winx-0.01f, -0.01f, ar->winy-0.01f);
+       
 }
 
 
index 38e778848b9942603c577200ac32ad42ad594b2e..09f5640dbf6e294d32c90459df574e631f0bdcdd 100644 (file)
@@ -387,6 +387,14 @@ static void scene_idpoin_handle(bContext *C, ID *id, int event)
        }
 }
 
+static void operator_call_cb(struct bContext *C, void *arg1, void *arg2)
+{
+       wmOperatorType *ot= arg2;
+       
+       if(ot)
+               WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, NULL);
+}
+
 static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
 {
        wmOperatorType *ot = WM_operatortype_first();
@@ -395,19 +403,19 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u
                
                if(BLI_strcasestr(ot->name, str)) {
                        if(ot->poll==NULL || ot->poll((bContext *)C)) {
+                               char name[256];
                                int len= strlen(ot->name);
                                
-                               BLI_strncpy(items->names[items->totitem], ot->name, items->maxstrlen);
+                               /* display name for menu, can hold hotkey */
+                               BLI_strncpy(name, ot->name, 256);
                                
                                /* check for hotkey */
-                               if(len < items->maxstrlen-6) {
-                                       if(WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, items->names[items->totitem]+len+1, items->maxstrlen-len-1)) {
-                                               items->names[items->totitem][len]= '|';
-                                       }
+                               if(len < 256-6) {
+                                       if(WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, &name[len+1], 256-len-1))
+                                               name[len]= '|';
                                }
                                
-                               items->totitem++;
-                               if(items->totitem>=items->maxitem)
+                               if(0==uiSearchItemAdd(items, name, ot))
                                        break;
                        }
                }
@@ -483,7 +491,7 @@ void info_header_buttons(const bContext *C, ARegion *ar)
                static char search[256]= "";
                uiBut *but= uiDefSearchBut(block, search, 0, ICON_PROP_ON, 256, xco+5, yco, 120, 19, "");
                
-               uiButSetSearchFunc(but, operator_search_cb, NULL);
+               uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb);
 
                xco+= 125;
        }
index a76a9ea94bf7bc85c788d2b5a1f2115443674467..b020e4c24a81c4c38851d10db583da5a6a08dff0 100644 (file)
@@ -373,6 +373,93 @@ static void WM_OT_debug_menu(wmOperatorType *ot)
        RNA_def_int(ot->srna, "debugval", 0, -10000, 10000, "Debug Value", "", INT_MIN, INT_MAX);
 }
 
+/* ***************** Search menu ************************* */
+static void operator_call_cb(struct bContext *C, void *arg1, void *arg2)
+{
+       wmOperatorType *ot= arg2;
+       
+       if(ot)
+               WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, NULL);
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
+{
+       wmOperatorType *ot = WM_operatortype_first();
+       
+       for(; ot; ot= ot->next) {
+               
+               if(BLI_strcasestr(ot->name, str)) {
+                       if(ot->poll==NULL || ot->poll((bContext *)C)) {
+                               char name[256];
+                               int len= strlen(ot->name);
+                               
+                               /* display name for menu, can hold hotkey */
+                               BLI_strncpy(name, ot->name, 256);
+                               
+                               /* check for hotkey */
+                               if(len < 256-6) {
+                                       if(WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, &name[len+1], 256-len-1))
+                                               name[len]= '|';
+                               }
+                               
+                               if(0==uiSearchItemAdd(items, name, ot))
+                                       break;
+                       }
+               }
+       }
+}
+
+static uiBlock *wm_block_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);
+       
+       but= uiDefSearchBut(block, search, 0, ICON_PROP_ON, 256, 10, 10, 180, 19, "");
+       uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb);
+       
+       uiPopupBoundsBlock(block, 0.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;
+}
+
+static int wm_search_menu_exec(bContext *C, wmOperator *op)
+{
+       
+       return OPERATOR_FINISHED;       
+}
+
+static int wm_search_menu_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       
+       uiPupBlock(C, wm_block_search_menu, op);
+       
+       return OPERATOR_CANCELLED;
+}
+
+static void WM_OT_search_menu(wmOperatorType *ot)
+{
+       ot->name= "Search Menu";
+       ot->idname= "WM_OT_search_menu";
+       
+       ot->invoke= wm_search_menu_invoke;
+       ot->exec= wm_search_menu_exec;
+       ot->poll= WM_operator_winactive;
+}
+
 
 /* ************ window / screen operator definitions ************** */
 
@@ -1437,6 +1524,7 @@ void wm_operatortype_init(void)
        WM_operatortype_append(WM_OT_save_mainfile);
        WM_operatortype_append(WM_OT_ten_timer);
        WM_operatortype_append(WM_OT_debug_menu);
+       WM_operatortype_append(WM_OT_search_menu);
 }
 
 /* default keymap for windows and screens, only call once per WM */
@@ -1461,6 +1549,7 @@ void wm_window_keymap(wmWindowManager *wm)
        /* debug/testing */
        WM_keymap_verify_item(keymap, "WM_OT_ten_timer", TKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
        WM_keymap_verify_item(keymap, "WM_OT_debug_menu", DKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
+       WM_keymap_verify_item(keymap, "WM_OT_search_menu", FKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
        
 }
 
index 4de7f645bfa65ccdab2a2b073976314dc43d7f4a..39c267b132c38642c4007916a697c932814f830a 100644 (file)
 #define EVT_FILESELECT_EXEC                    3
 #define EVT_FILESELECT_CANCEL          4       
 
+#define EVT_BUT_OPEN   0x5021
 
 #endif /* WM_EVENT_TYPES_H */