[Add] Significant inprovements to imageArray, including scrollwheel functionality.
This commit is contained in:
parent
88c40143c2
commit
e955b58817
132
src/toolkit.c
132
src/toolkit.c
@ -31,7 +31,8 @@ typedef enum WidgetType_ {
|
|||||||
typedef enum WidgetStatus_ {
|
typedef enum WidgetStatus_ {
|
||||||
WIDGET_STATUS_NORMAL,
|
WIDGET_STATUS_NORMAL,
|
||||||
WIDGET_STATUS_MOUSEOVER,
|
WIDGET_STATUS_MOUSEOVER,
|
||||||
WIDGET_STATUS_MOUSEDOWN
|
WIDGET_STATUS_MOUSEDOWN,
|
||||||
|
WIDGET_STATUS_SCROLLING
|
||||||
} WidgetStatus;
|
} WidgetStatus;
|
||||||
|
|
||||||
typedef struct Widget_ {
|
typedef struct Widget_ {
|
||||||
@ -135,6 +136,10 @@ static glColour* toolkit_colLight = &cGrey90;
|
|||||||
static glColour* toolkit_col = &cGrey70;
|
static glColour* toolkit_col = &cGrey70;
|
||||||
static glColour* toolkit_colDark = &cGrey30;
|
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. */
|
/* Widgets. */
|
||||||
static Widget* window_newWidget(Window* w);
|
static Widget* window_newWidget(Window* w);
|
||||||
static void widget_cleanup(Widget* widget);
|
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 int toolkit_inputInput(Uint8 type, Widget* inp, SDLKey key);
|
||||||
static void toolkit_mouseEvent(SDL_Event* event);
|
static void toolkit_mouseEvent(SDL_Event* event);
|
||||||
static int toolkit_keyEvent(SDL_Event* event);
|
static int toolkit_keyEvent(SDL_Event* event);
|
||||||
|
static void toolkit_imgarrMove(Widget* iar, double ry);
|
||||||
/* Focus. */
|
/* Focus. */
|
||||||
static void toolkit_nextFocus(void);
|
static void toolkit_nextFocus(void);
|
||||||
static int toolkit_isFocusable(Widget* wgt);
|
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;
|
double scroll_pos, sx, sy;
|
||||||
int xelem, yelem, xspace;
|
int xelem, yelem, xspace;
|
||||||
glColour* c, *dc, *lc;
|
glColour* c, *dc, *lc;
|
||||||
|
int is_selected;
|
||||||
|
|
||||||
x = bx + iar->x;
|
x = bx + iar->x;
|
||||||
y = by + iar->y;
|
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;
|
yelem = (int)iar->dat.iar.nelements / xelem + 1;
|
||||||
|
|
||||||
/* Background. */
|
/* Background. */
|
||||||
toolkit_drawRect(x, y, iar->w, iar->h, toolkit_colDark, NULL);
|
toolkit_drawRect(x, y, iar->w, iar->h, &cBlack, NULL);
|
||||||
|
|
||||||
/* Scrollbar. */
|
/* Scrollbar. */
|
||||||
|
|
||||||
@ -1227,10 +1234,17 @@ static void toolkit_renderImageArray(Widget* iar, double bx, double by) {
|
|||||||
for(j = 0; j < yelem; j++) {
|
for(j = 0; j < yelem; j++) {
|
||||||
xcurs = x + xspace + (double)SCREEN_W/2.;
|
xcurs = x + xspace + (double)SCREEN_W/2.;
|
||||||
for(i = 0; i < xelem; i++) {
|
for(i = 0; i < xelem; i++) {
|
||||||
/* Outfit elements. */
|
/* Out of elements. */
|
||||||
if((j*xelem + i) >= iar->dat.iar.nelements)
|
if((j*xelem + i) >= iar->dat.iar.nelements)
|
||||||
break;
|
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. */
|
/* Image. */
|
||||||
if(iar->dat.iar.images[j*xelem + i] != NULL)
|
if(iar->dat.iar.images[j*xelem + i] != NULL)
|
||||||
gl_blitScale(iar->dat.iar.images[j*xelem + i],
|
gl_blitScale(iar->dat.iar.images[j*xelem + i],
|
||||||
@ -1239,10 +1253,11 @@ static void toolkit_renderImageArray(Widget* iar, double bx, double by) {
|
|||||||
|
|
||||||
/* Caption. */
|
/* Caption. */
|
||||||
gl_printMid(&gl_smallFont, iar->dat.iar.iw, xcurs + 5., ycurs + 5.,
|
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. */
|
/* Outline. */
|
||||||
if(iar->dat.iar.selected == j*xelem + i) {
|
if(is_selected) {
|
||||||
lc = &cWhite;
|
lc = &cWhite;
|
||||||
c = &cGrey80;
|
c = &cGrey80;
|
||||||
dc = &cGrey60;
|
dc = &cGrey60;
|
||||||
@ -1347,7 +1362,7 @@ int toolkit_input(SDL_Event* event) {
|
|||||||
static int mouse_down = 0;
|
static int mouse_down = 0;
|
||||||
static void toolkit_mouseEvent(SDL_Event* event) {
|
static void toolkit_mouseEvent(SDL_Event* event) {
|
||||||
int i;
|
int i;
|
||||||
double x, y;
|
double x, y, rel_x, rel_y;
|
||||||
Window* w;
|
Window* w;
|
||||||
Widget* wgt, *wgt_func;
|
Widget* wgt, *wgt_func;
|
||||||
|
|
||||||
@ -1359,6 +1374,11 @@ static void toolkit_mouseEvent(SDL_Event* event) {
|
|||||||
if(event->type == SDL_MOUSEMOTION) {
|
if(event->type == SDL_MOUSEMOTION) {
|
||||||
x = (double)event->motion.x;
|
x = (double)event->motion.x;
|
||||||
y = SCREEN_H - (double)event->motion.y;
|
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)) {
|
else if((event->type == SDL_MOUSEBUTTONDOWN) || (event->type == SDL_MOUSEBUTTONUP)) {
|
||||||
x = (double)event->button.x;
|
x = (double)event->button.x;
|
||||||
@ -1390,10 +1410,24 @@ static void toolkit_mouseEvent(SDL_Event* event) {
|
|||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
if(!mouse_down)
|
if(!mouse_down)
|
||||||
wgt->status = WIDGET_STATUS_MOUSEOVER;
|
wgt->status = WIDGET_STATUS_MOUSEOVER;
|
||||||
|
else {
|
||||||
|
if(wgt->type == WIDGET_IMAGEARRAY)
|
||||||
|
toolkit_imgarrMove(wgt, rel_y);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
wgt->status = WIDGET_STATUS_MOUSEDOWN;
|
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))
|
if(toolkit_isFocusable(wgt))
|
||||||
w->focus = i;
|
w->focus = i;
|
||||||
|
|
||||||
@ -1407,6 +1441,11 @@ static void toolkit_mouseEvent(SDL_Event* event) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_MOUSEBUTTONUP:
|
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->status == WIDGET_STATUS_MOUSEDOWN) {
|
||||||
if((wgt->type == WIDGET_BUTTON) &&
|
if((wgt->type == WIDGET_BUTTON) &&
|
||||||
(wgt->dat.btn.disabled==0)) {
|
(wgt->dat.btn.disabled==0)) {
|
||||||
@ -1428,6 +1467,9 @@ static void toolkit_mouseEvent(SDL_Event* event) {
|
|||||||
else if(!mouse_down)
|
else if(!mouse_down)
|
||||||
wgt->status = WIDGET_STATUS_NORMAL;
|
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);
|
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;
|
if(wgt->dat.btn.disabled == 1) return 0;
|
||||||
case WIDGET_LIST:
|
case WIDGET_LIST:
|
||||||
case WIDGET_INPUT:
|
case WIDGET_INPUT:
|
||||||
|
case WIDGET_IMAGEARRAY:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
@ -1599,6 +1642,10 @@ static void toolkit_triggerFocus(void) {
|
|||||||
|
|
||||||
/* Try to scroll up/down by direction. */
|
/* Try to scroll up/down by direction. */
|
||||||
static void toolkit_listScroll(Widget* wgt, int direction) {
|
static void toolkit_listScroll(Widget* wgt, int direction) {
|
||||||
|
double w, h;
|
||||||
|
int xelem, yelem;
|
||||||
|
double hmax;
|
||||||
|
|
||||||
if(wgt == NULL) return;
|
if(wgt == NULL) return;
|
||||||
|
|
||||||
switch(wgt->type) {
|
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);
|
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);
|
if(wgt->dat.lst.fptr) (*wgt->dat.lst.fptr)(wgt->name);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1735,25 +1804,46 @@ static void toolkit_imgarrFocus(Widget* iar, double bx, double by) {
|
|||||||
y = iar->h - (iar->h - 30.) * scroll_pos - 15.;
|
y = iar->h - (iar->h - 30.) * scroll_pos - 15.;
|
||||||
|
|
||||||
/* Click below the bar. */
|
/* Click below the bar. */
|
||||||
if(by < y-15.) {
|
if(by < y-15.)
|
||||||
iar->dat.iar.pos += h*2.;
|
toolkit_listScroll(iar, -2);
|
||||||
}
|
|
||||||
|
|
||||||
/* Click above the bar. */
|
/* Click above the bar. */
|
||||||
else if(by > y+15.) {
|
else if(by > y+15.)
|
||||||
iar->dat.iar.pos -= h*2.;
|
toolkit_listScroll(iar, +2);
|
||||||
} else {
|
/* 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. */
|
/* Return the focused widget. */
|
||||||
|
Loading…
Reference in New Issue
Block a user