ncurses 4.2
[ncurses.git] / c++ / demo.cc
1 /*
2  *   Silly demo program for the NCursesPanel class.
3  *
4  *   written by Anatoly Ivasyuk (anatoly@nick.csh.rit.edu)
5  *
6  *   Demo code for NCursesMenu and NCursesForm written by
7  *   Juergen Pfeifer <Juergen.Pfeifer@T-Online.de>
8  *
9  * $Id: demo.cc,v 1.13 1998/02/19 16:54:54 florian Exp $
10  */
11
12 #include "cursesapp.h"
13 #include "cursesm.h"
14 #include "cursesf.h"
15
16 #if HAVE_LIBC_H
17 #  include <libc.h>
18 #endif
19
20 extern "C" unsigned int sleep(unsigned int);
21
22 //
23 // -------------------------------------------------------------------------
24 //
25 class SillyDemo 
26 {
27   public:
28   void run(int sleeptime) {
29
30     NCursesPanel *std = new NCursesPanel();
31
32     //  Make a few small demo panels
33
34     NCursesPanel *u = new NCursesPanel(8,20,12,4);
35     NCursesPanel *v = new NCursesPanel(8,20,10,6);
36     NCursesPanel *w = new NCursesPanel(8,20,8,8);
37     NCursesPanel *x = new NCursesPanel(8,20,6,10);
38     NCursesPanel *y = new NCursesPanel(8,20,4,12);
39     NCursesPanel *z = new NCursesPanel(8,30,2,14);
40
41     //  Draw something on the main screen, so we can see what happens
42     //  when panels get moved or deleted.
43
44     std->box();
45     std->move(std->height()/2,1);
46     std->hline(std->width()-2);
47     std->move(1,std->width()/2);
48     std->vline(std->height()-2);
49     std->addch(0,std->width()/2,ACS_TTEE);
50     std->addch(std->height()-1,std->width()/2,ACS_BTEE);
51     std->addch(std->height()/2,0,ACS_LTEE);
52     std->addch(std->height()/2,std->width()-1,ACS_RTEE);
53     std->addch(std->height()/2,std->width()/2,ACS_PLUS);
54
55     //  Draw frames with titles around panels so that we can see where
56     //  the panels are located.
57     u->boldframe("Win U");
58     v->frame("Win V");
59     w->boldframe("Win W");
60     x->frame("Win X");
61     y->boldframe("Win Y");
62     z->frame("Win Z");
63     if (NCursesApplication::getApplication()->useColors()) {
64       u->bkgd(' '|COLOR_PAIR(1));
65       w->bkgd(' '|COLOR_PAIR(1));
66       y->bkgd(' '|COLOR_PAIR(1));
67       v->bkgd(' '|COLOR_PAIR(2));
68       x->bkgd(' '|COLOR_PAIR(2));
69       z->bkgd(' '|COLOR_PAIR(2));
70     }
71
72     //  A refresh to any valid panel updates all panels and refreshes
73     //  the screen.  Using std is just convenient - We know it's always
74     //  valid until the end of the program.
75
76     std->refresh();
77     sleep(sleeptime);
78
79     //  Show what happens when panels are deleted and moved.
80
81     sleep(sleeptime);
82     delete u;
83     std->refresh();
84
85     sleep(sleeptime);
86     delete z;
87     std->refresh();
88
89     sleep(sleeptime);
90     delete v;
91     std->refresh();
92
93     // show how it looks when a panel moves
94     sleep(sleeptime);
95     y->mvwin(5,30);
96     std->refresh();
97
98     sleep(sleeptime);
99     delete y;
100     std->refresh();
101
102     // show how it looks when you raise a panel
103     sleep(sleeptime);
104     w->top();
105     std->refresh();
106
107     sleep(sleeptime);
108     delete w;
109     std->refresh();
110
111     sleep(sleeptime);
112     delete x;
113
114     std->clear();
115     std->refresh();
116
117     //  Don't forget to clean up the main screen.  Since this is the
118     //  last thing using NCursesWindow, this has the effect of
119     //  shutting down ncurses and restoring the terminal state.
120
121     sleep(sleeptime);
122     delete std;
123   }
124 };
125
126 class UserData
127 {
128 private:
129   int u;
130 public:
131   UserData(int x) : u(x) {} 
132   int sleeptime() const { return u; }  
133 };
134 //
135 // -------------------------------------------------------------------------
136 //
137 template<class T> class MyAction : public NCursesUserItem<T>
138 {
139 public:
140   MyAction (const char* p_name,
141             const T* p_UserData)
142     : NCursesUserItem<T>(p_name, (const char*)0, p_UserData)
143   {};
144
145   ~MyAction() {}
146
147   bool action() {
148     SillyDemo a;
149     a.run(UserData()->sleeptime());
150     return FALSE;
151   }
152 };
153
154 class QuitItem : public NCursesMenuItem
155 {
156 public:
157   QuitItem() : NCursesMenuItem("Quit") {
158   }
159
160   bool action() {
161     return TRUE;
162   }
163 };
164 //
165 // -------------------------------------------------------------------------
166 //
167 class Label : public NCursesFormField
168 {
169 public:
170   Label(const char*title,
171         int row, int col)
172     : NCursesFormField(1,(int)::strlen(title),row,col) {
173       set_value(title);
174       options_off(O_EDIT|O_ACTIVE);
175   }
176 };
177 //
178 // -------------------------------------------------------------------------
179 //
180 class MyFieldType : public UserDefinedFieldType {
181 private:
182   int chk;
183 protected:
184   bool field_check(NCursesFormField& f) {
185     return TRUE;
186   }
187   bool char_check(int c) {
188     return (c==chk?TRUE:FALSE);
189   }
190 public:
191   MyFieldType(int x) : chk(x) {
192   }
193 };
194 //
195 // -------------------------------------------------------------------------
196 //
197 class TestForm : public NCursesForm
198 {
199 private:
200   NCursesFormField** F;
201   MyFieldType* mft;
202   Integer_Field *ift;
203   Enumeration_Field *eft;
204
205   static char *weekdays[];
206   
207 public:
208   TestForm() : NCursesForm(13,51,(lines()-15)/2,(cols()-53)/2) {
209     
210     F     = new NCursesFormField*[10];
211     mft   = new MyFieldType('X');
212     ift   = new Integer_Field(0,1,10);
213     eft   = new Enumeration_Field(weekdays);
214
215     F[0]  = new Label("Demo Entry Form",0,16);
216     F[1]  = new Label("Weekday Enum",2,1);
217     F[2]  = new Label("Number(1-10)",2,21);
218     F[3]  = new Label("Only 'X'",2,35);
219     F[4]  = new Label("Multiline Field (Dynamic and Scrollable)",5,1);
220     F[5]  = new NCursesFormField(1,18,3,1);
221     F[6]  = new NCursesFormField(1,12,3,21);
222     F[7]  = new NCursesFormField(1,12,3,35);
223     F[8]  = new NCursesFormField(4,46,6,1,2);
224     F[9]  = new NCursesFormField();
225   
226     InitForm(F,TRUE,TRUE);
227     boldframe();
228     
229     F[5]->set_fieldtype(*eft);
230     F[6]->set_fieldtype(*ift);
231
232     F[7]->set_fieldtype(*mft);
233     F[7]->set_maximum_growth(20); // max. 20 characters
234     F[7]->options_off(O_STATIC);  // make field dynamic
235
236     F[8]->set_maximum_growth(10); // max. 10 lines
237     F[8]->options_off(O_STATIC);  // make field dynamic
238   }
239
240   ~TestForm() {
241     delete mft;
242     delete ift;
243     delete eft;
244   }
245 };
246
247 char* TestForm::weekdays[] = {
248     "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
249     "Friday", "Saturday", (char *)0 };
250 //
251 // -------------------------------------------------------------------------
252 //
253 class FormAction : public NCursesMenuItem
254 {
255 public:
256   FormAction(const char *s) : NCursesMenuItem(s) {
257   }
258
259   bool action() {
260     TestForm F;
261     Soft_Label_Key_Set* S = new Soft_Label_Key_Set;
262     for(int i=1; i <= S->labels(); i++) {
263       char buf[5];
264       ::sprintf(buf,"Frm%02d",i);
265       (*S)[i] = buf;                                      // Text
266       (*S)[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
267     }
268     NCursesApplication::getApplication()->push(*S);
269     F();
270     NCursesApplication::getApplication()->pop();
271     return FALSE;
272   }
273 };
274 //
275 // -------------------------------------------------------------------------
276 //
277 class PassiveItem : public NCursesMenuItem {
278 public:
279   PassiveItem(const char* text) : NCursesMenuItem(text) {
280     options_off(O_SELECTABLE);
281   }
282 };
283 //
284 // -------------------------------------------------------------------------
285 //
286 class MyMenu : public NCursesMenu
287 {
288 private:
289   NCursesPanel* P;
290   NCursesMenuItem** I;
291   UserData *u;
292
293 public:
294   MyMenu () 
295     : NCursesMenu (8, 8, (lines()-10)/2, (cols()-10)/2)
296   {
297     u = new UserData(1);
298     I = new NCursesMenuItem*[7];
299     I[0] = new PassiveItem("One");
300     I[1] = new PassiveItem("Two");
301     I[2] = new MyAction<UserData> ("Silly", u);
302     I[3] = new FormAction("Form");
303     I[4] = new PassiveItem("Five");
304     I[5] = new QuitItem();
305     I[6] = new NCursesMenuItem(); // Terminating empty item
306
307     InitMenu(I,TRUE,TRUE);
308     
309     P = new NCursesPanel(1,6,LINES-1,1);
310     boldframe("Demo","Silly");
311     P->show();
312   }
313
314   ~MyMenu()
315   {
316     P->hide();
317     delete P;
318     delete u;
319   }
320
321   virtual void On_Menu_Init()
322   {
323     NCursesWindow W(::stdscr);
324     P->move(0,0);
325     P->clrtoeol();
326     for(int i=1; i<=count(); i++)
327       P->addch('0' + i);
328     P->bkgd(W.getbkgd());
329     refresh();
330   }
331
332   virtual void On_Menu_Termination()
333   {
334     P->move(0,0);
335     P->clrtoeol();
336     refresh();
337   }
338
339   virtual void On_Item_Init(NCursesMenuItem& item)
340   {
341     P->move(0,item.index());
342     P->attron(A_REVERSE);
343     P->printw("%1d",1+item.index());
344     P->attroff(A_REVERSE);
345     refresh();
346   }
347
348   virtual void On_Item_Termination(NCursesMenuItem& item)
349   {
350     P->move(0,item.index());
351     P->attroff(A_REVERSE);
352     P->printw("%1d",1+item.index());
353     refresh();
354   }
355 };
356 //
357 // -------------------------------------------------------------------------
358 //
359 class TestApplication : public NCursesApplication {
360 protected:
361   int titlesize() const { return 1; }
362   void title();
363   Soft_Label_Key_Set::Label_Layout useSLKs() const {
364     return Soft_Label_Key_Set::PC_Style_With_Index;
365   }
366   void init_labels(Soft_Label_Key_Set& S) const;
367
368 public:
369   TestApplication() : NCursesApplication(TRUE) {
370   }
371
372   int run();
373 };
374
375 void TestApplication::init_labels(Soft_Label_Key_Set& S) const {
376   for(int i=1; i <= S.labels(); i++) {
377     char buf[5];
378     ::sprintf(buf,"Key%02d",i);
379     S[i] = buf;                                      // Text
380     S[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
381   }
382 }
383
384 void TestApplication::title() {
385   const char * const title = "Simple C++ Binding Demo";
386   const int len = ::strlen(title);
387
388   titleWindow->bkgd(screen_titles());
389   titleWindow->addstr(0,(titleWindow->cols()-len)/2,title);
390   titleWindow->noutrefresh();  
391 }
392
393
394 int TestApplication::run() {
395   MyMenu M;
396   M();
397   return 0;
398 }
399
400 //
401 // -------------------------------------------------------------------------
402 //
403 static TestApplication Demo;