[Bf-blender-cvs] [a1031d5] master: Fix T37739: uiList drag-resize was not working as expected outside of panels.

Bastien Montagne noreply at git.blender.org
Tue Dec 10 16:22:58 CET 2013


Commit: a1031d5dd529885fea53b0908a912585d65c4567
Author: Bastien Montagne
Date:   Tue Dec 10 16:06:20 2013 +0100
http://developer.blender.org/rBa1031d5dd529885fea53b0908a912585d65c4567

Fix T37739: uiList drag-resize was not working as expected outside of panels.

Patch by Brecht, with minor edits by myself, thanks a lot!

Tech details: previous drag-resize handling code was based on the assumption that coords
returned by ui_window_to_block() was relative to the bottom on the uiBlock.
This is in fact completly eroneous, usually this func does not translate at all the coords,
it merely rescale them - except for blocks inside panels, where returned values are relative
to the left/bottom corner of the panel... Pretty confusing, solution for now is to store ref mouse
position in window space, and convert them to block each time, just like current mouse pos.

===================================================================

M	source/blender/editors/interface/interface_handlers.c

===================================================================

diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index f858e58..61761d7 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -174,6 +174,7 @@ typedef struct uiHandleButtonData {
 	int draglastx, draglasty;
 	int dragstartx, dragstarty;
 	int draglastvalue;
+	int dragstartvalue;
 	bool dragchange, draglock;
 	int dragsel;
 	float dragf, dragfstart;
@@ -3585,18 +3586,20 @@ static int ui_do_but_LISTBOX(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
 {
 	uiList *ui_list = but->custom_data;
 	int *size = (int *)but->poin;
-	int mx, my, raw_dir_sign;
+	int mx, my, dragx, dragy;
 	int retval = WM_UI_HANDLER_CONTINUE;
 
-	mx = event->x;
-	my = event->y;
-
-	/* We find the direction of the mouse since last time, before converting coordinates into block's space.
-	 * We'll use it to avoid flickering in case some rows are higher than UI_UNIT_Y.
+	/* Note: Having to store org point in window space and recompute it to block "space" each time
+	 *       is not ideal, but this is a way to hack around behavior of ui_window_to_block(), which
+	 *       returns different results when the block is inside a panel or not...
+	 *       See T37739.
 	 */
-	raw_dir_sign = (data->draglasty - my < 0) ? -1 : 1;
-	data->draglasty = my;
+	dragx = data->dragstartx;
+	dragy = data->dragstarty;
+	ui_window_to_block(data->region, block, &dragx, &dragy);
 
+	mx = event->x;
+	my = event->y;
 	ui_window_to_block(data->region, block, &mx, &my);
 
 	if (data->state == BUTTON_STATE_NUM_EDITING) {
@@ -3622,52 +3625,40 @@ static int ui_do_but_LISTBOX(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
 			if (data->draglastvalue > 0 && *size == 0) {
 				data->draglastvalue = *size;
 				data->dragstartx = data->dragstarty;  /* draglasty already used... */
-				data->dragstarty = my;
+				data->dragstarty = event->y;
 			}
 			else {
-				int delta = data->dragstarty - my;
-				/* We only actually do something if the real mousemouve direction matches the "virtual"
-				 * mousemove direction in current block's space. This avoids flickering when drag-resizing lists with
-				 * items drawing higher that UI_UNIT_Y.
-				 */
-				if (delta * raw_dir_sign > 0) {
-					/* Number of rows to show/hide, UI_UNIT_Y should work nice in most cases. */
-					delta = (int)floorf(((float)delta / (float)UI_UNIT_Y) + 0.5f);
-
-					/* If we are not in autosize mode, default behavior... */
-					if (*size > 0 && delta != 0) {
-						/* This prevents some instability in case some items draw more/less than UI_UNIT_Y height. */
-						delta = (delta < -5) ? -5 : (delta > 5) ? 5 : delta;
-						/* We can't use ui_numedit_apply()... */
-						/* list template will clamp, but we do not want to reach 0 aka autosize mode! */
-						*size = max_ii(*size + delta, 1);
-
-						/* Used to detect switch to/from autosize mode. */
-						data->draglastvalue = *size;
-
-						data->dragchange = true;
-						data->applied = data->applied_interactive = true;
-
-						ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
-						ED_region_tag_redraw(data->region);
-					}
-					/* If we are leaving autosize mode (growing dragging), restore to minimal size. */
-					else if (delta > 0) {
-						/* We can't use ui_numedit_apply()... */
-						*size = ui_list->dyn_data->visual_height_min;
+				int newsize = *size;
+				int diff = dragy - my;
 
-						/* Restore real dragstarty value! */
-						data->dragstarty = data->dragstartx;
+				diff = (int)floorf(((float)diff / (float)UI_UNIT_Y) + 0.5f);
 
-						/* Used to detect switch to/from autosize mode. */
-						data->draglastvalue = *size;
+				/* If we are not in autosize mode, default behavior... */
+				if (*size > 0) {
+					/* list template will clamp, but we do not want to reach 0 aka autosize mode! */
+					newsize = data->dragstartvalue + diff;
+				}
+				/* If we are leaving autosize mode (growing dragging), restore to minimal size. */
+				else if (diff > 0) {
+					/* We can't use ui_numedit_apply()... */
+					newsize = ui_list->dyn_data->visual_height_min;
 
-						data->dragchange = true;
-						data->applied = data->applied_interactive = true;
+					/* Restore real dragstarty value! */
+					data->dragstarty = data->dragstartx;
+				}
 
-						ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
-						ED_region_tag_redraw(data->region);
-					}
+				/* Used to detect switch to/from autosize mode. */
+				data->draglastvalue = newsize;
+
+				if (newsize != *size) {
+					*size = newsize;
+
+					/* We can't use ui_numedit_apply()... */
+					data->dragchange = true;
+					data->applied = data->applied_interactive = true;
+
+					ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
+					ED_region_tag_redraw(data->region);
 				}
 			}
 		}
@@ -6877,12 +6868,13 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
 		button_activate_state(C, but, BUTTON_STATE_INIT);
 
 		data = but->active;
-		data->dragstarty = my;
+		data->dragstarty = event->y;
 
 		button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
 
 		/* Again, have to override values set by ui_numedit_begin, because our listbox button also has a rnapoin... */
 		*size = data->origvalue = (double)dyn_data->visual_height;
+		data->dragstartvalue = *size;
 		ui_list->flag |= UILST_RESIZING;
 
 		retval = WM_UI_HANDLER_BREAK;




More information about the Bf-blender-cvs mailing list