home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.0 / NeXTSTEP3.0.iso / NextDeveloper / Examples / AppKit / UnderPressure / PressureView.m < prev    next >
Text File  |  1992-06-11  |  4KB  |  193 lines

  1. #if 0
  2.  
  3.   PressureView.m -- Pressure sensitive View subclass for painting
  4.  
  5.   by Peter Graffagnino, NeXT Computer Inc.
  6.  
  7.   PressureView is a view subclass responsible for:
  8.  
  9.   - maintaining a special trackingrect to inform the low-level event
  10.     system of its interest in pressure and event coalescing.
  11.   - maintaining an NXImage backingstore for the View.
  12.   - implementing a mouseDown: painting loop and using a Brush object for
  13.     painting
  14.   - handling flagsChanged: events to update pen proximity state
  15.  
  16.   You may freely copy, distribute, and reuse the code in this example.
  17.   NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  18.   fitness for any particular use.
  19.  
  20. #endif
  21.  
  22. #import <appkit/appkit.h>
  23. #include <math.h>
  24. #include <dpsclient/wraps.h>
  25. #import "PressureView.h"
  26. #import "Brush.h"
  27. #import "pressurerect.h"
  28.  
  29. @implementation PressureView : View
  30.  
  31. - initFrame:(const NXRect *)r
  32. {
  33.     self = [super initFrame:r];
  34.     [self allocateGState];
  35.     backingImage = [[NXImage alloc] initSize: &r->size];
  36.     [backingImage setBackgroundColor: NX_COLORWHITE];
  37.     coalesceState = YES;
  38.     pressureState = YES;
  39.     [self clear: self];
  40.     return self;
  41. }
  42.  
  43. - free
  44. {
  45.     [backingImage free];
  46.     return [super free];
  47. }
  48.  
  49. - clear:sender
  50. {
  51.     if (! [backingImage lockFocus]) return self;
  52.     NXSetColor(NX_COLORWHITE);
  53.     NXRectFill(&bounds);
  54.     [backingImage unlockFocus];
  55.     [self display];
  56.     return self;
  57. }
  58.  
  59. - drawSelf:(const NXRect *)rects :(int)rectCount
  60. {
  61.     [backingImage composite: NX_COPY fromRect: rects toPoint: &rects->origin];
  62.     return self;
  63. }
  64.  
  65. - sizeTo: (NXCoord) x : (NXCoord) y
  66. {
  67.     NXSize size;
  68.     [super sizeTo: x : y];
  69.     size.width = x;
  70.     size.height = y;
  71.     [backingImage setSize: &size];
  72.     return self;
  73. }
  74.  
  75. - mouseDown:(NXEvent *)e
  76. {
  77.     NXPoint p;
  78.     NXRect dirty;
  79.     int emask=[window addToEventMask:(NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK)];
  80.  
  81.     if( ! [backingImage lockFocus] ) return self;
  82.  
  83.     p = e->location;
  84.     [self convertPoint: &p fromUCi: nil];
  85.     p.x += .5; p.y += .5;
  86.     [brush brushMoveTo: p.x : p.y withPressure: e->data.mouse.pressure/255.0
  87.                   dirtyRect: &dirty];
  88.     [self display: &dirty : 1];
  89.     while(1) {
  90.     e=[NXApp getNextEvent:(NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK)];
  91.     if(e->type == NX_MOUSEUP)
  92.         break;
  93.     p = e->location;
  94.     [self convertPoint: &p fromView: nil];
  95.     p.x += .5; p.y += .5;
  96.     [brush brushLineTo: p.x : p.y withPressure: 
  97.         e->data.mouse.pressure/255.0
  98.              dirtyRect: &dirty];
  99.     [self display: &dirty : 1];
  100.     NXPing();    
  101.     }
  102.     [backingImage unlockFocus];
  103.     [window setEventMask:emask];
  104.     return self;
  105. }
  106.  
  107.  
  108. - (BOOL) acceptsFirstResponder
  109. {
  110.     return YES;
  111. }
  112.  
  113. - awakeFromNib
  114. {
  115.     [window addToEventMask:NX_FLAGSCHANGEDMASK];
  116.     return self;
  117. }
  118.  
  119. /*
  120.  * we implement flagsChanged in order to receive proximity events from the
  121.  * tablet.  We just use this to update a status field.
  122.  */
  123.  
  124. - flagsChanged:(NXEvent *)e
  125. {
  126.     BOOL proximity;
  127.     
  128.     proximity = e->flags & NX_STYLUSPROXIMITYMASK;
  129.     [proximityText setStringValue:
  130.          proximity ?
  131.          NXLocalString("in proximity", NULL, NULL) :
  132.     NXLocalString ("out of proximity", NULL, NULL)];
  133.     return self;    
  134. }
  135.  
  136.  
  137. /* 
  138.  * Target/Action methods used to control the special tracking rect options
  139.  * (pressure and coalescing).
  140.  */
  141.  
  142. - setCoalesceState:sender
  143. {
  144.     coalesceState = [sender state];
  145.     [self setPressureRect];
  146.     return self;
  147. }
  148.  
  149. - setPressureState:sender
  150. {
  151.     pressureState = [sender state];
  152.     [self setPressureRect];
  153.     return self;
  154. }
  155.  
  156. /*
  157.  * resetCursorRects will be called to give the view an opportunity to
  158.  * re-establish its tracking rects after the relative geometry between the
  159.  * Window and the View has changed.  We use this opportunity to set up oue
  160.  * special tracking rects for pressure and coalescing.
  161.  */
  162.  
  163. - resetCursorRects
  164. {
  165.     return [self setPressureRect];
  166. }
  167.  
  168. - setPressureRect
  169. {
  170.     NXRect visibleRect;
  171.  
  172.     [self lockFocus];
  173.     [self getVisibleRect: &visibleRect];
  174.  
  175.     /*
  176.      *  Setup the pressure rect.  Use our object address as the trackingrect
  177.      *  tag.
  178.      */
  179.     
  180.     set_pressure_rect(visibleRect.origin.x,
  181.               visibleRect.origin.y,
  182.               visibleRect.size.width,
  183.               visibleRect.size.height,
  184.               coalesceState,
  185.               pressureState,
  186.               (int) self);
  187.     
  188.     [self unlockFocus];
  189.     return self;
  190. }
  191.  
  192. @end
  193.