You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
311 lines
9.9 KiB
311 lines
9.9 KiB
/* $Id: menulists.c,v 1.2 2003/12/26 02:20:10 stpohle Exp $
|
|
* Menuhandling: lists */
|
|
|
|
|
|
#include "basic.h"
|
|
#include "bomberclone.h"
|
|
#include "menu.h"
|
|
#include "menugui.h"
|
|
|
|
|
|
|
|
/* create a entryimages only in the menudatas.. darf all this only when menu_loop
|
|
* is called */
|
|
void menu_create_list (char *name, int x, int y, int w, int h, _charlist *data, _charlist **selected, int id) {
|
|
int i = menu_getlastitem(menu.items);
|
|
|
|
if (i == -1) { /* first entry in the itemslist */
|
|
menu.items = &menuitems[0];
|
|
i = 0;
|
|
}
|
|
else if (i >= MENU_MAXENTRYS) { /* max items reached, ignore new item */
|
|
d_fatal ("menu_create_entry: MENU_MAXENTRYS reached. Item Ignored\n");
|
|
return;
|
|
}
|
|
else { /* add new item to the list */
|
|
menuitems[i].next = &menuitems[i+1];
|
|
i++;
|
|
}
|
|
|
|
menuitems[i].type = MENU_list;
|
|
menuitems[i].pos.w = (1 + (int)
|
|
((w - menu.listimages[0][0]->w - menu.listimages[0][2]->w) / menu.listimages[0][1]->w))
|
|
* menu.listimages[0][1]->w + menu.listimages[0][0]->w + menu.listimages[0][2]->w;
|
|
menuitems[i].pos.h = (1 + (int)
|
|
((h - menu.listimages[0][0]->h - menu.listimages[0][6]->h) / menu.listimages[0][3]->h))
|
|
* menu.listimages[0][3]->h + menu.listimages[0][0]->h + menu.listimages[0][6]->h;
|
|
if (x != -1)
|
|
menuitems[i].pos.x = x;
|
|
else
|
|
menuitems[i].pos.x = (menu.oldscreenpos.w - 2 * menu.images[0]->w - menuitems[i].pos.w) / 2;
|
|
menuitems[i].pos.y = y;
|
|
menuitems[i].ptrdata = (char *) selected;
|
|
menuitems[i].list = data;
|
|
menuitems[i].id = id;
|
|
strncpy (menuitems[i].label, name, MENU_TITLELEN);
|
|
};
|
|
|
|
|
|
|
|
/* draw only a part of the background */
|
|
void menu_draw_listbackground (_menuitem *mi, SDL_Rect *updaterect) {
|
|
int x,y, dx, dy;
|
|
SDL_Rect dest, cdest, src, csrc, window;
|
|
|
|
y = 0; // start at the updaterect. start pos
|
|
for (; y <= (mi->pos.h - 2*menu.listimages[0][0]->h - 1)/menu.listimages[0][4]->h; y++) {
|
|
x = 0; // start at the updaterect. start pos
|
|
for (; x <= (mi->pos.w - 2*menu.listimages[0][0]->w - 1)/menu.listimages[0][4]->w; x++) {
|
|
dest.x = x * menu.listimages[0][4]->w; // start pos
|
|
dest.y = y * menu.listimages[0][4]->h;
|
|
|
|
dx = (1+x) * menu.listimages[0][4]->w; // end pos
|
|
if (dx >= (mi->pos.w - 2*menu.listimages[0][0]->w))
|
|
dest.w = menu.listimages[0][4]->w - (dx - (mi->pos.w - 2*menu.listimages[0][0]->w));
|
|
else
|
|
dest.w = menu.listimages[0][4]->w;
|
|
|
|
dy = (1+y) * menu.listimages[0][4]->h;
|
|
if (dy >= (mi->pos.h - 2*menu.listimages[0][0]->h))
|
|
dest.h = menu.listimages[0][4]->h - (dy - (mi->pos.h - 2*menu.listimages[0][0]->h));
|
|
else
|
|
dest.h = menu.listimages[0][4]->h;
|
|
|
|
if (dest.w > 0 || dest.h > 0) {
|
|
dest.x += MENUOFFSET_X + mi->pos.x + menu.listimages[0][0]->w;
|
|
dest.y += MENUOFFSET_Y + mi->pos.y + menu.listimages[0][0]->h;
|
|
src.x = 0; src.y = 0; src.h = dest.h; src.w = dest.w;
|
|
|
|
if (updaterect == NULL)
|
|
gfx_blit (menu.listimages[0][4], &src, gfx.screen, &dest, 10000);
|
|
else {
|
|
window = *updaterect;
|
|
window.x += MENUOFFSET_X + mi->pos.x + menu.listimages[0][0]->w;
|
|
window.y += MENUOFFSET_Y + mi->pos.y + menu.listimages[0][0]->h;
|
|
rect_clipping (&src, &dest, &window, &csrc, &cdest);
|
|
if (csrc.w < UINT16_HALF && csrc.h < UINT16_HALF && cdest.w < UINT16_HALF && cdest.h < UINT16_HALF)
|
|
gfx_blit (menu.listimages[1][4], &csrc, gfx.screen, &cdest, 10000);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
/* gets the number of the selected item
|
|
* returns the elemennumber or -1 if none where selected */
|
|
int menu_list_getselected (_menuitem *mi) {
|
|
int res = -1, i;
|
|
_charlist *l;
|
|
|
|
if (mi == NULL || mi->ptrdata == NULL) return -1;
|
|
|
|
for (i = 0, l = mi->list; l != NULL && res == -1; l = l->next, i++)
|
|
if (l == *((_charlist **)mi->ptrdata))
|
|
res = i;
|
|
|
|
return res;
|
|
};
|
|
|
|
|
|
/* gets the number of elements */
|
|
int menu_list_getcount (_menuitem *mi) {
|
|
int count = 0;
|
|
_charlist *l;
|
|
|
|
for (l = mi->list; l != NULL; l = l->next, count++);
|
|
|
|
return count;
|
|
};
|
|
|
|
|
|
/* select the element, return 0 if it was not working else 1 */
|
|
int menu_list_select (_menuitem *mi, int element) {
|
|
_charlist *l = mi->list;
|
|
int i = element;
|
|
|
|
/* set the new element if there is any */
|
|
for (; i > 0 && l != NULL; l = l->next, i--);
|
|
|
|
// check element
|
|
if (l == NULL || i < 0)
|
|
return 0;
|
|
|
|
*(_charlist **)mi->ptrdata = l;
|
|
|
|
menu_draw_list (mi);
|
|
|
|
return 1;
|
|
};
|
|
|
|
|
|
/* select the previous element in the list */
|
|
void menu_list_select_prev (_menuitem *mi) {
|
|
int sel = menu_list_getselected(mi);
|
|
|
|
if (!menu_list_select (mi, sel - 1))
|
|
menu_list_select (mi, menu_list_getcount(mi) - 1);
|
|
};
|
|
|
|
|
|
/* select the next element in the list */
|
|
void menu_list_select_next (_menuitem *mi) {
|
|
int sel = menu_list_getselected (mi);
|
|
|
|
if (!menu_list_select (mi, sel + 1))
|
|
menu_list_select (mi, 0);
|
|
};
|
|
|
|
|
|
|
|
/* this part will draw the textelement in a list */
|
|
void menu_draw_listtext (_menuitem *mi) {
|
|
int count = menu_list_getcount (mi);
|
|
int selected = menu_list_getselected (mi);
|
|
int countvis = (mi->pos.h - menu.listimages[0][0]->h - menu.listimages[0][6]->h)
|
|
/ font[MENU_BUTTON_FONTSIZE].size.y; // number of visible elements
|
|
_charlist *list;
|
|
int maxx, // max chars in X
|
|
dy, // current y position
|
|
dx, // x position, to start drawing
|
|
start;// start with this element
|
|
SDL_Rect wnd; // needed for the selected field to redraw the background
|
|
char text[255];
|
|
|
|
/* start element */
|
|
if (selected == -1)
|
|
start = 0;
|
|
else {
|
|
if ((start = selected - countvis/2) < 0)
|
|
start = 0;
|
|
else if ((start + countvis > count) && (count - countvis >= 0))
|
|
start = count - countvis;
|
|
}
|
|
list = &mi->list[start];
|
|
|
|
/* calculate the max numbers of chars to draw */
|
|
maxx = (mi->pos.w - menu.listimages[0][0]->w - menu.listimages[0][2]->w) / font[MENU_BUTTON_FONTSIZE].size.x;
|
|
|
|
/* calculate start point (y) */
|
|
dy = MENUOFFSET_Y + mi->pos.y + ((mi->pos.h - countvis*font[MENU_BUTTON_FONTSIZE].size.y) / 2);
|
|
|
|
/* draw the elements */
|
|
for (;countvis > 0 && list != NULL; countvis--, list = list->next) {
|
|
|
|
/* calculate dx and print only the text which fixs in the list */
|
|
strncpy (text, list->text, maxx);
|
|
dx = MENUOFFSET_X + mi->pos.x + ((mi->pos.w - strlen (text)*font[MENU_BUTTON_FONTSIZE].size.x) / 2);
|
|
|
|
if (mi->ptrdata != NULL && list == *(_charlist **)mi->ptrdata) {
|
|
// this is the selected element
|
|
wnd.x = menu.listimages[0][0]->w;
|
|
wnd.y = dy - (MENUOFFSET_Y + mi->pos.y + menu.listimages[0][0]->h);
|
|
wnd.w = mi->pos.w - menu.listimages[0][0]->w - menu.listimages[0][2]->w;
|
|
wnd.h = font[MENU_BUTTON_FONTSIZE].size.y;
|
|
menu_draw_listbackground (mi, &wnd);
|
|
font_gfxdraw (dx, dy, text, MENU_BUTTON_FONTSIZE, COLOR_black, 10000);
|
|
}
|
|
else
|
|
font_gfxdraw (dx, dy, text, MENU_BUTTON_FONTSIZE, COLOR_yellow, 10000);
|
|
|
|
dy += font[MENU_BUTTON_FONTSIZE].size.y;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/* draw the menuitem button or bool
|
|
* menuitem->pos.[x|y|w] - Position and X-Size inside the menu
|
|
* label - Text of the Button/Bool
|
|
*/
|
|
void menu_draw_list (_menuitem *mi) {
|
|
int i, focus;
|
|
SDL_Rect dest;
|
|
|
|
if (mi->type != MENU_list)
|
|
return;
|
|
|
|
dest.x = mi->pos.x;
|
|
dest.y = mi->pos.y;
|
|
dest.w = mi->pos.w;
|
|
dest.h = menu.listimages[0][0]->h;
|
|
menu_draw_background (&dest);
|
|
|
|
/* check the focus of the button */
|
|
if (menu.focusvis && mi == menu.focus)
|
|
focus = 1;
|
|
else
|
|
focus = 0;
|
|
|
|
// draw the top left and right of the list
|
|
dest.x = MENUOFFSET_X + mi->pos.x;
|
|
dest.y = MENUOFFSET_Y + mi->pos.y;
|
|
dest.w = menu.listimages[focus][0]->w;
|
|
dest.h = menu.listimages[focus][0]->h;
|
|
gfx_blit (menu.listimages[focus][0], NULL, gfx.screen, &dest, 10000);
|
|
dest.x = MENUOFFSET_X + mi->pos.x + mi->pos.w - menu.listimages[focus][2]->w;
|
|
gfx_blit (menu.listimages[focus][2], NULL, gfx.screen, &dest, 10000);
|
|
// draw the bottom left and right of the list
|
|
dest.y = MENUOFFSET_Y + mi->pos.y + mi->pos.h - menu.listimages[focus][8]->h;
|
|
gfx_blit (menu.listimages[focus][8], NULL, gfx.screen, &dest, 10000);
|
|
dest.x = MENUOFFSET_X + mi->pos.x;
|
|
gfx_blit (menu.listimages[focus][6], NULL, gfx.screen, &dest, 10000);
|
|
|
|
// draw the top and blow center of the list
|
|
for (i = 0; i < ((mi->pos.w -
|
|
(menu.listimages[focus][0]->w + menu.listimages[focus][2]->w))
|
|
/ menu.listimages[focus][1]->w); i++) {
|
|
dest.x = MENUOFFSET_X + mi->pos.x + menu.listimages[focus][0]->w + (i * menu.listimages[focus][1]->w);
|
|
dest.y = MENUOFFSET_Y + mi->pos.y;
|
|
dest.w = menu.listimages[focus][1]->w;
|
|
dest.h = menu.listimages[focus][1]->h;
|
|
gfx_blit (menu.listimages[focus][1], NULL, gfx.screen, &dest, 10000);
|
|
dest.y = MENUOFFSET_Y + mi->pos.y + mi->pos.h - menu.listimages[focus][7]->h;
|
|
gfx_blit (menu.listimages[focus][7], NULL, gfx.screen, &dest, 10000);
|
|
}
|
|
|
|
// draw the left and the right side of the list
|
|
for (i = 0; i < ((mi->pos.h -
|
|
(menu.listimages[focus][0]->h + menu.listimages[focus][6]->h))
|
|
/ menu.listimages[focus][3]->h); i++) {
|
|
dest.x = MENUOFFSET_X + mi->pos.x;
|
|
dest.y = MENUOFFSET_Y + mi->pos.y + menu.listimages[focus][0]->h + (i * menu.listimages[focus][3]->h);
|
|
dest.w = menu.listimages[focus][3]->w;
|
|
dest.h = menu.listimages[focus][3]->h;
|
|
gfx_blit (menu.listimages[focus][3], NULL, gfx.screen, &dest, 10000);
|
|
dest.x = MENUOFFSET_X + mi->pos.x + mi->pos.w - menu.listimages[focus][5]->w;
|
|
gfx_blit (menu.listimages[focus][5], NULL, gfx.screen, &dest, 10000);
|
|
}
|
|
|
|
menu_draw_listbackground (mi, NULL);
|
|
menu_draw_listtext (mi);
|
|
};
|
|
|
|
|
|
/* handle the event on the button
|
|
* on ESC - Reload Old Data
|
|
* on lose focus - Save Data
|
|
*/
|
|
int menu_event_list (_menuitem *mi, SDL_Event *event) {
|
|
switch (event->type) {
|
|
case (SDL_KEYDOWN): /* key was pressed */
|
|
if (event->key.keysym.sym == SDLK_LEFT)
|
|
menu_focus_prev ();
|
|
else if (event->key.keysym.sym == SDLK_RIGHT)
|
|
menu_focus_next ();
|
|
else if (event->key.keysym.sym == SDLK_UP)
|
|
menu_list_select_prev (mi);
|
|
else if (event->key.keysym.sym == SDLK_DOWN)
|
|
menu_list_select_next (mi);
|
|
else if (event->key.keysym.sym == SDLK_RETURN || event->key.keysym.sym == SDLK_RCTRL || event->key.keysym.sym == SDLK_RCTRL)
|
|
return 1;
|
|
break;
|
|
case (SDL_KEYUP):
|
|
keybinput_loop (&mi->keybi, event);
|
|
menu_draw_entry (mi);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
};
|