home *** CD-ROM | disk | FTP | other *** search
- #if 0
-
- PressureView.m -- Pressure sensitive View subclass for painting
-
- by Peter Graffagnino, NeXT Computer Inc.
-
- PressureView is a view subclass responsible for:
-
- - maintaining a special trackingrect to inform the low-level event
- system of its interest in pressure and event coalescing.
- - maintaining an NXImage backingstore for the View.
- - implementing a mouseDown: painting loop and using a Brush object for
- painting
- - handling flagsChanged: events to update pen proximity state
-
- You may freely copy, distribute, and reuse the code in this example.
- NeXT disclaims any warranty of any kind, expressed or implied, as to its
- fitness for any particular use.
-
- #endif
-
- #import <appkit/appkit.h>
- #include <math.h>
- #include <dpsclient/wraps.h>
- #import "PressureView.h"
- #import "Brush.h"
- #import "pressurerect.h"
-
- @implementation PressureView : View
-
- - initFrame:(const NXRect *)r
- {
- self = [super initFrame:r];
- [self allocateGState];
- backingImage = [[NXImage alloc] initSize: &r->size];
- [backingImage setBackgroundColor: NX_COLORWHITE];
- coalesceState = YES;
- pressureState = YES;
- [self clear: self];
- return self;
- }
-
- - free
- {
- [backingImage free];
- return [super free];
- }
-
- - clear:sender
- {
- if (! [backingImage lockFocus]) return self;
- NXSetColor(NX_COLORWHITE);
- NXRectFill(&bounds);
- [backingImage unlockFocus];
- [self display];
- return self;
- }
-
- - drawSelf:(const NXRect *)rects :(int)rectCount
- {
- [backingImage composite: NX_COPY fromRect: rects toPoint: &rects->origin];
- return self;
- }
-
- - sizeTo: (NXCoord) x : (NXCoord) y
- {
- NXSize size;
- [super sizeTo: x : y];
- size.width = x;
- size.height = y;
- [backingImage setSize: &size];
- return self;
- }
-
- - mouseDown:(NXEvent *)e
- {
- NXPoint p;
- NXRect dirty;
- int emask=[window addToEventMask:(NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK)];
-
- if( ! [backingImage lockFocus] ) return self;
-
- p = e->location;
- [self convertPoint: &p fromUCi: nil];
- p.x += .5; p.y += .5;
- [brush brushMoveTo: p.x : p.y withPressure: e->data.mouse.pressure/255.0
- dirtyRect: &dirty];
- [self display: &dirty : 1];
- while(1) {
- e=[NXApp getNextEvent:(NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK)];
- if(e->type == NX_MOUSEUP)
- break;
- p = e->location;
- [self convertPoint: &p fromView: nil];
- p.x += .5; p.y += .5;
- [brush brushLineTo: p.x : p.y withPressure:
- e->data.mouse.pressure/255.0
- dirtyRect: &dirty];
- [self display: &dirty : 1];
- NXPing();
- }
- [backingImage unlockFocus];
- [window setEventMask:emask];
- return self;
- }
-
-
- - (BOOL) acceptsFirstResponder
- {
- return YES;
- }
-
- - awakeFromNib
- {
- [window addToEventMask:NX_FLAGSCHANGEDMASK];
- return self;
- }
-
- /*
- * we implement flagsChanged in order to receive proximity events from the
- * tablet. We just use this to update a status field.
- */
-
- - flagsChanged:(NXEvent *)e
- {
- BOOL proximity;
-
- proximity = e->flags & NX_STYLUSPROXIMITYMASK;
- [proximityText setStringValue:
- proximity ?
- NXLocalString("in proximity", NULL, NULL) :
- NXLocalString ("out of proximity", NULL, NULL)];
- return self;
- }
-
-
- /*
- * Target/Action methods used to control the special tracking rect options
- * (pressure and coalescing).
- */
-
- - setCoalesceState:sender
- {
- coalesceState = [sender state];
- [self setPressureRect];
- return self;
- }
-
- - setPressureState:sender
- {
- pressureState = [sender state];
- [self setPressureRect];
- return self;
- }
-
- /*
- * resetCursorRects will be called to give the view an opportunity to
- * re-establish its tracking rects after the relative geometry between the
- * Window and the View has changed. We use this opportunity to set up oue
- * special tracking rects for pressure and coalescing.
- */
-
- - resetCursorRects
- {
- return [self setPressureRect];
- }
-
- - setPressureRect
- {
- NXRect visibleRect;
-
- [self lockFocus];
- [self getVisibleRect: &visibleRect];
-
- /*
- * Setup the pressure rect. Use our object address as the trackingrect
- * tag.
- */
-
- set_pressure_rect(visibleRect.origin.x,
- visibleRect.origin.y,
- visibleRect.size.width,
- visibleRect.size.height,
- coalesceState,
- pressureState,
- (int) self);
-
- [self unlockFocus];
- return self;
- }
-
- @end
-