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