1 /***************************************************************************
2 * Copyright (C) 2008-2014 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #ifndef NCMPCPP_WINDOW_H
22 #define NCMPCPP_WINDOW_H
27 # define NCURSES_MOUSE_VERSION 1
40 // define some Ctrl-? keys
84 #define KEY_SHIFT_TAB 353
88 // define alternative KEY_BACKSPACE (used in some terminal emulators)
89 #define KEY_BACKSPACE_2 127
91 // KEY_ENTER is 343, which doesn't make any sense. This makes it useful.
95 // undefine scroll macro as it collides with Window::scroll
99 // NOTICE: redefine BUTTON2_PRESSED as it doesn't always work, I noticed
100 // that it sometimes returns 134217728 (2^27) instead of expected mask, so the
101 // modified define does it right but is rather experimental.
102 # undef BUTTON2_PRESSED
103 # define BUTTON2_PRESSED (NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_PRESSED) | (1U << 27))
104 #endif // USE_PDCURSES
106 // workaraund for win32
108 # define wcwidth(x) int(!iscntrl(x))
111 /// NC namespace provides set of easy-to-use
112 /// wrappers over original curses library
115 /// Colors used by NCurses
116 enum class Color
{ Default
, Black
, Red
, Green
, Yellow
, Blue
, Magenta
, Cyan
, White
, End
};
118 std::ostream
&operator<<(std::ostream
&os
, Color c
);
119 std::istream
&operator>>(std::istream
&is
, Color
&c
);
121 /// Format flags used by NCurses
125 Underline
, NoUnderline
,
127 AltCharset
, NoAltCharset
130 std::ostream
&operator<<(std::ostream
&os
, Format f
);
132 /// Available border colors for window
133 enum class Border
{ None
, Black
, Red
, Green
, Yellow
, Blue
, Magenta
, Cyan
, White
};
135 std::ostream
&operator<<(std::ostream
&os
, Border b
);
136 std::istream
&operator>>(std::istream
&is
, Border
&b
);
138 /// This indicates how much the window has to be scrolled
139 enum class Scroll
{ Up
, Down
, PageUp
, PageDown
, Home
, End
};
141 std::ostream
&operator<<(std::ostream
&os
, Scroll s
);
143 /// Helper function that is invoked each time one will want
144 /// to obtain string from Window::getString() function
145 /// @see Window::getString()
146 typedef std::function
<bool(const char *)> GetStringHelper
;
148 /// Initializes curses screen and sets some additional attributes
149 /// @param window_title title of the window (has an effect only if pdcurses lib is used)
150 /// @param enable_colors enables colors
151 void initScreen(const char *window_title
, bool enable_colors
);
153 /// Destroys the screen
154 void destroyScreen();
156 /// Struct used to set color of both foreground and background of window
157 /// @see Window::operator<<()
160 Colors(Color one
, Color two
= Color::Default
) : fg(one
), bg(two
) { }
165 /// Struct used for going to given coordinates
166 /// @see Window::operator<<()
169 XY(int xx
, int yy
) : x(xx
), y(yy
) { }
174 /// Main class of NCurses namespace, used as base for other specialized windows
177 Window() : m_window(0), m_border_window(0) { }
179 /// Constructs an empty window with given parameters
180 /// @param startx X position of left upper corner of constructed window
181 /// @param starty Y position of left upper corner of constructed window
182 /// @param width width of constructed window
183 /// @param height height of constructed window
184 /// @param title title of constructed window
185 /// @param color base color of constructed window
186 /// @param border border of constructed window
187 Window(size_t startx
, size_t starty
, size_t width
, size_t height
,
188 const std::string
&title
, Color color
, Border border
);
190 Window(const Window
&rhs
);
191 Window(Window
&&rhs
);
192 Window
&operator=(Window w
);
196 /// Allows for direct access to internal WINDOW pointer in case there
197 /// is no wrapper for a function from curses library one may want to use
198 /// @return internal WINDOW pointer
199 WINDOW
*raw() const { return m_window
; }
201 /// @return window's width
202 size_t getWidth() const;
204 /// @return window's height
205 size_t getHeight() const;
207 /// @return X position of left upper window's corner
208 size_t getStartX() const;
210 /// @return Y position of left upper window's corner
211 size_t getStarty() const;
213 /// @return window's title
214 const std::string
&getTitle() const;
216 /// @return current window's color
217 Color
getColor() const;
219 /// @return current window's border
220 Border
getBorder() const;
222 /// @return current window's timeout
223 int getTimeout() const;
225 /// Reads the string from standard input. Note that this is much more complex
226 /// function than getstr() from curses library. It allows for moving through
227 /// letters with arrows, supports scrolling if string's length is bigger than
228 /// given area, supports history of previous strings and each time it receives
229 /// an input from the keyboard or the timeout is reached, it calls helper function
230 /// (if it's set) that takes as an argument currently edited string.
231 /// @param base base string that has to be edited
232 /// @param length max length of string, unlimited by default
233 /// @param width width of area that entry field can take. if it's reached, string
234 /// will be scrolled. if value is 0, field will be from cursor position to the end
235 /// of current line wide.
236 /// @param encrypted if set to true, '*' characters will be displayed instead of
238 /// @return edited string
240 /// @see setGetStringHelper()
241 /// @see SetTimeout()
242 /// @see CreateHistory()
243 std::string
getString(const std::string
&base
, size_t width
= 0, bool encrypted
= 0);
245 /// Wrapper for above function that doesn't take base string (it will be empty).
246 /// Taken parameters are the same as for above.
247 std::string
getString(size_t width
= 0, bool encrypted
= 0)
249 return getString("", width
, encrypted
);
252 /// Moves cursor to given coordinates
253 /// @param x given X position
254 /// @param y given Y position
255 void goToXY(int x
, int y
);
257 /// @return x window coordinate
260 /// @return y windows coordinate
263 /// Used to indicate whether given coordinates of main screen lies within
264 /// window area or not and if they do, transform them into in-window coords.
265 /// Otherwise function doesn't modify its arguments.
266 /// @param x X position of main screen to be checked
267 /// @param y Y position of main screen to be checked
268 /// @return true if it transformed variables, false otherwise
269 bool hasCoords(int &x
, int &y
);
271 /// Sets helper function used in getString()
272 /// @param helper pointer to function that matches getStringHelper prototype
274 void setGetStringHelper(GetStringHelper helper
) { m_get_string_helper
= helper
; }
276 /// Run current GetString helper function (if defined).
278 /// @return true if helper was run, false otherwise
279 bool runGetStringHelper(const char *arg
, bool *done
) const;
281 /// Sets window's base color
282 /// @param fg foregound base color
283 /// @param bg background base color
284 void setBaseColor(Color fg
, Color bg
= Color::Default
);
286 /// Sets window's border
287 /// @param border new window's border
288 void setBorder(Border border
);
290 /// Sets window's timeout
291 /// @param timeout window's timeout
292 void setTimeout(int timeout
);
294 /// Sets window's title
295 /// @param new_title new title for window
296 void setTitle(const std::string
&new_title
);
298 /// Refreshed whole window and its border
302 /// Refreshes whole window, but not the border
304 virtual void refresh();
306 /// Moves the window to new coordinates
307 /// @param new_x new X position of left upper corner of window
308 /// @param new_y new Y position of left upper corner of window
309 virtual void moveTo(size_t new_x
, size_t new_y
);
311 /// Resizes the window
312 /// @param new_width new window's width
313 /// @param new_height new window's height
314 virtual void resize(size_t new_width
, size_t new_height
);
316 /// Cleares the window
317 virtual void clear();
319 /// Adds given file descriptor to the list that will be polled in
320 /// ReadKey() along with stdin and callback that will be invoked
321 /// when there is data waiting for reading in it
322 /// @param fd file descriptor
323 /// @param callback callback
324 void addFDCallback(int fd
, void (*callback
)());
326 /// Clears list of file descriptors and their callbacks
327 void clearFDCallbacksList();
329 /// Checks if list of file descriptors is empty
330 /// @return true if list is empty, false otherwise
331 bool FDCallbacksListEmpty() const;
333 /// Reads key from standard input (or takes it from input queue)
334 /// and writes it into read_key variable
337 /// Push single character into input queue, so it can get consumed by ReadKey
338 void pushChar(int ch
);
340 /// @return const reference to internal input queue
341 const std::queue
<int> &inputQueue() { return m_input_queue
; }
343 /// Scrolls the window by amount of lines given in its parameter
344 /// @param where indicates how many lines it has to scroll
345 virtual void scroll(Scroll where
);
347 /// Applies function of compatible prototype to internal WINDOW pointer
348 /// The mostly used function in this case seem to be wclrtoeol(), which
349 /// clears the window from current cursor position to the end of line.
350 /// Note that delwin() also matches that prototype, but I wouldn't
351 /// recommend anyone passing this pointer here ;)
352 /// @param f pointer to function to call with internal WINDOW pointer
353 /// @return reference to itself
354 Window
&operator<<(int (*f
)(WINDOW
*));
356 /// Applies foreground and background colors to window
357 /// @param colors struct that holds new colors information
358 /// @return reference to itself
359 Window
&operator<<(Colors colors
);
361 /// Applies foregound color to window. Note that colors applied
362 /// that way are stacked, i.e if you applied Color::Red, then Color::Green
363 /// and Color::End, current color would be Color::Red. If you want to discard
364 /// all colors and fall back to base one, pass Color::Default.
365 /// @param color new color value
366 /// @return reference to itself
367 Window
&operator<<(Color color
);
369 /// Applies format flag to window. Note that these attributes are
370 /// also stacked, so if you applied Format::Bold twice, to get rid of
371 /// it you have to pass Format::NoBold also twice.
372 /// @param format format flag
373 /// @return reference to itself
374 Window
&operator<<(Format format
);
376 /// Moves current cursor position to given coordinates.
377 /// @param coords struct that holds information about new coordinations
378 /// @return reference to itself
379 Window
&operator<<(XY coords
);
381 /// Prints string to window
382 /// @param s const pointer to char array to be printed
383 /// @return reference to itself
384 Window
&operator<<(const char *s
);
386 /// Prints single character to window
387 /// @param c character to be printed
388 /// @return reference to itself
389 Window
&operator<<(char c
);
391 /// Prints wide string to window
392 /// @param ws const pointer to wchar_t array to be printed
393 /// @return reference to itself
394 Window
&operator<<(const wchar_t *ws
);
396 /// Prints single wide character to window
397 /// @param wc wide character to be printed
398 /// @return reference to itself
399 Window
&operator<<(wchar_t wc
);
401 /// Prints int to window
402 /// @param i integer value to be printed
403 /// @return reference to itself
404 Window
&operator<<(int i
);
406 /// Prints double to window
407 /// @param d double value to be printed
408 /// @return reference to itself
409 Window
&operator<<(double d
);
411 /// Prints size_t to window
412 /// @param s size value to be printed
413 /// @return reference to itself
414 Window
&operator<<(size_t s
);
416 /// Prints std::string to window
417 /// @param s string to be printed
418 /// @return reference to itself
419 Window
&operator<<(const std::string
&s
);
421 /// Prints std::wstring to window
422 /// @param ws wide string to be printed
423 /// @return reference to itself
424 Window
&operator<<(const std::wstring
&ws
);
426 /// Sets colors of window (interal use only)
427 /// @param fg foregound color
428 /// @param bg background color
430 void setColor(Color fg
, Color bg
= Color::Default
);
432 /// Refreshes window's border
434 void showBorder() const;
436 /// Changes dimensions of window, called from resize()
437 /// @param width new window's width
438 /// @param height new window's height
441 void adjustDimensions(size_t width
, size_t height
);
443 /// Deletes old window and creates new. It's called by resize(),
444 /// SetBorder() or setTitle() since internally windows are
445 /// handled as curses pads and change in size requires to delete
446 /// them and create again, there is no way to change size of pad.
451 virtual void recreate(size_t width
, size_t height
);
453 /// internal WINDOW pointers
455 WINDOW
*m_border_window
;
457 /// start points and dimensions
464 int m_window_timeout
;
472 Color m_base_bg_color
;
478 /// Sets state of bold attribute (internal use only)
479 /// @param bold_state state of bold attribute
481 void bold(bool bold_state
) const;
483 /// Sets state of underline attribute (internal use only)
484 /// @param underline_state state of underline attribute
486 void underline(bool underline_state
) const;
488 /// Sets state of reverse attribute (internal use only)
489 /// @param reverse_state state of reverse attribute
491 void reverse(bool reverse_state
) const;
493 /// Sets state of altcharset attribute (internal use only)
494 /// @param altcharset_state state of altcharset attribute
496 void altCharset(bool altcharset_state
) const;
498 /// pointer to helper function used by getString()
501 GetStringHelper m_get_string_helper
;
507 std::stack
<Colors
> m_color_stack
;
509 /// input queue of a window. you can put characters there using
510 /// PushChar and they will be immediately consumed and
511 /// returned by ReadKey
512 std::queue
<int> m_input_queue
;
514 /// containter used for additional file descriptors that have
515 /// to be polled in ReadKey() and correspondent callbacks that
516 /// are invoked if there is data available in them
517 typedef std::vector
< std::pair
<int, void (*)()> > FDCallbacks
;
520 /// counters for format flags
522 int m_underline_counter
;
523 int m_reverse_counter
;
524 int m_alt_charset_counter
;
529 #endif // NCMPCPP_WINDOW_H