1 // * This makes emacs happy -*-Mode: C++;-*-
2 /****************************************************************************
3 * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
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: *
13 * The above copyright notice and this permission notice shall be included *
14 * in all copies or substantial portions of the Software. *
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. *
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 *
28 ****************************************************************************/
31 * Silly demo program for the NCursesPanel class.
33 * written by Anatoly Ivasyuk (anatoly@nick.csh.rit.edu)
35 * Demo code for NCursesMenu and NCursesForm written by
38 * $Id: demo.cc,v 1.41 2012/02/23 10:41:56 tom Exp $
42 #include "cursesapp.h"
51 extern "C" unsigned int sleep(unsigned int);
54 #undef index // needed for NeXT
57 // -------------------------------------------------------------------------
62 void run(int sleeptime
) {
64 NCursesPanel
*mystd
= new NCursesPanel();
66 // Make a few small demo panels
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);
75 // Draw something on the main screen, so we can see what happens
76 // when panels get moved or deleted.
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
);
89 // Draw frames with titles around panels so that we can see where
90 // the panels are located.
91 u
->boldframe("Win U");
93 w
->boldframe("Win W");
95 y
->boldframe("Win Y");
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));
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.
113 // Show what happens when panels are deleted and moved.
127 // show how it looks when a panel moves
136 // show how it looks when you raise a panel
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.
165 UserData(int x
) : u(x
) {}
166 int sleeptime() const { return u
; }
169 // -------------------------------------------------------------------------
171 template<class T
> class MyAction
: public NCursesUserItem
<T
>
174 MyAction (const char* p_name
,
176 : NCursesUserItem
<T
>(p_name
, static_cast<const char*>(0), p_UserData
)
179 virtual ~MyAction() {}
183 a
.run(NCursesUserItem
<T
>::UserData()->sleeptime());
188 template class MyAction
<UserData
>;
189 template class NCURSES_IMPEXP NCursesUserItem
<UserData
>;
191 class QuitItem
: public NCursesMenuItem
194 QuitItem() : NCursesMenuItem("Quit") {
202 // -------------------------------------------------------------------------
204 class Label
: public NCursesFormField
207 Label(const char* title
,
209 : NCursesFormField(1, static_cast<int>(::strlen(title
)), row
, col
) {
211 options_off(O_EDIT
|O_ACTIVE
);
215 // -------------------------------------------------------------------------
217 class MyFieldType
: public UserDefinedFieldType
222 bool field_check(NCursesFormField
& f
) {
226 bool char_check(int c
) {
227 return (c
==chk
?TRUE
:FALSE
);
230 MyFieldType(int x
) : chk(x
) {
234 // -------------------------------------------------------------------------
236 class TestForm
: public NCursesForm
239 NCursesFormField
** F
;
242 Enumeration_Field
*eft
;
244 static const char *weekdays
[];
248 : NCursesForm(13, 51, (lines() - 15)/2, (cols() - 53)/2),
255 F
= new NCursesFormField
*[10];
256 mft
= new MyFieldType('X');
257 ift
= new Integer_Field(0, 1, 10);
258 eft
= new Enumeration_Field(weekdays
);
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();
271 InitForm(F
, TRUE
, TRUE
);
274 F
[5]->set_fieldtype(*eft
);
275 F
[6]->set_fieldtype(*ift
);
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
281 F
[8]->set_maximum_growth(10); // max. 10 lines
282 F
[8]->options_off(O_STATIC
); // make field dynamic
285 TestForm
& operator=(const TestForm
& rhs
)
293 TestForm(const TestForm
& rhs
)
294 : NCursesForm(rhs
), F(0), mft(0), ift(0), eft(0)
305 const char* TestForm::weekdays
[] = {
306 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
307 "Friday", "Saturday", NULL
};
309 // -------------------------------------------------------------------------
311 class FormAction
: public NCursesMenuItem
314 FormAction(const char *s
) : NCursesMenuItem(s
) {
319 Soft_Label_Key_Set
* S
= new Soft_Label_Key_Set
;
320 for(int i
=1; i
<= S
->labels(); i
++) {
323 ::_nc_SPRINTF(buf
, _nc_SLIMIT(sizeof(buf
)) "Frm%02d", i
);
324 (*S
)[i
] = buf
; // Text
325 (*S
)[i
] = Soft_Label_Key_Set::Soft_Label_Key::Left
; // Justification
327 NCursesApplication::getApplication()->push(*S
);
329 NCursesApplication::getApplication()->pop();
335 // -------------------------------------------------------------------------
337 class PadAction
: public NCursesMenuItem
340 PadAction(const char* s
) : NCursesMenuItem(s
) {
344 const int GRIDSIZE
= 3;
345 const int PADSIZE
= 200;
346 unsigned gridcount
= 0;
349 NCursesPanel
P(mystd
.lines()-2, mystd
.cols()-2, 1, 1);
350 NCursesFramedPad
FP(P
, PADSIZE
, PADSIZE
);
352 for (int i
=0; i
< PADSIZE
; i
++) {
353 for (int j
=0; j
< PADSIZE
; j
++) {
354 if (i
% GRIDSIZE
== 0 && j
% GRIDSIZE
== 0) {
358 FP
.addch(static_cast<chtype
>('A' + (gridcount
++ % 26)));
360 else if (i
% GRIDSIZE
== 0)
362 else if (j
% GRIDSIZE
== 0)
369 P
.label("Pad Demo", NULL
);
377 // -------------------------------------------------------------------------
379 class PassiveItem
: public NCursesMenuItem
382 PassiveItem(const char* text
) : NCursesMenuItem(text
) {
383 options_off(O_SELECTABLE
);
388 // -------------------------------------------------------------------------
390 class ScanAction
: public NCursesMenuItem
393 ScanAction(const char* s
) : NCursesMenuItem(s
) {
397 NCursesPanel
*mystd
= new NCursesPanel();
399 NCursesPanel
*w
= new NCursesPanel(mystd
->lines() - 2, mystd
->cols() - 2, 1, 1);
403 NCursesPanel
*s
= new NCursesPanel(w
->lines() - 6, w
->cols() - 6, 3, 3);
407 s
->printw("Enter decimal integers. The running total will be shown\n");
410 while (nvalue
!= 0) {
412 s
->scanw("%d", &nvalue
);
414 s
->printw("%d: ", result
+= nvalue
);
418 s
->printw("\nPress any key to continue...");
430 // -------------------------------------------------------------------------
432 class MyMenu
: public NCursesMenu
442 : NCursesMenu (n_items
+2, 8, (lines()-10)/2, (cols()-10)/2),
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
456 InitMenu(I
, TRUE
, TRUE
);
458 P
= new NCursesPanel(1, n_items
, LINES
-1, 1);
459 boldframe("Demo", "Silly");
463 MyMenu
& operator=(const MyMenu
& rhs
)
471 MyMenu(const MyMenu
& rhs
)
472 : NCursesMenu(rhs
), P(0), I(0), u(0)
483 virtual void On_Menu_Init()
485 NCursesWindow
W(::stdscr
);
488 for(int i
=1; i
<=count(); i
++)
490 P
->bkgd(W
.getbkgd());
494 virtual void On_Menu_Termination()
501 virtual void On_Item_Init(NCursesMenuItem
& item
)
503 P
->move(0, item
.index());
504 P
->attron(A_REVERSE
);
505 P
->printw("%1d", 1+item
.index());
506 P
->attroff(A_REVERSE
);
510 virtual void On_Item_Termination(NCursesMenuItem
& item
)
512 P
->move(0, item
.index());
513 P
->attroff(A_REVERSE
);
514 P
->printw("%1d", 1+item
.index());
519 // -------------------------------------------------------------------------
521 class TestApplication
: public NCursesApplication
524 int titlesize() const { return 1; }
526 Soft_Label_Key_Set::Label_Layout
useSLKs() const {
527 return Soft_Label_Key_Set::PC_Style_With_Index
;
529 void init_labels(Soft_Label_Key_Set
& S
) const;
532 TestApplication() : NCursesApplication(TRUE
) {
538 void TestApplication::init_labels(Soft_Label_Key_Set
& S
) const
540 for(int i
=1; i
<= S
.labels(); i
++) {
543 ::_nc_SPRINTF(buf
, _nc_SLIMIT(sizeof(buf
)) "Key%02d", i
);
545 S
[i
] = Soft_Label_Key_Set::Soft_Label_Key::Left
; // Justification
549 void TestApplication::title()
551 const char * const titleText
= "Simple C++ Binding Demo";
552 const int len
= ::strlen(titleText
);
554 titleWindow
->bkgd(screen_titles());
555 titleWindow
->addstr(0, (titleWindow
->cols() - len
)/2, titleText
);
556 titleWindow
->noutrefresh();
560 int TestApplication::run()
568 // -------------------------------------------------------------------------
570 static TestApplication
*Demo
= new TestApplication();