OSDN Git Service

Merge pull request #1192 from hengband/feature/3.0.0Alpha26
[hengbandforosx/hengbandosx.git] / src / autopick / autopick-command-menu.cpp
1 /*!
2  * @brief 自動拾いエディタのコマンドを受け付ける
3  * @date 2020/04/26
4  * @author Hourier
5  * @todo 1関数100行以上ある、後で関数を分割すること
6  */
7
8 #include "autopick/autopick-command-menu.h"
9 #include "autopick/autopick-menu-data-table.h"
10 #include "autopick/autopick-util.h"
11 #include "io/input-key-acceptor.h"
12 #include "system/angband.h"
13 #include "term/screen-processor.h"
14 #include "term/term-color-types.h"
15 #include "util/int-char-converter.h"
16
17 /*!
18  * @brief 自動拾いエディタの画面を再描画する
19  * @param redraw 再描画が必要ならTRUE
20  * @param level command_menu_type 構造体におけるメニュー (詳細不明)
21  * @param start
22  * @param linestr
23  * @param menu_key 自動拾いエディタのメニューで入力したキー
24  * @param max_len
25  */
26 static void redraw_edit_command_menu(bool *redraw, int level, int start, char *linestr, byte *menu_key, int max_len)
27 {
28     if (!*redraw)
29         return;
30
31     int col0 = 5 + level * 7;
32     int row0 = 1 + level * 3;
33     int row1 = row0 + 1;
34     term_putstr(col0, row0, -1, TERM_WHITE, linestr);
35
36     *menu_key = 0;
37     for (int i = start; menu_data[i].level >= level; i++) {
38         char com_key_str[3];
39         concptr str;
40         if (menu_data[i].level > level)
41             continue;
42
43         if (menu_data[i].com_id == -1) {
44             strcpy(com_key_str, _("▼", ">"));
45         } else if (menu_data[i].key != -1) {
46             com_key_str[0] = '^';
47             com_key_str[1] = menu_data[i].key + '@';
48             com_key_str[2] = '\0';
49         } else {
50             com_key_str[0] = '\0';
51         }
52
53         str = format("| %c) %-*s %2s | ", *menu_key + 'a', max_len, menu_data[i].name, com_key_str);
54
55         term_putstr(col0, row1++, -1, TERM_WHITE, str);
56
57         (*menu_key)++;
58     }
59
60     term_putstr(col0, row1, -1, TERM_WHITE, linestr);
61     *redraw = false;
62 }
63
64 /*
65  * Display the menu, and get a command
66  */
67 int do_command_menu(int level, int start)
68 {
69     int max_len = 0;
70     int menu_id_list[26];
71     byte menu_key = 0;
72     for (int i = start; menu_data[i].level >= level; i++) {
73         /* Ignore lower level sub menus */
74         if (menu_data[i].level > level)
75             continue;
76
77         int len = strlen(menu_data[i].name);
78         if (len > max_len)
79             max_len = len;
80
81         menu_id_list[menu_key] = i;
82         menu_key++;
83     }
84
85     while (menu_key < 26) {
86         menu_id_list[menu_key] = -1;
87         menu_key++;
88     }
89
90     int max_menu_wid = max_len + 3 + 3;
91
92     char linestr[MAX_LINELEN];
93     linestr[0] = '\0';
94     strcat(linestr, "+");
95     for (int i = 0; i < max_menu_wid + 2; i++) {
96         strcat(linestr, "-");
97     }
98
99     strcat(linestr, "+");
100     bool redraw = true;
101     while (true) {
102         redraw_edit_command_menu(&redraw, level, start, linestr, &menu_key, max_len);
103         prt(format(_("(a-%c) コマンド:", "(a-%c) Command:"), menu_key + 'a' - 1), 0, 0);
104         char key = inkey();
105         if (key == ESCAPE)
106             return 0;
107
108         int com_id;
109         bool is_alphabet = key >= 'a' && key <= 'z';
110         if (!is_alphabet) {
111             com_id = get_com_id(key);
112             if (com_id) {
113                 return com_id;
114             }
115
116             continue;
117         }
118
119         int menu_id = menu_id_list[key - 'a'];
120         if (menu_id < 0)
121             continue;
122
123         com_id = menu_data[menu_id].com_id;
124         if (com_id == -1) {
125             com_id = do_command_menu(level + 1, menu_id + 1);
126             if (com_id)
127                 return com_id;
128             else
129                 redraw = true;
130         } else if (com_id) {
131             return com_id;
132         }
133     }
134 }