diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-06-13 13:12:53 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-06-13 13:12:53 +0400 |
commit | 815a87a652c2f7177e606bfb9911d0711c49b992 (patch) | |
tree | aca1c2b747df615e4f26c3e1d7ab3b75886cd695 /source/blender | |
parent | 8b4bca6cf056e81b0ae0e4854d2bd93d08d3a932 (diff) |
fix [#35346] Python: still UI issue with popup and dropdown list
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/interface/interface.c | 21 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 96 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 4 |
3 files changed, 76 insertions, 45 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 1bebfa8a7a0..cb0784397ef 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -138,15 +138,11 @@ void ui_block_to_window(const ARegion *ar, uiBlock *block, int *x, int *y) *y = (int)(fy + 0.5f); } -void ui_block_to_window_rct(const ARegion *ar, uiBlock *block, const rctf *graph, rcti *winr) +void ui_block_to_window_rctf(const ARegion *ar, uiBlock *block, rctf *rct_dst, const rctf *rct_src) { - rctf tmpr; - - tmpr = *graph; - ui_block_to_window_fl(ar, block, &tmpr.xmin, &tmpr.ymin); - ui_block_to_window_fl(ar, block, &tmpr.xmax, &tmpr.ymax); - - BLI_rcti_rctf_copy(winr, &tmpr); + *rct_dst = *rct_src; + ui_block_to_window_fl(ar, block, &rct_dst->xmin, &rct_dst->ymin); + ui_block_to_window_fl(ar, block, &rct_dst->xmax, &rct_dst->ymax); } void ui_window_to_block_fl(const ARegion *ar, uiBlock *block, float *x, float *y) /* for mouse cursor */ @@ -1023,11 +1019,10 @@ void ui_fontscale(short *points, float aspect) /* project button or block (but==NULL) to pixels in regionspace */ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, uiBut *but) { - rctf rectf = (but) ? but->rect : block->rect; - - ui_block_to_window_fl(ar, block, &rectf.xmin, &rectf.ymin); - ui_block_to_window_fl(ar, block, &rectf.xmax, &rectf.ymax); - + rctf rectf; + + ui_block_to_window_rctf(ar, block, &rectf, (but) ? &but->rect : &block->rect); + rectf.xmin -= ar->winrct.xmin; rectf.ymin -= ar->winrct.ymin; rectf.xmax -= ar->winrct.xmin; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 875789c5758..a9378d11cc3 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -108,6 +108,9 @@ static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEve /* pixels to move the cursor to get out of keyboard navigation */ #define BUTTON_KEYNAV_PX_LIMIT 4 +#define MENU_TOWARDS_MARGIN 20 /* margin in pixels */ +#define MENU_TOWARDS_WIGGLE_ROOM 64 /* tolerance in pixels */ + typedef enum uiButtonActivateType { BUTTON_ACTIVATE_OVER, BUTTON_ACTIVATE, @@ -6554,12 +6557,12 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u * - only for 1 second */ -static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, int mx, int my, const bool force) +static void ui_mouse_motion_towards_init_ex(uiPopupBlockHandle *menu, const int xy[2], const bool force) { if (!menu->dotowards || force) { menu->dotowards = true; - menu->towardsx = mx; - menu->towardsy = my; + menu->towards_xy[0] = xy[0]; + menu->towards_xy[1] = xy[1]; if (force) menu->towardstime = DBL_MAX; /* unlimited time */ @@ -6568,38 +6571,62 @@ static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, int mx, int m } } -static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, int mx, int my) +static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, const int xy[2]) +{ + ui_mouse_motion_towards_init_ex(menu, xy, false); +} + +static void ui_mouse_motion_towards_reinit(uiPopupBlockHandle *menu, const int xy[2]) +{ + ui_mouse_motion_towards_init_ex(menu, xy, true); +} + +static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, const int xy[2]) { - float p1[2], p2[2], p3[2], p4[2], oldp[2], newp[2]; + float p1[2], p2[2], p3[2], p4[2]; + float oldp[2] = {menu->towards_xy[0], menu->towards_xy[1]}; + const float newp[2] = {xy[0], xy[1]}; bool closer; + const float margin = MENU_TOWARDS_MARGIN; + rctf rect_px; if (!menu->dotowards) { - return 0; + return false; } + if (len_squared_v2v2(oldp, newp) < (4.0f * 4.0f)) + return menu->dotowards; + /* verify that we are moving towards one of the edges of the * menu block, in other words, in the triangle formed by the * initial mouse location and two edge points. */ - p1[0] = block->rect.xmin - 20; - p1[1] = block->rect.ymin - 20; + ui_block_to_window_rctf(menu->region, block, &rect_px, &block->rect); - p2[0] = block->rect.xmax + 20; - p2[1] = block->rect.ymin - 20; - - p3[0] = block->rect.xmax + 20; - p3[1] = block->rect.ymax + 20; + p1[0] = rect_px.xmin - margin; + p1[1] = rect_px.ymin - margin; - p4[0] = block->rect.xmin - 20; - p4[1] = block->rect.ymax + 20; + p2[0] = rect_px.xmax + margin; + p2[1] = rect_px.ymin - margin; + + p3[0] = rect_px.xmax + margin; + p3[1] = rect_px.ymax + margin; - oldp[0] = menu->towardsx; - oldp[1] = menu->towardsy; + p4[0] = rect_px.xmin - margin; + p4[1] = rect_px.ymax + margin; - newp[0] = mx; - newp[1] = my; + /* allow for some wiggle room, if the user moves a few pixels away, + * don't immediately quit */ + { + const float cent[2] = { + BLI_rctf_cent_x(&rect_px), + BLI_rctf_cent_y(&rect_px)}; + float delta[2]; - if (len_squared_v2v2(oldp, newp) < (4.0f * 4.0f)) - return menu->dotowards; + sub_v2_v2v2(delta, oldp, cent); + normalize_v2(delta); + mul_v2_fl(delta, MENU_TOWARDS_WIGGLE_ROOM); + add_v2_v2(oldp, delta); + } closer = (isect_point_tri_v2(newp, oldp, p1, p2) || isect_point_tri_v2(newp, oldp, p2, p3) || @@ -6789,7 +6816,7 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH /* if a button is activated modal, always reset the start mouse * position of the towards mechanism to avoid loosing focus, * and don't handle events */ - ui_mouse_motion_towards_init(menu, mx, my, true); + ui_mouse_motion_towards_reinit(menu, &event->x); } else if (event->type == TIMER) { if (event->customdata == menu->scrolltimer) @@ -6798,7 +6825,7 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH else { /* for ui_mouse_motion_towards_block */ if (event->type == MOUSEMOVE) { - ui_mouse_motion_towards_init(menu, mx, my, false); + ui_mouse_motion_towards_init(menu, &event->x); /* add menu scroll timer, if needed */ if (ui_menu_scroll_test(block, my)) @@ -7103,7 +7130,7 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK; } else { - ui_mouse_motion_towards_check(block, menu, mx, my); + ui_mouse_motion_towards_check(block, menu, &event->x); /* check mouse moving outside of the menu */ if (inside == 0 && (block->flag & UI_BLOCK_MOVEMOUSE_QUIT)) { @@ -7166,7 +7193,6 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo uiBlock *block; uiHandleButtonData *data; uiPopupBlockHandle *submenu; - int mx, my, update; ar = menu->region; block = ar->uiblocks.first; @@ -7176,6 +7202,8 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo submenu = data->menu; if (submenu->menuretval) { + bool update; + /* 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 ((submenu->menuretval & UI_RETURN_OK) || (submenu->menuretval & UI_RETURN_CANCEL)) { @@ -7185,7 +7213,7 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo } } - update = (submenu->menuretval & UI_RETURN_UPDATE); + update = (submenu->menuretval & UI_RETURN_UPDATE) != 0; /* now let activated button in this menu exit, which * will actually close the submenu too */ @@ -7197,10 +7225,7 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo /* for cases where close does not cascade, allow the user to * move the mouse back towards the menu without closing */ - mx = event->x; - my = event->y; - ui_window_to_block(ar, block, &mx, &my); - ui_mouse_motion_towards_init(menu, mx, my, true); + ui_mouse_motion_towards_reinit(menu, &event->x); if (menu->menuretval) return WM_UI_HANDLER_CONTINUE; @@ -7214,6 +7239,7 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB uiHandleButtonData *data; uiPopupBlockHandle *submenu; int retval = WM_UI_HANDLER_CONTINUE; + bool do_towards_reinit = false; /* check if we have a submenu, and handle events for it first */ but = ui_but_find_activated(menu->region); @@ -7241,12 +7267,22 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB if (do_but_search) { retval = ui_handle_menu_button(C, event, menu); + + /* when there is a active search button and we close it, + * we need to reinit the mouse coords [#35346] */ + if (ui_but_find_activated(menu->region) != but) { + do_towards_reinit = true; + } } else { retval = ui_handle_menu_event(C, event, menu, level); } } + if (do_towards_reinit) { + ui_mouse_motion_towards_reinit(menu, &event->x); + } + return retval; } diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 14a4d42946c..9de608f2730 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -369,7 +369,7 @@ void ui_fontscale(short *points, float aspect); extern bool ui_block_is_menu(const uiBlock *block); extern void ui_block_to_window_fl(const struct ARegion *ar, uiBlock *block, float *x, float *y); extern void ui_block_to_window(const struct ARegion *ar, uiBlock *block, int *x, int *y); -extern void ui_block_to_window_rct(const struct ARegion *ar, uiBlock *block, const rctf *graph, rcti *winr); +extern void ui_block_to_window_rctf(const struct ARegion *ar, uiBlock *block, rctf *rct_dst, const rctf *rct_src); extern void ui_window_to_block_fl(const struct ARegion *ar, uiBlock *block, float *x, float *y); extern void ui_window_to_block(const struct ARegion *ar, uiBlock *block, int *x, int *y); extern void ui_window_to_region(const ARegion *ar, int *x, int *y); @@ -426,7 +426,7 @@ struct uiKeyNavLock { struct uiPopupBlockHandle { /* internal */ struct ARegion *region; - int towardsx, towardsy; + float towards_xy[2]; double towardstime; bool dotowards; |