Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2009-06-03 22:31:37 +0400
committerTon Roosendaal <ton@blender.org>2009-06-03 22:31:37 +0400
commit7c3c9df2c07f739448e804d2ed9fc3d596f5022a (patch)
tree85f0115de74f64caa11300703744a0a4796cfbda /source/blender
parent9b869755867bc47cf48ad2622503a57832745fbf (diff)
2.5
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/include/UI_interface.h17
-rw-r--r--source/blender/editors/interface/interface.c14
-rw-r--r--source/blender/editors/interface/interface_handlers.c83
-rw-r--r--source/blender/editors/interface/interface_intern.h6
-rw-r--r--source/blender/editors/interface/interface_regions.c141
-rw-r--r--source/blender/editors/interface/interface_widgets.c24
-rw-r--r--source/blender/editors/screen/area.c5
-rw-r--r--source/blender/editors/space_info/info_header.c24
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c89
-rw-r--r--source/blender/windowmanager/wm_event_types.h1
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 */