diff --git a/src/toolkit.c b/src/toolkit.c index 21b25d4..9bc0320 100644 --- a/src/toolkit.c +++ b/src/toolkit.c @@ -151,6 +151,7 @@ static void toolkit_setPos(Window* wdw, Widget* wgt, int x, int y); static int toolkit_inputInput(Uint8 type, Widget* inp, SDLKey key); static void toolkit_mouseEvent(SDL_Event* event); static int toolkit_keyEvent(SDL_Event* event); +static void toolkit_listMove(Widget* lst, double ay); static void toolkit_imgarrMove(Widget* iar, double ry); static void toolkit_clearKey(void); /* Focus. */ @@ -1166,7 +1167,7 @@ static void toolkit_renderList(Widget* lst, double bx, double by) { w -= 10.; scroll_pos = (double)(lst->dat.lst.pos * (2 + gl_defFont.h)); - scroll_pos /= ((double)lst->dat.lst.height - lst->h); + scroll_pos /= (double)lst->dat.lst.height - lst->h; toolkit_drawScrollbar(x + lst->w - 10., y, 10., lst->h, scroll_pos); } @@ -1488,6 +1489,8 @@ static void toolkit_mouseEvent(SDL_Event* event) { if(!mouse_down) wgt->status = WIDGET_STATUS_MOUSEOVER; else { + if(wgt->type == WIDGET_LIST) + toolkit_listMove(wgt, y-wgt->y); if(wgt->type == WIDGET_IMAGEARRAY) toolkit_imgarrMove(wgt, rel_y); } @@ -1834,14 +1837,31 @@ int toolkit_getListPos(const unsigned int wid, char* name) { /* List mouse even focus. */ static void toolkit_listFocus(Widget* lst, double bx, double by) { - (void)bx; int i; + double y, w; + double scroll_pos; - i = (lst->h - by) / (gl_defFont.h + 2.); - if(i< lst->dat.lst.noptions) { - /* Should not be out of boundaries. */ - lst->dat.lst.selected = i; - toolkit_listScroll(lst, 0); /* Check boundaries and trigger callback. */ + if(bx < w) { + i = lst->dat.lst.pos + (lst->h - by) / (gl_defFont.h + 2.); + if(i < lst->dat.lst.noptions) { /* Shouldn't be out of bounds. */ + lst->dat.lst.selected = i; + toolkit_listScroll(lst, 0); /* Check boundries and triggers callback. */ + } + } else { + /* Get bar position (center). */ + scroll_pos = (double)(lst->dat.lst.pos * (2 + gl_defFont.h)); + scroll_pos /= (double)lst->dat.lst.height - lst->h; + y = (lst->h - 30.) * (1.-scroll_pos) + 15.; + + /* Click below the bar. */ + if(by < y-15.) + toolkit_listScroll(lst, -5); + /* Click above the bar. */ + else if(by > y+15.) + toolkit_listScroll(lst, +5); + /* Click on the bar. */ + else + lst->status = WIDGET_STATUS_SCROLLING; } } @@ -1917,6 +1937,41 @@ static void toolkit_imgarrFocus(Widget* iar, double bx, double by) { } } +/** + * @brief Handle list movement. + * @param lst List that has mouse movement. + * @param ay Absolute Y mouse movement. + */ +static void toolkit_listMove(Widget* lst, double ay) { + Window* wdw; + int psel; + double p; + int h; + + if(lst->status == WIDGET_STATUS_SCROLLING) { + h = lst->h / (2 + gl_defFont.h) - 1; + + /* Save previous position. */ + psel = lst->dat.lst.pos; + + /* Find absolute position. */ + p = (lst->h - ay) / lst->h * (lst->dat.lst.height - lst->h); + p /= (2 + gl_defFont.h); + lst->dat.lst.pos = (int)round(p); + + /* Does boundry checks. */ + lst->dat.lst.selected = MAX(lst->dat.lst.selected, lst->dat.lst.pos); + lst->dat.lst.selected = MIN(lst->dat.lst.selected, lst->dat.lst.pos+h); + + /* Run change if position changed. */ + if(lst->dat.lst.selected != psel) + if(lst->dat.lst.fptr) { + wdw = &windows[nwindows-1]; /* Get active windw. */ + (*lst->dat.lst.fptr)(wdw->id, lst->name); + } + } +} + /** * @fn static void toolkit_imgarrMove(Widget* iar, double ry) *