1 /***************************************************************************
2 * Copyright (C) 2008-2012 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 ***************************************************************************/
27 # define NCURSES_MOUSE_VERSION 1
40 // define some Ctrl-? keys
83 #define KEY_SHIFT_TAB 353
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.
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
103 # define my_char_t wchar_t
105 # define TO_STRING(x) ToString(x)
106 # define TO_WSTRING(x) ToWString(x)
108 # define my_char_t char
110 # define TO_STRING(x) (x)
111 # define TO_WSTRING(x) (x)
114 // workaraund for win32
116 # define wcwidth(x) int(!iscntrl(x))
119 /// NC namespace provides set of easy-to-use
120 /// wrappers over original curses library
124 /// Colors used by NCurses
126 enum Color
{ clDefault
, clBlack
, clRed
, clGreen
, clYellow
, clBlue
, clMagenta
, clCyan
, clWhite
, clEnd
};
128 /// Format flags used by NCurses
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<<()
167 Colors(Color one
, Color two
= clDefault
) : fg(one
), bg(two
) { }
172 /// Struct used for going to given coordinates
173 /// @see Window::operator<<()
177 XY(int xx
, int yy
) : x(xx
), y(yy
) { }
182 /// Main class of NCurses namespace, used as base for other specialized windows
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
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
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
286 /// @return y windows coordinate
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
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
340 void Hide(char ch
= 32) const;
342 /// Refreshed whole window and its border
347 /// Refreshes whole window, but not the border
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
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
);
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
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.
536 virtual void Recreate(size_t width
, size_t height
);
538 /// internal WINDOW pointers
540 WINDOW
*itsWinBorder
;
542 /// start points and dimensions
549 int itsWindowTimeout
;
557 Color itsBaseBgColor
;
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()
586 GetStringHelper itsGetStringHelper
;
589 std::string itsTitle
;
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
;
605 /// pointer to container used as history
606 std::list
<std::wstring
> *itsHistory
;
608 /// counters for format flags
610 int itsUnderlineCounter
;
611 int itsReverseCounter
;
612 int itsAltCharsetCounter
;