From ca24322413e78b60ece51902da1b8a9ac22d13ba Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 2 Jun 2009 18:10:06 +0000 Subject: 2.5 Part one of new text button type: SEARCH_MENU This opens a popup showing all matches for a typed string, nice for object names, materials, operators, and so on. Warning: Currently menu doesn't function yet! Only draws choices. As test I've added an operator search button in top bar. It only shows operators that can be used in this context now. Also that is part of the WIP, tomorrow more fun :) --- .../blender/editors/interface/interface_regions.c | 176 +++++++++++++++++++++ 1 file changed, 176 insertions(+) (limited to 'source/blender/editors/interface/interface_regions.c') diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 0109612fdc0..3441abc94bd 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -383,6 +383,182 @@ void ui_tooltip_free(bContext *C, ARegion *ar) ui_remove_temporary_region(C, CTX_wm_screen(C), ar); } + +/************************* Creating Search Box **********************/ + + +typedef struct uiSearchboxData { + rcti bbox; + uiFontStyle fstyle; + uiSearchItems items; +} uiSearchboxData; + +#define SEARCH_ITEMS 10 + +/* ar is the search box itself */ +void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but) +{ + uiSearchboxData *data= ar->regiondata; + + /* callback */ + data->items.totitem= 0; + but->search_func(C, but->search_arg, but->editstr, &data->items); + + ED_region_tag_redraw(ar); +} + +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); + + /* draw text */ + if(data->items.totitem) { + rcti rect; + int a, buth; + + /* 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; aitems.totitem; a++) { + ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], a==0?UI_ACTIVE:0); + rect.ymax -= buth; + rect.ymin -= buth; + } + } +} + +static void ui_searchbox_region_free(ARegion *ar) +{ + uiSearchboxData *data= ar->regiondata; + int a; + + /* free search data */ + for(a=0; aitems.names[a]); + MEM_freeN(data->items.names); + MEM_freeN(data->items.pointers); + + MEM_freeN(data); + ar->regiondata= NULL; +} + +ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) +{ + uiStyle *style= U.uistyles.first; // XXX pass on as arg + static ARegionType type; + ARegion *ar; + uiSearchboxData *data; + float aspect= but->block->aspect; + float x1f, x2f, y1f, y2f; + int x1, x2, y1, y2, winx, winy, ofsx, ofsy; + + /* create area region */ + ar= ui_add_temporary_region(CTX_wm_screen(C)); + + memset(&type, 0, sizeof(ARegionType)); + type.draw= ui_searchbox_region_draw; + type.free= ui_searchbox_region_free; + ar->type= &type; + + /* create searchbox data */ + data= MEM_callocN(sizeof(uiSearchboxData), "uiSearchboxData"); + + /* set font, get bb */ + data->fstyle= style->widget; /* copy struct */ + data->fstyle.align= UI_STYLE_TEXT_CENTER; + ui_fontscale(&data->fstyle.points, aspect); + uiStyleFontSet(&data->fstyle); + + ar->regiondata= data; + + /* compute position */ + ofsx= (but->block->panel)? but->block->panel->ofsx: 0; + ofsy= (but->block->panel)? but->block->panel->ofsy: 0; + + x1f= but->x1; + x2f= but->x2; + y2f= but->y1; + y1f= y2f - SEARCH_ITEMS*MENU_BUTTON_HEIGHT - 2*MENU_SEPR_HEIGHT; + + /* minimal width */ + if(x2f - x1f < 180) x2f= x1f+180; // XXX arbitrary + + /* copy to int, gets projected if possible too */ + x1= x1f; y1= y1f; x2= x2f; y2= y2f; + + if(butregion) { + if(butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) { + UI_view2d_to_region_no_clip(&butregion->v2d, x1f, y1f, &x1, &y1); + UI_view2d_to_region_no_clip(&butregion->v2d, x2f, y2f, &x2, &y2); + } + + x1 += butregion->winrct.xmin; + x2 += butregion->winrct.xmin; + y1 += butregion->winrct.ymin; + y2 += butregion->winrct.ymin; + } + + wm_window_get_size(CTX_wm_window(C), &winx, &winy); + + if(x2 > winx) { + /* super size */ + if(x2 > winx + x1) { + x2= winx; + x1= 0; + } + else { + x1 -= x2-winx; + x2= winx; + } + } + if(y1 < 0) { + y1 += 36; + y2 += 36; + } + + /* widget rect, in region coords */ + data->bbox.xmin= MENU_SHADOW_SIDE; + data->bbox.xmax= x2-x1 + MENU_SHADOW_SIDE; + data->bbox.ymin= MENU_SHADOW_BOTTOM; + data->bbox.ymax= y2-y1 + MENU_SHADOW_BOTTOM; + + /* region bigger for shadow */ + 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; + + /* adds subwindow */ + ED_region_init(C, ar); + + /* notify change and redraw */ + ED_region_tag_redraw(ar); + + /* prepare search data */ + data->items.maxitem= SEARCH_ITEMS; + data->items.maxstrlen= but->hardmax; + data->items.totitem= 0; + data->items.names= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search names"); + data->items.pointers= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search pointers"); + for(x1=0; x1items.names[x1]= MEM_callocN(but->hardmax+1, "search pointers"); + + return ar; +} + +void ui_searchbox_free(bContext *C, ARegion *ar) +{ + ui_remove_temporary_region(C, CTX_wm_screen(C), ar); +} + + /************************* Creating Menu Blocks **********************/ /* position block relative to but, result is in window space */ -- cgit v1.2.3