Don't load Checkers sound files till a game is displayed on a board; this speeds up launch.
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 "GGBTextLayer.h"
25 #import "QuartzUtils.h"
31 static CGSize sCardSize = {100,150};
33 static CATransform3D kFaceUpTransform, kFaceDownTransform;
37 if( self==[Card class] ) {
38 kFaceUpTransform = kFaceDownTransform = CATransform3DIdentity;
39 // Construct a 180-degree rotation matrix:
40 kFaceDownTransform.m11 = kFaceDownTransform.m33 = -1;
41 // The more obvious way to create kFaceDownTransform would be to call
42 // CATransform3DMakeRotation(pi,0,1,0), but due to round-off errors, that transform
43 // will have non-zero values in some other places, making it appear to CA as a true
44 // 3D transform; this will then cause unexpected clipping behaviors when used.
49 + (NSRange) serialNumberRange;
51 NSAssert1(NO,@"%@ forgot to override +serialNumberRange",self);
52 return NSMakeRange(0,0);
56 + (CGSize) cardSize {return sCardSize;}
57 + (void) setCardSize: (CGSize)size {sCardSize = size;}
60 - (id) initWithSerialNumber: (int)serial position: (CGPoint)pos
64 _serialNumber = serial;
65 self.bounds = CGRectMake(0,0,sCardSize.width,sCardSize.height);
67 self.edgeAntialiasingMask = 0;
68 _back = [self createBack];
69 [self addSublayer: _back];
70 _front = [self createFront];
71 _front.transform = kFaceDownTransform;
72 [self addSublayer: _front];
78 - (id) copyWithZone: (NSZone*)zone
80 Card *clone = [super copyWithZone: zone];
81 clone->_serialNumber = _serialNumber;
86 - (NSString*) description
88 return [NSString stringWithFormat: @"%@[#%i]",self.class,_serialNumber];
92 @synthesize serialNumber=_serialNumber;
100 - (void) setFaceUp: (BOOL)up
102 if( up != _faceUp ) {
103 // The Card has separate sub-layers for its front and back. At any time, one of them
104 // is hidden, by having a 180 degree rotation about the Y axis.
105 // To flip the card, both front and back layers are flipped over.
107 xform = up ?kFaceUpTransform :kFaceDownTransform;
108 _front.transform = xform;
110 xform = up ?kFaceDownTransform :kFaceUpTransform;
111 _back.transform = xform;
117 - (GGBLayer*) createFront
119 GGBLayer *front = [[GGBLayer alloc] init];
120 front.bounds = CGRectMake(0,0,sCardSize.width,sCardSize.height);
121 front.position = CGPointMake(sCardSize.width/2,sCardSize.height/2);
122 front.edgeAntialiasingMask = 0;
123 front.backgroundColor = kWhiteColor;
124 front.cornerRadius = 8 * (sCardSize.height/150);
125 front.borderWidth = 1;
126 front.borderColor = CreateGray(0.7, 1.0);
127 front.doubleSided = NO; // this makes the layer invisible when it's flipped
128 return [front autorelease];
132 - (GGBLayer*) createBack
134 CGSize size = self.bounds.size;
135 GGBLayer *back = [[GGBLayer alloc] init];
136 back.bounds = CGRectMake(0,0,size.width,size.height);
137 back.position = CGPointMake(sCardSize.width/2,sCardSize.height/2);
139 back.backgroundColor = CreateRGB(0.0,0.5,0.5, 1.0);
141 back.contents = (id) GetCGImageNamed(@"/Library/Desktop Pictures/Classic Aqua Blue.jpg");
143 back.contentsGravity = kCAGravityResize;
144 back.masksToBounds = YES;
145 back.borderWidth = 4 * (sCardSize.height/150);
146 back.borderColor = kWhiteColor;
147 back.cornerRadius = 8 * (sCardSize.height/150);
148 back.edgeAntialiasingMask = 0;
149 back.doubleSided = NO; // this makes the layer invisible when it's flipped
152 // On iPhone, only Hiragana Kaku includes the coveted snowman glyph... who knows why?
153 UIFont *font = [UIFont fontWithName: @"HiraKakuProN-W3" size: 1*size.width];
155 NSFont *font = [NSFont systemFontOfSize: 1*size.width];
157 GGBTextLayer *label = [GGBTextLayer textLayerInSuperlayer: back
158 withText: @"\u2603" // Unicode snowman character
160 alignment: kCALayerWidthSizable|kCALayerHeightSizable];
161 label.foregroundColor = CreateGray(1.0,0.5);
162 return [back autorelease];
167 #pragma mark DRAG-AND-DROP:
170 #if ! TARGET_OS_IPHONE
172 // An image from another app can be dragged onto a Card to change its background. */
175 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
177 NSPasteboard *pb = [sender draggingPasteboard];
178 if( [NSImage canInitWithPasteboard: pb] )
179 return NSDragOperationCopy;
181 return NSDragOperationNone;
184 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
186 CGImageRef image = GetCGImageFromPasteboard([sender draggingPasteboard],sender);
188 GGBLayer *face = _faceUp ?_front :_back;
189 face.contents = (id) image;
190 face.contentsGravity = kCAGravityResizeAspectFill;
191 face.masksToBounds = YES;