home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
i
/
iv26_w_3.zip
/
EXAMPLES
/
IDRAW
/
RUBBANDS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-16
|
5KB
|
173 lines
/*
* Copyright (c) 1987, 1988, 1989 Stanford University
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Stanford not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Stanford makes no representations about
* the suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// $Header: rubbands.c,v 1.10 89/10/09 14:49:18 linton Exp $
// implements classes IStretchingRect, RubberMultiLine, and RubberPolygon.
#include "rubbands.h"
#include <InterViews/painter.h>
// abs returns the integer's magnitude.
inline int abs_ (int a) {
return a > 0 ? a : -a;
}
// IStretchingRect starts with no defined side yet.
IStretchingRect::IStretchingRect (Painter* p, Canvas* c, Coord x0, Coord y0,
Coord x1, Coord y1, Coord offx, Coord offy)
: (p, c, x0, y0, x1, y1, RightSide, offx, offy) {
firsttime = true;
undefinedside = true;
cx = (fixedx + movingx) / 2;
cy = (fixedy + movingy) / 2;
}
// Track stores the point on the first call, decides which side
// becomes the stretching side on the next call or two, and draws the
// rectangle on all following calls.
void IStretchingRect::Track (Coord x, Coord y) {
if (firsttime) {
firsttime = false;
origx = x;
origy = y;
} else if (undefinedside) {
DefineSide(x, y);
} else {
StretchingRect::Track(x, y);
}
}
// DefineSide picks the side to stretch after the motion of the
// tracking point becomes sufficiently unambiguous.
static const Coord THRESHOLD = 2;
void IStretchingRect::DefineSide (Coord x, Coord y) {
Coord dx = abs_(x - origx);
Coord dy = abs_(y - origy);
Coord xydiff = abs_(dx - dy);
if (xydiff >= THRESHOLD) {
undefinedside = false;
if (dx > dy) {
if (x > cx) {
side = RightSide;
} else {
side = LeftSide;
}
} else {
if (y > cy) {
side = TopSide;
} else {
side = BottomSide;
}
}
}
}
// CurrentSide returns the side that the user is dragging.
Alignment IStretchingRect::CurrentSide (boolean landscape) {
Alignment s = Left;
switch (side) {
case LeftSide:
s = landscape ? Bottom : Left;
break;
case RightSide:
s = landscape ? Top : Right;
break;
case TopSide:
s = landscape ? Right : Top;
break;
case BottomSide:
s = landscape ? Left : Bottom;
break;
}
return s;
}
// RubberMultiLine passes its arguments to RubberVertex.
RubberMultiLine::RubberMultiLine (
Painter* p, Canvas* c, Coord px[], Coord py[], int n, int pt,
Coord offx, Coord offy
) : (p, c, px, py, n, pt, offx, offy) {
/* nothing else to do */
}
// Draw draws only the one or two line segments attached to the rubber
// vertex.
void RubberMultiLine::Draw () {
if (x == nil || y == nil) {
return;
}
if (!drawn) {
int before = rubberPt - 1;
if (before >= 0) {
Coord x0 = x[before];
Coord y0 = y[before];
output->Line(canvas, x0+offx, y0+offy, trackx+offx, tracky+offy);
}
int after = rubberPt + 1;
if (after <= count - 1) {
Coord x1 = x[after];
Coord y1 = y[after];
output->Line(canvas, trackx+offx, tracky+offy, x1+offx, y1+offy);
}
drawn = true;
}
}
// RubberPolygon passes its arguments to RubberVertex.
RubberPolygon::RubberPolygon (
Painter* p, Canvas* c, Coord px[], Coord py[], int n, int pt,
Coord offx, Coord offy
) : (p, c, px, py, n, pt, offx, offy) {
/* nothing else to do */
}
// Draw draws only the two line segments attached to the rubber
// vertex.
void RubberPolygon::Draw () {
if (x == nil || y == nil) {
return;
}
if (!drawn) {
int before = (rubberPt > 0) ? rubberPt - 1 : count - 1;
Coord x0 = x[before];
Coord y0 = y[before];
output->Line(canvas, x0+offx, y0+offy, trackx+offx, tracky+offy);
if (count > 2) {
int after = (rubberPt < count - 1) ? rubberPt + 1 : 0;
Coord x1 = x[after];
Coord y1 = y[after];
output->Line(canvas, trackx+offx, tracky+offy, x1+offx, y1+offy);
}
drawn = true;
}
}