]> git.saurik.com Git - wxWidgets.git/blame - demos/forty/pile.cpp
Only give capture to wxPopupTransientWindow child if it's the only one.
[wxWidgets.git] / demos / forty / pile.cpp
CommitLineData
63cafd27
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: pile.cpp
3// Purpose: Forty Thieves patience game
4// Author: Chris Breeze
5// Modified by:
6// Created: 21/07/97
63cafd27 7// Copyright: (c) 1993-1998 Chris Breeze
010216e3 8// Licence: wxWindows licence
63cafd27 9//---------------------------------------------------------------------------
be5a51fb 10// Last modified: 22nd July 1998 - ported to wxWidgets 2.0
63cafd27
JS
11/////////////////////////////////////////////////////////////////////////////
12//+-------------------------------------------------------------+
010216e3
WS
13//| Description: |
14//| The base class for holding piles of playing cards. |
63cafd27
JS
15//+-------------------------------------------------------------+
16
63cafd27
JS
17// For compilers that support precompilation, includes "wx/wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
21#pragma hdrstop
22#endif
23
24#ifndef WX_PRECOMP
25#include "wx/wx.h"
26#endif
63cafd27
JS
27
28#include <stdlib.h>
29#include <stdio.h>
30#include <time.h>
31#include <string.h>
32#include "card.h"
33#include "pile.h"
868741e9
JS
34#include "forty.h"
35#include "canvas.h"
63cafd27 36
e3e65dac 37#include "wx/app.h"
63cafd27
JS
38
39//+-------------------------------------------------------------+
010216e3 40//| Pile::Pile() |
63cafd27 41//+-------------------------------------------------------------+
010216e3
WS
42//| Description: |
43//| Initialise the pile to be empty of cards. |
63cafd27
JS
44//+-------------------------------------------------------------+
45Pile::Pile(int x, int y, int dx, int dy)
46{
47 m_x = x;
48 m_y = y;
49 m_dx = dx;
50 m_dy = dy;
51 for (m_topCard = 0; m_topCard < NumCards; m_topCard++)
52 {
010216e3 53 m_cards[m_topCard] = 0;
63cafd27 54 }
010216e3 55 m_topCard = -1; // i.e. empty
63cafd27
JS
56}
57
58
59//+-------------------------------------------------------------+
010216e3 60//| Pile::Redraw() |
63cafd27 61//+-------------------------------------------------------------+
010216e3
WS
62//| Description: |
63//| Redraw the pile on the screen. If the pile is empty |
64//| just draw a NULL card as a place holder for the pile. |
65//| Otherwise draw the pile from the bottom up, starting |
66//| at the origin of the pile, shifting each subsequent |
67//| card by the pile's x and y offsets. |
63cafd27 68//+-------------------------------------------------------------+
e3e65dac 69void Pile::Redraw(wxDC& dc )
63cafd27 70{
010216e3
WS
71 FortyFrame *frame = (FortyFrame*) wxTheApp->GetTopWindow();
72 wxWindow *canvas = (wxWindow *) NULL;
73 if (frame)
74 {
75 canvas = frame->GetCanvas();
76 }
77
78 if (m_topCard >= 0)
79 {
80 if (m_dx == 0 && m_dy == 0)
81 {
82 if ((canvas) && (canvas->IsExposed(m_x,m_y,(int)(Card::GetScale()*60),(int)(Card::GetScale()*200))))
83 m_cards[m_topCard]->Draw(dc, m_x, m_y);
84 }
85 else
86 {
87 int x = m_x;
88 int y = m_y;
89 for (int i = 0; i <= m_topCard; i++)
90 {
91 if ((canvas) && (canvas->IsExposed(x,y,(int)(Card::GetScale()*60),(int)(Card::GetScale()*200))))
92 m_cards[i]->Draw(dc, x, y);
fc799548
JS
93 x += (int)Card::GetScale()*m_dx;
94 y += (int)Card::GetScale()*m_dy;
010216e3
WS
95 }
96 }
97 }
98 else
99 {
100 if ((canvas) && (canvas->IsExposed(m_x,m_y,(int)(Card::GetScale()*60),(int)(Card::GetScale()*200))))
101 Card::DrawNullCard(dc, m_x, m_y);
102 }
63cafd27
JS
103}
104
105
106//+-------------------------------------------------------------+
010216e3 107//| Pile::GetTopCard() |
63cafd27 108//+-------------------------------------------------------------+
010216e3
WS
109//| Description: |
110//| Return a pointer to the top card in the pile or NULL |
111//| if the pile is empty. |
112//| NB: Gets a copy of the card without removing it from the |
113//| pile. |
63cafd27
JS
114//+-------------------------------------------------------------+
115Card* Pile::GetTopCard()
116{
117 Card* card = 0;
118
119 if (m_topCard >= 0)
120 {
010216e3 121 card = m_cards[m_topCard];
63cafd27
JS
122 }
123 return card;
124}
125
126
127//+-------------------------------------------------------------+
128//| Pile::RemoveTopCard() |
129//+-------------------------------------------------------------+
010216e3
WS
130//| Description: |
131//| If the pile is not empty, remove the top card from the |
132//| pile and return the pointer to the removed card. |
133//| If the pile is empty return a NULL pointer. |
63cafd27
JS
134//+-------------------------------------------------------------+
135Card* Pile::RemoveTopCard()
136{
137 Card* card = 0;
138
139 if (m_topCard >= 0)
140 {
010216e3 141 card = m_cards[m_topCard--];
63cafd27
JS
142 }
143 return card;
144}
145
146
147//+-------------------------------------------------------------+
148//| Pile::RemoveTopCard() |
149//+-------------------------------------------------------------+
010216e3
WS
150//| Description: |
151//| As RemoveTopCard() but also redraw the top of the pile |
152//| after the card has been removed. |
153//| NB: the offset allows for the redrawn area to be in a |
154//| bitmap ready for 'dragging' cards acrosss the screen. |
63cafd27
JS
155//+-------------------------------------------------------------+
156Card* Pile::RemoveTopCard(wxDC& dc, int xOffset, int yOffset)
157{
010216e3
WS
158 int topX, topY, x, y;
159
160 GetTopCardPos(topX, topY);
161 Card* card = RemoveTopCard();
162
163 if (card)
164 {
165 card->Erase(dc, topX - xOffset, topY - yOffset);
166 GetTopCardPos(x, y);
167 if (m_topCard < 0)
168 {
169 Card::DrawNullCard(dc, x - xOffset, y - yOffset);
170 }
171 else
172 {
173 m_cards[m_topCard]->Draw(dc, x - xOffset, y - yOffset);
174 }
175 }
176
177 return card;
63cafd27
JS
178}
179
180
181void Pile::GetTopCardPos(int& x, int& y)
182{
010216e3
WS
183 if (m_topCard < 0)
184 {
185 x = m_x;
186 y = m_y;
187 }
188 else
189 {
190 x = m_x + (int)Card::GetScale()*m_dx * m_topCard;
191 y = m_y + (int)Card::GetScale()*m_dy * m_topCard;
192 }
63cafd27
JS
193}
194
195void Pile::AddCard(Card* card)
196{
197 if (m_topCard < -1) m_topCard = -1;
198
199 m_cards[++m_topCard] = card;
200}
201
202void Pile::AddCard(wxDC& dc, Card* card)
203{
204 AddCard(card);
205 int x, y;
206 GetTopCardPos(x, y);
207 card->Draw(dc, x, y);
208}
209
210// Can the card leave this pile.
211// If it is a member of the pile then the answer is yes.
212// Derived classes may override this behaviour to incorporate
213// the rules of the game
214bool Pile::CanCardLeave(Card* card)
215{
216 for (int i = 0; i <= m_topCard; i++)
217 {
010216e3 218 if (card == m_cards[i]) return true;
63cafd27 219 }
e0b5519a 220 return false;
63cafd27
JS
221}
222
223// Calculate how far x, y is from top card in the pile
224// Returns the square of the distance
225int Pile::CalcDistance(int x, int y)
226{
227 int cx, cy;
228 GetTopCardPos(cx, cy);
229 return ((cx - x) * (cx - x) + (cy - y) * (cy - y));
230}
231
232
233// Return the card at x, y. Check the top card first, then
234// work down the pile. If a card is found then return a pointer
235// to the card, otherwise return NULL
236Card* Pile::GetCard(int x, int y)
237{
010216e3
WS
238 int cardX;
239 int cardY;
240 GetTopCardPos(cardX, cardY);
241
242 for (int i = m_topCard; i >= 0; i--)
243 {
244 if (x >= cardX && x <= cardX + Card::GetWidth() &&
245 y >= cardY && y <= cardY + Card::GetHeight())
246 {
247 return m_cards[i];
248 }
249 cardX -= (int)Card::GetScale()*m_dx;
250 cardY -= (int)Card::GetScale()*m_dy;
251 }
252 return 0;
63cafd27
JS
253}
254
255
256// Return the position of the given card. If it is not a member of this pile
257// return the origin of the pile.
258void Pile::GetCardPos(Card* card, int& x, int& y)
259{
010216e3
WS
260 x = m_x;
261 y = m_y;
262
263 for (int i = 0; i <= m_topCard; i++)
264 {
265 if (card == m_cards[i])
266 {
267 return;
268 }
269 x += (int)Card::GetScale()*m_dx;
270 y += (int)Card::GetScale()*m_dy;
271 }
272
273 // card not found in pile, return origin of pile
274 x = m_x;
275 y = m_y;
63cafd27
JS
276}
277
278
279bool Pile::Overlap(int x, int y)
280{
281 int cardX;
282 int cardY;
283 GetTopCardPos(cardX, cardY);
284
fc799548
JS
285 if (x >= cardX - Card::GetWidth() && x <= cardX + Card::GetWidth() &&
286 y >= cardY - Card::GetHeight() && y <= cardY + Card::GetHeight())
63cafd27 287 {
010216e3 288 return true;
63cafd27 289 }
e0b5519a 290 return false;
63cafd27 291}