]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - c++/demo.cc
ncurses 5.5
[ncurses.git] / c++ / demo.cc
index 29b60fd74f1469b3e52b068f88435070872680d5..ffc46373b361d38f85b5f51cd86c94cc49424dce 100644 (file)
@@ -3,70 +3,77 @@
  *
  *   written by Anatoly Ivasyuk (anatoly@nick.csh.rit.edu)
  *
- * $Id: demo.cc,v 1.7 1997/05/05 20:53:41 tom Exp $
+ *   Demo code for NCursesMenu and NCursesForm written by
+ *   Juergen Pfeifer
+ *
+ * $Id: demo.cc,v 1.32 2005/08/13 18:14:44 tom Exp $
  */
 
-#include <stdlib.h>
-
+#include "internal.h"
+#include "cursesapp.h"
 #include "cursesm.h"
+#include "cursesf.h"
 
-#if HAVE_LIBC_H
-#  include <libc.h>
-#endif
+extern "C" unsigned int sleep(unsigned int);
 
-class SillyDemo 
+#undef index // needed for NeXT
+
+//
+// -------------------------------------------------------------------------
+//
+class SillyDemo
 {
   public:
   void run(int sleeptime) {
-    //  We need to define a full screen panel for the main screen so
-    //  that when redraws happen, the main screen actually gets redrawn.
-    //  I think there may be a bug in the panels code which won't redraw
-    //  the main screen otherwise.  Maybe someone out there can find it...
 
     NCursesPanel *std = new NCursesPanel();
 
     //  Make a few small demo panels
 
-    NCursesPanel *u = new NCursesPanel(10,20,12,4);
-    NCursesPanel *v = new NCursesPanel(10,20,10,6);
-    NCursesPanel *w = new NCursesPanel(10,20,8,8);
-    NCursesPanel *x = new NCursesPanel(10,20,6,10);
-    NCursesPanel *y = new NCursesPanel(10,20,4,12);
-    NCursesPanel *z = new NCursesPanel(10,30,2,14);
+    NCursesPanel *u = new NCursesPanel(8,20,12,4);
+    NCursesPanel *v = new NCursesPanel(8,20,10,6);
+    NCursesPanel *w = new NCursesPanel(8,20,8,8);
+    NCursesPanel *x = new NCursesPanel(8,20,6,10);
+    NCursesPanel *y = new NCursesPanel(8,20,4,12);
+    NCursesPanel *z = new NCursesPanel(8,30,2,14);
 
     //  Draw something on the main screen, so we can see what happens
     //  when panels get moved or deleted.
 
     std->box();
-    std->move(10,0);
-    std->hline('a',79);
-    std->move(0,40);
-    std->vline(20);
+    std->move(std->height()/2,1);
+    std->hline(std->width()-2);
+    std->move(1,std->width()/2);
+    std->vline(std->height()-2);
+    std->addch(0,std->width()/2,ACS_TTEE);
+    std->addch(std->height()-1,std->width()/2,ACS_BTEE);
+    std->addch(std->height()/2,0,ACS_LTEE);
+    std->addch(std->height()/2,std->width()-1,ACS_RTEE);
+    std->addch(std->height()/2,std->width()/2,ACS_PLUS);
 
     //  Draw frames with titles around panels so that we can see where
     //  the panels are located.
-
     u->boldframe("Win U");
     v->frame("Win V");
     w->boldframe("Win W");
     x->frame("Win X");
     y->boldframe("Win Y");
     z->frame("Win Z");
+    if (NCursesApplication::getApplication()->useColors()) {
+      u->bkgd(' '|COLOR_PAIR(1));
+      w->bkgd(' '|COLOR_PAIR(1));
+      y->bkgd(' '|COLOR_PAIR(1));
+      v->bkgd(' '|COLOR_PAIR(2));
+      x->bkgd(' '|COLOR_PAIR(2));
+      z->bkgd(' '|COLOR_PAIR(2));
+    }
 
     //  A refresh to any valid panel updates all panels and refreshes
     //  the screen.  Using std is just convenient - We know it's always
     //  valid until the end of the program.
 
     std->refresh();
-
-    //  Show that things actually come back correctly when the screen
-    //  is cleared and the global NCursesPanel::redraw() is called.
-
     sleep(sleeptime);
-    ::clear();                 // call ncurses clear() directly
-    ::wrefresh(stdscr);                // call ncurses refresh directly
-    sleep(sleeptime);
-    NCursesPanel::redraw();
 
     //  Show what happens when panels are deleted and moved.
 
@@ -84,7 +91,7 @@ class SillyDemo
 
     // show how it looks when a panel moves
     sleep(sleeptime);
-    y->mvpan(5,30);
+    y->mvwin(5,30);
     std->refresh();
 
     sleep(sleeptime);
@@ -102,6 +109,8 @@ class SillyDemo
 
     sleep(sleeptime);
     delete x;
+
+    std->clear();
     std->refresh();
 
     //  Don't forget to clean up the main screen.  Since this is the
@@ -113,34 +122,37 @@ class SillyDemo
   }
 };
 
-
 class UserData
 {
 private:
   int u;
 public:
-  UserData(int x) : u(x) {} 
+  UserData(int x) : u(x) {}
   int sleeptime() const { return u; }
-  
 };
-
+//
+// -------------------------------------------------------------------------
+//
 template<class T> class MyAction : public NCursesUserItem<T>
 {
 public:
-  MyAction (const T* p_UserData,
-           const char* p_name)
-    : NCursesUserItem<T>(p_UserData, p_name)
-  {};
+  MyAction (const char* p_name,
+            const T* p_UserData)
+    : NCursesUserItem<T>(p_name, static_cast<const char*>(0), p_UserData)
+  {}
 
-  ~MyAction() {}
+  virtual ~MyAction() {}
 
   bool action() {
     SillyDemo a;
-    a.run(UserData()->sleeptime());
+    a.run(NCursesUserItem<T>::UserData()->sleeptime());
     return FALSE;
   }
 };
 
+template class MyAction<UserData>;
+template class NCURSES_IMPEXP NCursesUserItem<UserData>;
+
 class QuitItem : public NCursesMenuItem
 {
 public:
@@ -148,50 +160,304 @@ public:
   }
 
   bool action() {
-    endwin();
     return TRUE;
   }
 };
+//
+// -------------------------------------------------------------------------
+//
+class Label : public NCursesFormField
+{
+public:
+  Label(const char* title,
+        int row, int col)
+    : NCursesFormField(1, static_cast<int>(::strlen(title)), row, col) {
+      set_value(title);
+      options_off(O_EDIT|O_ACTIVE);
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class MyFieldType : public UserDefinedFieldType
+{
+private:
+  int chk;
+protected:
+  bool field_check(NCursesFormField& f) {
+    return TRUE;
+  }
+  bool char_check(int c) {
+    return (c==chk?TRUE:FALSE);
+  }
+public:
+  MyFieldType(int x) : chk(x) {
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class TestForm : public NCursesForm
+{
+private:
+  NCursesFormField** F;
+  MyFieldType* mft;
+  Integer_Field *ift;
+  Enumeration_Field *eft;
+
+  static const char *weekdays[];
+
+public:
+  TestForm()
+    : NCursesForm(13, 51, (lines() - 15)/2, (cols() - 53)/2),
+      F(0),
+      mft(0),
+      ift(0),
+      eft(0)
+  {
+
+    F     = new NCursesFormField*[10];
+    mft   = new MyFieldType('X');
+    ift   = new Integer_Field(0,1,10);
+    eft   = new Enumeration_Field(weekdays);
+
+    F[0]  = new Label("Demo Entry Form",0,16);
+    F[1]  = new Label("Weekday Enum",2,1);
+    F[2]  = new Label("Number(1-10)",2,21);
+    F[3]  = new Label("Only 'X'",2,35);
+    F[4]  = new Label("Multiline Field (Dynamic and Scrollable)",5,1);
+    F[5]  = new NCursesFormField(1,18,3,1);
+    F[6]  = new NCursesFormField(1,12,3,21);
+    F[7]  = new NCursesFormField(1,12,3,35);
+    F[8]  = new NCursesFormField(4,46,6,1,2);
+    F[9]  = new NCursesFormField();
+
+    InitForm(F,TRUE,TRUE);
+    boldframe();
+
+    F[5]->set_fieldtype(*eft);
+    F[6]->set_fieldtype(*ift);
+
+    F[7]->set_fieldtype(*mft);
+    F[7]->set_maximum_growth(20); // max. 20 characters
+    F[7]->options_off(O_STATIC);  // make field dynamic
+
+    F[8]->set_maximum_growth(10); // max. 10 lines
+    F[8]->options_off(O_STATIC);  // make field dynamic
+  }
+
+  TestForm& operator=(const TestForm& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  TestForm(const TestForm& rhs)
+    : NCursesForm(rhs), F(0), mft(0), ift(0), eft(0)
+  {
+  }
+
+  ~TestForm() {
+    delete mft;
+    delete ift;
+    delete eft;
+  }
+};
 
+const char* TestForm::weekdays[] = {
+    "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+    "Friday", "Saturday", NULL };
+//
+// -------------------------------------------------------------------------
+//
+class FormAction : public NCursesMenuItem
+{
+public:
+  FormAction(const char *s) : NCursesMenuItem(s) {
+  }
+
+  bool action() {
+    TestForm F;
+    Soft_Label_Key_Set* S = new Soft_Label_Key_Set;
+    for(int i=1; i <= S->labels(); i++) {
+      char buf[5];
+      ::sprintf(buf,"Frm%02d",i);
+      (*S)[i] = buf;                                      // Text
+      (*S)[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
+    }
+    NCursesApplication::getApplication()->push(*S);
+    F();
+    NCursesApplication::getApplication()->pop();
+    return FALSE;
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class PadAction : public NCursesMenuItem
+{
+public:
+  PadAction(const char* s) : NCursesMenuItem(s) {
+  }
+
+  bool action() {
+    const int GRIDSIZE = 3;
+    const int PADSIZE  = 200;
+    unsigned gridcount = 0;
+
+    NCursesPanel std;
+    NCursesPanel P(std.lines()-2,std.cols()-2,1,1);
+    NCursesFramedPad FP(P,PADSIZE,PADSIZE);
+
+    for (int i=0; i < PADSIZE; i++) {
+      for (int j=0; j < PADSIZE; j++) {
+        if (i % GRIDSIZE == 0 && j % GRIDSIZE == 0) {
+          if (i==0 || j==0)
+            FP.addch('+');
+          else
+            FP.addch(static_cast<chtype>('A' + (gridcount++ % 26)));
+        }
+        else if (i % GRIDSIZE == 0)
+          FP.addch('-');
+        else if (j % GRIDSIZE == 0)
+          FP.addch('|');
+        else
+          FP.addch(' ');
+      }
+    }
+
+    P.label("Pad Demo",NULL);
+    FP();
+    P.clear();
+    return FALSE;
+  }
+};
+
+//
+// -------------------------------------------------------------------------
+//
+class PassiveItem : public NCursesMenuItem
+{
+public:
+  PassiveItem(const char* text) : NCursesMenuItem(text) {
+    options_off(O_SELECTABLE);
+  }
+};
+
+//
+// -------------------------------------------------------------------------
+//
+class ScanAction : public NCursesMenuItem
+{
+public:
+  ScanAction(const char* s) : NCursesMenuItem(s) {
+  }
+
+  bool action() {
+    NCursesPanel *std = new NCursesPanel();
+
+    NCursesPanel *w = new NCursesPanel(std->lines() - 2, std->cols() - 2, 1, 1);
+    w->box();
+    w->refresh();
+
+    NCursesPanel *s = new NCursesPanel(w->lines() - 6, w->cols() - 6, 3, 3);
+    s->scrollok(TRUE);
+    ::echo();
+
+    s->printw("Enter decimal integers.  The running total will be shown\n");
+    int nvalue = -1;
+    int result = 0;
+    while (nvalue != 0) {
+      nvalue = 0;
+      s->scanw("%d", &nvalue);
+      if (nvalue != 0) {
+        s->printw("%d: ", result += nvalue);
+      }
+      s->refresh();
+    }
+    s->printw("\nPress any key to continue...");
+    s->getch();
+
+    delete s;
+    delete w;
+    delete std;
+    ::noecho();
+    return FALSE;
+  }
+};
+
+//
+// -------------------------------------------------------------------------
+//
 class MyMenu : public NCursesMenu
 {
 private:
   NCursesPanel* P;
+  NCursesMenuItem** I;
+  UserData *u;
+  #define n_items 7
 
 public:
-  MyMenu (NCursesMenuItem* menu[]) 
-    : NCursesMenu (menu, 7, 8, 2, 2, TRUE)
+  MyMenu ()
+    : NCursesMenu (n_items+2, 8, (lines()-10)/2, (cols()-10)/2),
+      P(0), I(0), u(0)
   {
-    if (NCursesWindow::NumberOfColors() > 2) {
-      setcolor(1);
-      setpalette(COLOR_YELLOW, COLOR_BLUE);
-    }
-
-    P = new NCursesPanel(1,COLS,LINES-1,0);
+    u = new UserData(1);
+    I = new NCursesMenuItem*[1+n_items];
+    I[0] = new PassiveItem("One");
+    I[1] = new PassiveItem("Two");
+    I[2] = new MyAction<UserData> ("Silly", u);
+    I[3] = new FormAction("Form");
+    I[4] = new PadAction("Pad");
+    I[5] = new ScanAction("Scan");
+    I[6] = new QuitItem();
+    I[7] = new NCursesMenuItem(); // Terminating empty item
+
+    InitMenu(I,TRUE,TRUE);
+
+    P = new NCursesPanel(1,n_items,LINES-1,1);
     boldframe("Demo","Silly");
     P->show();
   }
 
+  MyMenu& operator=(const MyMenu& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  MyMenu(const MyMenu& rhs)
+    : NCursesMenu(rhs), P(0), I(0), u(0)
+  {
+  }
+
   ~MyMenu()
   {
     P->hide();
     delete P;
+    delete u;
   }
 
   virtual void On_Menu_Init()
   {
+    NCursesWindow W(::stdscr);
     P->move(0,0);
     P->clrtoeol();
-    P->addstr("12345");
-    NCursesPanel::refresh();
+    for(int i=1; i<=count(); i++)
+      P->addch('0' + i);
+    P->bkgd(W.getbkgd());
+    refresh();
   }
 
   virtual void On_Menu_Termination()
   {
     P->move(0,0);
     P->clrtoeol();
-    P->addstr("Menu Exit");
-    NCursesPanel::refresh();
+    refresh();
   }
 
   virtual void On_Item_Init(NCursesMenuItem& item)
@@ -200,7 +466,7 @@ public:
     P->attron(A_REVERSE);
     P->printw("%1d",1+item.index());
     P->attroff(A_REVERSE);
-    NCursesPanel::refresh();
+    refresh();
   }
 
   virtual void On_Item_Termination(NCursesMenuItem& item)
@@ -208,33 +474,58 @@ public:
     P->move(0,item.index());
     P->attroff(A_REVERSE);
     P->printw("%1d",1+item.index());
-    NCursesPanel::refresh();
+    refresh();
   }
 };
-
-main()
+//
+// -------------------------------------------------------------------------
+//
+class TestApplication : public NCursesApplication
 {
-  UserData* u = new UserData(1);
-
-  NCursesWindow::useColors();
+protected:
+  int titlesize() const { return 1; }
+  void title();
+  Soft_Label_Key_Set::Label_Layout useSLKs() const {
+    return Soft_Label_Key_Set::PC_Style_With_Index;
+  }
+  void init_labels(Soft_Label_Key_Set& S) const;
 
-  NCursesMenuItem** I = new NCursesMenuItem*[6];
-  I[0] = new NCursesMenuItem("One");
-  I[1] = new NCursesMenuItem("Two");
-  I[2] = new MyAction<UserData> (u, "Silly");
-  I[3] = new NCursesMenuItem("Four");
-  I[4] = new QuitItem();
-  I[5] = new NCursesMenuItem();
-  
-  MyMenu m(I);
+public:
+  TestApplication() : NCursesApplication(TRUE) {
+  }
 
-  m();
+  int run();
+};
 
-  for(int i=0; i < 6; i++) {
-    delete I[i];
+void TestApplication::init_labels(Soft_Label_Key_Set& S) const
+{
+  for(int i=1; i <= S.labels(); i++) {
+    char buf[5];
+    ::sprintf(buf,"Key%02d",i);
+    S[i] = buf;                                      // Text
+    S[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
   }
-  delete I;
-  delete u;
+}
 
-  exit(0);
+void TestApplication::title()
+{
+  const char * const titleText = "Simple C++ Binding Demo";
+  const int len = ::strlen(titleText);
+
+  titleWindow->bkgd(screen_titles());
+  titleWindow->addstr(0,(titleWindow->cols() - len)/2, titleText);
+  titleWindow->noutrefresh();
+}
+
+
+int TestApplication::run()
+{
+  MyMenu M;
+  M();
+  return 0;
 }
+
+//
+// -------------------------------------------------------------------------
+//
+static TestApplication Demo;