nsnake
Classic snake game for the terminal
Loading...
Searching...
No Matches
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
17void 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
24Window::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}
42Window::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}
79Window::~Window()
80{
81 if (this->win)
82 delwin(this->win);
83}
84bool Window::isValid()
85{
86 return !(this->error);
87}
88void Window::resize(int w, int h)
89{
90 wresize(this->win, h, w);
91 this->width = w;
92 this->height = h;
93}
94void 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}
100void 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}
105void 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}
111void Window::setBackground(chtype ch, ColorPair pair)
112{
113 wbkgd(this->win, ch | pair);
114}
115void 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}
128void 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}
168int Window::getW() const
169{
170 return this->width;
171}
172int Window::getH() const
173{
174 return this->height;
175}
176int Window::getX() const
177{
178 return this->x;
179}
180int Window::getY() const
181{
182 return this->y;
183}
184void 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}
209void 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}
214void 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
A segment of the terminal screen (2D char matrix).
Definition Window.hpp:17
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
WINDOW * win
Ncurses' internal data structure.
Definition Window.hpp:85
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
bool error
Tells if we've got some initialization error.
Definition Window.hpp:89