Some tweaking to uiList dragsize, to make it more reactive to very quick moves.

Note that, even though not officialy supporting non-UI_UNIT_Y height items (other point like scrollbar size would faill too), we try to maintain a not-that-bad behavior in this case, which implies a bit of black magic (esp. as our ref point is the bottom of the list, which moves when it is resized :/)...
This commit is contained in:
Bastien Montagne 2013-08-28 19:23:15 +00:00
parent 2c31bce47f
commit bcf18878a2

@ -3411,11 +3411,18 @@ static int ui_do_but_LISTBOX(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
{ {
uiList *ui_list = but->custom_data; uiList *ui_list = but->custom_data;
int *size = (int *)but->poin; int *size = (int *)but->poin;
int mx, my; int mx, my, raw_dir_sign;
int retval = WM_UI_HANDLER_CONTINUE; int retval = WM_UI_HANDLER_CONTINUE;
mx = event->x; mx = event->x;
my = event->y; 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.
*/
raw_dir_sign = (data->draglasty - my < 0) ? -1 : 1;
data->draglasty = my;
ui_window_to_block(data->region, block, &mx, &my); ui_window_to_block(data->region, block, &mx, &my);
if (data->state == BUTTON_STATE_NUM_EDITING) { if (data->state == BUTTON_STATE_NUM_EDITING) {
@ -3438,49 +3445,53 @@ static int ui_do_but_LISTBOX(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
*/ */
if (data->draglastvalue > 0 && *size == 0) { if (data->draglastvalue > 0 && *size == 0) {
data->draglastvalue = *size; data->draglastvalue = *size;
data->draglasty = data->dragstarty; data->dragstartx = data->dragstarty; /* draglasty already used... */
data->dragstarty = my; data->dragstarty = my;
} }
else { else {
int delta = -(my - data->dragstarty); int delta = data->dragstarty - my;
/* Number of rows to show/hide, UI_UNIT_Y should work nice in most cases. */ /* We only actually do something if the real mousemouve direction matches the "virtual"
delta = (int)floorf(((float)delta / (float)UI_UNIT_Y) + 0.5f); * 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 we are not in autosize mode, default behavior... */
if (*size > 0 && delta != 0) { if (*size > 0 && delta != 0) {
/* Note: In case some items of the list would draw more than UI_UNIT_Y height, we only grow from one /* This prevents some instability in case some items draw more/less than UI_UNIT_Y height. */
* item at a time, to avoid instability! delta = (delta < -5) ? -5 : (delta > 5) ? 5 : delta;
*/ /* We can't use ui_numedit_apply()... */
delta = delta / abs(delta); /* list template will clamp, but we do not want to reach 0 aka autosize mode! */
/* We can't use ui_numedit_apply()... */ *size = max_ii(*size + delta, 1);
/* 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. */ /* Used to detect switch to/from autosize mode. */
data->draglastvalue = *size; data->draglastvalue = *size;
data->dragchange = true; data->dragchange = true;
data->applied = data->applied_interactive = true; data->applied = data->applied_interactive = true;
ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
ED_region_tag_redraw(data->region); ED_region_tag_redraw(data->region);
} }
/* If we are leaving autosize mode (growing dragging), restore to minimal size. */ /* If we are leaving autosize mode (growing dragging), restore to minimal size. */
else if (delta > 0) { else if (delta > 0) {
/* We can't use ui_numedit_apply()... */ /* We can't use ui_numedit_apply()... */
*size = ui_list->dyn_data->visual_height_min; *size = ui_list->dyn_data->visual_height_min;
/* Restore real dragstarty value! */ /* Restore real dragstarty value! */
data->dragstarty = data->draglasty; data->dragstarty = data->dragstartx;
/* Used to detect switch to/from autosize mode. */ /* Used to detect switch to/from autosize mode. */
data->draglastvalue = *size; data->draglastvalue = *size;
data->dragchange = true; data->dragchange = true;
data->applied = data->applied_interactive = true; data->applied = data->applied_interactive = true;
ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
ED_region_tag_redraw(data->region); ED_region_tag_redraw(data->region);
}
} }
} }
} }