jens@0: /* This code is based on Apple's "GeekGameBoard" sample code, version 1.0. jens@0: http://developer.apple.com/samplecode/GeekGameBoard/ jens@0: Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved. jens@0: jens@0: Redistribution and use in source and binary forms, with or without modification, are permitted jens@0: provided that the following conditions are met: jens@0: jens@0: * Redistributions of source code must retain the above copyright notice, this list of conditions jens@0: and the following disclaimer. jens@0: * Redistributions in binary form must reproduce the above copyright notice, this list of jens@0: conditions and the following disclaimer in the documentation and/or other materials provided jens@0: with the distribution. jens@0: jens@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR jens@0: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND jens@0: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI- jens@0: BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES jens@0: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR jens@0: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN jens@0: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF jens@0: THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jens@0: */ jens@0: #import "Dispenser.h" jens@0: #import "Piece.h" jens@0: #import "QuartzUtils.h" jens@0: #import "GGBUtils.h" jens@0: jens@0: jens@0: @implementation Dispenser jens@0: jens@0: jens@0: - (id) initWithPrototype: (Bit*)prototype quantity: (unsigned)quantity frame: (CGRect)frame jens@0: { jens@0: self = [super init]; jens@0: if (self != nil) { jens@0: self.backgroundColor = kTranslucentLightGrayColor; jens@0: self.borderColor = kTranslucentGrayColor; jens@0: self.borderWidth = 3; jens@0: self.cornerRadius = 16; jens@0: self.zPosition = kBoardZ; jens@0: self.masksToBounds = YES; jens@0: self.frame = frame; jens@0: self.prototype = prototype; jens@0: self.quantity = quantity; jens@0: } jens@0: return self; jens@0: } jens@0: jens@0: jens@0: - (void) dealloc jens@0: { jens@0: [_prototype release]; jens@0: [super dealloc]; jens@0: } jens@0: jens@0: jens@29: - (Bit*) bit jens@29: { jens@29: return _bit; jens@29: } jens@29: jens@29: - (void) setBit: (Bit*)bit jens@29: { jens@29: setObj(&_bit, bit); jens@29: } jens@0: jens@0: jens@0: - (Bit*) createBit jens@0: { jens@0: if( _prototype ) { jens@0: Bit *bit = [_prototype copy]; jens@0: CGRect bounds = self.bounds; jens@0: bit.position = GetCGRectCenter(bounds); jens@0: return [bit autorelease]; jens@0: } else jens@0: return nil; jens@0: } jens@0: jens@0: - (void) x_regenerateCurrentBit jens@0: { jens@0: NSAssert(_bit==nil,@"Already have a currentBit"); jens@0: jens@9: BeginDisableAnimations(); jens@0: self.bit = [self createBit]; jens@0: CGPoint pos = _bit.position; jens@0: _bit.position = CGPointMake(pos.x, pos.y+70); jens@0: [self addSublayer: _bit]; jens@9: EndDisableAnimations(); jens@0: jens@0: _bit.position = pos; jens@0: } jens@0: jens@0: jens@0: - (Bit*) prototype jens@0: { jens@0: return _prototype; jens@0: } jens@0: jens@0: - (void) setPrototype: (Bit*)prototype jens@0: { jens@0: setObj(&_prototype, prototype); jens@0: if( _bit ) { jens@0: [_bit removeFromSuperlayer]; jens@0: self.bit = nil; jens@0: if( prototype ) jens@0: [self x_regenerateCurrentBit]; jens@0: } jens@0: } jens@0: jens@0: jens@0: - (unsigned) quantity jens@0: { jens@0: return _quantity; jens@0: } jens@0: jens@0: - (void) setQuantity: (unsigned)quantity jens@0: { jens@0: _quantity = quantity; jens@0: if( quantity > 0 && !_bit ) jens@0: [self x_regenerateCurrentBit]; jens@0: else if( quantity==0 && _bit ) { jens@0: [_bit removeFromSuperlayer]; jens@0: self.bit = nil; jens@0: } jens@0: } jens@0: jens@0: jens@0: #pragma mark - jens@0: #pragma mark DRAGGING BITS: jens@0: jens@0: jens@0: - (Bit*) canDragBit: (Bit*)bit jens@0: { jens@0: bit = [super canDragBit: bit]; jens@0: if( bit==_bit ) { jens@0: [[bit retain] autorelease]; jens@0: self.bit = nil; jens@0: } jens@0: return bit; jens@0: } jens@0: jens@0: - (void) cancelDragBit: (Bit*)bit jens@0: { jens@0: if( ! _bit ) jens@0: self.bit = bit; jens@0: else jens@0: [bit removeFromSuperlayer]; jens@0: } jens@0: jens@0: - (void) draggedBit: (Bit*)bit to: (id)dst jens@0: { jens@0: if( --_quantity > 0 ) jens@0: [self performSelector: @selector(x_regenerateCurrentBit) withObject: nil afterDelay: 0.0]; jens@0: } jens@0: jens@0: - (BOOL) canDropBit: (Bit*)bit atPoint: (CGPoint)point jens@0: { jens@0: return [bit isEqual: _bit]; jens@0: } jens@0: jens@0: - (BOOL) dropBit: (Bit*)bit atPoint: (CGPoint)point jens@0: { jens@0: [bit removeFromSuperlayer]; jens@0: return YES; jens@0: } jens@0: jens@0: jens@0: #pragma mark - jens@0: #pragma mark DRAG-AND-DROP: jens@0: jens@0: jens@8: #if ! TARGET_OS_IPHONE jens@1: jens@0: // An image from another app can be dragged onto a Dispenser to change the Piece's appearance. jens@0: jens@0: jens@0: - (NSDragOperation)draggingEntered:(id )sender jens@0: { jens@0: if( ! [_prototype isKindOfClass: [Piece class]] ) jens@0: return NSDragOperationNone; jens@0: NSPasteboard *pb = [sender draggingPasteboard]; jens@0: if( [NSImage canInitWithPasteboard: pb] ) jens@0: return NSDragOperationCopy; jens@0: else jens@0: return NSDragOperationNone; jens@0: } jens@0: jens@0: - (BOOL)performDragOperation:(id )sender jens@0: { jens@0: if( ! [_prototype isKindOfClass: [Piece class]] ) jens@0: return NO; jens@11: CGImageRef image = GetCGImageFromPasteboard([sender draggingPasteboard],sender); jens@0: if( image ) { jens@0: [(Piece*)_prototype setImage: image]; jens@0: self.prototype = _prototype; // recreates _bit jens@0: return YES; jens@0: } else jens@0: return NO; jens@0: } jens@0: jens@0: jens@1: #endif jens@1: jens@0: @end