mirror of
https://github.com/Aigor44/ncursesw-morphos.git
synced 2024-12-21 07:39:06 +08:00
561 lines
14 KiB
C++
561 lines
14 KiB
C++
// * This makes emacs happy -*-Mode: C++;-*-
|
|
/****************************************************************************
|
|
* Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. *
|
|
* *
|
|
* Permission is hereby granted, free of charge, to any person obtaining a *
|
|
* copy of this software and associated documentation files (the *
|
|
* "Software"), to deal in the Software without restriction, including *
|
|
* without limitation the rights to use, copy, modify, merge, publish, *
|
|
* distribute, distribute with modifications, sublicense, and/or sell *
|
|
* copies of the Software, and to permit persons to whom the Software is *
|
|
* furnished to do so, subject to the following conditions: *
|
|
* *
|
|
* The above copyright notice and this permission notice shall be included *
|
|
* in all copies or substantial portions of the Software. *
|
|
* *
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
|
|
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
|
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
|
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
|
|
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
|
* *
|
|
* Except as contained in this notice, the name(s) of the above copyright *
|
|
* holders shall not be used in advertising or otherwise to promote the *
|
|
* sale, use or other dealings in this Software without prior written *
|
|
* authorization. *
|
|
****************************************************************************/
|
|
|
|
/*
|
|
* Silly demo program for the NCursesPanel class.
|
|
*
|
|
* written by Anatoly Ivasyuk (anatoly@nick.csh.rit.edu)
|
|
*
|
|
* Demo code for NCursesMenu and NCursesForm written by
|
|
* Juergen Pfeifer
|
|
*
|
|
* $Id: demo.cc,v 1.34 2006/04/22 22:38:57 tom Exp $
|
|
*/
|
|
|
|
#include "internal.h"
|
|
#include "cursesapp.h"
|
|
#include "cursesm.h"
|
|
#include "cursesf.h"
|
|
|
|
extern "C" unsigned int sleep(unsigned int);
|
|
|
|
#undef index // needed for NeXT
|
|
|
|
//
|
|
// -------------------------------------------------------------------------
|
|
//
|
|
class SillyDemo
|
|
{
|
|
public:
|
|
void run(int sleeptime) {
|
|
|
|
NCursesPanel *std = new NCursesPanel();
|
|
|
|
// Make a few small demo panels
|
|
|
|
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(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();
|
|
sleep(sleeptime);
|
|
|
|
// Show what happens when panels are deleted and moved.
|
|
|
|
sleep(sleeptime);
|
|
delete u;
|
|
std->refresh();
|
|
|
|
sleep(sleeptime);
|
|
delete z;
|
|
std->refresh();
|
|
|
|
sleep(sleeptime);
|
|
delete v;
|
|
std->refresh();
|
|
|
|
// show how it looks when a panel moves
|
|
sleep(sleeptime);
|
|
y->mvwin(5,30);
|
|
std->refresh();
|
|
|
|
sleep(sleeptime);
|
|
delete y;
|
|
std->refresh();
|
|
|
|
// show how it looks when you raise a panel
|
|
sleep(sleeptime);
|
|
w->top();
|
|
std->refresh();
|
|
|
|
sleep(sleeptime);
|
|
delete w;
|
|
std->refresh();
|
|
|
|
sleep(sleeptime);
|
|
delete x;
|
|
|
|
std->clear();
|
|
std->refresh();
|
|
|
|
// Don't forget to clean up the main screen. Since this is the
|
|
// last thing using NCursesWindow, this has the effect of
|
|
// shutting down ncurses and restoring the terminal state.
|
|
|
|
sleep(sleeptime);
|
|
delete std;
|
|
}
|
|
};
|
|
|
|
class UserData
|
|
{
|
|
private:
|
|
int u;
|
|
public:
|
|
UserData(int x) : u(x) {}
|
|
int sleeptime() const { return u; }
|
|
};
|
|
//
|
|
// -------------------------------------------------------------------------
|
|
//
|
|
template<class T> class MyAction : public NCursesUserItem<T>
|
|
{
|
|
public:
|
|
MyAction (const char* p_name,
|
|
const T* p_UserData)
|
|
: NCursesUserItem<T>(p_name, static_cast<const char*>(0), p_UserData)
|
|
{}
|
|
|
|
virtual ~MyAction() {}
|
|
|
|
bool action() {
|
|
SillyDemo a;
|
|
a.run(NCursesUserItem<T>::UserData()->sleeptime());
|
|
return FALSE;
|
|
}
|
|
};
|
|
|
|
template class MyAction<UserData>;
|
|
template class NCURSES_IMPEXP NCursesUserItem<UserData>;
|
|
|
|
class QuitItem : public NCursesMenuItem
|
|
{
|
|
public:
|
|
QuitItem() : NCursesMenuItem("Quit") {
|
|
}
|
|
|
|
bool action() {
|
|
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[8];
|
|
::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 ()
|
|
: NCursesMenu (n_items+2, 8, (lines()-10)/2, (cols()-10)/2),
|
|
P(0), I(0), u(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();
|
|
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();
|
|
refresh();
|
|
}
|
|
|
|
virtual void On_Item_Init(NCursesMenuItem& item)
|
|
{
|
|
P->move(0,item.index());
|
|
P->attron(A_REVERSE);
|
|
P->printw("%1d",1+item.index());
|
|
P->attroff(A_REVERSE);
|
|
refresh();
|
|
}
|
|
|
|
virtual void On_Item_Termination(NCursesMenuItem& item)
|
|
{
|
|
P->move(0,item.index());
|
|
P->attroff(A_REVERSE);
|
|
P->printw("%1d",1+item.index());
|
|
refresh();
|
|
}
|
|
};
|
|
//
|
|
// -------------------------------------------------------------------------
|
|
//
|
|
class TestApplication : public NCursesApplication
|
|
{
|
|
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;
|
|
|
|
public:
|
|
TestApplication() : NCursesApplication(TRUE) {
|
|
}
|
|
|
|
int run();
|
|
};
|
|
|
|
void TestApplication::init_labels(Soft_Label_Key_Set& S) const
|
|
{
|
|
for(int i=1; i <= S.labels(); i++) {
|
|
char buf[8];
|
|
::sprintf(buf,"Key%02d",i);
|
|
S[i] = buf; // Text
|
|
S[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
|
|
}
|
|
}
|
|
|
|
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;
|