home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Graphics / ToyViewer-2.6a / src / ToyViewEvent.m < prev    next >
Encoding:
Text File  |  1996-09-28  |  6.3 KB  |  290 lines

  1. #import "ToyView.h"
  2. #import <dpsclient/wraps.h>
  3. #import <dpsclient/event.h>
  4. #import <appkit/publicWraps.h>
  5. #import <appkit/NXImage.h>
  6. #import <appkit/NXBitmapImageRep.h>
  7. #import <appkit/Application.h>
  8. #import <appkit/NXCursor.h>
  9. #import <appkit/TextField.h>
  10. #import <stdlib.h>
  11. #import "PrefControl.h"
  12.  
  13. #define  CrossCursor    "cross.tiff"
  14.  
  15. static NXCursor *xCursor = nil;
  16. static BOOL originUpperLeft = NO;
  17.  
  18.  
  19. @implementation ToyView (EventHandling)
  20.  
  21. + cursor
  22. {
  23.     if (!xCursor) {
  24.     NXPoint spot;
  25.     xCursor = [NXCursor newFromImage:[NXImage newFromSection:CrossCursor]];
  26.     spot.x = 7.0; spot.y = 7.0;
  27.     [xCursor setHotSpot:&spot];
  28.     }
  29.     return xCursor;
  30. }
  31.  
  32. + (BOOL)setOriginUpperLeft:(BOOL)flag
  33. {
  34.     BOOL oldflag = originUpperLeft;
  35.     originUpperLeft = flag;
  36.     return oldflag;
  37. }
  38.  
  39. - (BOOL)acceptsFirstResponder
  40. {
  41.     return YES;
  42. }
  43.  
  44. - (BOOL)acceptsFirstMouse
  45. {
  46.     return YES;
  47. }
  48.  
  49. - resetCursorRects
  50. {
  51.     NXRect visible;
  52.  
  53.     if ([self getVisibleRect:&visible])
  54.         [self addCursorRect:&visible cursor:xCursor];
  55.     return self;
  56. }
  57.  
  58. /* Local Method */
  59. - drawDraggedLine: (NXCoord)x : (NXCoord)y : (int)dx : (int)dy
  60. {
  61.     char    buf[20], points[64];
  62.     int    y1, y2;
  63.  
  64.     if (originUpperLeft) {
  65.         y1 = curSize.height - y - dy;
  66.         y2 = curSize.height - y - 1;
  67.     }else {
  68.         y1 = y,  y2 = y + dy - 1;
  69.     }
  70.     sprintf(points, "%d x %d  (%d, %d : %d, %d)",
  71.             dx, dy, (int)x, y1, (int)x + dx - 1, y2);
  72.     [commText setStringValue: points];
  73.  
  74.     // already 'lockFocus'ed
  75.     PSnewinstance();
  76.     PSsetinstance(YES);
  77.     PSsetlinewidth(0.0);
  78.     PSsetgray(0.1667);
  79.     PSrectstroke(x, y+1, dx-1, dy-1);    /* Why +1 ?? */
  80.     if ( dx >= 18 && dy >= 10 ) {
  81.         sprintf(buf, "%d x %d", dx, dy);
  82.         PSmoveto(x+1, y+2);
  83.         PSselectfont("Times-Roman", 12.0);
  84.         PSshow(buf);
  85.     }
  86.     PSsetinstance(NO);
  87.     NXPing();
  88.     return self;
  89. }
  90.  
  91. - clearDraggedLine
  92. {
  93.     NXSize *sz = &selectRect.size;
  94.     if (sz->width > 0.0 || sz->height > 0.0) {
  95.         [self lockFocus];
  96.         PSnewinstance();
  97.         [self unlockFocus];
  98.         sz->width = 0.0;
  99.         sz->height = 0.0;
  100.         [commText setStringValue: comInfo->memo];
  101.     }
  102.     return self;
  103. }
  104.  
  105. - setDraggedLine: sender
  106. {
  107.     NXSize *sz = &selectRect.size;
  108.     if (sz->width > 0.0 && sz->height > 0.0) {
  109.         [self lockFocus];
  110.         [self drawDraggedLine: selectRect.origin.x
  111.             : selectRect.origin.y : sz->width : sz->height];
  112.         [self unlockFocus];
  113.     }
  114.     return self;
  115. }
  116.  
  117. - rewriteComment
  118. {
  119.     [commText setStringValue: comInfo->memo];
  120.     return self;
  121. }
  122.  
  123. #define DRAG_MASK    (NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK)
  124. #define PRESS_MASK    (NX_MOUSEUPMASK|NX_MOUSEDOWNMASK)
  125.  
  126. /* Local Method */
  127. - mousePress: (int)count
  128. {
  129.     NXRect    rect;
  130.  
  131.     if (!comInfo->alpha)
  132.         return self;
  133.     if (count <= 1) {
  134.         if (backgray == 1.0) return self;
  135.         backgray = 1.0;
  136.     }else if (count > 3) backgray = 0.0;
  137.     else backgray = (4 - count) / 3.0;
  138.     // Double-click = Light Gray,  Triple click = Dark Gray
  139.     rect.origin.x = rect.origin.y = 0;
  140.     rect.size = curSize;
  141.     [self lockFocus];
  142.     [self drawSelf:&rect : 1];
  143.     [self unlockFocus];
  144.     [window flushWindow];
  145.     return self;
  146. }
  147.  
  148. /* Code based on pCD.app (H. Danisch & D. Phillips) */
  149.  
  150. - mouseDown:(NXEvent *)event
  151. {
  152.     NXPoint    p, start, lowerleft;
  153.     BOOL    altDrag = NO, sftDrag = NO;
  154.     int    oldMask, cn;
  155.     int    xn = 0, yn = 0, xs, ys;
  156.  
  157.     [self mousePress: (cn = event->data.mouse.click)];
  158.     if (cn > 1) return self;
  159.     oldMask = [window addToEventMask:DRAG_MASK];
  160.     p = event->location;
  161.     [self convertPoint:&p fromView:nil]; /* View based point */
  162.     if (p.x < 0.0) p.x = 0.0;
  163.     else if (p.x >= curSize.width) p.x = curSize.width - 1;
  164.     p.y--;
  165.     if (p.y < 0.0) p.y = 0.0;
  166.     else if (p.y > curSize.height) p.y = curSize.height - 1;
  167.     start.x = (int)p.x;
  168.     start.y = (int)p.y;
  169.     if (NX_ALTERNATEMASK &  event->flags)
  170.         altDrag = YES;
  171.  
  172.     [self lockFocus];
  173.     PSnewinstance();
  174.     PSsetinstance(YES);
  175.     event = [NXApp getNextEvent:DRAG_MASK];
  176.  
  177.     while( event->type != NX_MOUSEUP ) {
  178.         if (NX_ALTERNATEMASK &  event->flags)
  179.             altDrag = YES;
  180.         if (NX_SHIFTMASK &  event->flags)
  181.             sftDrag = YES;
  182.         p = event->location;
  183.         [self convertPoint:&p fromView:nil];
  184.         if (p.x < 0.0) p.x = 0.0;
  185.         else if (p.x >= curSize.width) p.x = curSize.width - 1;
  186.         p.y--;
  187.         if (p.y < 0.0) p.y = 0.0;
  188.         else if (p.y > curSize.height) p.y = curSize.height - 1;
  189.  
  190.         if (p.x > start.x)
  191.             xn = (int)p.x - start.x + 1,  xs = 1;
  192.         else
  193.             xn = start.x - (int)p.x + 1,  xs = -1;
  194.         if (p.y > start.y)
  195.             yn = (int)p.y - start.y + 1,  ys = 1;
  196.         else
  197.             yn = start.y - (int)p.y + 1,  ys = -1;
  198.         if (altDrag) {
  199.             if (xn < yn) yn = xn;
  200.             else xn = yn;
  201.         }
  202.         if (sftDrag) {
  203.             xn = (xn + 1) & ~3;
  204.             yn = (yn + 1) & ~3;
  205.         }
  206.         p.x = start.x + (xn-1)*xs;
  207.         p.y = start.y + (yn-1)*ys;
  208.         lowerleft.x = (start.x < p.x) ? start.x : p.x;
  209.         lowerleft.y = (start.y < p.y) ? start.y : p.y;
  210.         [self drawDraggedLine: lowerleft.x : lowerleft.y : xn : yn];
  211.         event = [NXApp getNextEvent:DRAG_MASK];
  212.     }
  213.     [self unlockFocus];
  214.         
  215.     selectRect.origin.x = lowerleft.x;
  216.     selectRect.origin.y = lowerleft.y;
  217.     selectRect.size.width  = xn;
  218.     selectRect.size.height = yn;
  219.     if (xn == 0 && yn == 0)        /* only click */
  220.         [commText setStringValue: comInfo->memo];
  221.     else if (xn < 3 && yn < 3)    /* Too small area */
  222.         [self clearDraggedLine];
  223.  
  224.     [window flushWindow];
  225.     [window setEventMask:oldMask];
  226.  
  227.     return self;
  228. }
  229.  
  230. - selectAll:sender
  231. {
  232.     [self clearDraggedLine];
  233.     selectRect.size = curSize;
  234.     selectRect.origin.x = selectRect.origin.y = 0.0;
  235.     [self setDraggedLine: sender];
  236.     return self;
  237. }
  238.  
  239. - copy:sender
  240. {
  241.     NXStream    *st;
  242.     NXBitmapImageRep *bm;
  243.     int        i = 0;
  244.     const char    *types[2];
  245.     id        pb = [Pasteboard new];
  246.  
  247.     if (selectRect.size.width < 1.0 || selectRect.size.height < 1.0) {
  248.         NXBeep();
  249.         return self;
  250.     }
  251.  
  252.     //  note that "owner:" in the following can not be "self", or the
  253.     //  id of anything else which might be freed inbetween "Copy"
  254.     //  operations.
  255.     types[i++] = NXTIFFPboardType;
  256.     [pb declareTypes:types num:i owner:NXApp];
  257.  
  258.     [self lockFocus];
  259.     bm = [[NXBitmapImageRep alloc] initData:NULL fromRect:&selectRect];
  260.     [self unlockFocus];
  261.  
  262.     st = NXOpenMemory(NULL, 0, NX_WRITEONLY);
  263.     [bm writeTIFF:st];
  264.     [pb writeType:NXTIFFPboardType fromStream:st];
  265.     NXCloseMemory(st, NX_FREEBUFFER);
  266.     [bm free];
  267.  
  268.     return self;
  269. }
  270.  
  271. - drawSelf:(NXRect *)r :(int) count
  272. {
  273.     NXSize *sz;
  274.  
  275.     if (comInfo->alpha) {
  276.         PSsetgray(backgray);    
  277.         NXRectFill(r);
  278.         [image composite:NX_SOVER fromRect:r toPoint:&(r->origin)];
  279.     }else
  280.         [image composite:NX_COPY fromRect:r toPoint:&(r->origin)];
  281.  
  282.     sz = &selectRect.size;
  283.     if (sz->width > 0.0 && sz->height > 0.0)
  284.         [self perform:@selector(setDraggedLine:) with:self
  285.         afterDelay:30 cancelPrevious:YES];
  286.     return self;
  287. }
  288.  
  289. @end
  290.