jens@0
|
1 |
/* This code is based on Apple's "GeekGameBoard" sample code, version 1.0.
|
jens@0
|
2 |
http://developer.apple.com/samplecode/GeekGameBoard/
|
jens@0
|
3 |
Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved.
|
jens@0
|
4 |
|
jens@0
|
5 |
Redistribution and use in source and binary forms, with or without modification, are permitted
|
jens@0
|
6 |
provided that the following conditions are met:
|
jens@0
|
7 |
|
jens@0
|
8 |
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
jens@0
|
9 |
and the following disclaimer.
|
jens@0
|
10 |
* Redistributions in binary form must reproduce the above copyright notice, this list of
|
jens@0
|
11 |
conditions and the following disclaimer in the documentation and/or other materials provided
|
jens@0
|
12 |
with the distribution.
|
jens@0
|
13 |
|
jens@0
|
14 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
jens@0
|
15 |
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
jens@0
|
16 |
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
|
jens@0
|
17 |
BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
jens@0
|
18 |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
jens@0
|
19 |
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
jens@0
|
20 |
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
jens@0
|
21 |
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
jens@0
|
22 |
*/
|
jens@0
|
23 |
#import "Grid.h"
|
jens@0
|
24 |
#import "Bit.h"
|
jens@0
|
25 |
#import "Game.h"
|
jens@0
|
26 |
#import "QuartzUtils.h"
|
jens@0
|
27 |
|
jens@0
|
28 |
|
jens@0
|
29 |
@implementation Grid
|
jens@0
|
30 |
|
jens@0
|
31 |
|
jens@0
|
32 |
- (id) initWithRows: (unsigned)nRows columns: (unsigned)nColumns
|
jens@0
|
33 |
spacing: (CGSize)spacing
|
jens@0
|
34 |
position: (CGPoint)pos
|
jens@0
|
35 |
{
|
jens@0
|
36 |
NSParameterAssert(nRows>0 && nColumns>0);
|
jens@0
|
37 |
self = [super init];
|
jens@0
|
38 |
if( self ) {
|
jens@0
|
39 |
_nRows = nRows;
|
jens@0
|
40 |
_nColumns = nColumns;
|
jens@0
|
41 |
_spacing = spacing;
|
jens@0
|
42 |
_cellClass = [GridCell class];
|
jens@1
|
43 |
self.lineColor = kBlackColor;
|
jens@0
|
44 |
_allowsMoves = YES;
|
jens@0
|
45 |
_usesDiagonals = YES;
|
jens@0
|
46 |
|
jens@0
|
47 |
self.bounds = CGRectMake(-1, -1, nColumns*spacing.width+2, nRows*spacing.height+2);
|
jens@0
|
48 |
self.position = pos;
|
jens@0
|
49 |
self.anchorPoint = CGPointMake(0,0);
|
jens@0
|
50 |
self.zPosition = kBoardZ;
|
jens@0
|
51 |
self.needsDisplayOnBoundsChange = YES;
|
jens@0
|
52 |
|
jens@0
|
53 |
unsigned n = nRows*nColumns;
|
jens@0
|
54 |
_cells = [[NSMutableArray alloc] initWithCapacity: n];
|
jens@0
|
55 |
id null = [NSNull null];
|
jens@0
|
56 |
while( n-- > 0 )
|
jens@0
|
57 |
[_cells addObject: null];
|
jens@0
|
58 |
|
jens@0
|
59 |
[self setNeedsDisplay];
|
jens@0
|
60 |
}
|
jens@0
|
61 |
return self;
|
jens@0
|
62 |
}
|
jens@0
|
63 |
|
jens@0
|
64 |
|
jens@0
|
65 |
- (id) initWithRows: (unsigned)nRows columns: (unsigned)nColumns
|
jens@0
|
66 |
frame: (CGRect)frame
|
jens@0
|
67 |
{
|
jens@0
|
68 |
CGFloat spacing = floor(MIN( (frame.size.width -2)/(CGFloat)nColumns,
|
jens@0
|
69 |
(frame.size.height-2)/(CGFloat)nRows) );
|
jens@3
|
70 |
CGSize size = CGSizeMake(nColumns*spacing+2, nRows*spacing+2);
|
jens@3
|
71 |
CGPoint position = frame.origin;
|
jens@3
|
72 |
position.x += round( (frame.size.width -size.width )/2.0 );
|
jens@3
|
73 |
position.y += round( (frame.size.height-size.height)/2.0 );
|
jens@3
|
74 |
|
jens@0
|
75 |
return [self initWithRows: nRows columns: nColumns
|
jens@0
|
76 |
spacing: CGSizeMake(spacing,spacing)
|
jens@3
|
77 |
position: position];
|
jens@0
|
78 |
}
|
jens@0
|
79 |
|
jens@0
|
80 |
|
jens@0
|
81 |
- (void) dealloc
|
jens@0
|
82 |
{
|
jens@0
|
83 |
CGColorRelease(_cellColor);
|
jens@0
|
84 |
CGColorRelease(_lineColor);
|
jens@0
|
85 |
[_cells release];
|
jens@0
|
86 |
[super dealloc];
|
jens@0
|
87 |
}
|
jens@0
|
88 |
|
jens@0
|
89 |
|
jens@0
|
90 |
static void setcolor( CGColorRef *var, CGColorRef color )
|
jens@0
|
91 |
{
|
jens@0
|
92 |
if( color != *var ) {
|
jens@0
|
93 |
CGColorRelease(*var);
|
jens@0
|
94 |
*var = CGColorRetain(color);
|
jens@0
|
95 |
}
|
jens@0
|
96 |
}
|
jens@0
|
97 |
|
jens@0
|
98 |
- (CGColorRef) cellColor {return _cellColor;}
|
jens@0
|
99 |
- (void) setCellColor: (CGColorRef)cellColor {setcolor(&_cellColor,cellColor);}
|
jens@0
|
100 |
|
jens@0
|
101 |
- (CGColorRef) lineColor {return _lineColor;}
|
jens@0
|
102 |
- (void) setLineColor: (CGColorRef)lineColor {setcolor(&_lineColor,lineColor);}
|
jens@0
|
103 |
|
jens@0
|
104 |
@synthesize cellClass=_cellClass, rows=_nRows, columns=_nColumns, spacing=_spacing,
|
jens@0
|
105 |
usesDiagonals=_usesDiagonals, allowsMoves=_allowsMoves, allowsCaptures=_allowsCaptures;
|
jens@0
|
106 |
|
jens@0
|
107 |
|
jens@0
|
108 |
#pragma mark -
|
jens@0
|
109 |
#pragma mark GEOMETRY:
|
jens@0
|
110 |
|
jens@0
|
111 |
|
jens@0
|
112 |
- (GridCell*) cellAtRow: (unsigned)row column: (unsigned)col
|
jens@0
|
113 |
{
|
jens@0
|
114 |
if( row < _nRows && col < _nColumns ) {
|
jens@0
|
115 |
id cell = [_cells objectAtIndex: row*_nColumns+col];
|
jens@0
|
116 |
if( cell != [NSNull null] )
|
jens@0
|
117 |
return cell;
|
jens@0
|
118 |
}
|
jens@0
|
119 |
return nil;
|
jens@0
|
120 |
}
|
jens@0
|
121 |
|
jens@0
|
122 |
|
jens@0
|
123 |
/** Subclasses can override this, to change the cell's class or frame. */
|
jens@0
|
124 |
- (GridCell*) createCellAtRow: (unsigned)row column: (unsigned)col
|
jens@0
|
125 |
suggestedFrame: (CGRect)frame
|
jens@0
|
126 |
{
|
jens@0
|
127 |
return [[[_cellClass alloc] initWithGrid: self
|
jens@0
|
128 |
row: row column: col
|
jens@0
|
129 |
frame: frame]
|
jens@0
|
130 |
autorelease];
|
jens@0
|
131 |
}
|
jens@0
|
132 |
|
jens@0
|
133 |
|
jens@0
|
134 |
- (GridCell*) addCellAtRow: (unsigned)row column: (unsigned)col
|
jens@0
|
135 |
{
|
jens@0
|
136 |
NSParameterAssert(row<_nRows);
|
jens@0
|
137 |
NSParameterAssert(col<_nColumns);
|
jens@0
|
138 |
unsigned index = row*_nColumns+col;
|
jens@0
|
139 |
GridCell *cell = [_cells objectAtIndex: index];
|
jens@0
|
140 |
if( (id)cell == [NSNull null] ) {
|
jens@0
|
141 |
CGRect frame = CGRectMake(col*_spacing.width, row*_spacing.height,
|
jens@0
|
142 |
_spacing.width,_spacing.height);
|
jens@0
|
143 |
cell = [self createCellAtRow: row column: col suggestedFrame: frame];
|
jens@0
|
144 |
if( cell ) {
|
jens@0
|
145 |
[_cells replaceObjectAtIndex: index withObject: cell];
|
jens@0
|
146 |
[self addSublayer: cell];
|
jens@0
|
147 |
[self setNeedsDisplay];
|
jens@0
|
148 |
}
|
jens@0
|
149 |
}
|
jens@0
|
150 |
return cell;
|
jens@0
|
151 |
}
|
jens@0
|
152 |
|
jens@0
|
153 |
|
jens@0
|
154 |
- (void) addAllCells
|
jens@0
|
155 |
{
|
jens@0
|
156 |
for( int row=_nRows-1; row>=0; row-- ) // makes 'upper' cells be in 'back'
|
jens@0
|
157 |
for( int col=0; col<_nColumns; col++ )
|
jens@0
|
158 |
[self addCellAtRow: row column: col];
|
jens@0
|
159 |
}
|
jens@0
|
160 |
|
jens@0
|
161 |
|
jens@0
|
162 |
- (void) removeCellAtRow: (unsigned)row column: (unsigned)col
|
jens@0
|
163 |
{
|
jens@0
|
164 |
NSParameterAssert(row<_nRows);
|
jens@0
|
165 |
NSParameterAssert(col<_nColumns);
|
jens@0
|
166 |
unsigned index = row*_nColumns+col;
|
jens@0
|
167 |
id cell = [_cells objectAtIndex: index];
|
jens@0
|
168 |
if( cell != [NSNull null] )
|
jens@0
|
169 |
[cell removeFromSuperlayer];
|
jens@0
|
170 |
[_cells replaceObjectAtIndex: index withObject: [NSNull null]];
|
jens@0
|
171 |
[self setNeedsDisplay];
|
jens@0
|
172 |
}
|
jens@0
|
173 |
|
jens@0
|
174 |
|
jens@0
|
175 |
#pragma mark -
|
jens@0
|
176 |
#pragma mark DRAWING:
|
jens@0
|
177 |
|
jens@0
|
178 |
|
jens@0
|
179 |
- (void) drawCellsInContext: (CGContextRef)ctx fill: (BOOL)fill
|
jens@0
|
180 |
{
|
jens@0
|
181 |
// Subroutine of -drawInContext:. Draws all the cells, with or without a fill.
|
jens@0
|
182 |
for( unsigned row=0; row<_nRows; row++ )
|
jens@0
|
183 |
for( unsigned col=0; col<_nColumns; col++ ) {
|
jens@0
|
184 |
GridCell *cell = [self cellAtRow: row column: col];
|
jens@0
|
185 |
if( cell )
|
jens@0
|
186 |
[cell drawInParentContext: ctx fill: fill];
|
jens@0
|
187 |
}
|
jens@0
|
188 |
}
|
jens@0
|
189 |
|
jens@0
|
190 |
|
jens@0
|
191 |
- (void)drawInContext:(CGContextRef)ctx
|
jens@0
|
192 |
{
|
jens@0
|
193 |
// Custom CALayer drawing implementation. Delegates to the cells to draw themselves
|
jens@0
|
194 |
// in me; this is more efficient than having each cell have its own drawing.
|
jens@3
|
195 |
[super drawInContext: ctx];
|
jens@0
|
196 |
if( _cellColor ) {
|
jens@0
|
197 |
CGContextSetFillColorWithColor(ctx, _cellColor);
|
jens@0
|
198 |
[self drawCellsInContext: ctx fill: YES];
|
jens@0
|
199 |
}
|
jens@0
|
200 |
if( _lineColor ) {
|
jens@0
|
201 |
CGContextSetStrokeColorWithColor(ctx,_lineColor);
|
jens@0
|
202 |
[self drawCellsInContext:ctx fill: NO];
|
jens@0
|
203 |
}
|
jens@0
|
204 |
}
|
jens@0
|
205 |
|
jens@0
|
206 |
|
jens@0
|
207 |
@end
|
jens@0
|
208 |
|
jens@0
|
209 |
|
jens@0
|
210 |
|
jens@0
|
211 |
#pragma mark -
|
jens@0
|
212 |
|
jens@0
|
213 |
@implementation GridCell
|
jens@0
|
214 |
|
jens@0
|
215 |
|
jens@0
|
216 |
- (id) initWithGrid: (Grid*)grid
|
jens@0
|
217 |
row: (unsigned)row column: (unsigned)col
|
jens@0
|
218 |
frame: (CGRect)frame
|
jens@0
|
219 |
{
|
jens@0
|
220 |
self = [super init];
|
jens@0
|
221 |
if (self != nil) {
|
jens@0
|
222 |
_grid = grid;
|
jens@0
|
223 |
_row = row;
|
jens@0
|
224 |
_column = col;
|
jens@0
|
225 |
self.position = frame.origin;
|
jens@0
|
226 |
CGRect bounds = frame;
|
jens@0
|
227 |
bounds.origin.x -= floor(bounds.origin.x); // make sure my coords fall on pixel boundaries
|
jens@0
|
228 |
bounds.origin.y -= floor(bounds.origin.y);
|
jens@0
|
229 |
self.bounds = bounds;
|
jens@0
|
230 |
self.anchorPoint = CGPointMake(0,0);
|
jens@0
|
231 |
self.borderColor = kHighlightColor; // Used when highlighting (see -setHighlighted:)
|
jens@0
|
232 |
}
|
jens@0
|
233 |
return self;
|
jens@0
|
234 |
}
|
jens@0
|
235 |
|
jens@0
|
236 |
- (NSString*) description
|
jens@0
|
237 |
{
|
jens@0
|
238 |
return [NSString stringWithFormat: @"%@(%u,%u)", [self class],_column,_row];
|
jens@0
|
239 |
}
|
jens@0
|
240 |
|
jens@0
|
241 |
@synthesize grid=_grid, row=_row, column=_column;
|
jens@0
|
242 |
|
jens@0
|
243 |
|
jens@0
|
244 |
- (void) drawInParentContext: (CGContextRef)ctx fill: (BOOL)fill
|
jens@0
|
245 |
{
|
jens@0
|
246 |
// Default implementation just fills or outlines the cell.
|
jens@0
|
247 |
CGRect frame = self.frame;
|
jens@0
|
248 |
if( fill )
|
jens@0
|
249 |
CGContextFillRect(ctx,frame);
|
jens@0
|
250 |
else
|
jens@0
|
251 |
CGContextStrokeRect(ctx, frame);
|
jens@0
|
252 |
}
|
jens@0
|
253 |
|
jens@0
|
254 |
|
jens@0
|
255 |
- (void) setBit: (Bit*)bit
|
jens@0
|
256 |
{
|
jens@0
|
257 |
if( bit != self.bit ) {
|
jens@0
|
258 |
[super setBit: bit];
|
jens@0
|
259 |
if( bit ) {
|
jens@0
|
260 |
// Center it:
|
jens@0
|
261 |
CGSize size = self.bounds.size;
|
jens@0
|
262 |
bit.position = CGPointMake(floor(size.width/2.0),
|
jens@0
|
263 |
floor(size.height/2.0));
|
jens@0
|
264 |
}
|
jens@0
|
265 |
}
|
jens@0
|
266 |
}
|
jens@0
|
267 |
|
jens@0
|
268 |
- (Bit*) canDragBit: (Bit*)bit
|
jens@0
|
269 |
{
|
jens@0
|
270 |
if( _grid.allowsMoves && bit==self.bit )
|
jens@0
|
271 |
return [super canDragBit: bit];
|
jens@0
|
272 |
else
|
jens@0
|
273 |
return nil;
|
jens@0
|
274 |
}
|
jens@0
|
275 |
|
jens@0
|
276 |
- (BOOL) canDropBit: (Bit*)bit atPoint: (CGPoint)point
|
jens@0
|
277 |
{
|
jens@0
|
278 |
return self.bit == nil || _grid.allowsCaptures;
|
jens@0
|
279 |
}
|
jens@0
|
280 |
|
jens@0
|
281 |
|
jens@0
|
282 |
- (BOOL) fwdIsN
|
jens@0
|
283 |
{
|
jens@0
|
284 |
return self.game.currentPlayer.index == 0;
|
jens@0
|
285 |
}
|
jens@0
|
286 |
|
jens@0
|
287 |
|
jens@0
|
288 |
- (NSArray*) neighbors
|
jens@0
|
289 |
{
|
jens@0
|
290 |
BOOL orthogonal = ! _grid.usesDiagonals;
|
jens@0
|
291 |
NSMutableArray *neighbors = [NSMutableArray arrayWithCapacity: 8];
|
jens@0
|
292 |
for( int dy=-1; dy<=1; dy++ )
|
jens@0
|
293 |
for( int dx=-1; dx<=1; dx++ )
|
jens@0
|
294 |
if( (dx || dy) && !(orthogonal && dx && dy) ) {
|
jens@0
|
295 |
GridCell *cell = [_grid cellAtRow: _row+dy column: _column+dx];
|
jens@0
|
296 |
if( cell )
|
jens@0
|
297 |
[neighbors addObject: cell];
|
jens@0
|
298 |
}
|
jens@0
|
299 |
return neighbors;
|
jens@0
|
300 |
}
|
jens@0
|
301 |
|
jens@0
|
302 |
|
jens@0
|
303 |
// Recursive subroutine used by getGroup:.
|
jens@0
|
304 |
- (void) x_addToGroup: (NSMutableSet*)group liberties: (NSMutableSet*)liberties owner: (Player*)owner
|
jens@0
|
305 |
{
|
jens@0
|
306 |
Bit *bit = self.bit;
|
jens@0
|
307 |
if( bit == nil ) {
|
jens@0
|
308 |
if( [liberties containsObject: self] )
|
jens@0
|
309 |
return; // already traversed
|
jens@0
|
310 |
[liberties addObject: self];
|
jens@0
|
311 |
} else if( bit.owner==owner ) {
|
jens@0
|
312 |
if( [group containsObject: self] )
|
jens@0
|
313 |
return; // already traversed
|
jens@0
|
314 |
[group addObject: self];
|
jens@0
|
315 |
for( GridCell *c in self.neighbors )
|
jens@0
|
316 |
[c x_addToGroup: group liberties: liberties owner: owner];
|
jens@0
|
317 |
}
|
jens@0
|
318 |
}
|
jens@0
|
319 |
|
jens@0
|
320 |
|
jens@0
|
321 |
- (NSSet*) getGroup: (int*)outLiberties
|
jens@0
|
322 |
{
|
jens@0
|
323 |
NSMutableSet *group=[NSMutableSet set], *liberties=nil;
|
jens@0
|
324 |
if( outLiberties )
|
jens@0
|
325 |
liberties = [NSMutableSet set];
|
jens@0
|
326 |
[self x_addToGroup: group liberties: liberties owner: self.bit.owner];
|
jens@0
|
327 |
if( outLiberties )
|
jens@0
|
328 |
*outLiberties = liberties.count;
|
jens@0
|
329 |
return group;
|
jens@0
|
330 |
}
|
jens@0
|
331 |
|
jens@0
|
332 |
|
jens@0
|
333 |
#pragma mark -
|
jens@0
|
334 |
#pragma mark DRAG-AND-DROP:
|
jens@0
|
335 |
|
jens@0
|
336 |
|
jens@1
|
337 |
#if ! TARGET_OS_ASPEN
|
jens@1
|
338 |
|
jens@0
|
339 |
// An image from another app can be dragged onto a Dispenser to change the Piece's appearance.
|
jens@0
|
340 |
|
jens@0
|
341 |
|
jens@0
|
342 |
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
jens@0
|
343 |
{
|
jens@0
|
344 |
NSPasteboard *pb = [sender draggingPasteboard];
|
jens@0
|
345 |
if( [NSImage canInitWithPasteboard: pb] )
|
jens@0
|
346 |
return NSDragOperationCopy;
|
jens@0
|
347 |
else
|
jens@0
|
348 |
return NSDragOperationNone;
|
jens@0
|
349 |
}
|
jens@0
|
350 |
|
jens@0
|
351 |
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
jens@0
|
352 |
{
|
jens@0
|
353 |
CGImageRef image = GetCGImageFromPasteboard([sender draggingPasteboard]);
|
jens@0
|
354 |
if( image ) {
|
jens@0
|
355 |
CGColorRef pattern = CreatePatternColor(image);
|
jens@0
|
356 |
_grid.cellColor = pattern;
|
jens@0
|
357 |
CGColorRelease(pattern);
|
jens@0
|
358 |
[_grid setNeedsDisplay];
|
jens@0
|
359 |
return YES;
|
jens@0
|
360 |
} else
|
jens@0
|
361 |
return NO;
|
jens@0
|
362 |
}
|
jens@0
|
363 |
|
jens@1
|
364 |
#endif
|
jens@0
|
365 |
|
jens@0
|
366 |
@end
|
jens@0
|
367 |
|
jens@0
|
368 |
|
jens@0
|
369 |
|
jens@0
|
370 |
|
jens@0
|
371 |
#pragma mark -
|
jens@0
|
372 |
|
jens@0
|
373 |
@implementation RectGrid
|
jens@0
|
374 |
|
jens@0
|
375 |
|
jens@0
|
376 |
- (id) initWithRows: (unsigned)nRows columns: (unsigned)nColumns
|
jens@0
|
377 |
spacing: (CGSize)spacing
|
jens@0
|
378 |
position: (CGPoint)pos
|
jens@0
|
379 |
{
|
jens@0
|
380 |
self = [super initWithRows: nRows columns: nColumns spacing: spacing position: pos];
|
jens@0
|
381 |
if( self ) {
|
jens@0
|
382 |
_cellClass = [Square class];
|
jens@0
|
383 |
}
|
jens@0
|
384 |
return self;
|
jens@0
|
385 |
}
|
jens@0
|
386 |
|
jens@0
|
387 |
|
jens@0
|
388 |
- (CGColorRef) altCellColor {return _altCellColor;}
|
jens@0
|
389 |
- (void) setAltCellColor: (CGColorRef)altCellColor {setcolor(&_altCellColor,altCellColor);}
|
jens@0
|
390 |
|
jens@0
|
391 |
|
jens@0
|
392 |
@end
|
jens@0
|
393 |
|
jens@0
|
394 |
|
jens@0
|
395 |
|
jens@0
|
396 |
#pragma mark -
|
jens@0
|
397 |
|
jens@0
|
398 |
@implementation Square
|
jens@0
|
399 |
|
jens@0
|
400 |
|
jens@0
|
401 |
- (void) drawInParentContext: (CGContextRef)ctx fill: (BOOL)fill
|
jens@0
|
402 |
{
|
jens@0
|
403 |
if( fill ) {
|
jens@0
|
404 |
CGColorRef c = ((RectGrid*)_grid).altCellColor;
|
jens@0
|
405 |
if( c ) {
|
jens@0
|
406 |
if( ! ((_row+_column) & 1) )
|
jens@0
|
407 |
c = _grid.cellColor;
|
jens@0
|
408 |
CGContextSetFillColorWithColor(ctx, c);
|
jens@0
|
409 |
}
|
jens@0
|
410 |
}
|
jens@0
|
411 |
[super drawInParentContext: ctx fill: fill];
|
jens@0
|
412 |
}
|
jens@0
|
413 |
|
jens@0
|
414 |
|
jens@0
|
415 |
- (void) setHighlighted: (BOOL)highlighted
|
jens@0
|
416 |
{
|
jens@0
|
417 |
[super setHighlighted: highlighted];
|
jens@3
|
418 |
self.cornerRadius = self.bounds.size.width/2.0;
|
jens@0
|
419 |
self.borderWidth = (highlighted ?6 :0);
|
jens@0
|
420 |
}
|
jens@0
|
421 |
|
jens@0
|
422 |
|
jens@0
|
423 |
- (Square*) nw {return (Square*)[_grid cellAtRow: _row+1 column: _column-1];}
|
jens@0
|
424 |
- (Square*) n {return (Square*)[_grid cellAtRow: _row+1 column: _column ];}
|
jens@0
|
425 |
- (Square*) ne {return (Square*)[_grid cellAtRow: _row+1 column: _column+1];}
|
jens@0
|
426 |
- (Square*) e {return (Square*)[_grid cellAtRow: _row column: _column+1];}
|
jens@0
|
427 |
- (Square*) se {return (Square*)[_grid cellAtRow: _row-1 column: _column+1];}
|
jens@0
|
428 |
- (Square*) s {return (Square*)[_grid cellAtRow: _row-1 column: _column ];}
|
jens@0
|
429 |
- (Square*) sw {return (Square*)[_grid cellAtRow: _row-1 column: _column-1];}
|
jens@0
|
430 |
- (Square*) w {return (Square*)[_grid cellAtRow: _row column: _column-1];}
|
jens@0
|
431 |
|
jens@0
|
432 |
// Directions relative to the current player:
|
jens@0
|
433 |
- (Square*) fl {return self.fwdIsN ?self.nw :self.se;}
|
jens@0
|
434 |
- (Square*) f {return self.fwdIsN ?self.n :self.s;}
|
jens@0
|
435 |
- (Square*) fr {return self.fwdIsN ?self.ne :self.sw;}
|
jens@0
|
436 |
- (Square*) r {return self.fwdIsN ?self.e :self.w;}
|
jens@0
|
437 |
- (Square*) br {return self.fwdIsN ?self.se :self.nw;}
|
jens@0
|
438 |
- (Square*) b {return self.fwdIsN ?self.s :self.n;}
|
jens@0
|
439 |
- (Square*) bl {return self.fwdIsN ?self.sw :self.ne;}
|
jens@0
|
440 |
- (Square*) l {return self.fwdIsN ?self.w :self.e;}
|
jens@0
|
441 |
|
jens@0
|
442 |
|
jens@1
|
443 |
#if ! TARGET_OS_ASPEN
|
jens@1
|
444 |
|
jens@0
|
445 |
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
jens@0
|
446 |
{
|
jens@0
|
447 |
CGImageRef image = GetCGImageFromPasteboard([sender draggingPasteboard]);
|
jens@0
|
448 |
if( image ) {
|
jens@0
|
449 |
CGColorRef color = CreatePatternColor(image);
|
jens@0
|
450 |
RectGrid *rectGrid = (RectGrid*)_grid;
|
jens@0
|
451 |
if( rectGrid.altCellColor && ((_row+_column) & 1) )
|
jens@0
|
452 |
rectGrid.altCellColor = color;
|
jens@0
|
453 |
else
|
jens@0
|
454 |
rectGrid.cellColor = color;
|
jens@0
|
455 |
CGColorRelease(color);
|
jens@0
|
456 |
[rectGrid setNeedsDisplay];
|
jens@0
|
457 |
return YES;
|
jens@0
|
458 |
} else
|
jens@0
|
459 |
return NO;
|
jens@0
|
460 |
}
|
jens@0
|
461 |
|
jens@1
|
462 |
#endif
|
jens@1
|
463 |
|
jens@0
|
464 |
@end
|
jens@0
|
465 |
|
jens@0
|
466 |
|
jens@0
|
467 |
|
jens@0
|
468 |
#pragma mark -
|
jens@0
|
469 |
|
jens@0
|
470 |
@implementation GoSquare
|
jens@0
|
471 |
|
jens@0
|
472 |
@synthesize dotted=_dotted;
|
jens@0
|
473 |
|
jens@0
|
474 |
- (void) drawInParentContext: (CGContextRef)ctx fill: (BOOL)fill
|
jens@0
|
475 |
{
|
jens@0
|
476 |
if( fill )
|
jens@0
|
477 |
[super drawInParentContext: ctx fill: fill];
|
jens@0
|
478 |
else {
|
jens@0
|
479 |
CGRect frame = self.frame;
|
jens@0
|
480 |
const CGFloat midx=floor(CGRectGetMidX(frame))+0.5,
|
jens@0
|
481 |
midy=floor(CGRectGetMidY(frame))+0.5;
|
jens@0
|
482 |
CGPoint p[4] = {{CGRectGetMinX(frame),midy},
|
jens@0
|
483 |
{CGRectGetMaxX(frame),midy},
|
jens@0
|
484 |
{midx,CGRectGetMinY(frame)},
|
jens@0
|
485 |
{midx,CGRectGetMaxY(frame)}};
|
jens@0
|
486 |
if( ! self.s ) p[2].y = midy;
|
jens@0
|
487 |
if( ! self.n ) p[3].y = midy;
|
jens@0
|
488 |
if( ! self.w ) p[0].x = midx;
|
jens@0
|
489 |
if( ! self.e ) p[1].x = midx;
|
jens@0
|
490 |
CGContextStrokeLineSegments(ctx, p, 4);
|
jens@0
|
491 |
|
jens@0
|
492 |
if( _dotted ) {
|
jens@0
|
493 |
CGContextSetFillColorWithColor(ctx,_grid.lineColor);
|
jens@0
|
494 |
CGRect dot = CGRectMake(midx-2.5, midy-2.5, 5, 5);
|
jens@0
|
495 |
CGContextFillEllipseInRect(ctx, dot);
|
jens@0
|
496 |
}
|
jens@0
|
497 |
}
|
jens@0
|
498 |
}
|
jens@0
|
499 |
|
jens@1
|
500 |
|
jens@0
|
501 |
@end
|