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:
-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 */