diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-12-15 22:19:39 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-12-15 22:19:39 +0300 |
commit | 6283b0c8c5a93baafa040c612ed356472b633582 (patch) | |
tree | 8b38ef8fbc1a0fef93418f249cd0860e5fe3f3a3 | |
parent | aad5e497013dc37acc1913fbbeec4bc0d16ccbc6 (diff) |
UI: getting popup menus to work again, just the internal interface
and event handling code still, how it integrates with operators and
handlers is not worked out yet. For testing, Ctrl+Q quit now shows
a confirmation popup using the following call:
okee_operator(C, "WM_OT_exit_blender", "Quit Blender");
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 22 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 189 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 198 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 7 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 11 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 21 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_system.h | 1 |
8 files changed, 205 insertions, 248 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 5b0f0bbc2bf..fffc161255f 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -185,20 +185,31 @@ void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, fl /* Popup Menu's */ typedef struct uiMenuBlockHandle { + /* internal */ struct ARegion *region; + int towardsx, towardsy; + double towardstime; + int dotowards; + + int popup; + void (*popup_func)(struct bContext *C, void *arg, int event); + void *popup_arg; + + /* return values */ int butretval; int menuretval; - float retvalue; float retvec[3]; } uiMenuBlockHandle; typedef uiBlock* (*uiBlockFuncFP)(struct bContext *C, struct uiMenuBlockHandle *handle, void *arg1); +typedef void (*uiPupmenuFunc)(struct bContext *C, void *arg, int event); extern void pupmenu_set_active(int val); -extern uiMenuBlockHandle *pupmenu_col(struct bContext *C, char *instr, int mx, int my, int maxrow); -extern uiMenuBlockHandle *pupmenu(struct bContext *C, char *instr, int mx, int my); -extern void pupmenu_free(struct bContext *C, uiMenuBlockHandle *handle); +extern void pupmenu_col(struct bContext *C, char *instr, int mx, int my, int maxrow, uiPupmenuFunc func, void *arg); +extern void pupmenu(struct bContext *C, char *instr, int mx, int my, uiPupmenuFunc func, void *arg); + +void okee_operator(struct bContext *C, char *opname, char *str, ...); /* Block */ @@ -354,6 +365,7 @@ void autocomplete_end(AutoComplete *autocpl, char *autoname); /* Handlers for regions with UI blocks */ void UI_add_region_handlers(struct ListBase *handlers); +void UI_add_popup_handlers(struct ListBase *handlers, uiMenuBlockHandle *menu); /* Module initialization and exit */ @@ -361,7 +373,5 @@ void UI_init(void); void UI_init_userdef(void); void UI_exit(void); -void uiTestRegion(const struct bContext *C); /* XXX 2.50 temporary test */ - #endif /* UI_INTERFACE_H */ diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 144e8490661..994fdc18d1a 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -82,14 +82,6 @@ typedef enum uiHandleButtonState { BUTTON_STATE_EXIT } uiHandleButtonState; -typedef struct uiHandleMenuData { - uiMenuBlockHandle *handle; - - int towardsx, towardsy; - double towardstime; - int dotowards; -} uiHandleMenuData; - typedef struct uiHandleButtonData { wmWindow *window; ARegion *region; @@ -126,7 +118,7 @@ typedef struct uiHandleButtonData { CBData *dragcbd; /* menu open */ - uiHandleMenuData *menu; + uiMenuBlockHandle *menu; int menuretval; /* post activate */ @@ -151,7 +143,9 @@ typedef struct uiAfterFunc { } uiAfterFunc; static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state); -static int ui_handler_window(bContext *C, wmEvent *event); +static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata); +static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata); +static void ui_handler_remove_popup(bContext *C, void *userdata); /* ********************** button apply/revert ************************/ @@ -1393,8 +1387,9 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data } if(func) { - data->menu= MEM_callocN(sizeof(uiHandleMenuData), "uiHandleMenuData"); - data->menu->handle= ui_menu_block_create(C, data->region, but, func, arg); + data->menu= ui_menu_block_create(C, data->region, but, func, arg); + if(but->block->handle) + data->menu->popup= but->block->handle->popup; } /* this makes adjacent blocks auto open from now on */ @@ -1411,8 +1406,7 @@ static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data) } if(data->menu) { - ui_menu_block_free(C, data->menu->handle); - MEM_freeN(data->menu); + ui_menu_block_free(C, data->menu); data->menu= NULL; } } @@ -2649,6 +2643,9 @@ static void ui_blocks_set_tooltips(ARegion *ar, int enable) { uiBlock *block; + if(!ar) + return; + /* we disabled buttons when when they were already shown, and * re-enable them on mouse move */ for(block=ar->uiblocks.first; block; block=block->next) @@ -2786,14 +2783,17 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s data->flashtimer= NULL; } - /* add a blocking ui handler at the window handler for blocking, modal states */ - if(button_modal_state(state)) { - if(!button_modal_state(data->state)) - WM_event_add_ui_handler(C, &data->window->handlers, ui_handler_window, NULL); - } - else { - if(button_modal_state(data->state)) - WM_event_remove_ui_handler(&data->window->handlers); + /* add a blocking ui handler at the window handler for blocking, modal states + * but not for popups, because we already have a window level handler*/ + if(!(but->block->handle && but->block->handle->popup)) { + if(button_modal_state(state)) { + if(!button_modal_state(data->state)) + WM_event_add_ui_handler(C, &data->window->handlers, ui_handler_region_menu, NULL, data); + } + else { + if(button_modal_state(data->state)) + WM_event_remove_ui_handler(&data->window->handlers, ui_handler_region_menu, NULL, data); + } } data->state= state; @@ -2840,20 +2840,20 @@ static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *b if(data->state != BUTTON_STATE_EXIT) button_activate_state(C, but, BUTTON_STATE_EXIT); + /* apply the button action or value */ + ui_apply_button(C, block, but, data, 0); + /* if this button is in a menu, this will set the button return * value to the button value and the menu return value to ok, the * menu return value will be picked up and the menu will close */ if(block->handle && !(block->flag & UI_BLOCK_KEEP_OPEN) && !data->cancel) { - uiMenuBlockHandle *handle; + uiMenuBlockHandle *menu; - handle= block->handle; - handle->butretval= data->retval; - handle->menuretval= UI_RETURN_OK; + menu= block->handle; + menu->butretval= data->retval; + menu->menuretval= UI_RETURN_OK; } - /* apply the button action or value */ - ui_apply_button(C, block, but, data, 0); - /* disable tooltips until mousemove */ ui_blocks_set_tooltips(data->region, 0); @@ -3070,27 +3070,27 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but) static void ui_handle_button_closed_submenu(bContext *C, uiBut *but) { uiHandleButtonData *data; - uiMenuBlockHandle *handle; + uiMenuBlockHandle *menu; data= but->active; - handle= data->menu->handle; + menu= data->menu; /* copy over return values from the closing menu */ - if(handle->menuretval == UI_RETURN_OK) { + if(menu->menuretval == UI_RETURN_OK) { if(but->type == COL) - VECCOPY(data->vec, handle->retvec) + VECCOPY(data->vec, menu->retvec) else if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW)) - data->value= handle->retvalue; + data->value= menu->retvalue; } /* now change button state or exit, which will close the submenu */ - if(ELEM(handle->menuretval, UI_RETURN_OK, UI_RETURN_CANCEL)) { - if(handle->menuretval != UI_RETURN_OK) + if(ELEM(menu->menuretval, UI_RETURN_OK, UI_RETURN_CANCEL)) { + if(menu->menuretval != UI_RETURN_OK) data->cancel= 1; button_activate_exit(C, data, but, 1); } - else if(handle->menuretval == UI_RETURN_OUT) + else if(menu->menuretval == UI_RETURN_OUT) button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT); } @@ -3149,7 +3149,7 @@ static uiBut *ui_but_last(uiBlock *block) * - only for 1 second */ -static void ui_mouse_motion_towards_init(uiHandleMenuData *menu, int mx, int my) +static void ui_mouse_motion_towards_init(uiMenuBlockHandle *menu, int mx, int my) { if(!menu->dotowards) { menu->dotowards= 1; @@ -3159,7 +3159,7 @@ static void ui_mouse_motion_towards_init(uiHandleMenuData *menu, int mx, int my) } } -static int ui_mouse_motion_towards_check(uiBlock *block, uiHandleMenuData *menu, int mx, int my) +static int ui_mouse_motion_towards_check(uiBlock *block, uiMenuBlockHandle *menu, int mx, int my) { int fac, dx, dy, domx, domy; @@ -3213,17 +3213,15 @@ static int ui_mouse_motion_towards_check(uiBlock *block, uiHandleMenuData *menu, return menu->dotowards; } -int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, int topmenu) +int ui_handle_menu_event(bContext *C, wmEvent *event, uiMenuBlockHandle *menu, int topmenu) { ARegion *ar; uiBlock *block; uiBut *but, *bt; - uiMenuBlockHandle *handle; int inside, act, count, mx, my, retval; - ar= menu->handle->region; + ar= menu->region; block= ar->uiblocks.first; - handle= menu->handle; act= 0; retval= WM_UI_HANDLER_CONTINUE; @@ -3248,7 +3246,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in case LEFTARROWKEY: if(event->val && (block->flag & UI_BLOCK_LOOP)) if(BLI_countlist(&block->saferct) > 0) - handle->menuretval= UI_RETURN_OUT; + menu->menuretval= UI_RETURN_OUT; retval= WM_UI_HANDLER_BREAK; break; @@ -3372,18 +3370,19 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in if(ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) && event->val) if(saferct && !BLI_in_rctf(&saferct->parent, event->x, event->y)) - handle->menuretval= UI_RETURN_OK; + menu->menuretval= UI_RETURN_OK; } - if(handle->menuretval); + if(menu->menuretval); else if(event->type==ESCKEY && event->val) { /* esc cancels this and all preceding menus */ - handle->menuretval= UI_RETURN_CANCEL; + menu->menuretval= UI_RETURN_CANCEL; } else if(ELEM(event->type, RETKEY, PADENTER) && event->val) { - /* enter will always close this block, but note that the event - * can still get pass through so the button is executed */ - handle->menuretval= UI_RETURN_OK; + /* enter will always close this block, but we let the event + * get handled by the button if it is activated */ + if(!ui_but_find_activated(ar)) + menu->menuretval= UI_RETURN_OK; } else { ui_mouse_motion_towards_check(block, menu, mx, my); @@ -3407,7 +3406,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in /* strict check, and include the parent rect */ if(!menu->dotowards && !saferct) - handle->menuretval= (block->flag & UI_BLOCK_KEEP_OPEN)? UI_RETURN_OK: UI_RETURN_OUT; + menu->menuretval= (block->flag & UI_BLOCK_KEEP_OPEN)? UI_RETURN_OK: UI_RETURN_OUT; else if(menu->dotowards && event->type==MOUSEMOVE) retval= WM_UI_HANDLER_BREAK; } @@ -3417,7 +3416,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in /* if we are inside the region and didn't handle the event yet, lets * pass it on to buttons inside this region */ - if((inside && !handle->menuretval && retval == WM_UI_HANDLER_CONTINUE) || event->type == TIMER) { + if((inside && !menu->menuretval && retval == WM_UI_HANDLER_CONTINUE) || event->type == TIMER) { but= ui_but_find_activated(ar); if(but) @@ -3429,7 +3428,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in /* if we set a menu return value, ensure we continue passing this on to * lower menus and buttons, so always set continue then, and if we are * inside the region otherwise, ensure we swallow the event */ - if(handle->menuretval) + if(menu->menuretval) return WM_UI_HANDLER_CONTINUE; else if(inside) return WM_UI_HANDLER_BREAK; @@ -3437,29 +3436,27 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiHandleMenuData *menu, in return retval; } -static int ui_handle_menu_closed_submenu(bContext *C, uiHandleMenuData *menu) +static int ui_handle_menu_closed_submenu(bContext *C, uiMenuBlockHandle *menu) { ARegion *ar; uiBut *but; uiBlock *block; uiHandleButtonData *data; - uiMenuBlockHandle *handle, *subhandle; + uiMenuBlockHandle *submenu; - ar= menu->handle->region; + ar= menu->region; block= ar->uiblocks.first; - handle= menu->handle; but= ui_but_find_activated(ar); data= but->active; - subhandle= data->menu->handle; - if(subhandle->menuretval) { + if(submenu->menuretval) { /* first decide if we want to close our own menu cascading, if * so pass on the sub menu return value to our own menu handle */ - if(ELEM(subhandle->menuretval, UI_RETURN_OK, UI_RETURN_CANCEL)) { + if(ELEM(submenu->menuretval, UI_RETURN_OK, UI_RETURN_CANCEL)) { if(!(block->flag & UI_BLOCK_KEEP_OPEN)) { - handle->menuretval= subhandle->menuretval; - handle->butretval= data->retval; + menu->menuretval= submenu->menuretval; + menu->butretval= data->retval; } } @@ -3468,21 +3465,21 @@ static int ui_handle_menu_closed_submenu(bContext *C, uiHandleMenuData *menu) ui_handle_button_closed_submenu(C, but); } - if(handle->menuretval) + if(menu->menuretval) return WM_UI_HANDLER_CONTINUE; else return WM_UI_HANDLER_BREAK; } -static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiHandleMenuData *menu) +static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiMenuBlockHandle *menu) { uiBut *but; uiHandleButtonData *data; - uiHandleMenuData *submenu; + uiMenuBlockHandle *submenu; int retval= WM_UI_HANDLER_CONTINUE; /* check if we have a submenu, and handle events for it first */ - but= ui_but_find_activated(menu->handle->region); + but= ui_but_find_activated(menu->region); data= (but)? but->active: NULL; submenu= (data)? data->menu: NULL; @@ -3491,7 +3488,7 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiHandleMenuDa /* now handle events for our own menu */ if(retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) { - if(submenu && submenu->handle->menuretval) + if(submenu && submenu->menuretval) retval= ui_handle_menu_closed_submenu(C, menu); else retval= ui_handle_menu_event(C, event, menu, (submenu == NULL)); @@ -3502,7 +3499,7 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiHandleMenuDa /* *************** UI event handlers **************** */ -static int ui_handler_region(bContext *C, wmEvent *event) +static int ui_handler_region(bContext *C, wmEvent *event, void *userdata) { ARegion *ar; uiBut *but; @@ -3533,7 +3530,7 @@ static int ui_handler_region(bContext *C, wmEvent *event) return retval; } -static void ui_handler_remove_region(bContext *C) +static void ui_handler_remove_region(bContext *C, void *userdata) { bScreen *sc; ARegion *ar; @@ -3553,7 +3550,7 @@ static void ui_handler_remove_region(bContext *C) ui_apply_but_funcs_after(C); } -static int ui_handler_window(bContext *C, wmEvent *event) +static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata) { ARegion *ar; uiBut *but; @@ -3563,11 +3560,10 @@ static int ui_handler_window(bContext *C, wmEvent *event) /* here we handle buttons at the window level, modal, for example * while number sliding, text editing, or when a menu block is open */ ar= C->region; - - /* handle activated button events */ but= ui_but_find_activated(ar); if(but) { + /* handle activated button events */ data= but->active; if(data->state == BUTTON_STATE_MENU_OPEN) { @@ -3577,7 +3573,7 @@ static int ui_handler_window(bContext *C, wmEvent *event) /* handle events for the activated button */ if(retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) { - if(data->menu->handle->menuretval) + if(data->menu->menuretval) ui_handle_button_closed_submenu(C, but); else ui_handle_button_event(C, event, but); @@ -3600,9 +3596,52 @@ static int ui_handler_window(bContext *C, wmEvent *event) return WM_UI_HANDLER_BREAK; } +static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata) +{ + uiMenuBlockHandle *menu= userdata; + + ui_handle_menus_recursive(C, event, menu); + + /* free if done, does not free handle itself */ + if(menu->menuretval) { + ui_menu_block_free(C, menu); + WM_event_remove_ui_handler(&C->window->handlers, ui_handler_popup, ui_handler_remove_popup, menu); + + if(menu->menuretval == UI_RETURN_OK && menu->popup_func) + menu->popup_func(C, menu->popup_arg, menu->retvalue); + } + else { + /* re-enable tooltips */ + if(event->type == MOUSEMOVE && (event->x!=event->prevx || event->y!=event->prevy)) + ui_blocks_set_tooltips(menu->region, 1); + } + + /* delayed apply callbacks */ + ui_apply_but_funcs_after(C); + + /* we block all events, this is modal interaction */ + return WM_UI_HANDLER_BREAK; +} + +static void ui_handler_remove_popup(bContext *C, void *userdata) +{ + uiMenuBlockHandle *menu= userdata; + + /* free menu block if window is closed for some reason */ + ui_menu_block_free(C, menu); + + /* delayed apply callbacks */ + ui_apply_but_funcs_after(C); +} + void UI_add_region_handlers(ListBase *handlers) { - WM_event_remove_ui_handler(handlers); - WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region); + WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL); + WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region, NULL); +} + +void UI_add_popup_handlers(ListBase *handlers, uiMenuBlockHandle *menu) +{ + WM_event_add_ui_handler(NULL, handlers, ui_handler_popup, ui_handler_remove_popup, menu); } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 2e01eb8c8b1..0c7613bbfcd 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1,4 +1,5 @@ +#include <stdarg.h> #include <stdlib.h> #include <string.h> @@ -585,10 +586,8 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar) { uiBlock *block; - for(block=ar->uiblocks.first; block; block=block->next) { - wm_subwindow_getmatrix(C->window, ar->swinid, block->winmat); + for(block=ar->uiblocks.first; block; block=block->next) uiDrawBlock(block); - } } uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut *but, uiBlockFuncFP block_func, void *arg) @@ -666,6 +665,10 @@ uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut * /* adds subwindow */ ED_region_init(C, ar); + + /* get winmat now that we actually have the subwindow */ + wm_subwindow_set(C->window, ar->swinid); + wm_subwindow_getmatrix(C->window, ar->swinid, block->winmat); /* notify change and redraw */ WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL); @@ -1604,9 +1607,10 @@ uiBlock *ui_block_func_PUPMENUCOL(bContext *C, uiMenuBlockHandle *handle, void * return block; } -uiMenuBlockHandle *pupmenu_col(bContext *C, char *instr, int mx, int my, int maxrow) +void pupmenu_col(bContext *C, char *instr, int mx, int my, int maxrow, uiPupmenuFunc func, void *arg) { uiPupMenuInfo info; + uiMenuBlockHandle *menu; memset(&info, 0, sizeof(info)); info.instr= instr; @@ -1614,181 +1618,61 @@ uiMenuBlockHandle *pupmenu_col(bContext *C, char *instr, int mx, int my, int max info.my= my; info.maxrow= maxrow; - return ui_menu_block_create(C, NULL, NULL, ui_block_func_PUPMENUCOL, &info); + menu= ui_menu_block_create(C, NULL, NULL, ui_block_func_PUPMENUCOL, &info); + menu->popup= 1; + + UI_add_popup_handlers(&C->window->handlers, menu); + WM_event_add_mousemove(C); + + menu->popup_func= func; + menu->popup_arg= arg; } -uiMenuBlockHandle *pupmenu(bContext *C, char *instr, int mx, int my) +void pupmenu(bContext *C, char *instr, int mx, int my, uiPupmenuFunc func, void *arg) { uiPupMenuInfo info; + uiMenuBlockHandle *menu; memset(&info, 0, sizeof(info)); info.instr= instr; info.mx= mx; info.my= my; - return ui_menu_block_create(C, NULL, NULL, ui_block_func_PUPMENU, &info); -} + menu= ui_menu_block_create(C, NULL, NULL, ui_block_func_PUPMENU, &info); + menu->popup= 1; + UI_add_popup_handlers(&C->window->handlers, menu); + WM_event_add_mousemove(C); -void pupmenu_free(bContext *C, uiMenuBlockHandle *handle) -{ - ui_menu_block_free(C, handle); + menu->popup_func= func; + menu->popup_arg= arg; } -/*************** Temporary Buttons Tests **********************/ - -static uiBlock *test_submenu(bContext *C, uiMenuBlockHandle *handle, void *arg) +/* XXX test */ +static void operator_callback(bContext *C, void *arg, int retval) { - ARegion *ar= handle->region; - uiBlock *block; - short yco= 0, menuwidth=120; - - block= uiBeginBlock(C, ar, "test_viewmenu", UI_EMBOSSP, UI_HELV); - //uiBlockSetButmFunc(block, do_test_viewmenu, NULL); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation", 0, yco-=20, - menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); - - uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Seconds|T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, ""); - - uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, - "Only Selected Data Keys|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, ""); - - uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Next Marker|PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Prev Marker|PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Next Key|Ctrl PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Prev Key|Ctrl PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, ""); - - uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center View|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, - "Lock Time to Other Windows|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, ""); - - uiBlockSetDirection(block, UI_RIGHT); + const char *opname= arg; - uiTextBoundsBlock(block, 50); - uiEndBlock(C, block); - - return block; + if(retval > 0) + WM_operator_call(C, opname); } -static uiBlock *test_viewmenu(bContext *C, uiMenuBlockHandle *handle, void *arg_area) +void okee_operator(bContext *C, char *opname, char *str, ...) { - ScrArea *area= arg_area; - ARegion *ar= handle->region; - uiBlock *block; - short yco= 0, menuwidth=120; - - block= uiBeginBlock(C, ar, "test_viewmenu", UI_EMBOSSP, UI_HELV); - //uiBlockSetButmFunc(block, do_test_viewmenu, NULL); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation", 0, yco-=20, - menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); - - uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Seconds|T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, ""); - - uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, - "Only Selected Data Keys|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, ""); - - uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Next Marker|PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Prev Marker|PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Next Key|Ctrl PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Prev Key|Ctrl PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, ""); - - uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center View|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, - "Lock Time to Other Windows|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, ""); - - uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefIconTextBlockBut(block, test_submenu, NULL, ICON_RIGHTARROW_THIN, "Sub Menu", 0, yco-=20, 120, 19, ""); - uiDefIconTextBlockBut(block, test_submenu, NULL, ICON_RIGHTARROW_THIN, "Sub Menu", 0, yco-=20, 120, 19, ""); - uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - - if(area->headertype==HEADERTOP) { - uiBlockSetDirection(block, UI_DOWN); - } - else { - uiBlockSetDirection(block, UI_TOP); - uiBlockFlipOrder(block); - } - - uiTextBoundsBlock(block, 50); - uiEndBlock(C, block); - - return block; -} - -void uiTestRegion(const bContext *C) -{ - uiBlock *block; - short xco; - - static float testcol[3]; - static char testtext[64]; - static float testnumf=5.0f; - static short testchoice= 0, testtog= 0, testicontog= 0; - -#if 0 - static CurveMapping *cumap= NULL; - static ColorBand *coba= NULL; -#endif - - block= uiBeginBlock(C, C->region, "header buttons", UI_EMBOSS, UI_HELV); - - uiDefPulldownBut(block, test_viewmenu, C->area, "View", - 13, 1, 50, 24, ""); - - uiDefBut(block, BUT, 31415, "Type BUT", - 13+50+5, 3, 80, 20, NULL, 0, 0, 0, 0, "A tooltip."); - uiDefButS(block, MENU, 31416, "Gather Method%t|Raytrace %x0|Approximate %x1", - 13+50+5+80+5, 3, 100, 20, &testchoice, 0, 0, 0, 0, "Method for occlusion gathering"); - uiDefButBitS(block, TOG, 1, 31417, "Pixel Cache", - 13+50+5+80+5+100+5, 3, 100, 20, &testtog, 0, 0, 0, 0, "Cache AO results in pixels and interpolate over neighbouring pixels for speedup."); - - uiDefBut(block, TEX, 31418, "Text: ", - 13+50+5+80+5+100+5+100+5, 3, 200, 20, testtext, 0, sizeof(testtext), 0, 0, "User defined text"); - - uiDefButF(block, NUMSLI, 31419, "Slider: ", - 13+50+5+80+5+100+5+100+5+200+5, 3, 150, 20, &testnumf, 0.0, 10.0, 0, 0, "Some tooltip."); - uiDefButF(block, NUM, 31419, "N: ", - 13+50+5+80+5+100+5+100+5+200+5+150+5, 3, 100, 20, &testnumf, 0.0, 10.0, 0, 0, "Some tooltip."); + va_list ap; + char *s, buf[512]; + int mx, my; - uiDefButF(block, COL, 3142, "", - 13+50+5+80+5+100+5+100+5+200+5+150+5+100+5, 3, 100, 20, testcol, 0, 0, 0, 0 /*B_BANDCOL*/, ""); + mx= C->window->eventstate->x; + my= C->window->eventstate->y; - xco = 13+50+5+80+5+100+5+100+5+200+5+150+5+100+5+100+5; - uiDefIconButBitS(block, ICONTOG, 1 /*AUTOKEY_ON*/, REDRAWINFO, ICON_PYTHON, - xco, 3, 20, 20, &testicontog, 0, 0, 0, 0, "Automatic keyframe insertion for Objects and Bones"); - xco += 5; + va_start(ap, str); -#if 0 - if(!cumap) { - cumap= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); - cumap->flag &= ~CUMA_DO_CLIP; - } - if(!coba) - coba= add_colorband(0); + s= buf; + s += sprintf(s, "OK? %%i%d%%t|", ICON_HELP); + vsprintf(s, str, ap); + va_end(ap); - uiDefBut(block, BUT_CURVE, 3143, "", - 13+400, 33, 100, 100, cumap, 0.0f, 1.0f, 0, 0, ""); - uiDefBut(block, BUT_COLORBAND, 3143, "", - 13+400+100+10, 33, 150, 30, coba, 0.0f, 1.0f, 0, 0, ""); -#endif - - uiEndBlock(C, block); - uiDrawBlock(block); + pupmenu(C, buf, mx, my, operator_callback, opname); } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index b0fdcee2c04..a2544e3e6e5 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -79,8 +79,11 @@ struct wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBa void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap); struct wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers, - int (*func)(bContext *C, struct wmEvent *event), void (*remove)(bContext *C)); -void WM_event_remove_ui_handler(ListBase *handlers); + int (*func)(bContext *C, struct wmEvent *event, void *userdata), + void (*remove)(bContext *C, void *userdata), void *userdata); +void WM_event_remove_ui_handler(ListBase *handlers, + int (*func)(bContext *C, struct wmEvent *event, void *userdata), + void (*remove)(bContext *C, void *userdata), void *userdata); struct wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOperator *op); void WM_event_remove_handlers(bContext *C, ListBase *handlers); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index b301976aeae..7307cb4bf23 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -91,8 +91,8 @@ typedef struct wmEvent { #define WM_UI_HANDLER_CONTINUE 0 #define WM_UI_HANDLER_BREAK 1 -typedef int (*wmUIHandlerFunc)(bContext *C, struct wmEvent *event); -typedef void (*wmUIHandlerRemoveFunc)(bContext *C); +typedef int (*wmUIHandlerFunc)(bContext *C, struct wmEvent *event, void *userdata); +typedef void (*wmUIHandlerRemoveFunc)(bContext *C, void *userdata); /* ************** Notifiers ****************** */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index aeb3899409f..a5cbc835168 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -393,7 +393,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) if(handler->ui_area) C->area= handler->ui_area; if(handler->ui_region) C->region= handler->ui_region; - handler->ui_remove(C); + handler->ui_remove(C, handler->ui_userdata); C->area= area; C->region= region; @@ -494,7 +494,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve if(handler->ui_area) C->area= handler->ui_area; if(handler->ui_region) C->region= handler->ui_region; - retval= handler->ui_handle(C, event); + retval= handler->ui_handle(C, event, handler->ui_userdata); /* putting back screen context */ C->area= area; @@ -748,11 +748,12 @@ void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap) } } -wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove) +wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata) { wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event ui handler"); handler->ui_handle= func; handler->ui_remove= remove; + handler->ui_userdata= userdata; handler->ui_area= (C)? C->area: NULL; handler->ui_region= (C)? C->region: NULL; @@ -761,12 +762,12 @@ wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers, wmUIHan return handler; } -void WM_event_remove_ui_handler(ListBase *handlers) +void WM_event_remove_ui_handler(ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata) { wmEventHandler *handler; for(handler= handlers->first; handler; handler= handler->next) { - if(handler->ui_handle) { + if(handler->ui_handle == func && handler->ui_remove == remove && handler->ui_userdata == userdata) { BLI_remlink(handlers, handler); wm_event_free_handler(handler); MEM_freeN(handler); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5dd36d737b1..5ed29a28abd 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -46,6 +46,8 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "UI_interface.h" + #include "WM_api.h" #include "WM_types.h" @@ -141,6 +143,22 @@ static void WM_OT_exit_blender(wmOperatorType *ot) ot->poll= WM_operator_winactive; } +static int exit_okee_blender_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + okee_operator(C, "WM_OT_exit_blender", "Quit Blender"); + + return OPERATOR_FINISHED; +} + +static void WM_OT_exit_okee_blender(wmOperatorType *ot) +{ + ot->name= "Exit Blender"; + ot->idname= "WM_OT_exit_okee_blender"; + + ot->invoke= exit_okee_blender_invoke; + ot->poll= WM_operator_winactive; +} + /* ************ window gesture operator-callback definitions ************** */ /* * These are default callbacks for use in operators requiring gesture input @@ -346,6 +364,7 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_save_homefile); WM_operatortype_append(WM_OT_window_fullscreen_toggle); WM_operatortype_append(WM_OT_exit_blender); + WM_operatortype_append(WM_OT_exit_okee_blender); WM_operatortype_append(WM_OT_tweak_gesture); } @@ -358,6 +377,6 @@ void wm_window_keymap(wmWindowManager *wm) WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); WM_keymap_verify_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_verify_item(keymap, "WM_OT_exit_okee_blender", QKEY, KM_PRESS, KM_CTRL, 0); } diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index d4dddf8e222..26c0b23df30 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -55,6 +55,7 @@ typedef struct wmEventHandler { /* ui handler */ wmUIHandlerFunc ui_handle; /* callback receiving events */ wmUIHandlerRemoveFunc ui_remove; /* callback when handler is removed */ + void *ui_userdata; /* user data pointer */ struct ScrArea *ui_area; /* for derived/modal handlers */ struct ARegion *ui_region; /* for derived/modal handlers */ |