[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [57425] trunk/blender/source/blender/ editors/interface: fix [#35346] Python: still UI issue with popup and dropdown list

Campbell Barton ideasman42 at gmail.com
Thu Jun 13 11:12:53 CEST 2013


Revision: 57425
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=57425
Author:   campbellbarton
Date:     2013-06-13 09:12:53 +0000 (Thu, 13 Jun 2013)
Log Message:
-----------
fix [#35346] Python: still UI issue with popup and dropdown list

Modified Paths:
--------------
    trunk/blender/source/blender/editors/interface/interface.c
    trunk/blender/source/blender/editors/interface/interface_handlers.c
    trunk/blender/source/blender/editors/interface/interface_intern.h

Modified: trunk/blender/source/blender/editors/interface/interface.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface.c	2013-06-13 08:55:51 UTC (rev 57424)
+++ trunk/blender/source/blender/editors/interface/interface.c	2013-06-13 09:12:53 UTC (rev 57425)
@@ -138,15 +138,11 @@
 	*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 @@
 /* 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;

Modified: trunk/blender/source/blender/editors/interface/interface_handlers.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_handlers.c	2013-06-13 08:55:51 UTC (rev 57424)
+++ trunk/blender/source/blender/editors/interface/interface_handlers.c	2013-06-13 09:12:53 UTC (rev 57425)
@@ -108,6 +108,9 @@
 /* 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 @@
  * - 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,39 +6571,63 @@
 	}
 }
 
-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])
 {
-	float p1[2], p2[2], p3[2], p4[2], oldp[2], newp[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];
+	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;
+	p1[0] = rect_px.xmin - margin;
+	p1[1] = rect_px.ymin - margin;
+
+	p2[0] = rect_px.xmax + margin;
+	p2[1] = rect_px.ymin - margin;
 	
-	p3[0] = block->rect.xmax + 20;
-	p3[1] = block->rect.ymax + 20;
+	p3[0] = rect_px.xmax + margin;
+	p3[1] = rect_px.ymax + margin;
 
-	p4[0] = block->rect.xmin - 20;
-	p4[1] = block->rect.ymax + 20;
+	p4[0] = rect_px.xmin - margin;
+	p4[1] = rect_px.ymax + margin;
 
-	oldp[0] = menu->towardsx;
-	oldp[1] = menu->towardsy;
+	/* 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];
 
-	newp[0] = mx;
-	newp[1] = my;
+		sub_v2_v2v2(delta, oldp, cent);
+		normalize_v2(delta);
+		mul_v2_fl(delta, MENU_TOWARDS_WIGGLE_ROOM);
+		add_v2_v2(oldp, delta);
+	}
 
-	if (len_squared_v2v2(oldp, newp) < (4.0f * 4.0f))
-		return menu->dotowards;
-
 	closer = (isect_point_tri_v2(newp, oldp, p1, p2) ||
 	          isect_point_tri_v2(newp, oldp, p2, p3) ||
 	          isect_point_tri_v2(newp, oldp, p3, p4) ||
@@ -6789,7 +6816,7 @@
 		/* 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 @@
 	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 @@
 					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 @@
 	uiBlock *block;
 	uiHandleButtonData *data;
 	uiPopupBlockHandle *submenu;
-	int mx, my, update;
 
 	ar = menu->region;
 	block = ar->uiblocks.first;
@@ -7176,6 +7202,8 @@
 	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 @@
 			}
 		}
 
-		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 @@
 
 	/* 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 @@
 	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 @@
 
 		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;
 }
 

Modified: trunk/blender/source/blender/editors/interface/interface_intern.h
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_intern.h	2013-06-13 08:55:51 UTC (rev 57424)
+++ trunk/blender/source/blender/editors/interface/interface_intern.h	2013-06-13 09:12:53 UTC (rev 57425)
@@ -369,7 +369,7 @@
 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 uiPopupBlockHandle {
 	/* internal */
 	struct ARegion *region;
-	int towardsx, towardsy;
+	float towards_xy[2];
 	double towardstime;
 	bool dotowards;
 




More information about the Bf-blender-cvs mailing list