get rid of HAVE_CONFIG_H directives
[ncmpcpp.git] / src / window.h
blobc5a23817d2ec2c0ac6ebb09351076b75e274fb1e
1 /***************************************************************************
2 * Copyright (C) 2008-2012 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 _WINDOW_H
22 #define _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 #ifndef USE_PDCURSES
95 // NOTICE: redefine BUTTON2_PRESSED as it doesn't always work, I noticed
96 // that it sometimes returns 134217728 (2^27) instead of expected mask, so the
97 // modified define does it right but is rather experimental.
98 # undef BUTTON2_PRESSED
99 # define BUTTON2_PRESSED (NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_PRESSED) | (1U << 27))
100 #endif // USE_PDCURSES
102 #ifdef _UTF8
103 # define my_char_t wchar_t
104 # define U(x) L##x
105 # define TO_STRING(x) ToString(x)
106 # define TO_WSTRING(x) ToWString(x)
107 #else
108 # define my_char_t char
109 # define U(x) x
110 # define TO_STRING(x) (x)
111 # define TO_WSTRING(x) (x)
112 #endif
114 // workaraund for win32
115 #ifdef WIN32
116 # define wcwidth(x) int(!iscntrl(x))
117 #endif
119 /// NC namespace provides set of easy-to-use
120 /// wrappers over original curses library
122 namespace NC
124 /// Colors used by NCurses
126 enum Color { clDefault, clBlack, clRed, clGreen, clYellow, clBlue, clMagenta, clCyan, clWhite, clEnd };
128 /// Format flags used by NCurses
130 enum Format {
131 fmtNone = clEnd+1,
132 fmtBold, fmtBoldEnd,
133 fmtUnderline, fmtUnderlineEnd,
134 fmtReverse, fmtReverseEnd,
135 fmtAltCharset, fmtAltCharsetEnd
138 /// Available border colors for window
140 enum Border { brNone, brBlack, brRed, brGreen, brYellow, brBlue, brMagenta, brCyan, brWhite };
142 /// This indicates how much the window has to be scrolled
144 enum Where { wUp, wDown, wPageUp, wPageDown, wHome, wEnd };
146 /// Helper function that is invoked each time one will want
147 /// to obtain string from Window::GetString() function
148 /// @see Window::GetString()
150 typedef std::function<void(const std::wstring &)> GetStringHelper;
152 /// Initializes curses screen and sets some additional attributes
153 /// @param window_title title of the window (has an effect only if pdcurses lib is used)
154 /// @param enable_colors enables colors
156 void InitScreen(const char *window_title, bool enable_colors);
158 /// Destroys the screen
160 void DestroyScreen();
162 /// Struct used to set color of both foreground and background of window
163 /// @see Window::operator<<()
165 struct Colors
167 Colors(Color one, Color two = clDefault) : fg(one), bg(two) { }
168 Color fg;
169 Color bg;
172 /// Struct used for going to given coordinates
173 /// @see Window::operator<<()
175 struct XY
177 XY(int xx, int yy) : x(xx), y(yy) { }
178 int x;
179 int y;
182 /// Main class of NCurses namespace, used as base for other specialized windows
184 struct Window
186 /// Constructs an empty window with given parameters
187 /// @param startx X position of left upper corner of constructed window
188 /// @param starty Y position of left upper corner of constructed window
189 /// @param width width of constructed window
190 /// @param height height of constructed window
191 /// @param title title of constructed window
192 /// @param color base color of constructed window
193 /// @param border border of constructed window
195 Window(size_t startx, size_t starty, size_t width, size_t height,
196 const std::string &title, Color color, Border border);
198 /// Copies thw window
199 /// @param w copied window
201 Window(const Window &w);
203 /// Destroys the window and frees memory
205 virtual ~Window();
207 /// Allows for direct access to internal WINDOW pointer in case there
208 /// is no wrapper for a function from curses library one may want to use
209 /// @return internal WINDOW pointer
211 WINDOW *Raw() const { return itsWindow; }
213 /// @return window's width
215 size_t GetWidth() const;
217 /// @return window's height
219 size_t GetHeight() const;
221 /// @return X position of left upper window's corner
223 size_t GetStartX() const;
225 /// @return Y position of left upper window's corner
227 size_t GetStartY() const;
229 /// @return window's title
231 const std::string &getTitle() const;
233 /// @return current window's color
235 Color GetColor() const;
237 /// @return current window's border
239 Border GetBorder() const;
241 /// @return current window's timeout
243 int GetTimeout() const;
245 /// Reads the string from standard input. Note that this is much more complex
246 /// function than getstr() from curses library. It allows for moving through
247 /// letters with arrows, supports scrolling if string's length is bigger than
248 /// given area, supports history of previous strings and each time it receives
249 /// an input from the keyboard or the timeout is reached, it calls helper function
250 /// (if it's set) that takes as an argument currently edited string.
251 /// @param base base string that has to be edited
252 /// @param length max length of string, unlimited by default
253 /// @param width width of area that entry field can take. if it's reached, string
254 /// will be scrolled. if value is 0, field will be from cursor position to the end
255 /// of current line wide.
256 /// @param encrypted if set to true, '*' characters will be displayed instead of
257 /// actual text.
258 /// @return edited string
260 /// @see SetGetStringHelper()
261 /// @see SetTimeout()
262 /// @see CreateHistory()
264 std::string GetString(const std::string &base, size_t length = -1,
265 size_t width = 0, bool encrypted = 0);
267 /// Wrapper for above function that doesn't take base string (it will be empty).
268 /// Taken parameters are the same as for above.
270 std::string GetString(size_t length = -1, size_t width = 0, bool encrypted = 0)
272 return GetString("", length, width, encrypted);
275 /// Moves cursor to given coordinates
276 /// @param x given X position
277 /// @param y given Y position
279 void GotoXY(int x, int y);
281 /// @return x window coordinate
282 /// @see GetXY()
284 int X();
286 /// @return y windows coordinate
287 /// @see GetXY()
289 int Y();
291 /// Used to indicate whether given coordinates of main screen lies within
292 /// window area or not and if they do, transform them into in-window coords.
293 /// Otherwise function doesn't modify its arguments.
294 /// @param x X position of main screen to be checked
295 /// @param y Y position of main screen to be checked
296 /// @return true if it transformed variables, false otherwise
298 bool hasCoords(int &x, int &y);
300 /// Sets helper function used in GetString()
301 /// @param helper pointer to function that matches GetStringHelper prototype
302 /// @see GetString()
304 void SetGetStringHelper(GetStringHelper helper) { itsGetStringHelper = helper; }
306 /// Sets window's base color
307 /// @param fg foregound base color
308 /// @param bg background base color
310 void SetBaseColor(Color fg, Color bg = clDefault);
312 /// Sets window's border
313 /// @param border new window's border
315 void SetBorder(Border border);
317 /// Sets window's timeout
318 /// @param timeout window's timeout
320 void SetTimeout(int timeout);
322 /// Sets window's title
323 /// @param new_title new title for window
325 void SetTitle(const std::string &new_title);
327 /// Creates internal container that stores all previous
328 /// strings that were edited using this window.
330 void CreateHistory();
332 /// Deletes container with all previous history entries
334 void DeleteHistory();
336 /// "Hides" the window by filling its area with given character
337 /// @param ch character to fill the area
338 /// @see Clear()
340 void Hide(char ch = 32) const;
342 /// Refreshed whole window and its border
343 /// @see Refresh()
345 void Display();
347 /// Refreshes whole window, but not the border
348 /// @see Display()
350 virtual void Refresh();
352 /// Moves the window to new coordinates
353 /// @param new_x new X position of left upper corner of window
354 /// @param new_y new Y position of left upper corner of window
356 virtual void MoveTo(size_t new_x, size_t new_y);
358 /// Resizes the window
359 /// @param new_width new window's width
360 /// @param new_height new window's height
362 virtual void Resize(size_t new_width, size_t new_height);
364 /// Cleares the window
366 virtual void Clear();
368 /// Adds given file descriptor to the list that will be polled in
369 /// ReadKey() along with stdin and callback that will be invoked
370 /// when there is data waiting for reading in it
371 /// @param fd file descriptor
372 /// @param callback callback
374 void AddFDCallback(int fd, void (*callback)());
376 /// Clears list of file descriptors and their callbacks
378 void ClearFDCallbacksList();
380 /// Checks if list of file descriptors is empty
381 /// @return true if list is empty, false otherwise
383 bool FDCallbacksListEmpty() const;
385 /// Reads key from standard input (or takes it from input queue)
386 /// and writes it into read_key variable
388 int ReadKey();
390 /// Push single character into input queue, so it can get consumed by ReadKey
391 void PushChar(int ch);
393 /// Scrolls the window by amount of lines given in its parameter
394 /// @param where indicates how many lines it has to scroll
396 virtual void Scroll(Where where);
398 /// Applies function of compatible prototype to internal WINDOW pointer
399 /// The mostly used function in this case seem to be wclrtoeol(), which
400 /// clears the window from current cursor position to the end of line.
401 /// Note that delwin() also matches that prototype, but I wouldn't
402 /// recommend anyone passing this pointer here ;)
403 /// @param f pointer to function to call with internal WINDOW pointer
404 /// @return reference to itself
406 Window &operator<<(int (*f)(WINDOW *));
408 /// Applies foreground and background colors to window
409 /// @param colors struct that holds new colors information
410 /// @return reference to itself
412 Window &operator<<(Colors colors);
414 /// Applies foregound color to window. Note that colors applied
415 /// that way are stacked, i.e if you applied clRed, then clGreen
416 /// and clEnd, current color would be clRed. If you want to discard
417 /// all colors and fall back to base one, pass clDefault.
418 /// @param color new color value
419 /// @return reference to itself
421 Window &operator<<(Color color);
423 /// Applies format flag to window. Note that these attributes are
424 /// also stacked, so if you applied fmtBold twice, to get rid of
425 /// it you have to pass fmtBoldEnd also twice.
426 /// @param format format flag
427 /// @return reference to itself
429 Window &operator<<(Format format);
431 /// Moves current cursor position to given coordinates.
432 /// @param coords struct that holds information about new coordinations
433 /// @return reference to itself
435 Window &operator<<(XY coords);
437 /// Prints string to window
438 /// @param s const pointer to char array to be printed
439 /// @return reference to itself
441 Window &operator<<(const char *s);
443 /// Prints single character to window
444 /// @param c character to be printed
445 /// @return reference to itself
447 Window &operator<<(char c);
449 /// Prints wide string to window
450 /// @param ws const pointer to wchar_t array to be printed
451 /// @return reference to itself
453 Window &operator<<(const wchar_t *ws);
455 /// Prints single wide character to window
456 /// @param wc wide character to be printed
457 /// @return reference to itself
459 Window &operator<<(wchar_t wc);
461 /// Prints int to window
462 /// @param i integer value to be printed
463 /// @return reference to itself
465 Window &operator<<(int i);
467 /// Prints double to window
468 /// @param d double value to be printed
469 /// @return reference to itself
471 Window &operator<<(double d);
473 /// Prints size_t to window
474 /// @param s size value to be printed
475 /// @return reference to itself
477 Window &operator<<(size_t s);
479 /// Prints std::string to window
480 /// @param s string to be printed
481 /// @return reference to itself
483 Window &operator<<(const std::string &s);
485 /// Prints std::wstring to window
486 /// @param ws wide string to be printed
487 /// @return reference to itself
489 Window &operator<<(const std::wstring &ws);
491 /// Fallback for Length() for wide strings used if unicode support is disabled
492 /// @param s string that real length has to be measured
493 /// @return standard std::string::length() result since it's only fallback
495 static size_t Length(const std::string &s) { return s.length(); }
497 /// Measures real length of wide string (required if e.g. asian characters are used)
498 /// @param ws wide string that real length has to be measured
499 /// @return real length of wide string
501 static size_t Length(const std::wstring &ws);
503 /// Cuts string so it fits desired length on the screen. Note that it uses
504 /// wcwidth to check real width of all characters it contains. If string
505 /// fits requested length it's not modified at all.
506 /// @param ws wide string to be cut
507 /// @param max_len maximal length of string
508 static void Cut(std::wstring &ws, size_t max_len);
510 protected:
511 /// Sets colors of window (interal use only)
512 /// @param fg foregound color
513 /// @param bg background color
515 void SetColor(Color fg, Color bg = clDefault);
517 /// Refreshes window's border
519 void ShowBorder() const;
521 /// Changes dimensions of window, called from Resize()
522 /// @param width new window's width
523 /// @param height new window's height
524 /// @see Resize()
526 void AdjustDimensions(size_t width, size_t height);
528 /// Deletes old window and creates new. It's called by Resize(),
529 /// SetBorder() or SetTitle() since internally windows are
530 /// handled as curses pads and change in size requires to delete
531 /// them and create again, there is no way to change size of pad.
532 /// @see SetBorder()
533 /// @see SetTitle()
534 /// @see Resize()
536 virtual void Recreate(size_t width, size_t height);
538 /// internal WINDOW pointers
539 WINDOW *itsWindow;
540 WINDOW *itsWinBorder;
542 /// start points and dimensions
543 size_t itsStartX;
544 size_t itsStartY;
545 size_t itsWidth;
546 size_t itsHeight;
548 /// window timeout
549 int itsWindowTimeout;
551 /// current colors
552 Color itsColor;
553 Color itsBgColor;
555 /// base colors
556 Color itsBaseColor;
557 Color itsBaseBgColor;
559 /// current border
560 Border itsBorder;
562 private:
563 /// Sets state of bold attribute (internal use only)
564 /// @param bold_state state of bold attribute
566 void Bold(bool bold_state) const;
568 /// Sets state of underline attribute (internal use only)
569 /// @param underline_state state of underline attribute
571 void Underline(bool underline_state) const;
573 /// Sets state of reverse attribute (internal use only)
574 /// @param reverse_state state of reverse attribute
576 void Reverse(bool reverse_state) const;
578 /// Sets state of altcharset attribute (internal use only)
579 /// @param altcharset_state state of altcharset attribute
581 void AltCharset(bool altcharset_state) const;
583 /// pointer to helper function used by GetString()
584 /// @see GetString()
586 GetStringHelper itsGetStringHelper;
588 /// window title
589 std::string itsTitle;
591 /// stack of colors
592 std::stack<Colors> itsColors;
594 /// input queue of a window. you can put characters there using
595 /// PushChar and they will be immediately consumed and
596 /// returned by ReadKey
597 std::queue<int> itsInputQueue;
599 /// containter used for additional file descriptors that have
600 /// to be polled in ReadKey() and correspondent callbacks that
601 /// are invoked if there is data available in them
602 typedef std::vector< std::pair<int, void (*)()> > FDCallbacks;
603 FDCallbacks itsFDs;
605 /// pointer to container used as history
606 std::list<std::wstring> *itsHistory;
608 /// counters for format flags
609 int itsBoldCounter;
610 int itsUnderlineCounter;
611 int itsReverseCounter;
612 int itsAltCharsetCounter;
617 #endif