This is AbstractFilledSquare.m in view mode; [Download] [Up]
#import "AbstractFilledSquare.h" #import "EmptySquare.h" /* for foundAdajacent message decl. */ @implementation AbstractFilledSquare - (BOOL) acceptsFirstMouse { return YES; } - (float) color { return [self subclassResponsibility: _cmd], 0; /* ", 0" for -Wall */ } #define FRACTION 0.6 - drawSelf: (const NXRect *) rects : (int) rectCount { double cx = NX_MIDX(&bounds), cy = NX_MIDY(&bounds); [super drawSelf: rects : rectCount]; PSsetgray([self color]); PSarc(cx, cy, FRACTION * bounds.size.width / 2, 0, 360); PSfill(); if ([self isSelected]) [self select: cx : cy]; return self; } - (BOOL) isMyMove { return [[self window] isWhiteMove] == [self isWhite]; } - (BOOL) isSelected { return isSelected; } - (BOOL) isWhite { return [self subclassResponsibility: _cmd], NO; } - mouseDown: (NXEvent *) theEvent { if ([self isMyMove]) [self setIsSelected: YES]; return self; } - mouseEntered: (NXEvent *) theEvent { if ([self isSelected] || ([self isMyMove] /* could see if ANY move legal */ && ![[self window] isSomeoneSelected])) [self setIsHighlighted: YES]; return self; } - mouseUp: (NXEvent *) theEvent { id emptySquare = [[self window] highlightedSquare]; if (self != emptySquare && [self isSelected] /* && emptySquare != nil */ && [emptySquare isHighlighted]) { id emptyClass = [emptySquare class]; short jump = [self distanceTo: emptySquare]; [[self window] makeSquaresPerform: @selector(capture:) with: [emptySquare become: [self class]]]; [self setIsSelected: NO]; /* won't be done by free in become: */ if (jump > 1) /* below since it needs [self window] to work */ return [[[self become: emptyClass] window] letOtherColorMove]; return [[self window] letOtherColorMove]; /* hope any non-nil is OK */ } return [self setIsSelected: NO]; } - setIsSelected: (BOOL) state { [[self window] setIsSomeoneSelected: isSelected = state]; return [self display]; } /* Private methods: */ - capture: sender { if ([self class] != [sender class] && [self distanceTo: sender] == 1) return [self become: [sender class]]; return self; } - checkAdjacencyWith: sender { /* can extend below for a toroidal board */ if ([self isSelected] && [self distanceTo: sender] <= 2) [sender foundAdjacent]; return self; } - free { if ([self isSelected]) /* this no longer works right after */ [[self window] setIsSomeoneSelected: NO]; /* a removeFromSuperview */ return [super free]; } #define X_OFFSET 9 /* should really be a % of width */ #define X_WIDTH 4 - select: (double) cx : (double) cy { PSsetgray(NX_DKGRAY); PSsetlinewidth(X_WIDTH); PSmoveto(cx - X_OFFSET, cy + X_OFFSET); PSlineto(cx + X_OFFSET, cy - X_OFFSET); PSmoveto(cx + X_OFFSET, cy + X_OFFSET); PSlineto(cx - X_OFFSET, cy - X_OFFSET); PSstroke(); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.