diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2013-08-28 23:23:15 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2013-08-28 23:23:15 +0400 |
commit | bcf18878a2ed18f16f5f9a4a8896644a3a3ddaae (patch) | |
tree | 4582e7e356dce5c4aea1727e16cca2a5915a8736 /source/blender | |
parent | 2c31bce47f055404218bf6d4d145f29fb81da797 (diff) |
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 :/)...
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 85 |
1 files changed, 48 insertions, 37 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index f30701e07d8..e4e756a8892 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3411,11 +3411,18 @@ 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; + int mx, my, raw_dir_sign; 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. + */ + raw_dir_sign = (data->draglasty - my < 0) ? -1 : 1; + data->draglasty = my; + ui_window_to_block(data->region, block, &mx, &my); 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) { data->draglastvalue = *size; - data->draglasty = data->dragstarty; + data->dragstartx = data->dragstarty; /* draglasty already used... */ data->dragstarty = my; } else { - int delta = -(my - data->dragstarty); - /* 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) { - /* Note: In case some items of the list would draw more than UI_UNIT_Y height, we only grow from one - * item at a time, to avoid instability! - */ - delta = delta / abs(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 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; - /* Restore real dragstarty value! */ - data->dragstarty = data->draglasty; + /* Restore real dragstarty value! */ + data->dragstarty = data->dragstartx; - /* Used to detect switch to/from autosize mode. */ - data->draglastvalue = *size; + /* Used to detect switch to/from autosize mode. */ + data->draglastvalue = *size; - data->dragchange = true; - data->applied = data->applied_interactive = true; + data->dragchange = true; + data->applied = data->applied_interactive = true; - ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; - ED_region_tag_redraw(data->region); + ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; + ED_region_tag_redraw(data->region); + } } } } |