Revision: 17880 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17880 Author: blendix Date: 2008-12-15 20:19:39 +0100 (Mon, 15 Dec 2008)
Log Message: ----------- 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"); Modified Paths: -------------- branches/blender2.5/blender/source/blender/editors/include/UI_interface.h branches/blender2.5/blender/source/blender/editors/interface/interface_handlers.c branches/blender2.5/blender/source/blender/editors/interface/interface_regions.c branches/blender2.5/blender/source/blender/windowmanager/WM_api.h branches/blender2.5/blender/source/blender/windowmanager/WM_types.h branches/blender2.5/blender/source/blender/windowmanager/intern/wm_event_system.c branches/blender2.5/blender/source/blender/windowmanager/intern/wm_operators.c branches/blender2.5/blender/source/blender/windowmanager/wm_event_system.h Modified: branches/blender2.5/blender/source/blender/editors/include/UI_interface.h =================================================================== --- branches/blender2.5/blender/source/blender/editors/include/UI_interface.h 2008-12-15 18:43:18 UTC (rev 17879) +++ branches/blender2.5/blender/source/blender/editors/include/UI_interface.h 2008-12-15 19:19:39 UTC (rev 17880) @@ -185,21 +185,32 @@ /* 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 */ uiBlock *uiBeginBlock(const struct bContext *C, struct ARegion *region, char *name, short dt, short font); @@ -354,6 +365,7 @@ /* 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_userdef(void); void UI_exit(void); -void uiTestRegion(const struct bContext *C); /* XXX 2.50 temporary test */ - #endif /* UI_INTERFACE_H */ Modified: branches/blender2.5/blender/source/blender/editors/interface/interface_handlers.c =================================================================== --- branches/blender2.5/blender/source/blender/editors/interface/interface_handlers.c 2008-12-15 18:43:18 UTC (rev 17879) +++ branches/blender2.5/blender/source/blender/editors/interface/interface_handlers.c 2008-12-15 19:19:39 UTC (rev 17880) @@ -82,14 +82,6 @@ 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 @@ CBData *dragcbd; /* menu open */ - uiHandleMenuData *menu; + uiMenuBlockHandle *menu; int menuretval; /* post activate */ @@ -151,7 +143,9 @@ } 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 @@ } 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 @@ } 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 @@ { 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,15 +2783,18 @@ 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); + /* 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); + } } - else { - if(button_modal_state(data->state)) - WM_event_remove_ui_handler(&data->window->handlers); - } data->state= state; WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL); @@ -2840,20 +2840,20 @@ 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 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 @@ * - 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 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ /* 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 @@ @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs