|
|
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.