|
|
1.1 root 1: /*
2: * Money Well - cool dragging stuff
3: *
4: * Author: Kris Younger, NeXT Systems Engineering
5: * You may freely copy, distribute and reuse the code in this example.
6: * NeXT disclaims any warranty of any kind, expressed or implied, as to
7: * its fitness for any particular use.
8: */
9:
10: #import "MoneyWell.h"
11: #import "Transaction.h"
12: #import "MainDelegate.h"
13: #import "LedgerController.h"
14:
15: #define BOX(X,Y,W,H) PSmoveto(X,Y); PSrlineto(0, H); PSrlineto (W, 0); \
16: PSrlineto(0, (-1 * H)); PSclosepath()
17:
18: @implementation MoneyWell
19:
20: #define TRANS_PBOARDTYPE_NAME "Transaction"
21:
22: NXAtom TransPboardType = NULL;
23: static id dragObject = nil;
24: static id dragPBoard = nil;
25:
26:
27: - initFrame:(const NXRect *)frameRect
28: {
29: NXAtom type = NXUniqueString(TRANS_PBOARDTYPE_NAME);
30:
31: [super initFrame:frameRect];
32: image = [[NXImage alloc] initFromSection:"well"];
33: TransPboardType = type;
34: [self registerForDraggedTypes:&type count:1];
35: sel = NO;
36: return self;
37: }
38:
39: - (BOOL)acceptsFirstResponder
40: {
41: return YES;
42: }
43:
44: - (BOOL)acceptsFirstMouse
45: {
46: return YES;
47: }
48:
49: - free
50: {
51: [self unregisterDraggedTypes];
52: return[super free];
53: }
54:
55: - drawSelf:(const NXRect *)rects :(int)rectCount
56: {
57: NXSize imsze;
58: NXPoint origin;
59: NXRect inbounds;
60:
61: NXDrawButton(&bounds, rects);
62: if (sel) {
63: PSsetgray(1.0);
64: BOX((bounds.origin.x + 1), (bounds.origin.y + 2),
65: (bounds.size.width - 4), (bounds.size.height - 3));
66: PSfill();
67: }
68: inbounds.origin.x = inbounds.origin.y = 6;
69: inbounds.size.width = bounds.size.width - 12;
70: inbounds.size.height = bounds.size.height - 12;
71: NXDrawGrayBezel(&inbounds, rects);
72: [image getSize:&imsze];
73: origin.x = (bounds.size.width / 2) - (imsze.width / 2);
74: origin.y = (bounds.size.height / 2) - (imsze.height / 2);
75: [image composite:NX_SOVER toPoint:&origin];
76:
77: return self;
78: }
79:
80: #define mask (NX_LMOUSEUPMASK|NX_LMOUSEDRAGGEDMASK)
81: #define Shift(e) (e->flags&(NX_NEXTLSHIFTKEYMASK|NX_NEXTRSHIFTKEYMASK))
82: #ifndef abs
83: #define abs(x) (((x)<0)? -(x) : (x))
84: #endif
85:
86: int
87: aMouseMoved(NXPoint *o, int n)
88: { /* true if mouse moves > n pixels from 'o' */
89: NXEvent *e;
90: NXPoint p;
91: float d;
92:
93: do {
94: e = [NXApp getNextEvent:mask];
95: p = e->location;
96: d = abs(p.x - o->x);
97: if (d < abs(p.y - o->y))
98: d = abs(p.y - o->y);
99: } while (e->type != NX_LMOUSEUP && d < n);
100: *o = p;
101: return e->type != NX_LMOUSEUP;
102: }
103:
104: #define COPYPOINT(A, B) A.x = B.x; A.y = B.y
105: - mouseDown:(NXEvent *)e
106: {
107: NXPoint hit, me;
108: int oldMask;
109: NXEvent saveEvent;
110: Pasteboard *dragPasteboard;
111:
112: oldMask = [window eventMask];
113: [window setEventMask:(oldMask | mask)];
114: saveEvent = *e;
115: hit = e->location;
116: COPYPOINT(me, hit);
117: [self convertPoint:&me fromView:nil];
118:
119: if (((me.x <= 7.0) || (me.x >= (bounds.size.width - 7.0))) ||
120: ((me.y <= 7.0) || (me.y >= (bounds.size.height - 7.0)))) {
121: if (sel) {
122: sel = NO;
123: [self display];
124: } else {
125: sel = YES;
126: [self display];
127: }
128: } else {
129: if (aMouseMoved(&hit, 4)) {
130: NXRect dragRect;
131:
132: [self convertPoint:&hit fromView:nil];
133: [self getBounds:&dragRect];
134: dragRect.origin.x = 8;
135: dragRect.origin.y = 8;
136: dragPasteboard = [Pasteboard newName:NXDragPboard];
137: [dragPasteboard declareTypes:&TransPboardType num:1 owner:self];
138: dragObject = nil;
139:
140: [self dragImage:image at:&(dragRect.origin) offset :&hit
141: event:&saveEvent pasteboard:dragPasteboard
142: source:self slideBack:YES];
143: }
144: }
145: return[super mouseDown:e];
146: }
147:
148: - transaction:requestor
149: {
150: id farOne, nearOne;
151: double trValue;
152: const char *today;
153: char buf[256];
154:
155: trValue = [valueTF doubleValue];
156: if (trValue > 0.0) {
157: nearOne = [[Transaction alloc] init];
158: farOne = [[Transaction alloc] init];
159: today = [[NXApp delegate] todaysDate];
160:
161: [nearOne setTAmount:-trValue];
162: [farOne setTAmount:trValue];
163: [nearOne setTDate:today];
164: [farOne setTDate:today];
165: strcpy(buf, "Transfer to ");
166: strcat(buf,[requestor accountName]);
167: [nearOne setTMemo:buf];
168: strcpy(buf, "Transfer from ");
169: strcat(buf,[ledgerController accountName]);
170: [farOne setTMemo:buf];
171:
172: [ledgerController appendThis:nearOne];
173: [ledgerController commit:self];
174: [valueTF setStringValue:"0.00"];
175: return farOne;
176: } else
177: return nil;
178: }
179:
180: //Drag Support
181: - (NXDragOperation) draggingSourceOperationMaskForLocal:(BOOL)flag
182: {
183: return (flag) ? NX_DragOperationCopy : NX_DragOperationNone;
184: }
185:
186: static BOOL
187: includesType(const NXAtom * types, NXAtom type)
188: {
189: if (types)
190: while (*types)
191: if (*types++ == type)
192: return YES;
193: return NO;
194: }
195:
196: - (NXDragOperation) draggingEntered:(id <NXDraggingInfo >)sender
197: {
198: char *transName;
199: const char *const * types;
200: int length;
201: id aPasteboard;
202:
203: aPasteboard = [sender draggingPasteboard];
204: for (types = [aPasteboard types]; *types; types++)
205: if (*types == TransPboardType)
206: {
207: [aPasteboard readType:*types data:&transName length:&length];
208: dragObject = [sender draggingSource];
209: [aPasteboard deallocatePasteboardData:transName length:length];
210: break;
211: }
212:
213: return (dragObject != nil) ? NX_DragOperationCopy : NX_DragOperationNone;
214: }
215:
216: - declareTypesFor:anObject inPasteboard:aPasteboard
217: {
218: const char *types[1] = {TransPboardType};
219:
220: if ([anObject isKindOfClassNamed:NXUniqueString(TRANS_PBOARDTYPE_NAME)]) {
221: [aPasteboard declareTypes:types num:1 owner:self];
222: dragObject = anObject;
223: dragPBoard = aPasteboard;
224: return self;
225: }
226: return nil;
227: }
228:
229: - draggingExited:sender
230: {
231: if (includesType([[sender draggingPasteboard] types], TransPboardType)) {
232: dropping = NO;
233: dragObject = nil;
234: [self display];
235: }
236: return self;
237: }
238:
239: - (BOOL)performDragOperation:(id <NXDraggingInfo >)sender
240: {
241: Pasteboard *pboard = [sender draggingPasteboard];
242:
243: dropping = NO;
244: if (includesType([pboard types], TransPboardType)) {
245: [ledgerController appendThis: [dragObject transaction:ledgerController]];
246: [ledgerController commit:self];
247: [valueTF setStringValue:"0.00"];
248: return YES;
249: } else
250: return NO;
251: }
252:
253: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.