nsnake
Classic snake game for the terminal
MenuItemNumberbox.cpp
1 #include <Interface/Menu/MenuItemNumberbox.hpp>
2 #include <Config/Globals.hpp>
3 #include <Misc/Utils.hpp>
4 #include <Misc/Timer.hpp>
5 #include <Flow/InputManager.hpp>
6 
7 MenuItemNumberbox::MenuItemNumberbox(std::string label, int id, int min, int max, int initial, int jump):
8  MenuItem(label, id),
9  min(min),
10  max(max),
11  initial(initial),
12  current(initial),
13  jump(jump)
14 {
15  this->type = MenuItem::NUMBERBOX; // placing it above wont work
16 }
17 void MenuItemNumberbox::draw(Window* window, int x, int y, int width, bool hilite)
18 {
19  std::string number = Utils::String::toString(this->current);
20 
21  // Will draw
22  // label text
23  // If not hilite.
24  // If hilite:
25  // label < text >
26  MenuItem::draw(window,
27  x,
28  y,
29  (width - number.size() - 5),
30  hilite);
31 
32  int rightmost = x + width;
33 
34  window->print(((hilite)?
35  "<":
36  "["),
37  rightmost - number.size() - 2,
38  y,
39  ((hilite)?
40  Globals::Theme::hilite_text:
41  Globals::Theme::text));
42 
43  window->print(((hilite)?
44  ">":
45  "]"),
46  rightmost - 1,
47  y,
48  ((hilite)?
49  Globals::Theme::hilite_text:
50  Globals::Theme::text));
51 
52  window->print(number,
53  rightmost - number.size() - 1,
54  y,
55  Globals::Theme::hilite_text);
56 }
58 {
59  if (InputManager::noKeyPressed())
60  return;
61 
62  // These will allow the user to type numbers
63  // and set the current value.
64  // It the user press numbers within a well-defined
65  // time delta, they'll add up to the current value
66  // until hit the maximum.
67  // If the user doesn't press a number for that
68  // period, the timer "resets".
69  static Timer lastKeyTimer;
70  static int lastKeyDelay = 500;
71  static bool firstDigit = false;
72  static bool secondDigit = false;
73  static bool thirdDigit = false;
74 
75  int input = InputManager::pressedKey;
76 
77  // Special case, input was a number
78  if (input >= '0' && input <= '9')
79  {
80  if (! firstDigit)
81  {
82  this->set(input - '0');
83  firstDigit = true;
84  lastKeyTimer.start();
85  return;
86  }
87 
88  if (lastKeyTimer.delta_ms() < lastKeyDelay)
89  {
90  if (! secondDigit)
91  {
92  this->set(this->current * 10 + (input - '0'));
93  secondDigit = true;
94  lastKeyTimer.start();
95  return;
96  }
97  if (! thirdDigit)
98  {
99  this->set(this->current * 10 + (input - '0'));
100  thirdDigit = true;
101  lastKeyTimer.start();
102  return;
103  }
104  }
105  else
106  {
107  // reset everything
108  this->set(input - '0');
109  firstDigit = true;
110  secondDigit = false;
111  thirdDigit = false;
112  lastKeyTimer.start();
113 
114  }
115  return;
116  }
117 
118  // Anything else
119  if (InputManager::isPressed("left") || // user-defined
120  InputManager::isPressed(KEY_LEFT))
121  this->decrease();
122 
123  else if (InputManager::isPressed("right") ||
124  InputManager::isPressed(KEY_RIGHT))
125  this->increase();
126 
127  else if (InputManager::isPressed('r') ||
128  InputManager::isPressed('R') ||
129  InputManager::isPressed(' ') ||
130  InputManager::isPressed('\n') ||
131  InputManager::isPressed(KEY_ENTER))
132  this->reset();
133 }
134 void MenuItemNumberbox::set(int value)
135 {
136  this->current = value;
137  this->cap();
138 }
139 void MenuItemNumberbox::increase()
140 {
141  this->current += this->jump;
142  this->cap();
143 }
144 void MenuItemNumberbox::decrease()
145 {
146  this->current -= this->jump;
147  this->cap();
148 }
149 void MenuItemNumberbox::reset()
150 {
151  this->current = this->initial;
152 }
153 void MenuItemNumberbox::cap()
154 {
155  if (this->current > this->max)
156  this->current = this->max;
157 
158  if (this->current < this->min)
159  this->current = this->min;
160 }
161 
void handleInput()
Makes the menu item react to input, as seen on the global InputManager.
MenuItemNumberbox(std::string label, int id, int min, int max, int initial, int jump=1)
Create a new number box.
MenuItemType type
Specific type of this widget.
Definition: MenuItem.hpp:51
A segment of the terminal screen (2D char matrix).
Definition: Window.hpp:16
void start()
Sets a starting point for the timer.
Definition: Timer.cpp:26
void draw(Window *window, int x, int y, int width, bool hilite=false)
Shows this item at #x, #y with #width.
Simplest type of item possible, with a label and user-defined id.
Definition: MenuItem.hpp:11
virtual void draw(Window *window, int x, int y, int width, bool hilite=false)
Shows this item at #x, #y with #width.
Definition: MenuItem.cpp:12
suseconds_t delta_ms()
Returns the milisseconds part of the timer&#39;s difference.
Definition: Timer.cpp:75
Definition: Timer.hpp:7
void print(std::string str, int x, int y, ColorPair pair=0)
Shows text #str at #x #y on the window with color #pair.
Definition: Window.cpp:94