XRC: make wxStaticText's wrap property a dimension.
[wxWidgets.git] / demos / forty / card.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: card.cpp
3 // Purpose: Forty Thieves patience game
4 // Author: Chris Breeze
5 // Modified by:
6 // Created: 21/07/97
7 // Copyright: (c) 1993-1998 Chris Breeze
8 // Licence: wxWindows licence
9 //---------------------------------------------------------------------------
10 // Last modified: 22nd July 1998 - ported to wxWidgets 2.0
11 /////////////////////////////////////////////////////////////////////////////
12 //+-------------------------------------------------------------+
13 //| Description
14 //| A class for drawing playing cards.
15 //| Currently assumes that the card symbols have been
16 //| loaded into hbmap_symbols and the pictures for the
17 //| Jack, Queen and King have been loaded into
18 //| hbmap_pictures.
19 //+-------------------------------------------------------------+
20
21 // For compilers that support precompilation, includes "wx/wx.h".
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 #ifndef WX_PRECOMP
29 #include "wx/wx.h"
30 #endif
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include "forty.h"
36 #include "card.h"
37
38 #include "pictures.xpm"
39 #include "symbols.xpm"
40
41 wxBitmap* Card::m_pictureBmap = 0;
42 wxBitmap* Card::m_symbolBmap = 0;
43
44 double Card::m_scale = 1.0;
45 int Card::m_width = 50;
46 int Card::m_height = 70;
47
48 //+-------------------------------------------------------------+
49 //| Card::Card() |
50 //+-------------------------------------------------------------+
51 //| Description: |
52 //| Constructor for a playing card. |
53 //| Checks that the value is in the range 1..52 and then |
54 //| initialises the suit, colour, pipValue and wayUp. |
55 //+-------------------------------------------------------------+
56 Card::Card(int value, WayUp way_up) :
57 m_wayUp(way_up)
58 {
59 if (!m_symbolBmap)
60 {
61 m_symbolBmap = new wxBitmap(symbols_xpm);
62 if (!m_symbolBmap->IsOk())
63 {
64 ::wxMessageBox(wxT("Failed to load bitmap CardSymbols"), wxT("Error"));
65 }
66 }
67 if (!m_pictureBmap)
68 {
69 m_pictureBmap = new wxBitmap(Pictures);
70 if (!m_pictureBmap->IsOk())
71 {
72 ::wxMessageBox(wxT("Failed to load bitmap CardPictures"), wxT("Error"));
73 }
74 }
75
76 if (value >= 1 && value <= PackSize)
77 {
78 switch ((value - 1) / 13)
79 {
80 case 0:
81 m_suit = clubs;
82 m_colour = black;
83 break;
84 case 1:
85 m_suit = diamonds;
86 m_colour = red;
87 break;
88 case 2:
89 m_suit = hearts;
90 m_colour = red;
91 break;
92 case 3:
93 m_suit = spades;
94 m_colour = black;
95 break;
96 }
97 m_pipValue = 1 + (value - 1) % 13;
98 m_status = true;
99 }
100 else
101 {
102 m_status = false;
103 }
104 } // Card::Card()
105
106
107 //+-------------------------------------------------------------+
108 //| Card::SetScale() |
109 //+-------------------------------------------------------------+
110 //| Description: |
111 //| Scales the cards |
112 //+-------------------------------------------------------------+
113 void Card::SetScale(double scale)
114 {
115 m_scale = scale;
116 m_width = int(50*scale);
117 m_height = int(70*scale);
118 }
119
120 //+-------------------------------------------------------------+
121 //| Card::Erase() |
122 //+-------------------------------------------------------------+
123 //| Description: |
124 //| Erase the card at (x, y) by drawing a rectangle in the |
125 //| background colour. |
126 //+-------------------------------------------------------------+
127 void Card::Erase(wxDC& dc, int x, int y)
128 {
129 wxPen* pen = wxThePenList->FindOrCreatePen(
130 FortyApp::BackgroundColour(),
131 1,
132 wxSOLID
133 );
134 dc.SetPen(* pen);
135 dc.SetBrush(FortyApp::BackgroundBrush());
136 dc.DrawRectangle(x, y, m_width, m_height);
137 } // Card::Erase()
138
139
140 //+-------------------------------------------------------------+
141 //| Card::Draw() |
142 //+-------------------------------------------------------------+
143 //| Description: |
144 //| Draw the card at (x, y). |
145 //| If the card is facedown draw the back of the card. |
146 //| If the card is faceup draw the front of the card. |
147 //| Cards are not held in bitmaps, instead they are drawn |
148 //| from their constituent parts when required. |
149 //| hbmap_symbols contains large and small suit symbols and |
150 //| pip values. These are copied to the appropriate part of |
151 //| the card. Picture cards use the pictures defined in |
152 //| hbmap_pictures. Note that only one picture is defined |
153 //| for the Jack, Queen and King, unlike a real pack where |
154 //| each suit is different. |
155 //| |
156 //| WARNING: |
157 //| The locations of these symbols is 'hard-wired' into the |
158 //| code. Editing the bitmaps or the numbers below will |
159 //| result in the wrong symbols being displayed. |
160 //+-------------------------------------------------------------+
161 void Card::Draw(wxDC& dc, int x, int y)
162 {
163 wxBrush backgroundBrush( dc.GetBackground() );
164 dc.SetBrush(* wxWHITE_BRUSH);
165 dc.SetPen(* wxBLACK_PEN);
166 dc.DrawRoundedRectangle(x, y, m_width, m_height, 4);
167 if (m_wayUp == facedown)
168 {
169 dc.SetBackground(* wxRED_BRUSH);
170 dc.SetBackgroundMode(wxSOLID);
171 wxBrush* brush = wxTheBrushList->FindOrCreateBrush(
172 *wxBLACK, wxCROSSDIAG_HATCH
173 );
174 dc.SetBrush(* brush);
175
176 dc.DrawRoundedRectangle(
177 x + 4, y + 4,
178 m_width - 8, m_height - 8,
179 2
180 );
181 }
182 else
183 {
184 wxMemoryDC memoryDC;
185
186 memoryDC.SelectObject(*m_symbolBmap);
187
188 // dc.SetBackgroundMode(wxTRANSPARENT);
189
190 dc.SetTextBackground(*wxWHITE);
191 switch (m_suit)
192 {
193 case spades:
194 case clubs:
195 dc.SetTextForeground(*wxBLACK);
196 break;
197 case diamonds:
198 case hearts:
199 dc.SetTextForeground(*wxRED);
200 break;
201 }
202
203 int symsize = 11;
204 int sympos = 14;
205 int sympos2 = 25;
206 int symdist = 5;
207 int symdist2 = 6;
208
209 int pipsize,pippos,valueheight,valuewidth;
210 int valuepos;
211 if (m_scale > 1.2)
212 {
213 pipsize = symsize;
214 pippos = sympos;
215 valueheight = 10;
216 valuewidth = 9;
217 valuepos = 50;
218 }
219 else
220 {
221 pipsize = 7;
222 pippos = 0;
223 valueheight = 7;
224 valuewidth = 6;
225 valuepos = 36;
226 }
227
228 // Draw the value
229 dc.Blit((wxCoord)(x + m_scale*3),
230 (wxCoord)(y + m_scale*3),
231 valuewidth,
232 valueheight,
233 &memoryDC,
234 valuewidth * (m_pipValue - 1),
235 valuepos,
236 wxCOPY);
237 dc.Blit((wxCoord)(x + m_width - m_scale*3 - valuewidth),
238 (wxCoord)(y + m_height - valueheight - m_scale*3),
239 valuewidth,
240 valueheight,
241 &memoryDC,
242 valuewidth * (m_pipValue - 1),
243 valuepos+valueheight,
244 wxCOPY);
245
246 // Draw the pips
247 dc.Blit((wxCoord)(x + m_scale*3 + valuewidth+2),
248 (wxCoord)(y + m_scale*3),
249 pipsize,
250 pipsize,
251 &memoryDC,
252 pipsize * m_suit,
253 pippos,
254 wxCOPY);
255 dc.Blit((wxCoord)(x + m_width - m_scale*3-valuewidth-pipsize-2),
256 (wxCoord)(y + m_height - pipsize - m_scale*3),
257 pipsize,
258 pipsize,
259 &memoryDC,
260 pipsize * m_suit,
261 pipsize+pippos,
262 wxCOPY);
263
264 switch (m_pipValue)
265 {
266 case 1:
267 dc.Blit((wxCoord)(x - symdist + m_width / 2),
268 (wxCoord)(y - m_scale*5 + m_height / 2),
269 symsize,
270 symsize,
271 &memoryDC,
272 symsize * m_suit,
273 sympos,
274 wxCOPY);
275 break;
276
277 case 3:
278 dc.Blit((wxCoord)(x - symdist + m_width / 2),
279 (wxCoord)(y - symdist + m_height / 2),
280 symsize,
281 symsize,
282 &memoryDC,
283 symsize * m_suit,
284 sympos,
285 wxCOPY);
286 case 2:
287 dc.Blit((wxCoord)(x - symdist + m_width / 2),
288 (wxCoord)(y - symdist + m_height / 4),
289 symsize,
290 symsize,
291 &memoryDC,
292 symsize * m_suit,
293 sympos,
294 wxCOPY);
295 dc.Blit((wxCoord)(x - symdist + m_width / 2),
296 (wxCoord)(y - symdist + 3 * m_height / 4),
297 symsize,
298 symsize,
299 &memoryDC,
300 symsize * m_suit,
301 sympos2,
302 wxCOPY);
303 break;
304
305 case 5:
306 dc.Blit((wxCoord)(x - symdist + m_width / 2),
307 (wxCoord)(y - symdist + m_height / 2),
308 symsize,
309 symsize,
310 &memoryDC,
311 symsize * m_suit,
312 sympos,
313 wxCOPY);
314 case 4:
315 dc.Blit((wxCoord)(x - symdist + m_width / 4),
316 (wxCoord)(y - symdist + m_height / 4),
317 symsize,
318 symsize,
319 &memoryDC,
320 symsize * m_suit,
321 sympos,
322 wxCOPY);
323 dc.Blit((wxCoord)(x - symdist + m_width / 4),
324 (wxCoord)(y - symdist + 3 * m_height / 4),
325 symsize,
326 symsize,
327 &memoryDC,
328 symsize * m_suit,
329 sympos2,
330 wxCOPY);
331 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
332 (wxCoord)(y - symdist + m_height / 4),
333 symsize,
334 symsize,
335 &memoryDC,
336 symsize * m_suit,
337 sympos,
338 wxCOPY);
339 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
340 (wxCoord)(y - symdist + 3 * m_height / 4),
341 symsize,
342 symsize,
343 &memoryDC,
344 symsize * m_suit,
345 sympos2,
346 wxCOPY);
347 break;
348
349 case 8:
350 dc.Blit((wxCoord)(x - symdist + 5 * m_width / 10),
351 (wxCoord)(y - symdist + 5 * m_height / 8),
352 symsize,
353 symsize,
354 &memoryDC,
355 symsize * m_suit,
356 sympos2,
357 wxCOPY);
358 case 7:
359 dc.Blit((wxCoord)(x - symdist + 5 * m_width / 10),
360 (wxCoord)(y - symdist + 3 * m_height / 8),
361 symsize,
362 symsize,
363 &memoryDC,
364 symsize * m_suit,
365 sympos,
366 wxCOPY);
367 case 6:
368 dc.Blit((wxCoord)(x - symdist + m_width / 4),
369 (wxCoord)(y - symdist + m_height / 4),
370 symsize,
371 symsize,
372 &memoryDC, symsize * m_suit, sympos, wxCOPY);
373 dc.Blit((wxCoord)(x - symdist + m_width / 4),
374 (wxCoord)(y - symdist + m_height / 2),
375 symsize,
376 symsize,
377 &memoryDC,
378 symsize * m_suit,
379 sympos,
380 wxCOPY);
381 dc.Blit((wxCoord)(x - symdist + m_width / 4),
382 (wxCoord)(y - symdist + 3 * m_height / 4),
383 symsize,
384 symsize,
385 &memoryDC,
386 symsize * m_suit,
387 sympos2,
388 wxCOPY);
389 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
390 (wxCoord)(y - symdist + m_height / 4),
391 symsize,
392 symsize,
393 &memoryDC,
394 symsize * m_suit,
395 sympos,
396 wxCOPY);
397 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
398 (wxCoord)(y - symdist + m_height / 2),
399 symsize,
400 symsize,
401 &memoryDC,
402 symsize * m_suit,
403 sympos,
404 wxCOPY);
405 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
406 (wxCoord)(y - symdist + 3 * m_height / 4),
407 symsize,
408 symsize,
409 &memoryDC,
410 symsize * m_suit,
411 sympos2,
412 wxCOPY);
413 break;
414
415 case 10:
416 dc.Blit((wxCoord)(x - symdist + m_width / 2),
417 (wxCoord)(y - symdist + 2 * m_height / 3),
418 symsize,
419 symsize,
420 &memoryDC,
421 symsize * m_suit,
422 sympos2,
423 wxCOPY);
424 case 9:
425 dc.Blit((wxCoord)(x - symdist + m_width / 4),
426 (wxCoord)(y - symdist2 + m_height / 4),
427 symsize,
428 symsize,
429 &memoryDC,
430 symsize * m_suit,
431 sympos,
432 wxCOPY);
433 dc.Blit((wxCoord)(x - symdist + m_width / 4),
434 (wxCoord)(y - symdist2 + 5 * m_height / 12),
435 symsize,
436 symsize,
437 &memoryDC,
438 symsize * m_suit,
439 sympos,
440 wxCOPY);
441 dc.Blit((wxCoord)(x - symdist + m_width / 4),
442 (wxCoord)(y - symdist + 7 * m_height / 12),
443 symsize,
444 symsize,
445 &memoryDC,
446 symsize * m_suit,
447 sympos2,
448 wxCOPY);
449 dc.Blit((wxCoord)(x - symdist + m_width / 4),
450 (wxCoord)(y - symdist + 3 * m_height / 4),
451 symsize,
452 symsize,
453 &memoryDC,
454 symsize * m_suit,
455 sympos2,
456 wxCOPY);
457
458 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
459 (wxCoord)(y - symdist2 + m_height / 4),
460 symsize,
461 symsize,
462 &memoryDC,
463 symsize * m_suit,
464 sympos,
465 wxCOPY);
466 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
467 (wxCoord)(y - symdist2 + 5 * m_height / 12),
468 symsize,
469 symsize,
470 &memoryDC,
471 symsize * m_suit,
472 sympos,
473 wxCOPY);
474 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
475 (wxCoord)(y - symdist + 7 * m_height / 12),
476 symsize,
477 symsize,
478 &memoryDC,
479 symsize * m_suit,
480 sympos2,
481 wxCOPY);
482 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
483 (wxCoord)(y - symdist + 3 * m_height / 4),
484 symsize,
485 symsize,
486 &memoryDC,
487 symsize * m_suit,
488 sympos2,
489 wxCOPY);
490 dc.Blit((wxCoord)(x - symdist + m_width / 2),
491 (wxCoord)(y - symdist + m_height / 3),
492 symsize,
493 symsize,
494 &memoryDC,
495 symsize * m_suit,
496 sympos,
497 wxCOPY);
498 break;
499 case 11:
500 case 12:
501 case 13:
502 memoryDC.SelectObject(*m_pictureBmap);
503 int picwidth = 40,picheight = 45;
504 dc.Blit((wxCoord)(x + (m_width-picwidth)/2),
505 (wxCoord)(y - picheight/2 + m_height/2),
506 picwidth,
507 picheight,
508 &memoryDC,
509 picwidth * (m_pipValue - 11),
510 0,
511 wxCOPY);
512
513 memoryDC.SelectObject(*m_symbolBmap);
514 dc.Blit((wxCoord)(x + m_width-(m_width-picwidth)/2-symsize-3),
515 (wxCoord)(y - picheight/2+m_height/2+1),
516 symsize,
517 symsize,
518 &memoryDC,
519 symsize * m_suit,
520 sympos,
521 wxCOPY);
522 dc.Blit((wxCoord)(x + (m_width-picwidth)/2+2),
523 (wxCoord)(y + picheight/2 + m_height/2-symsize),
524 symsize,
525 symsize,
526 &memoryDC,
527 symsize * m_suit,
528 sympos2,
529 wxCOPY);
530 break;
531 }
532
533 }
534 dc.SetBackground( backgroundBrush );
535 } // Card:Draw()
536
537
538 //+-------------------------------------------------------------+
539 //| Card::DrawNullCard() |
540 //+-------------------------------------------------------------+
541 //| Description: |
542 //| Draws the outline of a card at (x, y). |
543 //| Used to draw place holders for empty piles of cards. |
544 //+-------------------------------------------------------------+
545 void Card::DrawNullCard(wxDC& dc, int x, int y)
546 {
547 wxPen* pen = wxThePenList->FindOrCreatePen(FortyApp::TextColour(), 1, wxSOLID);
548 dc.SetBrush(FortyApp::BackgroundBrush());
549 dc.SetPen(*pen);
550 dc.DrawRoundedRectangle(x, y, m_width, m_height, 4);
551 } // Card::DrawNullCard()