OSDN Git Service

[Feature] 候補のリストを表示し選択するクラス
[hengbandforosx/hengbandosx.git] / src / util / candidate-selector.cpp
1 #include "util/candidate-selector.h"
2 #include <algorithm>
3 #include <iterator>
4
5 /*!
6  * @brief 候補の選択に使用するシンボルのリスト
7  */
8 const std::array<char, 62> CandidateSelector::i2sym = {
9     // clang-format off
10     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
11     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
12     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
13     // clang-format on
14 };
15
16 CandidateSelector::CandidateSelector()
17     : prompt(_("選択: ", "Choose: "))
18     , start_col(0)
19 {
20     this->set_max_per_page();
21 }
22
23 std::pair<size_t, std::optional<size_t>> CandidateSelector::process_input(char cmd, size_t current_page, size_t page_max)
24 {
25     switch (cmd) {
26     case ' ':
27         current_page++;
28         break;
29     case '-':
30         current_page += (page_max - 1);
31         break;
32     default:
33         if (auto select_sym_it = std::find(i2sym.begin(), i2sym.end(), cmd);
34             select_sym_it != i2sym.end()) {
35             const auto idx = static_cast<size_t>(std::distance(i2sym.begin(), select_sym_it));
36             return { current_page, idx };
37         }
38         break;
39     }
40
41     if (current_page >= page_max) {
42         current_page %= page_max;
43     }
44
45     return { current_page, std::nullopt };
46 }
47
48 /*!
49  * @brief 1ページに表示する候補の最大数を設定する
50  *
51  * 引数を省略した場合もしくは設定数が端末の高さより大きい場合は、端末の高さに合わせる
52  *
53  * @param max 1ページに表示する候補の最大数
54  */
55 void CandidateSelector::set_max_per_page(size_t max)
56 {
57     TERM_LEN term_w, term_h;
58     term_get_size(&term_w, &term_h);
59
60     this->max_per_page = std::min<size_t>(max, term_h - 2);
61 }