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 >
C/C++ Source or Header  |  1992-01-16  |  5KB  |  173 lines

  1. /*
  2.  * Copyright (c) 1987, 1988, 1989 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and its
  5.  * documentation for any purpose is hereby granted without fee, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of Stanford not be used in advertising or
  9.  * publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  Stanford makes no representations about
  11.  * the suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  19.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  20.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  */
  22.  
  23. // $Header: rubbands.c,v 1.10 89/10/09 14:49:18 linton Exp $
  24. // implements classes IStretchingRect, RubberMultiLine, and RubberPolygon.
  25.  
  26. #include "rubbands.h"
  27. #include <InterViews/painter.h>
  28.  
  29. // abs returns the integer's magnitude.
  30.  
  31. inline int abs_ (int a) {
  32.     return a > 0 ? a : -a;
  33. }
  34.  
  35. // IStretchingRect starts with no defined side yet.
  36.  
  37. IStretchingRect::IStretchingRect (Painter* p, Canvas* c, Coord x0, Coord y0,
  38. Coord x1, Coord y1, Coord offx, Coord offy)
  39. : (p, c, x0, y0, x1, y1, RightSide, offx, offy) {
  40.     firsttime = true;
  41.     undefinedside = true;
  42.     cx = (fixedx + movingx) / 2;
  43.     cy = (fixedy + movingy) / 2;
  44. }
  45.  
  46. // Track stores the point on the first call, decides which side
  47. // becomes the stretching side on the next call or two, and draws the
  48. // rectangle on all following calls.
  49.  
  50. void IStretchingRect::Track (Coord x, Coord y) {
  51.     if (firsttime) {
  52.     firsttime = false;
  53.     origx = x;
  54.     origy = y;
  55.     } else if (undefinedside) {
  56.     DefineSide(x, y);
  57.     } else {
  58.     StretchingRect::Track(x, y);
  59.     }
  60. }
  61.  
  62. // DefineSide picks the side to stretch after the motion of the
  63. // tracking point becomes sufficiently unambiguous.
  64.  
  65. static const Coord THRESHOLD = 2;
  66.  
  67. void IStretchingRect::DefineSide (Coord x, Coord y) {
  68.     Coord dx = abs_(x - origx);
  69.     Coord dy = abs_(y - origy);
  70.     Coord xydiff = abs_(dx - dy);
  71.     if (xydiff >= THRESHOLD) {
  72.     undefinedside = false;
  73.     if (dx > dy) {
  74.         if (x > cx) {
  75.         side = RightSide;
  76.         } else {
  77.         side = LeftSide;
  78.         }
  79.     } else {
  80.         if (y > cy) {
  81.         side = TopSide;
  82.         } else {
  83.         side = BottomSide;
  84.         }
  85.     }
  86.     }
  87. }
  88.  
  89. // CurrentSide returns the side that the user is dragging.
  90.  
  91. Alignment IStretchingRect::CurrentSide (boolean landscape) {
  92.     Alignment s = Left;
  93.     switch (side) {
  94.     case LeftSide:
  95.     s = landscape ? Bottom : Left;
  96.     break;
  97.     case RightSide:
  98.     s = landscape ? Top : Right;
  99.     break;
  100.     case TopSide:
  101.     s = landscape ? Right : Top;
  102.     break;
  103.     case BottomSide:
  104.     s = landscape ? Left : Bottom;
  105.     break;
  106.     }
  107.     return s;
  108. }
  109.  
  110. // RubberMultiLine passes its arguments to RubberVertex.
  111.  
  112. RubberMultiLine::RubberMultiLine (
  113.     Painter* p, Canvas* c, Coord px[], Coord py[], int n, int pt,
  114.     Coord offx, Coord offy
  115. ) : (p, c, px, py, n, pt, offx, offy) {
  116.     /* nothing else to do */
  117. }
  118.  
  119. // Draw draws only the one or two line segments attached to the rubber
  120. // vertex.
  121.  
  122. void RubberMultiLine::Draw () {
  123.     if (x == nil || y == nil) {
  124.         return;
  125.     }
  126.     if (!drawn) {
  127.     int before = rubberPt - 1;
  128.     if (before >= 0) {
  129.         Coord x0 = x[before];
  130.         Coord y0 = y[before];
  131.         output->Line(canvas, x0+offx, y0+offy, trackx+offx, tracky+offy);
  132.     }
  133.     int after = rubberPt + 1;
  134.     if (after <= count - 1) {
  135.         Coord x1 = x[after];
  136.         Coord y1 = y[after];
  137.         output->Line(canvas, trackx+offx, tracky+offy, x1+offx, y1+offy);
  138.     }
  139.     drawn = true;
  140.     }
  141. }
  142.  
  143. // RubberPolygon passes its arguments to RubberVertex.
  144.  
  145. RubberPolygon::RubberPolygon (
  146.     Painter* p, Canvas* c, Coord px[], Coord py[], int n, int pt,
  147.     Coord offx, Coord offy
  148. ) : (p, c, px, py, n, pt, offx, offy) {
  149.     /* nothing else to do */
  150. }
  151.  
  152. // Draw draws only the two line segments attached to the rubber
  153. // vertex.
  154.  
  155. void RubberPolygon::Draw () {
  156.     if (x == nil || y == nil) {
  157.         return;
  158.     }
  159.     if (!drawn) {
  160.     int before = (rubberPt > 0) ? rubberPt - 1 : count - 1;
  161.     Coord x0 = x[before];
  162.     Coord y0 = y[before];
  163.     output->Line(canvas, x0+offx, y0+offy, trackx+offx, tracky+offy);
  164.     if (count > 2) {
  165.         int after = (rubberPt < count - 1) ? rubberPt + 1 : 0;
  166.         Coord x1 = x[after];
  167.         Coord y1 = y[after];
  168.         output->Line(canvas, trackx+offx, tracky+offy, x1+offx, y1+offy);
  169.     }
  170.     drawn = true;
  171.     }
  172. }
  173.