mirror of
https://github.com/nielssp/csol
synced 2024-11-16 19:49:01 +01:00
Menu system wip.
This commit is contained in:
parent
4c3c30b6cb
commit
327a7e577d
3 changed files with 201 additions and 4 deletions
|
@ -25,4 +25,4 @@ install(TARGETS csol DESTINATION bin COMPONENT binaries)
|
||||||
install(FILES "${CMAKE_BINARY_DIR}/csolrc" DESTINATION /etc/xdg/csol COMPONENT config)
|
install(FILES "${CMAKE_BINARY_DIR}/csolrc" DESTINATION /etc/xdg/csol COMPONENT config)
|
||||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/themes" DESTINATION /etc/xdg/csol COMPONENT config)
|
install(DIRECTORY "${CMAKE_BINARY_DIR}/themes" DESTINATION /etc/xdg/csol COMPONENT config)
|
||||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/games" DESTINATION /etc/xdg/csol COMPONENT config)
|
install(DIRECTORY "${CMAKE_BINARY_DIR}/games" DESTINATION /etc/xdg/csol COMPONENT config)
|
||||||
install(FILES "${CMAKE_BINARY_DIR}/doc/csol.6" DESTINATION ${CMAKE_INSTALL_PREFIX}/man/man6)
|
install(FILES "${PROJECT_SOURCE_DIR}/doc/csol.6" DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man6)
|
||||||
|
|
|
@ -31,6 +31,9 @@ struct color {
|
||||||
short red;
|
short red;
|
||||||
short green;
|
short green;
|
||||||
short blue;
|
short blue;
|
||||||
|
short old_red;
|
||||||
|
short old_green;
|
||||||
|
short old_blue;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct color_pair {
|
struct color_pair {
|
||||||
|
|
200
src/ui.c
200
src/ui.c
|
@ -99,6 +99,58 @@ struct color_name default_colors[] = {
|
||||||
{NULL, -1}
|
{NULL, -1}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct Menu Menu;
|
||||||
|
|
||||||
|
struct Menu {
|
||||||
|
char *label;
|
||||||
|
char *key;
|
||||||
|
Menu *submenu;
|
||||||
|
};
|
||||||
|
|
||||||
|
Menu file_menu[] = {
|
||||||
|
{"Select &game", NULL, NULL},
|
||||||
|
{"Select &theme", NULL, NULL},
|
||||||
|
{"&Quit", "q", NULL},
|
||||||
|
{NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
Menu game_menu[] = {
|
||||||
|
{"&Undo", "u", NULL},
|
||||||
|
{"&Redo", "U", NULL},
|
||||||
|
{"&Auto", "a", NULL},
|
||||||
|
{"From &Stock", "s", NULL},
|
||||||
|
{"From &Waste", "w", NULL},
|
||||||
|
{"R&estart", "r", NULL},
|
||||||
|
{NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
Menu settings_menu[] = {
|
||||||
|
{"Smart &cursor", "^S", NULL},
|
||||||
|
{"&Vertical stabilization", "^V", NULL},
|
||||||
|
{"Show &score", "", NULL},
|
||||||
|
{"Show &menubar", "", NULL},
|
||||||
|
{NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
Menu help_menu[] = {
|
||||||
|
{"&How to play", "?", NULL},
|
||||||
|
{"&About csol", "", NULL},
|
||||||
|
{NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
Menu main_menu[] = {
|
||||||
|
{"&File", NULL, file_menu},
|
||||||
|
{"&Game", NULL, game_menu},
|
||||||
|
{"&Settings", NULL, settings_menu},
|
||||||
|
{"&Help", NULL, help_menu},
|
||||||
|
{NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
Menu *menu_selection[] = {
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
static void print_card_name_l(int y, int x, Card *card, Theme *theme) {
|
static void print_card_name_l(int y, int x, Card *card, Theme *theme) {
|
||||||
if (y < 0 || y >= win_h) {
|
if (y < 0 || y >= win_h) {
|
||||||
return;
|
return;
|
||||||
|
@ -519,7 +571,78 @@ static int ui_victory(Pile *piles, Theme *theme, int32_t score, int32_t time, St
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_menu_label(const char *label) {
|
||||||
|
while (*label) {
|
||||||
|
if (*label == '&') {
|
||||||
|
label++;
|
||||||
|
attron(A_BOLD);
|
||||||
|
if (*label) {
|
||||||
|
printw("%c", *label);
|
||||||
|
label++;
|
||||||
|
}
|
||||||
|
attroff(A_BOLD);
|
||||||
|
} else {
|
||||||
|
printw("%c", *label);
|
||||||
|
label++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ui_menu(int y, int x, Menu *menu, Menu **selection) {
|
||||||
|
Menu *item;
|
||||||
|
int max_length = 0;
|
||||||
|
int height = 0;
|
||||||
|
for (item = menu; item->label; item++) {
|
||||||
|
int length = strlen(item->label);
|
||||||
|
if (item->key) {
|
||||||
|
length += 2 + strlen(item->key);
|
||||||
|
}
|
||||||
|
if (length > max_length) {
|
||||||
|
max_length = length;
|
||||||
|
}
|
||||||
|
height++;
|
||||||
|
}
|
||||||
|
ui_box(y++, x, height + 2, max_length + 4, 1);
|
||||||
|
for (item = menu; item->label; item++) {
|
||||||
|
if (item == *selection) {
|
||||||
|
attron(A_REVERSE);
|
||||||
|
}
|
||||||
|
mvprintw(y, x + 1, " %*s ", max_length, item->key ? item-> key : "");
|
||||||
|
move(y, x + 2);
|
||||||
|
print_menu_label(item->label);
|
||||||
|
if (item == *selection) {
|
||||||
|
attroff(A_REVERSE);
|
||||||
|
}
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ui_menubar() {
|
||||||
|
Menu *item;
|
||||||
|
move(0, 0);
|
||||||
|
for (item = main_menu; item->label; item++) {
|
||||||
|
if (item == menu_selection[0]) {
|
||||||
|
int x1 = getcurx(stdscr), x2;
|
||||||
|
attron(A_REVERSE);
|
||||||
|
printw(" ");
|
||||||
|
print_menu_label(item->label);
|
||||||
|
printw(" ");
|
||||||
|
attroff(A_REVERSE);
|
||||||
|
x2 = getcurx(stdscr);
|
||||||
|
if (item->submenu) {
|
||||||
|
ui_menu(1, x1, item->submenu, &menu_selection[1]);
|
||||||
|
}
|
||||||
|
move(0, x2);
|
||||||
|
} else {
|
||||||
|
printw(" ");
|
||||||
|
print_menu_label(item->label);
|
||||||
|
printw(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int ui_loop(Game *game, Theme *theme, Pile *piles) {
|
static int ui_loop(Game *game, Theme *theme, Pile *piles) {
|
||||||
|
Menu *menu_item;
|
||||||
MEVENT mouse;
|
MEVENT mouse;
|
||||||
int new_game = 1;
|
int new_game = 1;
|
||||||
int move_made = 0;
|
int move_made = 0;
|
||||||
|
@ -563,6 +686,7 @@ static int ui_loop(Game *game, Theme *theme, Pile *piles) {
|
||||||
print_pile(pile, theme);
|
print_pile(pile, theme);
|
||||||
}
|
}
|
||||||
attron(COLOR_PAIR(COLOR_PAIR_BACKGROUND));
|
attron(COLOR_PAIR(COLOR_PAIR_BACKGROUND));
|
||||||
|
ui_menubar();
|
||||||
if (show_score) {
|
if (show_score) {
|
||||||
mvprintw(win_h - 1, 0, "Score: %d", game_score);
|
mvprintw(win_h - 1, 0, "Score: %d", game_score);
|
||||||
}
|
}
|
||||||
|
@ -642,6 +766,51 @@ static int ui_loop(Game *game, Theme *theme, Pile *piles) {
|
||||||
} else {
|
} else {
|
||||||
ch = getch();
|
ch = getch();
|
||||||
}
|
}
|
||||||
|
if (menu_selection[0]) {
|
||||||
|
switch (ch) {
|
||||||
|
case KEY_LEFT:
|
||||||
|
if (menu_selection[0] > main_menu) {
|
||||||
|
menu_selection[0]--;
|
||||||
|
} else {
|
||||||
|
for (menu_item = main_menu; menu_item->label; menu_item++) {
|
||||||
|
menu_selection[0] = menu_item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
menu_selection[1] = NULL;
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
menu_selection[0]++;
|
||||||
|
if (!menu_selection[0]->label) {
|
||||||
|
menu_selection[0] = main_menu;
|
||||||
|
}
|
||||||
|
menu_selection[1] = NULL;
|
||||||
|
break;
|
||||||
|
case KEY_UP:
|
||||||
|
if (menu_selection[1] && menu_selection[1] > menu_selection[0]->submenu) {
|
||||||
|
menu_selection[1]--;
|
||||||
|
} else if (menu_selection[0]->submenu) {
|
||||||
|
for (menu_item = menu_selection[0]->submenu; menu_item->label; menu_item++) {
|
||||||
|
menu_selection[1] = menu_item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
if (menu_selection[1]) {
|
||||||
|
menu_selection[1]++;
|
||||||
|
if (!menu_selection[1]->label) {
|
||||||
|
menu_selection[1] = menu_selection[0]->submenu;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
menu_selection[1] = menu_selection[0]->submenu;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 27:
|
||||||
|
menu_selection[0] = NULL;
|
||||||
|
menu_selection[1] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'h':
|
case 'h':
|
||||||
case KEY_LEFT:
|
case KEY_LEFT:
|
||||||
|
@ -960,10 +1129,29 @@ static int ui_loop(Game *game, Theme *theme, Pile *piles) {
|
||||||
redo_move();
|
redo_move();
|
||||||
clear();
|
clear();
|
||||||
break;
|
break;
|
||||||
|
case KEY_F(10):
|
||||||
|
menu_selection[0] = main_menu;
|
||||||
|
break;
|
||||||
case 27:
|
case 27:
|
||||||
clear();
|
|
||||||
selection = NULL;
|
selection = NULL;
|
||||||
selection_pile = NULL;
|
selection_pile = NULL;
|
||||||
|
ch = getch();
|
||||||
|
for (menu_item = main_menu; menu_item->label; menu_item++) {
|
||||||
|
char *l = menu_item->label;
|
||||||
|
while (*l) {
|
||||||
|
if (*l == '&') {
|
||||||
|
if (tolower(l[1]) == ch) {
|
||||||
|
menu_selection[0] = menu_item;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
l++;
|
||||||
|
}
|
||||||
|
if (menu_selection[0]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clear();
|
||||||
break;
|
break;
|
||||||
case 19: /* ^s */
|
case 19: /* ^s */
|
||||||
smart_cursor = !smart_cursor;
|
smart_cursor = !smart_cursor;
|
||||||
|
@ -1218,6 +1406,7 @@ static void convert_theme(Theme *theme) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ui_main(Game *game, Theme *theme, int enable_color, unsigned int seed) {
|
void ui_main(Game *game, Theme *theme, int enable_color, unsigned int seed) {
|
||||||
|
Color *color;
|
||||||
#ifdef USE_PDCURSES
|
#ifdef USE_PDCURSES
|
||||||
if (theme->utf8) {
|
if (theme->utf8) {
|
||||||
printf("Converting UTF8 theme\n");
|
printf("Converting UTF8 theme\n");
|
||||||
|
@ -1228,10 +1417,10 @@ void ui_main(Game *game, Theme *theme, int enable_color, unsigned int seed) {
|
||||||
initscr();
|
initscr();
|
||||||
if (enable_color) {
|
if (enable_color) {
|
||||||
short index = 15;
|
short index = 15;
|
||||||
Color *color;
|
|
||||||
start_color();
|
start_color();
|
||||||
for (color = theme->colors; color; color = color->next) {
|
for (color = theme->colors; color; color = color->next) {
|
||||||
short color_index = color->name ? ++index : color->index;
|
short color_index = color->name ? ++index : color->index;
|
||||||
|
color_content(color_index, &color->old_red, &color->old_green, &color->old_blue);
|
||||||
if (init_color(color_index, color->red, color->green, color->blue) == 0) {
|
if (init_color(color_index, color->red, color->green, color->blue) == 0) {
|
||||||
color->index = color_index;
|
color->index = color_index;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1274,7 +1463,12 @@ void ui_main(Game *game, Theme *theme, int enable_color, unsigned int seed) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Restore palette colors to their previous values */
|
||||||
|
for (color = theme->colors; color; color = color->next) {
|
||||||
|
if (color->index) {
|
||||||
|
init_color(color->index, color->old_red, color->old_green, color->old_blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
endwin();
|
endwin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue