1// * This makes emacs happy -*-Mode: C++;-*- 2/**************************************************************************** 3 * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * 4 * * 5 * Permission is hereby granted, free of charge, to any person obtaining a * 6 * copy of this software and associated documentation files (the * 7 * "Software"), to deal in the Software without restriction, including * 8 * without limitation the rights to use, copy, modify, merge, publish, * 9 * distribute, distribute with modifications, sublicense, and/or sell * 10 * copies of the Software, and to permit persons to whom the Software is * 11 * furnished to do so, subject to the following conditions: * 12 * * 13 * The above copyright notice and this permission notice shall be included * 14 * in all copies or substantial portions of the Software. * 15 * * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 19 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 23 * * 24 * Except as contained in this notice, the name(s) of the above copyright * 25 * holders shall not be used in advertising or otherwise to promote the * 26 * sale, use or other dealings in this Software without prior written * 27 * authorization. * 28 ****************************************************************************/ 29 30/* 31 * Silly demo program for the NCursesPanel class. 32 * 33 * written by Anatoly Ivasyuk (anatoly@nick.csh.rit.edu) 34 * 35 * Demo code for NCursesMenu and NCursesForm written by 36 * Juergen Pfeifer 37 * 38 * $Id: demo.cc,v 1.38 2008/08/04 17:16:57 tom Exp $ 39 */ 40 41#include "internal.h" 42#include "cursesapp.h" 43#include "cursesm.h" 44#include "cursesf.h" 45 46extern "C" unsigned int sleep(unsigned int); 47 48#undef index // needed for NeXT 49 50// 51// ------------------------------------------------------------------------- 52// 53class SillyDemo 54{ 55 public: 56 void run(int sleeptime) { 57 58 NCursesPanel *mystd = new NCursesPanel(); 59 60 // Make a few small demo panels 61 62 NCursesPanel *u = new NCursesPanel(8, 20, 12, 4); 63 NCursesPanel *v = new NCursesPanel(8, 20, 10, 6); 64 NCursesPanel *w = new NCursesPanel(8, 20, 8, 8); 65 NCursesPanel *x = new NCursesPanel(8, 20, 6, 10); 66 NCursesPanel *y = new NCursesPanel(8, 20, 4, 12); 67 NCursesPanel *z = new NCursesPanel(8, 30, 2, 14); 68 69 // Draw something on the main screen, so we can see what happens 70 // when panels get moved or deleted. 71 72 mystd->box(); 73 mystd->move(mystd->height()/2, 1); 74 mystd->hline(mystd->width()-2); 75 mystd->move(1, mystd->width()/2); 76 mystd->vline(mystd->height()-2); 77 mystd->addch(0, mystd->width()/2, ACS_TTEE); 78 mystd->addch(mystd->height()-1, mystd->width()/2, ACS_BTEE); 79 mystd->addch(mystd->height()/2, 0, ACS_LTEE); 80 mystd->addch(mystd->height()/2, mystd->width()-1, ACS_RTEE); 81 mystd->addch(mystd->height()/2, mystd->width()/2, ACS_PLUS); 82 83 // Draw frames with titles around panels so that we can see where 84 // the panels are located. 85 u->boldframe("Win U"); 86 v->frame("Win V"); 87 w->boldframe("Win W"); 88 x->frame("Win X"); 89 y->boldframe("Win Y"); 90 z->frame("Win Z"); 91 if (NCursesApplication::getApplication()->useColors()) { 92 u->bkgd(' '|COLOR_PAIR(1)); 93 w->bkgd(' '|COLOR_PAIR(1)); 94 y->bkgd(' '|COLOR_PAIR(1)); 95 v->bkgd(' '|COLOR_PAIR(2)); 96 x->bkgd(' '|COLOR_PAIR(2)); 97 z->bkgd(' '|COLOR_PAIR(2)); 98 } 99 100 // A refresh to any valid panel updates all panels and refreshes 101 // the screen. Using mystd is just convenient - We know it's always 102 // valid until the end of the program. 103 104 mystd->refresh(); 105 sleep(sleeptime); 106 107 // Show what happens when panels are deleted and moved. 108 109 sleep(sleeptime); 110 delete u; 111 mystd->refresh(); 112 113 sleep(sleeptime); 114 delete z; 115 mystd->refresh(); 116 117 sleep(sleeptime); 118 delete v; 119 mystd->refresh(); 120 121 // show how it looks when a panel moves 122 sleep(sleeptime); 123 y->mvwin(5, 30); 124 mystd->refresh(); 125 126 sleep(sleeptime); 127 delete y; 128 mystd->refresh(); 129 130 // show how it looks when you raise a panel 131 sleep(sleeptime); 132 w->top(); 133 mystd->refresh(); 134 135 sleep(sleeptime); 136 delete w; 137 mystd->refresh(); 138 139 sleep(sleeptime); 140 delete x; 141 142 mystd->clear(); 143 mystd->refresh(); 144 145 // Don't forget to clean up the main screen. Since this is the 146 // last thing using NCursesWindow, this has the effect of 147 // shutting down ncurses and restoring the terminal state. 148 149 sleep(sleeptime); 150 delete mystd; 151 } 152}; 153 154class UserData 155{ 156private: 157 int u; 158public: 159 UserData(int x) : u(x) {} 160 int sleeptime() const { return u; } 161}; 162// 163// ------------------------------------------------------------------------- 164// 165template<class T> class MyAction : public NCursesUserItem<T> 166{ 167public: 168 MyAction (const char* p_name, 169 const T* p_UserData) 170 : NCursesUserItem<T>(p_name, static_cast<const char*>(0), p_UserData) 171 {} 172 173 virtual ~MyAction() {} 174 175 bool action() { 176 SillyDemo a; 177 a.run(NCursesUserItem<T>::UserData()->sleeptime()); 178 return FALSE; 179 } 180}; 181 182template class MyAction<UserData>; 183template class NCURSES_IMPEXP NCursesUserItem<UserData>; 184 185class QuitItem : public NCursesMenuItem 186{ 187public: 188 QuitItem() : NCursesMenuItem("Quit") { 189 } 190 191 bool action() { 192 return TRUE; 193 } 194}; 195// 196// ------------------------------------------------------------------------- 197// 198class Label : public NCursesFormField 199{ 200public: 201 Label(const char* title, 202 int row, int col) 203 : NCursesFormField(1, static_cast<int>(::strlen(title)), row, col) { 204 set_value(title); 205 options_off(O_EDIT|O_ACTIVE); 206 } 207}; 208// 209// ------------------------------------------------------------------------- 210// 211class MyFieldType : public UserDefinedFieldType 212{ 213private: 214 int chk; 215protected: 216 bool field_check(NCursesFormField& f) { 217 return TRUE; 218 } 219 bool char_check(int c) { 220 return (c==chk?TRUE:FALSE); 221 } 222public: 223 MyFieldType(int x) : chk(x) { 224 } 225}; 226// 227// ------------------------------------------------------------------------- 228// 229class TestForm : public NCursesForm 230{ 231private: 232 NCursesFormField** F; 233 MyFieldType* mft; 234 Integer_Field *ift; 235 Enumeration_Field *eft; 236 237 static const char *weekdays[]; 238 239public: 240 TestForm() 241 : NCursesForm(13, 51, (lines() - 15)/2, (cols() - 53)/2), 242 F(0), 243 mft(0), 244 ift(0), 245 eft(0) 246 { 247 248 F = new NCursesFormField*[10]; 249 mft = new MyFieldType('X'); 250 ift = new Integer_Field(0, 1, 10); 251 eft = new Enumeration_Field(weekdays); 252 253 F[0] = new Label("Demo Entry Form", 0, 16); 254 F[1] = new Label("Weekday Enum", 2, 1); 255 F[2] = new Label("Number(1-10)", 2, 21); 256 F[3] = new Label("Only 'X'", 2, 35); 257 F[4] = new Label("Multiline Field (Dynamic and Scrollable)", 5, 1); 258 F[5] = new NCursesFormField(1, 18, 3, 1); 259 F[6] = new NCursesFormField(1, 12, 3, 21); 260 F[7] = new NCursesFormField(1, 12, 3, 35); 261 F[8] = new NCursesFormField(4, 46, 6, 1, 2); 262 F[9] = new NCursesFormField(); 263 264 InitForm(F, TRUE, TRUE); 265 boldframe(); 266 267 F[5]->set_fieldtype(*eft); 268 F[6]->set_fieldtype(*ift); 269 270 F[7]->set_fieldtype(*mft); 271 F[7]->set_maximum_growth(20); // max. 20 characters 272 F[7]->options_off(O_STATIC); // make field dynamic 273 274 F[8]->set_maximum_growth(10); // max. 10 lines 275 F[8]->options_off(O_STATIC); // make field dynamic 276 } 277 278 TestForm& operator=(const TestForm& rhs) 279 { 280 if (this != &rhs) { 281 *this = rhs; 282 } 283 return *this; 284 } 285 286 TestForm(const TestForm& rhs) 287 : NCursesForm(rhs), F(0), mft(0), ift(0), eft(0) 288 { 289 } 290 291 ~TestForm() { 292 delete mft; 293 delete ift; 294 delete eft; 295 } 296}; 297 298const char* TestForm::weekdays[] = { 299 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", 300 "Friday", "Saturday", NULL }; 301// 302// ------------------------------------------------------------------------- 303// 304class FormAction : public NCursesMenuItem 305{ 306public: 307 FormAction(const char *s) : NCursesMenuItem(s) { 308 } 309 310 bool action() { 311 TestForm F; 312 Soft_Label_Key_Set* S = new Soft_Label_Key_Set; 313 for(int i=1; i <= S->labels(); i++) { 314 char buf[8]; 315 assert(i < 100); 316 ::sprintf(buf, "Frm%02d", i); 317 (*S)[i] = buf; // Text 318 (*S)[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification 319 } 320 NCursesApplication::getApplication()->push(*S); 321 F(); 322 NCursesApplication::getApplication()->pop(); 323 delete S; 324 return FALSE; 325 } 326}; 327// 328// ------------------------------------------------------------------------- 329// 330class PadAction : public NCursesMenuItem 331{ 332public: 333 PadAction(const char* s) : NCursesMenuItem(s) { 334 } 335 336 bool action() { 337 const int GRIDSIZE = 3; 338 const int PADSIZE = 200; 339 unsigned gridcount = 0; 340 341 NCursesPanel mystd; 342 NCursesPanel P(mystd.lines()-2, mystd.cols()-2, 1, 1); 343 NCursesFramedPad FP(P, PADSIZE, PADSIZE); 344 345 for (int i=0; i < PADSIZE; i++) { 346 for (int j=0; j < PADSIZE; j++) { 347 if (i % GRIDSIZE == 0 && j % GRIDSIZE == 0) { 348 if (i==0 || j==0) 349 FP.addch('+'); 350 else 351 FP.addch(static_cast<chtype>('A' + (gridcount++ % 26))); 352 } 353 else if (i % GRIDSIZE == 0) 354 FP.addch('-'); 355 else if (j % GRIDSIZE == 0) 356 FP.addch('|'); 357 else 358 FP.addch(' '); 359 } 360 } 361 362 P.label("Pad Demo", NULL); 363 FP(); 364 P.clear(); 365 return FALSE; 366 } 367}; 368 369// 370// ------------------------------------------------------------------------- 371// 372class PassiveItem : public NCursesMenuItem 373{ 374public: 375 PassiveItem(const char* text) : NCursesMenuItem(text) { 376 options_off(O_SELECTABLE); 377 } 378}; 379 380// 381// ------------------------------------------------------------------------- 382// 383class ScanAction : public NCursesMenuItem 384{ 385public: 386 ScanAction(const char* s) : NCursesMenuItem(s) { 387 } 388 389 bool action() { 390 NCursesPanel *mystd = new NCursesPanel(); 391 392 NCursesPanel *w = new NCursesPanel(mystd->lines() - 2, mystd->cols() - 2, 1, 1); 393 w->box(); 394 w->refresh(); 395 396 NCursesPanel *s = new NCursesPanel(w->lines() - 6, w->cols() - 6, 3, 3); 397 s->scrollok(TRUE); 398 ::echo(); 399 400 s->printw("Enter decimal integers. The running total will be shown\n"); 401 int nvalue = -1; 402 int result = 0; 403 while (nvalue != 0) { 404 nvalue = 0; 405 s->scanw("%d", &nvalue); 406 if (nvalue != 0) { 407 s->printw("%d: ", result += nvalue); 408 } 409 s->refresh(); 410 } 411 s->printw("\nPress any key to continue..."); 412 s->getch(); 413 414 delete s; 415 delete w; 416 delete mystd; 417 ::noecho(); 418 return FALSE; 419 } 420}; 421 422// 423// ------------------------------------------------------------------------- 424// 425class MyMenu : public NCursesMenu 426{ 427private: 428 NCursesPanel* P; 429 NCursesMenuItem** I; 430 UserData *u; 431 #define n_items 7 432 433public: 434 MyMenu () 435 : NCursesMenu (n_items+2, 8, (lines()-10)/2, (cols()-10)/2), 436 P(0), I(0), u(0) 437 { 438 u = new UserData(1); 439 I = new NCursesMenuItem*[1+n_items]; 440 I[0] = new PassiveItem("One"); 441 I[1] = new PassiveItem("Two"); 442 I[2] = new MyAction<UserData> ("Silly", u); 443 I[3] = new FormAction("Form"); 444 I[4] = new PadAction("Pad"); 445 I[5] = new ScanAction("Scan"); 446 I[6] = new QuitItem(); 447 I[7] = new NCursesMenuItem(); // Terminating empty item 448 449 InitMenu(I, TRUE, TRUE); 450 451 P = new NCursesPanel(1, n_items, LINES-1, 1); 452 boldframe("Demo", "Silly"); 453 P->show(); 454 } 455 456 MyMenu& operator=(const MyMenu& rhs) 457 { 458 if (this != &rhs) { 459 *this = rhs; 460 } 461 return *this; 462 } 463 464 MyMenu(const MyMenu& rhs) 465 : NCursesMenu(rhs), P(0), I(0), u(0) 466 { 467 } 468 469 ~MyMenu() 470 { 471 P->hide(); 472 delete P; 473 delete u; 474 } 475 476 virtual void On_Menu_Init() 477 { 478 NCursesWindow W(::stdscr); 479 P->move(0, 0); 480 P->clrtoeol(); 481 for(int i=1; i<=count(); i++) 482 P->addch('0' + i); 483 P->bkgd(W.getbkgd()); 484 refresh(); 485 } 486 487 virtual void On_Menu_Termination() 488 { 489 P->move(0, 0); 490 P->clrtoeol(); 491 refresh(); 492 } 493 494 virtual void On_Item_Init(NCursesMenuItem& item) 495 { 496 P->move(0, item.index()); 497 P->attron(A_REVERSE); 498 P->printw("%1d", 1+item.index()); 499 P->attroff(A_REVERSE); 500 refresh(); 501 } 502 503 virtual void On_Item_Termination(NCursesMenuItem& item) 504 { 505 P->move(0, item.index()); 506 P->attroff(A_REVERSE); 507 P->printw("%1d", 1+item.index()); 508 refresh(); 509 } 510}; 511// 512// ------------------------------------------------------------------------- 513// 514class TestApplication : public NCursesApplication 515{ 516protected: 517 int titlesize() const { return 1; } 518 void title(); 519 Soft_Label_Key_Set::Label_Layout useSLKs() const { 520 return Soft_Label_Key_Set::PC_Style_With_Index; 521 } 522 void init_labels(Soft_Label_Key_Set& S) const; 523 524public: 525 TestApplication() : NCursesApplication(TRUE) { 526 } 527 528 int run(); 529}; 530 531void TestApplication::init_labels(Soft_Label_Key_Set& S) const 532{ 533 for(int i=1; i <= S.labels(); i++) { 534 char buf[8]; 535 assert(i < 100); 536 ::sprintf(buf, "Key%02d", i); 537 S[i] = buf; // Text 538 S[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification 539 } 540} 541 542void TestApplication::title() 543{ 544 const char * const titleText = "Simple C++ Binding Demo"; 545 const int len = ::strlen(titleText); 546 547 titleWindow->bkgd(screen_titles()); 548 titleWindow->addstr(0, (titleWindow->cols() - len)/2, titleText); 549 titleWindow->noutrefresh(); 550} 551 552 553int TestApplication::run() 554{ 555 MyMenu M; 556 M(); 557 return 0; 558} 559 560// 561// ------------------------------------------------------------------------- 562// 563static TestApplication *Demo = new TestApplication(); 564