|
|
Sample Programs from NeXSTEP 3.3
/*
* Money Well - cool dragging stuff
*
* Author: Kris Younger, NeXT Systems Engineering
* 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.
*/
#import "MoneyWell.h"
#import "Transaction.h"
#import "MainDelegate.h"
#import "LedgerController.h"
#define BOX(X,Y,W,H) PSmoveto(X,Y); PSrlineto(0, H); PSrlineto (W, 0); \
PSrlineto(0, (-1 * H)); PSclosepath()
@implementation MoneyWell
#define TRANS_PBOARDTYPE_NAME "Transaction"
NXAtom TransPboardType = NULL;
static id dragObject = nil;
static id dragPBoard = nil;
- initFrame:(const NXRect *)frameRect
{
NXAtom type = NXUniqueString(TRANS_PBOARDTYPE_NAME);
[super initFrame:frameRect];
image = [[NXImage alloc] initFromSection:"well"];
TransPboardType = type;
[self registerForDraggedTypes:&type count:1];
sel = NO;
return self;
}
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (BOOL)acceptsFirstMouse
{
return YES;
}
- free
{
[self unregisterDraggedTypes];
return[super free];
}
- drawSelf:(const NXRect *)rects :(int)rectCount
{
NXSize imsze;
NXPoint origin;
NXRect inbounds;
NXDrawButton(&bounds, rects);
if (sel) {
PSsetgray(1.0);
BOX((bounds.origin.x + 1), (bounds.origin.y + 2),
(bounds.size.width - 4), (bounds.size.height - 3));
PSfill();
}
inbounds.origin.x = inbounds.origin.y = 6;
inbounds.size.width = bounds.size.width - 12;
inbounds.size.height = bounds.size.height - 12;
NXDrawGrayBezel(&inbounds, rects);
[image getSize:&imsze];
origin.x = (bounds.size.width / 2) - (imsze.width / 2);
origin.y = (bounds.size.height / 2) - (imsze.height / 2);
[image composite:NX_SOVER toPoint:&origin];
return self;
}
#define mask (NX_LMOUSEUPMASK|NX_LMOUSEDRAGGEDMASK)
#define Shift(e) (e->flags&(NX_NEXTLSHIFTKEYMASK|NX_NEXTRSHIFTKEYMASK))
#ifndef abs
#define abs(x) (((x)<0)? -(x) : (x))
#endif
int
aMouseMoved(NXPoint *o, int n)
{ /* true if mouse moves > n pixels from 'o' */
NXEvent *e;
NXPoint p;
float d;
do {
e = [NXApp getNextEvent:mask];
p = e->location;
d = abs(p.x - o->x);
if (d < abs(p.y - o->y))
d = abs(p.y - o->y);
} while (e->type != NX_LMOUSEUP && d < n);
*o = p;
return e->type != NX_LMOUSEUP;
}
#define COPYPOINT(A, B) A.x = B.x; A.y = B.y
- mouseDown:(NXEvent *)e
{
NXPoint hit, me;
int oldMask;
NXEvent saveEvent;
Pasteboard *dragPasteboard;
oldMask = [window eventMask];
[window setEventMask:(oldMask | mask)];
saveEvent = *e;
hit = e->location;
COPYPOINT(me, hit);
[self convertPoint:&me fromView:nil];
if (((me.x <= 7.0) || (me.x >= (bounds.size.width - 7.0))) ||
((me.y <= 7.0) || (me.y >= (bounds.size.height - 7.0)))) {
if (sel) {
sel = NO;
[self display];
} else {
sel = YES;
[self display];
}
} else {
if (aMouseMoved(&hit, 4)) {
NXRect dragRect;
[self convertPoint:&hit fromView:nil];
[self getBounds:&dragRect];
dragRect.origin.x = 8;
dragRect.origin.y = 8;
dragPasteboard = [Pasteboard newName:NXDragPboard];
[dragPasteboard declareTypes:&TransPboardType num:1 owner:self];
dragObject = nil;
[self dragImage:image at:&(dragRect.origin) offset :&hit
event:&saveEvent pasteboard:dragPasteboard
source:self slideBack:YES];
}
}
return[super mouseDown:e];
}
- transaction:requestor
{
id farOne, nearOne;
double trValue;
const char *today;
char buf[256];
trValue = [valueTF doubleValue];
if (trValue > 0.0) {
nearOne = [[Transaction alloc] init];
farOne = [[Transaction alloc] init];
today = [[NXApp delegate] todaysDate];
[nearOne setTAmount:-trValue];
[farOne setTAmount:trValue];
[nearOne setTDate:today];
[farOne setTDate:today];
strcpy(buf, "Transfer to ");
strcat(buf,[requestor accountName]);
[nearOne setTMemo:buf];
strcpy(buf, "Transfer from ");
strcat(buf,[ledgerController accountName]);
[farOne setTMemo:buf];
[ledgerController appendThis:nearOne];
[ledgerController commit:self];
[valueTF setStringValue:"0.00"];
return farOne;
} else
return nil;
}
//Drag Support
- (NXDragOperation) draggingSourceOperationMaskForLocal:(BOOL)flag
{
return (flag) ? NX_DragOperationCopy : NX_DragOperationNone;
}
static BOOL
includesType(const NXAtom * types, NXAtom type)
{
if (types)
while (*types)
if (*types++ == type)
return YES;
return NO;
}
- (NXDragOperation) draggingEntered:(id <NXDraggingInfo >)sender
{
char *transName;
const char *const * types;
int length;
id aPasteboard;
aPasteboard = [sender draggingPasteboard];
for (types = [aPasteboard types]; *types; types++)
if (*types == TransPboardType)
{
[aPasteboard readType:*types data:&transName length:&length];
dragObject = [sender draggingSource];
[aPasteboard deallocatePasteboardData:transName length:length];
break;
}
return (dragObject != nil) ? NX_DragOperationCopy : NX_DragOperationNone;
}
- declareTypesFor:anObject inPasteboard:aPasteboard
{
const char *types[1] = {TransPboardType};
if ([anObject isKindOfClassNamed:NXUniqueString(TRANS_PBOARDTYPE_NAME)]) {
[aPasteboard declareTypes:types num:1 owner:self];
dragObject = anObject;
dragPBoard = aPasteboard;
return self;
}
return nil;
}
- draggingExited:sender
{
if (includesType([[sender draggingPasteboard] types], TransPboardType)) {
dropping = NO;
dragObject = nil;
[self display];
}
return self;
}
- (BOOL)performDragOperation:(id <NXDraggingInfo >)sender
{
Pasteboard *pboard = [sender draggingPasteboard];
dropping = NO;
if (includesType([pboard types], TransPboardType)) {
[ledgerController appendThis: [dragObject transaction:ledgerController]];
[ledgerController commit:self];
[valueTF setStringValue:"0.00"];
return YES;
} else
return NO;
}
@end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.