home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
d
/
dots151.zip
/
GRAPHSRC.ZIP
/
GMOUSE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-16
|
28KB
|
976 lines
#define RR(x) /* sprintf x; note(buf); scr_ci() /**/
#define NOMOUSE
/*
gmouse - mouse handler for graph
The top level routine here is adjust_parameters. It expects
the calling program to have put the screen into graphics mode.
#include <string.h>
*/
#include <stdio.h>
#include <math.h>
#ifdef __DESMET__
#define far
#else
#include <string.h>
#endif
#define exp10(x) exp((x)*2.302585093) /* 10**x */
#include "scr_ci.h"
#include "g.h"
#include "graph.h"
#include "window.h"
#define ENTRIES 5000
#define MAXSTYLES 100
#define MIN_GRID_STYLE (-4)
#define BUFSIZE 200
/* local functions */
static MODEL adjust_abscissas( );
static MODEL adjust_grid( );
static MODEL adjust_label( );
static MODEL adjust_limits( float *x, double *min, double *max,
int *log_scale, float *y );
static MODEL adjust_styles( );
static MODEL adjust_window( MESSAGE msg, int *data, WINDOW *pw );
static double MODEL fetch_value( double deflt, double least, double most );
static MODEL GetStyleCode( char *buf );
static MODEL script_file( int *argcp, char ***argvp );
static MODEL ShowStyles( MESSAGE msg, int *data, WINDOW *pw );
static MODEL show_style( char *buf, int n, int style );
extern char buf[BUFSIZE];
char buf2[BUFSIZE];
extern char *text_label, *default_label;
extern double xmin, xmax, xdel, ymin, ymax, ydel;
extern double
requested_height_used, /* fraction of vertical space used */
requested_width_used, /* fraction of horizontal space used */
requested_right_move, /* fraction of space to move right before plotting */
requested_up_move, /* fraction of space to move up before plotting */
abscissa, /* current value for automatic abscissas */
abscissa_start, /* default starting value for automatic abscissas */
abscissa_step; /* default step for automatic abscissas */
extern int breaking; /* nonzero if breaking (disconnecting)
graph after each label in input */
extern int equal; /* nonzero if vertical and horizontal
scales must be equal */
extern int debugging;
extern int default_labeling; /* nonzero if default point label was given */
extern int grid_width; /* width of grid lines */
extern int grid_style; /* 0 for no grid, 1 for frame with tics,
2 for full grid */
extern int numeric_labeling;
extern int out_of_memory; /* set nonzero when malloc fails */
extern int transposing; /* nonzero if transposing x & y */
extern int labels; /* number of user-supplied labels */
extern int logx; /* nonzero if x axis is to be logrithmic */
extern int logy; /* nonzero if y axis is to be logrithmic */
extern int requested_rlx; /* approximate number of x axis labels */
extern int requested_rtx; /* requested # tics on axis */
extern int requested_rly; /* approximate number of y axis labels */
extern int requested_rty; /* requested # tics on axis */
extern int standard_input; /* nonzero if data is from standard input */
extern int text_labeling;
extern int x_arguments; /* number specified: xmin, xmax, xdel */
extern int y_arguments; /* number specified: ymin, ymax, ydel */
extern int style[MAXSTYLES]; /* array of requested line styles */
extern int repeat[MAXSTYLES]; /* array of repeat counts for line styles */
extern int numstyles; /* # linestyles specified by user */
extern int automatic_abscissas; /* nonzero if abscissas are to be generated */
extern int magnitude; /* nonzero if showing magnitude of complex # */
extern int max_points; /* # x or y points */
extern int phase; /* nonzero if displaying phase of complex # */
extern int dividing_by_pi; /* nonzero if dividing phase by pi */
extern int last; /* number of entries in x and y */
extern FILE *file;
extern float *x, *y;
extern int set_linestyle(), set_linewidth(), set_color_or_intensity();
extern int (*after_line)();
int (*set_line_attribute)() = set_linewidth;
extern double /* imported from g31.c */
rot11, rot12, rot13, rot14, /* rotation & projection matrix */
rot21, rot22, rot23, rot24;
typedef struct _blk
{struct _blk *nxt;
int num;
char txt[1];
} BLOCK;
extern BLOCK *top_label;
extern char *default_script_file;
static int mouseInstalled = 0;
#define BIG 1.e100
#define up_char 30
#define down_char 31
static MENU *main_men, *x_men, *f_men, *s_men, *g_men, *a_men;
WINDOW *bwin, *qwin, *dwin;
double fetch_value(deflt, least, most) double deflt, least, most;
{ double value, eps;
eps = .000001*(most - least);
while(1)
{
sprintf(buf, "%2.4g", deflt);
WinGetString("new value?", buf, 0, char_width, 2*char_height, qwin);
if(!buf[0]) {value = deflt; break;}
value = atof(buf);
if(least - eps < value && value < most + eps) break;
sprintf(buf, "must be in range %2.4g ... %2.4g", least, most);
note(buf);
}
if(dwin->vis) (*dwin->accept)(CLEAR, NULL, dwin);
(*qwin->accept)(CLEAR, NULL, qwin);
/*
scr_rowcol(23, 0);
if(.1 < fabs(value) && fabs(value) < 1.)
printf("value revised to %5.4f", value);
else
printf("value revised to %2.4g", value);
scr_clrl();
*/
return value;
}
static note(format, s) char *format, *s;
{ sprintf(buf, format, s);
if(dwin->vis) (*dwin->accept)(CLEAR, NULL, dwin);
WinShowString(buf, char_width, char_height, dwin);
}
BUTTON x_strings[] =
{
{" min & max", "m", "m"}, /* "adjust limits of data to be shown", */
{" log/linear", "l", "l"}, /* "log/linear scale (toggle)", */
{0}
};
adjust_limits(x, min, max, log_scale, y)
float *x, *y;
double *min, *max;
int *log_scale;
{ int c, ch, i, j, cur_style, cur_repeat, warned;
double new_min, new_max, data_min, data_max, temp;
char *finish_msg;
static char log_msg[] = "log scale", lin_msg[] = "linear scale",
discard_msg[] = "nonpositive points discarded";
BLOCK *current_label, **ppb;
c = MenuResponse(x_men);
warned = 0;
switch(c)
{case 'm':
while(1)
{
if(*log_scale) {new_min = exp10(*min); new_max = exp10(*max);}
else {new_min = *min; new_max = *max;}
sprintf(buf, "%2.4g %2.4g", new_min, new_max);
ch = WinGetString("new limits?", buf, 0, char_width,
2*char_height, qwin);
if(ch == 0 || ch == up_char || !buf[0]) goto X_QUIT;
sscanf(buf, "%lf %lf", &new_min, &new_max);
if(new_min >= new_max)
note(" must have min < max");
else if(*log_scale && new_min<=0.)
note(" need positive values for log scale");
else break;
}
if(dwin->vis) (*dwin->accept)(CLEAR, NULL, dwin);
(*qwin->accept)(CLEAR, NULL, qwin);
/*
printf("limits revised to %2.4g %2.4g", new_min, new_max);
*/
if(*log_scale)
{new_min = log10(new_min);
new_max = log10(new_max);
}
*min = new_min;
*max = new_max;
break;
case 'l':
{
if(*log_scale)
{
finish_msg = lin_msg;
*min = exp10(*min);
*max = exp10(*max);
for (i = 0; i <= last; i++) x[i] = (float)exp10(x[i]);
*log_scale = 0;
}
else
{finish_msg = log_msg;
/* discard nonpositive data points */
current_label = top_label;
for (i = j = 0; i <= last; i++)
{
temp = (double)x[i];
if(temp > 0.)
{y[j] = y[i];
x[j++] = (float)log10(temp);
}
if(current_label->num == i)
{current_label->num = j?j-1:0;
current_label = current_label->nxt;
}
}
if(j == 0)
{
note("there are no positive data values");
scr_ci(); /* wait for one keystroke */
terminate(1);
}
else if(last != j-1) finish_msg = discard_msg;
last = j - 1;
/* keep last label for each point */
ppb = &top_label;
if(*ppb)
{
i = j = 0;
cur_style = style[i];
cur_repeat = repeat[i];
repeat[j] = 0;
while((*ppb)->nxt)
{
if((*ppb)->num == (*ppb)->nxt->num)
{ /* discard a label */
*ppb = (*ppb)->nxt;
labels--;
}
else
{ /* keep a label */
ppb = &((*ppb)->nxt);
if(cur_style != style[j])
{
style[++j] = cur_style;
repeat[j] = 0;
}
repeat[j]++;
}
if(--cur_repeat <= 0)
{cur_repeat = repeat[++i];
cur_style = style[i];
}
}
}
/*
if current lower or upper limit is now
invalid (nonpositive), replace with
minimum (or maximum) remaining data value
*/
data_min = data_max = x[0];
for (i = 1; i <= last; i++)
{temp = (double)x[i];
if(temp<data_min) data_min = temp;
if(temp>data_max) data_max = temp;
}
if(*min <= 0.) *min = exp10(data_min);
if(*max <= *min) *max = exp10(data_max);
take_log(min);
take_log(max);
*log_scale = 1;
}
note(finish_msg);
break;
}
}
X_QUIT:
(*x_men->accept)(CLEAR, NULL, x_men);
if(qwin->vis) (*qwin->accept)(CLEAR, NULL, qwin);
}
BUTTON a_strings[] =
{
{" start", "s", "s"}, /* "abscissa starting value", */
{" increment", "i", "i"}, /* "abscissa increment", */
{0}
};
adjust_abscissas()
{ int c, i;
double val;
BLOCK *current_label;
if(automatic_abscissas)
{while(c = MenuResponse(a_men))
{switch(c)
{case 'i':
abscissa_step = fetch_value(abscissa_step, -BIG, BIG);
break;
case 's':
abscissa_start = fetch_value(abscissa_start, -BIG, BIG);
break;
}
}
(*a_men->accept)(CLEAR, NULL, a_men);
}
else
{
for (i=0; i <= last; i++) y[i] = x[i];
automatic_abscissas = 1;
ymin = xmin;
ymax = xmax;
note("old y values discarded");
}
xmin = xmax = val = abscissa_start;
current_label = top_label;
for (i=0; i <= last; i++)
{x[i] = (float)val;
if(val < xmin) xmin = val;
if(val > xmax) xmax = val;
val += abscissa_step;
if(current_label->num == i)
{val = abscissa_start;
current_label = current_label->nxt;
}
}
automatic_abscissas = 1;
}
BUTTON s_strings[] =
{
{" 0", "0", "0"},
{" 1", "1", "1"},
{" 2", "2", "2"},
{" 3", "3", "3"},
{" 4", "4", "4"},
{" 5", "5", "5"},
{" 6", "6", "6"},
{" 7", "7", "7"},
{" 8", "8", "8"},
{" 9", "9", "9"},
{" a", "a", "a"},
{" b", "b", "b"},
{" c", "c", "c"},
{" d", "d", "d"},
{" e", "e", "e"},
{" f", "f", "f"},
{" previous ", "p", "p"},
{0}
};
#ifndef NOMOUSE
void ShowStyles(msg, data, pw) MESSAGE msg; int *data; WINDOW *pw;
{ int i, x0, x1, y0;
if(msg == REDRAW)
{MsgMenu(msg, data, pw);
HideMouseCursor();
x0 = pw->x + 2*char_width;
x1 = x0 + 10*char_width;
y0 = pw->y + char_height/2;
for (i = 0; i < 16; i++)
{
(*set_line_attribute)(i);
(*after_line)(x0, y0, x1, y0);
y0 += char_height;
}
(*draw_line)(data[0], data[1], data[2], data[3]);
ShowMouseCursor();
}
else
MsgMenu(msg, data, pw);
}
#endif /* NOMOUSE */
GetStyleCode(buf) char *buf;
{ int ch, code;
set_linestyle(0);
set_linewidth(1);
set_color_or_intensity(0);
set_line_attribute = set_linewidth;
ch = MenuResponse(s_men);
if(ch == 'p' || ch == 0) return ch;
else if(ch == ' ') return RETURN;
code = ch - '0';
set_line_attribute = set_color_or_intensity;
ch = MenuResponse(s_men);
if(ch == 'p' || ch == 0) return ch;
else if(ch == ' ') return RETURN;
code = code*16 + ch - '0';
set_line_attribute = set_linestyle;
ch = MenuResponse(s_men);
if(ch == 'p' || ch == 0) return ch;
else if(ch == ' ') return RETURN;
code = code*16 + ch - '0';
show_style(buf, 1, code);
return RETURN;
}
adjust_styles()
{
int i, j, ch, num;
char *s, *token;
i = 0;
while(1)
{if(i == numstyles && i < MAXSTYLES)
{style[i] = repeat[i] = 1;
numstyles++;
}
sprintf(buf2, "line style for group %2d: ", i);
show_style(buf, repeat[i], style[i]);
ch = WinGetString(buf2, buf, 0, char_width, 2*char_height, qwin);
(*qwin->accept)(CLEAR, NULL, qwin);
/*
ch = GetStyleCode(buf);
(*s_men->accept)(CLEAR, NULL, s_men);
if(ch == 'p' && i) repeat[i - 1]++;
else
*/
if(ch == 0) break;
else if(ch == up_char)
{if(i > 0) i--;
}
else if(ch == down_char)
{if(i < numstyles) i++;
}
else
{ /* delete this style */
for (j=i; j<numstyles-1; j++)
{style[j] = style[j+1];
repeat[j] = repeat[j+1];
}
numstyles--;
if(token = strtok(buf, " "))
{do
{ /* insert a style */
if(numstyles == MAXSTYLES) break;
for (j = numstyles++; j > i; j--)
{style[j] = style[j-1];
repeat[j] = repeat[j-1];
}
num = 1;
if(s = strchr(token,'*'))
{num = atoi(token);
s++;
}
else s = token;
repeat[i] = num<1 ? 1 : num;
style[i++] = atox(s);
} while (token = strtok(0, " "));
}
}
}
if(numstyles > 1) breaking = 1;
/* (*qwin->accept)(CLEAR, NULL, qwin); */
}
show_style(buf, n, style) char *buf; int n, style;
{ char stylebuf[10];
if(n > 1) sprintf(buf, "%d*", n); else buf[0] = 0;
if(style<0) sprintf(stylebuf, "-%x", -style);
else sprintf(stylebuf, "%x", style);
strcat(buf, stylebuf);
}
BUTTON main_strings[] =
{
{" / (redraw)", "/", "/"}, /* "redisplay graph", */
{" abscissas", "a", "a"}, /* "automatically generate abscissas", */
{" break +-", "b", "b"}, /* "break line after each label (toggle)", */
{" equal +-", "e", "e"}, /* "equal vertical and horizontal scales (toggle)", */
{" file", "f", "f"}, /* "script file input/output", */
{" grid", "g", "g"}, /* "grid style", */
{" label", "l", "l"}, /* "label for top of graph", */
{" marker", "m", "m"}, /* "marker and line styles", */
{" numbers +-", "n", "n"}, /* "numeric labels on axes (toggle)", */
{" quit", "q", "q"}, /* "terminate program", */
{" transpose +-", "t", "t"}, /* "transpose x and y axes (toggle)", */
{" x", "x", "x"}, /* "x axis plotting range", */
{" y", "y", "y"}, /* "y axis plotting range", */
{" right", "r", "r"}, /* "offset of plot to right", */
{" up", "u", "u"}, /* "offset of plot upwards", */
{" height", "h", "h"}, /* "height of plot", */
{" width", "w", "w"}, /* "width of plot", */
{" zoom", "z", "z"}, /* "zoom out", */
/* {" debug", "d", "d"}, /* "debug mouse code", */
{0}
};
adjust_parameters(argcp, argvp) int *argcp; char ***argvp;
{ int c, i;
double d;
float *pf;
static int WasReset = 0, numButtons, status, horiz, vert;
#ifndef NOMOUSE
if(mouseInstalled)
{
if(!WasReset) {FlagReset(&status, &numButtons); WasReset = 1;}
do
{GetPosBut(&status, &horiz, &vert);
} while (status);
SetEventHandler(1 + 2 + 4 + 8, MouseHandler);
ShowMouseCursor();
}
#endif
while(c = MenuResponse(main_men))
{if(c == '/') break;
switch(c)
{case 'e':
equal ^= 1;
note("%sequal scales", equal ? "" : "un");
break;
case 'a': adjust_abscissas(); break;
case 'l': adjust_label(); break;
case 'm': adjust_styles(); break;
case 't':
transposing ^= 1;
i = logx; logx = logy; logy = i;
pf = x; x = y; y = pf;
d = xmin; xmin = ymin; ymin = d;
d = xmax; xmax = ymax; ymax = d;
d = xdel; xdel = ydel; ydel = d;
note("%stransposing scales", transposing ? "" : "not ");
break;
case 'f':
script_file(argcp, argvp);
break;
case 'b':
breaking ^= 1;
note("%sbreaking after labels", breaking ? "" : "not ");
break;
case 'n':
numeric_labeling ^= 1;
note("numeric labels %sabled",
numeric_labeling ? "en" : "dis");
break;
case 'h':
requested_height_used = fetch_value(requested_height_used,
.01, 1.);
if(requested_height_used + requested_up_move > 1.)
requested_up_move = 1. - requested_height_used;
break;
case 'w':
requested_width_used = fetch_value(requested_width_used,
.01, 1.);
if(requested_width_used + requested_right_move > 1.)
requested_right_move = 1. - requested_width_used;
break;
case 'u':
requested_up_move = fetch_value(requested_up_move, 0., .99);
if(requested_height_used + requested_up_move > 1.)
requested_height_used = 1. - requested_up_move;
break;
case 'r':
requested_right_move = fetch_value(requested_right_move,
0., .99);
if(requested_width_used + requested_right_move > 1.)
requested_width_used = 1. - requested_right_move;
break;
case 'q': terminate();
case 'g': adjust_grid(); break;
case 'x': adjust_limits(x, &xmin, &xmax, &logx, y); break;
case 'y': adjust_limits(y, &ymin, &ymax, &logy, x); break;
case 'z':
d = xmax - xmin; xmin -= d; xmax += d;
d = ymax - ymin; ymin -= d; ymax += d;
ungets("\033");
break;
/*
case 'd':
{extern int WinVis;
sprintf(buf, "curves = %d", curves);
WinShowString(buf, char_width, char_height, dwin);
break;
}
*/
default:;
}
}
#ifndef NOMOUSE
if(mouseInstalled)
{SetEventHandler(0, MouseHandler);
HideMouseCursor();
}
#endif
(*bwin->accept)(HIDE, NULL, bwin);
(*main_men->accept)(CLEAR, NULL, main_men);
if(dwin->vis) (*dwin->accept)(CLEAR, NULL, dwin);
if(qwin->vis) (*qwin->accept)(CLEAR, NULL, qwin);
/*
clear_graphics();
*/
}
adjust_label()
{ char *malloc();
if(!text_labeling)
{
text_label = malloc(80);
if(!text_label) {terminate();}
text_labeling = 1;
text_label[0] = 0;
}
WinGetString("label?", text_label, 0, char_width, 2*char_height, qwin);
}
BUTTON f_strings[] =
{
{" output", "o", "o"}, /* "write both format and data file names" */
{" format", "f", "f"}, /* "write format only" */
{" data", "d", "d"}, /* "write data file names only" */
{" input", "i", "i"}, /* "read format from script file", */
{0}
};
script_file(argcp, argvp) int *argcp; char ***argvp;
{
int c, ch, i, output_format, output_data_file_names, paramc, error;
FILE *sfile;
char **paramsp;
double min, max;
static char *params[2] = {"-f", ""};
c = MenuResponse(f_men);
if(c == 'i')
{do
{
strcpy(buf2, default_script_file);
ch = WinGetString("file name? ", buf2, 0, char_width, 2*char_height,
qwin);
(*qwin->accept)(CLEAR, NULL, qwin);
if(ch != 0x0d) break;
/* reset to initial conditions */
breaking = equal = default_labeling = dividing_by_pi = labels =
magnitude = numstyles = phase =
text_labeling = transposing = 0;
grid_width = grid_style = numeric_labeling = 1;
requested_rlx = requested_rly = 6;
requested_rtx = requested_rty = 30;
requested_height_used = requested_width_used = 1.;
requested_right_move = requested_up_move = 0.;
params[1]=buf2;
paramsp = params;
paramc = 2;
if(error = parse_args(¶mc, ¶msp))
{if(dwin->vis) (*dwin->accept)(CLEAR, NULL, dwin);
WinShowString(buf, char_width, char_height, dwin);
}
} while(error);
}
else if(c == 'o' || c == 'f' || c == 'd')
{
output_format = (c == 'o' || c == 'f');
output_data_file_names = (c == 'o' || c == 'd');
strcpy(buf, default_script_file);
ch = WinGetString("file name? ", buf, 0, char_width, 2*char_height, qwin);
(*qwin->accept)(CLEAR, NULL, qwin);
if(ch == 0x0d)
{unlink(buf);
sfile = fopen(buf, "w");
if(sfile == 0) note("cannot open %s", buf);
else
{
if(output_data_file_names)
{for (i = 0; i < *argcp; i++)
fprintf(sfile, "%s ", (*argvp)[i]);
fprintf(sfile, "\n");
}
if(output_format)
{
if(automatic_abscissas)
fprintf(sfile, "-a %g %g ", abscissa_step, abscissa_start);
if(breaking) fprintf(sfile, "-b ");
if(!numeric_labeling) fprintf(sfile, "-n ");
if(default_labeling) fprintf(sfile, "-c %s ", default_label);
if(equal) fprintf(sfile, "-e ");
if(requested_width_used != 1.)
fprintf(sfile, "-w %5.3f ", requested_width_used);
if(requested_right_move != 0.)
fprintf(sfile, "-r %5.3f ", requested_right_move);
if(requested_height_used != 1.)
fprintf(sfile, "-h %5.3f ", requested_height_used);
if(requested_up_move != 0.)
fprintf(sfile, "-u %5.3f ", requested_up_move);
fprintf(sfile, "-g %d %d %d\n", grid_style, requested_rtx/requested_rlx,
grid_width);
if(text_labeling) fprintf(sfile, "-l \"%s\"\n", text_label);
if(numstyles)
{fprintf(sfile, "-m");
for (i=0; i<numstyles; i++)
{show_style(buf, repeat[i], style[i]);
fprintf(sfile, " %s", buf);
if((i&7) == 7 || i == numstyles - 1)
fprintf(sfile, "\n");
}
}
if(transposing)
{fprintf(sfile, "-t ");
min = ymin; max = ymax;
}
else {min = xmin; max = xmax;}
if(logx) {min = exp10(min); max = exp10(max);}
fprintf(sfile, "-x%s %2.4g %2.4g ",
logx ? "l" : "",
min, max);
if(transposing) {min = xmin; max = xmax;}
else {min = ymin; max = ymax;}
if(logy) {min = exp10(min); max = exp10(max);}
fprintf(sfile, "\n-y%s%s%s%s %2.4g %2.4g\n",
logy ? "l" : "",
magnitude ? "m" : "",
phase ? "p" : "",
dividing_by_pi ? "p" : "",
min, max);
fclose(sfile);
}
}
}
}
(*f_men->accept)(CLEAR, NULL, f_men);
}
BUTTON g_strings[] =
{
{" grid +-", "g", "g"}, /* "show/eliminate grid (toggle)", */
{" tics", "t", "t"}, /* "tic marks per numerical label", */
{" full +-", "f", "f"}, /* "full grid or tic marks only (toggle)", */
{" inside +-", "i", "i"}, /* "tic marks on inside or outside (toggle)", */
{" 2 sides", "2", "2"}, /* "show axes on only two sides", */
{" 4 sides", "4", "4"}, /* "show axes on all four sides", */
{" separation +-", "s", "s"}, /* "separate axes from graph", */
{" width", "w", "w"}, /* "grid line width", */
{0}
};
adjust_grid()
{ int c;
static int toggle_separation[] = {-1, -4, -4, -4, 0, 4, 4, 4, 1};
static int to_four_sides[] = {-1, -1, -1, -1, 0, 1, 2, 1, 1};
c = MenuResponse(g_men);
{switch(c)
{case 'g':
if(grid_style) grid_style = 0; else grid_style = 1;
note("grid %sabled", grid_style?"en":"dis");
break;
case 'i':
grid_style *= -1;
if(grid_style)
note("tic marks %sside", grid_style<0 ? "out" : "in");
else
note("(grid is disabled)");
break;
case '2':
grid_style = (grid_style<0)?-3:3;
note("axes on 2 sides", "");
break;
case '4':
/* before: -4 -3 -2 -1 0 1 2 3 4
after: -1 -1 -1 -1 0 1 2 1 1 */
grid_style = to_four_sides[grid_style - MIN_GRID_STYLE];
note("axes on 4 sides", "");
break;
case 'f':
if(abs(grid_style) == 2)
{grid_style = 1;
note("tic marks", "");
}
else
{grid_style = 2;
note("full grid", "");
}
break;
case 's':
/* before: -4 -3 -2 -1 0 1 2 3 4
after: -1 -4 -4 -4 0 4 4 4 1 */
grid_style = toggle_separation[grid_style - MIN_GRID_STYLE];
note("grid %sseparated", abs(grid_style) > 3 ? "" : "not ");
break;
case 't':
requested_rtx = requested_rty = requested_rlx*
(int)fetch_value((double)requested_rtx/requested_rlx,
1., 10.);
break;
case 'w':
grid_width = (int)fetch_value((double)grid_width, 1., 7.);
break;
}
}
(*g_men->accept)(CLEAR, NULL, g_men);
}
/* For parallel projection, the transformation is...
(rot11 rot12 rot13 rot14) (x)
(rot21 rot22 rot23 rot24) (y)
(z)
(1)
*/
#ifndef NOMOUSE
void adjust_window(msg, data, pw) MESSAGE msg; int *data; WINDOW *pw;
{ int t;
double x1, x2, y1, y2, wxmin, wxmax, wymin, wymax;
inquire_window(&wxmin, &wxmax, &wymin, &wymax);
if(msg == DRAG)
{
x2 = (data[0] - rot14)/rot11;
y2 = (data[1] - rot24)/rot22;
x1 = (data[2] - rot14)/rot11;
y1 = (data[3] - rot24)/rot22;
if(x2 < .99*wxmin + .01*wxmax) /* enlarge to left */
xmin -= (xmax - xmin);
else if(x2 > .01*wxmin + .99*wxmax) /* enlarge to right */
xmax += (xmax - xmin);
else if(y2 < .99*wymin + .01*wymax) /* enlarge downwards */
ymin -= (ymax - ymin);
else if(y2 > .01*wymin + .99*wymax) /* enlarge upwards */
ymax += (ymax - ymin);
else /* shrink */
{if(x1 < x2) {xmin = x1; xmax = x2;}
else {xmin = x2; xmax = x1;}
if(y1 < y2) {ymin = y1; ymax = y2;}
else {ymin = y2; ymax = y1;}
}
/*
sprintf(buf, "mouse x = (%d, %d), y = (%d, %d)", data[0], data[2], data[1], data[3]);
note(buf);
getchar();
sprintf(buf, "x = (%lf, %lf), y = (%lf, %lf)", x1, x2, y1, y2);
note(buf);
getchar();
sprintf(buf, "limits x = (%lf, %lf), y = (%lf, %lf)", xmin, xmax, ymin, ymax);
note(buf);
getchar();
*/
ungets("\033");
}
else if(msg == START_DRAGGING) {} /* do nothing */
else MsgWindow(msg, data, pw);
}
#endif /* NOMOUSE */
int GetEvent()
{ int status, hor, ver;
while(1)
{
#ifndef NOMOUSE
if(mouseInstalled)
{GetPosBut(&status, &hor, &ver);
if(status & 1) return '/';
if(status & 2) return ESC;
}
#endif
#ifdef __TURBOC__
if(kbhit()) return scr_ci();
#else
if(_os(0xb,0)) return scr_ci();
#endif
}
}
MENU *CreateSubMenu(ch, child_strings, pm)
char ch; BUTTON *child_strings; MENU *pm;
{ BUTTON *pb;
int x0, y0;
for (pb = pm->pab; *(int *)pb; pb++)
if(pb->val[0] == ch)
{y0 = main_men->y + pb->y + pb->h;
x0 = main_men->x + pb->x + char_width;
return pb->pm = CreateVMenu("", child_strings, x0, y0, 0);
}
/* couldn't find the specified character
- this should make the mistake apparent */
return pm;
}
init_menus()
{ BUTTON *pb;
static int data[2];
#ifdef NOMOUSE
mouseInstalled = 0;
#else
mouseInstalled = IsMouse();
#endif
bwin = CreateWindow("", 0, 0, 0); /* background window */
data[0] = pixels_wide - 1;
data[1] = pixels_high - 1;
(*bwin->accept)(RESIZE, data, bwin);
#ifndef NOMOUSE
bwin->accept = adjust_window;
#endif
bwin->border_style = 0; /* no border */
/* (*bwin->accept)(REDRAW, NULL, bwin); */
main_men = CreateVMenu("", main_strings, pixels_wide - 200, 10, 0);
pb = main_men->pab;
x_men = CreateSubMenu('y', x_strings, main_men);
f_men = CreateSubMenu('f', f_strings, main_men);
g_men = CreateSubMenu('g', g_strings, main_men);
a_men = CreateSubMenu('a', a_strings, main_men);
s_men = CreateSubMenu('m', s_strings, main_men);
#ifndef NOMOUSE
s_men->accept = ShowStyles;
#endif
qwin = CreateWindow("", 6*char_width, 17*char_height, 0);
data[0] = 40*char_width;
data[1] = 2*char_height + 2;
(*qwin->accept)(RESIZE, data, qwin);
dwin = CreateWindow("", 6*char_width, 20*char_height, 0);
data[0] = 40*char_width;
data[1] = char_height + 2;
(*dwin->accept)(RESIZE, data, dwin);
/*
show_menu(main_men); getchar();
show_menu(x_men); getchar();
show_menu(f_men); getchar();
show_menu(g_men); getchar();
show_menu(a_men); getchar();
*/
}
terminate()
{
#ifndef NOMOUSE
if(mouseInstalled)
{SetEventHandler(0, MouseHandler);
HideMouseCursor();
}
#endif
terminate_view_surface(1);
exit();
}