diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-10-31 15:31:30 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-10-31 15:31:30 +0400 |
commit | 3406586d8829c60a420b26977e160ab53b26a833 (patch) | |
tree | 487c69d97098e6c3e09f6d5afff61e9cc39563fe | |
parent | ebdc9056af48279884c3d014821cb4f75738beed (diff) |
UI: fix for menu scrolling when window is too small. It was not working well
with arbitrary button layouts like multi column menus, because it was making
assumptions about position of previous/next buttons which doesn't work in
general.
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 65 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 30 |
2 files changed, 42 insertions, 53 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 55b20bddd80..e043712810e 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -6322,46 +6322,39 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my) char test = ui_menu_scroll_test(block, my); if (test) { - uiBut *b1 = block->buttons.first; - uiBut *b2 = block->buttons.last; - uiBut *bnext; - uiBut *bprev; - int dy = 0; - - /* get first and last visible buttons */ - while (b1 && ui_but_next(b1) && (b1->flag & UI_SCROLLED)) - b1 = ui_but_next(b1); - while (b2 && ui_but_prev(b2) && (b2->flag & UI_SCROLLED)) - b2 = ui_but_prev(b2); - /* skips separators */ - bnext = ui_but_next(b1); - bprev = ui_but_prev(b2); - - if (bnext == NULL || bprev == NULL) - return 0; - + uiBut *bt; + float dy = 0.0f, ymin = FLT_MAX, ymax = -FLT_MAX; + if (test == 't') { - /* bottom button is first button */ - if (b1->rect.ymin < b2->rect.ymin) - dy = bnext->rect.ymin - b1->rect.ymin; - /* bottom button is last button */ - else - dy = bprev->rect.ymin - b2->rect.ymin; + /* scroll to the top */ + dy = -UI_UNIT_Y; + + /* stop at top item, 1.5 mutliplier makes it snap nicer */ + for (bt = block->buttons.first; bt; bt = bt->next) + ymax = max_ff(ymax, bt->rect.ymax); + + if (ymax + 1.5f*dy < block->rect.ymax) + dy = block->rect.ymax - ymax; } else if (test == 'b') { - /* bottom button is first button */ - if (b1->rect.ymin < b2->rect.ymin) - dy = b1->rect.ymin - bnext->rect.ymin; - /* bottom button is last button */ - else - dy = b2->rect.ymin - bprev->rect.ymin; - } - if (dy) { - - for (b1 = block->buttons.first; b1; b1 = b1->next) { - b1->rect.ymin -= dy; - b1->rect.ymax -= dy; + /* scroll to the bottom */ + dy = UI_UNIT_Y; + + /* stop at bottom item, 1.5 mutliplier makes it snap nicer */ + for (bt = block->buttons.first; bt; bt = bt->next) + ymin = min_ff(ymin, bt->rect.ymin); + + if (ymin + 1.5f*dy > block->rect.ymin) + dy = block->rect.ymin - ymin; + } + + if (dy != 0.0f) { + /* apply scroll offset */ + for (bt = block->buttons.first; bt; bt = bt->next) { + bt->rect.ymin += dy; + bt->rect.ymax += dy; } + /* set flags again */ ui_popup_block_scrolltest(block); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index f522af51c42..c0a8f6582f6 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1570,8 +1570,6 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block) void ui_popup_block_scrolltest(uiBlock *block) { uiBut *bt; - /* Knowing direction is necessary for multi-column menus... */ - int is_flip = (block->direction & UI_TOP) && !(block->flag & UI_BLOCK_NO_FLIP); block->flag &= ~(UI_BLOCK_CLIPBOTTOM | UI_BLOCK_CLIPTOP); @@ -1581,29 +1579,27 @@ void ui_popup_block_scrolltest(uiBlock *block) if (block->buttons.first == block->buttons.last) return; - /* mark buttons that are outside boundary and the ones next to it for arrow(s) */ + /* mark buttons that are outside boundary */ for (bt = block->buttons.first; bt; bt = bt->next) { if (bt->rect.ymin < block->rect.ymin) { bt->flag |= UI_SCROLLED; block->flag |= UI_BLOCK_CLIPBOTTOM; - /* make space for arrow */ - if (bt->rect.ymax < block->rect.ymin + 10) { - if (is_flip && bt->next && bt->next->rect.ymin > bt->rect.ymin) - bt->next->flag |= UI_SCROLLED; - else if (!is_flip && bt->prev && bt->prev->rect.ymin > bt->rect.ymin) - bt->prev->flag |= UI_SCROLLED; - } } if (bt->rect.ymax > block->rect.ymax) { bt->flag |= UI_SCROLLED; block->flag |= UI_BLOCK_CLIPTOP; - /* make space for arrow */ - if (bt->rect.ymin > block->rect.ymax - 10) { - if (!is_flip && bt->next && bt->next->rect.ymax < bt->rect.ymax) - bt->next->flag |= UI_SCROLLED; - else if (is_flip && bt->prev && bt->prev->rect.ymax < bt->rect.ymax) - bt->prev->flag |= UI_SCROLLED; - } + } + } + + /* mark buttons overlapping arrows, if we have them */ + for (bt = block->buttons.first; bt; bt = bt->next) { + if(block->flag & UI_BLOCK_CLIPBOTTOM) { + if (bt->rect.ymin < block->rect.ymin + 12) + bt->flag |= UI_SCROLLED; + } + if(block->flag & UI_BLOCK_CLIPTOP) { + if (bt->rect.ymax > block->rect.ymax - 12) + bt->flag |= UI_SCROLLED; } } } |