|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.