// ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» // º NPSGUI.LIB º // º Copyright 93-94, Nearly Perfect Software. Ç¿ // º All Rights Reserved º³ // º þ Written by Brad Broerman º³ // º þ Last Modified: 04/08/94 º³ // º þ Revision 2.5 º³ // ÈÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ³ // ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ #include <stdio.h> #include <iostream.h> #include <fstream.h> #include <stdlib.h> #include <conio.h> #include <string.h> #include <io.h> #include <dos.h> #include <malloc.h> #include <fcntl.h> #include <math.h> #include <time.h> #include <sys\types.h> #include "npsgui.h" #include "emmlib.h" extern gmouse mouse; // Your instance of gmouse MUST be called mouse!!! extern int directvideo=1; // Used for faster output. struct Event { // This structure is the Event Queue Node. int X,Y; // The location of the event. int Btns; // The button status: bit 1 = left, bit2 = right. }; Event EventQueue[50]; // An array of 50 events. This is a circular queue. int EventSize = 0, // The Size of the queue. EventHead = 0, // The offset of the head and tail nodes. EventTail = 0; // This is the standard PCX header. typedef struct { char manufacturer; char version; char encoding; char bits_per_pixel; int xmin, ymin; int xmax, ymax; int hres; int vres; unsigned char palette[48]; char reserved; char color_planes; int bytes_per_line; int palette_type; char filler[58]; } PCXHDR; // Data for mouse cursor shapes below. They consist of 2 16x16 bitmaps. The // first one is AND'ed with the background to produce a 'hole', and the second // one is OR'ed with that to produce the cursor shape. static unsigned int arrowptr [32]={0xFFFF,0x8FFF,0x8FFF,0x87FF,0x83FF,0x81FF,0x80FF,0x807F, 0x803F,0x801F,0x800F,0x801F,0x807F,0x887F,0xDC3F,0xFC3F, 0x0000,0x0000,0x2000,0x3000,0x3800,0x3C00,0x3E00,0x3F00, 0x3F80,0x3FC0,0x3FE0,0x3E00,0x3300,0x2300,0x0180,0x0180}; static unsigned int uparrow [32] ={0xF9FF,0xF0FF,0xE07F,0xE07F,0xC03F,0xC03F,0x801F,0x801F, 0x000F,0x000F,0xF0FF,0xF0FF,0xF0FF,0xF0FF,0xF0FF,0xF0FF, 0x0000,0x0600,0x0F00,0x0F00,0x1F80,0x1F80,0x3FC0,0x3FC0, 0x7FE0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600}; static unsigned int lftarrow [32]={0xFE1F,0xF01F,0x0000,0x0000,0x0000,0xF01F,0xFE1F,0xFFFF, 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF, 0x0000,0x00C0,0x07C0,0x7FFE,0x07C0,0x00C0,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; static unsigned int chekmark [32]={0xFFF0,0xFFE0,0xFFC0,0xFF81,0xFF03,0x0607,0x000F,0x001F, 0xC03F,0xF07F,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF, 0x0000,0x0006,0x000C,0x0018,0x0030,0x0060,0x70C0,0x1D80, 0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; static unsigned int pointhand[32]={0xE1FF,0xE1FF,0xE1FF,0xE1FF,0xE1FF,0xE000,0xE000,0xE000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x1E00,0x1200,0x1200,0x1200,0x1200,0x13FF,0x1249,0x1249, 0xF249,0x9001,0x9001,0x9001,0x9002,0x8001,0x8001,0xFFFF}; static unsigned int hourglass[32]={0x0000,0x0000,0x0000,0x0000,0x8001,0xC003,0xE007,0xF00F, 0xE007,0xC003,0x8001,0x0000,0x0000,0x0000,0x0000,0xFFFF, 0x0000,0x7FFE,0x6006,0x300C,0x1818,0x0C30,0x0660,0x03C0, 0x0660,0x0C30,0x1998,0x33CC,0x67E6,0x7FFE,0x0000,0x0000}; // The Screen Class. This class sets up BGI graphics in a VGA mode. screen::screen(int mode) { init(mode); } void screen::init(int mode) { int errorcode; registerfarbgidriver(EGAVGA_driver_far); gdriver = VGA; errorcode = graphresult(); if (errorcode != grOk) /* an error occurred */ { cerr << "Graphics load error: "<<grapherrormsg(errorcode)<<endl; cerr << "Press any key to halt:"; getkey(); exit(1); /* terminate with an error code */ } gmode=mode; initgraph( &gdriver , &gmode, ""); errorcode = graphresult(); if (errorcode != grOk) /* an error occurred */ { cerr << "Graphics init error: "<<grapherrormsg(errorcode)<<endl; cerr << "Press any key to halt:"; getkey(); exit(1); /* terminate with an error code */ } directvideo=1; mouse.init(); } screen::~screen() { close(); } void screen::close() { mouse.hide(); closegraph(); mouse.init(); } // The GBase Class. This is the basis for all the graphic objects. gbase::gbase(int x, int y, int w, int h, int k) { BackBuffer = NULL; BkgPages = 0; BkgHndl = 0; X=x; Y=y; Height=h; Width=w; KeepBkg=k; isShown=0; } gbase::~gbase() { if (BackBuffer) { if (BkgPages) emm_free(BkgHndl); else farfree (BackBuffer); } } void gbase::ReSize(int w, int h) { if (isShown) { hide(); Width = w; Height = h; show(); } else { Width = w; Height = h; } } void gbase::getbkg() { size_t size; unsigned int L_P_P, offset; int i; if ((!KeepBkg) || (isShown)) return; if (BackBuffer) { if (BkgPages) emm_free (BkgHndl); else farfree(BackBuffer); BackBuffer = NULL; BkgHndl = 0; } size = imagesize(X, Y, X+Width-1, Y+Height-1); L_P_P = ((16 * 1024) - 8)/ Width; BkgPages = ceil((float)Height / (float)L_P_P); if ((emm_type()) && (emm_pgsleft() >= BkgPages) && ((BkgHndl = emm_maloc(BkgPages)) != 0)) { for (offset = 0,i = 0;offset < Height; ++i, offset += L_P_P) { BackBuffer = emm_map(BkgHndl,1,i); if (!BackBuffer) { closegraph(); cerr<<"Error allocating memory for background."<<endl; exit(1); } if ((offset+L_P_P) < Height) getimage(X,Y+offset,X+Width-1,Y+offset+L_P_P-1,BackBuffer); else getimage(X,Y+offset,X+Width-1,Y+Height-1,BackBuffer); } } else { BkgPages = 0; if (!(BackBuffer = (char far *)farmalloc(size))) { closegraph(); cerr<<"Error allocating memory for background."<<endl; exit(1); } getimage (X,Y,X+Width-1,Y+Height-1,BackBuffer); } } void gbase::hide() { int i, offset, L_P_P; if (isShown) { mouse.hide(); L_P_P = ((16 * 1024) - 8)/ Width; if (BackBuffer) { if (BkgPages) { for (offset = 0,i = 0;i < BkgPages; ++i, offset += L_P_P) { BackBuffer = emm_map(BkgHndl,1,i); if (BackBuffer) putimage(X,Y+offset,BackBuffer,COPY_PUT); } } else putimage (X,Y,BackBuffer,COPY_PUT); } if (BackBuffer) { if (BkgPages) emm_free (BkgHndl); else farfree(BackBuffer); BackBuffer = NULL; BkgHndl = 0; } isShown=0; mouse.show(); } } int gbase::hit() { if (isShown) if ((mouse.getmX() >=X) && (mouse.getmX() <= X+Width-1)) if ((mouse.getmY() >=Y) && (mouse.getmY() <= Y+Height-1)) return(1); return (0); } void gbase::moveto(int x, int y) { if (isShown) { hide(); X=x; Y=y; show(); } else { X=x; Y=y; } } bitmap::bitmap(int x, int y,int mode, char *fname, int k):gbase(x,y,0,0,k) { ImageSize = 0; Buffer = NULL; load(fname,mode); } bitmap::~bitmap() { hide(); if (Buffer) free(Buffer); } int ReadPcxLine(char *pointer, long count , ifstream &F) { char byte; int run, index = 0; memset(pointer,0,count); while(index < count) { F.get(byte); if ((byte & 0xc0) == 0xc0) { run = byte & 0x3f; F.get(byte); while (run--) pointer[index++] = (char)byte; } else pointer[index++] = byte; } return index; } char bitmap::get_imgpxl(int x, int y) { // Gets the color value for a pixel in an image buffer. unsigned int offset, bytes_per_line; char mask, retval; bytes_per_line = (Width+7)/8; offset = (y*bytes_per_line*4)+x/8; mask = 0x01 << (x%8); retval = 0; if (*(Buffer+offset+4) & mask) retval |= 0x08; if (*(Buffer+offset+4+bytes_per_line) & mask) retval |= 0x04; if (*(Buffer+offset+4+bytes_per_line*2) & mask) retval |= 0x02; if (*(Buffer+offset+4+bytes_per_line*3) & mask) retval |= 0x01; return retval; } void bitmap::put_imgpxl(int x, int y, char color) { // Places a pixel of the appropriate color at x,y in the buffer. unsigned int offset, bytes_per_line; char mask; bytes_per_line = (Width+7)/8; offset = (y*bytes_per_line*4)+x/8+4; mask = 0x01 << (x%8); if (color & 0x08) *(Buffer+offset) |= mask; else *(Buffer+offset) &= ~mask; if (color & 0x04) *(Buffer+offset+bytes_per_line) |= mask; else *(Buffer+offset+bytes_per_line) &= ~mask; if (color & 0x02) *(Buffer+offset+bytes_per_line*2) |= mask; else *(Buffer+offset+bytes_per_line*2) &= ~mask; if (color & 0x01) *(Buffer+offset+bytes_per_line*3) |= mask; else *(Buffer+offset+bytes_per_line*3) &= ~mask; } void bitmap::load(char *fname, int mode) { PCXHDR header; RGBPAL cur_pal; struct palettetype EGA_Palette; int Palette_Map[16]={0,4,2,6,1,5,3,8,7,12,10,14,9,13,11,15}, min_indx, pcx_entry, n, i, j; unsigned int gw, gh, bytes; long FE; unsigned long dist, min_dist; ifstream F(fname,ios::binary); if (!F) { Buffer = NULL; Width = Height = 0; return; } if (mode == 0) // Load a npg file. { F.seekg(0,istream::end); FE = F.tellg(); F.seekg(0,istream::beg); ImageSize = FE-F.tellg()+1; F.close(); if (Buffer) free (Buffer); Buffer = (char far*)farmalloc(ImageSize); if (!Buffer) { closegraph(); cerr<<"Memory allocation error while loading graphic image."<<endl; exit(1); } F.open(fname,ios::binary); F.read (Buffer,ImageSize); F.close(); gw=*(Buffer+1)*256+*(Buffer); gh=*(Buffer+3)*256+*(Buffer+2); Height = gh+1; Width = gw+1; } else if (mode == 1) // Load a pcx file. { F.seekg(0,istream::beg); F.read((char *)&header, sizeof(header)); // lets make sure it's a valid 16 color PCX file... if ((header.manufacturer != 0x0A) || (header.encoding != 1) || (header.bits_per_pixel != 1) || (header.color_planes != 4)) { Buffer = NULL; Width = Height = 0; return; } Width = gw = header.xmax-header.xmin+1; Height = gh = header.ymax-header.ymin+1; bytes = header.bytes_per_line; ImageSize = 4+gh*bytes*header.color_planes; Buffer = (char far*)farmalloc(ImageSize); if (!Buffer) { closegraph(); F.close(); cerr<<"Memory allocation error while loading graphic image."<<endl; exit(1); } Buffer[0] = (char)(gw-1); Buffer[1] = (char)((gw-1) >> 8); Buffer[2] = (char)(gh-1); Buffer[3] = (char)((gh-1) >> 8); for (i=0, n=0; i < gh; ++i) { j=header.color_planes; ReadPcxLine(Buffer+4+(bytes*(n + --j)), bytes, F); ReadPcxLine(Buffer+4+(bytes*(n + --j)), bytes, F); ReadPcxLine(Buffer+4+(bytes*(n + --j)), bytes, F); ReadPcxLine(Buffer+4+(bytes*(n + --j)), bytes, F); n += header.color_planes; } F.close(); // Now that the image is in memory, we need to map it's colors over. for (i=0; i < (bytes*8); ++i) for (n=0; n < Height; ++n) put_imgpxl(i,n,Palette_Map[get_imgpxl(i,n)]); } } void bitmap::show() { if (!Buffer) return; mouse.hide(); getbkg(); putimage(X, Y, Buffer,COPY_PUT); isShown=1; mouse.show(); } int bitmap::getW() { return (Width); } int bitmap::getH() { return (Width); } panel::panel(int x,int y,int w,int h, int d, int io, int c, int k) :gbase(x-d,y-d,w+2*d,h+2*d,k) { Depth = d; InorOut=!(io == 0); Color=c; } panel::~panel() { } void panel::show () { unsigned int size; int top_left[14], btm_right[14], orig_color; struct fillsettingstype orig_settings; struct linesettingstype orig_line; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); setlinestyle(0,1,0); top_left[0]=X; top_left[1]=Y; top_left[2]=X+Width-1; top_left[3]=Y; top_left[4]=X+Width-Depth-1; top_left[5]=Y+Depth; top_left[6]=X+Depth; top_left[7]=Y+Depth; top_left[8]=X+Depth; top_left[9]=Y+Height-Depth-1; top_left[10]=X; top_left[11]=Y+Height-1; top_left[12]=X; top_left[13]=Y; btm_right[0]=X+Width-1; btm_right[1]=Y+Height-1; btm_right[2]=X+Width-1; btm_right[3]=Y+1; btm_right[4]=X+Width-Depth-1; btm_right[5]=Y+Depth+1; btm_right[6]=X+Width-Depth-1; btm_right[7]=Y+Height-Depth-1; btm_right[8]=X+Depth+1; btm_right[9]=Y+Height-Depth-1; btm_right[10]=X+1; btm_right[11]=Y+Height-1; btm_right[12]=X+Width-1;btm_right[13]=Y+Height-1; getbkg(); if (InorOut) { setcolor (Color+8); setfillstyle(SOLID_FILL,Color+8); fillpoly(7,top_left); setcolor (DARKGRAY); setfillstyle(SOLID_FILL,DARKGRAY); fillpoly(7,btm_right); } else { setcolor (DARKGRAY); setfillstyle(SOLID_FILL,DARKGRAY); fillpoly(7,top_left); setcolor (Color+8); setfillstyle(SOLID_FILL,Color+8); fillpoly(7,btm_right); } setcolor (Color); setfillstyle(SOLID_FILL,Color); bar(X+Depth,Y+Depth,X+Width-Depth-1,Y+Height-Depth-1); isShown=1; setcolor(orig_color); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); mouse.show(); } void panel::setbkgclr(int c) { Color = c; } void panel::resize(int w, int h) { ReSize(w+2*Depth,h+2*Depth); } void panel::moveto(int x, int y) { gbase::moveto(x-Depth,y-Depth); } bevel::bevel(int x, int y, int w, int h, int d, int bw, int c, int k) :panel(x-d-bw,y-d-bw,w+2*(bw+d),h+2*(bw+d),d,1,c,k) { inner = new panel(x,y,w,h,d,0,c,0); BWidth = bw; } bevel::~bevel() { delete inner; } void bevel::show () { panel::show(); inner->show(); } void bevel::resize(int w, int h) { if (isShown) { hide(); panel::resize(w+2*(BWidth+Depth),h+2*(BWidth+Depth)); inner->resize(w,h); show(); } else { panel::resize(w+2*(BWidth+Depth),h+2*(BWidth+Depth)); inner->resize(w,h); } } void bevel::moveto(int x, int y) { if (isShown) { hide(); panel::moveto(x-Depth-BWidth,y-Depth-BWidth); inner->moveto(x,y); show(); } else { panel::moveto(x-Depth-BWidth,y-Depth-BWidth); inner->moveto(x,y); } } button::button (int x, int y, int w, int h, int d, int c,int b,int m, char* strn, int k) : panel(x,y,w,h,d+b,OUT,c,k) { int slen; HkHiClr = TxtClr = WHITE; Mode=m; Border = b; if (Mode==0) { String = NULL; slen = strlen(strn); if (slen > 0) { String = (char *)calloc(1,slen+2); if (!String) { closegraph(); cerr<<"Memory allocation error in button setup."<<endl; exit(1); } strncpy(String,strn,slen); } } else { Bgraphic = new graphic(X+Depth,Y+Depth,0,m-1,strn); } } button::~button() { if (!Mode) free(String); else delete Bgraphic; } void button::setextclr(int clr) { TxtClr = clr; } void button::sethkhiclr(int clr) { HkHiClr = clr; } void button::show() { int top_left[14], btm_right[14], i, Tild, j, j2, orig_color; char temp[2] = " "; unsigned int gw, gh, size; struct fillsettingstype orig_settings; struct linesettingstype orig_line; struct textsettingstype textinfo; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); gettextsettings(&textinfo); setlinestyle(0,1,0); if (Mode==0) { if (String != NULL) { Tild = 0; for (i=0; *(char *)(String+i) != (char)0x00 ; ++i) if (*(char *)(String+i) == '~') ++ Tild; Tild *= textwidth("~"); if (textheight((char *)String)+2 > Height-2*Depth) Height=textheight((char *)String)+2*Depth+2; if (textwidth((char *)String)+2-Tild > Width-2*Depth) Width=textwidth((char *)String)+2*Depth+2-Tild; } } else { if (Bgraphic->getH() > Height-2*Depth) Height=Bgraphic->getH()+2*Depth; if (Bgraphic->getW() > Width-2*Depth) Width=Bgraphic->getW()+2*Depth; } panel::show(); setcolor(BLACK); for (i=1; i<Border+1 ; ++i) rectangle(X+i-1,Y+i-1,X+Width-i,Y+Height-i); if (!Mode) { setcolor (TxtClr); settextjustify(LEFT_TEXT,CENTER_TEXT); if (String != NULL) { for (j = 0, j2 = 0; (char)*(String+j) != (char)0x00 ;++j, ++ j2) { strncpy(temp,(char *)(String+j),1); if (*(char *)(String+j) == '~') { strncpy(temp,(char *)(String+(++j)),1); setcolor(HkHiClr); outtextxy(X+(Width/2)-((textwidth((char *)String)-Tild)/2)+j2*textwidth("A"), Y+(Height/2)+1,temp); setcolor(TxtClr); } else outtextxy(X+(Width/2)-((textwidth((char *)String)-Tild)/2)+j2*textwidth("A"), Y+(Height/2)+1,temp); } } } else { Bgraphic->moveto(X+(Width-Bgraphic->getW())/2,Y+(Height-Bgraphic->getW())/2); Bgraphic->show(); } Selected=0; settextjustify(textinfo.horiz,textinfo.vert); setcolor(orig_color); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); mouse.show(); } void button::select() { int top_left[14], btm_right[14], i, j, j2, Tild, orig_color; char temp[2] = " "; unsigned int gw, gh; struct fillsettingstype orig_settings; struct linesettingstype orig_line; struct textsettingstype textinfo; if (!isShown) return; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); gettextsettings(&textinfo); setlinestyle(0,1,0); top_left[0]=X; top_left[1]=Y; top_left[2]=X+Width-1; top_left[3]=Y; top_left[4]=X+Width-Depth-1; top_left[5]=Y+Depth; top_left[6]=X+Depth; top_left[7]=Y+Depth; top_left[8]=X+Depth; top_left[9]=Y+Height-Depth-1; top_left[10]=X; top_left[11]=Y+Height-1; top_left[12]=X; top_left[13]=Y; btm_right[0]=X+Width-1; btm_right[1]=Y+Height-1; btm_right[2]=X+Width-1; btm_right[3]=Y+1; btm_right[4]=X+Width-Depth-1; btm_right[5]=Y+Depth+1; btm_right[6]=X+Width-Depth-1; btm_right[7]=Y+Height-Depth-1; btm_right[8]=X+Depth+1; btm_right[9]=Y+Height-Depth-1; btm_right[10]=X+1; btm_right[11]=Y+Height-1; btm_right[12]=X+Width-1;btm_right[13]=Y+Height-1; setcolor (DARKGRAY); setfillstyle(SOLID_FILL,DARKGRAY); fillpoly(7,top_left); fillpoly(7,btm_right); setcolor (Color); setfillstyle(SOLID_FILL,Color); bar(X+Depth+1,Y+Depth+1,X+Width-Depth,Y+Height-Depth); setcolor(BLACK); for (i=1; i<Border+1 ; ++i) rectangle(X+i-1,Y+i-1,X+Width-i,Y+Height-i); if (!Mode) { if (String != NULL) { Tild = 0; for (i=0; *(char *)(String+i) != (char)0x00 ; ++i) if (*(char *)(String+i) == '~') ++ Tild; Tild *= textwidth("~"); setcolor(TxtClr); settextjustify(LEFT_TEXT,CENTER_TEXT); for (j = 0, j2 = 0; (char)*(String+j) != (char)0x00 ;++j, ++ j2) { strncpy(temp,(char *)(String+j),1); if (*(char *)(String+j) == '~') { strncpy(temp,(char *)(String+(++j)),1); setcolor(HkHiClr); outtextxy(X+(Width/2)-((textwidth((char *)String)-Tild)/2)+j2*textwidth("A")+1, Y+(Height/2)+2,temp); setcolor(TxtClr); } else outtextxy(X+(Width/2)-((textwidth((char *)String)-Tild)/2)+j2*textwidth("A")+1, Y+(Height/2)+2,temp); } } } else { Bgraphic->moveto(X+(Width-Bgraphic->getW())/2+1,Y+(Height-Bgraphic->getW())/2+1); Bgraphic->show(); } Selected=1; settextjustify(textinfo.horiz,textinfo.vert); setcolor(orig_color); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); mouse.show(); } int button::is_selected() { return (Selected); } void button::setborder(int b) { if ((b >= 0) && (b <= 5)) if (isShown) { if (is_selected()) { hide(); resize(Width-2*Depth-Border+b,Height-2*Depth-Border+b); Depth = Depth - Border+b; Border = b; show(); select(); } else { hide(); resize(Width-2*Depth-Border+b,Height-2*Depth-Border+b); Depth = Depth - Border+b; Border = b; show(); } } else { resize(Width-2*Depth-Border+b,Height-2*Depth-Border+b); Depth = Depth - Border+b; Border = b; } } graphic::graphic(int x, int y, int k,int mode, char *fname) : bitmap(x,y,mode,fname,k) { } graphic::~graphic() { } void graphic::save(char *fname) { ofstream F(fname,ios::binary); F.write(Buffer,ImageSize); F.flush(); F.close(); } void graphic::capture(int x, int y, int x1, int y1) { mouse.hide(); if (Buffer) { free(Buffer); Buffer = NULL; } ImageSize=imagesize(x,y,x1,y1); Buffer = (char far*)farmalloc(ImageSize); if (!Buffer) { closegraph(); cerr<<"Memory allocation error during graphic capture."<<endl; exit(1); } getimage(x,y,x1,y1,Buffer); X=x; Y=y; Width=x1-x+1; Height=y1-y+1; isShown=1; mouse.show(); } gmouse::~gmouse() { mouse.hide(); mouse.init(); } void gmouse::init() { unsigned int btns; asm { mov ax,0x0000 mov bx,0x0000 int 0x33 mov btns,bx } show_lvl=-100; num_btns=(int)btns; } void gmouse::arm() { show_lvl=0; } void gmouse::disarm() {show_lvl=-100;} void gmouse::show() { if (show_lvl == 0) { asm { mov ax,0x0001 int 0x33 }; } ++show_lvl; } void gmouse::hide() { if (show_lvl == 1) { asm { mov ax,0x0002 int 0x33 }; } --show_lvl; } int gmouse::getmX() { unsigned int mouseX; asm { mov ax,0x0003 int 0x33 mov mouseX,cx }; return ((int)mouseX); } int gmouse::getmY() { unsigned int mouseY; asm { mov ax,0x0003 int 0x33 mov mouseY,dx }; return ((int)mouseY); } int gmouse::getbutton( int btn) { unsigned int bstat; asm { mov ax,0x0003 int 0x33 mov bstat,bx }; if (bstat & btn) return (1); return (0); } int gmouse::btnpressed() { unsigned int bstat; asm { mov ax,0x0003 int 0x33 mov bstat,bx }; if (bstat & 7) return (1); return (0); } void gmouse::moveptr(int X, int Y) { asm { mov ax,0x0004 mov cx,X mov dx,Y int 0x33 }; } void gmouse::setbounds(int left, int right, int top, int btm) { asm { mov ax,0x0007 mov cx,left mov dx,right int 0x33 mov ax,0x0008 mov cx,top mov dx,btm int 0x33 }; } void gmouse::setexclarea(int left, int right, int top, int btm) { asm { mov ax,0x0010 mov cx,left mov si,right mov dx,top mov di,btm int 0x33 }; } void gmouse::newpointer(int Type=0) { unsigned int *Ptr, X, Y; if ((Type < 1) || (Type > 6)) return; switch (Type) { case 1: X=1; Y=1; Ptr=arrowptr; break; case 2: X=5; Y=1; Ptr=uparrow; break; case 3: X=0; Y=3; Ptr=lftarrow; break; case 4: X=6; Y=7; Ptr=chekmark; break; case 5: X=5; Y=0; Ptr=pointhand; break; case 6: X=7; Y=7; Ptr=hourglass; break; } custmpointer(X,Y,Ptr); } void gmouse::custmpointer(int X, int Y, unsigned int *Ptr) { unsigned int sg, ofst; sg =(unsigned)(void _seg *)(void far *)Ptr; ofst =(unsigned)Ptr; asm { mov AX,0x0009 mov BX,X mov CX,Y mov DX,ofst mov ES,sg int 0x33 }; } int gmouse::getrecentX() { unsigned int recX; asm { mov ax,0x000B int 0x33 mov recX,cx }; return ((int) recX); } int gmouse::getrecentY() { unsigned int recY; asm { mov ax,0x000B int 0x33 mov recY,dx }; return ((int) recY); } void gmouse::setevnthndlr( unsigned int mask, void far *pointer) { unsigned int sg,ofst; sg =(unsigned)(void _seg *)(void far *)pointer; ofst =(unsigned)pointer; asm { mov ax,0x000C mov cx,mask mov dx,ofst mov es,sg int 0x33 }; } static int mx,my,mb; static int InProgress = 0; interrupt MouseInterruptHndlr(...) { if (!InProgress) { asm { mov mx,cx // Place the X coordinate into the record. mov my,dx // Place the Y coordinate into the record. mov mb,ax // Place the button status into the record. } ++InProgress; if (EventSize+1 < 50) { ++EventSize; ++EventHead; if (EventHead == 50) EventHead = 0; EventQueue[EventHead].X = mx; EventQueue[EventHead].Y = my; EventQueue[EventHead].Btns = mb; } --InProgress; } } void gmouse::setdefhndlr() { setevnthndlr(6,MouseInterruptHndlr); } int gmouse::nextevent(int &X, int &Y, int &Btn) { if (EventSize == 0) return 0; X = EventQueue[EventHead].X; Y = EventQueue[EventHead].Y; Btn = EventQueue[EventHead++].Btns; --EventSize; if (EventHead == 50) EventHead = 0; return 1; } void gmouse::setsens( unsigned int X, unsigned int Y) { asm { mov ax,0x000F mov cx,X mov dx,Y int 0x33 }; } checkbox::checkbox(int x, int y, int w, int h, int d, int c, int k) : panel (x,y,w,h,d,IN,c,k) { LineWidth=0; Selected=0; } checkbox::~checkbox() { } void checkbox::show() { hide(); panel::show(); Selected = 0; } void checkbox::select() { int orig_color; struct fillsettingstype orig_settings; struct linesettingstype orig_line; mouse.hide(); if (isShown) { orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); setlinestyle(0,1,LineWidth); setcolor (BLACK); line(X+Depth,Y+Depth,(X+Width-Depth-1),(Y+Height-Depth-1)); line((X+Width-Depth-1),Y+Depth,X+Depth,(Y+Height-Depth-1)); setcolor(orig_color); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); Selected=1; } mouse.show(); return; } void checkbox::setline(int w) { LineWidth = w; } int checkbox::is_selected() { return (Selected); } rbutton::rbutton(int x, int y, int R, int C, int k) :gbase(x-R,y-R,2*R+1,2*R+1,k) { Radius = R; Color =C; Selected=0; } rbutton::~rbutton() { } void rbutton::moveto(int x, int y) { gbase::moveto(x-Radius,y-Radius); } void rbutton::resize(int R) { if (isShown) { hide(); Radius = R; gbase::moveto(X-R,Y-R); ReSize(2*R+1,2*R+1); show(); } else { gbase::moveto(X-R,Y-R); ReSize(2*R+1,2*R+1); } } void rbutton::show() { size_t size; int orig_color; struct fillsettingstype orig_settings; struct linesettingstype orig_line; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); setlinestyle(0,1,0); getbkg(); setcolor(LIGHTGRAY); setfillstyle(SOLID_FILL,LIGHTGRAY); pieslice(X+Radius,Y+Radius,0,360,Radius); setcolor(DARKGRAY); arc (X+Radius, Y+Radius, 45, 225, Radius); setcolor(WHITE); arc(X+Radius,Y+Radius,226,360,Radius); arc(X+Radius,Y+Radius,0,44,Radius); isShown=1; Selected=0; setcolor(orig_color); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); mouse.show(); } void rbutton::select() { int orig_color; struct fillsettingstype orig_settings; struct linesettingstype orig_line; if (!isShown) return; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); setlinestyle(0,1,0); setcolor(Color); setfillstyle(SOLID_FILL,Color); pieslice(X+Radius, Y+Radius, 0, 360, Radius-3); setcolor(WHITE); arc (X+Radius,Y+Radius,45,225,Radius-3); setcolor(DARKGRAY); arc (X+Radius,Y+Radius,226,360,Radius-3); arc (X+Radius,Y+Radius,0,44,Radius-3); Selected=1; setcolor(orig_color); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); mouse.show(); } void rbutton::chgclr(int c) { Color = c; } int rbutton::is_selected() { return (Selected); } icon::icon(int x, int y, int mode, char *fname, int k): bitmap(x,y,mode,fname,k) { Selected = 0; } icon::~icon() { } void icon::show() { bitmap::show(); Selected=0; } void icon::select() { unsigned int size; if (!isShown) return; mouse.hide(); putimage(X, Y, Buffer, NOT_PUT); isShown=1; Selected=1; mouse.show(); } int icon::is_selected() { return(Selected); } instrn::instrn (int x, int y, int w, int h, int d, int c, int k) :panel(x,y,w,h,d,IN,c,k) { TxtColor=WHITE; CsrColor=BLACK; CsrBlink=1; Pointer=0; MaxLen=0; instmode=0; Buffer=NULL; HiClr = RED; Hilight_Begin = 0; Hilight_End = 0; } instrn::~instrn() { if (Buffer) free (Buffer); } void instrn::settxtclr(int clr) { TxtColor = clr; hide(); show(); } void instrn::setcsrclr (int clr) { CsrColor=clr; hide(); show(); } void instrn::sethiclr(int clr) { HiClr = clr; } void instrn::setcsrblink(int blk) { CsrBlink = blk; } void instrn::show() { int orig_color; struct textsettingstype textinfo; gettextsettings(&textinfo); orig_color=getcolor(); if (Height < textheight("jgAT")+2) { Height = textheight("jgAT")+2; } panel::show(); if (Buffer) { mouse.hide(); setcolor(TxtColor); settextjustify(LEFT_TEXT,CENTER_TEXT); outtextxy(X+Depth+3,(Y+(Height/2+1)),Buffer); mouse.show(); } setcolor(orig_color); settextjustify(textinfo.horiz,textinfo.vert); } char instrn::lastkey() { return ((char)inkey); } char *instrn::getinput(int hi_init) { int newline=0, // Time to quit this line? i=0, // Counter used for insert/delete loops. j = 0, orig_color, Hilight_Last = 0; struct fillsettingstype orig_settings; struct linesettingstype orig_line; struct textsettingstype textinfo; if (!isShown) return (""); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); gettextsettings(&textinfo); setlinestyle(0,1,0); setcolor(BLACK); if (!Buffer) { MaxLen=(Width-(2*Depth)-4)/textwidth("A"); Buffer = (char *)malloc (MaxLen+1); if (!Buffer) { closegraph(); cerr << "Memory allocation error in instrn::getinput"<<endl; exit(1); } for (i=0; i<=MaxLen; ++i) *(Buffer+i) = '\0'; Pointer=0; hide(); // erase and re-draw panel to get ready for new input. show(); } // Set Hilight_Begin and Hilight_End. if (hi_init == 1) { Hilight_Begin = 0; Hilight_End = strlen(Buffer); } // Draw the hilight. if (Hilight_Begin != Hilight_End) { setcolor(HiClr); setfillstyle(SOLID_FILL,HiClr); mouse.hide(); bar(X+Depth+1,Y+Depth,X+Depth+Hilight_End*textwidth("A")+2,Y+Height-Depth-1); if (Buffer) { setcolor(TxtColor); settextjustify(LEFT_TEXT,CENTER_TEXT); outtextxy(X+Depth+3,(Y+(Height/2+1)),Buffer); } mouse.show(); } // Wait for the mouse to release if it's presed while (mouse.btnpressed()) ; do // This is the outer MAIN LOOP. { do // This is the IDLE LOOP, blinking the cursor. { mouse.hide(); setcolor(CsrColor); line((X+Depth+Pointer*textwidth("A")+2),Y+Depth+2,(X+Depth+Pointer*textwidth("A")+2),Y+Height-Depth-3); mouse.show(); if (CsrBlink) { if (!keyhit() && !(mouse.btnpressed() && !hit())) delay(100); mouse.hide(); setcolor(Color); line((X+Depth+Pointer*textwidth("A")+2),Y+Depth+1,(X+Depth+Pointer*textwidth("A")+2),Y+Height-Depth-1); mouse.show(); if (!keyhit() && !(mouse.btnpressed() && !hit())) delay(100); } } while (!keyhit() && !mouse.btnpressed()) ; if (mouse.btnpressed() && hit()) { show(); Hilight_End = (mouse.getmX()-X)/textwidth("A"); Hilight_Begin = Hilight_End; Hilight_Last = Hilight_End; while (mouse.btnpressed() && hit()) { Hilight_End = (mouse.getmX()-X)/textwidth("A"); if (Hilight_End != Hilight_Last) { mouse.hide(); Hilight_Last = Hilight_End; setcolor(Color); setfillstyle(SOLID_FILL,Color); bar(X+Depth,Y+Depth,X+Width-Depth-1,Y+Height-Depth-1); setcolor(HiClr); setfillstyle(SOLID_FILL,HiClr); bar(X+Depth+(int)min(Hilight_End, Hilight_Begin)*textwidth("A")+2,Y+Depth, X+Depth+(int)max(Hilight_End, Hilight_Begin)*textwidth("A")+2,Y+Height-Depth-1); if (Buffer) { setcolor(TxtColor); settextjustify(LEFT_TEXT,CENTER_TEXT); outtextxy(X+Depth+3,(Y+(Height/2+1)),Buffer); } mouse.show(); } } } else if (!(mouse.btnpressed() && !hit())) { inkey=getkey(); if (inkey > 255) { putbk(inkey); inkey =(char)0; } else inkey = inkey & 0xff; switch (inkey) //Proccess the keystrokes. { case 0: //extended keys! inkey = getkey() & 0xff; switch (inkey) { case 71: // HOME key Pointer = 0; if (getkbflags() & 0x03) { Hilight_End = Pointer; } else { Hilight_Begin = Hilight_End = Pointer; } break; case 79: // End Key. Pointer = strlen(Buffer); if (getkbflags() & 0x03) { Hilight_End = Pointer; } else { Hilight_Begin = Hilight_End = Pointer; } break; case 75: //left-arrow (Pointer > 0) ? --Pointer:0; if (getkbflags() & 0x03) { Hilight_End = Pointer; } else { Hilight_Begin = Hilight_End = Pointer; } break; case 77: //right-arrow (*(Buffer+Pointer) != '\0') ? ++Pointer:Pointer; if (getkbflags() & 0x03) { Hilight_End = Pointer; } else { Hilight_Begin = Hilight_End = Pointer; } break; case 72: //up-arrow Hilight_Begin = Hilight_End; newline=1; break; case 80: //down_arrow Hilight_Begin = Hilight_End; newline=1; break; case 82: //insert if (!instmode) instmode=1; else instmode=0; break; case 83: //delete if (Hilight_End != Hilight_Begin) { Pointer = (int)min(Hilight_End, Hilight_Begin); for (i=Pointer, j=(int) max(Hilight_End, Hilight_Begin);*(Buffer+j) != '\0' ; ++i, ++j) *(Buffer+i)=*(Buffer+j); for (;i < MaxLen; ++i) *(Buffer+i)='\0'; Hilight_Begin = Hilight_End; } else { for (i=Pointer; i < MaxLen ; ++i) *(Buffer+i)=*(Buffer+i+1); *(Buffer+MaxLen)='\0'; } break; }; break; case 9: // tab Hilight_Begin = Hilight_End; newline=1; break; case 13: // return Hilight_Begin = Hilight_End; newline=1; break; case 27: // escape Hilight_Begin = Hilight_End; newline=1; break; case 8: //backspace if (Hilight_End != Hilight_Begin) { Pointer = (int)min(Hilight_End, Hilight_Begin); for (i=Pointer, j=(int) max(Hilight_End, Hilight_Begin);*(Buffer+j) != '\0' ; ++i, ++j) *(Buffer+i)=*(Buffer+j); for (;i < MaxLen; ++i) *(Buffer+i)='\0'; Hilight_Begin = Hilight_End; } else { if (Pointer >0) { for (i=Pointer; i <= MaxLen; ++i) *(Buffer+i-1) = *(Buffer+i); *(Buffer+MaxLen) = '\0'; --Pointer; } } break; default: //other key pressed (enter char to buffer). if (Hilight_End != Hilight_Begin) { Pointer = (int)min(Hilight_End, Hilight_Begin); for (i=Pointer, j=(int) max(Hilight_End, Hilight_Begin);*(Buffer+j) != '\0' ; ++i, ++j) *(Buffer+i)=*(Buffer+j); for (;i < MaxLen; ++i) *(Buffer+i)='\0'; if (Pointer > (MaxLen-1)) Pointer = MaxLen-1; for (i=MaxLen-1; i > Pointer; --i) *(Buffer+i) = *(Buffer+i-1); Hilight_Begin = Hilight_End = Pointer+1; } else { if (Pointer > (MaxLen-1)) Pointer = MaxLen-1; if (instmode) for (i=MaxLen-1; i > Pointer; --i) *(Buffer+i) = *(Buffer+i-1); } *(Buffer+Pointer) = inkey; ++Pointer; } mouse.hide(); setcolor(Color); setfillstyle(SOLID_FILL,Color); bar(X+Depth,Y+Depth,X+Width-Depth-1,Y+Height-Depth-1); if (Hilight_End != Hilight_Begin) { setcolor(HiClr); setfillstyle(SOLID_FILL,HiClr); bar(X+Depth+(int)min(Hilight_End, Hilight_Begin)*textwidth("A")+2,Y+Depth, X+Depth+(int)max(Hilight_End, Hilight_Begin)*textwidth("A")+2,Y+Height-Depth-1); } setcolor(TxtColor); settextjustify(LEFT_TEXT,CENTER_TEXT); outtextxy(X+Depth+3,(Y+(Height/2+1)),Buffer); mouse.show(); } else { newline = 1; inkey = 0; } } while (!newline); show(); mouse.hide(); setcolor(Color); setfillstyle(SOLID_FILL,Color); bar(X+Depth,Y+Depth,X+Width-Depth-1,Y+Height-Depth-1); setcolor(TxtColor); settextjustify(LEFT_TEXT,CENTER_TEXT); outtextxy(X+Depth+3,(Y+(Height/2+1)),Buffer); mouse.show(); setcolor(orig_color); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); settextjustify(textinfo.horiz,textinfo.vert); return (Buffer); } void instrn::hilight(int start, int end) { if (Buffer == NULL) return; // Set Hilight_Begin and Hilight_End. if (start < 0) start = 0; if (end > strlen(Buffer)) end = strlen(Buffer); Hilight_Begin = start; Hilight_End = end; // Draw the hilight. if (Hilight_Begin != Hilight_End) { setcolor(HiClr); setfillstyle(SOLID_FILL,HiClr); mouse.hide(); bar(X+Depth+1,Y+Depth,X+Depth+Hilight_End*textwidth("A")+2,Y+Height-Depth-1); if (Buffer) { setcolor(TxtColor); settextjustify(LEFT_TEXT,CENTER_TEXT); outtextxy(X+Depth+3,(Y+(Height/2+1)),Buffer); } mouse.show(); } } void instrn::clear() { int i; if (!Buffer) return; free (Buffer); Buffer = NULL; inkey = 0; return; } void instrn::preset(char *B) { if (Buffer) free(Buffer); MaxLen=(Width-(2*Depth)-4)/textwidth("A"); Buffer = (char *)malloc (MaxLen+1); memset(Buffer,0x00,MaxLen+1); strncpy(Buffer,B,MaxLen); } char *instrn::gettext( char *text) { int len = strlen(Buffer); strncpy(text, Buffer, len); *(text+len) = (char)0; return text; } menubar::menubar(int x, int y, int w, int h, int c, int tc, int hc, int k) :panel(x,y,w,h,2,OUT,c,k) { BX=0; BY=0; BW=0; BH=0; TxtColor=tc; HiColor=hc; HkHiColor=tc; MenuSelected=0; ItemSelected=0; PulledDown=0; Menus = NULL; NumMenus = 0; NumItems = 0; MenuBackBuffer = NULL; MenuBkgPages = 0; MenuBkgHndl = 0; } menubar::~menubar() { while (Menus != NULL) delmenu(1); } int menubar::find_char (char *str, char fnd, int begin) { int i; for (i= begin; *(str+i) != '\0' ;++i) { if ( *(str+i) == fnd ) break; } if (!(*(str+i) == '\0')) return i; else return -1; } char *menubar::mids (char *strn, int begin, int count) { int i; char *target; target =(char *)malloc(count+1); if (target != NULL) { for (i= 0; i<count; ++i) *(target+i) = *(strn +i+ begin); *(target+i) = '\0'; return target; } else { closegraph(); cerr << "Memory allocation error in menubar::mids."<<endl; exit (-1); } return (NULL); } void menubar::addmenu(char *heading, char *items, int Key) { MenuTYPE *newmenu, *tempM; itemTYPE *newitem, *tempI; char *temp; int pos,epos; newmenu = new (MenuTYPE); if (!newmenu) { closegraph(); cerr << "Memory allocation error while making menu item. "<<endl; exit(1); } ++NumMenus; memset(newmenu->Heading,0,40); strncpy(newmenu->Heading, heading,39); newmenu->X=0; newmenu->Y=0; newmenu->Width=0; newmenu->Height=Height; newmenu->NextMenu=NULL; newmenu->Items = NULL; newmenu->hotkey = Key; if (Menus==NULL) Menus = newmenu; else { tempM = Menus; while(tempM->NextMenu != NULL) tempM = tempM->NextMenu; tempM->NextMenu = newmenu; } pos = 0; epos = 0; while (epos != -1) { epos = find_char(items,',',pos); temp = mids(items,pos,((epos == -1) ? strlen(items) : epos)-pos); pos = epos + 1; newitem = new(itemTYPE); if (!newitem) { closegraph(); cerr << "Memory allocation error while making menu item."<<endl; exit(1); } memcpy(newitem->Item,0,40); strncpy(newitem->Item,temp,39); newitem->X=0; newitem->Y=0; newitem->Width=0; newitem->Height=0; newitem->NextItem=NULL; if (newmenu->Items==NULL) newmenu->Items = newitem; else { tempI = newmenu->Items; while(tempI->NextItem != NULL) tempI = tempI->NextItem; tempI->NextItem = newitem; } } } void menubar::delmenu(int no) { int i; MenuTYPE *tempM, *prevM; itemTYPE *tempI, *prevI; tempM=Menus; prevM=NULL; pushup(); for (i=1; i<no; ++i) // Find the no'th menu. if end reached, return. { if (tempM==NULL) return; prevM = tempM; tempM = tempM->NextMenu; } if (tempM==NULL) return; if (Menus == tempM) Menus = tempM->NextMenu; else prevM->NextMenu = tempM->NextMenu; tempI = tempM->Items; prevI = NULL; while (tempI != NULL) { prevI = tempI; tempI = tempI->NextItem; free(prevI); } free (tempM); } void menubar::setbkgclr(int C) { Color = C; } void menubar::sethkhiclr(int C) { HkHiColor = C; } void menubar::settextclr(int C) { TxtColor = C; } void menubar::sethighclr(int C) { HiColor = C; } void menubar::show() { MenuTYPE *tempM; int tempX; int orig_color; int i, i2; char temp[2] =" "; struct fillsettingstype orig_settings; struct linesettingstype orig_line; struct textsettingstype textinfo; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); gettextsettings(&textinfo); setlinestyle(0,1,0); if (Height-2*Depth < textheight("AjBg")+2) Height = textheight("AjBg")+2*Depth+2; panel::show(); tempM = Menus; tempX = X+Depth+5; while (tempM != NULL) { setcolor(TxtColor); settextjustify(LEFT_TEXT,CENTER_TEXT); for (i = 0, i2 = 0; *(tempM->Heading+i) != (char)0x00 ;++i, ++ i2) { strncpy(temp,tempM->Heading+i,1); if (*(tempM->Heading+i) == '~') { setcolor(HkHiColor); strncpy(temp,tempM->Heading+(++i),1); outtextxy(tempX+i2*textwidth("A"), Y+(Height/2),temp); setcolor(TxtColor); } else outtextxy(tempX+i2*textwidth("A"), Y+(Height/2), temp); } tempM->X = tempX-4; tempM->Y = Y+Depth; tempM->Width = textwidth(tempM->Heading)+8; tempM->Height = Height-2*Depth; tempX = tempX + tempM->Width + 8; tempM = tempM->NextMenu; } setcolor(orig_color); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); settextjustify(textinfo.horiz,textinfo.vert); mouse.show(); MenuSelected = 0; } void menubar::pulldown() { MenuTYPE *TempM; itemTYPE *TempI; int i, Wth, Tht, highlt[10], tempY; size_t Sze; unsigned int L_P_P, offset; int orig_color; struct fillsettingstype orig_settings; struct linesettingstype orig_line; struct textsettingstype textinfo; TempM = Menus; if ((!MenuSelected) || (!isShown) || (PulledDown)) return; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); gettextsettings(&textinfo); setlinestyle(0,1,0); NumItems = 0; for (i=1; i < MenuSelected; ++i) TempM = TempM->NextMenu; TempI = TempM->Items; Wth = 0; while (TempI != NULL) { if (strcmp(TempI->Item,"LINE")) if (Wth < textwidth(TempI->Item)) Wth = textwidth(TempI->Item); TempI = TempI->NextItem; } TempI = TempM->Items; Tht = 0; Wth = Wth + 8; while (TempI != NULL) { TempI->Width = Wth; TempI->Height = textheight(TempI->Item)+4; Tht += strcmp(TempI->Item,"LINE") ? textheight(TempI->Item)+4 : 5; TempI = TempI->NextItem; } Tht = Tht + 11; BX=(TempM->X-1); BY=(Y+Height-Depth+1); BW=(TempM->X+Wth+10); BH=(Y+Height-Depth+Tht+1); Sze = imagesize(BX,BY,BW,BH); L_P_P = ((16 * 1024) - 8)/(BW-BX+1); MenuBkgPages = ceil((float)(BH-BY+1) / (float)L_P_P); if ((emm_type()) && (emm_pgsleft() >= MenuBkgPages) && ((MenuBkgHndl = emm_maloc(MenuBkgPages)) != 0)) { for (offset = 0,i = 0;i < MenuBkgPages; ++i, offset += L_P_P) { MenuBackBuffer = emm_map(MenuBkgHndl,1,i); if (!MenuBackBuffer) { closegraph(); cerr<<"Error allocating memory for PDM background in menubar."<<endl; exit(1); } if ((offset+L_P_P) < (BH-BY)) getimage(BX,BY+offset,BW,BY+offset+L_P_P-1,MenuBackBuffer); else getimage(BX,BY+offset,BW,BH,MenuBackBuffer); } } else { MenuBkgPages = 0; if (!(MenuBackBuffer = (char far *)farmalloc(Sze))) { closegraph(); cerr<<"Error allocating memory for PDM background in menubar."<<endl; exit(1); } getimage (BX,BY,BW,BH,MenuBackBuffer); } // Header // setcolor(Color); // Bar Face setfillstyle(SOLID_FILL,Color); bar ((TempM->X),(Y+Height-Depth+1),(TempM->X+Wth+8),(Y+Height-Depth+5)); setcolor(DARKGRAY); // Bar Shadows. setfillstyle(SOLID_FILL,DARKGRAY); bar ((TempM->X+3),(Y+Height-Depth+4),(TempM->X+Wth+4),(Y+Height-Depth+5)); bar ((TempM->X+Wth+8),(Y+Height-Depth+1),(TempM->X+Wth+9),(Y+Height-Depth+5)); setcolor(Color+8); // Bar Reflections. setfillstyle(SOLID_FILL,Color+8); highlt[0] = TempM->X; highlt[1] = Y+Height-Depth+1; highlt[2] = highlt[0]-1; highlt[3] = highlt[1]+1; highlt[4] = highlt[2] ; highlt[5] = highlt[3]+3; highlt[6] = highlt[0] ; highlt[7] = highlt[5]; highlt[8] = highlt[0] ; highlt[9] = highlt[1]; fillpoly (5, highlt); highlt[0] = highlt[0] + Wth+5; highlt[1] = highlt[1] + 3; highlt[2] = highlt[0]-1; highlt[3] = highlt[1]+1; highlt[4] = highlt[0]; highlt[5] = highlt[3]; highlt[6] = highlt[0]; highlt[7] = highlt[1]; fillpoly(4, highlt); tempY = Y+Height-Depth+6; TempI = TempM->Items; for(TempI = TempM->Items ; TempI != NULL ; TempI = TempI->NextItem) { TempI->X = TempM->X+5; TempI->Y = tempY; if (strcmp(TempI->Item,"LINE")) // other than a LINE. { if (strcmp(TempI->Item,"")) // If not blank, ++NumItems; // Increment NumItems in this menu. setcolor(Color); setfillstyle(SOLID_FILL,Color); bar((TempM->X),(tempY),(TempM->X+Wth+9),(tempY+TempI->Height-1)); setcolor(DARKGRAY); setfillstyle(SOLID_FILL,DARKGRAY); bar((TempM->X+3),(tempY),(TempM->X+4),(tempY+TempI->Height-1)); bar((TempM->X+Wth+8),(tempY),TempM->X+Wth+9,(tempY+TempI->Height-1)); setcolor(Color+8); setfillstyle(SOLID_FILL,Color+8); bar((TempM->X-1),(tempY),(TempM->X),(tempY+TempI->Height-1)); bar((TempM->X+Wth+4),(tempY),(TempM->X+Wth+5),(tempY+TempI->Height-1)); setcolor(TxtColor); settextjustify(LEFT_TEXT,CENTER_TEXT); outtextxy((TempM->X+8),(tempY+(TempI->Height/2)),TempI->Item); tempY = tempY + TempI->Height; } else // it is a LINE. { setcolor(Color); setfillstyle(SOLID_FILL,Color); bar((TempM->X),tempY,(TempM->X+Wth+8),(tempY+4)); setcolor(DARKGRAY); setfillstyle(SOLID_FILL,DARKGRAY); bar((TempM->X+3),(tempY+3),(TempM->X+Wth+5),(tempY+4)); bar((TempM->X+Wth+8),tempY,(TempM->X+Wth+9),(tempY+4)); setcolor(Color+8); setfillstyle(SOLID_FILL,Color+8); bar((TempM->X-1),tempY,(TempM->X),(tempY+4)); bar((TempM->X+3),tempY,(TempM->X+Wth+5),(tempY+1)); setcolor(DARKGRAY); setfillstyle(SOLID_FILL,DARKGRAY); highlt[0]=TempM->X+3; highlt[1]=tempY; highlt[2]=highlt[0] ; highlt[3]=tempY+1; highlt[4]=highlt[0]+1;highlt[5]=highlt[1]; highlt[6]=highlt[0] ; highlt[7]=highlt[1]; fillpoly(4,highlt); setcolor(Color+8); setfillstyle(SOLID_FILL,Color+8); highlt[0]=TempM->X+Wth+5 ; highlt[1]=tempY+3; highlt[2]=highlt[0]-1 ; highlt[3]=highlt[1]+1; highlt[4]=highlt[0] ; highlt[5] = highlt[3]; highlt[6]=highlt[0] ; highlt[7] = highlt[1]; fillpoly(4,highlt); tempY = tempY + 5; } } setcolor(DARKGRAY); setfillstyle(SOLID_FILL,DARKGRAY); bar((TempM->X-1),tempY,(TempM->X+Wth+9),(tempY+5)); setcolor(Color); setfillstyle(SOLID_FILL,Color); bar((TempM->X),tempY,(TempM->X+Wth+7),(tempY+3)); setcolor(Color+8); setfillstyle(SOLID_FILL,Color+8); bar((TempM->X+3),tempY,(TempM->X+Wth+5),tempY+1); highlt[0]=TempM->X-1; highlt[1]=tempY; highlt[2]=TempM->X ; highlt[3]=tempY; highlt[4]=highlt[2] ; highlt[5]=tempY+3; highlt[6]=highlt[0] ; highlt[7]=tempY+5; highlt[8]=highlt[0] ; highlt[9]=highlt[1]; fillpoly(5,highlt); setcolor(DARKGRAY); setfillstyle(SOLID_FILL,DARKGRAY); highlt[0]=TempM->X+3 ; highlt[1]=tempY; highlt[2]=highlt[0] ; highlt[3]=tempY+1; highlt[4]=highlt[0]+1; highlt[5]=highlt[1]; highlt[6]=highlt[0] ; highlt[7]=highlt[1]; fillpoly(4,highlt); setcolor(orig_color); settextjustify(textinfo.horiz,textinfo.vert); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); mouse.show(); PulledDown=1; } void menubar::pushup() { unsigned L_P_P, offset; int i; if ((!MenuSelected) || (!isShown) || (!PulledDown)) return; mouse.hide(); L_P_P = ((16 * 1024) - 8)/(BW-BX+1); if (MenuBackBuffer) { if (MenuBkgPages) { for (offset = 0,i = 0;i < MenuBkgPages; ++i, offset += L_P_P) { MenuBackBuffer = emm_map(MenuBkgHndl,1,i); if (MenuBackBuffer) putimage(BX,BY+offset,MenuBackBuffer,COPY_PUT); } } else putimage (BX,BY,MenuBackBuffer,COPY_PUT); } if (MenuBackBuffer) { if (MenuBkgPages) emm_free (MenuBkgHndl); else farfree(MenuBackBuffer); MenuBackBuffer = NULL; MenuBkgHndl = 0; } mouse.show(); PulledDown=0; } int menubar::menuhit() { MenuTYPE *TempM; int Number; for (TempM = Menus, Number = 1; TempM != NULL ; TempM = TempM->NextMenu, ++Number) { if (isShown) if ((mouse.getmX() >= TempM->X) && (mouse.getmX() <= (TempM->X+TempM->Width-1))) if ((mouse.getmY() >= TempM->Y) && (mouse.getmY() <= (TempM->Y+TempM->Height-1))) return(Number); } return (0); } int menubar::pdhit() { if (PulledDown) if ((mouse.getmX() >=BX) && (mouse.getmX() <= BX+BW+-1)) if ((mouse.getmY() >=BY) && (mouse.getmY() <= BY+BH-1)) return(1); return (0); } int menubar::itemhit() { int i, Number; MenuTYPE *TempM; itemTYPE *TempI; if (!MenuSelected || !isShown) return (0); TempM = Menus; for (i=1; i < MenuSelected; ++i) TempM = TempM->NextMenu; for ((TempI = TempM->Items), (Number = 1); TempI != NULL; TempI = TempI->NextItem) if (strcmp(TempI->Item,"LINE") && strcmp(TempI->Item,"")) { if ((mouse.getmX() >= TempI->X) && (mouse.getmX() <= (TempI->X+TempI->Width-1))) if ((mouse.getmY() >= TempI->Y) && (mouse.getmY() <= (TempI->Y+TempI->Height-1))) return(Number); ++Number; } return (0); } void menubar::menuselect(int no) { int i, // Counter for loop j, j2; char temp[2]=" "; MenuTYPE *tempM; // Pointer to current menu. int orig_color; struct fillsettingstype orig_settings; struct linesettingstype orig_line; struct textsettingstype textinfo; if (!isShown || !no) return; tempM = Menus; for (i=1; (i<no) && (tempM != NULL) ; ++i) // Step 1: Find the right menu. tempM = tempM->NextMenu; if (tempM == NULL) // that menu doesn't exist. return; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); gettextsettings(&textinfo); setlinestyle(0,1,0); setcolor(HiColor); // Step 2: Draw the highlight bar. setfillstyle(SOLID_FILL,HiColor); bar((tempM->X+1),(tempM->Y+1),(tempM->X+tempM->Width),(tempM->Y+tempM->Height-2)); setcolor(TxtColor); // Step 3: Re-draw tht menu heading. settextjustify(LEFT_TEXT,CENTER_TEXT); for (j = 0, j2 = 0; *(tempM->Heading+j) != (char)0x00 ;++j, ++ j2) { strncpy(temp,tempM->Heading+j,1); if (*(tempM->Heading+j) == '~') { setcolor(HkHiColor); strncpy(temp,tempM->Heading+(++j),1); outtextxy((tempM->X+4)+(j2*textwidth("A")), tempM->Y+(tempM->Height/2), temp); setcolor(TxtColor); } else outtextxy((tempM->X+4)+(j2*textwidth("A")), tempM->Y+(tempM->Height/2), temp); } MenuSelected = no; // Step 4: Set the appropriate flags. setcolor(orig_color); settextjustify(textinfo.horiz,textinfo.vert); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); mouse.show(); } void menubar::itemselect(int no) { int i; // Counter for loop. MenuTYPE *tempM; // Pointer to current menu. itemTYPE *tempI; // Pointer to current item in the menu. int orig_color; struct fillsettingstype orig_settings; struct linesettingstype orig_line; struct textsettingstype textinfo; if ((!isShown) || (!MenuSelected) || (!PulledDown) || (!no)) return; tempM = Menus; for (i=1;(i<MenuSelected) && (tempM != NULL) ; ++i) // Step 1: Find the right menu. tempM = tempM->NextMenu; if (tempM == NULL) // That menu doesn't exist. return; i=0; tempI = tempM->Items; while (tempI != NULL) // Step 2: Find the right item, skipping blanks and LINEs. { if (strcmp(tempI->Item,"LINE") && strcmp(tempI->Item,"")) ++i; if (i == no) break; tempI = tempI->NextItem; } if (tempI == NULL) // That item doesn't exist. return; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); gettextsettings(&textinfo); setlinestyle(0,1,0); setcolor(HiColor); // Step 3: Draw the highlight bar. setfillstyle(SOLID_FILL,HiColor); bar((tempI->X+1),(tempI->Y),(tempI->X+tempI->Width-3),(tempI->Y+tempI->Height-1)); setcolor(TxtColor); // Step 4: Re-draw tht menu item. settextjustify(LEFT_TEXT,CENTER_TEXT); outtextxy((tempI->X+3),(tempI->Y+(tempI->Height/2)),tempI->Item); ItemSelected = no; // Step 5: Set the appropriate flags. setcolor(orig_color); settextjustify(textinfo.horiz,textinfo.vert); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); mouse.show(); } void menubar::itemclear() { int i; // Counter for loop. MenuTYPE *tempM; // Pointer to current menu. itemTYPE *tempI; // Pointer to current item in the menu. int orig_color; struct fillsettingstype orig_settings; struct linesettingstype orig_line; struct textsettingstype textinfo; if ((!isShown) || (!MenuSelected) || (!ItemSelected)|| (!PulledDown)) return; tempM = Menus; for (i=1; (i<MenuSelected) && (tempM != NULL) ; ++i) // Step 1: Find the right menu. tempM = tempM->NextMenu; if (tempM == NULL) // That menu doesn't exist. return; i=0; tempI = tempM->Items; while (tempI != NULL) // Step 2: Find the right item, skipping blanks and LINEs. { if (strcmp(tempI->Item,"LINE") && strcmp(tempI->Item,"")) ++i; if (i == ItemSelected) break; tempI = tempI->NextItem; } if (tempI == NULL) // That item doesn't exist. return; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); gettextsettings(&textinfo); setlinestyle(0,1,0); setcolor(Color); // Step 3: Erase the highlight bar. setfillstyle(SOLID_FILL,Color); bar((tempI->X+1),(tempI->Y),(tempI->X+tempI->Width-3),(tempI->Y+tempI->Height-1)); setcolor(TxtColor); // Step 4: Re-draw tht menu item. settextjustify(LEFT_TEXT,CENTER_TEXT); outtextxy((tempI->X+3),(tempI->Y+(tempI->Height/2)),tempI->Item); ItemSelected = 0; // Step 5: Set the appropriate flags. setcolor(orig_color); settextjustify(textinfo.horiz,textinfo.vert); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); mouse.show(); } void menubar::menuclear() { int i; // Counter for loop int j, j2; char temp[2] = " "; MenuTYPE *tempM; // Pointer to current menu. int orig_color; struct fillsettingstype orig_settings; struct linesettingstype orig_line; struct textsettingstype textinfo; if (!isShown || !MenuSelected) return; tempM = Menus; for (i=1; (i<MenuSelected) && (tempM != NULL) ; ++i) // Step 1: Find the right menu. tempM = tempM->NextMenu; if (tempM == NULL) // That menu doesn't exist. return; mouse.hide(); orig_color=getcolor(); getfillsettings(&orig_settings); getlinesettings(&orig_line); gettextsettings(&textinfo); NumItems = 0; setlinestyle(0,1,0); setcolor(Color); // Step 2: Erase the highlight bar. setfillstyle(SOLID_FILL,Color); bar((tempM->X+1),(tempM->Y+1),(tempM->X+tempM->Width),(tempM->Y+tempM->Height-2)); setcolor(TxtColor); // Step 3: Re-draw tht menu heading. settextjustify(LEFT_TEXT,CENTER_TEXT); for (j = 0, j2 = 0; *(tempM->Heading+j) != (char)0x00 ;++j, ++ j2) { strncpy(temp,tempM->Heading+j,1); if (*(tempM->Heading+j) == '~') { setcolor(HkHiColor); strncpy(temp,tempM->Heading+(++j),1); outtextxy((tempM->X+4)+(j2*textwidth("A")), tempM->Y+(tempM->Height/2), temp); setcolor(TxtColor); } else outtextxy((tempM->X+4)+(j2*textwidth("A")), tempM->Y+(tempM->Height/2), temp); } MenuSelected = 0; // Step 4: Set the appropriate flags. setcolor(orig_color); setfillstyle(orig_settings.pattern, orig_settings.color); setlinestyle(orig_line.linestyle, orig_line.upattern, orig_line.thickness); settextjustify(textinfo.horiz,textinfo.vert); mouse.show(); } int menubar::itemselected() { return(ItemSelected); } int menubar::menuselected() { return(MenuSelected); } void menubar::checkforevent() { int chr; MenuTYPE *MenuPtr; int i, MenuNo; lastMenuSelected = 0; lastItemSelected = 0; if (keyhit() || (mouse.getbutton(LEFT_BTN) && menuhit()) || (menuselected())) // If event happening, continue. { if (keyhit()) // If it's a keyboard event { if (( chr = getkey()) > 255) // See if it's an extended key. { chr = chr & 0xff; if (chr == 68) // Is is F-10? menuselect(1); // If so, just select menu 1 else // if not, see if it's a hotkey! { MenuPtr = Menus; MenuNo = 0; while (MenuPtr != NULL) // Check all the menus if need be. { ++MenuNo; if (chr == MenuPtr->hotkey) // Is this the one we want? { menuselect(MenuNo); // Select it. pulldown(); break; } MenuPtr = MenuPtr->NextMenu; // If not, go to the next one. } if (MenuPtr == NULL) // If that was not a hotkey { putbk(chr+256); return; // and return. } } } else // If it wasn't an extened key in the first place, { putbk(chr); // Put it back return; // And return. } } while (1) // The Menu/Item select loop. { if (menuhit() && mouse.getbutton(LEFT_BTN)) // If the mouse clicks on a menu { pushup(); // Clear any previous menu menuclear(); menuselect(menuhit()); // Select the new menu pulldown(); // Pull it down itemselect(1); do{}while(mouse.btnpressed()); // Wait for button release. } if (itemhit() && mouse.getbutton(LEFT_BTN)) // If the mouse clicks on an item { itemclear(); // Clear any previous item. itemselect(itemhit()); // Select the new one. do{}while(mouse.btnpressed()); // Wait for button release. lastItemSelected = ItemSelected; // Indicate the selection lastMenuSelected = MenuSelected; itemclear(); // Clean up the menubar pushup(); menuclear(); return; // and return. } if (mouse.getbutton(LEFT_BTN) && (!menuhit() || !pdhit())) { // If clicked outside the menubar area. itemclear(); // clear everything pushup(); menuclear(); lastItemSelected = 0; lastMenuSelected = 0; return; // and return. } if (keyhit()) // If it's a keyboard selection, { chr = getkey(); // get the key. if (chr == 27) // If it's the escape key, { itemclear(); // clear everything pushup(); menuclear(); lastItemSelected = 0; lastMenuSelected = 0; return; // and return. } if (chr == 13) // If it's the ENTER key, { if (!PulledDown) // and no menu is selected, { pulldown(); // Select it. itemselect(1); } else // Otherwise indicate the selected item, { lastItemSelected = ItemSelected; lastMenuSelected = MenuSelected; itemclear(); // Clean up the menubar, pushup(); menuclear(); return; // and return. } } if (chr > 255) // If it's an extended key, check for the arrows. { chr = chr & 0xff; if (chr == 72) // If it's an up arrow, { i = ItemSelected; itemclear(); // Clear the old item. itemselect(((i-1)>0) ? (i-1) : 1); // Select the previous item. } else if (chr == 80) // If it's a down arrow { if (PulledDown) // and a menu's pulled down, { i = ItemSelected; // Clear the old item selected itemclear(); itemselect(((i+1)<=NumItems) ? (i+1) : NumItems); // and select the next one down. } else // But if no menu's selected, { pulldown(); // Select one. itemselect(1); } } else if (chr == 77) // If it's a right arrow, { i = MenuSelected; // Get the old menu if (PulledDown) { itemclear(); // Clean up the menubar, pushup(); menuclear(); menuselect (((i+1)<=NumMenus) ? (i+1) : NumMenus); // and select the next menu over. pulldown(); itemselect(1); } else { menuclear(); menuselect (((i+1)<=NumMenus) ? (i+1) : NumMenus); // and select the next menu over. } } else if (chr == 75) // If it's a left arrow, { i = MenuSelected; // Get the old one, if (PulledDown) { itemclear(); // Clear it pushup(); menuclear(); menuselect (((i-1) >0) ? (i-1) : 1); // and select the next one over. pulldown(); itemselect(1); } else { menuclear(); menuselect (((i-1) >0) ? (i-1) : 1); // and select the next one over. } } else // check for a hotkey for another menu. { MenuPtr = Menus; MenuNo = 0; while (MenuPtr != NULL) // Check all the menus if need be. { ++MenuNo; if (chr == MenuPtr->hotkey) // Is this the one we want? { itemclear(); pushup(); menuclear(); menuselect(MenuNo); // Select it. pulldown(); break; } MenuPtr = MenuPtr->NextMenu; // If not, go to the next one. } } } } } // end while(1). } } int menubar::lastevntitem() { return (lastItemSelected); } int menubar::lastevntmenu() { return (lastMenuSelected); } int menubar::htkypressed() { int chr; MenuTYPE *MenuPtr; int MenuNo = 0; if (keyhit()) // If it's a keyboard event { if ((chr = getkey()) > 255) // See if it's an extended key. { chr = chr & 0xff; // Get the actual code. MenuPtr = Menus; MenuNo = 0; while (MenuPtr != NULL) // Check all the menus if need be. { ++MenuNo; if (chr == MenuPtr->hotkey) // Is this the one we want? { putbk(chr + 256); break; } MenuPtr = MenuPtr->NextMenu; // If not, go to the next one. } if (MenuPtr == NULL) // If that was not a hotkey { putbk(chr + 256); return 0; } } else // If it wasn't an extened key in the first place, { putbk (chr); // Put it back return 0; // And return. } } return MenuNo; // Finally, If it was a hotkey, return the menu number. } int menubar::ishtkey(int keypd) { char chr; MenuTYPE *MenuPtr; int MenuNo; chr = (char)keypd; // Get just the lower byte. MenuPtr = Menus; MenuNo = 0; while (MenuPtr != NULL) // Check all the menus if need be. { ++MenuNo; if (chr == MenuPtr->hotkey) // Is this the one we want? break; MenuPtr = MenuPtr->NextMenu; // If not, go to the next one. } if (MenuPtr == NULL) // If that was not a hotkey return 0; // and return. return MenuNo; // Finally, If it was a hotkey, return the menu number. } static int KBBUF; int getkbflags() { REGS regs; regs.h.ah = 0x02; int86(0x16,®s,®s); return (int)regs.h.al; } int keyhit() { int Rdy; REGS regs; if (KBBUF != 0) return 1; regs.h.ah = 0x01; int86 (0x16,®s,®s); if (regs.x.flags & 0x0040) return 0; return 1; } int getkey() { int keypd; REGS regs; if (KBBUF != 0) keypd = KBBUF; else { regs.h.ah = 0x00; int86(0x16,®s,®s); if (regs.h.al == 0x00) keypd = 256 + regs.h.ah; else keypd = regs.h.al; } KBBUF = 0; return keypd; } int putbk(int keypb) { if (KBBUF == 0) { KBBUF = keypb; return 1; } return 0; } vscroll::vscroll(int x, int y, int w, int h, int hdh, int bht, int bc, int hc, int bkgc, int k) : panel (x+1,y+1,w-2,h-2,1,IN,bkgc,k) { int error = 0; char UpChr[2] = {24,0}, DnChr[2] = {25,0}; Min_Position = 0; Max_Position = 100; Curr_Position = 0; Lines_Per_Page = 5; if ((bht < 10) || (w < 14)) { strcpy(UpChr,""); strcpy(DnChr,""); } Dn = new button(x+2,y+h-bht-1,w-4,bht,2,bc,0,TEXT,DnChr,0); if (!Dn) error = 1; Up = new button(x+2,y+1,w-4,bht,2,bc,0,TEXT,UpChr,0); if (!Up) error = 1; Hnd = new panel(x+2,y+bht+5,w-4,hdh,1,OUT,hc,1); if (!Hnd) error = 1; HDH = hdh; BTH = bht; if (error) { if (Up) delete Up; if (Dn) delete Dn; if (Hnd) delete Hnd; closegraph(); cerr << "Memory allocation error in vscroll::vscroll." << endl; } } vscroll::~vscroll() { delete Up; delete Dn; delete Hnd; } void vscroll::setrange(int min, int max) { Min_Position = min; Max_Position = max; if (Curr_Position < Min_Position) Curr_Position = Min_Position; if (Curr_Position > Max_Position) Curr_Position = Max_Position; } void vscroll::hide(void) { if (!isShown) return; Hnd->hide(); Up->hide(); Dn->hide(); panel::hide(); } void vscroll::show(void) { float Step_Size; int Ycord; panel::show(); Up->show(); Dn->show(); Hnd->show(); if ((Max_Position-Min_Position) == 0) Step_Size = 0; else Step_Size = (float)(Height-8-(2*BTH)-HDH)/(float)(Max_Position-Min_Position); Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord > 0) ? Ycord : 0; Ycord = (Ycord < Height-8-(2*BTH)-HDH) ? Ycord : (Height-8-(2*BTH)-HDH); Hnd->moveto(X+2,Y+BTH+4+Ycord); } void vscroll::setpos(int p) { float Step_Size; int Ycord; if ((Max_Position-Min_Position) == 0) Step_Size = 0; else Step_Size = (float)(Height-8-(2*BTH)-HDH)/(float)(Max_Position-Min_Position); Curr_Position = (p >= Min_Position)? p : Min_Position; Curr_Position = (p <= Max_Position)? Curr_Position : Max_Position; Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord > 0) ? Ycord : 0; Ycord = (Ycord < Height-8-(2*BTH)-HDH) ? Ycord : (Height-8-(2*BTH)-HDH); Hnd->moveto(X+2,Y+BTH+4+Ycord); } int vscroll::getpos(void) { return Curr_Position; } int vscroll::uphit(void) { return Up->hit(); } int vscroll::dnhit(void) { return Dn->hit(); } int vscroll::hndhit(void) { return Hnd->hit(); } void vscroll::uppres(void) { Up->select(); } void vscroll::dnpres(void) { Dn->select(); } void vscroll::uprels(void) { Up->show(); } void vscroll::dnrels(void) { Dn->show(); } int vscroll::getevent(void) { time_t Intl; float Step_Size; int Ycord, Last_Y; if ((Max_Position-Min_Position) == 0) Step_Size = 0; else Step_Size = (float)(Height-8-(2*BTH)-HDH)/(float)(Max_Position-Min_Position); if (mouse.getbutton(LEFT_BTN) & panel::hit()) { if (Up->hit()) { Up->select(); Curr_Position = (Curr_Position > Min_Position) ? --Curr_Position : Min_Position; Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord > 0) ? Ycord : 0; Hnd->moveto(X+2,Y+BTH+4+Ycord); Intl = clock(); while (mouse.btnpressed()) while (((clock()-Intl) > CLK_TCK ) && mouse.btnpressed() && Up->hit()) { Curr_Position = (Curr_Position > Min_Position) ? --Curr_Position : Min_Position; Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord > 0) ? Ycord : 0; Hnd->moveto(X+2,Y+BTH+4+Ycord); delay(50); } Up->show(); Last_Y = Ycord; } else if (Dn->hit()) { Dn->select(); Curr_Position = (Curr_Position < Max_Position)? ++Curr_Position : Max_Position; Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord < Height-8-(2*BTH)-HDH) ? Ycord : (Height-8-(2*BTH)-HDH); Hnd->moveto(X+2,Y+BTH+4+Ycord); Intl = clock(); while (mouse.btnpressed()) while (((clock()-Intl) > CLK_TCK) && mouse.btnpressed() && Dn->hit()) { Curr_Position = (Curr_Position < Max_Position)? ++Curr_Position : Max_Position; Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord < Height-8-(2*BTH)-HDH) ? Ycord : (Height-6-(2*BTH)-HDH); Hnd->moveto(X+2,Y+BTH+4+Ycord); delay(50); } Dn->show(); Last_Y = Ycord; } else if (hit() && !Dn->hit() && !Up->hit() && !Hnd->hit()) { if (mouse.getmY() < Hnd->getY()) // Clicked on Page Up. { Curr_Position = (Curr_Position >= Min_Position+Lines_Per_Page) ? (Curr_Position - Lines_Per_Page) : Min_Position; Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord > 0) ? Ycord : 0; Hnd->moveto(X+2,Y+BTH+4+Ycord); Intl = clock(); while (mouse.btnpressed()) while (((clock()-Intl) > CLK_TCK ) && mouse.btnpressed() && hit()) { Curr_Position = (Curr_Position >= Min_Position+Lines_Per_Page) ? (Curr_Position - Lines_Per_Page) : Min_Position; Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord > 0) ? Ycord : 0; Hnd->moveto(X+2,Y+BTH+4+Ycord); delay(50); } Last_Y = Ycord; } else // else, clicked Page Down. { Curr_Position = (Curr_Position <= Max_Position-Lines_Per_Page)? (Curr_Position + Lines_Per_Page) : Max_Position; Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord < Height-8-(2*BTH)-HDH) ? Ycord : (Height-8-(2*BTH)-HDH); Hnd->moveto(X+2,Y+BTH+4+Ycord); Intl = clock(); while (mouse.btnpressed()) while (((clock()-Intl) > CLK_TCK) && mouse.btnpressed() && hit()) { Curr_Position = (Curr_Position <= Max_Position-Lines_Per_Page)? (Curr_Position + Lines_Per_Page) : Max_Position; Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord < Height-8-(2*BTH)-HDH) ? Ycord : (Height-6-(2*BTH)-HDH); Hnd->moveto(X+2,Y+BTH+4+Ycord); delay(50); } Last_Y = Ycord; } } else if (Hnd->hit()) { while (mouse.btnpressed()) { Ycord = mouse.getmY(); if (Step_Size == 0) Curr_Position = Min_Position; else { Curr_Position = ((Ycord-Y-BTH-8-HDH/2)/ Step_Size)+Min_Position; Curr_Position = (Curr_Position >= Min_Position)? Curr_Position : Min_Position; Curr_Position = (Curr_Position <= Max_Position)? Curr_Position : Max_Position; } Ycord = (int)(Step_Size*(Curr_Position-Min_Position)); Ycord = (Ycord > 0) ? Ycord : 0; Ycord = (Ycord < Height-8-(2*BTH)-HDH) ? Ycord : (Height-8-(2*BTH)-HDH); if (Ycord != Last_Y) { Hnd->moveto(X+2,Y+BTH+4+Ycord); Last_Y = Ycord; } } } return 1; } return 0; } void vscroll::resize (int w, int h) { if (isShown) { hide(); Up->resize(w-2,BTH); Dn->resize(w-2,BTH); Dn->moveto(X+2,Y+h-BTH); Hnd->resize(w-2,HDH); panel::resize(w,h); show(); } else { Up->resize(w-2,BTH); Dn->resize(w-2,BTH); Dn->moveto(X+2,Y+h-BTH); Hnd->resize(w-2,HDH); panel::resize(w,h); } } void vscroll::setpagesize(int LPP) { Lines_Per_Page = LPP; } void vscroll::moveto (int x, int y) { int Ycord; if (isShown) { hide(); Up->moveto(x+2,y+2); Dn->moveto(x+2,y+Height-2-BTH); panel::moveto(x+1,y+1); show(); } else { Up->moveto(x+2,y+2); Dn->moveto(x+2,y+Height-2-BTH); panel::moveto(x+1,y+1); } } void vscroll::setbkgclr(int c) { panel::setbkgclr(c); } void vscroll::setbtnclr(int c) { Up->setbkgclr(c); Dn->setbkgclr(c); } void vscroll::sethdlclr(int c) { Hnd->setbkgclr(c); } void vscroll::setarrclr(int c) { Up->setextclr(c); Dn->setextclr(c); } hscroll::hscroll(int x, int y, int w, int h, int hdw, int bhw, int bc, int hc, int bkgc, int k) : panel (x+1,y+1,w-2,h-2,1,IN,bkgc,k) { int error = 0; char LfChr[2] = {27,0}, RtChr[2] = {26,0}; Lines_Per_Page = 5; Min_Position = 0; Max_Position = 100; Curr_Position = 0; if ((bhw < 10) || (h < 14)) { strcpy(LfChr,""); strcpy(RtChr,""); } Lf = new button(x+2,y+2,bhw,h-4,2,bc,0,TEXT,LfChr,0); if (!Lf) error = 1; Rt = new button(x+w-bhw-2,y+2,bhw,h-4,2,bc,0,TEXT,RtChr,0); if (!Rt) error = 1; Hnd = new panel(x+5+bhw,y+2,hdw,h-4,1,OUT,hc,1); if (!Hnd) error = 1; HDW = hdw; BTW = bhw; if (error) { if (Lf) delete Lf; if (Rt) delete Rt; if (Hnd) delete Hnd; closegraph(); cerr << "Memory allocation error in hscroll::hscroll." << endl; } } hscroll::~hscroll() { delete Lf; delete Rt; delete Hnd; } void hscroll::show(void) { float Step_Size; int Xcord; panel::show(); Lf->show(); Rt->show(); Hnd->show(); if (Max_Position-Min_Position == 0) Step_Size = 0; else Step_Size = (float)(Width-10-(2*BTW)-HDW)/(float)(Max_Position-Min_Position); Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord > 0) ? Xcord : 0; Xcord = (Xcord < Width-10-(2*BTW)-HDW) ? Xcord : (Width-10-(2*BTW)-HDW); Hnd->moveto(X+5+BTW+Xcord,Y+2); } void hscroll::hide(void) { if (!isShown) return; Hnd->hide(); Lf->hide(); Rt->hide(); panel::hide(); } void hscroll::setpos(int p) { float Step_Size; int Xcord; if (Max_Position-Min_Position == 0) Step_Size = 0; else Step_Size = (float)(Width-10-(2*BTW)-HDW)/(float)(Max_Position-Min_Position); Curr_Position = (p >= Min_Position)? p : Min_Position; Curr_Position = (p <= Max_Position)? Curr_Position : Max_Position; Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord > 0) ? Xcord : 0; Xcord = (Xcord < Width-10-(2*BTW)-HDW) ? Xcord : (Width-10-(2*BTW)-HDW); Hnd->moveto(X+5+BTW+Xcord,Y+2); } int hscroll::getpos(void) { return Curr_Position; } int hscroll::lfhit(void) { return Lf->hit(); } int hscroll::rthit(void) { return Rt->hit(); } int hscroll::hndhit(void) { return Hnd->hit(); } void hscroll::lfpres(void) { Lf->select(); } void hscroll::rtpres(void) { Rt->select(); } void hscroll::lfrels(void) { Lf->show(); } void hscroll::rtrels(void) { Rt->show(); } void hscroll::setbkgclr(int c) { panel::setbkgclr(c); } void hscroll::setbtnclr(int c) { Lf->setbkgclr(c); Rt->setbkgclr(c); } void hscroll::sethdlclr(int c) { Hnd->setbkgclr(c); } void hscroll::setarrclr(int c) { Lf->setextclr(c); Rt->setextclr(c); } int hscroll::getevent(void) { time_t Intl; float Step_Size; int Xcord, Last_X; if (Max_Position-Min_Position == 0) Step_Size = 0; else Step_Size = (float)(Width-10-(2*BTW)-HDW)/(float)(Max_Position-Min_Position); if (mouse.getbutton(LEFT_BTN) & panel::hit()) { if (Lf->hit()) { Lf->select(); Curr_Position = (Curr_Position > Min_Position) ? --Curr_Position : Min_Position; Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord > 0) ? Xcord : 0; Hnd->moveto(X+5+BTW+Xcord,Y+2); Intl = clock(); while (mouse.btnpressed()) while (((clock()-Intl) > CLK_TCK ) && mouse.btnpressed() && Lf->hit()) { Curr_Position = (Curr_Position > Min_Position) ? --Curr_Position : Min_Position; Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord > 0) ? Xcord : 0; Hnd->moveto(X+5+BTW+Xcord,Y+2); delay(50); } Last_X = Xcord; Lf->show(); } else if (Rt->hit()) { Rt->select(); Curr_Position = (Curr_Position < Max_Position)? ++Curr_Position : Max_Position; Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord < Width-10-(2*BTW)-HDW) ? Xcord : (Width-10-(2*BTW)-HDW); Hnd->moveto(X+5+BTW+Xcord,Y+2); Intl = clock(); while (mouse.btnpressed()) while (((clock()-Intl) > CLK_TCK) && mouse.btnpressed() && Rt->hit()) { Curr_Position = (Curr_Position < Max_Position)? ++Curr_Position : Max_Position; Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord < Width-10-(2*BTW)-HDW) ? Xcord : (Width-10-(2*BTW)-HDW); Hnd->moveto(X+5+BTW+Xcord,Y+2); delay(50); } Last_X = Xcord; Rt->show(); } else if (hit() && !Rt->hit() && !Lf->hit() && !Hnd->hit()) { if (mouse.getmX() < Hnd->getX()) // Clicked on Page Left. { Curr_Position = (Curr_Position >= Min_Position+Lines_Per_Page) ? Curr_Position-Lines_Per_Page : Min_Position; Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord > 0) ? Xcord : 0; Hnd->moveto(X+5+BTW+Xcord,Y+2); Intl = clock(); while (mouse.btnpressed()) while (((clock()-Intl) > CLK_TCK ) && mouse.btnpressed() && Lf->hit()) { Curr_Position = (Curr_Position >= Min_Position+Lines_Per_Page) ? Curr_Position-Lines_Per_Page : Min_Position; Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord > 0) ? Xcord : 0; Hnd->moveto(X+5+BTW+Xcord,Y+2); delay(50); } Last_X = Xcord; } else // Else, clicked on Page Right. { Curr_Position = (Curr_Position <= Max_Position-Lines_Per_Page)? Curr_Position+Lines_Per_Page : Max_Position; Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord < Width-10-(2*BTW)-HDW) ? Xcord : (Width-10-(2*BTW)-HDW); Hnd->moveto(X+5+BTW+Xcord,Y+2); Intl = clock(); while (mouse.btnpressed()) while (((clock()-Intl) > CLK_TCK) && mouse.btnpressed() && Rt->hit()) { Curr_Position = (Curr_Position <= Max_Position-Lines_Per_Page)? Curr_Position+Lines_Per_Page : Max_Position; Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord < Width-10-(2*BTW)-HDW) ? Xcord : (Width-10-(2*BTW)-HDW); Hnd->moveto(X+5+BTW+Xcord,Y+2); delay(50); } Last_X = Xcord; } } else if (Hnd->hit()) { while (mouse.btnpressed()) { Xcord = mouse.getmX(); if (Step_Size == 0) Curr_Position = Min_Position; else { Curr_Position = ((Xcord-X-BTW-5-HDW/2)/ Step_Size)+Min_Position; Curr_Position = (Curr_Position >= Min_Position)? Curr_Position : Min_Position; Curr_Position = (Curr_Position <= Max_Position)? Curr_Position : Max_Position; } Xcord = (int)(Step_Size*(Curr_Position-Min_Position)); Xcord = (Xcord < Width-10-(2*BTW)-HDW) ? Xcord : (Width-10-(2*BTW)-HDW); if (Last_X != Xcord) { Hnd->moveto(X+5+BTW+Xcord,Y+2); Last_X = Xcord; } } } return 1; } return 0; } void hscroll::moveto (int x, int y) { if (isShown) { hide(); Lf->moveto(x+2,y+2); Rt->moveto(x+Width-2-BTW,y+2); panel::moveto(x+1,y+1); show(); } else { Lf->moveto(x+2,y+2); Rt->moveto(x+Width-2-BTW,y+2); panel::moveto(x+1,y+1); } } void hscroll::resize (int w, int h) { int Xoff; if (isShown) { hide(); Lf->resize(BTW,h-2); Rt->resize(BTW,h-2); Rt->moveto(X+w-2-BTW,Y+2); Hnd->resize(w-2,HDW); panel::resize(w,h); show(); } else { Lf->resize(BTW,h-2); Rt->resize(BTW,h-2); Rt->moveto(X+w-2-BTW,Y+2); Hnd->resize(w-2,HDW); panel::resize(w,h); } } void hscroll::setrange(int min, int max) { Min_Position = min; Max_Position = max; if (Curr_Position < Min_Position) Curr_Position = Min_Position; if (Curr_Position > Max_Position) Curr_Position = Max_Position; } void hscroll::setpagesize(int LPP) { Lines_Per_Page = LPP; }