Annotation of Examples/AppKit/UnderPressure/PressureView.m, revision 1.1.1.1

1.1       root        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 fromView: 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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.