option parser: make assign_default_once work with non-copyable types
[ncmpcpp.git] / src / window.h
blob144b9e9eeb6db919a8b46061acdab20ef253b2ae
1 /***************************************************************************
2 * Copyright (C) 2008-2014 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
4 * *
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. *
9 * *
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. *
14 * *
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
24 #include "config.h"
26 #ifdef USE_PDCURSES
27 # define NCURSES_MOUSE_VERSION 1
28 #endif
30 #include "curses.h"
31 #include "gcc.h"
33 #include <functional>
34 #include <list>
35 #include <stack>
36 #include <vector>
37 #include <string>
38 #include <queue>
40 // define some Ctrl-? keys
41 #define KEY_CTRL_A 1
42 #define KEY_CTRL_B 2
43 #define KEY_CTRL_C 3
44 #define KEY_CTRL_D 4
45 #define KEY_CTRL_E 5
46 #define KEY_CTRL_F 6
47 #define KEY_CTRL_G 7
48 #define KEY_CTRL_H 8
49 #define KEY_CTRL_I 9
50 #define KEY_CTRL_J 10
51 #define KEY_CTRL_K 11
52 #define KEY_CTRL_L 12
53 #define KEY_CTRL_M 13
54 #define KEY_CTRL_N 14
55 #define KEY_CTRL_O 15
56 #define KEY_CTRL_P 16
57 #define KEY_CTRL_Q 17
58 #define KEY_CTRL_R 18
59 #define KEY_CTRL_S 19
60 #define KEY_CTRL_T 20
61 #define KEY_CTRL_U 21
62 #define KEY_CTRL_V 22
63 #define KEY_CTRL_W 23
64 #define KEY_CTRL_X 24
65 #define KEY_CTRL_Y 25
66 #define KEY_CTRL_Z 26
68 // define F? keys
69 #define KEY_F1 265
70 #define KEY_F2 266
71 #define KEY_F3 267
72 #define KEY_F4 268
73 #define KEY_F5 269
74 #define KEY_F6 270
75 #define KEY_F7 271
76 #define KEY_F8 272
77 #define KEY_F9 273
78 #define KEY_F10 274
79 #define KEY_F11 275
80 #define KEY_F12 276
82 // other handy keys
83 #define KEY_SHIFT_TAB 353
84 #define KEY_SPACE 32
85 #define KEY_TAB 9
87 // define alternative KEY_BACKSPACE (used in some terminal emulators)
88 #define KEY_BACKSPACE_2 127
90 // KEY_ENTER is 343, which doesn't make any sense. This makes it useful.
91 #undef KEY_ENTER
92 #define KEY_ENTER 10
94 // undefine scroll macro as it collides with Window::scroll
95 #undef scroll
97 #ifndef USE_PDCURSES
98 // NOTICE: redefine BUTTON2_PRESSED as it doesn't always work, I noticed
99 // that it sometimes returns 134217728 (2^27) instead of expected mask, so the
100 // modified define does it right but is rather experimental.
101 # undef BUTTON2_PRESSED
102 # define BUTTON2_PRESSED (NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_PRESSED) | (1U << 27))
103 #endif // USE_PDCURSES
105 // workaraund for win32
106 #ifdef WIN32
107 # define wcwidth(x) int(!iscntrl(x))
108 #endif
110 /// NC namespace provides set of easy-to-use
111 /// wrappers over original curses library
112 namespace NC {//
114 /// Colors used by NCurses
115 enum class Color { Default, Black, Red, Green, Yellow, Blue, Magenta, Cyan, White, End };
117 std::ostream &operator<<(std::ostream &os, Color c);
118 std::istream &operator>>(std::istream &is, Color &c);
120 /// Format flags used by NCurses
121 enum class Format {
122 None,
123 Bold, NoBold,
124 Underline, NoUnderline,
125 Reverse, NoReverse,
126 AltCharset, NoAltCharset
129 std::ostream &operator<<(std::ostream &os, Format f);
131 /// Available border colors for window
132 enum class Border { None, Black, Red, Green, Yellow, Blue, Magenta, Cyan, White };
134 std::ostream &operator<<(std::ostream &os, Border b);
135 std::istream &operator>>(std::istream &is, Border &b);
137 /// This indicates how much the window has to be scrolled
138 enum class Scroll { Up, Down, PageUp, PageDown, Home, End };
140 std::ostream &operator<<(std::ostream &os, Scroll s);
142 /// Helper function that is invoked each time one will want
143 /// to obtain string from Window::getString() function
144 /// @see Window::getString()
145 typedef std::function<bool(const char *)> GetStringHelper;
147 /// Initializes curses screen and sets some additional attributes
148 /// @param window_title title of the window (has an effect only if pdcurses lib is used)
149 /// @param enable_colors enables colors
150 void initScreen(const char *window_title, bool enable_colors);
152 /// Destroys the screen
153 void destroyScreen();
155 /// Struct used to set color of both foreground and background of window
156 /// @see Window::operator<<()
157 struct Colors
159 Colors(Color one, Color two = Color::Default) : fg(one), bg(two) { }
160 Color fg;
161 Color bg;
164 /// Struct used for going to given coordinates
165 /// @see Window::operator<<()
166 struct XY
168 XY(int xx, int yy) : x(xx), y(yy) { }
169 int x;
170 int y;
173 /// Main class of NCurses namespace, used as base for other specialized windows
174 struct Window
176 Window() : m_window(0), m_border_window(0) { }
178 /// Constructs an empty window with given parameters
179 /// @param startx X position of left upper corner of constructed window
180 /// @param starty Y position of left upper corner of constructed window
181 /// @param width width of constructed window
182 /// @param height height of constructed window
183 /// @param title title of constructed window
184 /// @param color base color of constructed window
185 /// @param border border of constructed window
186 Window(size_t startx, size_t starty, size_t width, size_t height,
187 const std::string &title, Color color, Border border);
189 Window(const Window &rhs);
190 Window(Window &&rhs);
191 Window &operator=(Window w);
193 virtual ~Window();
195 /// Allows for direct access to internal WINDOW pointer in case there
196 /// is no wrapper for a function from curses library one may want to use
197 /// @return internal WINDOW pointer
198 WINDOW *raw() const { return m_window; }
200 /// @return window's width
201 size_t getWidth() const;
203 /// @return window's height
204 size_t getHeight() const;
206 /// @return X position of left upper window's corner
207 size_t getStartX() const;
209 /// @return Y position of left upper window's corner
210 size_t getStarty() const;
212 /// @return window's title
213 const std::string &getTitle() const;
215 /// @return current window's color
216 Color getColor() const;
218 /// @return current window's border
219 Border getBorder() const;
221 /// @return current window's timeout
222 int getTimeout() const;
224 /// Reads the string from standard input. Note that this is much more complex
225 /// function than getstr() from curses library. It allows for moving through
226 /// letters with arrows, supports scrolling if string's length is bigger than
227 /// given area, supports history of previous strings and each time it receives
228 /// an input from the keyboard or the timeout is reached, it calls helper function
229 /// (if it's set) that takes as an argument currently edited string.
230 /// @param base base string that has to be edited
231 /// @param length max length of string, unlimited by default
232 /// @param width width of area that entry field can take. if it's reached, string
233 /// will be scrolled. if value is 0, field will be from cursor position to the end
234 /// of current line wide.
235 /// @param encrypted if set to true, '*' characters will be displayed instead of
236 /// actual text.
237 /// @return edited string
239 /// @see setGetStringHelper()
240 /// @see SetTimeout()
241 /// @see CreateHistory()
242 std::string getString(const std::string &base, size_t width = 0, bool encrypted = 0);
244 /// Wrapper for above function that doesn't take base string (it will be empty).
245 /// Taken parameters are the same as for above.
246 std::string getString(size_t width = 0, bool encrypted = 0)
248 return getString("", width, encrypted);
251 /// Moves cursor to given coordinates
252 /// @param x given X position
253 /// @param y given Y position
254 void goToXY(int x, int y);
256 /// @return x window coordinate
257 int getX();
259 /// @return y windows coordinate
260 int getY();
262 /// Used to indicate whether given coordinates of main screen lies within
263 /// window area or not and if they do, transform them into in-window coords.
264 /// Otherwise function doesn't modify its arguments.
265 /// @param x X position of main screen to be checked
266 /// @param y Y position of main screen to be checked
267 /// @return true if it transformed variables, false otherwise
268 bool hasCoords(int &x, int &y);
270 /// Sets helper function used in getString()
271 /// @param helper pointer to function that matches getStringHelper prototype
272 /// @see getString()
273 void setGetStringHelper(GetStringHelper helper) { m_get_string_helper = helper; }
275 /// Run current GetString helper function (if defined).
276 /// @see getString()
277 /// @return true if helper was run, false otherwise
278 bool runGetStringHelper(const char *arg, bool *done) const;
280 /// Sets window's base color
281 /// @param fg foregound base color
282 /// @param bg background base color
283 void setBaseColor(Color fg, Color bg = Color::Default);
285 /// Sets window's border
286 /// @param border new window's border
287 void setBorder(Border border);
289 /// Sets window's timeout
290 /// @param timeout window's timeout
291 void setTimeout(int timeout);
293 /// Sets window's title
294 /// @param new_title new title for window
295 void setTitle(const std::string &new_title);
297 /// Refreshed whole window and its border
298 /// @see refresh()
299 void display();
301 /// Refreshes whole window, but not the border
302 /// @see display()
303 virtual void refresh();
305 /// Moves the window to new coordinates
306 /// @param new_x new X position of left upper corner of window
307 /// @param new_y new Y position of left upper corner of window
308 virtual void moveTo(size_t new_x, size_t new_y);
310 /// Resizes the window
311 /// @param new_width new window's width
312 /// @param new_height new window's height
313 virtual void resize(size_t new_width, size_t new_height);
315 /// Cleares the window
316 virtual void clear();
318 /// Adds given file descriptor to the list that will be polled in
319 /// ReadKey() along with stdin and callback that will be invoked
320 /// when there is data waiting for reading in it
321 /// @param fd file descriptor
322 /// @param callback callback
323 void addFDCallback(int fd, void (*callback)());
325 /// Clears list of file descriptors and their callbacks
326 void clearFDCallbacksList();
328 /// Checks if list of file descriptors is empty
329 /// @return true if list is empty, false otherwise
330 bool FDCallbacksListEmpty() const;
332 /// Reads key from standard input (or takes it from input queue)
333 /// and writes it into read_key variable
334 int readKey();
336 /// Push single character into input queue, so it can get consumed by ReadKey
337 void pushChar(int ch);
339 /// @return const reference to internal input queue
340 const std::queue<int> &inputQueue() { return m_input_queue; }
342 /// Scrolls the window by amount of lines given in its parameter
343 /// @param where indicates how many lines it has to scroll
344 virtual void scroll(Scroll where);
346 /// Applies function of compatible prototype to internal WINDOW pointer
347 /// The mostly used function in this case seem to be wclrtoeol(), which
348 /// clears the window from current cursor position to the end of line.
349 /// Note that delwin() also matches that prototype, but I wouldn't
350 /// recommend anyone passing this pointer here ;)
351 /// @param f pointer to function to call with internal WINDOW pointer
352 /// @return reference to itself
353 Window &operator<<(int (*f)(WINDOW *));
355 /// Applies foreground and background colors to window
356 /// @param colors struct that holds new colors information
357 /// @return reference to itself
358 Window &operator<<(Colors colors);
360 /// Applies foregound color to window. Note that colors applied
361 /// that way are stacked, i.e if you applied Color::Red, then Color::Green
362 /// and Color::End, current color would be Color::Red. If you want to discard
363 /// all colors and fall back to base one, pass Color::Default.
364 /// @param color new color value
365 /// @return reference to itself
366 Window &operator<<(Color color);
368 /// Applies format flag to window. Note that these attributes are
369 /// also stacked, so if you applied Format::Bold twice, to get rid of
370 /// it you have to pass Format::NoBold also twice.
371 /// @param format format flag
372 /// @return reference to itself
373 Window &operator<<(Format format);
375 /// Moves current cursor position to given coordinates.
376 /// @param coords struct that holds information about new coordinations
377 /// @return reference to itself
378 Window &operator<<(XY coords);
380 /// Prints string to window
381 /// @param s const pointer to char array to be printed
382 /// @return reference to itself
383 Window &operator<<(const char *s);
385 /// Prints single character to window
386 /// @param c character to be printed
387 /// @return reference to itself
388 Window &operator<<(char c);
390 /// Prints wide string to window
391 /// @param ws const pointer to wchar_t array to be printed
392 /// @return reference to itself
393 Window &operator<<(const wchar_t *ws);
395 /// Prints single wide character to window
396 /// @param wc wide character to be printed
397 /// @return reference to itself
398 Window &operator<<(wchar_t wc);
400 /// Prints int to window
401 /// @param i integer value to be printed
402 /// @return reference to itself
403 Window &operator<<(int i);
405 /// Prints double to window
406 /// @param d double value to be printed
407 /// @return reference to itself
408 Window &operator<<(double d);
410 /// Prints size_t to window
411 /// @param s size value to be printed
412 /// @return reference to itself
413 Window &operator<<(size_t s);
415 /// Prints std::string to window
416 /// @param s string to be printed
417 /// @return reference to itself
418 Window &operator<<(const std::string &s);
420 /// Prints std::wstring to window
421 /// @param ws wide string to be printed
422 /// @return reference to itself
423 Window &operator<<(const std::wstring &ws);
424 protected:
425 /// Sets colors of window (interal use only)
426 /// @param fg foregound color
427 /// @param bg background color
429 void setColor(Color fg, Color bg = Color::Default);
431 /// Refreshes window's border
433 void showBorder() const;
435 /// Changes dimensions of window, called from resize()
436 /// @param width new window's width
437 /// @param height new window's height
438 /// @see resize()
440 void adjustDimensions(size_t width, size_t height);
442 /// Deletes old window and creates new. It's called by resize(),
443 /// SetBorder() or setTitle() since internally windows are
444 /// handled as curses pads and change in size requires to delete
445 /// them and create again, there is no way to change size of pad.
446 /// @see SetBorder()
447 /// @see setTitle()
448 /// @see resize()
450 virtual void recreate(size_t width, size_t height);
452 /// internal WINDOW pointers
453 WINDOW *m_window;
454 WINDOW *m_border_window;
456 /// start points and dimensions
457 size_t m_start_x;
458 size_t m_start_y;
459 size_t m_width;
460 size_t m_height;
462 /// window timeout
463 int m_window_timeout;
465 /// current colors
466 Color m_color;
467 Color m_bg_color;
469 /// base colors
470 Color m_base_color;
471 Color m_base_bg_color;
473 /// current border
474 Border m_border;
476 private:
477 /// Sets state of bold attribute (internal use only)
478 /// @param bold_state state of bold attribute
480 void bold(bool bold_state) const;
482 /// Sets state of underline attribute (internal use only)
483 /// @param underline_state state of underline attribute
485 void underline(bool underline_state) const;
487 /// Sets state of reverse attribute (internal use only)
488 /// @param reverse_state state of reverse attribute
490 void reverse(bool reverse_state) const;
492 /// Sets state of altcharset attribute (internal use only)
493 /// @param altcharset_state state of altcharset attribute
495 void altCharset(bool altcharset_state) const;
497 /// pointer to helper function used by getString()
498 /// @see getString()
500 GetStringHelper m_get_string_helper;
502 /// window title
503 std::string m_title;
505 /// stack of colors
506 std::stack<Colors> m_color_stack;
508 /// input queue of a window. you can put characters there using
509 /// PushChar and they will be immediately consumed and
510 /// returned by ReadKey
511 std::queue<int> m_input_queue;
513 /// containter used for additional file descriptors that have
514 /// to be polled in ReadKey() and correspondent callbacks that
515 /// are invoked if there is data available in them
516 typedef std::vector< std::pair<int, void (*)()> > FDCallbacks;
517 FDCallbacks m_fds;
519 /// counters for format flags
520 int m_bold_counter;
521 int m_underline_counter;
522 int m_reverse_counter;
523 int m_alt_charset_counter;
528 #endif // NCMPCPP_WINDOW_H