nsnake
Classic snake game for the terminal
MenuAlphabetic.cpp
1 #include <Interface/Menu/MenuAlphabetic.hpp>
2 #include <Misc/Utils.hpp>
3 #include <Flow/InputManager.hpp>
4 
5 #include <algorithm>
6 
7 MenuAlphabetic::MenuAlphabetic(int x, int y, int width, int height):
8  Menu(x, y, width, height)
9 { }
10 
11 
12 
13 // Local function that compares two Menu Items
14 bool menuItemLess(const MenuItem* x, const MenuItem* y)
15 {
16  return Utils::String::caseInsensitiveSmallerString(x->label, y->label);
17 }
18 
19 void MenuAlphabetic::add(MenuItem* item)
20 {
21  Menu::add(item);
22 
23  // This is a very specific behavior, read with attention.
24  //
25  // If the menu has no blank items,
26  // we're going to sort it normally.
27  //
28  // If it has a single blank item, we'll sort the entire menu
29  // starting from the item AFTER the blank one.
30 
31  std::vector<MenuItem*>::iterator firstItem = this->item.begin();
32 
33  // So here we look for a blank item
34 
35  for (size_t i = 0; i < (this->item.size()); i++)
36  if (this->item[i] == NULL)
37  {
38  firstItem += i; // Pointing to the current items' position
39  break;
40  }
41 
42  // And start sorting from AFTER it
43  std::sort(firstItem + 1,
44  this->item.end(),
45  menuItemLess);
46 
47  // TODO: make it keep pointing to the previous item
48  // instead of jumping to the first
49  this->goFirst();
50 }
51 
52 void MenuAlphabetic::handleInput()
53 {
55 
56  // This is very ugly...
57 
58  char key = std::tolower(InputManager::pressedKey);
59 
60  if (key >= 'a' && key <= 'z')
61  {
62  // See specific behavior on `MenuAlphabetic::add`
63  //
64  // Start looking only after the first Blank item.
65  int startingIndex = 0;
66 
67  for (size_t i = 0; i < this->item.size(); i++)
68  if (this->item[i] == NULL)
69  {
70  startingIndex = i;
71  break;
72  }
73 
74  // And only make possible to jump on items AFTER
75  // the blank one
76  for (size_t i = startingIndex + 1; i < this->item.size(); i++)
77  if (std::tolower(this->item[i]->label[0]) == key)
78  {
79  this->currentIndex = i;
80  this->current = this->item[i];
81  break;
82  }
83  }
84 }
86 {
87  // See specific behavior on `MenuAlphabetic::add`
88  //
89  // Start looking only after the first Blank item.
90  int startingIndex = 0;
91 
92  for (size_t i = 0; i < this->item.size(); i++)
93  if (this->item[i] == NULL)
94  {
95  startingIndex = i;
96  break;
97  }
98 
99 
100  this->currentIndex = Utils::Random::between(startingIndex + 1, this->item.size() - 1);
101  this->current = this->item[this->currentIndex];
102 }
103 
void handleInput()
Makes the menu react to input, as seen on the global InputManager.
Definition: Menu.cpp:183
MenuItem * current
Current item selected.
Definition: Menu.hpp:115
void goRandom()
Selects a random item right AFTER the first blank one.
unsigned int currentIndex
Index of the currently selected item.
Definition: Menu.hpp:119
std::vector< MenuItem * > item
Container of all the options inside the menu.
Definition: Menu.hpp:109
Simplest type of item possible, with a label and user-defined id.
Definition: MenuItem.hpp:11
List of selectable items.
Definition: Menu.hpp:28
int between(int min, int max)
Random number between min and max.
Definition: Utils.cpp:48
std::string label
Text that will be shown on the screen.
Definition: MenuItem.hpp:54