home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xpaint-247 / boxop.c < prev    next >
C/C++ Source or Header  |  1996-06-25  |  7KB  |  252 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)           | */
  3. /* |                                       | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.     There is no           | */
  9. /* | representations about the suitability of this software for           | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                           | */
  12. /* |                                       | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. /* $Id: boxOp.c,v 1.3 1996/04/19 09:05:53 torsten Exp $ */
  16.  
  17. #include <X11/Intrinsic.h>
  18. #include <X11/StringDefs.h>
  19. #include "xpaint.h"
  20. #include "misc.h"
  21. #include "Paint.h"
  22. #include "ops.h"
  23.  
  24. typedef struct {
  25.     int rx, ry;
  26.     int startX, startY, endX, endY;
  27.     int drawn;
  28.     Boolean type;        /* 0: rectangle, 1: square,
  29.                    2: centered rectangle, 3: centered square */
  30.     Boolean fill;        /* Filled rectangle? */
  31.     Boolean swap;
  32.     GC gcx;
  33. } LocalInfo;
  34.  
  35. #define MKRECT(rect, sx, sy, ex, ey, typeFlag) do {            \
  36.     if (typeFlag == 1) {    /* square */                \
  37.         (rect)->width  = MAX(ABS(sx - ex),ABS(sy - ey));    \
  38.         (rect)->height = (rect)->width;                \
  39.         (rect)->x = (ex - sx < 0) ? sx - (rect)->width : sx;    \
  40.         (rect)->y = (ey - sy < 0) ? sy - (rect)->height : sy;    \
  41.     } else if (typeFlag == 2) {    /* center */            \
  42.         (rect)->x      = sx - ABS(sx - ex);            \
  43.         (rect)->y      = sy - ABS(sy - ey);            \
  44.         (rect)->width  = 2*ABS(sx - ex);            \
  45.         (rect)->height = 2*ABS(sy - ey);            \
  46.     } else if (typeFlag == 3) {    /* center, square */        \
  47.         (rect)->width  = MAX(ABS(sx - ex),ABS(sy - ey));    \
  48.         (rect)->x      = sx - (rect)->width;            \
  49.         (rect)->y      = sy - (rect)->width;            \
  50.         (rect)->width  *= 2;                    \
  51.         (rect)->height = (rect)->width;                \
  52.     } else {        /* no constraints */            \
  53.         (rect)->x      = MIN(sx, ex);                \
  54.         (rect)->y      = MIN(sy, ey);                \
  55.         (rect)->width  = MAX(sx, ex) - (rect)->x;        \
  56.         (rect)->height = MAX(sy, ey) - (rect)->y;        \
  57.     }                                \
  58. } while (0)
  59.  
  60. static int boxStyle = 0;
  61.  
  62. static void 
  63. press(Widget w, LocalInfo * l,
  64.       XButtonEvent * event, OpInfo * info)
  65. {
  66.     /*
  67.     **    Check to make sure all buttons are up, before doing this
  68.      */
  69.     if ((event->state & AllButtonsMask) != 0)
  70.     return;
  71.  
  72.     l->swap = (event->button == Button2);
  73.  
  74.     l->rx = info->x;
  75.     l->ry = info->y;
  76.     l->endX = l->startX = event->x;
  77.     l->endY = l->startY = event->y;
  78.  
  79.     l->type = 2 * boxStyle + ((event->state & ShiftMask) ? 1 : 0);
  80.     l->drawn = False;
  81. }
  82.  
  83. static void 
  84. motion(Widget w, LocalInfo * l,
  85.        XMotionEvent * event, OpInfo * info)
  86. {
  87.     XRectangle rect;
  88.  
  89.     if (l->drawn) {
  90.     MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->type);
  91.  
  92.     XDrawRectangles(XtDisplay(w), XtWindow(w), l->gcx, &rect, 1);
  93.     }
  94.     l->endX = event->x;
  95.     l->endY = event->y;
  96.  
  97.     l->type = 2 * boxStyle + ((event->state & ShiftMask) ? 1 : 0);
  98.  
  99.     if ((l->drawn = (l->startX != l->endX || l->startY != l->endY))) {
  100.     MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->type);
  101.  
  102.     XDrawRectangles(XtDisplay(w), XtWindow(w), l->gcx, &rect, 1);
  103.     }
  104. }
  105.  
  106. static void 
  107. release(Widget w, LocalInfo * l,
  108.     XButtonEvent * event, OpInfo * info)
  109. {
  110.     XRectangle rect;
  111.     int mask;
  112.     GC fgc, lgc;
  113.  
  114.     /*
  115.     **    Check to make sure all buttons are up, before doing this
  116.      */
  117.     mask = AllButtonsMask;
  118.     switch (event->button) {
  119.     case Button1:
  120.     mask ^= Button1Mask;
  121.     break;
  122.     case Button2:
  123.     mask ^= Button2Mask;
  124.     break;
  125.     case Button3:
  126.     mask ^= Button3Mask;
  127.     break;
  128.     case Button4:
  129.     mask ^= Button4Mask;
  130.     break;
  131.     case Button5:
  132.     mask ^= Button5Mask;
  133.     break;
  134.     }
  135.     if ((event->state & mask) != 0)
  136.     return;
  137.  
  138.     if (l->drawn && info->surface == opWindow) {
  139.     MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->type);
  140.  
  141.     XDrawRectangles(XtDisplay(w), XtWindow(w), l->gcx, &rect, 1);
  142.     }
  143.     if (info->isFat && info->surface == opWindow)
  144.     return;
  145.  
  146.     MKRECT(&rect, l->rx, l->ry, event->x, event->y, l->type);
  147.  
  148.     UndoStart(w, info);
  149.  
  150.     if (l->swap) {
  151.     fgc = info->first_gc;
  152.     lgc = info->second_gc;
  153.     } else {
  154.     fgc = info->second_gc;
  155.     lgc = info->first_gc;
  156.     }
  157.  
  158.     if (l->fill)
  159.     XFillRectangles(XtDisplay(w), info->drawable, fgc, &rect, 1);
  160.     XDrawRectangles(XtDisplay(w), info->drawable, lgc, &rect, 1);
  161.  
  162.     if (info->surface == opPixmap) {
  163.     rect.width++;
  164.     rect.height++;
  165.     UndoSetRectangle(w, &rect);
  166.     PwUpdate(w, &rect, False);
  167.     }
  168. }
  169.  
  170. /*
  171. **  Public routines
  172.  */
  173.  
  174. void *
  175. BoxAdd(Widget w)
  176. {
  177.     LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
  178.  
  179.     l->fill = False;
  180.     l->gcx = GetGCX(w);
  181.  
  182.     XtVaSetValues(w, XtNcompress, True, NULL);
  183.  
  184.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
  185.               (OpEventProc) press, l);
  186.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  187.               (OpEventProc) motion, l);
  188.     OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  189.               (OpEventProc) release, l);
  190.     SetCrossHairCursor(w);
  191.  
  192.     return l;
  193. }
  194. void 
  195. BoxRemove(Widget w, void *l)
  196. {
  197.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
  198.              (OpEventProc) press, l);
  199.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  200.              (OpEventProc) motion, l);
  201.     OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  202.              (OpEventProc) release, l);
  203.  
  204.     XtFree((XtPointer) l);
  205. }
  206.  
  207. void *
  208. FBoxAdd(Widget w)
  209. {
  210.     LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
  211.  
  212.     l->fill = True;
  213.     l->gcx = GetGCX(w);
  214.  
  215.     XtVaSetValues(w, XtNcompress, False, NULL);
  216.  
  217.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
  218.               (OpEventProc) press, l);
  219.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  220.               (OpEventProc) motion, l);
  221.     OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  222.               (OpEventProc) release, l);
  223.     SetCrossHairCursor(w);
  224.  
  225.     return l;
  226. }
  227.  
  228. void 
  229. FBoxRemove(Widget w, void *l)
  230. {
  231.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
  232.              (OpEventProc) press, l);
  233.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  234.              (OpEventProc) motion, l);
  235.     OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  236.              (OpEventProc) release, l);
  237.  
  238.     XtFree((XtPointer) l);
  239. }
  240.  
  241. void 
  242. BoxSetStyle(Boolean mode)
  243. {
  244.     boxStyle = mode ? 1 : 0;
  245. }
  246.  
  247. Boolean
  248. BoxGetStyle(void)
  249. {
  250.     return boxStyle == 0 ? False : True;
  251. }
  252.