cwidget
0.5.16
|
00001 // curses++.h (this is -*-c++-*-) 00002 // 00003 // Copyright 1999-2005, 2007 Daniel Burrows 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 2 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; see the file COPYING. If not, write to 00017 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 // Boston, MA 02111-1307, USA. 00019 // 00020 // Simple class wrappers around various CURSES functions. 00021 00022 #ifndef CURSES_PLUSPLUS_H 00023 #define CURSES_PLUSPLUS_H 00024 00025 #include <string> 00026 #include <ncursesw/curses.h> 00027 00028 #include <cwidget/generic/util/eassert.h> 00029 00030 // For isspace 00031 #include <ctype.h> 00032 00033 #include <string.h> 00034 00035 #include <cwidget-config.h> 00036 00037 namespace cwidget 00038 { 00047 struct wchtype 00048 { 00054 wchar_t ch; 00055 00059 attr_t attrs; 00060 00061 wchtype() 00062 { 00063 } 00064 00065 wchtype(const wchar_t &_ch, const attr_t &_attrs) 00066 :ch(_ch), attrs(_attrs) 00067 { 00068 } 00069 00070 bool operator==(const wchtype &other) const 00071 { 00072 return ch==other.ch && attrs==other.attrs; 00073 } 00074 00075 bool operator!=(const wchtype &other) const 00076 { 00077 return ch!=other.ch || attrs!=other.attrs; 00078 } 00079 00080 bool operator<(const wchtype &other) const 00081 { 00082 return ch<other.ch || (ch==other.ch && attrs<other.attrs); 00083 } 00084 00085 bool operator<=(const wchtype &other) const 00086 { 00087 return (*this) == other || (*this) < other; 00088 } 00089 00090 bool operator>(const wchtype &other) const 00091 { 00092 return !((*this)<=other); 00093 } 00094 00095 bool operator>=(const wchtype &other) const 00096 { 00097 return !((*this)<other); 00098 } 00099 }; 00100 } 00101 00102 namespace std { 00103 template <> 00113 struct TRAITS_CLASS<chtype> { 00114 typedef chtype char_type; 00115 00116 static void assign (char_type& c1, const char_type& c2) 00117 { c1 = c2; } 00118 static bool eq (const char_type & c1, const char_type& c2) 00119 { return (c1 == c2); } 00120 static bool ne (const char_type& c1, const char_type& c2) 00121 { return (c1 != c2); } 00122 static bool lt (const char_type& c1, const char_type& c2) 00123 { return (c1 < c2); } 00124 static char_type eos () { return 0; } 00125 static bool is_del(char_type a) { return isspace(a|A_CHARTEXT); } 00126 00127 static int compare (const char_type* s1, const char_type* s2, size_t n); 00128 static size_t length (const char_type* s); 00129 static char_type* copy (char_type* s1, const char_type* s2, size_t n) 00130 { return (char_type*) memcpy (s1, s2, n*sizeof(char_type)); } 00131 static char_type* move (char_type* s1, const char_type* s2, size_t n) 00132 { return (char_type*) memmove (s1, s2, n*sizeof(char_type)); } 00133 static char_type* assign (char_type* s1, size_t n, const char_type& c); 00134 }; 00135 00136 template <> 00137 struct TRAITS_CLASS<cwidget::wchtype> { 00138 typedef cwidget::wchtype char_type; 00139 00140 static void assign (char_type& c1, const char_type& c2) 00141 { c1 = c2; } 00142 static bool eq (const char_type & c1, const char_type& c2) 00143 { return (c1 == c2); } 00144 static bool ne (const char_type& c1, const char_type& c2) 00145 { return (c1 != c2); } 00146 static bool lt (const char_type& c1, const char_type& c2) 00147 { return (c1 < c2); } 00148 static char_type eos () { return cwidget::wchtype(0,0); } 00149 static bool is_del(char_type a) { return isspace(a.ch); } 00150 00151 static int compare (const char_type* s1, const char_type* s2, size_t n); 00152 static size_t length (const char_type* s); 00153 static char_type* copy (char_type* s1, const char_type* s2, size_t n) 00154 { return (char_type*) memcpy (s1, s2, n*sizeof(char_type)); } 00155 static char_type* move (char_type* s1, const char_type* s2, size_t n) 00156 { return (char_type*) memmove (s1, s2, n*sizeof(char_type)); } 00157 static char_type* assign (char_type* s1, size_t n, const char_type& c); 00158 }; 00159 } 00160 00161 namespace cwidget 00162 { 00163 class style; 00164 00170 class chstring:public std::basic_string<chtype> 00171 { 00172 typedef std::basic_string<chtype> super; 00173 public: 00174 chstring(const std::basic_string<chtype> &s) 00175 :std::basic_string<chtype>(s) {} 00176 00177 chstring(const std::string &s); 00178 chstring(const std::string &s, const style &st); 00179 00180 chstring(const chstring &s):super(s) {} 00184 chstring(const chstring &s, const style &st); 00185 00186 chstring(const chstring &s, size_t loc, size_t n=npos) 00187 :super(s, loc, n) {} 00188 00189 chstring(size_t n, chtype c) 00190 :super(n, c) {} 00191 00193 chstring &operator=(const std::string &s); 00194 00196 void apply_style(const style &st); 00197 }; 00198 00199 class wchstring:public std::basic_string<wchtype> 00200 { 00201 typedef std::basic_string<wchtype> super; 00202 public: 00203 wchstring(const std::basic_string<wchtype> &s) 00204 :std::basic_string<wchtype>(s) {} 00205 00207 wchstring(const std::wstring &s); 00208 00212 wchstring(const std::wstring &s, const style &st); 00213 00214 wchstring(const wchstring &s):super(s) {} 00218 wchstring(const wchstring &s, const style &st); 00219 00220 wchstring(const wchstring &s, size_t loc, size_t n=npos) 00221 :super(s, loc, n) {} 00222 00223 wchstring(size_t n, wchtype c) 00224 :super(n, c) {} 00225 00226 wchstring(size_t n, wchar_t c, attr_t a) 00227 :super(n, wchtype(c, a)) {} 00228 00230 void apply_style(const style &st); 00231 00233 int width() const; 00234 }; 00235 00236 inline chtype _getbkgd(WINDOW *win) 00237 { 00238 return getbkgd(win); 00239 } 00240 00241 inline int _box(WINDOW *win, chtype verch, chtype horch) 00242 { 00243 return box(win, verch, horch); 00244 } 00245 00246 inline void _getyx(WINDOW *win, int &y, int &x) 00247 { 00248 getyx(win, y, x); 00249 } 00250 00251 inline void _getparyx(WINDOW *win, int &y, int &x) 00252 { 00253 getparyx(win, y, x); 00254 } 00255 00256 inline void _getbegyx(WINDOW *win, int &y, int &x) 00257 { 00258 getbegyx(win, y, x); 00259 } 00260 00261 inline void _getmaxyx(WINDOW *win, int &y, int &x) 00262 { 00263 getmaxyx(win, y, x); 00264 } 00265 00266 inline int _getmaxy(WINDOW *win) 00267 { 00268 return getmaxy(win); 00269 } 00270 00271 inline int _getmaxx(WINDOW *win) 00272 { 00273 return getmaxx(win); 00274 } 00275 00276 inline int _touchwin(WINDOW *win) 00277 { 00278 return touchwin(win); 00279 } 00280 00281 inline int _untouchwin(WINDOW *win) 00282 { 00283 return untouchwin(win); 00284 } 00285 00286 #undef getbkgd 00287 #undef box 00288 00289 #undef getyx 00290 #undef getparyx 00291 #undef getbegyx 00292 #undef getmaxyx 00293 #undef getmaxy 00294 #undef getmaxx 00295 00296 #undef addch 00297 #undef addchnstr 00298 #undef addchstr 00299 #undef add_wch 00300 #undef addnstr 00301 #undef addstr 00302 #undef attroff 00303 #undef attron 00304 #undef attrset 00305 #undef attr_set 00306 #undef bkgd 00307 #undef bkgdset 00308 #undef clear 00309 #undef clrtobot 00310 #undef clrtoeol 00311 #undef delch 00312 #undef deleteln 00313 #undef echochar 00314 #undef erase 00315 #undef getch 00316 #undef get_wch 00317 #undef getstr 00318 #undef inch 00319 #undef inchnstr 00320 #undef innstr 00321 #undef insch 00322 #undef insdelln 00323 #undef insertln 00324 #undef insnstr 00325 #undef insstr 00326 #undef instr 00327 #undef move 00328 #undef refresh 00329 #undef scrl 00330 #undef scroll 00331 #undef setscrreg 00332 #undef standend 00333 #undef standout 00334 #undef timeout 00335 00336 #undef mvaddch 00337 #undef mvadd_wch 00338 #undef mvaddchnstr 00339 #undef mvaddchstr 00340 #undef mvaddnstr 00341 #undef mvaddstr 00342 #undef mvdelch 00343 #undef mvgetch 00344 #undef mvget_wch 00345 #undef mvgetnstr 00346 #undef mvgetstr 00347 #undef mvhline 00348 #undef mvinch 00349 #undef mvinchnstr 00350 #undef mvinchstr 00351 #undef mvinnstr 00352 #undef mvinsch 00353 #undef mvinsnstr 00354 #undef mvinsstr 00355 #undef mvinstr 00356 #undef mvvline 00357 00358 #undef border 00359 #undef hline 00360 #undef vline 00361 00362 #undef touchline 00363 00364 // The following class encapsulates a CURSES window, mostly with inlined 00365 // versions of w* and mvw*. subwin and newwin are encapsulated with 00366 // constructors; casting to WINDOW * is also supported. 00367 // 00368 // er, these will be inlined. Right? 00369 class cwindow 00370 { 00371 // Blech. Used to memory-manage WINDOW *s 00372 class cwindow_master 00373 { 00374 WINDOW *win; 00375 int refs; 00376 cwindow_master *parent; 00377 00378 friend class cwindow; 00379 00380 ~cwindow_master() 00381 { 00382 eassert(refs==0); 00383 00384 if(win) 00385 delwin(win); 00386 if(parent) 00387 parent->deref(); 00388 } 00389 public: 00390 cwindow_master(WINDOW *_win, cwindow_master *_parent) 00391 :win(_win), refs(0), parent(_parent) 00392 { 00393 if(parent) 00394 parent->ref(); 00395 } 00396 00397 inline void ref() 00398 { 00399 refs++; 00400 } 00401 00402 // ?????? 00403 inline void deref() 00404 { 00405 refs--; 00406 00407 if(refs==0) 00408 delete this; 00409 } 00410 }; 00411 00412 WINDOW *win; 00413 // The actual curses window 00414 00415 cwindow_master *master; 00416 // Keeps track of where we got this from (so we can deref() it later) 00417 00418 cwindow(WINDOW *_win, cwindow_master *_master) 00419 :win(_win), master(_master) 00420 { 00421 master->ref(); 00422 } 00423 public: 00424 cwindow(WINDOW *_win):win(_win), master(new cwindow_master(_win, NULL)) 00425 { 00426 master->ref(); 00427 } 00428 cwindow(const cwindow &a):win(a.win), master(a.master) 00429 { 00430 master->ref(); 00431 } 00432 00433 ~cwindow() 00434 { 00435 master->deref(); 00436 } 00437 00438 cwindow derwin(int h, int w, int y, int x) 00439 { 00440 WINDOW *new_win=::derwin(win, h, w, y, x); 00441 return cwindow(new_win, new cwindow_master(new_win, master)); 00442 } 00443 00444 int mvwin(int y, int x) {return ::mvwin(win, y, x);} 00445 00446 void syncup() {wsyncup(win);} 00447 int syncok(bool bf) {return ::syncok(win, bf);} 00448 void cursyncup() {wcursyncup(win);} 00449 void syncdown() {wsyncdown(win);} 00450 00451 int scroll(int n=1) {return wscrl(win, n);} 00452 // Does both scroll() and wscsrl() 00453 00454 int addch(chtype ch) {return waddch(win, ch);} 00455 int mvaddch(int y, int x, chtype ch) {return mvwaddch(win, y, x, ch);} 00456 00457 int add_wch(wchar_t wch) 00458 { 00459 wchar_t tmp[2]; 00460 tmp[0]=wch; 00461 tmp[1]=0; 00462 00463 cchar_t cch; 00464 if(setcchar(&cch, tmp, 0, 0, 0)==ERR) 00465 return ERR; 00466 else 00467 return wadd_wch(win, &cch); 00468 } 00469 00470 int mvadd_wch(int y, int x, wchar_t wch) 00471 { 00472 move(y, x); 00473 return add_wch(wch); 00474 } 00475 00476 int add_wch(const cchar_t *cch) 00477 { 00478 return wadd_wch(win, cch); 00479 } 00480 00481 int mvadd_wch(int y, int x, const cchar_t *cch) 00482 { 00483 return mvwadd_wch(win, y, x, cch); 00484 } 00485 00486 int addstr(const std::wstring &str) {return addstr(str.c_str());} 00487 int addnstr(const std::wstring &str, int n) {return addnstr(str.c_str(), n);} 00488 int mvaddstr(int y, int x, const std::wstring &str) {return mvaddstr(y, x, str.c_str());} 00489 int mvaddnstr(int y, int x, const std::wstring &str, int n) {return mvaddnstr(y, x, str.c_str(), n);} 00490 00491 int addstr(const wchar_t *str) {return waddwstr(win, str);} 00492 int addnstr(const wchar_t *str, int n) {return waddnwstr(win, str, n);} 00493 int mvaddstr(int y, int x, const wchar_t *str) {return mvwaddwstr(win, y, x, str);} 00494 int mvaddnstr(int y, int x, const wchar_t *str, int n) {return mvwaddnwstr(win, y, x, str, n);} 00495 00496 int addstr(const char *str) {return waddstr(win, str);} 00497 int addnstr(const char *str, int n) {return waddnstr(win, str, n);} 00498 int mvaddstr(int y, int x, const char *str) {return mvwaddstr(win, y, x, str);} 00499 int mvaddnstr(int y, int x, const char *str, int n) {return mvwaddnstr(win, y, x, str, n);} 00500 00501 // The following are implemented hackily due to the weirdness of 00502 // curses. NB: they don't work with characters of negative width. 00503 int addstr(const wchstring &str); 00504 int addnstr(const wchstring &str, size_t n); 00505 int mvaddstr(int y, int x, const wchstring &str); 00506 int mvaddnstr(int y, int x, const wchstring &str, size_t n); 00507 00508 int addstr(const chstring &str) {return waddchstr(win, str.c_str());} 00509 int addnstr(const chstring &str, int n) {return waddchnstr(win, str.c_str(), n);} 00510 int mvaddstr(int y, int x, const chstring &str) {return mvwaddchstr(win, y, x, str.c_str());} 00511 int mvaddnstr(int y, int x, const chstring &str, int n) {return mvwaddchnstr(win, y, x, str.c_str(), n);} 00512 00513 int attroff(int attrs) {return wattroff(win, attrs);} 00514 int attron(int attrs) {return wattron(win, attrs);} 00515 int attrset(int attrs) {return wattrset(win, attrs);} 00516 // int attr_set(int attrs, void *opts) {return wattr_set(win, attrs, opts);} 00517 00518 void bkgdset(const chtype ch) {wbkgdset(win, ch);} 00519 int bkgd(const chtype ch) {return wbkgd(win, ch);} 00520 chtype getbkgd() {return _getbkgd(win);} 00521 00522 int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br) 00523 {return wborder(win, ls, rs, ts, bs, tl, tr, bl, br);} 00524 00525 int box(chtype verch, chtype horch) {return _box(win, verch, horch);} 00526 int hline(chtype ch, int n) {return whline(win, ch, n);} 00527 int vline(chtype ch, int n) {return wvline(win, ch, n);} 00528 int mvhline(int y, int x, chtype ch, int n) {return mvwhline(win, y, x, ch, n);} 00529 int mvvline(int y, int x, chtype ch, int n) {return mvwvline(win, y, x, ch, n);} 00530 00531 int delch() {return wdelch(win);} 00532 int mvdelch(int y, int x) {return mvwdelch(win, y, x);} 00533 00534 int deleteln() {return wdeleteln(win);} 00535 int insdelln(int n) {return winsdelln(win,n);} 00536 int insertln() {return winsertln(win);} 00537 00538 int echochar(chtype ch) {return wechochar(win, ch);} 00539 00540 int getch() {return wgetch(win);} 00541 int mvgetch(int y, int x) {return mvwgetch(win, y, x);} 00542 00543 int get_wch(wint_t *wch) {return wget_wch(win, wch);} 00544 int mvget_wch(int y, int x, wint_t *wch) {return mvwget_wch(win, y, x, wch);} 00545 00546 int move(int y, int x) {return wmove(win, y, x);} 00547 void getyx(int &y, int &x) {_getyx(win, y, x);} 00548 void getparyx(int &y, int &x) {_getparyx(win, y, x);} 00549 void getbegyx(int &y, int &x) {_getbegyx(win, y, x);} 00550 void getmaxyx(int &y, int &x) {_getmaxyx(win, y, x);} 00551 int getmaxy() {return _getmaxy(win);} 00552 int getmaxx() {return _getmaxx(win);} 00553 00554 void show_string_as_progbar(int x, int y, const std::wstring &s, 00555 int attr1, int attr2, int size1, 00556 int totalsize); 00557 // Glitz bit :) Displays the given string with a progress bar behind it. 00558 00559 void display_header(std::wstring s, const attr_t attr); 00560 void display_status(std::wstring s, const attr_t attr); 00561 // Make it easier to write interfaces that have a header and status line.. 00562 // they do what they say :) 00563 00564 int overlay(cwindow &dstwin) {return ::overlay(win, dstwin.win);} 00565 int overwrite(cwindow &dstwin) {return ::overwrite(win, dstwin.win);} 00566 int copywin(cwindow &dstwin, int sminrow, int smincol, int dminrow, int dmincol, int dmaxrow, int dmaxcol, int overlay) 00567 {return ::copywin(win, dstwin.win, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, overlay);} 00568 00569 int refresh() {return wrefresh(win);} 00570 int noutrefresh() {return wnoutrefresh(win);} 00571 00572 int touch() {return _touchwin(win);} 00573 int untouch() {return _untouchwin(win);} 00574 int touchln(int y, int n, int changed) {return ::wtouchln(win, y, n, changed);} 00575 int touchline(int start, int count) {return touchln(start, count, 1);} 00576 int untouchline(int start, int count) {return touchln(start, count, 0);} 00577 00578 int erase() {return werase(win);} 00579 int clear() {return wclear(win);} 00580 int clrtobot() {return wclrtobot(win);} 00581 int clrtoeol() {return wclrtoeol(win);} 00582 00583 int keypad(bool bf) {return ::keypad(win,bf);} 00584 int meta(bool bf) {return ::meta(win,bf);} 00585 int nodelay(bool bf) {return ::nodelay(win, bf);} 00586 int notimeout(bool bf) {return ::notimeout(win, bf);} 00587 void timeout(int delay) {wtimeout(win, delay);} 00588 00589 int clearok(bool bf) {return ::clearok(win, bf);} 00590 int idlok(bool bf) {return ::idlok(win, bf);} 00591 void idcok(bool bf) {::idcok(win, bf);} 00592 void immedok(bool bf) {::immedok(win, bf);} 00593 #if defined(NCURSES_VERSION_MAJOR) && NCURSES_VERSION_MAJOR>=5 00594 int leaveok(bool bf) {int rval=::leaveok(win, bf); curs_set(bf?0:1); return rval;} 00595 #else 00596 int leaveok(bool bf) {return ::leaveok(win, bf);} 00597 #endif 00598 int setscrreg(int top, int bot) {return wsetscrreg(win, top, bot);} 00599 int scrollok(bool bf) {return ::scrollok(win,bf);} 00600 00601 int printw(char *str, ...); 00602 /* You guessed it.. :) */ 00603 00604 bool enclose(int y, int x) {return wenclose(win, y, x);} 00605 00606 WINDOW *getwin() {return win;} 00607 operator bool () {return win!=NULL;} 00608 cwindow &operator =(const cwindow &a) 00609 { 00610 cwindow_master *newmaster=a.master; 00611 newmaster->ref(); 00612 00613 master->deref(); 00614 master=newmaster; 00615 win=a.win; 00616 return *this; 00617 } 00618 bool operator ==(cwindow &other) {return win==other.win;} 00619 bool operator !=(cwindow &other) {return win!=other.win;} 00620 00621 static void remove_cruft(); 00622 }; 00623 00624 extern cwindow rootwin; 00625 // This is stdscr, but calling it 'stdscr' would confuse the compiler, so I'm 00626 // confusing the programmer instead :) 00627 00628 void init_curses(); 00629 // Initializes curses and sets rootwin to the correct value 00630 00631 void resize(); 00632 // Called when a terminal resize is detected. 00633 } 00634 00635 #endif