]> git.saurik.com Git - wxWidgets.git/blame - samples/drawing/drawing.cpp
A clarification
[wxWidgets.git] / samples / drawing / drawing.cpp
CommitLineData
aba99005
RR
1/////////////////////////////////////////////////////////////////////////////
2// Name: drawing.cpp
0f0c61d0 3// Purpose: shows and tests wxDC features
aba99005
RR
4// Author: Robert Roebling
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Robert Roebling
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
568708e2 19
788233da 20#if defined(__GNUG__) && !defined(__APPLE__)
0f0c61d0
VZ
21 #pragma implementation "drawing.cpp"
22 #pragma interface "drawing.cpp"
aba99005
RR
23#endif
24
25// For compilers that support precompilation, includes "wx/wx.h".
26#include "wx/wxprec.h"
27
28#ifdef __BORLANDC__
29 #pragma hdrstop
30#endif
31
32// for all others, include the necessary headers (this file is usually all you
33// need because it includes almost all "standard" wxWindows headers
34#ifndef WX_PRECOMP
35 #include "wx/wx.h"
36#endif
37
0f0c61d0 38#include "wx/colordlg.h"
107a1787 39#include "wx/image.h"
389d906b 40#include "wx/artprov.h"
0f0c61d0 41
aba99005
RR
42// ----------------------------------------------------------------------------
43// ressources
44// ----------------------------------------------------------------------------
568708e2 45
aba99005 46// the application icon
a11672a4 47#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__)
aba99005
RR
48 #include "mondrian.xpm"
49#endif
50
568708e2
VZ
51// ----------------------------------------------------------------------------
52// constants
53// ----------------------------------------------------------------------------
54
55// what do we show on screen (there are too many shapes to put them all on
56// screen simultaneously)
57enum ScreenToShow
58{
59 Show_Default,
60 Show_Text,
61 Show_Lines,
6386110d 62 Show_Brushes,
568708e2 63 Show_Polygons,
81278df2 64 Show_Mask,
bc3cedfa 65 Show_Ops,
f6bcfd97
BP
66 Show_Regions,
67 Show_Circles
568708e2
VZ
68};
69
70// ----------------------------------------------------------------------------
71// global variables
72// ----------------------------------------------------------------------------
73
f6bcfd97
BP
74static wxBitmap *gs_bmpNoMask = NULL,
75 *gs_bmpWithColMask = NULL,
76 *gs_bmpMask = NULL,
77 *gs_bmpWithMask = NULL,
78 *gs_bmp4 = NULL,
79 *gs_bmp4_mono = NULL,
80 *gs_bmp36 = NULL;
568708e2 81
aba99005
RR
82// ----------------------------------------------------------------------------
83// private classes
84// ----------------------------------------------------------------------------
85
86// Define a new application type, each program should derive a class from wxApp
87class MyApp : public wxApp
88{
89public:
90 // override base class virtuals
91 // ----------------------------
92
93 // this one is called on application startup and is a good place for the app
94 // initialization (doing it here and not in the ctor allows to have an error
95 // return: if OnInit() returns false, the application terminates)
96 virtual bool OnInit();
568708e2 97
f6bcfd97
BP
98 virtual int OnExit() { DeleteBitmaps(); return 0; }
99
568708e2 100protected:
f6bcfd97
BP
101 void DeleteBitmaps();
102
568708e2 103 bool LoadImages();
aba99005
RR
104};
105
b62c3631
RR
106class MyCanvas;
107
aba99005
RR
108// Define a new frame type: this is going to be our main frame
109class MyFrame : public wxFrame
110{
111public:
112 // ctor(s)
113 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
114
115 // event handlers (these functions should _not_ be virtual)
116 void OnQuit(wxCommandEvent& event);
117 void OnAbout(wxCommandEvent& event);
204dd9a7 118 void OnClip(wxCommandEvent& event);
568708e2 119 void OnShow(wxCommandEvent &event);
aba99005 120 void OnOption(wxCommandEvent &event);
aba99005 121
220af862
VZ
122 wxColour SelectColour();
123 void PrepareDC(wxDC& dc);
0f0c61d0 124
b62c3631 125 int m_backgroundMode;
1edc9f45 126 int m_textureBackground;
b62c3631
RR
127 int m_mapMode;
128 double m_xUserScale;
129 double m_yUserScale;
130 int m_xLogicalOrigin;
131 int m_yLogicalOrigin;
132 bool m_xAxisReversed,
133 m_yAxisReversed;
134 wxColour m_colourForeground, // these are _text_ colours
135 m_colourBackground;
136 wxBrush m_backgroundBrush;
137 MyCanvas *m_canvas;
aba99005
RR
138
139private:
140 // any class wishing to process wxWindows events must use this macro
141 DECLARE_EVENT_TABLE()
142};
143
b62c3631
RR
144// define a scrollable canvas for drawing onto
145class MyCanvas: public wxScrolledWindow
146{
147public:
148 MyCanvas( MyFrame *parent );
1e7fd311 149
b62c3631 150 void OnPaint(wxPaintEvent &event);
bf0c00c6 151 void OnMouseMove(wxMouseEvent &event);
4786aabd 152
dacaa6f1 153 void ToShow(ScreenToShow show) { m_show = show; Refresh(); }
568708e2 154
204dd9a7
VZ
155 // set or remove the clipping region
156 void Clip(bool clip) { m_clip = clip; Refresh(); }
157
b62c3631 158protected:
568708e2 159 void DrawTestLines( int x, int y, int width, wxDC &dc );
6386110d
VZ
160 void DrawTestPoly(wxDC& dc);
161 void DrawTestBrushes(wxDC& dc);
568708e2
VZ
162 void DrawText(wxDC& dc);
163 void DrawImages(wxDC& dc);
81278df2 164 void DrawWithLogicalOps(wxDC& dc);
bc3cedfa 165 void DrawRegions(wxDC& dc);
f6bcfd97 166 void DrawCircles(wxDC& dc);
568708e2 167 void DrawDefault(wxDC& dc);
4786aabd 168
4cbcae16 169 void DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime);
8e0e4b1b 170
b62c3631 171private:
568708e2
VZ
172 MyFrame *m_owner;
173
174 ScreenToShow m_show;
0e09f76e
RR
175 wxBitmap m_smile_bmp;
176 wxIcon m_std_icon;
204dd9a7 177 bool m_clip;
568708e2 178
b62c3631
RR
179 DECLARE_EVENT_TABLE()
180};
181
aba99005
RR
182// ----------------------------------------------------------------------------
183// constants
184// ----------------------------------------------------------------------------
185
186// IDs for the controls and the menu commands
187enum
188{
189 // menu items
568708e2
VZ
190 File_Quit = 1,
191 File_About,
192
193 MenuShow_First,
194 File_ShowDefault = MenuShow_First,
195 File_ShowText,
196 File_ShowLines,
6386110d 197 File_ShowBrushes,
568708e2
VZ
198 File_ShowPolygons,
199 File_ShowMask,
81278df2 200 File_ShowOps,
bc3cedfa 201 File_ShowRegions,
f6bcfd97
BP
202 File_ShowCircles,
203 MenuShow_Last = File_ShowCircles,
0f0c61d0 204
204dd9a7
VZ
205 File_Clip,
206
0f0c61d0
VZ
207 MenuOption_First,
208
209 MapMode_Text = MenuOption_First,
aba99005
RR
210 MapMode_Lometric,
211 MapMode_Twips,
212 MapMode_Points,
213 MapMode_Metric,
0f0c61d0 214
aba99005
RR
215 UserScale_StretchHoriz,
216 UserScale_ShrinkHoriz,
217 UserScale_StretchVertic,
218 UserScale_ShrinkVertic,
0f0c61d0
VZ
219 UserScale_Restore,
220
aba99005
RR
221 AxisMirror_Horiz,
222 AxisMirror_Vertic,
0f0c61d0 223
aba99005
RR
224 LogicalOrigin_MoveDown,
225 LogicalOrigin_MoveUp,
226 LogicalOrigin_MoveLeft,
227 LogicalOrigin_MoveRight,
fb576291
VZ
228 LogicalOrigin_Set,
229 LogicalOrigin_Restore,
0f0c61d0
VZ
230
231 Colour_TextForeground,
232 Colour_TextBackground,
233 Colour_Background,
234 Colour_BackgroundMode,
1edc9f45 235 Colour_TextureBackgound,
0f0c61d0 236
1edc9f45 237 MenuOption_Last = Colour_TextureBackgound
aba99005
RR
238};
239
240// ----------------------------------------------------------------------------
241// event tables and other macros for wxWindows
242// ----------------------------------------------------------------------------
243
aba99005
RR
244
245// Create a new application object: this macro will allow wxWindows to create
246// the application object during program execution (it's better than using a
247// static object for many reasons) and also declares the accessor function
248// wxGetApp() which will return the reference of the right type (i.e. MyApp and
249// not wxApp)
250IMPLEMENT_APP(MyApp)
251
252// ============================================================================
253// implementation
254// ============================================================================
255
256// ----------------------------------------------------------------------------
257// the application class
258// ----------------------------------------------------------------------------
259
568708e2
VZ
260bool MyApp::LoadImages()
261{
f6bcfd97
BP
262 gs_bmpNoMask = new wxBitmap;
263 gs_bmpWithColMask = new wxBitmap;
264 gs_bmpMask = new wxBitmap;
265 gs_bmpWithMask = new wxBitmap;
266 gs_bmp4 = new wxBitmap;
267 gs_bmp4_mono = new wxBitmap;
268 gs_bmp36 = new wxBitmap;
269
568708e2 270 wxPathList pathList;
ab1ca7b3
MB
271 pathList.Add(_T("."));
272 pathList.Add(_T(".."));
568708e2 273
ab1ca7b3 274 wxString path = pathList.FindValidPath(_T("pat4.bmp"));
568708e2
VZ
275 if ( !path )
276 return FALSE;
f6bcfd97 277
e1208c31 278 /* 4 colour bitmap */
f6bcfd97 279 gs_bmp4->LoadFile(path, wxBITMAP_TYPE_BMP);
e1208c31 280 /* turn into mono-bitmap */
f6bcfd97
BP
281 gs_bmp4_mono->LoadFile(path, wxBITMAP_TYPE_BMP);
282 wxMask* mask4 = new wxMask(*gs_bmp4_mono, *wxBLACK);
283 gs_bmp4_mono->SetMask(mask4);
568708e2 284
ab1ca7b3 285 path = pathList.FindValidPath(_T("pat36.bmp"));
568708e2
VZ
286 if ( !path )
287 return FALSE;
f6bcfd97
BP
288 gs_bmp36->LoadFile(path, wxBITMAP_TYPE_BMP);
289 wxMask* mask36 = new wxMask(*gs_bmp36, *wxBLACK);
290 gs_bmp36->SetMask(mask36);
568708e2 291
ab1ca7b3 292 path = pathList.FindValidPath(_T("image.bmp"));
568708e2
VZ
293 if ( !path )
294 return FALSE;
f6bcfd97
BP
295 gs_bmpNoMask->LoadFile(path, wxBITMAP_TYPE_BMP);
296 gs_bmpWithMask->LoadFile(path, wxBITMAP_TYPE_BMP);
297 gs_bmpWithColMask->LoadFile(path, wxBITMAP_TYPE_BMP);
568708e2 298
ab1ca7b3 299 path = pathList.FindValidPath(_T("mask.bmp"));
568708e2
VZ
300 if ( !path )
301 return FALSE;
f6bcfd97 302 gs_bmpMask->LoadFile(path, wxBITMAP_TYPE_BMP);
b9de1315 303
f6bcfd97
BP
304 wxMask *mask = new wxMask(*gs_bmpMask, *wxBLACK);
305 gs_bmpWithMask->SetMask(mask);
568708e2 306
f6bcfd97
BP
307 mask = new wxMask(*gs_bmpWithColMask, *wxWHITE);
308 gs_bmpWithColMask->SetMask(mask);
568708e2
VZ
309
310 return TRUE;
311}
312
aba99005
RR
313// `Main program' equivalent: the program execution "starts" here
314bool MyApp::OnInit()
315{
316 // Create the main application window
ab1ca7b3 317 MyFrame *frame = new MyFrame(_T("Drawing sample"),
b62c3631 318 wxPoint(50, 50), wxSize(550, 340));
aba99005
RR
319
320 // Show it and tell the application that it's our main window
aba99005
RR
321 frame->Show(TRUE);
322 SetTopWindow(frame);
323
568708e2
VZ
324 if ( !LoadImages() )
325 {
4693b20c
MB
326 wxLogError(wxT("Can't load one of the bitmap files needed ")
327 wxT("for this sample from the current or parent ")
328 wxT("directory, please copy them there."));
568708e2
VZ
329
330 // stop here
f6bcfd97
BP
331 DeleteBitmaps();
332
568708e2
VZ
333 return FALSE;
334 }
335
336 // ok, continue
aba99005
RR
337 return TRUE;
338}
339
f6bcfd97
BP
340void MyApp::DeleteBitmaps()
341{
342 delete gs_bmpNoMask;
343 delete gs_bmpWithColMask;
344 delete gs_bmpMask;
345 delete gs_bmpWithMask;
346 delete gs_bmp4;
347 delete gs_bmp4_mono;
348 delete gs_bmp36;
17b898bb
VZ
349
350 gs_bmpNoMask = NULL;
351 gs_bmpWithColMask = NULL;
352 gs_bmpMask = NULL;
353 gs_bmpWithMask = NULL;
354 gs_bmp4 = NULL;
355 gs_bmp4_mono = NULL;
356 gs_bmp36 = NULL;
f6bcfd97
BP
357}
358
aba99005 359// ----------------------------------------------------------------------------
b62c3631 360// MyCanvas
aba99005
RR
361// ----------------------------------------------------------------------------
362
b62c3631
RR
363// the event tables connect the wxWindows events with the functions (event
364// handlers) which process them.
365BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
366 EVT_PAINT (MyCanvas::OnPaint)
bf0c00c6 367 EVT_MOTION (MyCanvas::OnMouseMove)
b62c3631
RR
368END_EVENT_TABLE()
369
c4218a74 370#include "smile.xpm"
0e09f76e 371
c4218a74
VZ
372MyCanvas::MyCanvas(MyFrame *parent)
373 : wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize,
374 wxHSCROLL | wxVSCROLL | wxNO_FULL_REPAINT_ON_RESIZE)
b62c3631 375{
b97fa7cf 376 m_owner = parent;
568708e2 377 m_show = Show_Default;
0e09f76e 378 m_smile_bmp = wxBitmap(smile_xpm);
389d906b 379 m_std_icon = wxArtProvider::GetIcon(wxART_INFORMATION);
3f148eb6 380 m_clip = FALSE;
b97fa7cf
VZ
381}
382
6386110d 383void MyCanvas::DrawTestBrushes(wxDC& dc)
b97fa7cf 384{
6386110d
VZ
385 static const wxCoord WIDTH = 200;
386 static const wxCoord HEIGHT = 80;
387
388 wxCoord x = 10,
389 y = 10;
390
391 dc.SetBrush(wxBrush(*wxGREEN, wxSOLID));
392 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
ab1ca7b3 393 dc.DrawText(_T("Solid green"), x + 10, y + 10);
6386110d
VZ
394
395 y += HEIGHT;
396 dc.SetBrush(wxBrush(*wxRED, wxCROSSDIAG_HATCH));
397 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
ab1ca7b3 398 dc.DrawText(_T("Hatched red"), x + 10, y + 10);
6386110d
VZ
399
400 y += HEIGHT;
401 dc.SetBrush(wxBrush(*gs_bmpMask));
402 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
ab1ca7b3 403 dc.DrawText(_T("Stipple mono"), x + 10, y + 10);
6386110d
VZ
404
405 y += HEIGHT;
406 dc.SetBrush(wxBrush(*gs_bmpNoMask));
407 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
ab1ca7b3 408 dc.DrawText(_T("Stipple colour"), x + 10, y + 10);
6386110d 409}
b97fa7cf 410
6386110d
VZ
411void MyCanvas::DrawTestPoly(wxDC& dc)
412{
413 wxBrush brushHatch(*wxRED, wxFDIAGONAL_HATCH);
414 dc.SetBrush(brushHatch);
415
416 wxPoint star[5];
417 star[0] = wxPoint(100, 60);
418 star[1] = wxPoint(60, 150);
419 star[2] = wxPoint(160, 100);
420 star[3] = wxPoint(40, 100);
421 star[4] = wxPoint(140, 150);
422
ab1ca7b3
MB
423 dc.DrawText(_T("You should see two (irregular) stars below, the left one ")
424 _T("hatched"), 10, 10);
425 dc.DrawText(_T("except for the central region and the right ")
426 _T("one entirely hatched"), 10, 30);
163dc80e
VZ
427 dc.DrawText(_T("The third star only has a hatched outline"), 10, 50);
428
429 dc.DrawPolygon(WXSIZEOF(star), star, 0, 30);
430 dc.DrawPolygon(WXSIZEOF(star), star, 160, 30, wxWINDING_RULE);
431
432 wxPoint star2[10];
433 star2[0] = wxPoint(0, 100);
434 star2[1] = wxPoint(-59, -81);
435 star2[2] = wxPoint(95, 31);
436 star2[3] = wxPoint(-95, 31);
437 star2[4] = wxPoint(59, -81);
438 star2[5] = wxPoint(0, 80);
439 star2[6] = wxPoint(-47, -64);
440 star2[7] = wxPoint(76, 24);
441 star2[8] = wxPoint(-76, 24);
442 star2[9] = wxPoint(47, -64);
443 int count[2] = {5, 5};
444
445 dc.DrawPolyPolygon(WXSIZEOF(count), count, star2, 450, 150);
b62c3631
RR
446}
447
1e7fd311 448void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc )
b62c3631 449{
a60b1f5d 450 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
1e7fd311 451 dc.SetBrush( *wxRED_BRUSH );
4693b20c 452 dc.DrawText(wxString::Format(wxT("Testing lines of width %d"), width), x + 10, y - 10);
9a8c7620 453 dc.DrawRectangle( x+10, y+10, 100, 190 );
4786aabd 454
ab1ca7b3 455 dc.DrawText(_T("Solid/dot/short dash/long dash/dot dash"), x + 150, y + 10);
a60b1f5d 456 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
696e1ea0 457 dc.DrawLine( x+20, y+20, 100, y+20 );
a60b1f5d 458 dc.SetPen( wxPen( wxT("black"), width, wxDOT) );
696e1ea0 459 dc.DrawLine( x+20, y+30, 100, y+30 );
a60b1f5d 460 dc.SetPen( wxPen( wxT("black"), width, wxSHORT_DASH) );
696e1ea0 461 dc.DrawLine( x+20, y+40, 100, y+40 );
a60b1f5d 462 dc.SetPen( wxPen( wxT("black"), width, wxLONG_DASH) );
696e1ea0 463 dc.DrawLine( x+20, y+50, 100, y+50 );
a60b1f5d 464 dc.SetPen( wxPen( wxT("black"), width, wxDOT_DASH) );
696e1ea0 465 dc.DrawLine( x+20, y+60, 100, y+60 );
1e7fd311 466
ab1ca7b3 467 dc.DrawText(_T("Misc hatches"), x + 150, y + 70);
a60b1f5d 468 dc.SetPen( wxPen( wxT("black"), width, wxBDIAGONAL_HATCH) );
696e1ea0 469 dc.DrawLine( x+20, y+70, 100, y+70 );
a60b1f5d 470 dc.SetPen( wxPen( wxT("black"), width, wxCROSSDIAG_HATCH) );
696e1ea0 471 dc.DrawLine( x+20, y+80, 100, y+80 );
a60b1f5d 472 dc.SetPen( wxPen( wxT("black"), width, wxFDIAGONAL_HATCH) );
696e1ea0 473 dc.DrawLine( x+20, y+90, 100, y+90 );
a60b1f5d 474 dc.SetPen( wxPen( wxT("black"), width, wxCROSS_HATCH) );
696e1ea0 475 dc.DrawLine( x+20, y+100, 100, y+100 );
a60b1f5d 476 dc.SetPen( wxPen( wxT("black"), width, wxHORIZONTAL_HATCH) );
696e1ea0 477 dc.DrawLine( x+20, y+110, 100, y+110 );
a60b1f5d 478 dc.SetPen( wxPen( wxT("black"), width, wxVERTICAL_HATCH) );
696e1ea0 479 dc.DrawLine( x+20, y+120, 100, y+120 );
1e7fd311 480
ab1ca7b3 481 dc.DrawText(_T("User dash"), x + 150, y + 140);
a60b1f5d 482 wxPen ud( wxT("black"), width, wxUSER_DASH );
e2a5251d
VZ
483 wxDash dash1[6];
484 dash1[0] = 8; // Long dash <---------+
485 dash1[1] = 2; // Short gap |
486 dash1[2] = 3; // Short dash |
487 dash1[3] = 2; // Short gap |
488 dash1[4] = 3; // Short dash |
489 dash1[5] = 2; // Short gap and repeat +
490 ud.SetDashes( 6, dash1 );
491 dc.SetPen( ud );
696e1ea0 492 dc.DrawLine( x+20, y+140, 100, y+140 );
e2a5251d
VZ
493 dash1[0] = 5; // Make first dash shorter
494 ud.SetDashes( 6, dash1 );
495 dc.SetPen( ud );
696e1ea0 496 dc.DrawLine( x+20, y+150, 100, y+150 );
e2a5251d
VZ
497 dash1[2] = 5; // Make second dash longer
498 ud.SetDashes( 6, dash1 );
499 dc.SetPen( ud );
696e1ea0 500 dc.DrawLine( x+20, y+160, 100, y+160 );
e2a5251d
VZ
501 dash1[4] = 5; // Make third dash longer
502 ud.SetDashes( 6, dash1 );
503 dc.SetPen( ud );
696e1ea0 504 dc.DrawLine( x+20, y+170, 100, y+170 );
b62c3631
RR
505}
506
568708e2 507void MyCanvas::DrawDefault(wxDC& dc)
b62c3631 508{
b62c3631
RR
509 // mark the origin
510 dc.DrawCircle(0, 0, 10);
f88c1a17
JS
511
512 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
513 dc.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID));
514 wxColour tmpColour ;
515 dc.GetPixel(1,1, &tmpColour);
516 dc.FloodFill(1,1, tmpColour, wxFLOOD_SURFACE);
b62c3631 517
cd9da200
VZ
518 dc.DrawCheckMark(5, 80, 15, 15);
519 dc.DrawCheckMark(25, 80, 30, 30);
520 dc.DrawCheckMark(60, 80, 60, 60);
521
0e09f76e 522 // this is the test for "blitting bitmap into DC damages selected brush" bug
0e09f76e 523 wxCoord rectSize = m_std_icon.GetWidth() + 10;
cd9da200 524 wxCoord x = 100;
11f26ea0
VZ
525 dc.SetPen(*wxTRANSPARENT_PEN);
526 dc.SetBrush( *wxGREEN_BRUSH );
cd9da200 527 dc.DrawRectangle(x, 10, rectSize, rectSize);
0e09f76e 528 dc.DrawBitmap(m_std_icon, x + 5, 15, TRUE);
cd9da200
VZ
529 x += rectSize + 10;
530 dc.DrawRectangle(x, 10, rectSize, rectSize);
0e09f76e 531 dc.DrawIcon(m_std_icon, x + 5, 15);
cd9da200
VZ
532 x += rectSize + 10;
533 dc.DrawRectangle(x, 10, rectSize, rectSize);
11f26ea0
VZ
534
535 // test for "transparent" bitmap drawing (it intersects with the last
536 // rectangle above)
537 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
d6f0a4b3 538
0e09f76e
RR
539 if (m_smile_bmp.Ok())
540 dc.DrawBitmap(m_smile_bmp, x + rectSize - 20, rectSize - 10, TRUE);
107a1787 541
ff7c6c9c 542 dc.SetBrush( *wxBLACK_BRUSH );
107a1787
RR
543 dc.DrawRectangle( 0, 160, 1000, 300 );
544
545 // draw lines
546 wxBitmap bitmap(20,70);
547 wxMemoryDC memdc;
548 memdc.SelectObject( bitmap );
549 memdc.SetBrush( *wxBLACK_BRUSH );
550 memdc.SetPen( *wxWHITE_PEN );
551 memdc.DrawRectangle(0,0,20,70);
552 memdc.DrawLine( 10,0,10,70 );
81278df2 553
d4aa3a4b 554 // to the right
4c45f240 555 wxPen pen = *wxRED_PEN;
4c45f240 556 memdc.SetPen(pen);
107a1787
RR
557 memdc.DrawLine( 10, 5,10, 5 );
558 memdc.DrawLine( 10,10,11,10 );
559 memdc.DrawLine( 10,15,12,15 );
560 memdc.DrawLine( 10,20,13,20 );
81278df2 561
d4aa3a4b
RR
562/*
563 memdc.SetPen(*wxRED_PEN);
107a1787
RR
564 memdc.DrawLine( 12, 5,12, 5 );
565 memdc.DrawLine( 12,10,13,10 );
566 memdc.DrawLine( 12,15,14,15 );
567 memdc.DrawLine( 12,20,15,20 );
d4aa3a4b 568*/
81278df2 569
107a1787
RR
570 // same to the left
571 memdc.DrawLine( 10,25,10,25 );
572 memdc.DrawLine( 10,30, 9,30 );
573 memdc.DrawLine( 10,35, 8,35 );
574 memdc.DrawLine( 10,40, 7,40 );
575
576 // XOR draw lines
d4aa3a4b 577 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
578 memdc.SetLogicalFunction( wxINVERT );
579 memdc.SetPen( *wxWHITE_PEN );
580 memdc.DrawLine( 10,50,10,50 );
581 memdc.DrawLine( 10,55,11,55 );
582 memdc.DrawLine( 10,60,12,60 );
583 memdc.DrawLine( 10,65,13,65 );
81278df2 584
107a1787
RR
585 memdc.DrawLine( 12,50,12,50 );
586 memdc.DrawLine( 12,55,13,55 );
587 memdc.DrawLine( 12,60,14,60 );
588 memdc.DrawLine( 12,65,15,65 );
81278df2 589
107a1787
RR
590 memdc.SelectObject( wxNullBitmap );
591 dc.DrawBitmap( bitmap, 10, 170 );
389d906b 592 wxImage image = bitmap.ConvertToImage();
107a1787 593 image.Rescale( 60,210 );
389d906b 594 bitmap = wxBitmap(image);
107a1787 595 dc.DrawBitmap( bitmap, 50, 170 );
81278df2 596
b9de1315 597 // test the rectangle outline drawing - there should be one pixel between
ff7c6c9c
RR
598 // the rect and the lines
599 dc.SetPen(*wxWHITE_PEN);
600 dc.SetBrush( *wxTRANSPARENT_BRUSH );
ff7c6c9c 601 dc.DrawRectangle(150, 170, 49, 29);
107a1787 602 dc.DrawRectangle(200, 170, 49, 29);
ff7c6c9c 603 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
604 dc.DrawLine(250, 210, 250, 170);
605 dc.DrawLine(260, 200, 150, 200);
b9de1315
VZ
606
607 // test the rectangle filled drawing - there should be one pixel between
ff7c6c9c
RR
608 // the rect and the lines
609 dc.SetPen(*wxTRANSPARENT_PEN);
610 dc.SetBrush( *wxWHITE_BRUSH );
611 dc.DrawRectangle(300, 170, 49, 29);
568708e2 612 dc.DrawRectangle(350, 170, 49, 29);
ff7c6c9c 613 dc.SetPen(*wxWHITE_PEN);
b9de1315
VZ
614 dc.DrawLine(400, 170, 400, 210);
615 dc.DrawLine(300, 200, 410, 200);
616
3d2d8da1
RR
617 // a few more tests of this kind
618 dc.SetPen(*wxRED_PEN);
619 dc.SetBrush( *wxWHITE_BRUSH );
620 dc.DrawRectangle(300, 220, 1, 1);
621 dc.DrawRectangle(310, 220, 2, 2);
622 dc.DrawRectangle(320, 220, 3, 3);
623 dc.DrawRectangle(330, 220, 4, 4);
624
625 dc.SetPen(*wxTRANSPARENT_PEN);
626 dc.SetBrush( *wxWHITE_BRUSH );
627 dc.DrawRectangle(300, 230, 1, 1);
628 dc.DrawRectangle(310, 230, 2, 2);
629 dc.DrawRectangle(320, 230, 3, 3);
630 dc.DrawRectangle(330, 230, 4, 4);
631
b9de1315
VZ
632 // and now for filled rect with outline
633 dc.SetPen(*wxRED_PEN);
634 dc.SetBrush( *wxWHITE_BRUSH );
635 dc.DrawRectangle(500, 170, 49, 29);
636 dc.DrawRectangle(550, 170, 49, 29);
637 dc.SetPen(*wxWHITE_PEN);
638 dc.DrawLine(600, 170, 600, 210);
639 dc.DrawLine(500, 200, 610, 200);
640
641 // test the rectangle outline drawing - there should be one pixel between
ff7c6c9c
RR
642 // the rect and the lines
643 dc.SetPen(*wxWHITE_PEN);
644 dc.SetBrush( *wxTRANSPARENT_BRUSH );
ff7c6c9c 645 dc.DrawRoundedRectangle(150, 270, 49, 29, 6);
107a1787 646 dc.DrawRoundedRectangle(200, 270, 49, 29, 6);
ff7c6c9c 647 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
648 dc.DrawLine(250, 270, 250, 310);
649 dc.DrawLine(150, 300, 260, 300);
b9de1315
VZ
650
651 // test the rectangle filled drawing - there should be one pixel between
ff7c6c9c
RR
652 // the rect and the lines
653 dc.SetPen(*wxTRANSPARENT_PEN);
654 dc.SetBrush( *wxWHITE_BRUSH );
655 dc.DrawRoundedRectangle(300, 270, 49, 29, 6);
656 dc.DrawRoundedRectangle(350, 270, 49, 29, 6);
657 dc.SetPen(*wxWHITE_PEN);
b9de1315
VZ
658 dc.DrawLine(400, 270, 400, 310);
659 dc.DrawLine(300, 300, 410, 300);
ff7c6c9c 660
b14c14ff
JS
661 // Added by JACS to demonstrate bizarre behaviour.
662 // With a size of 70, we get a missing red RHS,
663 // and the hight is too small, so we get yellow
664 // showing. With a size of 40, it draws as expected:
665 // it just shows a white rectangle with red outline.
666 int totalWidth = 70;
667 int totalHeight = 70;
668 wxBitmap bitmap2(totalWidth, totalHeight);
669
670 wxMemoryDC memdc2;
671 memdc2.SelectObject(bitmap2);
672
d6f0a4b3
JS
673 wxBrush yellowBrush(wxColour(255, 255, 0), wxSOLID);
674 memdc2.SetBackground(yellowBrush);
675 memdc2.Clear();
b14c14ff 676
d6f0a4b3 677 wxPen yellowPen(wxColour(255, 255, 0), 1, wxSOLID);
b14c14ff
JS
678
679 // Now draw a white rectangle with red outline. It should
680 // entirely eclipse the yellow background.
681 memdc2.SetPen(*wxRED_PEN);
682 memdc2.SetBrush(*wxWHITE_BRUSH);
683
684 memdc2.DrawRectangle(0, 0, totalWidth, totalHeight);
685
b14c14ff
JS
686 memdc2.SetPen(wxNullPen);
687 memdc2.SetBrush(wxNullBrush);
cd9da200 688 memdc2.SelectObject(wxNullBitmap);
b14c14ff
JS
689
690 dc.DrawBitmap(bitmap2, 500, 270);
d6f0a4b3
JS
691
692 // Repeat, but draw directly on dc
693 // Draw a yellow rectangle filling the bitmap
694
695 x = 600; int y = 270;
696 dc.SetPen(yellowPen);
697 dc.SetBrush(yellowBrush);
698 dc.DrawRectangle(x, y, totalWidth, totalHeight);
699
700 // Now draw a white rectangle with red outline. It should
701 // entirely eclipse the yellow background.
702 dc.SetPen(*wxRED_PEN);
703 dc.SetBrush(*wxWHITE_BRUSH);
704
705 dc.DrawRectangle(x, y, totalWidth, totalHeight);
568708e2
VZ
706}
707
708void MyCanvas::DrawText(wxDC& dc)
709{
9a8c7620
VZ
710 // set underlined font for testing
711 dc.SetFont( wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, TRUE) );
ab1ca7b3
MB
712 dc.DrawText( _T("This is text"), 110, 10 );
713 dc.DrawRotatedText( _T("That is text"), 20, 10, -45 );
9a8c7620 714
4770df95
VZ
715 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
716 // under Win9x (it is not TrueType)
717 dc.SetFont( *wxSWISS_FONT );
b62c3631 718
696e1ea0 719 wxString text;
f6bcfd97 720 dc.SetBackgroundMode(wxTRANSPARENT);
696e1ea0
VZ
721
722 for ( int n = -180; n < 180; n += 30 )
723 {
4693b20c 724 text.Printf(wxT(" %d rotated text"), n);
696e1ea0
VZ
725 dc.DrawRotatedText(text , 400, 400, n);
726 }
95724b1a 727
196c87f4 728 dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) );
c45a644e 729
ab1ca7b3 730 dc.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
c45a644e
RR
731
732 long length;
733 long height;
734 long descent;
ab1ca7b3 735 dc.GetTextExtent( _T("This is Swiss 18pt text."), &length, &height, &descent );
4693b20c 736 text.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length, height, descent );
c45a644e
RR
737 dc.DrawText( text, 110, 80 );
738
4693b20c 739 text.Printf( wxT("CharHeight() returns: %d"), dc.GetCharHeight() );
c45a644e
RR
740 dc.DrawText( text, 110, 120 );
741
568708e2 742 dc.DrawRectangle( 100, 40, 4, height );
f6bcfd97
BP
743
744 // test the logical function effect
745 wxCoord y = 150;
746 dc.SetLogicalFunction(wxINVERT);
ab1ca7b3 747 dc.DrawText( _T("There should be no text below"), 110, 150 );
f6bcfd97
BP
748 dc.DrawRectangle( 110, y, 100, height );
749
750 // twice drawn inverted should result in invisible
751 y += height;
ab1ca7b3 752 dc.DrawText( _T("Invisible text"), 110, y );
f6bcfd97 753 dc.DrawRectangle( 110, y, 100, height );
ab1ca7b3 754 dc.DrawText( _T("Invisible text"), 110, y );
f6bcfd97
BP
755 dc.DrawRectangle( 110, y, 100, height );
756 dc.SetLogicalFunction(wxCOPY);
757
758 y += height;
759 dc.DrawRectangle( 110, y, 100, height );
ab1ca7b3 760 dc.DrawText( _T("Visible text"), 110, y );
568708e2
VZ
761}
762
81278df2 763static const struct
568708e2 764{
81278df2
VZ
765 const wxChar *name;
766 int rop;
767} rasterOperations[] =
768{
4693b20c
MB
769 { wxT("wxAND"), wxAND },
770 { wxT("wxAND_INVERT"), wxAND_INVERT },
771 { wxT("wxAND_REVERSE"), wxAND_REVERSE },
772 { wxT("wxCLEAR"), wxCLEAR },
773 { wxT("wxCOPY"), wxCOPY },
774 { wxT("wxEQUIV"), wxEQUIV },
775 { wxT("wxINVERT"), wxINVERT },
776 { wxT("wxNAND"), wxNAND },
777 { wxT("wxNO_OP"), wxNO_OP },
778 { wxT("wxOR"), wxOR },
779 { wxT("wxOR_INVERT"), wxOR_INVERT },
780 { wxT("wxOR_REVERSE"), wxOR_REVERSE },
781 { wxT("wxSET"), wxSET },
782 { wxT("wxSRC_INVERT"), wxSRC_INVERT },
783 { wxT("wxXOR"), wxXOR },
81278df2 784};
568708e2 785
81278df2
VZ
786void MyCanvas::DrawImages(wxDC& dc)
787{
ab1ca7b3 788 dc.DrawText(_T("original image"), 0, 0);
f6bcfd97 789 dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0);
ab1ca7b3 790 dc.DrawText(_T("with colour mask"), 0, 100);
f6bcfd97 791 dc.DrawBitmap(*gs_bmpWithColMask, 0, 120, TRUE);
ab1ca7b3 792 dc.DrawText(_T("the mask image"), 0, 200);
f6bcfd97 793 dc.DrawBitmap(*gs_bmpMask, 0, 220, 0);
ab1ca7b3 794 dc.DrawText(_T("masked image"), 0, 300);
f6bcfd97 795 dc.DrawBitmap(*gs_bmpWithMask, 0, 320, TRUE);
568708e2 796
f6bcfd97
BP
797 int cx = gs_bmpWithColMask->GetWidth(),
798 cy = gs_bmpWithColMask->GetHeight();
568708e2
VZ
799
800 wxMemoryDC memDC;
801 for ( size_t n = 0; n < WXSIZEOF(rasterOperations); n++ )
802 {
803 wxCoord x = 120 + 150*(n%4),
804 y = 20 + 100*(n/4);
4786aabd 805
568708e2 806 dc.DrawText(rasterOperations[n].name, x, y - 20);
f6bcfd97 807 memDC.SelectObject(*gs_bmpWithColMask);
568708e2
VZ
808 dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, TRUE);
809 }
810}
811
81278df2
VZ
812void MyCanvas::DrawWithLogicalOps(wxDC& dc)
813{
814 static const wxCoord w = 60;
815 static const wxCoord h = 60;
816
817 // reuse the text colour here
818 dc.SetPen(wxPen(m_owner->m_colourForeground, 1, wxSOLID));
11f26ea0 819 dc.SetBrush(*wxTRANSPARENT_BRUSH);
81278df2 820
5888ef1e
VZ
821 size_t n;
822 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
81278df2
VZ
823 {
824 wxCoord x = 20 + 150*(n%4),
825 y = 20 + 100*(n/4);
826
827 dc.DrawText(rasterOperations[n].name, x, y - 20);
828 dc.SetLogicalFunction(rasterOperations[n].rop);
11f26ea0 829 dc.DrawRectangle(x, y, w, h);
81278df2
VZ
830 dc.DrawLine(x, y, x + w, y + h);
831 dc.DrawLine(x + w, y, x, y + h);
832 }
c1d139da
GRG
833
834 // now some filled rectangles
835 dc.SetBrush(wxBrush(m_owner->m_colourForeground, wxSOLID));
836
5888ef1e 837 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
c1d139da
GRG
838 {
839 wxCoord x = 20 + 150*(n%4),
840 y = 500 + 100*(n/4);
841
842 dc.DrawText(rasterOperations[n].name, x, y - 20);
843 dc.SetLogicalFunction(rasterOperations[n].rop);
844 dc.DrawRectangle(x, y, w, h);
845 }
81278df2
VZ
846}
847
f6bcfd97
BP
848void MyCanvas::DrawCircles(wxDC& dc)
849{
850 int x = 100,
851 y = 100,
852 r = 20;
853
ab1ca7b3 854 dc.DrawText(_T("Some circles"), 0, y);
f6bcfd97
BP
855 dc.DrawCircle(x, y, r);
856 dc.DrawCircle(x + 2*r, y, r);
857 dc.DrawCircle(x + 4*r, y, r);
858
859 y += 2*r;
ab1ca7b3 860 dc.DrawText(_T("And ellipses"), 0, y);
f6bcfd97
BP
861 dc.DrawEllipse(x - r, y, 2*r, r);
862 dc.DrawEllipse(x + r, y, 2*r, r);
863 dc.DrawEllipse(x + 3*r, y, 2*r, r);
864
865 y += 2*r;
ab1ca7b3 866 dc.DrawText(_T("And arcs"), 0, y);
f6bcfd97
BP
867 dc.DrawArc(x - r, y, x + r, y, x, y);
868 dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y);
869 dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y);
870
871 y += 2*r;
872 dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90);
873 dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
874 dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
875 dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
876}
877
bc3cedfa
RR
878void MyCanvas::DrawRegions(wxDC& dc)
879{
ab1ca7b3
MB
880 dc.DrawText(_T("You should see a red rect partly covered by a cyan one ")
881 _T("on the left"), 10, 5);
882 dc.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
8e0e4b1b 883 10, 5 + dc.GetCharHeight());
ab1ca7b3
MB
884 dc.DrawText(_T("The second copy should be identical but right part of it ")
885 _T("should be offset by 10 pixels."),
4cbcae16 886 10, 5 + 2*dc.GetCharHeight());
8e0e4b1b 887
4cbcae16
VZ
888 DrawRegionsHelper(dc, 10, TRUE);
889 DrawRegionsHelper(dc, 350, FALSE);
8e0e4b1b 890}
c4218a74 891
4cbcae16 892void MyCanvas::DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime)
8e0e4b1b 893{
4cbcae16
VZ
894 wxCoord y = 100;
895
8e0e4b1b 896 dc.DestroyClippingRegion();
bc3cedfa
RR
897 dc.SetBrush( *wxWHITE_BRUSH );
898 dc.SetPen( *wxTRANSPARENT_PEN );
4cbcae16 899 dc.DrawRectangle( x, y, 310, 310 );
c4218a74 900
4cbcae16 901 dc.SetClippingRegion( x + 10, y + 10, 100, 270 );
c4218a74 902
bc3cedfa 903 dc.SetBrush( *wxRED_BRUSH );
4cbcae16 904 dc.DrawRectangle( x, y, 310, 310 );
c4218a74 905
4cbcae16 906 dc.SetClippingRegion( x + 10, y + 10, 100, 100 );
993f97ee 907
993f97ee 908 dc.SetBrush( *wxCYAN_BRUSH );
4cbcae16
VZ
909 dc.DrawRectangle( x, y, 310, 310 );
910
911 dc.DestroyClippingRegion();
912
913 wxRegion region(x + 110, y + 20, 100, 270);
13a2eea0 914#if !defined(__WXMOTIF__) && !defined(__WXMAC__)
4cbcae16
VZ
915 if ( !firstTime )
916 region.Offset(10, 10);
4cae9a20 917#endif
4cbcae16 918 dc.SetClippingRegion(region);
c4218a74 919
bc3cedfa 920 dc.SetBrush( *wxGREY_BRUSH );
4cbcae16 921 dc.DrawRectangle( x, y, 310, 310 );
c4218a74 922
5d25c050
RR
923 if (m_smile_bmp.Ok())
924 {
4cbcae16
VZ
925 dc.DrawBitmap( m_smile_bmp, x + 150, y + 150, TRUE );
926 dc.DrawBitmap( m_smile_bmp, x + 130, y + 10, TRUE );
927 dc.DrawBitmap( m_smile_bmp, x + 130, y + 280, TRUE );
928 dc.DrawBitmap( m_smile_bmp, x + 100, y + 70, TRUE );
929 dc.DrawBitmap( m_smile_bmp, x + 200, y + 70, TRUE );
5d25c050 930 }
bc3cedfa
RR
931}
932
568708e2
VZ
933void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
934{
935 wxPaintDC dc(this);
936 PrepareDC(dc);
c4218a74 937
568708e2
VZ
938 m_owner->PrepareDC(dc);
939
940 dc.SetBackgroundMode( m_owner->m_backgroundMode );
941 if ( m_owner->m_backgroundBrush.Ok() )
942 dc.SetBackground( m_owner->m_backgroundBrush );
943 if ( m_owner->m_colourForeground.Ok() )
944 dc.SetTextForeground( m_owner->m_colourForeground );
945 if ( m_owner->m_colourBackground.Ok() )
946 dc.SetTextBackground( m_owner->m_colourBackground );
4786aabd 947
1edc9f45 948 if ( m_owner->m_textureBackground) {
047473c9 949 if ( ! m_owner->m_backgroundBrush.Ok() ) {
1edc9f45
RD
950 wxBrush b(wxColour(0,128,0), wxSOLID);
951 dc.SetBackground(b);
952 }
047473c9
RD
953 }
954
204dd9a7
VZ
955 if ( m_clip )
956 dc.SetClippingRegion(100, 100, 100, 100);
957
e1208c31 958 dc.Clear();
1edc9f45 959
204dd9a7
VZ
960 if ( m_owner->m_textureBackground )
961 {
1edc9f45 962 dc.SetPen(*wxMEDIUM_GREY_PEN);
204dd9a7 963 for ( int i = 0; i < 200; i++ )
1edc9f45
RD
964 dc.DrawLine(0, i*10, i*10, 0);
965 }
966
568708e2
VZ
967 switch ( m_show )
968 {
969 case Show_Default:
970 DrawDefault(dc);
971 break;
1e7fd311 972
f6bcfd97
BP
973 case Show_Circles:
974 DrawCircles(dc);
975 break;
976
bc3cedfa
RR
977 case Show_Regions:
978 DrawRegions(dc);
979 break;
980
568708e2
VZ
981 case Show_Text:
982 DrawText(dc);
983 break;
1e7fd311 984
568708e2
VZ
985 case Show_Lines:
986 DrawTestLines( 0, 100, 0, dc );
f6bcfd97
BP
987 DrawTestLines( 0, 320, 1, dc );
988 DrawTestLines( 0, 540, 2, dc );
989 DrawTestLines( 0, 760, 6, dc );
568708e2 990 break;
1e7fd311 991
6386110d
VZ
992 case Show_Brushes:
993 DrawTestBrushes(dc);
994 break;
995
568708e2 996 case Show_Polygons:
6386110d 997 DrawTestPoly(dc);
568708e2 998 break;
1e7fd311 999
568708e2
VZ
1000 case Show_Mask:
1001 DrawImages(dc);
1002 break;
81278df2
VZ
1003
1004 case Show_Ops:
1005 DrawWithLogicalOps(dc);
1006 break;
568708e2 1007 }
b62c3631
RR
1008}
1009
bf0c00c6
RR
1010void MyCanvas::OnMouseMove(wxMouseEvent &event)
1011{
1012 wxClientDC dc(this);
1013 PrepareDC(dc);
1014 m_owner->PrepareDC(dc);
1015
1016 wxPoint pos = event.GetPosition();
1017 long x = dc.DeviceToLogicalX( pos.x );
1018 long y = dc.DeviceToLogicalY( pos.y );
1019 wxString str;
4693b20c 1020 str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y );
bf0c00c6
RR
1021 m_owner->SetStatusText( str );
1022}
1023
b62c3631
RR
1024// ----------------------------------------------------------------------------
1025// MyFrame
1026// ----------------------------------------------------------------------------
1027
1028// the event tables connect the wxWindows events with the functions (event
1029// handlers) which process them. It can be also done at run-time, but for the
1030// simple menu events like this the static method is much simpler.
1031BEGIN_EVENT_TABLE(MyFrame, wxFrame)
568708e2
VZ
1032 EVT_MENU (File_Quit, MyFrame::OnQuit)
1033 EVT_MENU (File_About, MyFrame::OnAbout)
204dd9a7 1034 EVT_MENU (File_Clip, MyFrame::OnClip)
568708e2
VZ
1035
1036 EVT_MENU_RANGE(MenuShow_First, MenuShow_Last, MyFrame::OnShow)
1037
b62c3631
RR
1038 EVT_MENU_RANGE(MenuOption_First, MenuOption_Last, MyFrame::OnOption)
1039END_EVENT_TABLE()
1040
aba99005
RR
1041// frame constructor
1042MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
c4218a74
VZ
1043 : wxFrame((wxFrame *)NULL, -1, title, pos, size,
1044 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
aba99005
RR
1045{
1046 // set the frame icon
1047 SetIcon(wxICON(mondrian));
1048
1049 wxMenu *menuFile = new wxMenu;
ab1ca7b3
MB
1050 menuFile->Append(File_ShowDefault, _T("&Default screen\tF1"));
1051 menuFile->Append(File_ShowText, _T("&Text screen\tF2"));
1052 menuFile->Append(File_ShowLines, _T("&Lines screen\tF3"));
1053 menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4"));
1054 menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5"));
1055 menuFile->Append(File_ShowMask, _T("&Mask screen\tF6"));
1056 menuFile->Append(File_ShowOps, _T("&ROP screen\tF7"));
1057 menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8"));
1058 menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9"));
568708e2 1059 menuFile->AppendSeparator();
ab1ca7b3 1060 menuFile->AppendCheckItem(File_Clip, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
204dd9a7 1061 menuFile->AppendSeparator();
ab1ca7b3 1062 menuFile->Append(File_About, _T("&About...\tCtrl-A"), _T("Show about dialog"));
aba99005 1063 menuFile->AppendSeparator();
ab1ca7b3 1064 menuFile->Append(File_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
0f0c61d0 1065
aba99005 1066 wxMenu *menuMapMode = new wxMenu;
ab1ca7b3
MB
1067 menuMapMode->Append( MapMode_Text, _T("&TEXT map mode") );
1068 menuMapMode->Append( MapMode_Lometric, _T("&LOMETRIC map mode") );
1069 menuMapMode->Append( MapMode_Twips, _T("T&WIPS map mode") );
1070 menuMapMode->Append( MapMode_Points, _T("&POINTS map mode") );
1071 menuMapMode->Append( MapMode_Metric, _T("&METRIC map mode") );
0f0c61d0 1072
aba99005 1073 wxMenu *menuUserScale = new wxMenu;
ab1ca7b3
MB
1074 menuUserScale->Append( UserScale_StretchHoriz, _T("Stretch &horizontally\tCtrl-H") );
1075 menuUserScale->Append( UserScale_ShrinkHoriz, _T("Shrin&k horizontally\tCtrl-G") );
1076 menuUserScale->Append( UserScale_StretchVertic, _T("Stretch &vertically\tCtrl-V") );
1077 menuUserScale->Append( UserScale_ShrinkVertic, _T("&Shrink vertically\tCtrl-W") );
0f0c61d0 1078 menuUserScale->AppendSeparator();
ab1ca7b3 1079 menuUserScale->Append( UserScale_Restore, _T("&Restore to normal\tCtrl-0") );
0f0c61d0 1080
aba99005 1081 wxMenu *menuAxis = new wxMenu;
ab1ca7b3
MB
1082 menuAxis->Append( AxisMirror_Horiz, _T("Mirror horizontally\tCtrl-M"), _T(""), TRUE );
1083 menuAxis->Append( AxisMirror_Vertic, _T("Mirror vertically\tCtrl-N"), _T(""), TRUE );
0f0c61d0 1084
aba99005 1085 wxMenu *menuLogical = new wxMenu;
ab1ca7b3
MB
1086 menuLogical->Append( LogicalOrigin_MoveDown, _T("Move &down\tCtrl-D") );
1087 menuLogical->Append( LogicalOrigin_MoveUp, _T("Move &up\tCtrl-U") );
1088 menuLogical->Append( LogicalOrigin_MoveLeft, _T("Move &right\tCtrl-L") );
1089 menuLogical->Append( LogicalOrigin_MoveRight, _T("Move &left\tCtrl-R") );
fb576291 1090 menuLogical->AppendSeparator();
ab1ca7b3
MB
1091 menuLogical->Append( LogicalOrigin_Set, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1092 menuLogical->Append( LogicalOrigin_Restore, _T("&Restore to normal\tShift-Ctrl-0") );
aba99005 1093
0f0c61d0 1094 wxMenu *menuColour = new wxMenu;
ab1ca7b3
MB
1095 menuColour->Append( Colour_TextForeground, _T("Text &foreground...") );
1096 menuColour->Append( Colour_TextBackground, _T("Text &background...") );
1097 menuColour->Append( Colour_Background, _T("Background &colour...") );
1098 menuColour->Append( Colour_BackgroundMode, _T("&Opaque/transparent\tCtrl-B"), _T(""), TRUE );
1099 menuColour->Append( Colour_TextureBackgound, _T("Draw textured back&ground\tCtrl-T"), _T(""), TRUE);
0f0c61d0 1100
aba99005
RR
1101 // now append the freshly created menu to the menu bar...
1102 wxMenuBar *menuBar = new wxMenuBar;
ab1ca7b3
MB
1103 menuBar->Append(menuFile, _T("&File"));
1104 menuBar->Append(menuMapMode, _T("&Mode"));
1105 menuBar->Append(menuUserScale, _T("&Scale"));
1106 menuBar->Append(menuAxis, _T("&Axis"));
1107 menuBar->Append(menuLogical, _T("&Origin"));
1108 menuBar->Append(menuColour, _T("&Colours"));
aba99005
RR
1109
1110 // ... and attach this menu bar to the frame
1111 SetMenuBar(menuBar);
1112
1113 // create a status bar just for fun (by default with 1 pane only)
1114 CreateStatusBar(2);
ab1ca7b3 1115 SetStatusText(_T("Welcome to wxWindows!"));
0f0c61d0 1116
aba99005
RR
1117 m_mapMode = wxMM_TEXT;
1118 m_xUserScale = 1.0;
1119 m_yUserScale = 1.0;
1120 m_xLogicalOrigin = 0;
1121 m_yLogicalOrigin = 0;
0f0c61d0
VZ
1122 m_xAxisReversed =
1123 m_yAxisReversed = FALSE;
1124 m_backgroundMode = wxSOLID;
b97fa7cf
VZ
1125 m_colourForeground = *wxRED;
1126 m_colourBackground = *wxBLUE;
1edc9f45 1127 m_textureBackground = FALSE;
aba99005 1128
b62c3631 1129 m_canvas = new MyCanvas( this );
b97fa7cf 1130 m_canvas->SetScrollbars( 10, 10, 100, 240 );
b62c3631 1131}
aba99005
RR
1132
1133// event handlers
1134
1135void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1136{
1137 // TRUE is to force the frame to close
1138 Close(TRUE);
1139}
1140
1141void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1142{
1143 wxString msg;
c916e13b
RR
1144 msg.Printf( wxT("This is the about dialog of the drawing sample.\n")
1145 wxT("This sample tests various primitive drawing functions\n")
6386110d 1146 wxT("(without any attempts to prevent flicker).\n")
c916e13b 1147 wxT("Copyright (c) Robert Roebling 1999")
aba99005
RR
1148 );
1149
ab1ca7b3 1150 wxMessageBox(msg, _T("About Drawing"), wxOK | wxICON_INFORMATION, this);
aba99005
RR
1151}
1152
204dd9a7
VZ
1153void MyFrame::OnClip(wxCommandEvent& event)
1154{
1155 m_canvas->Clip(event.IsChecked());
1156}
1157
568708e2
VZ
1158void MyFrame::OnShow(wxCommandEvent& event)
1159{
dacaa6f1 1160 m_canvas->ToShow((ScreenToShow)(event.GetId() - MenuShow_First));
568708e2
VZ
1161}
1162
1163void MyFrame::OnOption(wxCommandEvent& event)
aba99005 1164{
3ca6a5f0 1165 switch (event.GetId())
aba99005
RR
1166 {
1167 case MapMode_Text:
b9857632 1168 m_mapMode = wxMM_TEXT;
0f0c61d0 1169 break;
aba99005
RR
1170 case MapMode_Lometric:
1171 m_mapMode = wxMM_LOMETRIC;
0f0c61d0
VZ
1172 break;
1173 case MapMode_Twips:
aba99005 1174 m_mapMode = wxMM_TWIPS;
0f0c61d0
VZ
1175 break;
1176 case MapMode_Points:
aba99005 1177 m_mapMode = wxMM_POINTS;
0f0c61d0
VZ
1178 break;
1179 case MapMode_Metric:
aba99005 1180 m_mapMode = wxMM_METRIC;
0f0c61d0
VZ
1181 break;
1182
1183 case LogicalOrigin_MoveDown:
1184 m_yLogicalOrigin += 10;
1185 break;
1186 case LogicalOrigin_MoveUp:
1187 m_yLogicalOrigin -= 10;
1188 break;
1189 case LogicalOrigin_MoveLeft:
1190 m_xLogicalOrigin += 10;
1191 break;
1192 case LogicalOrigin_MoveRight:
1193 m_xLogicalOrigin -= 10;
1194 break;
fb576291
VZ
1195 case LogicalOrigin_Set:
1196 m_xLogicalOrigin =
1197 m_yLogicalOrigin = -100;
1198 break;
1199 case LogicalOrigin_Restore:
1200 m_xLogicalOrigin =
1201 m_yLogicalOrigin = 0;
1202 break;
0f0c61d0
VZ
1203
1204 case UserScale_StretchHoriz:
1205 m_xUserScale *= 1.10;
1206 break;
1207 case UserScale_ShrinkHoriz:
1208 m_xUserScale /= 1.10;
1209 break;
1210 case UserScale_StretchVertic:
1211 m_yUserScale *= 1.10;
1212 break;
1213 case UserScale_ShrinkVertic:
1214 m_yUserScale /= 1.10;
1215 break;
1216 case UserScale_Restore:
1217 m_xUserScale =
1218 m_yUserScale = 1.0;
1219 break;
1220
1221 case AxisMirror_Vertic:
1222 m_yAxisReversed = !m_yAxisReversed;
1223 break;
1224 case AxisMirror_Horiz:
1225 m_xAxisReversed = !m_xAxisReversed;
1226 break;
1227
1228 case Colour_TextForeground:
1229 m_colourForeground = SelectColour();
1230 break;
1231 case Colour_TextBackground:
1232 m_colourBackground = SelectColour();
1233 break;
1234 case Colour_Background:
1235 {
1236 wxColour col = SelectColour();
1237 if ( col.Ok() )
1238 {
1239 m_backgroundBrush.SetColour(col);
1240 }
1241 }
1242 break;
1243 case Colour_BackgroundMode:
1244 m_backgroundMode = m_backgroundMode == wxSOLID ? wxTRANSPARENT
1245 : wxSOLID;
1246 break;
1247
1edc9f45
RD
1248 case Colour_TextureBackgound:
1249 m_textureBackground = ! m_textureBackground;
1250 break;
1251
0f0c61d0
VZ
1252 default:
1253 // skip Refresh()
1254 return;
aba99005 1255 }
0f0c61d0 1256
1e7fd311 1257 m_canvas->Refresh();
aba99005
RR
1258}
1259
220af862 1260void MyFrame::PrepareDC(wxDC& dc)
aba99005 1261{
0f0c61d0 1262 dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin );
428db2ea 1263 dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed );
fb576291
VZ
1264 dc.SetUserScale( m_xUserScale, m_yUserScale );
1265 dc.SetMapMode( m_mapMode );
220af862
VZ
1266}
1267
220af862 1268wxColour MyFrame::SelectColour()
0f0c61d0
VZ
1269{
1270 wxColour col;
1271 wxColourData data;
1272 wxColourDialog dialog(this, &data);
1273
1274 if ( dialog.ShowModal() == wxID_OK )
1275 {
428db2ea 1276 col = dialog.GetColourData().GetColour();
0f0c61d0
VZ
1277 }
1278
1279 return col;
aba99005 1280}
253fe8ab 1281