* Fixed scaling of king pieces when the board's state is set.
* Added IBOutlets for tilting the BoardView.
1 /* This code is based on Apple's "GeekGameBoard" sample code, version 1.0.
2 http://developer.apple.com/samplecode/GeekGameBoard/
3 Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved.
5 Redistribution and use in source and binary forms, with or without modification, are permitted
6 provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright notice, this list of conditions
9 and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice, this list of
11 conditions and the following disclaimer in the documentation and/or other materials provided
12 with the distribution.
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
17 BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
19 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
21 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 #import "QuartzUtils.h"
30 - (id) initWithStartPos: (CGPoint)startPos spacing: (CGSize)spacing
31 wrapInterval: (int)wrapInterval wrapSpacing: (CGSize)wrapSpacing
37 _wrapInterval = wrapInterval;
38 _wrapSpacing = wrapSpacing;
39 self.cornerRadius = 8;
40 self.backgroundColor = kAlmostInvisibleWhiteColor;
41 self.borderColor = kHighlightColor;
42 _bits = [[NSMutableArray alloc] init];
47 - (id) initWithStartPos: (CGPoint)startPos spacing: (CGSize)spacing;
49 return [self initWithStartPos: startPos spacing: spacing
50 wrapInterval: INT_MAX wrapSpacing: CGSizeZero];
61 @synthesize spacing=_spacing, wrapSpacing=_wrapSpacing, startPos=_startPos, wrapInterval=_wrapInterval;
62 @synthesize dragAsStacks=_dragAsStacks;
63 @synthesize bits=_bits;
66 - (NSUInteger) numberOfBits
71 - (void) setNumberOfBits: (NSUInteger)n
73 NSAssert2(n<=_bits.count,@"Cannot increase numberOfBits (from %u to %u)", _bits.count,n);
74 while( _bits.count > n )
75 [self removeBit: self.topBit];
80 return [_bits lastObject];
87 for( GGBLayer *layer in self.sublayers )
88 printf("%s @z=%g ", [[layer description] UTF8String],layer.zPosition);
93 - (void) x_repositionBit: (Bit*)bit forIndex: (int)i
95 bit.position = CGPointMake(_startPos.x + _spacing.width *(i%_wrapInterval) + _wrapSpacing.width *(i/_wrapInterval),
96 _startPos.y + _spacing.height*(i%_wrapInterval) + _wrapSpacing.height*(i/_wrapInterval));
99 - (void) addBit: (Bit*)bit
101 if( [bit isKindOfClass: [DraggedStack class]] ) {
102 for( Bit *subBit in [(DraggedStack*)bit bits] )
103 [self addBit: subBit];
106 [_bits addObject: bit];
107 ChangeSuperlayer(bit, self, n);
108 [self x_repositionBit: bit forIndex: n];
113 - (void) removeBit: (Bit*)bit
115 NSUInteger index = [_bits indexOfObjectIdenticalTo: bit];
116 if( index != NSNotFound ) {
117 [bit removeFromSuperlayer];
118 [_bits removeObjectAtIndex: index];
123 - (void) setHighlighted: (BOOL)highlighted
125 [super setHighlighted: highlighted];
126 self.borderWidth = (highlighted ?6 :0);
130 - (Bit*) canDragBit: (Bit*)bit
132 NSInteger index = [_bits indexOfObjectIdenticalTo: bit];
133 if( index==NSNotFound )
135 if( _dragAsStacks && index < _bits.count-1 ) {
136 // Move bit and those above it into a temporary DraggedStack:
137 NSRange r = NSMakeRange(index,_bits.count-index);
138 NSArray *bitsToDrag = [_bits subarrayWithRange: r];
139 [_bits removeObjectsInRange: r];
140 DraggedStack *stack = [[DraggedStack alloc] initWithBits: bitsToDrag];
141 [self addSublayer: stack];
143 stack.anchorPoint = CGPointMake( bit.position.x/stack.bounds.size.width,
144 bit.position.y/stack.bounds.size.height );
145 stack.position = bit.position;
149 [_bits removeObjectIdenticalTo: bit];
150 return [bit autorelease];
155 - (void) cancelDragBit: (Bit*)bit
158 if( [bit isKindOfClass: [DraggedStack class]] ) {
159 [bit removeFromSuperlayer];
164 - (void) draggedBit: (Bit*)bit to: (id<BitHolder>)dst
167 for( Bit *bit in self.sublayers )
168 [self x_repositionBit: bit forIndex: i++];
172 - (BOOL) dropBit: (Bit*)bit atPoint: (CGPoint)point
183 @implementation DraggedStack
186 - (id) initWithBits: (NSArray*)bits
190 CGRect bounds = CGRectZero;
191 for( Bit *bit in bits ) {
192 bounds = CGRectUnion(bounds, bit.frame);
193 [self addSublayer: bit];
195 self.bounds = bounds;
196 self.anchorPoint = CGPointZero;
197 self.position = CGPointZero;
204 return [self.sublayers.copy autorelease];