cwidget  0.5.17
curses++.h
1 // curses++.h (this is -*-c++-*-)
2 //
3 // Copyright 1999-2005, 2007 Daniel Burrows
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; see the file COPYING. If not, write to
17 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 // Boston, MA 02111-1307, USA.
19 //
20 // Simple class wrappers around various CURSES functions.
21 
22 #ifndef CURSES_PLUSPLUS_H
23 #define CURSES_PLUSPLUS_H
24 
25 #include <string>
26 #include <ncursesw/curses.h>
27 
28 #include <cwidget/generic/util/eassert.h>
29 
30 // For isspace
31 #include <ctype.h>
32 
33 #include <string.h>
34 
35 #include <cwidget-config.h>
36 
37 namespace cwidget
38 {
47  struct wchtype
48  {
54  wchar_t ch;
55 
59  attr_t attrs;
60 
61  wchtype()
62  {
63  }
64 
65  wchtype(const wchar_t &_ch, const attr_t &_attrs)
66  :ch(_ch), attrs(_attrs)
67  {
68  }
69 
70  bool operator==(const wchtype &other) const
71  {
72  return ch==other.ch && attrs==other.attrs;
73  }
74 
75  bool operator!=(const wchtype &other) const
76  {
77  return ch!=other.ch || attrs!=other.attrs;
78  }
79 
80  bool operator<(const wchtype &other) const
81  {
82  return ch<other.ch || (ch==other.ch && attrs<other.attrs);
83  }
84 
85  bool operator<=(const wchtype &other) const
86  {
87  return (*this) == other || (*this) < other;
88  }
89 
90  bool operator>(const wchtype &other) const
91  {
92  return !((*this)<=other);
93  }
94 
95  bool operator>=(const wchtype &other) const
96  {
97  return !((*this)<other);
98  }
99  };
100 }
101 
102 namespace std {
103  template <>
113  struct TRAITS_CLASS<chtype> {
114  typedef chtype char_type;
115 
116  static void assign (char_type& c1, const char_type& c2)
117  { c1 = c2; }
118  static bool eq (const char_type & c1, const char_type& c2)
119  { return (c1 == c2); }
120  static bool ne (const char_type& c1, const char_type& c2)
121  { return (c1 != c2); }
122  static bool lt (const char_type& c1, const char_type& c2)
123  { return (c1 < c2); }
124  static char_type eos () { return 0; }
125  static bool is_del(char_type a) { return isspace(a|A_CHARTEXT); }
126 
127  static int compare (const char_type* s1, const char_type* s2, size_t n);
128  static size_t length (const char_type* s);
129  static char_type* copy (char_type* s1, const char_type* s2, size_t n)
130  { return (char_type*) memcpy (s1, s2, n*sizeof(char_type)); }
131  static char_type* move (char_type* s1, const char_type* s2, size_t n)
132  { return (char_type*) memmove (s1, s2, n*sizeof(char_type)); }
133  static char_type* assign (char_type* s1, size_t n, const char_type& c);
134  };
135 
136  template <>
137  struct TRAITS_CLASS<cwidget::wchtype> {
138  typedef cwidget::wchtype char_type;
139 
140  static void assign (char_type& c1, const char_type& c2)
141  { c1 = c2; }
142  static bool eq (const char_type & c1, const char_type& c2)
143  { return (c1 == c2); }
144  static bool ne (const char_type& c1, const char_type& c2)
145  { return (c1 != c2); }
146  static bool lt (const char_type& c1, const char_type& c2)
147  { return (c1 < c2); }
148  static char_type eos () { return cwidget::wchtype(0,0); }
149  static bool is_del(char_type a) { return isspace(a.ch); }
150 
151  static int compare (const char_type* s1, const char_type* s2, size_t n);
152  static size_t length (const char_type* s);
153  static char_type* copy (char_type* s1, const char_type* s2, size_t n)
154  { return (char_type*) memcpy (s1, s2, n*sizeof(char_type)); }
155  static char_type* move (char_type* s1, const char_type* s2, size_t n)
156  { return (char_type*) memmove (s1, s2, n*sizeof(char_type)); }
157  static char_type* assign (char_type* s1, size_t n, const char_type& c);
158  };
159 }
160 
161 namespace cwidget
162 {
163  class style;
164 
170  class chstring:public std::basic_string<chtype>
171  {
172  typedef std::basic_string<chtype> super;
173  public:
174  chstring(const std::basic_string<chtype> &s)
175  :std::basic_string<chtype>(s) {}
176 
177  chstring(const std::string &s);
178  chstring(const std::string &s, const style &st);
179 
180  chstring(const chstring &s):super(s) {}
184  chstring(const chstring &s, const style &st);
185 
186  chstring(const chstring &s, size_t loc, size_t n=npos)
187  :super(s, loc, n) {}
188 
189  chstring(size_t n, chtype c)
190  :super(n, c) {}
191 
193  chstring &operator=(const std::string &s);
194 
196  void apply_style(const style &st);
197  };
198 
199  class wchstring:public std::basic_string<wchtype>
200  {
201  typedef std::basic_string<wchtype> super;
202  public:
203  wchstring(const std::basic_string<wchtype> &s)
204  :std::basic_string<wchtype>(s) {}
205 
207  wchstring(const std::wstring &s);
208 
212  wchstring(const std::wstring &s, const style &st);
213 
214  wchstring(const wchstring &s):super(s) {}
218  wchstring(const wchstring &s, const style &st);
219 
220  wchstring(const wchstring &s, size_t loc, size_t n=npos)
221  :super(s, loc, n) {}
222 
223  wchstring(size_t n, wchtype c)
224  :super(n, c) {}
225 
226  wchstring(size_t n, wchar_t c, attr_t a)
227  :super(n, wchtype(c, a)) {}
228 
230  void apply_style(const style &st);
231 
233  int width() const;
234  };
235 
236  inline chtype _getbkgd(WINDOW *win)
237  {
238  return getbkgd(win);
239  }
240 
241  inline int _box(WINDOW *win, chtype verch, chtype horch)
242  {
243  return box(win, verch, horch);
244  }
245 
246  inline void _getyx(WINDOW *win, int &y, int &x)
247  {
248  getyx(win, y, x);
249  }
250 
251  inline void _getparyx(WINDOW *win, int &y, int &x)
252  {
253  getparyx(win, y, x);
254  }
255 
256  inline void _getbegyx(WINDOW *win, int &y, int &x)
257  {
258  getbegyx(win, y, x);
259  }
260 
261  inline void _getmaxyx(WINDOW *win, int &y, int &x)
262  {
263  getmaxyx(win, y, x);
264  }
265 
266  inline int _getmaxy(WINDOW *win)
267  {
268  return getmaxy(win);
269  }
270 
271  inline int _getmaxx(WINDOW *win)
272  {
273  return getmaxx(win);
274  }
275 
276  inline int _touchwin(WINDOW *win)
277  {
278  return touchwin(win);
279  }
280 
281  inline int _untouchwin(WINDOW *win)
282  {
283  return untouchwin(win);
284  }
285 
286 #undef getbkgd
287 #undef box
288 
289 #undef getyx
290 #undef getparyx
291 #undef getbegyx
292 #undef getmaxyx
293 #undef getmaxy
294 #undef getmaxx
295 
296 #undef addch
297 #undef addchnstr
298 #undef addchstr
299 #undef add_wch
300 #undef addnstr
301 #undef addstr
302 #undef attroff
303 #undef attron
304 #undef attrset
305 #undef attr_set
306 #undef bkgd
307 #undef bkgdset
308 #undef clear
309 #undef clrtobot
310 #undef clrtoeol
311 #undef delch
312 #undef deleteln
313 #undef echochar
314 #undef erase
315 #undef getch
316 #undef get_wch
317 #undef getstr
318 #undef inch
319 #undef inchnstr
320 #undef innstr
321 #undef insch
322 #undef insdelln
323 #undef insertln
324 #undef insnstr
325 #undef insstr
326 #undef instr
327 #undef move
328 #undef refresh
329 #undef scrl
330 #undef scroll
331 #undef setscrreg
332 #undef standend
333 #undef standout
334 #undef timeout
335 
336 #undef mvaddch
337 #undef mvadd_wch
338 #undef mvaddchnstr
339 #undef mvaddchstr
340 #undef mvaddnstr
341 #undef mvaddstr
342 #undef mvdelch
343 #undef mvgetch
344 #undef mvget_wch
345 #undef mvgetnstr
346 #undef mvgetstr
347 #undef mvhline
348 #undef mvinch
349 #undef mvinchnstr
350 #undef mvinchstr
351 #undef mvinnstr
352 #undef mvinsch
353 #undef mvinsnstr
354 #undef mvinsstr
355 #undef mvinstr
356 #undef mvvline
357 
358 #undef border
359 #undef hline
360 #undef vline
361 
362 #undef touchline
363 
364  // The following class encapsulates a CURSES window, mostly with inlined
365  // versions of w* and mvw*. subwin and newwin are encapsulated with
366  // constructors; casting to WINDOW * is also supported.
367  //
368  // er, these will be inlined. Right?
369  class cwindow
370  {
371  // Blech. Used to memory-manage WINDOW *s
372  class cwindow_master
373  {
374  WINDOW *win;
375  int refs;
376  cwindow_master *parent;
377 
378  friend class cwindow;
379 
380  ~cwindow_master()
381  {
382  eassert(refs==0);
383 
384  if(win)
385  delwin(win);
386  if(parent)
387  parent->deref();
388  }
389  public:
390  cwindow_master(WINDOW *_win, cwindow_master *_parent)
391  :win(_win), refs(0), parent(_parent)
392  {
393  if(parent)
394  parent->ref();
395  }
396 
397  inline void ref()
398  {
399  refs++;
400  }
401 
402  // ??????
403  inline void deref()
404  {
405  refs--;
406 
407  if(refs==0)
408  delete this;
409  }
410  };
411 
412  WINDOW *win;
413  // The actual curses window
414 
415  cwindow_master *master;
416  // Keeps track of where we got this from (so we can deref() it later)
417 
418  cwindow(WINDOW *_win, cwindow_master *_master)
419  :win(_win), master(_master)
420  {
421  master->ref();
422  }
423  public:
424  cwindow(WINDOW *_win):win(_win), master(new cwindow_master(_win, NULL))
425  {
426  master->ref();
427  }
428  cwindow(const cwindow &a):win(a.win), master(a.master)
429  {
430  master->ref();
431  }
432 
433  ~cwindow()
434  {
435  master->deref();
436  }
437 
438  cwindow derwin(int h, int w, int y, int x)
439  {
440  WINDOW *new_win=::derwin(win, h, w, y, x);
441  return cwindow(new_win, new cwindow_master(new_win, master));
442  }
443 
444  int mvwin(int y, int x) {return ::mvwin(win, y, x);}
445 
446  void syncup() {wsyncup(win);}
447  int syncok(bool bf) {return ::syncok(win, bf);}
448  void cursyncup() {wcursyncup(win);}
449  void syncdown() {wsyncdown(win);}
450 
451  int scroll(int n=1) {return wscrl(win, n);}
452  // Does both scroll() and wscsrl()
453 
454  int addch(chtype ch) {return waddch(win, ch);}
455  int mvaddch(int y, int x, chtype ch) {return mvwaddch(win, y, x, ch);}
456 
457  int add_wch(wchar_t wch)
458  {
459  wchar_t tmp[2];
460  tmp[0]=wch;
461  tmp[1]=0;
462 
463  cchar_t cch;
464  if(setcchar(&cch, tmp, 0, 0, 0)==ERR)
465  return ERR;
466  else
467  return wadd_wch(win, &cch);
468  }
469 
470  int mvadd_wch(int y, int x, wchar_t wch)
471  {
472  move(y, x);
473  return add_wch(wch);
474  }
475 
476  int add_wch(const cchar_t *cch)
477  {
478  return wadd_wch(win, cch);
479  }
480 
481  int mvadd_wch(int y, int x, const cchar_t *cch)
482  {
483  return mvwadd_wch(win, y, x, cch);
484  }
485 
486  int addstr(const std::wstring &str) {return addstr(str.c_str());}
487  int addnstr(const std::wstring &str, int n) {return addnstr(str.c_str(), n);}
488  int mvaddstr(int y, int x, const std::wstring &str) {return mvaddstr(y, x, str.c_str());}
489  int mvaddnstr(int y, int x, const std::wstring &str, int n) {return mvaddnstr(y, x, str.c_str(), n);}
490 
491  int addstr(const wchar_t *str) {return waddwstr(win, str);}
492  int addnstr(const wchar_t *str, int n) {return waddnwstr(win, str, n);}
493  int mvaddstr(int y, int x, const wchar_t *str) {return mvwaddwstr(win, y, x, str);}
494  int mvaddnstr(int y, int x, const wchar_t *str, int n) {return mvwaddnwstr(win, y, x, str, n);}
495 
496  int addstr(const char *str) {return waddstr(win, str);}
497  int addnstr(const char *str, int n) {return waddnstr(win, str, n);}
498  int mvaddstr(int y, int x, const char *str) {return mvwaddstr(win, y, x, str);}
499  int mvaddnstr(int y, int x, const char *str, int n) {return mvwaddnstr(win, y, x, str, n);}
500 
501  // The following are implemented hackily due to the weirdness of
502  // curses. NB: they don't work with characters of negative width.
503  int addstr(const wchstring &str);
504  int addnstr(const wchstring &str, size_t n);
505  int mvaddstr(int y, int x, const wchstring &str);
506  int mvaddnstr(int y, int x, const wchstring &str, size_t n);
507 
508  int addstr(const chstring &str) {return waddchstr(win, str.c_str());}
509  int addnstr(const chstring &str, int n) {return waddchnstr(win, str.c_str(), n);}
510  int mvaddstr(int y, int x, const chstring &str) {return mvwaddchstr(win, y, x, str.c_str());}
511  int mvaddnstr(int y, int x, const chstring &str, int n) {return mvwaddchnstr(win, y, x, str.c_str(), n);}
512 
513  int attroff(int attrs) {return wattroff(win, attrs);}
514  int attron(int attrs) {return wattron(win, attrs);}
515  int attrset(int attrs) {return wattrset(win, attrs);}
516  // int attr_set(int attrs, void *opts) {return wattr_set(win, attrs, opts);}
517 
518  void bkgdset(const chtype ch) {wbkgdset(win, ch);}
519  int bkgd(const chtype ch) {return wbkgd(win, ch);}
520  chtype getbkgd() {return _getbkgd(win);}
521 
522  int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br)
523  {return wborder(win, ls, rs, ts, bs, tl, tr, bl, br);}
524 
525  int box(chtype verch, chtype horch) {return _box(win, verch, horch);}
526  int hline(chtype ch, int n) {return whline(win, ch, n);}
527  int vline(chtype ch, int n) {return wvline(win, ch, n);}
528  int mvhline(int y, int x, chtype ch, int n) {return mvwhline(win, y, x, ch, n);}
529  int mvvline(int y, int x, chtype ch, int n) {return mvwvline(win, y, x, ch, n);}
530 
531  int delch() {return wdelch(win);}
532  int mvdelch(int y, int x) {return mvwdelch(win, y, x);}
533 
534  int deleteln() {return wdeleteln(win);}
535  int insdelln(int n) {return winsdelln(win,n);}
536  int insertln() {return winsertln(win);}
537 
538  int echochar(chtype ch) {return wechochar(win, ch);}
539 
540  int getch() {return wgetch(win);}
541  int mvgetch(int y, int x) {return mvwgetch(win, y, x);}
542 
543  int get_wch(wint_t *wch) {return wget_wch(win, wch);}
544  int mvget_wch(int y, int x, wint_t *wch) {return mvwget_wch(win, y, x, wch);}
545 
546  int move(int y, int x) {return wmove(win, y, x);}
547  void getyx(int &y, int &x) {_getyx(win, y, x);}
548  void getparyx(int &y, int &x) {_getparyx(win, y, x);}
549  void getbegyx(int &y, int &x) {_getbegyx(win, y, x);}
550  void getmaxyx(int &y, int &x) {_getmaxyx(win, y, x);}
551  int getmaxy() {return _getmaxy(win);}
552  int getmaxx() {return _getmaxx(win);}
553 
554  void show_string_as_progbar(int x, int y, const std::wstring &s,
555  int attr1, int attr2, int size1,
556  int totalsize);
557  // Glitz bit :) Displays the given string with a progress bar behind it.
558 
559  void display_header(std::wstring s, const attr_t attr);
560  void display_status(std::wstring s, const attr_t attr);
561  // Make it easier to write interfaces that have a header and status line..
562  // they do what they say :)
563 
564  int overlay(cwindow &dstwin) {return ::overlay(win, dstwin.win);}
565  int overwrite(cwindow &dstwin) {return ::overwrite(win, dstwin.win);}
566  int copywin(cwindow &dstwin, int sminrow, int smincol, int dminrow, int dmincol, int dmaxrow, int dmaxcol, int overlay)
567  {return ::copywin(win, dstwin.win, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, overlay);}
568 
569  int refresh() {return wrefresh(win);}
570  int noutrefresh() {return wnoutrefresh(win);}
571 
572  int touch() {return _touchwin(win);}
573  int untouch() {return _untouchwin(win);}
574  int touchln(int y, int n, int changed) {return ::wtouchln(win, y, n, changed);}
575  int touchline(int start, int count) {return touchln(start, count, 1);}
576  int untouchline(int start, int count) {return touchln(start, count, 0);}
577 
578  int erase() {return werase(win);}
579  int clear() {return wclear(win);}
580  int clrtobot() {return wclrtobot(win);}
581  int clrtoeol() {return wclrtoeol(win);}
582 
583  int keypad(bool bf) {return ::keypad(win,bf);}
584  int meta(bool bf) {return ::meta(win,bf);}
585  int nodelay(bool bf) {return ::nodelay(win, bf);}
586  int notimeout(bool bf) {return ::notimeout(win, bf);}
587  void timeout(int delay) {wtimeout(win, delay);}
588 
589  int clearok(bool bf) {return ::clearok(win, bf);}
590  int idlok(bool bf) {return ::idlok(win, bf);}
591  void idcok(bool bf) {::idcok(win, bf);}
592  void immedok(bool bf) {::immedok(win, bf);}
593 #if defined(NCURSES_VERSION_MAJOR) && NCURSES_VERSION_MAJOR>=5
594  int leaveok(bool bf) {int rval=::leaveok(win, bf); curs_set(bf?0:1); return rval;}
595 #else
596  int leaveok(bool bf) {return ::leaveok(win, bf);}
597 #endif
598  int setscrreg(int top, int bot) {return wsetscrreg(win, top, bot);}
599  int scrollok(bool bf) {return ::scrollok(win,bf);}
600 
601  int printw(char *str, ...);
602  /* You guessed it.. :) */
603 
604  bool enclose(int y, int x) {return wenclose(win, y, x);}
605 
606  WINDOW *getwin() {return win;}
607  operator bool () {return win!=NULL;}
608  cwindow &operator =(const cwindow &a)
609  {
610  cwindow_master *newmaster=a.master;
611  newmaster->ref();
612 
613  master->deref();
614  master=newmaster;
615  win=a.win;
616  return *this;
617  }
618  bool operator ==(cwindow &other) {return win==other.win;}
619  bool operator !=(cwindow &other) {return win!=other.win;}
620 
621  static void remove_cruft();
622  };
623 
624  extern cwindow rootwin;
625  // This is stdscr, but calling it 'stdscr' would confuse the compiler, so I'm
626  // confusing the programmer instead :)
627 
628  void init_curses();
629  // Initializes curses and sets rootwin to the correct value
630 
631  void resize();
632  // Called when a terminal resize is detected.
633 }
634 
635 #endif
A "style" is a setting to be applied to a display element (widget, text, etc).
Definition: style.h:51
Definition: curses++.h:199
Definition: curses++.h:102
The namespace containing everything defined by cwidget.
Definition: columnify.cc:26
A structure that amalgamates a wchar_t together with attributes.
Definition: curses++.h:47
wchar_t ch
The character value associated with this string.
Definition: curses++.h:54
attr_t attrs
The text attributes (including color) associated with this character.
Definition: curses++.h:59
Definition: curses++.h:369
A string class which stores attributes along with characters.
Definition: curses++.h:170