Source/Dispenser.m
author Jens Alfke <jens@mooseyard.com>
Sun Feb 06 16:31:03 2011 -0800 (2011-02-06)
changeset 29 0b1c315ffc64
parent 11 436cbdf56810
permissions -rw-r--r--
Minor compiler-compatibility fixes.
     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.
     4 
     5     Redistribution and use in source and binary forms, with or without modification, are permitted
     6     provided that the following conditions are met:
     7 
     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.
    13 
    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.
    22 */
    23 #import "Dispenser.h"
    24 #import "Piece.h"
    25 #import "QuartzUtils.h"
    26 #import "GGBUtils.h"
    27 
    28 
    29 @implementation Dispenser
    30 
    31 
    32 - (id) initWithPrototype: (Bit*)prototype quantity: (unsigned)quantity frame: (CGRect)frame
    33 {
    34     self = [super init];
    35     if (self != nil) {
    36         self.backgroundColor = kTranslucentLightGrayColor;
    37         self.borderColor = kTranslucentGrayColor;
    38         self.borderWidth = 3;
    39         self.cornerRadius = 16;
    40         self.zPosition = kBoardZ;
    41         self.masksToBounds = YES;
    42         self.frame = frame;
    43         self.prototype = prototype;
    44         self.quantity = quantity;
    45     }
    46     return self;
    47 }
    48 
    49 
    50 - (void) dealloc
    51 {
    52     [_prototype release];
    53     [super dealloc];
    54 }
    55 
    56 
    57 - (Bit*) bit
    58 {
    59     return _bit;
    60 }
    61 
    62 - (void) setBit: (Bit*)bit
    63 {
    64     setObj(&_bit, bit);
    65 }
    66 
    67 
    68 - (Bit*) createBit
    69 {
    70     if( _prototype ) {
    71         Bit *bit = [_prototype copy];
    72         CGRect bounds = self.bounds;
    73         bit.position = GetCGRectCenter(bounds);
    74         return [bit autorelease];
    75     } else
    76         return nil;
    77 }
    78 
    79 - (void) x_regenerateCurrentBit
    80 {
    81     NSAssert(_bit==nil,@"Already have a currentBit");
    82 
    83     BeginDisableAnimations();
    84     self.bit = [self createBit];
    85     CGPoint pos = _bit.position;
    86     _bit.position = CGPointMake(pos.x, pos.y+70);
    87     [self addSublayer: _bit];
    88     EndDisableAnimations();
    89     
    90     _bit.position = pos;
    91 }
    92 
    93 
    94 - (Bit*) prototype
    95 {
    96     return _prototype;
    97 }
    98 
    99 - (void) setPrototype: (Bit*)prototype
   100 {
   101     setObj(&_prototype, prototype);
   102     if( _bit ) {
   103         [_bit removeFromSuperlayer];
   104         self.bit = nil;
   105         if( prototype )
   106             [self x_regenerateCurrentBit];
   107     }
   108 }
   109 
   110 
   111 - (unsigned) quantity
   112 {
   113     return _quantity;
   114 }
   115 
   116 - (void) setQuantity: (unsigned)quantity
   117 {
   118     _quantity = quantity;
   119     if( quantity > 0 && !_bit )
   120         [self x_regenerateCurrentBit];
   121     else if( quantity==0 && _bit ) {
   122         [_bit removeFromSuperlayer];
   123         self.bit = nil;
   124     }
   125 }
   126 
   127 
   128 #pragma mark -
   129 #pragma mark DRAGGING BITS:
   130 
   131 
   132 - (Bit*) canDragBit: (Bit*)bit
   133 {
   134     bit = [super canDragBit: bit];
   135     if( bit==_bit ) {
   136         [[bit retain] autorelease];
   137         self.bit = nil;
   138     }
   139     return bit;
   140 }
   141 
   142 - (void) cancelDragBit: (Bit*)bit
   143 {
   144     if( ! _bit )
   145         self.bit = bit;
   146     else
   147         [bit removeFromSuperlayer];
   148 }
   149 
   150 - (void) draggedBit: (Bit*)bit to: (id<BitHolder>)dst
   151 {
   152     if( --_quantity > 0 )
   153         [self performSelector: @selector(x_regenerateCurrentBit) withObject: nil afterDelay: 0.0];
   154 }
   155 
   156 - (BOOL) canDropBit: (Bit*)bit atPoint: (CGPoint)point  
   157 {
   158     return [bit isEqual: _bit];
   159 }
   160 
   161 - (BOOL) dropBit: (Bit*)bit atPoint: (CGPoint)point
   162 {
   163     [bit removeFromSuperlayer];
   164     return YES;
   165 }
   166 
   167 
   168 #pragma mark -
   169 #pragma mark DRAG-AND-DROP:
   170 
   171 
   172 #if ! TARGET_OS_IPHONE
   173 
   174 // An image from another app can be dragged onto a Dispenser to change the Piece's appearance.
   175 
   176 
   177 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
   178 {
   179     if( ! [_prototype isKindOfClass: [Piece class]] )
   180         return NSDragOperationNone;
   181     NSPasteboard *pb = [sender draggingPasteboard];
   182     if( [NSImage canInitWithPasteboard: pb] )
   183         return NSDragOperationCopy;
   184     else
   185         return NSDragOperationNone;
   186 }
   187 
   188 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
   189 {
   190     if( ! [_prototype isKindOfClass: [Piece class]] )
   191         return NO;
   192     CGImageRef image = GetCGImageFromPasteboard([sender draggingPasteboard],sender);
   193     if( image ) {
   194         [(Piece*)_prototype setImage: image];
   195         self.prototype = _prototype; // recreates _bit
   196         return YES;
   197     } else
   198         return NO;
   199 }
   200 
   201 
   202 #endif
   203 
   204 @end