home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
disks
/
disk386.lzh
/
XLispStat
/
src2.lzh
/
XLisp-Stat
/
xsscatmat.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-04
|
15KB
|
509 lines
/* xsscatmat - XLISP interface to IVIEW dynamic graphics package. */
/* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
/* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
/* You may give out copies of this software; for conditions see the */
/* file COPYING included with this distribution. */
#include "xlisp.h"
#include "osdef.h"
#ifdef ANSI
#include "xlproto.h"
#include "xlsproto.h"
#include "iviewproto.h"
#include "Stproto.h"
#else
#include "xlfun.h"
#include "xlsfun.h"
#include "iviewfun.h"
#include "Stfun.h"
#endif ANSI
#include "xlsvar.h"
#ifdef ANSI
void get_plot_layout(IVIEW_WINDOW,int *,int *,int *),
DrawLabel(IVIEW_WINDOW,int),find_current_plot(IVIEW_WINDOW,int,int),
ScatDrawPoint(IVIEW_WINDOW,int,PointState,PointState),
scat_draw_point(IVIEW_WINDOW,int,PointState),
find_current_plot(IVIEW_WINDOW,int,int);
LVAL scatmat_add_data(int),iview_scatmat_mouse(int);
#else
void get_plot_layout(),
DrawLabel(),find_current_plot(),
ScatDrawPoint(),
scat_draw_point(),
find_current_plot();
LVAL scatmat_add_data(),iview_scatmat_mouse();
#endif ANSI
#define SCAT_PLOT_GAP 1
#define SCAT_INSET 4
#define LABEL_OFFSET 5
#define MAX_NUM_VARS 10
#define VAR_FORMAT "var %d"
#define POINT_FORMAT "%d"
static int pdata[MAX_NUM_VARS];
static struct {
int x, y, left, top, size, bottom;
} current;
/**************************************************************************/
/** **/
/** Plot Creation Functions **/
/** **/
/**************************************************************************/
LVAL iview_scatmat_allocate()
{
LVAL object;
int i, vars, show;
IVIEW_WINDOW w;
char s[100];
object = xlgaobject();
show = xsboolkey(sk_show, TRUE);
get_iview_ivars(object, &vars);
if (vars < 2) xlfail("Too few variables for scatmat");
if (vars > MAX_NUM_VARS) xlfail("Too many variables for scatmat");
w = IViewNew(object);
/* should replace this by something lisp-based +++++++ */
for (i = 0; i < vars; i++) {
sprintf(s, VAR_FORMAT, i);
IViewSetVariableLabel(w, i, s);
IViewSetRange(w, i, 0.0, 1.0);
}
initialize_iview(w, object);
/* use StShowWindow to show (map) window but NOT send :resize or :redraw */
if (show) StShowWindow(w);
return(object);
}
/**************************************************************************/
/** **/
/** Data Functions **/
/** **/
/**************************************************************************/
static LVAL scatmat_add_data(which)
int which;
{
IVIEW_WINDOW w;
LVAL data, object;
int old_n, n;
object = xlgaobject();
w = GETIVIEWADDRESS(object);
if (w == nil) return(NIL);
data = xlgetarg();
switch(which) {
case 'P':
old_n = IViewNumPoints(w);
internal_iview_add_points(w, object, data);
n = IViewNumPoints(w);
break;
case 'L':
old_n = IViewNumLines(w);
internal_iview_add_lines(w, object, data);
n = IViewNumLines(w);
break;
#ifdef USESTRINGS
case 'S':
old_n = IViewNumStrings(w);
internal_iview_add_strings(w, object, data);
n = IViewNumStrings(w);
break;
#endif /* USESTRINGS */
}
check_add_to_screen(object, which, old_n, n, TRUE);
return(NIL);
}
LVAL iview_scatmat_add_points() { return(scatmat_add_data('P')); }
LVAL iview_scatmat_add_lines() { return(scatmat_add_data('L')); }
#ifdef USESTRINGS
LVAL iview_scatmat_add_strings() { return(scatmat_add_data('S')); }
#endif /* USESTRINGS */
/**************************************************************************/
/** **/
/** Drawing and Resizing Functions **/
/** **/
/**************************************************************************/
LVAL iview_scatmat_resize()
{
int vars;
int i, top, left, subsize, low, high;
IVIEW_WINDOW w;
LVAL object;
object = xlgaobject();
xllastarg();
w = GETIVIEWADDRESS(object);
if (w == nil) return(NIL);
vars = IViewNumVariables(w);
IViewSetFixedAspect(w, TRUE);
IViewStdResize(w);
get_plot_layout(w, &left, &top, &subsize);
for (i = 0; i < vars; i++) {
low = i * (subsize + SCAT_PLOT_GAP) + 2 * SCAT_INSET + SCAT_PLOT_GAP;
high = low + subsize - 3 * SCAT_INSET;
IViewSetScreenRange(w, i, low, high);
}
return(NIL);
}
LVAL iview_scatmat_redraw_content()
{
int vars;
int left, top, subleft, subtop, subsize;
int viewleft, viewtop, viewwidth, viewheight;
int i, j;
double low, high;
char s[100];
IVIEW_WINDOW w;
LVAL object, scale_type;
/* char */ StGWWinInfo *gwinfo; /* changed JKL */
object = xlgaobject();
xllastarg();
gwinfo = StGWObWinInfo(object);
w = GETIVIEWADDRESS(object);
if (w == nil) return(NIL);
vars = IViewNumVariables(w);
if (IViewMouseMode(w) == brushing) IViewEraseBrush(w);
StGWGetViewRect(gwinfo, &viewleft, &viewtop, &viewwidth, &viewheight);
get_plot_layout(w, &left, &top, &subsize);
scale_type = slot_value(object, s_scale_type);
StGWStartBuffering(gwinfo);
StGWEraseRect(gwinfo, viewleft, viewtop, viewwidth, viewheight);
for (i = 0; i < vars; i++)
for (j = 0; j < vars; j++) {
subleft = left + j * (SCAT_PLOT_GAP + subsize);
subtop = top + (vars - i - 1) * (SCAT_PLOT_GAP + subsize);
StGWFrameRect(gwinfo, subleft, subtop, subsize, subsize);
if (i == j && scale_type == NIL) {
if (IViewVariableLabel(w, i) != 0)
StGWDrawText(gwinfo, IViewVariableLabel(w, i),
subleft + subsize / 2, subtop + subsize / 2, 1, 0);
IViewGetRange(w, i, &low, &high);
sprintf(s, "%.3lg", high);
StGWDrawText(gwinfo, s,
subleft + subsize - SCAT_INSET,
subtop + SCAT_INSET, 2, 1);
sprintf(s, "%.3lg", low);
StGWDrawText(gwinfo, s,
subleft + SCAT_INSET,
subtop + subsize - SCAT_INSET, 0, 0);
}
else if (i != j) {
IViewDrawDataPoints(w, i, j, 0, IViewNumPoints(w));
IViewDrawDataLines(w, i, j, 0, IViewNumLines(w));
#ifdef USESTRINGS
IViewDrawDataStrings(w, i, j, 0, IViewNumStrings(w));
#endif /* USESTRINGS */
}
}
StGWBufferToScreen(gwinfo, viewleft, viewtop, viewwidth, viewheight);
if (IViewMouseMode(w) == brushing) IViewDrawBrush(w);
IViewResetScreenStates(w);
return(NIL);
}
/**************************************************************************/
/** **/
/** Mouse Functions **/
/** **/
/**************************************************************************/
/*extern LVAL peekarg(); in headers JKL */
static LVAL iview_scatmat_mouse(click)
int click;
{
IVIEW_WINDOW w;
LVAL object;
int x, y;
object = xlgaobject();
w = GETIVIEWADDRESS(object);
if (w != nil) {
x = fixp(peekarg(0)) ? getfixnum(peekarg(0)) : 0;
y = fixp(peekarg(1)) ? getfixnum(peekarg(1)) : 0;
find_current_plot(w, x, y);
if (click) IViewDoClick(object);
else IViewDoMotion(object);
}
return(NIL);
}
LVAL iview_scatmat_click() { return(iview_scatmat_mouse(TRUE)); }
LVAL iview_scatmat_motion() { return(iview_scatmat_mouse(FALSE)); }
LVAL iview_scatmat_adjust_screen_point()
{
LVAL object;
int point;
IVIEW_WINDOW w;
PointState state, screen_state;
object = xlgaobject();
point = getfixnum(xlgafixnum());
xllastarg();
w = GETIVIEWADDRESS(object);
if (w == nil) return(NIL);
if (! IViewPointMasked(w, point)) {
state = IViewPointState(w, point);
screen_state = IViewPointScreenState(w, point);
if (state == pointInvisible || screen_state == pointInvisible) {
StGrSetDirty(StGWObWinInfo(object), TRUE);
}
else {
scat_draw_point(w, point, state);
}
}
return(NIL);
}
LVAL iview_scatmat_adjust_points_in_rect()
{
int var1, var2, x, y, px, py;
int i, n, in_rect, right, bottom, left, top, width, height;
PointState point_state, state;
IVIEW_WINDOW w;
LVAL object;
/* char*/ StGWWinInfo *gwinfo; /* changed JKL */
object = xlgaobject();
w = GETIVIEWADDRESS(object);
left = getfixnum(xlgafixnum());
top = getfixnum(xlgafixnum());
width = getfixnum(xlgafixnum());
height = getfixnum(xlgafixnum());
state = decode_point_state(xlgetarg());
xllastarg();
if (w == nil) return(NIL);
gwinfo = StGWObWinInfo(object);
IViewCheckLinks(w);
n = IViewNumPoints(w);
bottom = top + height;
right = left + width;
StGrGetContentVariables(gwinfo, &var1, &var2);
StGrGetContentOrigin(gwinfo, &x, &y);
if (IViewMouseMode(w) == brushing) IViewEraseBrush(w);
for (i = 0; i < n; i++) {
point_state = IViewPointState(w, i);
if (! IViewPointMasked(w, i) && point_state != pointInvisible) {
px = x + IViewPointScreenValue(w, var1, i);
py = y - IViewPointScreenValue(w, var2, i);
in_rect = (var1 != var2
&& px >= left && px <= right && py >= top && py <= bottom);
if (in_rect && (int) point_state < (int) state) {
IViewSetPointState(w, i, state);
}
else if (! in_rect
&& state == pointHilited && point_state == pointHilited) {
IViewSetPointState(w, i, pointNormal);
}
}
}
IViewAdjustScreens(w);
if (IViewMouseMode(w) == brushing) IViewDrawBrush(w);
return(NIL);
}
LVAL iview_scatmat_mark_points_in_rect()
{
int var1, var2;
int left, top, width, height;
IVIEW_WINDOW w;
LVAL object;
/*char*/ StGWWinInfo *gwinfo; /* changed JKL */
object = xlgaobject();
w = GETIVIEWADDRESS(object);
left = getfixnum(xlgafixnum());
top = getfixnum(xlgafixnum());
width = getfixnum(xlgafixnum());
height = getfixnum(xlgafixnum());
xllastarg();
if (w == nil) return(NIL);
gwinfo = StGWObWinInfo(object);
StGrGetContentVariables(gwinfo, &var1, &var2);
if (var1 == var2) IViewClearPointMarks(w);
else IViewStdMarkPointsInRect(w, left, top, width, height);
return(NIL);
}
/**************************************************************************/
/** **/
/** Internal Functions **/
/** **/
/**************************************************************************/
static void get_plot_layout(w,subleft,subtop,subsize)
IVIEW_WINDOW w;
int *subleft, *subtop, *subsize;
{
int vars, left, top, width, height, delta;
/*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
vars = IViewNumVariables(w);
StGrGetContentRect(gwinfo, &left, &top, &width, &height);
if (subleft != nil && subtop != nil && subsize != nil) {
*subsize = (width - SCAT_PLOT_GAP * (vars + 1)) / vars;
if (*subsize < 0) *subsize = 0;
delta = (width - (vars * *subsize + (vars - 1) * SCAT_PLOT_GAP)) / 2;
if (delta < 0) delta = 0;
*subleft = left + delta;
*subtop = top + delta;
}
}
static void ScatDrawPoint(w, point, state, screen_state)
IVIEW_WINDOW w;
int point;
PointState state, screen_state;
{
int vars = IViewNumVariables(w);
int left, bottom;
int oldwidth, oldheight, newwidth, newheight;
int i, j;
int x, y, oldsym, newsym, sym, hsym, replace;
/*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
ColorCode color, oldcolor, use_color = StGWUseColor(gwinfo);
IViewGetPointSymbol(w, point, &sym, &hsym);
oldsym = (screen_state == pointNormal) ? sym : hsym;
newsym = (state == pointNormal) ? sym : hsym;
if (state == pointInvisible) return;
StGWGetSymbolSize(oldsym, &oldwidth, &oldheight);
StGWGetSymbolSize(newsym, &newwidth, &newheight);
replace = (oldwidth > newwidth || oldheight > newheight);
IViewGetScreenPointValues(w, point, pdata);
StGrGetContentOrigin(gwinfo, &left, &bottom);
if (use_color) {
oldcolor = StGWDrawColor(gwinfo);
color = IViewPointColor(w, point);
if (color >= 0) StGWSetDrawColor(gwinfo, color);
}
for (i = 0; i < vars; i++) {
y = bottom - pdata[i];
for (j = 0; j < vars; j++)
if (i != j) {
x = left + pdata[j];
if (replace) StGWReplaceSymbol(gwinfo, oldsym, newsym, x, y);
else StGWDrawSymbol(gwinfo, newsym, x, y);
}
}
if (use_color && color >= 0) StGWSetDrawColor(gwinfo, oldcolor);
}
static void DrawLabel(w, point)
IVIEW_WINDOW w;
int point;
{
int vars = IViewNumVariables(w);
int left, bottom;
int i, j;
int x, y;
char *label;
/*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
int mode = StGWDrawMode(gwinfo);
label = IViewPointLabel(w, point);
if (label == nil) return;
for (i = 0; i < vars; i++) pdata[i] = IViewPointScreenValue(w, i, point);
StGrGetContentOrigin(gwinfo, &left, &bottom);
for (i = 0; i < vars; i++) {
y = bottom - pdata[i] - LABEL_OFFSET;
for (j = 0; j < vars; j++)
if (i != j) {
x = left + pdata[j] + LABEL_OFFSET;
StGWSetDrawMode(gwinfo, 1);
StGWDrawString(gwinfo, label, x, y);
StGWSetDrawMode(gwinfo, mode);
}
}
}
static void find_current_plot(w, x, y)
IVIEW_WINDOW w;
int x, y;
{
int width, height;
int left, top, subsize, vars;
/*char*/StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
vars = IViewNumVariables(w);
if (IViewMouseMode(w) == brushing) {
IViewGetBrush(w, nil, nil, &width, &height);
x -= width / 2;
y -= height / 2;
}
get_plot_layout(w, &left, &top, &subsize);
subsize += SCAT_PLOT_GAP;
current.x = (x - left) / subsize;
current.y = (top + vars * subsize - y - SCAT_PLOT_GAP) / subsize;
if (current.x < 0 || current.x >= vars
|| current.y < 0 || current.y >= vars) {
current.x = 0;
current.y = 0;
}
current.size = vars * subsize - SCAT_PLOT_GAP;
current.left = left;
current.top = top;
current.bottom = current.left + current.top + current.size;
StGrSetContentVariables(gwinfo, current.x, current.y);
}
static void scat_draw_point(w, i, state)
IVIEW_WINDOW w;
int i;
PointState state;
{
int showingLabels = IViewShowingLabels(w);
if (state == pointNormal && showingLabels) DrawLabel(w, i); /* to erase */
ScatDrawPoint(w, i, state, state);
if (state != pointNormal && showingLabels) DrawLabel(w, i); /* to draw */
IViewSetPointScreenState(w, i, state);
}