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.
jens@0
     1
/*  This code is based on Apple's "GeekGameBoard" sample code, version 1.0.
jens@0
     2
    http://developer.apple.com/samplecode/GeekGameBoard/
jens@0
     3
    Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved.
jens@0
     4
jens@0
     5
    Redistribution and use in source and binary forms, with or without modification, are permitted
jens@0
     6
    provided that the following conditions are met:
jens@0
     7
jens@0
     8
    * Redistributions of source code must retain the above copyright notice, this list of conditions
jens@0
     9
      and the following disclaimer.
jens@0
    10
    * Redistributions in binary form must reproduce the above copyright notice, this list of
jens@0
    11
      conditions and the following disclaimer in the documentation and/or other materials provided
jens@0
    12
      with the distribution.
jens@0
    13
jens@0
    14
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
jens@0
    15
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
jens@0
    16
    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
jens@0
    17
    BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
jens@0
    18
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
jens@0
    19
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
jens@0
    20
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
jens@0
    21
    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
jens@0
    22
*/
jens@0
    23
#import "Dispenser.h"
jens@0
    24
#import "Piece.h"
jens@0
    25
#import "QuartzUtils.h"
jens@0
    26
#import "GGBUtils.h"
jens@0
    27
jens@0
    28
jens@0
    29
@implementation Dispenser
jens@0
    30
jens@0
    31
jens@0
    32
- (id) initWithPrototype: (Bit*)prototype quantity: (unsigned)quantity frame: (CGRect)frame
jens@0
    33
{
jens@0
    34
    self = [super init];
jens@0
    35
    if (self != nil) {
jens@0
    36
        self.backgroundColor = kTranslucentLightGrayColor;
jens@0
    37
        self.borderColor = kTranslucentGrayColor;
jens@0
    38
        self.borderWidth = 3;
jens@0
    39
        self.cornerRadius = 16;
jens@0
    40
        self.zPosition = kBoardZ;
jens@0
    41
        self.masksToBounds = YES;
jens@0
    42
        self.frame = frame;
jens@0
    43
        self.prototype = prototype;
jens@0
    44
        self.quantity = quantity;
jens@0
    45
    }
jens@0
    46
    return self;
jens@0
    47
}
jens@0
    48
jens@0
    49
jens@0
    50
- (void) dealloc
jens@0
    51
{
jens@0
    52
    [_prototype release];
jens@0
    53
    [super dealloc];
jens@0
    54
}
jens@0
    55
jens@0
    56
jens@29
    57
- (Bit*) bit
jens@29
    58
{
jens@29
    59
    return _bit;
jens@29
    60
}
jens@29
    61
jens@29
    62
- (void) setBit: (Bit*)bit
jens@29
    63
{
jens@29
    64
    setObj(&_bit, bit);
jens@29
    65
}
jens@0
    66
jens@0
    67
jens@0
    68
- (Bit*) createBit
jens@0
    69
{
jens@0
    70
    if( _prototype ) {
jens@0
    71
        Bit *bit = [_prototype copy];
jens@0
    72
        CGRect bounds = self.bounds;
jens@0
    73
        bit.position = GetCGRectCenter(bounds);
jens@0
    74
        return [bit autorelease];
jens@0
    75
    } else
jens@0
    76
        return nil;
jens@0
    77
}
jens@0
    78
jens@0
    79
- (void) x_regenerateCurrentBit
jens@0
    80
{
jens@0
    81
    NSAssert(_bit==nil,@"Already have a currentBit");
jens@0
    82
jens@9
    83
    BeginDisableAnimations();
jens@0
    84
    self.bit = [self createBit];
jens@0
    85
    CGPoint pos = _bit.position;
jens@0
    86
    _bit.position = CGPointMake(pos.x, pos.y+70);
jens@0
    87
    [self addSublayer: _bit];
jens@9
    88
    EndDisableAnimations();
jens@0
    89
    
jens@0
    90
    _bit.position = pos;
jens@0
    91
}
jens@0
    92
jens@0
    93
jens@0
    94
- (Bit*) prototype
jens@0
    95
{
jens@0
    96
    return _prototype;
jens@0
    97
}
jens@0
    98
jens@0
    99
- (void) setPrototype: (Bit*)prototype
jens@0
   100
{
jens@0
   101
    setObj(&_prototype, prototype);
jens@0
   102
    if( _bit ) {
jens@0
   103
        [_bit removeFromSuperlayer];
jens@0
   104
        self.bit = nil;
jens@0
   105
        if( prototype )
jens@0
   106
            [self x_regenerateCurrentBit];
jens@0
   107
    }
jens@0
   108
}
jens@0
   109
jens@0
   110
jens@0
   111
- (unsigned) quantity
jens@0
   112
{
jens@0
   113
    return _quantity;
jens@0
   114
}
jens@0
   115
jens@0
   116
- (void) setQuantity: (unsigned)quantity
jens@0
   117
{
jens@0
   118
    _quantity = quantity;
jens@0
   119
    if( quantity > 0 && !_bit )
jens@0
   120
        [self x_regenerateCurrentBit];
jens@0
   121
    else if( quantity==0 && _bit ) {
jens@0
   122
        [_bit removeFromSuperlayer];
jens@0
   123
        self.bit = nil;
jens@0
   124
    }
jens@0
   125
}
jens@0
   126
jens@0
   127
jens@0
   128
#pragma mark -
jens@0
   129
#pragma mark DRAGGING BITS:
jens@0
   130
jens@0
   131
jens@0
   132
- (Bit*) canDragBit: (Bit*)bit
jens@0
   133
{
jens@0
   134
    bit = [super canDragBit: bit];
jens@0
   135
    if( bit==_bit ) {
jens@0
   136
        [[bit retain] autorelease];
jens@0
   137
        self.bit = nil;
jens@0
   138
    }
jens@0
   139
    return bit;
jens@0
   140
}
jens@0
   141
jens@0
   142
- (void) cancelDragBit: (Bit*)bit
jens@0
   143
{
jens@0
   144
    if( ! _bit )
jens@0
   145
        self.bit = bit;
jens@0
   146
    else
jens@0
   147
        [bit removeFromSuperlayer];
jens@0
   148
}
jens@0
   149
jens@0
   150
- (void) draggedBit: (Bit*)bit to: (id<BitHolder>)dst
jens@0
   151
{
jens@0
   152
    if( --_quantity > 0 )
jens@0
   153
        [self performSelector: @selector(x_regenerateCurrentBit) withObject: nil afterDelay: 0.0];
jens@0
   154
}
jens@0
   155
jens@0
   156
- (BOOL) canDropBit: (Bit*)bit atPoint: (CGPoint)point  
jens@0
   157
{
jens@0
   158
    return [bit isEqual: _bit];
jens@0
   159
}
jens@0
   160
jens@0
   161
- (BOOL) dropBit: (Bit*)bit atPoint: (CGPoint)point
jens@0
   162
{
jens@0
   163
    [bit removeFromSuperlayer];
jens@0
   164
    return YES;
jens@0
   165
}
jens@0
   166
jens@0
   167
jens@0
   168
#pragma mark -
jens@0
   169
#pragma mark DRAG-AND-DROP:
jens@0
   170
jens@0
   171
jens@8
   172
#if ! TARGET_OS_IPHONE
jens@1
   173
jens@0
   174
// An image from another app can be dragged onto a Dispenser to change the Piece's appearance.
jens@0
   175
jens@0
   176
jens@0
   177
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
jens@0
   178
{
jens@0
   179
    if( ! [_prototype isKindOfClass: [Piece class]] )
jens@0
   180
        return NSDragOperationNone;
jens@0
   181
    NSPasteboard *pb = [sender draggingPasteboard];
jens@0
   182
    if( [NSImage canInitWithPasteboard: pb] )
jens@0
   183
        return NSDragOperationCopy;
jens@0
   184
    else
jens@0
   185
        return NSDragOperationNone;
jens@0
   186
}
jens@0
   187
jens@0
   188
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
jens@0
   189
{
jens@0
   190
    if( ! [_prototype isKindOfClass: [Piece class]] )
jens@0
   191
        return NO;
jens@11
   192
    CGImageRef image = GetCGImageFromPasteboard([sender draggingPasteboard],sender);
jens@0
   193
    if( image ) {
jens@0
   194
        [(Piece*)_prototype setImage: image];
jens@0
   195
        self.prototype = _prototype; // recreates _bit
jens@0
   196
        return YES;
jens@0
   197
    } else
jens@0
   198
        return NO;
jens@0
   199
}
jens@0
   200
jens@0
   201
jens@1
   202
#endif
jens@1
   203
jens@0
   204
@end