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 CATransform3D kFaceUpTransform, kFaceDownTransform;
35 if( self==[Card class] ) {
36 kFaceUpTransform = kFaceDownTransform = CATransform3DIdentity;
37 // Construct a 180-degree rotation matrix:
38 kFaceDownTransform.m11 = kFaceDownTransform.m33 = -1;
39 // The more obvious way to create kFaceDownTransform would be to call
40 // CATransform3DMakeRotation(pi,0,1,0), but due to round-off errors, that transform
41 // will have non-zero values in some other places, making it appear to CA as a true
42 // 3D transform; this will then cause unexpected clipping behaviors when used.
47 + (NSRange) serialNumberRange;
49 NSAssert1(NO,@"%@ forgot to override +serialNumberRange",self);
50 return NSMakeRange(0,0);
54 - (id) initWithSerialNumber: (int)serial position: (CGPoint)pos
58 _serialNumber = serial;
59 self.bounds = CGRectMake(0,0,kCardWidth,kCardHeight);
61 self.edgeAntialiasingMask = 0;
62 _back = [self createBack];
63 [self addSublayer: _back];
64 _front = [self createFront];
65 _front.transform = kFaceDownTransform;
66 [self addSublayer: _front];
72 - (id) copyWithZone: (NSZone*)zone
74 Card *clone = [super copyWithZone: zone];
75 clone->_serialNumber = _serialNumber;
80 - (NSString*) description
82 return [NSString stringWithFormat: @"%@[#%i]",self.class,_serialNumber];
86 @synthesize serialNumber=_serialNumber;
94 - (void) setFaceUp: (BOOL)up
97 // The Card has separate sub-layers for its front and back. At any time, one of them
98 // is hidden, by having a 180 degree rotation about the Y axis.
99 // To flip the card, both front and back layers are flipped over.
101 xform = up ?kFaceUpTransform :kFaceDownTransform;
102 _front.transform = xform;
104 xform = up ?kFaceDownTransform :kFaceUpTransform;
105 _back.transform = xform;
111 - (GGBLayer*) createFront
113 GGBLayer *front = [[GGBLayer alloc] init];
114 front.bounds = CGRectMake(0,0,kCardWidth,kCardHeight);
115 front.position = CGPointMake(kCardWidth/2,kCardHeight/2);
116 front.edgeAntialiasingMask = 0;
117 front.backgroundColor = kWhiteColor;
118 front.cornerRadius = 8;
119 front.borderWidth = 1;
120 front.borderColor = CreateGray(0.7, 1.0);
121 front.doubleSided = NO; // this makes the layer invisible when it's flipped
122 return [front autorelease];
126 - (GGBLayer*) createBack
128 CGSize size = self.bounds.size;
129 GGBLayer *back = [[GGBLayer alloc] init];
130 back.bounds = CGRectMake(0,0,size.width,size.height);
131 back.position = CGPointMake(kCardWidth/2,kCardHeight/2);
132 back.contents = (id) GetCGImageNamed(@"/Library/Desktop Pictures/Classic Aqua Blue.jpg");
133 back.contentsGravity = kCAGravityResize;
134 back.masksToBounds = YES;
135 back.borderWidth = 4;
136 back.borderColor = kWhiteColor;
137 back.cornerRadius = 8;
138 back.edgeAntialiasingMask = 0;
139 back.doubleSided = NO; // this makes the layer invisible when it's flipped
141 GGBTextLayer *label = [GGBTextLayer textLayerInSuperlayer: back
142 withText: @"\u2603" // Unicode snowman character
143 fontSize: 0.9*size.width
144 alignment: kCALayerWidthSizable|kCALayerHeightSizable];
145 label.foregroundColor = CreateGray(1.0,0.5);
146 return [back autorelease];
151 #pragma mark DRAG-AND-DROP:
154 #if ! TARGET_OS_ASPEN
156 // An image from another app can be dragged onto a Card to change its background. */
159 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
161 NSPasteboard *pb = [sender draggingPasteboard];
162 if( [NSImage canInitWithPasteboard: pb] )
163 return NSDragOperationCopy;
165 return NSDragOperationNone;
168 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
170 CGImageRef image = GetCGImageFromPasteboard([sender draggingPasteboard]);
172 GGBLayer *face = _faceUp ?_front :_back;
173 face.contents = (id) image;
174 face.contentsGravity = kCAGravityResizeAspectFill;
175 face.masksToBounds = YES;