cpp-terminal 1.0.0
Small C++ library for writing multiplatform terminal applications
Loading...
Searching...
No Matches
Term::Window Class Reference

Represents a rectangular window, as a 2D array of characters and their attributes. More...

#include <cpp-terminal/window.hpp>

Public Member Functions

 Window (const Size &size)
 
 Window (const Screen &screen)
 
const Columnscolumns () const noexcept
 
const Rowsrows () const noexcept
 
void set_char (const std::size_t &column, const std::size_t &row, const char32_t &character)
 
void set_fg_reset (const std::size_t &column, const std::size_t &row)
 
void set_bg_reset (const std::size_t &column, const std::size_t &row)
 
void set_fg (const std::size_t &column, const std::size_t &row, const Color &color)
 
void set_bg (const std::size_t &column, const std::size_t &row, const Color &color)
 
void set_style (const std::size_t &column, const std::size_t &row, const Style &style)
 
void set_cursor_pos (const std::size_t &column, const std::size_t &row)
 
void set_h (const std::size_t &)
 
void print_str (const std::size_t &column, const std::size_t &, const std::string &, const std::size_t &=0, bool=false)
 
void fill_fg (const std::size_t &column, const std::size_t &, const std::size_t &, const std::size_t &, const Color &)
 
void fill_bg (const std::size_t &column, const std::size_t &, const std::size_t &, const std::size_t &, const Color &)
 
void fill_style (const std::size_t &column, const std::size_t &, const std::size_t &, const std::size_t &, const Style &)
 
void print_border ()
 
void print_rect (const std::size_t &column, const std::size_t &, const std::size_t &, const std::size_t &)
 
void clear ()
 
bool insideWindow (const std::size_t &column, const std::size_t &row) const
 
std::string render (const std::size_t &, const std::size_t &, bool)
 

Private Member Functions

std::size_t index (const std::size_t &column, const std::size_t &row) const
 
char32_t get_char (const std::size_t &column, const std::size_t &row)
 
bool get_fg_reset (const std::size_t &column, const std::size_t &row)
 
bool get_bg_reset (const std::size_t &column, const std::size_t &row)
 
Term::Color get_fg (const std::size_t &column, const std::size_t &row)
 
Term::Color get_bg (const std::size_t &column, const std::size_t &row)
 
Term::Style get_style (const std::size_t &column, const std::size_t &row)
 

Private Attributes

Term::Size m_size
 
Term::Cursor m_cursor {1, 1}
 
std::vector< char32_t > m_chars
 
std::vector< Term::Colorm_fg
 
std::vector< Term::Colorm_bg
 
std::vector< bool > m_fg_reset
 
std::vector< bool > m_bg_reset
 
std::vector< Stylem_style
 

Detailed Description

Represents a rectangular window, as a 2D array of characters and their attributes.

Represents a rectangular window, as a 2D array of characters and their attributes. The render method can convert this internal representation to a string that when printed will show the Window on the screen. The natural way to represent a character in a terminal would be a "unicode grapheme cluster", but due to a lack of a good library for C++ that could handle those, we simply use a Unicode code point as a character.

Definition at line 33 of file window.hpp.

Constructor & Destructor Documentation

◆ Window() [1/2]

Term::Window::Window ( const Size & size)
explicit

Definition at line 26 of file window.cpp.

26: m_size(size) { clear(); }
Term::Size m_size
Definition window.hpp:81
void clear()
Definition window.cpp:189

◆ Window() [2/2]

Term::Window::Window ( const Screen & screen)
explicit

Definition at line 28 of file window.cpp.

28: m_size({screen.rows(), screen.columns()}) { clear(); }

Member Function Documentation

◆ clear()

void Term::Window::clear ( )

Definition at line 189 of file window.cpp.

190{
191 m_style.assign(m_size.area(), Style::Reset);
192 m_bg_reset.assign(m_size.area(), true);
194 m_fg_reset.assign(m_size.area(), true);
196 m_chars.assign(m_size.area(), ' ');
197}
@ Default
Use the default terminal color, FG: 39, BG: 49.
std::size_t area() const noexcept
Definition size.hpp:46
std::vector< Term::Color > m_bg
Definition window.hpp:85
std::vector< bool > m_fg_reset
Definition window.hpp:86
std::vector< Term::Color > m_fg
Definition window.hpp:84
std::vector< bool > m_bg_reset
Definition window.hpp:87
std::vector< Style > m_style
Definition window.hpp:88
std::vector< char32_t > m_chars
Definition window.hpp:83
@ Reset
resets all attributes (styles and colors)

◆ columns()

const Columns & Term::Window::columns ( ) const
noexcept

Definition at line 42 of file window.cpp.

42{ return m_size.columns(); }
const Columns & columns() const noexcept
Definition size.hpp:48

◆ fill_bg()

void Term::Window::fill_bg ( const std::size_t & column,
const std::size_t & y1,
const std::size_t & x2,
const std::size_t & y2,
const Color & rgb )

Definition at line 132 of file window.cpp.

133{
134 for(std::size_t j = y1; j <= y2; ++j)
135 {
136 for(std::size_t i = x1; i <= x2; ++i) { set_bg(i, j, rgb); }
137 }
138}
void set_bg(const std::size_t &column, const std::size_t &row, const Color &color)
Definition window.cpp:70

◆ fill_fg()

void Term::Window::fill_fg ( const std::size_t & column,
const std::size_t & y1,
const std::size_t & x2,
const std::size_t & y2,
const Color & rgb )

Definition at line 124 of file window.cpp.

125{
126 for(std::size_t j = y1; j <= y2; ++j)
127 {
128 for(std::size_t i = x1; i <= x2; ++i) { set_fg(i, j, rgb); }
129 }
130}
void set_fg(const std::size_t &column, const std::size_t &row, const Color &color)
Definition window.cpp:64

◆ fill_style()

void Term::Window::fill_style ( const std::size_t & column,
const std::size_t & y1,
const std::size_t & x2,
const std::size_t & y2,
const Style & color )

Definition at line 140 of file window.cpp.

141{
142 for(std::size_t j = y1; j <= y2; ++j)
143 {
144 for(std::size_t i = x1; i <= x2; ++i) { set_style(i, j, color); }
145 }
146}
void set_style(const std::size_t &column, const std::size_t &row, const Style &style)
Definition window.cpp:76

◆ get_bg()

Term::Color Term::Window::get_bg ( const std::size_t & column,
const std::size_t & row )
private

Definition at line 38 of file window.cpp.

38{ return m_bg[index(column, row)]; }
std::size_t index(const std::size_t &column, const std::size_t &row) const
Definition window.cpp:299

◆ get_bg_reset()

bool Term::Window::get_bg_reset ( const std::size_t & column,
const std::size_t & row )
private

Definition at line 34 of file window.cpp.

34{ return m_bg_reset[index(column, row)]; }

◆ get_char()

char32_t Term::Window::get_char ( const std::size_t & column,
const std::size_t & row )
private

Definition at line 30 of file window.cpp.

30{ return m_chars[index(column, row)]; }

◆ get_fg()

Term::Color Term::Window::get_fg ( const std::size_t & column,
const std::size_t & row )
private

Definition at line 36 of file window.cpp.

36{ return m_fg[index(column, row)]; }

◆ get_fg_reset()

bool Term::Window::get_fg_reset ( const std::size_t & column,
const std::size_t & row )
private

Definition at line 32 of file window.cpp.

32{ return m_fg_reset[index(column, row)]; }

◆ get_style()

Term::Style Term::Window::get_style ( const std::size_t & column,
const std::size_t & row )
private

Definition at line 40 of file window.cpp.

40{ return m_style[index(column, row)]; }

◆ index()

std::size_t Term::Window::index ( const std::size_t & column,
const std::size_t & row ) const
private

Definition at line 299 of file window.cpp.

300{
301 if(!insideWindow(column, row)) { throw Term::Exception("Cursor out of range"); }
302 return ((row - 1) * m_size.columns()) + (column - 1);
303}
bool insideWindow(const std::size_t &column, const std::size_t &row) const
Definition window.cpp:305

◆ insideWindow()

bool Term::Window::insideWindow ( const std::size_t & column,
const std::size_t & row ) const

Definition at line 305 of file window.cpp.

305{ return (column >= 1) && (row >= 1) && (column <= m_size.columns()) && (row <= m_size.rows()); }
const Rows & rows() const noexcept
Definition size.hpp:47

◆ print_border()

void Term::Window::print_border ( )

Definition at line 148 of file window.cpp.

148{ print_rect(1, 1, m_size.columns(), m_size.rows()); }
void print_rect(const std::size_t &column, const std::size_t &, const std::size_t &, const std::size_t &)
Definition window.cpp:150

◆ print_rect()

void Term::Window::print_rect ( const std::size_t & column,
const std::size_t & y1,
const std::size_t & x2,
const std::size_t & y2 )

Definition at line 150 of file window.cpp.

151{
152 std::u32string border = Private::utf8_to_utf32("│─┌┐└┘");
154 {
155 for(std::size_t j = y1 + 1; j <= (y2 - 1); ++j)
156 {
157 set_char(x1, j, border[0]);
158 set_char(x2, j, border[0]);
159 }
160 for(std::size_t i = x1 + 1; i <= (x2 - 1); ++i)
161 {
162 set_char(i, y1, border[1]);
163 set_char(i, y2, border[1]);
164 }
165 set_char(x1, y1, border[2]);
166 set_char(x2, y1, border[3]);
167 set_char(x1, y2, border[4]);
168 set_char(x2, y2, border[5]);
169 }
170 else
171 {
172 for(std::size_t j = y1 + 1; j <= (y2 - 1); ++j)
173 {
174 set_char(x1, j, '|');
175 set_char(x2, j, '|');
176 }
177 for(std::size_t i = x1 + 1; i <= (x2 - 1); ++i)
178 {
179 set_char(i, y1, '-');
180 set_char(i, y2, '-');
181 }
182 set_char(x1, y1, '+');
183 set_char(x2, y1, '+');
184 set_char(x1, y2, '+');
185 set_char(x2, y2, '+');
186 }
187}
static bool get(const Term::Terminfo::Bool &key)
Definition terminfo.cpp:30
@ UTF8
terminal has UTF-8 activated.
void set_char(const std::size_t &column, const std::size_t &row, const char32_t &character)
Definition window.cpp:46
std::u32string utf8_to_utf32(const std::string &str)

◆ print_str()

void Term::Window::print_str ( const std::size_t & column,
const std::size_t & y,
const std::string & s,
const std::size_t & indent = 0,
bool move_cursor = false )

Definition at line 97 of file window.cpp.

98{
99 std::u32string s2 = Private::utf8_to_utf32(s);
100 std::size_t xpos = x;
101 std::size_t ypos = y;
102 for(char32_t i: s2)
103 {
104 if(i == U'\n')
105 {
106 xpos = x + indent;
107 ypos++;
108 if(insideWindow(xpos, ypos))
109 {
110 for(std::size_t j = 0; j < indent; ++j) { set_char(x + j, ypos, '.'); }
111 }
112 else { return; }
113 }
114 else
115 {
116 if(insideWindow(xpos, ypos)) { set_char(xpos, y, i); }
117 else { return; }
118 ++xpos;
119 }
120 }
121 if(move_cursor) { m_cursor = {ypos, xpos}; }
122}
Term::Cursor m_cursor
Definition window.hpp:82

◆ render()

std::string Term::Window::render ( const std::size_t & x0,
const std::size_t & y0,
bool term )

Definition at line 199 of file window.cpp.

200{
201 std::string out;
202 if(term) { out.append(cursor_off()); }
203 Color current_fg = Term::Color::Name::Default;
204 Color current_bg = Term::Color::Name::Default;
205 bool current_fg_reset = true;
206 bool current_bg_reset = true;
207 Style current_style = Style::Reset;
208 for(std::size_t j = 1; j <= m_size.rows(); ++j)
209 {
210 if(term) { out.append(cursor_move(y0 + j - 1, x0)); }
211 for(std::size_t i = 1; i <= m_size.columns(); ++i)
212 {
213 bool update_fg = false;
214 bool update_bg = false;
215 bool update_fg_reset = false;
216 bool update_bg_reset = false;
217 bool update_style = false;
218 if(current_fg_reset != get_fg_reset(i, j))
219 {
220 current_fg_reset = get_fg_reset(i, j);
221 if(current_fg_reset)
222 {
223 update_fg_reset = true;
224 current_fg = {255, 255, 255};
225 }
226 }
227
228 if(current_bg_reset != get_bg_reset(i, j))
229 {
230 current_bg_reset = get_bg_reset(i, j);
231 if(current_bg_reset)
232 {
233 update_bg_reset = true;
234 current_bg = {255, 255, 255};
235 }
236 }
237
238 if(!current_fg_reset)
239 {
240 if(!(current_fg == get_fg(i, j)))
241 {
242 current_fg = get_fg(i, j);
243 update_fg = true;
244 }
245 }
246
247 if(!current_fg_reset)
248 {
249 if(!(current_bg == get_bg(i, j)))
250 {
251 current_bg = get_bg(i, j);
252 update_bg = true;
253 }
254 }
255 if(current_style != get_style(i, j))
256 {
257 current_style = get_style(i, j);
258 update_style = true;
259 if(current_style == Style::Reset)
260 {
261 // style::reset: reset fg and bg colors too, we have to
262 // set them again if they are non-default, but if fg or
263 // bg colors are reset, we do not update them, as
264 // style::reset already did that.
265 update_fg = !current_fg_reset;
266 update_bg = !current_bg_reset;
267 }
268 }
269 // Set style first, as style::reset will reset colors too
270 if(update_style) { out.append(style(get_style(i, j))); }
271 if(update_fg_reset) { out.append(color_fg(Term::Color::Name::Default)); }
272 else if(update_fg)
273 {
274 const Term::Color color_tmp = get_fg(i, j);
275 out.append(color_fg(color_tmp));
276 }
277
278 if(update_bg_reset) { out.append(color_bg(Term::Color::Name::Default)); }
279 else if(update_bg)
280 {
281 const Term::Color color_tmp = get_bg(i, j);
282 out.append(color_bg(color_tmp));
283 }
284 out.append(Private::utf32_to_utf8(get_char(i, j)));
285 }
286 if(j < m_size.rows()) { out.append("\n"); }
287 }
288 if(!current_fg_reset) { out.append(color_fg(Term::Color::Name::Default)); }
289 if(!current_bg_reset) { out.append(color_bg(Term::Color::Name::Default)); }
290 if(current_style != Style::Reset) { out.append(style(Style::Reset)); }
291 if(term)
292 {
293 out.append(cursor_move(y0 + (m_cursor.row() - 1), x0 + (m_cursor.column() - 1)));
294 out.append(cursor_on());
295 }
296 return out;
297}
std::size_t column() const
Definition cursor.cpp:16
std::size_t row() const
Definition cursor.cpp:14
Term::Color get_fg(const std::size_t &column, const std::size_t &row)
Definition window.cpp:36
Term::Color get_bg(const std::size_t &column, const std::size_t &row)
Definition window.cpp:38
char32_t get_char(const std::size_t &column, const std::size_t &row)
Definition window.cpp:30
bool get_bg_reset(const std::size_t &column, const std::size_t &row)
Definition window.cpp:34
bool get_fg_reset(const std::size_t &column, const std::size_t &row)
Definition window.cpp:32
Term::Style get_style(const std::size_t &column, const std::size_t &row)
Definition window.cpp:40
std::string utf32_to_utf8(const char32_t &codepoint, const bool &exception=false)
Encode a codepoint using UTF-8 std::string .
Definition unicode.cpp:55
OutputFileHandler & out
Definition file.cpp:44
std::string color_bg(const Term::Color::Name &name)
Definition color.cpp:79
std::string style(const Term::Style &style)
Definition style.cpp:12
std::string cursor_off()
Definition cursor.cpp:28
Style
Definition style.hpp:24
std::string cursor_move(const std::size_t &row, const std::size_t &column)
Definition cursor.cpp:32
std::string cursor_on()
Definition cursor.cpp:30
std::string color_fg(const Term::Color::Name &name)
Definition color.cpp:110

◆ rows()

const Rows & Term::Window::rows ( ) const
noexcept

Definition at line 44 of file window.cpp.

44{ return m_size.rows(); }

◆ set_bg()

void Term::Window::set_bg ( const std::size_t & column,
const std::size_t & row,
const Color & color )

Definition at line 70 of file window.cpp.

71{
72 m_bg_reset[index(column, row)] = false;
73 m_bg[index(column, row)] = color;
74}

◆ set_bg_reset()

void Term::Window::set_bg_reset ( const std::size_t & column,
const std::size_t & row )

Definition at line 58 of file window.cpp.

59{
60 m_bg_reset[index(column, row)] = true;
62}

◆ set_char()

void Term::Window::set_char ( const std::size_t & column,
const std::size_t & row,
const char32_t & character )

Definition at line 46 of file window.cpp.

47{
48 if(insideWindow(column, row)) { m_chars[index(column, row)] = character; }
49 else { throw Term::Exception("set_char(): (x,y) out of bounds"); }
50}

◆ set_cursor_pos()

void Term::Window::set_cursor_pos ( const std::size_t & column,
const std::size_t & row )

Definition at line 78 of file window.cpp.

78{ m_cursor = {row, column}; }

◆ set_fg()

void Term::Window::set_fg ( const std::size_t & column,
const std::size_t & row,
const Color & color )

Definition at line 64 of file window.cpp.

65{
66 m_fg_reset[index(column, row)] = false;
67 m_fg[index(column, row)] = color;
68}

◆ set_fg_reset()

void Term::Window::set_fg_reset ( const std::size_t & column,
const std::size_t & row )

Definition at line 52 of file window.cpp.

53{
54 m_fg_reset[index(column, row)] = true;
56}

◆ set_h()

void Term::Window::set_h ( const std::size_t & new_h)

Definition at line 80 of file window.cpp.

81{
82 if(new_h == m_size.rows()) { return; }
83 if(new_h > m_size.rows())
84 {
85 const std::size_t dc = (new_h - m_size.rows()) * m_size.columns();
86 m_chars.insert(m_chars.end(), dc, ' ');
87 m_fg_reset.insert(m_fg_reset.end(), dc, true);
88 m_bg_reset.insert(m_bg_reset.end(), dc, true);
89 m_fg.insert(m_fg.end(), dc, {0, 0, 0});
90 m_bg.insert(m_bg.end(), dc, {0, 0, 0});
91 m_style.insert(m_style.end(), dc, Style::Reset);
93 }
94 else { throw Term::Exception("Shrinking height not supported."); }
95}

◆ set_style()

void Term::Window::set_style ( const std::size_t & column,
const std::size_t & row,
const Style & style )

Definition at line 76 of file window.cpp.

76{ m_style[index(column, row)] = style; }

Member Data Documentation

◆ m_bg

std::vector<Term::Color> Term::Window::m_bg
private

Definition at line 85 of file window.hpp.

◆ m_bg_reset

std::vector<bool> Term::Window::m_bg_reset
private

Definition at line 87 of file window.hpp.

◆ m_chars

std::vector<char32_t> Term::Window::m_chars
private

Definition at line 83 of file window.hpp.

◆ m_cursor

Term::Cursor Term::Window::m_cursor {1, 1}
private

Definition at line 82 of file window.hpp.

82{1, 1};

◆ m_fg

std::vector<Term::Color> Term::Window::m_fg
private

Definition at line 84 of file window.hpp.

◆ m_fg_reset

std::vector<bool> Term::Window::m_fg_reset
private

Definition at line 86 of file window.hpp.

◆ m_size

Term::Size Term::Window::m_size
private

Definition at line 81 of file window.hpp.

◆ m_style

std::vector<Style> Term::Window::m_style
private

Definition at line 88 of file window.hpp.


The documentation for this class was generated from the following files: