[Add] Significant inprovements to imageArray, including scrollwheel functionality.
This commit is contained in:
parent
88c40143c2
commit
e955b58817
128
src/toolkit.c
128
src/toolkit.c
@ -31,7 +31,8 @@ typedef enum WidgetType_ {
|
||||
typedef enum WidgetStatus_ {
|
||||
WIDGET_STATUS_NORMAL,
|
||||
WIDGET_STATUS_MOUSEOVER,
|
||||
WIDGET_STATUS_MOUSEDOWN
|
||||
WIDGET_STATUS_MOUSEDOWN,
|
||||
WIDGET_STATUS_SCROLLING
|
||||
} WidgetStatus;
|
||||
|
||||
typedef struct Widget_ {
|
||||
@ -135,6 +136,10 @@ static glColour* toolkit_colLight = &cGrey90;
|
||||
static glColour* toolkit_col = &cGrey70;
|
||||
static glColour* toolkit_colDark = &cGrey30;
|
||||
|
||||
/* Converts absolute mouse events to relative mouse events. */
|
||||
static double last_x = 0.; /**< Last x mouse position. */
|
||||
static double last_y = 0.; /**< Last y mouse position. */
|
||||
|
||||
/* Widgets. */
|
||||
static Widget* window_newWidget(Window* w);
|
||||
static void widget_cleanup(Widget* widget);
|
||||
@ -145,6 +150,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_imgarrMove(Widget* iar, double ry);
|
||||
/* Focus. */
|
||||
static void toolkit_nextFocus(void);
|
||||
static int toolkit_isFocusable(Widget* wgt);
|
||||
@ -1188,6 +1194,7 @@ static void toolkit_renderImageArray(Widget* iar, double bx, double by) {
|
||||
double scroll_pos, sx, sy;
|
||||
int xelem, yelem, xspace;
|
||||
glColour* c, *dc, *lc;
|
||||
int is_selected;
|
||||
|
||||
x = bx + iar->x;
|
||||
y = by + iar->y;
|
||||
@ -1202,7 +1209,7 @@ static void toolkit_renderImageArray(Widget* iar, double bx, double by) {
|
||||
yelem = (int)iar->dat.iar.nelements / xelem + 1;
|
||||
|
||||
/* Background. */
|
||||
toolkit_drawRect(x, y, iar->w, iar->h, toolkit_colDark, NULL);
|
||||
toolkit_drawRect(x, y, iar->w, iar->h, &cBlack, NULL);
|
||||
|
||||
/* Scrollbar. */
|
||||
|
||||
@ -1227,10 +1234,17 @@ static void toolkit_renderImageArray(Widget* iar, double bx, double by) {
|
||||
for(j = 0; j < yelem; j++) {
|
||||
xcurs = x + xspace + (double)SCREEN_W/2.;
|
||||
for(i = 0; i < xelem; i++) {
|
||||
/* Outfit elements. */
|
||||
/* Out of elements. */
|
||||
if((j*xelem + i) >= iar->dat.iar.nelements)
|
||||
break;
|
||||
|
||||
is_selected = (iar->dat.iar.selected == j*xelem + i) ? 1 : 0;
|
||||
|
||||
if(is_selected)
|
||||
toolkit_drawRect(xcurs-(double)SCREEN_W/2. + 2.,
|
||||
ycurs-(double)SCREEN_H/2. + 2.,
|
||||
w - 4., h - 4., &cDConsole, NULL);
|
||||
|
||||
/* Image. */
|
||||
if(iar->dat.iar.images[j*xelem + i] != NULL)
|
||||
gl_blitScale(iar->dat.iar.images[j*xelem + i],
|
||||
@ -1239,10 +1253,11 @@ static void toolkit_renderImageArray(Widget* iar, double bx, double by) {
|
||||
|
||||
/* Caption. */
|
||||
gl_printMid(&gl_smallFont, iar->dat.iar.iw, xcurs + 5., ycurs + 5.,
|
||||
&cBlack, iar->dat.iar.captions[j*xelem + i]);
|
||||
(is_selected) ? &cBlack : &cWhite,
|
||||
iar->dat.iar.captions[j*xelem + i]);
|
||||
|
||||
/* Outline. */
|
||||
if(iar->dat.iar.selected == j*xelem + i) {
|
||||
if(is_selected) {
|
||||
lc = &cWhite;
|
||||
c = &cGrey80;
|
||||
dc = &cGrey60;
|
||||
@ -1347,7 +1362,7 @@ int toolkit_input(SDL_Event* event) {
|
||||
static int mouse_down = 0;
|
||||
static void toolkit_mouseEvent(SDL_Event* event) {
|
||||
int i;
|
||||
double x, y;
|
||||
double x, y, rel_x, rel_y;
|
||||
Window* w;
|
||||
Widget* wgt, *wgt_func;
|
||||
|
||||
@ -1359,6 +1374,11 @@ static void toolkit_mouseEvent(SDL_Event* event) {
|
||||
if(event->type == SDL_MOUSEMOTION) {
|
||||
x = (double)event->motion.x;
|
||||
y = SCREEN_H - (double)event->motion.y;
|
||||
/* Create relative events. */
|
||||
rel_x = x - last_x;
|
||||
rel_y = y - last_y;
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
}
|
||||
else if((event->type == SDL_MOUSEBUTTONDOWN) || (event->type == SDL_MOUSEBUTTONUP)) {
|
||||
x = (double)event->button.x;
|
||||
@ -1390,10 +1410,24 @@ static void toolkit_mouseEvent(SDL_Event* event) {
|
||||
case SDL_MOUSEMOTION:
|
||||
if(!mouse_down)
|
||||
wgt->status = WIDGET_STATUS_MOUSEOVER;
|
||||
else {
|
||||
if(wgt->type == WIDGET_IMAGEARRAY)
|
||||
toolkit_imgarrMove(wgt, rel_y);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
wgt->status = WIDGET_STATUS_MOUSEDOWN;
|
||||
|
||||
/* Handle mouse wheel. */
|
||||
if(event->button.button == SDL_BUTTON_WHEELUP) {
|
||||
toolkit_listScroll(wgt, +1);
|
||||
break;
|
||||
}
|
||||
if(event->button.button == SDL_BUTTON_WHEELDOWN) {
|
||||
toolkit_listScroll(wgt, -1);
|
||||
break;
|
||||
}
|
||||
|
||||
if(toolkit_isFocusable(wgt))
|
||||
w->focus = i;
|
||||
|
||||
@ -1407,6 +1441,11 @@ static void toolkit_mouseEvent(SDL_Event* event) {
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
/* Since basically only buttons are handled here, we ignore
|
||||
* it all except the left mouse button. */
|
||||
if(event->button.button != SDL_BUTTON_LEFT)
|
||||
break;
|
||||
|
||||
if(wgt->status == WIDGET_STATUS_MOUSEDOWN) {
|
||||
if((wgt->type == WIDGET_BUTTON) &&
|
||||
(wgt->dat.btn.disabled==0)) {
|
||||
@ -1428,6 +1467,9 @@ static void toolkit_mouseEvent(SDL_Event* event) {
|
||||
else if(!mouse_down)
|
||||
wgt->status = WIDGET_STATUS_NORMAL;
|
||||
}
|
||||
|
||||
/* We trigger this at the end in case it destroys the window that is calling
|
||||
* this function. Otherwise ugly segfaults appear. */
|
||||
if(wgt_func) (*wgt_func->dat.btn.fptr)(wgt_func->name);
|
||||
}
|
||||
|
||||
@ -1568,6 +1610,7 @@ static int toolkit_isFocusable(Widget* wgt) {
|
||||
if(wgt->dat.btn.disabled == 1) return 0;
|
||||
case WIDGET_LIST:
|
||||
case WIDGET_INPUT:
|
||||
case WIDGET_IMAGEARRAY:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
@ -1599,6 +1642,10 @@ static void toolkit_triggerFocus(void) {
|
||||
|
||||
/* Try to scroll up/down by direction. */
|
||||
static void toolkit_listScroll(Widget* wgt, int direction) {
|
||||
double w, h;
|
||||
int xelem, yelem;
|
||||
double hmax;
|
||||
|
||||
if(wgt == NULL) return;
|
||||
|
||||
switch(wgt->type) {
|
||||
@ -1608,6 +1655,28 @@ static void toolkit_listScroll(Widget* wgt, int direction) {
|
||||
wgt->dat.lst.selected = MIN(wgt->dat.lst.selected, wgt->dat.lst.noptions-1);
|
||||
if(wgt->dat.lst.fptr) (*wgt->dat.lst.fptr)(wgt->name);
|
||||
break;
|
||||
|
||||
case WIDGET_IMAGEARRAY:
|
||||
/* Element dimensions. */
|
||||
w = wgt->dat.iar.iw + 5.*2.; /* Includes border. */
|
||||
h = wgt->dat.iar.ih + 5.*2. + 2 + gl_smallFont.h;
|
||||
|
||||
/* Number of elements. */
|
||||
xelem = (int)((wgt->w - 10.) / w);
|
||||
yelem = (int)wgt->dat.iar.nelements / xelem + 1;
|
||||
|
||||
/* Maximum. */
|
||||
hmax = h * (yelem - (int)(wgt->h / h));
|
||||
|
||||
/* Move. */
|
||||
wgt->dat.iar.pos -= direction * h;
|
||||
|
||||
/* Boundry check. */
|
||||
wgt->dat.iar.pos = MAX(wgt->dat.iar.pos, 0.);
|
||||
wgt->dat.iar.pos = MIN(wgt->dat.iar.pos, hmax);
|
||||
if(wgt->dat.iar.fptr)(*wgt->dat.iar.fptr)(wgt->name);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1735,25 +1804,46 @@ static void toolkit_imgarrFocus(Widget* iar, double bx, double by) {
|
||||
y = iar->h - (iar->h - 30.) * scroll_pos - 15.;
|
||||
|
||||
/* Click below the bar. */
|
||||
if(by < y-15.) {
|
||||
iar->dat.iar.pos += h*2.;
|
||||
}
|
||||
if(by < y-15.)
|
||||
toolkit_listScroll(iar, -2);
|
||||
|
||||
/* Click above the bar. */
|
||||
else if(by > y+15.) {
|
||||
iar->dat.iar.pos -= h*2.;
|
||||
} else {
|
||||
|
||||
else if(by > y+15.)
|
||||
toolkit_listScroll(iar, +2);
|
||||
/* Click on the bar. */
|
||||
else
|
||||
iar->status = WIDGET_STATUS_SCROLLING;
|
||||
}
|
||||
}
|
||||
|
||||
/* Boundry check. */
|
||||
if(iar->dat.iar.pos < 0.)
|
||||
iar->dat.iar.pos = 0.;
|
||||
else if(iar->dat.iar.pos > hmax)
|
||||
iar->dat.iar.pos = hmax;
|
||||
/**
|
||||
* @fn static void toolkit_imgarrMove(Widget* iar, double ry)
|
||||
*
|
||||
* @brief Handles image array movement.
|
||||
* @param iar Image Array that has mouse movement.
|
||||
* @param ry Relative Y mouse movement.
|
||||
*/
|
||||
static void toolkit_imgarrMove(Widget* iar, double ry) {
|
||||
double w, h;
|
||||
int xelem, yelem;
|
||||
double hmax;
|
||||
|
||||
if(iar->status == WIDGET_STATUS_SCROLLING) {
|
||||
/* Element dimensions. */
|
||||
w = iar->dat.iar.iw + 5.*2.; /* Includes border. */
|
||||
h = iar->dat.iar.ih + 5.*2. + 2. + gl_smallFont.h;
|
||||
|
||||
/* Number of elements. */
|
||||
xelem = (int)((iar->w - 10.) / w);
|
||||
yelem = (int)iar->dat.iar.nelements / xelem + 1;
|
||||
|
||||
hmax = h * (yelem - (int)(iar->h / h));
|
||||
|
||||
iar->dat.iar.pos -= (ry * (iar->w - 30.) / hmax) / 2.;
|
||||
|
||||
/* Does boundry checks. */
|
||||
toolkit_listScroll(iar, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Return the focused widget. */
|
||||
|
Loading…
Reference in New Issue
Block a user