Files
z80/ui_menu.cpp

130 lines
3.9 KiB
C++

#include "ui_menu.h"
#include "ui.h"
#include <vector>
#include <string>
#include "zx_screen.h"
namespace ui
{
namespace menu
{
#define OPTION_TYPE_NORMAL 0
#define OPTION_TYPE_SEPARATOR 1
#define OPTION_TYPE_BOOLEAN 2
struct option_t
{
std::string label;
int type;
int value;
int (*callback)(int);
};
struct menu_t
{
std::string label;
SDL_Rect rect;
std::vector<option_t> options;
};
std::vector<menu_t> menus;
int visible_menu = -1;
int menu_x = 0;
void init()
{
// No se si hi ha algo que fer ací...
}
void show()
{
int mx, my;
Uint32 mb = SDL_GetMouseState(&mx, &my);
mx=mx/CHR_W; my=my/CHR_H;
ui::printrect(0, 0, 59, 1, COLOR_BLACK);
int opt_pos=1;
int index=0;
for (auto menu : menus)
{
const int text_size = (menu.label.size()+2);
uint8_t text_color = COLOR_WHITE;
if (my<1 && mx>=opt_pos && mx<opt_pos+text_size)
{
ui::printrect(opt_pos-1, 0, text_size, 1, COLOR_DARK_BLUE);
text_color = COLOR_WHITE;
visible_menu = index;
menu_x = opt_pos-1;
}
ui::printtxt(opt_pos, 0, menu.label.c_str(), text_color);
opt_pos+=text_size;
index++;
}
if (visible_menu!=-1)
{
opt_pos=2;
menu_t m = menus[visible_menu];
ui::printrect(menu_x, 1, 22, m.options.size()+2, COLOR_BLACK);
ui::box(menu_x, 1, 22, m.options.size()+2, COLOR_WHITE);
for (auto option : m.options)
{
if (option.type!=OPTION_TYPE_SEPARATOR)
{
const int text_size = (option.label.size()+2);
uint8_t text_color = COLOR_WHITE;
if (my==opt_pos && mx>=menu_x && mx<menu_x+text_size)
{
ui::printrect(menu_x+1, opt_pos, 20, 1, COLOR_DARK_BLUE);
text_color = COLOR_WHITE;
}
ui::printtxt(menu_x+1, opt_pos, option.label.c_str(), text_color);
if (option.type==OPTION_TYPE_BOOLEAN)
{
const char *check = option.value?"[X]":"[ ]";
ui::printtxt(menu_x+18, opt_pos, check, text_color);
}
}
opt_pos++;
}
}
}
const int addsubmenu(const char *label)
{
menu_t m;
m.label = label;
m.rect = {0, 0, 100, 0};
menus.push_back(m);
return menus.size()-1;
}
void addoption(int menu, const char *label, int(*callback)(int))
{
option_t op;
op.type = OPTION_TYPE_NORMAL;
op.label = label;
op.callback = callback;
menus[menu].options.push_back(op);
menus[menu].rect.h += 15;
}
void addbooloption(int menu, const char *label, bool default_value, int(*callback)(int))
{
option_t op;
op.type = OPTION_TYPE_BOOLEAN;
op.label = label;
op.value = default_value?1:0;
op.callback = callback;
menus[menu].options.push_back(op);
menus[menu].rect.h += 15;
}
void addseparator(int menu)
{
option_t op;
op.type = OPTION_TYPE_SEPARATOR;
menus[menu].options.push_back(op);
}
}
}