home *** CD-ROM | disk | FTP | other *** search
- /*
- Routines for menus using mouse
- */
- #include <stdio.h>
- #include <graphics.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include <dir.h>
- #include <conio.h>
- #include <dos.h>
- #include "fdestria.h"
- #include "fdesequa.h"
- #include "fdesfile.h"
- #include "fdesmous.h"
- #include "fdesplot.h"
- #define CURSOR_RIGHT (77<<8) /* cursor right key */
- #define CURSOR_LEFT (75<<8) /* cursor left key */
-
- float area_scaled; /* area scale factor from zooming */
- typedef struct {
- int selections; /* number of selections */
- char *item[16]; /* 16 strings that represent selections */
- } popmenu;
-
- #define ITEM_HEIGHT 20 /* Item height in pixels */
- #define CHAR_WIDTH 8 /* Item width per character in pixels */
-
- /* ************************************************************************
- pop-up menus
- ************************************************************************ */
- /* menu routines */
- int popup(int x, int y, popmenu *menu, int foreground, int background)
- /* display a pop-up menu and wait for mouse
- selection */
- {
- int i,rcode;
- int left,top,right,bottom;
- void *scr_save;
- mouse_state m;
- int maxwidth;
- maxwidth = 0;
- for (i=0; i<(*menu).selections; i++) {
- if (strlen((*menu).item[i]) > maxwidth)
- maxwidth = strlen((*menu).item[i]);
- }
- left = x;
- top = y;
- right = x + CHAR_WIDTH*maxwidth + 2;
- bottom = y + (*menu).selections*ITEM_HEIGHT;
- scr_save = malloc(imagesize(left,top,right,bottom));
- if (scr_save == NULL)
- {
- restorecrtmode();
- printf("Out of Memory, Sorry.");
- exit(0);
- }
- /* save screen portion */
- getimage(left,top,right,bottom,scr_save);
- /* display pop-up menu */
- setfillstyle(SOLID_FILL,background);
- bar(left,top,right,bottom);
- setcolor(foreground);
- for (i=0; i<(*menu).selections; i++) {
- outtextxy(left+2,top+i*ITEM_HEIGHT+6,(*menu).item[i]);
- }
- /* input selection from mouse */
- do {
- mouse_click(&m);
- rcode = (m.row - top - 2)/ITEM_HEIGHT + 1;
- } while ((rcode < 1) || (rcode > (*menu).selections)
- || !((m.col >= left) && (m.col <= right)));
-
- /* restore screen portion */
- putimage(left,top,scr_save,COPY_PUT);
- free(scr_save);
- return(rcode);
- }
-
- int mleft[10],mtop[10],mright,mbottom;
- void *mscr_save[10];
- int mscr_sp = -1;
- /*
- putmsg
- returns next pixel in X direction
- */
- int putmsg(int x, int y, char *str, int colorbk, int colorfo) /* display a pop-up message */
- {
- if (strlen(str) == 0) return(x);
- mscr_sp++;
- mleft[mscr_sp] = x;
- mtop[mscr_sp] = y;
- mright = x + strlen(str)*CHAR_WIDTH + 2;
- mbottom = y + ITEM_HEIGHT;
- mscr_save[mscr_sp] = malloc(imagesize(mleft[mscr_sp],mtop[mscr_sp],
- mright,mbottom));
- if (mscr_save[mscr_sp] == NULL)
- {
- restorecrtmode();
- printf("Out of Memory, Sorry.");
- exit(0);
- }
- /* save screen portion */
- getimage(mleft[mscr_sp],mtop[mscr_sp],mright,mbottom,mscr_save[mscr_sp]);
- /* display pop-up menu */
- setfillstyle(SOLID_FILL,colorbk);
- bar(mleft[mscr_sp],mtop[mscr_sp],mright,mbottom);
- setcolor(colorfo);
- outtextxy(mleft[mscr_sp]+2,mtop[mscr_sp]+6,str);
- return(mright+1);
- }
- void clrmsg(void)
- {
- /* restore screen portion */
- if (mscr_sp < 0) {
- restorecrtmode();
- printf("Too many pops of message text");
- exit(0);
- }
- putimage(mleft[mscr_sp],mtop[mscr_sp],mscr_save[mscr_sp],COPY_PUT);
- free(mscr_save[mscr_sp--]);
- }
- /*
- putmsg destructive
- */
- int putmsg_d(int x, int y, char *str, int colorbk, int colorfo) /* display a pop-up message */
- {
- int mleft,mright,mtop,mbottom;
- if (strlen(str) == 0) return(x);
- mleft = x;
- mtop = y;
- mright = x + strlen(str)*CHAR_WIDTH + 2;
- mbottom = y + ITEM_HEIGHT;
- /* display pop-up menu */
- setfillstyle(SOLID_FILL,colorbk);
- bar(mleft,mtop,mright,mbottom);
- setcolor(colorfo);
- outtextxy(mleft+2,mtop+6,str);
- return(mright+1);
- }
-
- /* ************************************************************************
- A 'scanf' for graphics mode
- returns # of arguments
- ************************************************************************ */
- int gscanf(int x, int y, char *prompt, int maxlength, char *format, ...)
- {
- char buf[133];
- int si; /* string index into buf */
- va_list parmlist;
- unsigned int ch;
- int input_x;
- int i;
- int rcode;
- int mleft, mtop, mright, mbottom;
-
- input_x = putmsg(x,y,prompt,YELLOW,RED);
-
- for (i=0; i<maxlength; i++) buf[i]='_';
- buf[maxlength] = 0;
- putmsg(input_x, y, buf, WHITE, BLUE);
-
- buf[0] = 0; /* null the string */
- si = 0;
- do {
- if ((ch = getch()) == 0) ch = getch() << 8;
-
- if (ch == 015) break; /* carriage return */
- if (ch == 033) /* escape */
- {
- clrmsg();
- clrmsg();
- return(0);
- }
- switch (ch)
- {
- case 010: /* backspace */
- if (si == 0) break;
- si--;
- buf[si] = 0;
- break;
- default:
- if (si == maxlength) break;
- buf[si++] = ch;
- buf[si] = 0;
- break;
- }
- mleft = input_x;
- mtop = y;
- mright = input_x + maxlength*CHAR_WIDTH + 2;
- mbottom = y + ITEM_HEIGHT;
- setfillstyle(SOLID_FILL,WHITE);
- bar(mleft,mtop,mright,mbottom);
- setcolor(BLUE);
- outtextxy(mleft+2,mtop+6,buf);
- } while (1);
-
- if (strlen(buf) != 0)
- {
- va_start(parmlist,format);
- rcode = vsscanf(buf,format,parmlist);
- va_end(parmlist);
- }
- else rcode = 0;
- clrmsg();
- clrmsg();
- return(rcode);
- }
-
- /***************************************************************************
- Returns filename pointed to by mouse
- ****************************************************************************/
- int fname_cmp(char *s1,char *s2)
- {
- return(strcmp(s1,s2));
- }
- char trn_select[15];
- char *trn_directory(void) /* returns NULL if no files */
- {
- struct ffblk ffblock;
- int num_files,i;
- mouse_state m;
- char trn_files[240][9];
- char fname[15];
- cleardevice();
- if (findfirst("*.TRN",&ffblock,0) == -1)
- {
- putmsg(100,100,"No .TRN files in directory",BLUE,WHITE);
- mouse_click(&m);
- clrmsg();
- return(NULL);
- }
- else {
- num_files = 0;
- /* get directory from DOS */
- do {
- strncpy(fname,ffblock.ff_name,14);
- stpcpy(trn_files[num_files],strtok(fname,". "));
- num_files++;
- } while ((findnext(&ffblock) == 0) && (num_files < 240));
- qsort(trn_files[0],num_files,9,fname_cmp);
- /* display on screen */
- cleardevice();
- setcolor(LIGHTGREEN);
- for (i=0; i<num_files; i++)
- {
- outtextxy((i/30)*80,(i%30)*10,trn_files[i]);
- }
- /* input mouse pointer */
- putmsg(0,330,"Click Left to view, Right to End",RED,WHITE);
-
- plot_type = 1; /* do a small plot while inputting */
- mouse_idle_job = doIFSrand; /* do a small plot while inputting */
- do {
- mouse_click(&m);
- if (m.buttons & MOUSE_LEFT)
- {
- i = (m.row/10)%30 + (m.col/80)*30;
-
- if (i>(num_files-1))
- {
- putmsg(100,100,"click on filename",WHITE,RED);
- delay(1000);
- clrmsg();
- }
- else
- {
- stpcpy(trn_select,trn_files[i]);
-
- /* load in the file */
- if (trnfile_load(trn_select) != 0) {
- IFS_changed = 1;
- }
- }
- }
- } while (!(m.buttons & MOUSE_RIGHT));
- clrmsg();
-
- mouse_idle_job = mouse_idle;
- return(trn_select);
- }
- ;
- }
- /*****************************************************************************
- Non-destructive line drawing
- ******************************************************************************/
- void *line_stack[10];
- int left[10],top[10];
-
- int lsp = -1;
- void line_ovly(int x1,int y1,int x2,int y2)
- {
- int right,bottom;
- lsp++;
- if (x1 <= x2)
- {
- left[lsp] = max(0,x1 - 2);
- right = min(x2 + 2,maxx);
- }
- else
- {
- left[lsp] = max(0,x2 - 2);
- right = min(x1 + 2,maxx);
- }
- if (y1 <= y2)
- {
- top[lsp] = max(0,y1 - 2);
- bottom = min(y2 + 2,maxy);
- }
- else
- {
- top[lsp] = max(0,y2 - 2);
- bottom = min(y1 + 2,maxy);
- }
- line_stack[lsp] = malloc(imagesize(left[lsp],top[lsp],right,bottom));
- getimage(left[lsp],top[lsp],right,bottom,line_stack[lsp]);
- setcolor(WHITE);
- line(x1,y1,x2,y2);
- }
- void line_clear(void)
- {
- putimage(left[lsp],top[lsp],line_stack[lsp],COPY_PUT);
- free(line_stack[lsp]);
- lsp--;
- }
- /******************************************************************************
- Mouse input of a zoom box
- ******************************************************************************/
- void box_new(int *x1, int *y1, int *x2, int *y2)
- {
- mouse_state m;
- float widthx,widthy;
- float centerx,centery;
- int oldcol,oldrow;
- float oldwidthx,oldwidthy;
- float oldcenterx,oldcentery;
-
- widthx = 300.0;
- widthy = widthx*3.0/4.0;
- centerx = maxx/2.0;
- centery = maxy/2.0;
- m.row = maxy/2.0;
- m.col = maxx/2.0;
- mouse_put(&m);
- *x1 = centerx - widthx/2.0;
- *x2 = centerx + widthx/2.0;
- *y1 = centery - widthy/2.0;
- *y2 = centery + widthy/2.0;
- while (mouse_get(&m) != 0x00) ;
- putmsg(10,10,"Press any key to accept",YELLOW,BLACK);
- setlinestyle(DASHED_LINE,0,NORM_WIDTH);
- line_ovly(*x1,*y1,*x1,*y2);
- line_ovly(*x2,*y1,*x2,*y2);
- line_ovly(*x1,*y1,*x2,*y1);
- line_ovly(*x1,*y2,*x2,*y2);
- oldrow = m.row;
- oldcol = m.col;
- do
- {
- mouse_get(&m);
- oldwidthx = widthx;
- oldwidthy = widthy;
- oldcenterx = centerx;
- oldcentery = centery;
- if ((m.col != oldcol) || (m.row != oldrow))
- {
- if (m.buttons&MOUSE_LEFT)
- {
- widthx *= (1.0 + (m.row-oldrow)/100.0);
- if (widthx < 20.0) widthx = 20.0;
- widthy = widthx*3.0/4.0;
- }
- else
- {
- centerx += (m.col-oldcol);
- centery += (m.row-oldrow);
- }
- m.row = maxy/2.0;
- m.col = maxx/2.0;
- mouse_put(&m);
- *x1 = centerx - widthx/2.0;
- *x2 = centerx + widthx/2.0;
- *y1 = centery - widthy/2.0;
- *y2 = centery + widthy/2.0;
- if ((*x1 <= 2.0) || (*x2 >maxx-2.0) || (*y1 <= 2.0)
- || (*y2 >= (maxy-2.0)))
- {
- widthx = oldwidthx;
- widthy = oldwidthy;
- centerx = oldcenterx;
- centery = oldcentery;
- *x1 = centerx - widthx/2.0;
- *x2 = centerx + widthx/2.0;
- *y1 = centery - widthy/2.0;
- *y2 = centery + widthy/2.0;
- }
- line_clear();
- line_clear();
- line_clear();
- line_clear();
- line_ovly(*x1,*y1,*x1,*y2);
- line_ovly(*x2,*y1,*x2,*y2);
- line_ovly(*x1,*y1,*x2,*y1);
- line_ovly(*x1,*y2,*x2,*y2);
- oldcol = m.col;
- oldrow = m.row;
- }
- } while (!kbhit());
- if (getch() == 0) getch();
- line_clear();
- line_clear();
- line_clear();
- line_clear();
- clrmsg();
- }
- /******************************************************************************
- Zooming on plot
- This code really belongs somewhere else.
- ******************************************************************************/
- void zoom_in(void)
- {
- int x1,y1,x2,y2;
- float xscale,xoffset,yscale,yoffset;
-
- putmsg(0,0,"Zoom Box",BLUE,WHITE);
- box_new(&x1,&y1,&x2,&y2);
- clrmsg();
-
- if (x1 == x2) return;
- if (y1 == y2) return;
- xscale = maxx/(x2-x1);
- yscale = maxy/(y2-y1);
- if (xscale > yscale) xscale = yscale;
- else yscale = xscale;
- xoffset = -((x1+x2)/2.0)*xscale + maxx/2.0;
- yoffset = -((y1+y2)/2.0)*yscale + maxy/2.0;
-
- /* scale relative to already scaled triangles */
- IFS_rescale(xscale,xoffset,yscale,yoffset,1);
- area_scaled *= xscale;
- area_scaled *= yscale;
- }
- void zoom_out(void)
- {
- area_scaled = 1.0;
- IFS_changed = 1;
- cleardevice();
- doIFSrand();
- }
-
-