]> git.saurik.com Git - wxWidgets.git/blame_incremental - demos/forty/card.cpp
fixed focus tracking for spin controls (patch from Dimitri)
[wxWidgets.git] / demos / forty / card.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: card.cpp
3// Purpose: Forty Thieves patience game
4// Author: Chris Breeze
5// Modified by:
6// Created: 21/07/97
7// RCS-ID: $Id$
8// Copyright: (c) 1993-1998 Chris Breeze
9// Licence: wxWindows licence
10//---------------------------------------------------------------------------
11// Last modified: 22nd July 1998 - ported to wxWindows 2.0
12/////////////////////////////////////////////////////////////////////////////
13//+-------------------------------------------------------------+
14//| Description
15//| A class for drawing playing cards.
16//| Currently assumes that the card symbols have been
17//| loaded into hbmap_symbols and the pictures for the
18//| Jack, Queen and King have been loaded into
19//| hbmap_pictures.
20//+-------------------------------------------------------------+
21
22#ifdef __GNUG__
23#pragma implementation
24#pragma interface
25#endif
26
27// For compilers that support precompilation, includes "wx/wx.h".
28#include "wx/wxprec.h"
29
30#ifdef __BORLANDC__
31#pragma hdrstop
32#endif
33
34#ifndef WX_PRECOMP
35#include "wx/wx.h"
36#endif
37
38#include <stdlib.h>
39#include <stdio.h>
40#include <string.h>
41#include "forty.h"
42#include "card.h"
43
44#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXX11__)
45#include "pictures.xpm"
46#include "symbols.xbm"
47#endif
48
49wxBitmap* Card::m_pictureBmap = 0;
50wxBitmap* Card::m_symbolBmap = 0;
51
52double Card::m_scale = 1.0;
53int Card::m_width = 50;
54int Card::m_height = 70;
55
56//+-------------------------------------------------------------+
57//| Card::Card() |
58//+-------------------------------------------------------------+
59//| Description: |
60//| Constructor for a playing card. |
61//| Checks that the value is in the range 1..52 and then |
62//| initialises the suit, colour, pipValue and wayUp. |
63//+-------------------------------------------------------------+
64Card::Card(int value, WayUp way_up) :
65 m_wayUp(way_up)
66{
67 if (!m_symbolBmap)
68 {
69#ifdef __WXMSW__
70 m_symbolBmap = new wxBitmap("CardSymbols", wxBITMAP_TYPE_BMP_RESOURCE);
71#else
72 m_symbolBmap = new wxBitmap(Symbols_bits, Symbols_width, Symbols_height);
73#endif
74 if (!m_symbolBmap->Ok())
75 {
76 ::wxMessageBox("Failed to load bitmap CardSymbols", "Error");
77 }
78 }
79 if (!m_pictureBmap)
80 {
81#ifdef __WXMSW__
82 m_pictureBmap = new wxBitmap("CardPictures", wxBITMAP_TYPE_BMP_RESOURCE);
83#else
84 m_pictureBmap = new wxBitmap(Pictures);
85#endif
86 if (!m_pictureBmap->Ok())
87 {
88 ::wxMessageBox("Failed to load bitmap CardPictures", "Error");
89 }
90 }
91
92 if (value >= 1 && value <= PackSize)
93 {
94 switch ((value - 1) / 13)
95 {
96 case 0:
97 m_suit = clubs;
98 m_colour = black;
99 break;
100 case 1:
101 m_suit = diamonds;
102 m_colour = red;
103 break;
104 case 2:
105 m_suit = hearts;
106 m_colour = red;
107 break;
108 case 3:
109 m_suit = spades;
110 m_colour = black;
111 break;
112 }
113 m_pipValue = 1 + (value - 1) % 13;
114 m_status = TRUE;
115 }
116 else
117 {
118 m_status = FALSE;
119 }
120} // Card::Card()
121
122
123//+-------------------------------------------------------------+
124//| Card::SetScale() |
125//+-------------------------------------------------------------+
126//| Description: |
127//| Scales the cards |
128//+-------------------------------------------------------------+
129void Card::SetScale(double scale)
130{
131 m_scale = scale;
132 m_width = int(50*scale);
133 m_height = int(70*scale);
134}
135
136//+-------------------------------------------------------------+
137//| Card::~Card() |
138//+-------------------------------------------------------------+
139//| Description: |
140//| Destructor - nothing to do at present. |
141//+-------------------------------------------------------------+
142Card::~Card()
143{
144}
145
146
147//+-------------------------------------------------------------+
148//| Card::Erase() |
149//+-------------------------------------------------------------+
150//| Description: |
151//| Erase the card at (x, y) by drawing a rectangle in the |
152//| background colour. |
153//+-------------------------------------------------------------+
154void Card::Erase(wxDC& dc, int x, int y)
155{
156 wxPen* pen = wxThePenList->FindOrCreatePen(
157 FortyApp::BackgroundColour(),
158 1,
159 wxSOLID
160 );
161 dc.SetPen(* pen);
162 dc.SetBrush(FortyApp::BackgroundBrush());
163 dc.DrawRectangle(x, y, m_width, m_height);
164} // Card::Erase()
165
166
167//+-------------------------------------------------------------+
168//| Card::Draw() |
169//+-------------------------------------------------------------+
170//| Description: |
171//| Draw the card at (x, y). |
172//| If the card is facedown draw the back of the card. |
173//| If the card is faceup draw the front of the card. |
174//| Cards are not held in bitmaps, instead they are drawn |
175//| from their constituent parts when required. |
176//| hbmap_symbols contains large and small suit symbols and |
177//| pip values. These are copied to the appropriate part of |
178//| the card. Picture cards use the pictures defined in |
179//| hbmap_pictures. Note that only one picture is defined |
180//| for the Jack, Queen and King, unlike a real pack where |
181//| each suit is different. |
182//| |
183//| WARNING: |
184//| The locations of these symbols is 'hard-wired' into the |
185//| code. Editing the bitmaps or the numbers below will |
186//| result in the wrong symbols being displayed. |
187//+-------------------------------------------------------------+
188void Card::Draw(wxDC& dc, int x, int y)
189{
190 wxBrush backgroundBrush( dc.GetBackground() );
191 dc.SetBrush(* wxWHITE_BRUSH);
192 dc.SetPen(* wxBLACK_PEN);
193 dc.DrawRoundedRectangle(x, y, m_width, m_height, 4);
194 if (m_wayUp == facedown)
195 {
196 dc.SetBackground(* wxRED_BRUSH);
197 dc.SetBackgroundMode(wxSOLID);
198 wxBrush* brush = wxTheBrushList->FindOrCreateBrush(
199 "BLACK", wxCROSSDIAG_HATCH
200 );
201 dc.SetBrush(* brush);
202
203 dc.DrawRoundedRectangle(
204 x + 4, y + 4,
205 m_width - 8, m_height - 8,
206 2
207 );
208 }
209 else
210 {
211 wxMemoryDC memoryDC;
212
213 memoryDC.SelectObject(*m_symbolBmap);
214
215// dc.SetBackgroundMode(wxTRANSPARENT);
216
217 dc.SetTextBackground(*wxWHITE);
218 switch (m_suit)
219 {
220 case spades:
221 case clubs:
222 dc.SetTextForeground(*wxBLACK);
223 break;
224 case diamonds:
225 case hearts:
226 dc.SetTextForeground(*wxRED);
227 break;
228 }
229
230 int symsize = 11;
231 int sympos = 14;
232 int sympos2 = 25;
233 int symdist = 5;
234 int symdist2 = 6;
235
236 int pipsize,pippos,valueheight,valuewidth;
237 int valuepos;
238 if (m_scale > 1.2)
239 {
240 pipsize = symsize;
241 pippos = sympos;
242 valueheight = 10;
243 valuewidth = 9;
244 valuepos = 50;
245 }
246 else
247 {
248 pipsize = 7;
249 pippos = 0;
250 valueheight = 7;
251 valuewidth = 6;
252 valuepos = 36;
253 }
254
255 // Draw the value
256 dc.Blit(x + m_scale*3, y + m_scale*3, valuewidth, valueheight,
257 &memoryDC, valuewidth * (m_pipValue - 1), valuepos, wxCOPY);
258 dc.Blit(x + m_width - m_scale*3 - valuewidth, y + m_height - valueheight - m_scale*3,
259 valuewidth, valueheight,
260 &memoryDC, valuewidth * (m_pipValue - 1), valuepos+valueheight, wxCOPY);
261
262 // Draw the pips
263 dc.Blit(x + m_scale*3 + valuewidth+2, y + m_scale*3, pipsize, pipsize,
264 &memoryDC, pipsize * m_suit, pippos, wxCOPY);
265 dc.Blit(x + m_width - m_scale*3-valuewidth-pipsize-2, y + m_height - pipsize - m_scale*3,
266 pipsize, pipsize,
267 &memoryDC, pipsize * m_suit, pipsize+pippos, wxCOPY);
268
269 switch (m_pipValue)
270 {
271 case 1:
272 dc.Blit(x - symdist + m_width / 2, y - m_scale*5 + m_height / 2, symsize, symsize,
273 &memoryDC, symsize * m_suit, sympos, wxCOPY);
274 break;
275
276 case 3:
277 dc.Blit(x - symdist + m_width / 2, y - symdist + m_height / 2, symsize, symsize,
278 &memoryDC, symsize * m_suit, sympos, wxCOPY);
279 case 2:
280 dc.Blit(x - symdist + m_width / 2,
281 y - symdist + m_height / 4, symsize, symsize,
282 &memoryDC, symsize * m_suit, sympos, wxCOPY);
283 dc.Blit(x - symdist + m_width / 2,
284 y - symdist + 3 * m_height / 4, symsize, symsize,
285 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
286 break;
287
288 case 5:
289 dc.Blit(x - symdist + m_width / 2, y - symdist + m_height / 2, symsize, symsize,
290 &memoryDC, symsize * m_suit, sympos, wxCOPY);
291 case 4:
292 dc.Blit(x - symdist + m_width / 4,
293 y - symdist + m_height / 4, symsize, symsize,
294 &memoryDC, symsize * m_suit, sympos, wxCOPY);
295 dc.Blit(x - symdist + m_width / 4,
296 y - symdist + 3 * m_height / 4, symsize, symsize,
297 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
298 dc.Blit(x - symdist + 3 * m_width / 4,
299 y - symdist + m_height / 4, symsize, symsize,
300 &memoryDC, symsize * m_suit, sympos, wxCOPY);
301 dc.Blit(x - symdist + 3 * m_width / 4,
302 y - symdist + 3 * m_height / 4, symsize, symsize,
303 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
304 break;
305
306 case 8:
307 dc.Blit(x - symdist + 5 * m_width / 10,
308 y - symdist + 5 * m_height / 8, symsize, symsize,
309 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
310 case 7:
311 dc.Blit(x - symdist + 5 * m_width / 10,
312 y - symdist + 3 * m_height / 8, symsize, symsize,
313 &memoryDC, symsize * m_suit, sympos, wxCOPY);
314 case 6:
315 dc.Blit(x - symdist + m_width / 4,
316 y - symdist + m_height / 4, symsize, symsize,
317 &memoryDC, symsize * m_suit, sympos, wxCOPY);
318 dc.Blit(x - symdist + m_width / 4,
319 y - symdist + m_height / 2, symsize, symsize,
320 &memoryDC, symsize * m_suit, sympos, wxCOPY);
321 dc.Blit(x - symdist + m_width / 4,
322 y - symdist + 3 * m_height / 4, symsize, symsize,
323 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
324 dc.Blit(x - symdist + 3 * m_width / 4,
325 y - symdist + m_height / 4, symsize, symsize,
326 &memoryDC, symsize * m_suit, sympos, wxCOPY);
327 dc.Blit(x - symdist + 3 * m_width / 4,
328 y - symdist + m_height / 2, symsize, symsize,
329 &memoryDC, symsize * m_suit, sympos, wxCOPY);
330 dc.Blit(x - symdist + 3 * m_width / 4,
331 y - symdist + 3 * m_height / 4, symsize, symsize,
332 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
333 break;
334
335 case 10:
336 dc.Blit(x - symdist + m_width / 2,
337 y - symdist + 2 * m_height / 3, symsize, symsize,
338 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
339 case 9:
340 dc.Blit(x - symdist + m_width / 4,
341 y - symdist2 + m_height / 4, symsize, symsize,
342 &memoryDC, symsize * m_suit, sympos, wxCOPY);
343 dc.Blit(x - symdist + m_width / 4,
344 y - symdist2 + 5 * m_height / 12, symsize, symsize,
345 &memoryDC, symsize * m_suit, sympos, wxCOPY);
346 dc.Blit(x - symdist + m_width / 4,
347 y - symdist + 7 * m_height / 12, symsize, symsize,
348 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
349 dc.Blit(x - symdist + m_width / 4,
350 y - symdist + 3 * m_height / 4, symsize, symsize,
351 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
352
353 dc.Blit(x - symdist + 3 * m_width / 4,
354 y - symdist2 + m_height / 4, symsize, symsize,
355 &memoryDC, symsize * m_suit, sympos, wxCOPY);
356 dc.Blit(x - symdist + 3 * m_width / 4,
357 y - symdist2 + 5 * m_height / 12, symsize, symsize,
358 &memoryDC, symsize * m_suit, sympos, wxCOPY);
359 dc.Blit(x - symdist + 3 * m_width / 4,
360 y - symdist + 7 * m_height / 12, symsize, symsize,
361 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
362 dc.Blit(x - symdist + 3 * m_width / 4,
363 y - symdist + 3 * m_height / 4, symsize, symsize,
364 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
365 dc.Blit(x - symdist + m_width / 2,
366 y - symdist + m_height / 3, symsize, symsize,
367 &memoryDC, symsize * m_suit, sympos, wxCOPY);
368 break;
369 case 11:
370 case 12:
371 case 13:
372 memoryDC.SelectObject(*m_pictureBmap);
373 int picwidth = 40,picheight = 45;
374 dc.Blit(x + (m_width-picwidth)/2, y - picheight/2 + m_height/2,
375 picwidth, picheight,
376 &memoryDC, picwidth * (m_pipValue - 11), 0, wxCOPY);
377
378 memoryDC.SelectObject(*m_symbolBmap);
379 dc.Blit(x + m_width-(m_width-picwidth)/2-symsize-3,y - picheight/2+m_height/2+1, symsize, symsize,
380 &memoryDC, symsize * m_suit, sympos, wxCOPY);
381 dc.Blit(x + (m_width-picwidth)/2+2,y + picheight/2 + m_height/2-symsize, symsize, symsize,
382 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
383 break;
384 }
385
386 }
387 dc.SetBackground( backgroundBrush );
388} // Card:Draw()
389
390
391//+-------------------------------------------------------------+
392//| Card::DrawNullCard() |
393//+-------------------------------------------------------------+
394//| Description: |
395//| Draws the outline of a card at (x, y). |
396//| Used to draw place holders for empty piles of cards. |
397//+-------------------------------------------------------------+
398void Card::DrawNullCard(wxDC& dc, int x, int y)
399{
400 wxPen* pen = wxThePenList->FindOrCreatePen(FortyApp::TextColour(), 1, wxSOLID);
401 dc.SetBrush(FortyApp::BackgroundBrush());
402 dc.SetPen(*pen);
403 dc.DrawRoundedRectangle(x, y, m_width, m_height, 4);
404} // Card::DrawNullCard()
405
406