diff options
Diffstat (limited to 'source/blender/editors/interface/interface_regions.c')
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 176 |
1 files changed, 176 insertions, 0 deletions
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; 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; + } + } +} + +static void ui_searchbox_region_free(ARegion *ar) +{ + uiSearchboxData *data= ar->regiondata; + int a; + + /* free search data */ + for(a=0; a<SEARCH_ITEMS; a++) + MEM_freeN(data->items.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; x1<SEARCH_ITEMS; x1++) + data->items.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 */ |