nsnake
Classic snake game for the terminal
Window.cpp
1 #include <Interface/Window.hpp>
2 
3 #include <sstream> // stringstream
4 #include <iostream>
5 
6 /* dag-nabbit, PDCurses (windows) doesnt have 'mvwhline' */
7 #if OS_IS_WINDOWS
8 #define mvwhline my_mvwhline
9 #endif
10 
17 void my_mvwhline(WINDOW* win, int y, int x, chtype ch, int num)
18 {
19  int i;
20  for (i = 0; i < num; i++)
21  mvwaddch(win, y, (x + i), ch);
22 }
23 
24 Window::Window(int x, int y, int w, int h):
25  win(NULL),
26  error(false),
27  x(x),
28  y(y),
29  width(w),
30  height(h),
31  borderType(BORDER_NONE),
32  topLeftTitle(""),
33  topRightTitle(""),
34  bottomLeftTitle(""),
35  bottomRightTitle("")
36 {
37  this->win = newwin(height, width, y, x);
38 
39  if (!this->win)
40  this->error = true;
41 }
42 Window::Window(Window* parent, int x, int y, int width, int height):
43  win(NULL),
44  error(false),
45  borderType(BORDER_NONE),
46  topLeftTitle(""),
47  topRightTitle(""),
48  bottomLeftTitle(""),
49  bottomRightTitle("")
50 {
51  // By sending any parameter as 0, we want it to expand
52  // until possible.
53  // Let's expand based if the parent window has borders
54  // or not.
55  if (parent->borderType == BORDER_NONE)
56  {
57  if (width == 0) width = parent->width;
58  if (height == 0) height = parent->height;
59  }
60  else
61  {
62  // Has borders
63  if (x == 0) x = 1;
64  if (y == 0) y = 1;
65 
66  if (width == 0) width = parent->width - 2;
67  if (height == 0) height = parent->height - 2;
68  }
69 
70  this->x = x;
71  this->y = y;
72  this->width = width;
73  this->height = height;
74 
75  this->win = derwin(parent->win, height, width, y, x);
76  if (!win)
77  this->error = true;
78 }
79 Window::~Window()
80 {
81  if (this->win)
82  delwin(this->win);
83 }
84 bool Window::isValid()
85 {
86  return !(this->error);
87 }
88 void Window::resize(int w, int h)
89 {
90  wresize(this->win, h, w);
91  this->width = w;
92  this->height = h;
93 }
94 void Window::print(std::string str, int x, int y, ColorPair pair)
95 {
96  Colors::pairActivate(this->win, pair);
97 
98  mvwaddstr(this->win, y, x, str.c_str());
99 }
100 void Window::print(std::vector<std::string> lines, int x, int y, ColorPair pair)
101 {
102  for (size_t i = 0; i < lines.size(); i++)
103  this->print(lines[i], x, y + i, pair);
104 }
105 void Window::printChar(int c, int x, int y, ColorPair pair)
106 {
107  Colors::pairActivate(this->win, pair);
108 
109  mvwaddch(this->win, y, x, c);
110 }
111 void Window::setBackground(chtype ch, ColorPair pair)
112 {
113  wbkgd(this->win, ch | pair);
114 }
115 void Window::refresh()
116 {
117  //wrefresh(this->win);
118 
119  // I've changed all calls to wrefresh() to wnoutrefresh
120  // because when I have several WINDOW*, it gets heavy
121  // to do the former.
122  //
123  // As a tradeoff, I need to call `refresh()` at the end
124  // of every draw cycle.
125  //
126  wnoutrefresh(this->win);
127 }
128 void Window::clear()
129 {
130  werase(this->win);
131 
132  // Redrawing borders if existing
133  if (this->borderType != BORDER_NONE)
134  this->borders(this->borderType);
135 
136  // Now, to the titles!
137  if (! this->topLeftTitle.empty())
138  {
139  this->print(this->topLeftTitle,
140  1, 0,
141  Colors::pair(COLOR_BLUE, COLOR_DEFAULT));
142  }
143  if (! this->bottomLeftTitle.empty())
144  {
145  this->print(this->bottomLeftTitle,
146  0, this->getH() - 1,
147  Colors::pair(COLOR_BLUE, COLOR_DEFAULT));
148  }
149  if (! this->topRightTitle.empty())
150  {
151  int x = (this->getW() - 1);
152  int w = this->topRightTitle.size();
153 
154  this->print(this->topRightTitle,
155  x - w, 0,
156  Colors::pair(COLOR_BLUE, COLOR_DEFAULT));
157  }
158  if (! this->bottomRightTitle.empty())
159  {
160  int x = (this->getW() - 1);
161  int w = this->bottomRightTitle.size();
162 
163  this->print(this->bottomRightTitle,
164  x - w, this->getH() - 1,
165  Colors::pair(COLOR_BLUE, COLOR_DEFAULT));
166  }
167 }
168 int Window::getW() const
169 {
170  return this->width;
171 }
172 int Window::getH() const
173 {
174  return this->height;
175 }
176 int Window::getX() const
177 {
178  return this->x;
179 }
180 int Window::getY() const
181 {
182  return this->y;
183 }
184 void Window::borders(BorderType type)
185 {
186  this->borderType = type;
187 
188  if (type == Window::BORDER_NONE)
189  return;
190 
191  if (type == Window::BORDER_FANCY)
192  {
193  wborder(this->win,
194  ACS_VLINE | Colors::pair(COLOR_WHITE, COLOR_DEFAULT),
195  ACS_VLINE | Colors::pair(COLOR_BLACK, COLOR_DEFAULT, true),
196  ACS_HLINE | Colors::pair(COLOR_WHITE, COLOR_DEFAULT),
197  ACS_HLINE | Colors::pair(COLOR_BLACK, COLOR_DEFAULT, true),
198  ACS_ULCORNER | Colors::pair(COLOR_WHITE, COLOR_DEFAULT, true),
199  ACS_URCORNER | Colors::pair(COLOR_WHITE, COLOR_DEFAULT),
200  ACS_LLCORNER | Colors::pair(COLOR_WHITE, COLOR_DEFAULT),
201  ACS_LRCORNER | Colors::pair(COLOR_BLACK, COLOR_DEFAULT, true));
202  }
203  else if (type == Window::BORDER_REGULAR)
204  {
205  wattrset(this->win, Colors::pair(COLOR_BLACK, COLOR_DEFAULT, true));
206  wborder(this->win, '|', '|', '-', '-', '+', '+', '+', '+');
207  }
208 }
209 void Window::horizontalLine(int x, int y, int c, int width, ColorPair pair)
210 {
211  Colors::pairActivate(this->win, pair);
212  mvwhline(this->win, y, x, c, width);
213 }
214 void Window::setTitle(std::string title, WindowTitlePosition position)
215 {
216  switch (position)
217  {
218  case TOP_LEFT: this->topLeftTitle = title; break;
219  case TOP_RIGHT: this->topRightTitle = title; break;
220  case BOTTOM_LEFT: this->bottomLeftTitle = title; break;
221  case BOTTOM_RIGHT: this->bottomRightTitle = title; break;
222  default: return;
223  }
224 }
225 
WINDOW * win
Ncurses&#39; internal data structure.
Definition: Window.hpp:85
A segment of the terminal screen (2D char matrix).
Definition: Window.hpp:16
void setTitle(std::string title, WindowTitlePosition position=Window::TOP_LEFT)
Sets a text that will appear at the top of the Window.
Definition: Window.cpp:214
void printChar(int c, int x, int y, ColorPair pair=0)
Shows #c at #x #y with color #pair.
Definition: Window.cpp:105
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