Annotation of Examples/AppKit/UnderPressure/PressureView.m, revision 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.