ar.constantine
27-04-2009, 21:25
با سلام
میخوام سورس منوهای دینامیک رو با C++ براتون بزارم.
امید وارم لذت ببرید.
با تشکر
ar.constantine@yahoo.com
:5:
/*
dynamic menu with C++
This program must be run under BC v3.0 or higher version
*/
#include<conio.h>
#include<dos.h>
#include<stdio.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define FAIL 0
#define ENT 0x000d
#define ESC 0x001b
#define UP 0x4800
#define DOWN 0x5000
#define LEFT 0x4b00
#define RIGHT 0x4d00
/*
This menu system designed for CGA/EGA/VGA adapter,monochrom is not
supported
*/
class base{
public:
int StrLen(char*);
void StrCopy(char*,char*);
int StrCmp(char*,char*);
};
//----------------------------------------------------------------------
int base::StrLen(char *s)
{
int i;
i=0;
while(*s++)i++;
return i;
}
//---------------------------------------------------------------------
void base::StrCopy(char *dest,char *src)
{
while(*src)*dest++=*src++;
*dest=*src;
}
//---------------------------------------------------------------------
int base::StrCmp(char *dest,char *src)
{
do{
if(*src++!=*dest++)return TRUE;
}while(*src&&*dest);
return FALSE;
}
//************************************************** *******************
class screen:public base{
private:
unsigned char TextAttribute,current_x,current_y;
public:
unsigned int last_pressed_key;
screen(void);
unsigned int GetKey(void);
void SetColor(char,char);
void SetTColor(char);
void SetBColor(char);
void SetVideoMode(char);
void CLS(void);
int ReadChar(int,int);
void PutChar(int,int,char);
void PutString(int,int,char*);
void Locate(char,char);
void SetCursor(char,char);
void HideCursor(void);
void ShowCursor(void);
void Fill(char,char,char,char,char);
void Box(int,int,int,int,char*);
void SaveScreen(int,int,int,int,int*);
void LoadScreen(int,int,int,int,int*);
};
//--------------------------------------------------------------
screen::screen(void)
{
TextAttribute=14;
current_x=0;
current_y=0;
}
//--------------------------------------------------------------
unsigned int screen::GetKey(void)
{
unsigned int key;
if(!(key=getch()))key=getch()<<8;
last_pressed_key=key;
return key;
}
//--------------------------------------------------------------
void screen::SetColor(char tcolor,char bcolor)
{
TextAttribute=bcolor<<4|tcolor;
}
//--------------------------------------------------------------
void screen::SetTColor(char text)
{
TextAttribute=(TextAttribute&0xf0)|text;
}
//--------------------------------------------------------------
void screen::SetBColor(char text)
{
TextAttribute=(TextAttribute&0x0f)|text<<4;
}
//--------------------------------------------------------------
void screen::SetVideoMode(char mode)
{
asm{
mov ah,0
mov al,mode
int 0x10
}
}
//--------------------------------------------------------------
void screen::CLS(void)
{
SetVideoMode(3);
}
//--------------------------------------------------------------
int screen::ReadChar(int x, int y)
{
int attrib;
asm{
mov ax,0xb800
mov es,ax
mov ax,y
mov bl,160
mul bl
mov bx,x
shl bx,1
add bx,ax
mov ax,es:[bx]
mov attrib,ax
}
return attrib;
}
//--------------------------------------------------------------
void WriteChar(int x,int y ,int char_attrib)
{
asm{
mov ax,0xb800
mov es,ax
mov ax,y
mov bl,160
mul bl
mov bx,x
shl bx,1
add bx,ax
mov cx,char_attrib
mov es:[bx],cx
}
}
//--------------------------------------------------------------
void screen::Locate(char x,char y)
{
char xx,yy;
asm{
mov ah,2
mov bh,0
mov dl,x
mov dh,y
int 0x10
mov xx,dl
mov yy,dh
}
current_x=xx;
current_y=yy;
}
//--------------------------------------------------------------
void screen::PutChar(int x,int y,char chr)
{
WriteChar(x,y,(unsigned char)chr|(TextAttribute<<8));
}
//--------------------------------------------------------------
void screen::PutString(int x,int y,char *s)
{
while(*s)PutChar(x++,y,*s++);
Locate(x,y);
}
//--------------------------------------------------------------
void screen::SetCursor(char start,char end)
{
asm{
mov ah,1
mov ch,start
mov cl,end
int 0x10
}
}
//--------------------------------------------------------------
void screen::HideCursor(void)
{
SetCursor(1,0);
}
//--------------------------------------------------------------
void screen::ShowCursor(void)
{
SetCursor(4,5);
}
//--------------------------------------------------------------
void screen::Fill(char x1,char y1,char width,char height,char chr)
{
char i,j,x2,y2;
x2=x1+width-1;
y2=y1+height-1;
for(j=y1;j<=y2;j++)
for(i=x1;i<=x2;i++)
PutChar(i,j,chr);
}
//--------------------------------------------------------------
void screen::Box(int x1,int y1,int width,int height,char *pattern)
{
int i,j,x2,y2;
x2=x1+width-1;
y2=y1+height-1;
for(i=x1;i<x2;i++)
{
PutChar(i,y1,pattern[1]);
PutChar(i,y2,pattern[5]);
}
for(j=y1;j<y2;j++)
{
PutChar(x1,j,pattern[7]);
PutChar(x2,j,pattern[3]);
}
PutChar(x1,y1,pattern[0]);
PutChar(x2,y1,pattern[2]);
PutChar(x2,y2,pattern[4]);
PutChar(x1,y2,pattern[6]);
}
//--------------------------------------------------------------
void screen::SaveScreen(int x1,int y1,int width,int height,int *buff)
{
int i,j,x2,y2;
x2=x1+width-1;
y2=y1+height-1;
for(j=y1;j<=y2;j++)
for(i=x1;i<=x2;i++)
*buff++=ReadChar(i,j);
}
//--------------------------------------------------------------
void screen::LoadScreen(int x1,int y1,int width,int height,int *buff)
{
int i,j,x2,y2;
x2=x1+width-1;
y2=y1+height-1;
for(j=y1;j<=y2;j++)
for(i=x1;i<=x2;i++)
WriteChar(i,j,*buff++);
}
//************************************************** ********************
struct bar_pad{
char *prompt;
char *popup_name;
struct bar_pad *next;
};
struct popup_pad{
char *prompt;
struct popup_pad *next;
};
struct bar_menu{
char *name;
int x,y,count,act;
struct bar_pad *pad;
struct bar_menu *next;
};
struct popup_menu{
char *name;
int x,y,count,act,max;
struct popup_pad *pad;
struct popup_menu *next;
};
class menu:public screen{
protected:
struct{
char text,background,
a_text,a_background,
b_text,b_background,
s_text,s_background;
}menu_color;
struct bar_menu *bar;
struct popup_menu *popup;
char default_border[8];
char *current_popup_name;
char *current_bar_name;
void AddBarPad(struct bar_menu*,char*,char*);
struct bar_pad* GotoBarPad(struct bar_menu*,int);
void DeleteBarPads(struct bar_menu*);
struct bar_menu* GotoBar(char*);
void AddPopupPad(struct popup_menu*,char*);
struct popup_pad *GotoPopupPad(struct popup_menu*,int);
void DeletePopupPads(struct popup_menu*);
struct popup_menu *GotoPopup(char*);
public:
menu(void);
~menu(void);
void DefineBar(char*,int,int);
void DefineBarPad(char*,char*,char*);
void DeleteBars(void);
void DefinePopup(char*,int,int);
void DefinePopupPad(char*,char*);
void DeletePopups(void);
char ActivateBar(char*);
char ActivatePopup(char*);
virtual void OnPopupPad(char*,int){};
virtual void OnBarPad(char*,int){};
virtual void OnSelectBar(char*,int){};
virtual void OnSelectPopup(char*,int){};
};
menu::menu(void)
{
bar=NULL;
popup=NULL;
current_bar_name=NULL;
current_popup_name=NULL;
menu_color.text=BLACK;
menu_color.background=LIGHTGRAY;
menu_color.a_text=WHITE;
menu_color.a_background=RED;
menu_color.b_text=BLACK;
menu_color.b_background=LIGHTGRAY;
menu_color.s_text=BLACK;
menu_color.s_background=BLACK;
default_border[0]='Ú';
default_border[1]='Ä';
default_border[2]='·';
default_border[3]='º';
default_border[4]='¼';
default_border[5]='Í';
default_border[6]='Ô';
default_border[7]='³';
}
menu::~menu(void)
{
DeleteBars();
DeletePopups();
}
void menu::AddBarPad(struct bar_menu *bm,char *prompt,char
*popup_name){
struct bar_pad *p,*tmp;
p=new bar_pad;
p->prompt=new char[StrLen(prompt)+1];
p->popup_name=new char[StrLen(popup_name)+1];
StrCopy(p->prompt,prompt);
StrCopy(p->popup_name,popup_name);
p->next=NULL;
if(bm->pad==NULL){
bm->pad=p;
bm->count=1;
}else{
tmp=bm->pad;
while(tmp->next)tmp=tmp->next;
tmp->next=p;
bm->count++;
}
}
struct bar_pad* menu::GotoBarPad(struct bar_menu *bm,int n){
struct bar_pad *p;
int i;
p=bm->pad;
for(i=1;i<n;i++)p=p->next;
return p;
}
void menu::DeleteBarPads(struct bar_menu *bm){
struct bar_pad *tmp;
while(bm->pad){
tmp=bm->pad;
bm->pad=tmp->next;
delete[] tmp->prompt;
delete[] tmp->popup_name;
delete tmp;
}
bm->count=0;
}
void menu::DefineBar(char *name,int x,int y){
struct bar_menu *p,*tmp;
p=new bar_menu;
p->name=new char[StrLen(name)+1];
StrCopy(p->name,name);
p->x=x;
p->y=y;
p->count=p->act=0;
p->pad=NULL;
p->next=NULL;
if(bar==NULL)bar=p;
else{
tmp=bar;
while(tmp->next)tmp=tmp->next;
tmp->next=p;
}
}
struct bar_menu* menu::GotoBar(char *name){
struct bar_menu *p;
p=bar;
while(p){
if(!StrCmp(p->name,name))return p;
p=p->next;
}
return NULL;
}
void menu::DefineBarPad(char *name,char *prompt,char *popup_name){
struct bar_menu *p;
p=GotoBar(name);
if(p)AddBarPad(p,prompt,popup_name);
}
void menu::DeleteBars(void){
struct bar_menu *tmp;
while(bar){
tmp=bar;
bar=tmp->next;
DeleteBarPads(tmp);
delete tmp;
}
}
void menu::AddPopupPad(struct popup_menu *pm,char *prompt){
struct popup_pad *p,*tmp;
p=new popup_pad;
p->prompt=new char[StrLen(prompt)+1];
StrCopy(p->prompt,prompt);
p->next=NULL;
if(pm->pad==NULL){
pm->pad=p;
pm->count=1;
}else{
tmp=pm->pad;
while(tmp->next)tmp=tmp->next;
tmp->next=p;
pm->count++;
}
}
void menu::DeletePopupPads(struct popup_menu *pm){
struct popup_pad *tmp;
while(pm->pad){
tmp=pm->pad;
pm->pad=tmp->next;
delete[] tmp->prompt;
delete tmp;
}
pm->count=0;
if(current_bar_name){
delete[] current_bar_name;
current_bar_name=NULL;
}
}
struct popup_pad* menu::GotoPopupPad(struct popup_menu *pm,int n){
struct popup_pad *p;
int i;
p=pm->pad;
for(i=1;i<n;i++)p=p->next;
return p;
}
void menu::DefinePopup(char *name,int x,int y){
struct popup_menu *p,*tmp;
p=new popup_menu;
p->name=new char[StrLen(name)+1];
StrCopy(p->name,name);
p->x=x;
p->y=y;
p->count=0;
p->act=1;
p->max=5;
p->pad=NULL;
p->next=NULL;
if(popup==NULL)popup=p;
else{
tmp=popup;
while(tmp->next)tmp=tmp->next;
tmp->next=p;
}
}
struct popup_menu* menu::GotoPopup(char *name){
struct popup_menu *p;
p=popup;
while(p){
if(!StrCmp(p->name,name))return p;
p=p->next;
}
return NULL;
}
void menu::DefinePopupPad(char *name,char *prompt){
struct popup_menu *p;
p=GotoPopup(name);
if(p) AddPopupPad(p,prompt);
}
void menu::DeletePopups(void){
struct popup_menu *tmp;
while(popup){
tmp=popup;
popup=tmp->next;
DeletePopupPads(tmp);
delete tmp;
}
if(current_popup_name){
delete[] current_popup_name;
current_popup_name=NULL;
}
}
char menu::ActivateBar(char *name)
{
struct bar_menu *bmenu;
struct bar_pad *bpad;
int i,l,act;
unsigned int key;
bmenu=GotoBar(name);
if(bmenu&&bmenu->count){
if(current_bar_name)delete[] current_bar_name;
current_bar_name=new char[StrLen(name+1)];
StrCopy(current_bar_name,name);
key=0;
bmenu->act=1;
SetColor(menu_color.text,menu_color.background);
Fill(0,bmenu->y,80,1,' ');
while(key!=ESC&&bmenu->count){
l=0;
for(i=1;i<=bmenu->count;i++){
bpad=GotoBarPad(bmenu,i);
SetColor(menu_color.text,menu_color.background);
PutString(bmenu->x+l,bmenu->y,bpad->prompt);
l+=StrLen(bpad->prompt);
}
l=0;
for(i=1;i<=bmenu->act;i++){
bpad=GotoBarPad(bmenu,i);
if(i<bmenu->act)l+=StrLen(bpad->prompt);
}
SetColor(menu_color.a_text,menu_color.a_background );
PutString(bmenu->x+l,bmenu->y,bpad->prompt);
OnBarPad(bmenu->name,bmenu->act);
if(ActivatePopup(bpad->popup_name)) key=last_pressed_key;
else key=GetKey();
switch(key){
case LEFT:bmenu->act--;break;
case RIGHT:bmenu->act++;break;
}
if(bmenu->act<1)bmenu->act=bmenu->count;
if(bmenu->act>bmenu->count)bmenu->act=1;
}
}else return FAIL;
return OK;
}
char menu::ActivatePopup(char *name){
struct popup_menu *pmenu;
struct popup_pad *ppad;
int i,len,act;
char rotate_flag,loop_flag;
int
i_start,i_end,border_x,border_y,border_width,borde r_mid_x,border_height;
int pad_x,pad_y;
int buff[80*25];
unsigned int key;
pmenu=GotoPopup(name);
if(pmenu&&pmenu->count){
if(current_popup_name)delete[] current_popup_name;
current_popup_name=new char[StrLen(name+1)];
StrCopy(current_popup_name,name);
if(pmenu->max>pmenu->count)pmenu->max=pmenu->count;
i_start=1;
i_end=pmenu->count-pmenu->max+1;
if(pmenu->act>pmenu->max){
act=pmenu->max;
i_start=pmenu->act-pmenu->max+1;
}else act=pmenu->act;
border_width=0;
for(i=1;i<=pmenu->count;i++){
ppad=GotoPopupPad(pmenu,i);
len=StrLen(ppad->prompt);
if(len>border_width)border_width=len;//detect max width
}
border_x=pmenu->x;
border_y=pmenu->y;
border_width+=2;
border_height=pmenu->max+2;
pad_x=border_x+1;
pad_y=border_y+1;
key=0;
SaveScreen(border_x,border_y,border_width+2,border _height+1,buff);
SetColor(menu_color.b_text,menu_color.b_background );
Fill(border_x,border_y,border_width,border_height, 32);
Box(border_x,border_y,border_width,border_height,d efault_border);
SetColor(menu_color.s_text,menu_color.s_background );
SetColor(menu_color.s_text,menu_color.s_background );
Fill(border_x+border_width,border_y+1,2,border_hei ght,32);
Fill(border_x+1,border_y+border_height,border_widt h,1,32);
loop_flag=TRUE;
while(loop_flag){
SetColor(menu_color.b_text,menu_color.b_background );
for(i=0;i<pmenu->max;i++){
ppad=GotoPopupPad(pmenu,i+i_start);
SetColor(menu_color.text,menu_color.background);
PutString(pad_x,pad_y+i,ppad->prompt);
len=StrLen(ppad->prompt);
Fill(pad_x+len,pad_y+i,border_width-len-2,1,' ');
}
SetColor(menu_color.b_text,menu_color.b_background );
border_mid_x=border_width/2+border_x;
PutChar(border_mid_x,border_y,default_border[1]);
PutChar(border_mid_x,border_y+border_height-1,default_border[5]);
if(i_start>1) PutChar(border_mid_x,border_y,30);
if(i_start<i_end) PutChar(border_mid_x,border_y+border_height-1,31);
SetColor(menu_color.a_text,menu_color.a_background );
ppad=GotoPopupPad(pmenu,act+i_start-1);
PutString(pmenu->x+1,pmenu->y+act,ppad->prompt);
pmenu->act=act+i_start-1;
OnPopupPad(pmenu->name,pmenu->act);
key=GetKey();
switch(key){
case UP :act--;break;
case DOWN:act++;break;
case LEFT:loop_flag=FALSE;break;
case RIGHT:loop_flag=FALSE;break;
case ESC:loop_flag=FALSE;break;
case ENT:loop_flag=FALSE;break;
}
if(act<1){
act=1;i_start--;
}
if(act>pmenu->max){
act=pmenu->max;i_start++;
}
if(i_start<1){
i_start=i_end;
act=pmenu->max;
}
if(i_start>i_end){
i_start=1;
act=1;
}
}
LoadScreen(border_x,border_y,border_width+2,border _height+1,buff);
if(key==ENT)OnSelectPopup(pmenu->name,pmenu->act);
}else return FALSE;
return OK;
}
//************************************************** ************************
class menu_test:public menu{
public:
void OnPopupPad(char *popup_name,int act){
gotoxy(35,25);
printf("%15s %d",popup_name,act);
}
void OnBarPad(char *bar_name,int act){
gotoxy(20,25);
printf("%10s %d",bar_name,act);
}
void OnSelectBar(char *bar_name,int act){
gotoxy(10,19);
printf("%10s %d",bar_name, act);
}
void OnSelectPopup(char *popup_name,int act){
gotoxy(10,19);
printf("%10s %d",popup_name, act);
GetKey();
}
void run(void)
{
SetColor(1,7);
Fill(0,0,80,25,'±');
Fill(0,24,80,25,' ');
HideCursor();
DefineBar("main",2,0);
DefineBarPad("main"," File ","file");
DefineBarPad("main"," Edit ","edit");
DefineBarPad("main"," Search ","search");
DefineBarPad("main"," Run ","run");
DefineBarPad("main"," Compile ","compile");
DefineBarPad("main"," Help ","help");
DefinePopup("file",1,1);
DefinePopupPad("file"," New ");
DefinePopupPad("file"," Open ");
DefinePopupPad("file"," Save ");
DefinePopupPad("file"," Save As ");
DefinePopupPad("file"," Change Dir ");
DefinePopupPad("file"," Print ");
DefinePopupPad("file"," OS Shell ");
DefinePopupPad("file"," Exit ");
DefinePopup("edit",8,1);
DefinePopupPad("edit"," Cut ");
DefinePopupPad("edit"," Copy ");
DefinePopupPad("edit"," Past ");
DefinePopupPad("edit"," Clear ");
DefinePopup("search",15,1);
DefinePopupPad("search"," Find ");
DefinePopupPad("search"," Replace ");
DefinePopupPad("search"," Search ");
DefinePopupPad("search"," Go to Line Number ");
DefinePopup("run",24,1);
DefinePopupPad("run"," Run ");
DefinePopupPad("run"," Trace Into ");
DefinePopupPad("run"," Step Over ");
DefinePopupPad("run"," Argoments ... ");
DefinePopup("compile",30,1);
DefinePopupPad("compile"," Compile ");
DefinePopupPad("compile"," Make ");
DefinePopupPad("compile"," Link ");
DefinePopupPad("compile"," Build All ");
DefinePopup("help",39,1);
DefinePopupPad("help"," Contents ");
DefinePopupPad("help"," Index ");
DefinePopupPad("help"," About ");
ActivateBar("main");
ShowCursor();
CLS();
}
};
void main()
{
menu_test test;
test.run();
}
میخوام سورس منوهای دینامیک رو با C++ براتون بزارم.
امید وارم لذت ببرید.
با تشکر
ar.constantine@yahoo.com
:5:
/*
dynamic menu with C++
This program must be run under BC v3.0 or higher version
*/
#include<conio.h>
#include<dos.h>
#include<stdio.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define FAIL 0
#define ENT 0x000d
#define ESC 0x001b
#define UP 0x4800
#define DOWN 0x5000
#define LEFT 0x4b00
#define RIGHT 0x4d00
/*
This menu system designed for CGA/EGA/VGA adapter,monochrom is not
supported
*/
class base{
public:
int StrLen(char*);
void StrCopy(char*,char*);
int StrCmp(char*,char*);
};
//----------------------------------------------------------------------
int base::StrLen(char *s)
{
int i;
i=0;
while(*s++)i++;
return i;
}
//---------------------------------------------------------------------
void base::StrCopy(char *dest,char *src)
{
while(*src)*dest++=*src++;
*dest=*src;
}
//---------------------------------------------------------------------
int base::StrCmp(char *dest,char *src)
{
do{
if(*src++!=*dest++)return TRUE;
}while(*src&&*dest);
return FALSE;
}
//************************************************** *******************
class screen:public base{
private:
unsigned char TextAttribute,current_x,current_y;
public:
unsigned int last_pressed_key;
screen(void);
unsigned int GetKey(void);
void SetColor(char,char);
void SetTColor(char);
void SetBColor(char);
void SetVideoMode(char);
void CLS(void);
int ReadChar(int,int);
void PutChar(int,int,char);
void PutString(int,int,char*);
void Locate(char,char);
void SetCursor(char,char);
void HideCursor(void);
void ShowCursor(void);
void Fill(char,char,char,char,char);
void Box(int,int,int,int,char*);
void SaveScreen(int,int,int,int,int*);
void LoadScreen(int,int,int,int,int*);
};
//--------------------------------------------------------------
screen::screen(void)
{
TextAttribute=14;
current_x=0;
current_y=0;
}
//--------------------------------------------------------------
unsigned int screen::GetKey(void)
{
unsigned int key;
if(!(key=getch()))key=getch()<<8;
last_pressed_key=key;
return key;
}
//--------------------------------------------------------------
void screen::SetColor(char tcolor,char bcolor)
{
TextAttribute=bcolor<<4|tcolor;
}
//--------------------------------------------------------------
void screen::SetTColor(char text)
{
TextAttribute=(TextAttribute&0xf0)|text;
}
//--------------------------------------------------------------
void screen::SetBColor(char text)
{
TextAttribute=(TextAttribute&0x0f)|text<<4;
}
//--------------------------------------------------------------
void screen::SetVideoMode(char mode)
{
asm{
mov ah,0
mov al,mode
int 0x10
}
}
//--------------------------------------------------------------
void screen::CLS(void)
{
SetVideoMode(3);
}
//--------------------------------------------------------------
int screen::ReadChar(int x, int y)
{
int attrib;
asm{
mov ax,0xb800
mov es,ax
mov ax,y
mov bl,160
mul bl
mov bx,x
shl bx,1
add bx,ax
mov ax,es:[bx]
mov attrib,ax
}
return attrib;
}
//--------------------------------------------------------------
void WriteChar(int x,int y ,int char_attrib)
{
asm{
mov ax,0xb800
mov es,ax
mov ax,y
mov bl,160
mul bl
mov bx,x
shl bx,1
add bx,ax
mov cx,char_attrib
mov es:[bx],cx
}
}
//--------------------------------------------------------------
void screen::Locate(char x,char y)
{
char xx,yy;
asm{
mov ah,2
mov bh,0
mov dl,x
mov dh,y
int 0x10
mov xx,dl
mov yy,dh
}
current_x=xx;
current_y=yy;
}
//--------------------------------------------------------------
void screen::PutChar(int x,int y,char chr)
{
WriteChar(x,y,(unsigned char)chr|(TextAttribute<<8));
}
//--------------------------------------------------------------
void screen::PutString(int x,int y,char *s)
{
while(*s)PutChar(x++,y,*s++);
Locate(x,y);
}
//--------------------------------------------------------------
void screen::SetCursor(char start,char end)
{
asm{
mov ah,1
mov ch,start
mov cl,end
int 0x10
}
}
//--------------------------------------------------------------
void screen::HideCursor(void)
{
SetCursor(1,0);
}
//--------------------------------------------------------------
void screen::ShowCursor(void)
{
SetCursor(4,5);
}
//--------------------------------------------------------------
void screen::Fill(char x1,char y1,char width,char height,char chr)
{
char i,j,x2,y2;
x2=x1+width-1;
y2=y1+height-1;
for(j=y1;j<=y2;j++)
for(i=x1;i<=x2;i++)
PutChar(i,j,chr);
}
//--------------------------------------------------------------
void screen::Box(int x1,int y1,int width,int height,char *pattern)
{
int i,j,x2,y2;
x2=x1+width-1;
y2=y1+height-1;
for(i=x1;i<x2;i++)
{
PutChar(i,y1,pattern[1]);
PutChar(i,y2,pattern[5]);
}
for(j=y1;j<y2;j++)
{
PutChar(x1,j,pattern[7]);
PutChar(x2,j,pattern[3]);
}
PutChar(x1,y1,pattern[0]);
PutChar(x2,y1,pattern[2]);
PutChar(x2,y2,pattern[4]);
PutChar(x1,y2,pattern[6]);
}
//--------------------------------------------------------------
void screen::SaveScreen(int x1,int y1,int width,int height,int *buff)
{
int i,j,x2,y2;
x2=x1+width-1;
y2=y1+height-1;
for(j=y1;j<=y2;j++)
for(i=x1;i<=x2;i++)
*buff++=ReadChar(i,j);
}
//--------------------------------------------------------------
void screen::LoadScreen(int x1,int y1,int width,int height,int *buff)
{
int i,j,x2,y2;
x2=x1+width-1;
y2=y1+height-1;
for(j=y1;j<=y2;j++)
for(i=x1;i<=x2;i++)
WriteChar(i,j,*buff++);
}
//************************************************** ********************
struct bar_pad{
char *prompt;
char *popup_name;
struct bar_pad *next;
};
struct popup_pad{
char *prompt;
struct popup_pad *next;
};
struct bar_menu{
char *name;
int x,y,count,act;
struct bar_pad *pad;
struct bar_menu *next;
};
struct popup_menu{
char *name;
int x,y,count,act,max;
struct popup_pad *pad;
struct popup_menu *next;
};
class menu:public screen{
protected:
struct{
char text,background,
a_text,a_background,
b_text,b_background,
s_text,s_background;
}menu_color;
struct bar_menu *bar;
struct popup_menu *popup;
char default_border[8];
char *current_popup_name;
char *current_bar_name;
void AddBarPad(struct bar_menu*,char*,char*);
struct bar_pad* GotoBarPad(struct bar_menu*,int);
void DeleteBarPads(struct bar_menu*);
struct bar_menu* GotoBar(char*);
void AddPopupPad(struct popup_menu*,char*);
struct popup_pad *GotoPopupPad(struct popup_menu*,int);
void DeletePopupPads(struct popup_menu*);
struct popup_menu *GotoPopup(char*);
public:
menu(void);
~menu(void);
void DefineBar(char*,int,int);
void DefineBarPad(char*,char*,char*);
void DeleteBars(void);
void DefinePopup(char*,int,int);
void DefinePopupPad(char*,char*);
void DeletePopups(void);
char ActivateBar(char*);
char ActivatePopup(char*);
virtual void OnPopupPad(char*,int){};
virtual void OnBarPad(char*,int){};
virtual void OnSelectBar(char*,int){};
virtual void OnSelectPopup(char*,int){};
};
menu::menu(void)
{
bar=NULL;
popup=NULL;
current_bar_name=NULL;
current_popup_name=NULL;
menu_color.text=BLACK;
menu_color.background=LIGHTGRAY;
menu_color.a_text=WHITE;
menu_color.a_background=RED;
menu_color.b_text=BLACK;
menu_color.b_background=LIGHTGRAY;
menu_color.s_text=BLACK;
menu_color.s_background=BLACK;
default_border[0]='Ú';
default_border[1]='Ä';
default_border[2]='·';
default_border[3]='º';
default_border[4]='¼';
default_border[5]='Í';
default_border[6]='Ô';
default_border[7]='³';
}
menu::~menu(void)
{
DeleteBars();
DeletePopups();
}
void menu::AddBarPad(struct bar_menu *bm,char *prompt,char
*popup_name){
struct bar_pad *p,*tmp;
p=new bar_pad;
p->prompt=new char[StrLen(prompt)+1];
p->popup_name=new char[StrLen(popup_name)+1];
StrCopy(p->prompt,prompt);
StrCopy(p->popup_name,popup_name);
p->next=NULL;
if(bm->pad==NULL){
bm->pad=p;
bm->count=1;
}else{
tmp=bm->pad;
while(tmp->next)tmp=tmp->next;
tmp->next=p;
bm->count++;
}
}
struct bar_pad* menu::GotoBarPad(struct bar_menu *bm,int n){
struct bar_pad *p;
int i;
p=bm->pad;
for(i=1;i<n;i++)p=p->next;
return p;
}
void menu::DeleteBarPads(struct bar_menu *bm){
struct bar_pad *tmp;
while(bm->pad){
tmp=bm->pad;
bm->pad=tmp->next;
delete[] tmp->prompt;
delete[] tmp->popup_name;
delete tmp;
}
bm->count=0;
}
void menu::DefineBar(char *name,int x,int y){
struct bar_menu *p,*tmp;
p=new bar_menu;
p->name=new char[StrLen(name)+1];
StrCopy(p->name,name);
p->x=x;
p->y=y;
p->count=p->act=0;
p->pad=NULL;
p->next=NULL;
if(bar==NULL)bar=p;
else{
tmp=bar;
while(tmp->next)tmp=tmp->next;
tmp->next=p;
}
}
struct bar_menu* menu::GotoBar(char *name){
struct bar_menu *p;
p=bar;
while(p){
if(!StrCmp(p->name,name))return p;
p=p->next;
}
return NULL;
}
void menu::DefineBarPad(char *name,char *prompt,char *popup_name){
struct bar_menu *p;
p=GotoBar(name);
if(p)AddBarPad(p,prompt,popup_name);
}
void menu::DeleteBars(void){
struct bar_menu *tmp;
while(bar){
tmp=bar;
bar=tmp->next;
DeleteBarPads(tmp);
delete tmp;
}
}
void menu::AddPopupPad(struct popup_menu *pm,char *prompt){
struct popup_pad *p,*tmp;
p=new popup_pad;
p->prompt=new char[StrLen(prompt)+1];
StrCopy(p->prompt,prompt);
p->next=NULL;
if(pm->pad==NULL){
pm->pad=p;
pm->count=1;
}else{
tmp=pm->pad;
while(tmp->next)tmp=tmp->next;
tmp->next=p;
pm->count++;
}
}
void menu::DeletePopupPads(struct popup_menu *pm){
struct popup_pad *tmp;
while(pm->pad){
tmp=pm->pad;
pm->pad=tmp->next;
delete[] tmp->prompt;
delete tmp;
}
pm->count=0;
if(current_bar_name){
delete[] current_bar_name;
current_bar_name=NULL;
}
}
struct popup_pad* menu::GotoPopupPad(struct popup_menu *pm,int n){
struct popup_pad *p;
int i;
p=pm->pad;
for(i=1;i<n;i++)p=p->next;
return p;
}
void menu::DefinePopup(char *name,int x,int y){
struct popup_menu *p,*tmp;
p=new popup_menu;
p->name=new char[StrLen(name)+1];
StrCopy(p->name,name);
p->x=x;
p->y=y;
p->count=0;
p->act=1;
p->max=5;
p->pad=NULL;
p->next=NULL;
if(popup==NULL)popup=p;
else{
tmp=popup;
while(tmp->next)tmp=tmp->next;
tmp->next=p;
}
}
struct popup_menu* menu::GotoPopup(char *name){
struct popup_menu *p;
p=popup;
while(p){
if(!StrCmp(p->name,name))return p;
p=p->next;
}
return NULL;
}
void menu::DefinePopupPad(char *name,char *prompt){
struct popup_menu *p;
p=GotoPopup(name);
if(p) AddPopupPad(p,prompt);
}
void menu::DeletePopups(void){
struct popup_menu *tmp;
while(popup){
tmp=popup;
popup=tmp->next;
DeletePopupPads(tmp);
delete tmp;
}
if(current_popup_name){
delete[] current_popup_name;
current_popup_name=NULL;
}
}
char menu::ActivateBar(char *name)
{
struct bar_menu *bmenu;
struct bar_pad *bpad;
int i,l,act;
unsigned int key;
bmenu=GotoBar(name);
if(bmenu&&bmenu->count){
if(current_bar_name)delete[] current_bar_name;
current_bar_name=new char[StrLen(name+1)];
StrCopy(current_bar_name,name);
key=0;
bmenu->act=1;
SetColor(menu_color.text,menu_color.background);
Fill(0,bmenu->y,80,1,' ');
while(key!=ESC&&bmenu->count){
l=0;
for(i=1;i<=bmenu->count;i++){
bpad=GotoBarPad(bmenu,i);
SetColor(menu_color.text,menu_color.background);
PutString(bmenu->x+l,bmenu->y,bpad->prompt);
l+=StrLen(bpad->prompt);
}
l=0;
for(i=1;i<=bmenu->act;i++){
bpad=GotoBarPad(bmenu,i);
if(i<bmenu->act)l+=StrLen(bpad->prompt);
}
SetColor(menu_color.a_text,menu_color.a_background );
PutString(bmenu->x+l,bmenu->y,bpad->prompt);
OnBarPad(bmenu->name,bmenu->act);
if(ActivatePopup(bpad->popup_name)) key=last_pressed_key;
else key=GetKey();
switch(key){
case LEFT:bmenu->act--;break;
case RIGHT:bmenu->act++;break;
}
if(bmenu->act<1)bmenu->act=bmenu->count;
if(bmenu->act>bmenu->count)bmenu->act=1;
}
}else return FAIL;
return OK;
}
char menu::ActivatePopup(char *name){
struct popup_menu *pmenu;
struct popup_pad *ppad;
int i,len,act;
char rotate_flag,loop_flag;
int
i_start,i_end,border_x,border_y,border_width,borde r_mid_x,border_height;
int pad_x,pad_y;
int buff[80*25];
unsigned int key;
pmenu=GotoPopup(name);
if(pmenu&&pmenu->count){
if(current_popup_name)delete[] current_popup_name;
current_popup_name=new char[StrLen(name+1)];
StrCopy(current_popup_name,name);
if(pmenu->max>pmenu->count)pmenu->max=pmenu->count;
i_start=1;
i_end=pmenu->count-pmenu->max+1;
if(pmenu->act>pmenu->max){
act=pmenu->max;
i_start=pmenu->act-pmenu->max+1;
}else act=pmenu->act;
border_width=0;
for(i=1;i<=pmenu->count;i++){
ppad=GotoPopupPad(pmenu,i);
len=StrLen(ppad->prompt);
if(len>border_width)border_width=len;//detect max width
}
border_x=pmenu->x;
border_y=pmenu->y;
border_width+=2;
border_height=pmenu->max+2;
pad_x=border_x+1;
pad_y=border_y+1;
key=0;
SaveScreen(border_x,border_y,border_width+2,border _height+1,buff);
SetColor(menu_color.b_text,menu_color.b_background );
Fill(border_x,border_y,border_width,border_height, 32);
Box(border_x,border_y,border_width,border_height,d efault_border);
SetColor(menu_color.s_text,menu_color.s_background );
SetColor(menu_color.s_text,menu_color.s_background );
Fill(border_x+border_width,border_y+1,2,border_hei ght,32);
Fill(border_x+1,border_y+border_height,border_widt h,1,32);
loop_flag=TRUE;
while(loop_flag){
SetColor(menu_color.b_text,menu_color.b_background );
for(i=0;i<pmenu->max;i++){
ppad=GotoPopupPad(pmenu,i+i_start);
SetColor(menu_color.text,menu_color.background);
PutString(pad_x,pad_y+i,ppad->prompt);
len=StrLen(ppad->prompt);
Fill(pad_x+len,pad_y+i,border_width-len-2,1,' ');
}
SetColor(menu_color.b_text,menu_color.b_background );
border_mid_x=border_width/2+border_x;
PutChar(border_mid_x,border_y,default_border[1]);
PutChar(border_mid_x,border_y+border_height-1,default_border[5]);
if(i_start>1) PutChar(border_mid_x,border_y,30);
if(i_start<i_end) PutChar(border_mid_x,border_y+border_height-1,31);
SetColor(menu_color.a_text,menu_color.a_background );
ppad=GotoPopupPad(pmenu,act+i_start-1);
PutString(pmenu->x+1,pmenu->y+act,ppad->prompt);
pmenu->act=act+i_start-1;
OnPopupPad(pmenu->name,pmenu->act);
key=GetKey();
switch(key){
case UP :act--;break;
case DOWN:act++;break;
case LEFT:loop_flag=FALSE;break;
case RIGHT:loop_flag=FALSE;break;
case ESC:loop_flag=FALSE;break;
case ENT:loop_flag=FALSE;break;
}
if(act<1){
act=1;i_start--;
}
if(act>pmenu->max){
act=pmenu->max;i_start++;
}
if(i_start<1){
i_start=i_end;
act=pmenu->max;
}
if(i_start>i_end){
i_start=1;
act=1;
}
}
LoadScreen(border_x,border_y,border_width+2,border _height+1,buff);
if(key==ENT)OnSelectPopup(pmenu->name,pmenu->act);
}else return FALSE;
return OK;
}
//************************************************** ************************
class menu_test:public menu{
public:
void OnPopupPad(char *popup_name,int act){
gotoxy(35,25);
printf("%15s %d",popup_name,act);
}
void OnBarPad(char *bar_name,int act){
gotoxy(20,25);
printf("%10s %d",bar_name,act);
}
void OnSelectBar(char *bar_name,int act){
gotoxy(10,19);
printf("%10s %d",bar_name, act);
}
void OnSelectPopup(char *popup_name,int act){
gotoxy(10,19);
printf("%10s %d",popup_name, act);
GetKey();
}
void run(void)
{
SetColor(1,7);
Fill(0,0,80,25,'±');
Fill(0,24,80,25,' ');
HideCursor();
DefineBar("main",2,0);
DefineBarPad("main"," File ","file");
DefineBarPad("main"," Edit ","edit");
DefineBarPad("main"," Search ","search");
DefineBarPad("main"," Run ","run");
DefineBarPad("main"," Compile ","compile");
DefineBarPad("main"," Help ","help");
DefinePopup("file",1,1);
DefinePopupPad("file"," New ");
DefinePopupPad("file"," Open ");
DefinePopupPad("file"," Save ");
DefinePopupPad("file"," Save As ");
DefinePopupPad("file"," Change Dir ");
DefinePopupPad("file"," Print ");
DefinePopupPad("file"," OS Shell ");
DefinePopupPad("file"," Exit ");
DefinePopup("edit",8,1);
DefinePopupPad("edit"," Cut ");
DefinePopupPad("edit"," Copy ");
DefinePopupPad("edit"," Past ");
DefinePopupPad("edit"," Clear ");
DefinePopup("search",15,1);
DefinePopupPad("search"," Find ");
DefinePopupPad("search"," Replace ");
DefinePopupPad("search"," Search ");
DefinePopupPad("search"," Go to Line Number ");
DefinePopup("run",24,1);
DefinePopupPad("run"," Run ");
DefinePopupPad("run"," Trace Into ");
DefinePopupPad("run"," Step Over ");
DefinePopupPad("run"," Argoments ... ");
DefinePopup("compile",30,1);
DefinePopupPad("compile"," Compile ");
DefinePopupPad("compile"," Make ");
DefinePopupPad("compile"," Link ");
DefinePopupPad("compile"," Build All ");
DefinePopup("help",39,1);
DefinePopupPad("help"," Contents ");
DefinePopupPad("help"," Index ");
DefinePopupPad("help"," About ");
ActivateBar("main");
ShowCursor();
CLS();
}
};
void main()
{
menu_test test;
test.run();
}