CardSet Release 2.1
Modified by Mark Trombino for use with NEXTVegas.

CardPileView 

Inherits From:	View : Responder : Object

Conforms To:	NXDraggingSource (Informal)
NXDraggingDestination

Declared In:	CardPileView.h

Class Description

Instances of this class provide a visual representation of a pile of cards.  CardPileView uses CardPile as the underlying representation, but adds a visual aspect and user interaction.  Users can click on CardPileViews and drag cards from one view to another.  The decisions on when this is allowed and what happens as a result are left to the CardPileView's delegate.

Dragging cards between applications is disabled by default.  It can be enabled by subclassing and overriding draggingSourceOperationMaskForLocal:. 

Notifying the CardPileView Object's Delegate

The logic of a card game is primarily implemented through the delegate mechanism.  The delegate has the option of implementing the following methods:

clickedCard:in:
doubleClickedCard:in:
draggedPile:from:
canAcceptPile:from:in:
acceptPile:in:
removedPile:from:
getOffset::

Knowing the sequence in which these delegate messages are sent is critical in using the CardSet objects to create card games.  If there is no delegate (or the delegate does not implement the above methods) the cards on a pile may not be dragged, flipped, or have cards dropped on them.

When the user single clicks on a CardPileView, the message clickedCard:aCard in:aCardPileView is sent to the delegate.  Note that the parameter aCard will be nil if the pile was empty, or if the user clicked in an area of the pile where there is no Card displayed.  This message is sent even if the user keeps holding down the mouse button (ie. dragging) after clicking.

If the user holds down the mouse button, and is pointing at a Card, the delegate receives the message draggedPile:aCardPile from:aCardPileView.  aCardPile is a temporary pile containing the Card that the user clicked on.  The delegate may add additional cards to this pile, if desired.  This would typically be done in games where the user can click on a card part-way down a deck, and drag that card and all the cards above it.  The delegate is responsible for adding the cards above the clicked card to aCardPile.

If draggedPile:from: returns YES, CardPileView performs the dragging animation with the cards on the temporary CardPile.  If the user releases the dragged pile on any CardPileView (other than the source pile), that CardPileView's delegate receives the canAcceptPile:dropPile from:sender in:cardPileView message, where dropPile is the pile that wants to be dropped, cardPileView is the pile receiving the cards, and sender is the CardPileView that the cards were dragged from  If this method returns NO, the dragged cards return to the source pile.

If a CardPileView agrees to accept some dragged cards, they are automatically added to that pile.  Then the delegate receives the acceptPile:dropPile in:self message, which lets the pile know which cards were added to it.  Note that the dropped cards are, at this point, on both the original pile (where the cards were dragged from), and on the pile that they have been dropped on.

The cards are now removed from the original CardPileView, and its delegate receives the removePile:aCardPile from:aCardPileView message.

The getOffset:: message allows the delegate to control the amount of stagger that the deck has when it draws.

Instance Variables

float xOffset, yOffset;
id cardPile;
id dragCardPile;
BOOL useDragCardPile;
id delegate;
int delegateFlags;
int tag;
NXColor backgroundColor;
float backgroundGray;
BOOL drawOutline;
BOOL coversOthers;
id coverPile1;
id coverPile2;
id coverPile3;
id coverPile4;
id beneath;

xOffset, yOffset 	The current drawing offset between cards.

cardPile 	The CardPile holding all the cards.

dragCardPile 	Used internally for dragging cards.

useDragCardPile 	Used internally for dragging cards.

delegate 	The object's delegate.

delegateFlags 	Used internally.

tag 	The pile's tag.

backgroundColor 	Background color.

backgroundGray 	Background color on 2-bit monochrome displays.

drawOutline 	Controls display of CardPileView outline.

coversOthers 	YES if this pile overlaps other piles.

coverPile1 	A CardPileView overlapped by this pile.

coverPile2 	A CardPileView overlapped by this pile.

coverPile3 	A CardPileView overlapped by this pile.

coverPile4 	A CardPileView overlapped by this pile.

beneath 	NXImage used internally.

Adopted Protocols

NXDraggingSource (Informal)	- draggingSourceOperationMaskForLocal:
- draggedImage:beganAt:
- draggedImage:endedAt:deposited:

NXDraggingDestination	- prepareForDragOperation:
- draggingEntered:
- performDragOperation:

Method Types

Initializing the class	+ initialize

Creating and freeing	± free
± initFrame:
	
Managing related objects	- cardPile
± delegate
± setDelegate:

Displaying the CardPileView	- backgroundColor
± drawSelf::
± setBackgroundColor:
± setCardSize:
± setDrawOutline:
± setUseShoe:
± willDrawOutline

Overlapping CardPileViews	- pileCovered:
± pileCoveredBy:
± resetBacking:
± setCoverPile:to:
± setCoversOthers:

Responder methods	- mouseDown:

Utility methods	- drawDragCard:
± findCardAt:thePoint
± getRect:forCard:
± setTag:
± tag

Class Methods

initialize
+ initialize

Initializes the class object.  Returns self.

See also:  + initialize (Object)

Instance Methods

backgroundColor
- (NXColor)backgroundColor

Returns the current background color (color displays only).

See also:  ± setBackgroundColor:

cardPile
- cardPile

Returns the CardPile holding all the cards.

See also:  CardPile class.

delegate
- delegate

Returns the object's delegate, or nil if it has none.

See also:  ± setDelegate:

drawDragCard:
- drawDragCard:sender

Draw the pile of cards being dragged.  Do not call directly.  Returns self.

drawSelf:
- drawSelf:(NXRect *)theRect :(int)rectCount

Draws a visual representation of our CardPile.  Use the display message, rather than calling this method directly.  You must call display after any change to a CardPileView.

See also:  ± display (View)

findCardAt:
- findCardAt:(NXPoint *)thePoint

Returns the Card object at thePoint, or nil if there is no card at that location.  

free
- free

Frees all memory used by the CardPileView (including all Cards), and frees the CardPileView itself.  Returns nil.

See also:  ± initFrame:

getRect:forCard:
- getRect:(NXRect *)cardRect forCard:aCard

Supply the bounding rectangle for a card in our pile.  Returns self if the card was found and cardRect was set, otherwise returns nil.

initFrame:
- initFrame:(NXRect *)theFrame

Creates an empty CardPile object to be managed by the CardPileView.  If theFrame is wider and/or taller than the size required by a single Card object, then the pile will automatically be drawn with an offset in that direction.  Returns self.

See also:  ± getOffset:: (delegate)

mouseDown:
- mouseDown:(NXEvent *)theEvent

Used internally to handle card dragging and clicking.  Returns self.

pileCovered:
- (BOOL)pileCovered:sender

Returns YES if any of the CardPileViews connected to coverPile1, coverPile2, coverPile3, or coverPile4 contain cards.  Returns NO if these id's are nil, or if the covering piles are empty.

See also:  ± pileCoveredBy:, ± setCoversOthers:, ± resetBacking:, ± setCoverPile:to:

pileCoveredBy:
- pileCoveredBy:aCardPileView

Returns YES if aCarePileView is non-empty (ie. contains cards) and covers this CardPileView (ie. is connected to coverPile1, coverPile2, coverPile3, or coverPile4).

See also:  ± pileCovered:, ± setCoversOthers:, ± resetBacking:, ± setCoverPile:to:

resetBacking:
- resetBacking:sender

Discards the current backing, and reloads it when the pile is redisplayed.  Only relevant if setCoversOthers: is set to YES.

See also:  ± pileCovered:, ± pileCoveredBy:, ± setCoversOthers:, ± setCoverPile:to:

setBackgroundColor:
- setBackgroundColor:(NXColor *)aColor

Set the background color.  Used only if the display is 8-bit greyscale or deeper.  Returns self.

See also:  ± backgroundColor

setCardSize:
- setCardSize:(CardSize)aSize

Sets the size of cards displayed in this pile.  Returns self.

Constant	Description
CS_SMALL	Small cards
CS_LARGE	Big cards

setCoverPile:to:
- setCoverPile:(int)offset to:aPile

Set the cover pile indicated by offset (which must be in the range 1 to 4) to aPile.  Returns self.

See also:  ± pileCovered:,  ± pileCoveredBy:,  ± resetBacking:, ± setCoversOthers:

setCoversOthers:
- setCoversOthers:(BOOL)doesCover

If this flag is set to YES, the pile will cache and restore the area under the pile, rather that just drawing a rectangle in the current background color, when the pile is redrawn.  Used when one card pile overlaps another.  Returns self.

See also:  ± pileCovered:,  ± pileCoveredBy:,  ± resetBacking:, ± setCoverPile:to:

setDelegate:
- setDelegate:anObject

Sets the delegate for the CardPileView.

See also: Delegate methods below.

setDrawOutline:
- setDrawOutline:(BOOL)aFlag

Set whether the CardPileView draws a border.

See also: ± willDrawOutline:

setOffset::
- setOffset:(float *)xOffset (float *):yOffset

Sets the offset used by pile.  This method was added for piles that do not have a delegate.  (Trombino 7/3/95)

setTag:
- setTag:(int)theTag

Sets the pile's tag.  Returns self.

See also: ± tag

setUseShoe:
- setUseShoe:(BOOL)flag

When flag is YES, makes the CardPileView display its CardPile in a Casino-Type of shoe.  By default the view does not display itself with a shoe.  Returns self.

See also: 

tag
- (int)tag

Returns the pile's tag.

See also: ± setTag:

willDrawOutline
- (BOOL)willDrawOutline

Returns YES if the CardPileView will draw a border, NO otherwise.

See also: ± setDrawOutline:

Methods Implemented By The Delegate

acceptPile:in:
- acceptPile:aCardPile in:aCardPileView

Sent to the delegate after cards have been dropped on a CardPileView and accepted.  aCardPile is the pile which was dropped on aCardPileView.  At this point, the cards which were dragged and dropped are in three piles:  (1) the pile which they were originally dragged from, (2) the temporary dragging pile (aCardPile) and (3) the receiving pile (aCardPileView).

canAcceptPile:from:in:
- (BOOL)canAcceptPile:aCardPile from:sender in:aCardPileView

Sent to a CardPileView's delegate to determine if the pile will allow the cards in aCardPile which were dragged from the CardPileView sender to be dropped on aCardPileView.  This method should return YES if the cards can be dropped; NO if they can't.

clickedCard:in:
- clickedCard:aCard in:aCardPileView

Sent to the delegate when the user single clicks on a CardPileView.  Note that aCard may be nil, typically if the pile is empty, or the user clicked on an area of the CardPileView where there is no card.

doubleClickedCard:in:
- doubleClickedCard:aCard in:aCardPileView

Sent to the delegate when the user double clicks on a CardPileView.  Note that aCard may be nil, typically if the pile is empty, or the user clicked on an area of the CardPileView where there is no card.

draggedPile:from:
- (BOOL)draggedPile:aCardPile from:aCardPileView

Sent to the delegate when the user tries to drag cards off a pile.  When this method is called, aCardPile will only contain the card which the user was pointing at when they began dragging.  Note that this can be any exposed card in the pile.  You may add additional cards from aCardPileView to this pile, and they will be dragged along with the original card.  If this method returns YES, the cards will be dragged.  Returning NO prevents the cards from being dragged.

getOffset::
- getOffset:(float *)xOffset (float *):yOffset

Sent to the delegate to determine the drawing offset of the cards.  This message is only sent once, when the delegate is initially set.

removedPile:from:
- removedPile:aCardPile from:aCardPileView

Sent to the delegate after cards have been successfully dragged from aCardPileView and dropped on another pile.  When this message is sent, the cards in aCardPile have already been removed from the receiver.