diff options
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 17 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 14 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 83 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 6 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 141 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 24 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_info/info_header.c | 24 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 89 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_types.h | 1 |
10 files changed, 350 insertions, 54 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 4c2634e2a75..feca59bca30 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -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)); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 69ee0d470d0..68973fe540c 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -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); } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 5617874ab0e..c009c5cfc7b 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -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; } diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index f4483a0540d..db100d8cf86 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -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; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 3441abc94bd..0bde1be2107 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -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); } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 82bfb898f99..47c4a729956 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -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= '|'; } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index ad6b6e04b8e..7d9cc748d05 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -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); + } diff --git a/source/blender/editors/space_info/info_header.c b/source/blender/editors/space_info/info_header.c index 38e778848b9..09f5640dbf6 100644 --- a/source/blender/editors/space_info/info_header.c +++ b/source/blender/editors/space_info/info_header.c @@ -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; } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index a76a9ea94bf..b020e4c24a8 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -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); } diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 4de7f645bfa..39c267b132c 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -238,6 +238,7 @@ #define EVT_FILESELECT_EXEC 3 #define EVT_FILESELECT_CANCEL 4 +#define EVT_BUT_OPEN 0x5021 #endif /* WM_EVENT_TYPES_H */ |