From 70058fa3e21de397c5f34c8390ea1ecf6fea5d24 Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Sat, 6 May 2006 18:44:11 -0400 Subject: [PATCH] Added .draw_menu_exit to menu_input_s. Added a history move menu. Can edit annotations from this too. --- src/cboard.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/cboard.h | 10 +++ src/menu.c | 8 ++- src/menu.h | 1 + 4 files changed, 231 insertions(+), 10 deletions(-) diff --git a/src/cboard.c b/src/cboard.c index 9ea65a7..e513647 100644 --- a/src/cboard.c +++ b/src/cboard.c @@ -542,6 +542,7 @@ void file_browser_home(struct menu_input_s *m) pw = getpwuid(getuid()); path = strdup(pw->pw_dir); in->arg = path; + m->selected = 0; } void file_browser_abort(struct menu_input_s *m) @@ -2277,15 +2278,225 @@ void do_move_jump(WIN *win) free(in); } +struct history_menu_s { + char *line; + int hindex; + int ravlevel; + int move; + int indent; +}; + +void get_history_data(HISTORY **hp, struct history_menu_s ***menu, int m, + int turn) +{ + int i, n = 0; + int t = pgn_history_total(hp); + char buf[MAX_SAN_MOVE_LEN + 3]; + static int depth; + struct history_menu_s **hmenu = *menu; + + if (hmenu) + for (n = 0; hmenu[n]; n++); + else + depth = 0; + + for (i = 0; i < t; i++) { + hmenu = Realloc(hmenu, (n + 2) * sizeof(struct history_menu_s *)); + hmenu[n] = Malloc(sizeof(struct history_menu_s)); + snprintf(buf, sizeof(buf), "%c%s", (turn == WHITE) ? 'W' : 'B', + hp[i]->move); + hmenu[n]->line = strdup(buf); + hmenu[n]->hindex = i; + hmenu[n]->indent = 0; + hmenu[n]->ravlevel = depth; + hmenu[n]->move = (n && depth > hmenu[n-1]->ravlevel) ? m++ : m; + n++; + hmenu[n] = NULL; + + if (hp[i]->rav) { + depth++; + get_history_data(hp[i]->rav, &hmenu, m, turn); + for (n = 0; hmenu[n]; n++); + depth--; + + if (depth) + m--; + } + + turn = (turn == WHITE) ? BLACK : WHITE; + } + + *menu = hmenu; +} + +void history_draw_update(struct menu_input_s *m) +{ + GAME *g = m->data; + struct userdata_s *d = g->data; + + g->hindex = m->selected + 1; + update_cursor(*g, m->selected); + pgn_board_update(g, d->b, m->selected + 1); +} + +struct menu_item_s **get_history_items(WIN *win) +{ + struct menu_input_s *m = win->data; + GAME *g = m->data; + struct userdata_s *d = g->data; + struct history_menu_s **hm = d->data; + struct menu_item_s **items = m->items; + int i; + + if (!hm) { + get_history_data(g->history, &hm, 0, + TEST_FLAG(g->flags, GF_BLACK_OPENING)); + m->selected = g->hindex - 1; + + if (m->selected < 0) + m->selected = 0; + + m->draw_exit_func = history_draw_update; + } + + d->data = hm; + + if (items) { + for (i = 0; items[i]; i++) + free(items[i]); + + free(items); + items = NULL; + } + + for (i = 0; hm[i]; i++) { + items = Realloc(items, (i+2) * sizeof(struct menu_item_s *)); + items[i] = Malloc(sizeof(struct menu_item_s)); + items[i]->name = hm[i]->line; + items[i]->value = NULL; + items[i]->selected = 0; + } + + if (items) + items[i] = NULL; + + m->nofree = 1; + m->items = items; + return items; +} + +void history_menu_quit(struct menu_input_s *m) +{ + pushkey = -1; +} + +void history_menu_exit(WIN *win) +{ + GAME *g = win->data; + struct userdata_s *d = g->data; + struct history_menu_s **hm = d->data; + int i; + + if (!hm) + return; + + for (i = 0; hm[i]; i++) { + free(hm[i]->line); + free(hm[i]); + } + + free(hm); + d->data = NULL; +} + +// FIXME RAV +void history_menu_next(struct menu_input_s *m) +{ + GAME *g = m->data; + struct userdata_s *d = g->data; + struct history_menu_s **hm = d->data; + int n, t; + + for (t = 0; hm[t]; t++); + + if (m->selected + 1 == t) + n = 0; + else + n = hm[m->selected + 1]->hindex; + + n++; + g->hindex = n; +} + +// FIXME RAV +void history_menu_prev(struct menu_input_s *m) +{ + GAME *g = m->data; + struct userdata_s *d = g->data; + struct history_menu_s **hm = d->data; + int n, t; + + for (t = 0; hm[t]; t++); + + if (m->selected - 1 < 0) + n = t - 1; + else + n = hm[m->selected - 1]->hindex; + + n++; + g->hindex = n; +} + +void history_menu_help(struct menu_input_s *m) +{ + message("History Menu Help", ANYKEY, "%s", history_menu_help_str); +} + +void do_annotate_move(HISTORY *hp) +{ + char buf[COLS - 4]; + struct input_data_s *in; + + snprintf(buf, sizeof(buf), "%s \"%s\"", ANNOTATION_EDIT_TITLE, hp->move); + in = Calloc(1, sizeof(struct input_data_s)); + in->data = hp; + in->efunc = do_annotate_finalize; + construct_input(buf, hp->comment, MAX_PGN_LINE_LEN / INPUT_WIDTH, 0, + NAG_PROMPT, edit_nag, NULL, CTRL('T'), in, -1); +} + +void history_menu_annotate(struct menu_input_s *m) +{ + GAME *g = m->data; + + // FIXME RAV + do_annotate_move(g->history[m->selected]); +} + +void history_menu(GAME *g) +{ + struct menu_key_s **keys = NULL; + + add_menu_key(&keys, KEY_ESCAPE, history_menu_quit); + add_menu_key(&keys, KEY_UP, history_menu_prev); + add_menu_key(&keys, KEY_DOWN, history_menu_next); + add_menu_key(&keys, KEY_F(1), history_menu_help); + add_menu_key(&keys, 'a', history_menu_annotate); + construct_menu(LINES, TAG_WIDTH, 0, 0, "Move History Tree", 1, + get_history_items, keys, g, history_menu_exit); +} + static void historymode_keys(chtype c) { int n; - char buf[COLS - 4]; struct userdata_s *d = game[gindex].data; struct input_data_s *in; int *p; switch (c) { + case 'M': + history_menu(&game[gindex]); + break; case 'd': config.details = (config.details) ? 0 : 1; break; @@ -2323,14 +2534,7 @@ static void historymode_keys(chtype c) else break; - snprintf(buf, sizeof(buf), "%s \"%s\"", ANNOTATION_EDIT_TITLE, - game[gindex].hp[n]->move); - in = Calloc(1, sizeof(struct input_data_s)); - in->data = game[gindex].hp[n]; - in->efunc = do_annotate_finalize; - construct_input(buf, game[gindex].hp[n]->comment, - MAX_PGN_LINE_LEN / INPUT_WIDTH, 0, NAG_PROMPT, edit_nag, - NULL, CTRL('T'), in, -1); + do_annotate_move(game[gindex].hp[n]); break; case ']': case '[': diff --git a/src/cboard.h b/src/cboard.h index f51a10e..1e1b00a 100644 --- a/src/cboard.h +++ b/src/cboard.h @@ -87,10 +87,20 @@ const char *historyhelp = { " + - next variation for the previous move\n" \ " - - previous variation for the previous move\n" \ " d - toggle board details\n" \ + " M - move history menu\n" \ " h - exit history mode\n" \ " F1 - global and other key help" }; +const char *history_menu_help_str = { + " UP/DOWN - previous/next menu item\n" \ + " HOME/END - first/last menu item\n" \ + " PGDN/PGUP - next/previous page\n" \ + " a-zA-Z0-9 - jump to item\n" \ + " a - annotate the selected move\n" \ + " ESCAPE - quit" +}; + const char *mainhelp = { "p - play mode keys\n" \ "h - history mode keys\n" \ diff --git a/src/menu.c b/src/menu.c index 925f669..426978b 100644 --- a/src/menu.c +++ b/src/menu.c @@ -242,7 +242,6 @@ int display_menu(WIN *win) int key = 0; char *p; - draw_menu(win); cbreak(); noecho(); keypad(win->w, TRUE); @@ -277,6 +276,9 @@ int display_menu(WIN *win) m->search[0] = 0; break; default: + if (!win->c) + break; + if (strlen(m->search) + 1 > sizeof(m->search) - 1) m->search[0] = 0; @@ -307,6 +309,10 @@ end: set_menu_vars(win->c, win->rows - 4, m->total - 1, &m->selected, &m->top); fix_menu_vals(win); draw_menu(win); + + if (m->draw_exit_func) + (*m->draw_exit_func)(m); + return 1; done: diff --git a/src/menu.h b/src/menu.h index d1107e3..26d4461 100644 --- a/src/menu.h +++ b/src/menu.h @@ -46,6 +46,7 @@ struct menu_input_s { int top; int total; menu_items *func; + menu_key *draw_exit_func; char *title; int name_only; struct menu_item_s **items; -- 2.11.4.GIT