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:
authorCampbell Barton <ideasman42@gmail.com>2013-06-13 13:12:53 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-06-13 13:12:53 +0400
commit815a87a652c2f7177e606bfb9911d0711c49b992 (patch)
treeaca1c2b747df615e4f26c3e1d7ab3b75886cd695 /source/blender
parent8b4bca6cf056e81b0ae0e4854d2bd93d08d3a932 (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.c21
-rw-r--r--source/blender/editors/interface/interface_handlers.c96
-rw-r--r--source/blender/editors/interface/interface_intern.h4
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;