]> git.saurik.com Git - wxWidgets.git/blame - samples/drawing/drawing.cpp
Fix unintialized pointer in wxCommandProcessor when
[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
568708e2
VZ
153 void Show(ScreenToShow show) { m_show = show; Refresh(); }
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);
6386110d
VZ
427
428 dc.DrawPolygon(WXSIZEOF(star), star);
429 dc.DrawPolygon(WXSIZEOF(star), star, 160, 0, wxWINDING_RULE);
b62c3631
RR
430}
431
1e7fd311 432void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc )
b62c3631 433{
a60b1f5d 434 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
1e7fd311 435 dc.SetBrush( *wxRED_BRUSH );
4693b20c 436 dc.DrawText(wxString::Format(wxT("Testing lines of width %d"), width), x + 10, y - 10);
9a8c7620 437 dc.DrawRectangle( x+10, y+10, 100, 190 );
4786aabd 438
ab1ca7b3 439 dc.DrawText(_T("Solid/dot/short dash/long dash/dot dash"), x + 150, y + 10);
a60b1f5d 440 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
696e1ea0 441 dc.DrawLine( x+20, y+20, 100, y+20 );
a60b1f5d 442 dc.SetPen( wxPen( wxT("black"), width, wxDOT) );
696e1ea0 443 dc.DrawLine( x+20, y+30, 100, y+30 );
a60b1f5d 444 dc.SetPen( wxPen( wxT("black"), width, wxSHORT_DASH) );
696e1ea0 445 dc.DrawLine( x+20, y+40, 100, y+40 );
a60b1f5d 446 dc.SetPen( wxPen( wxT("black"), width, wxLONG_DASH) );
696e1ea0 447 dc.DrawLine( x+20, y+50, 100, y+50 );
a60b1f5d 448 dc.SetPen( wxPen( wxT("black"), width, wxDOT_DASH) );
696e1ea0 449 dc.DrawLine( x+20, y+60, 100, y+60 );
1e7fd311 450
ab1ca7b3 451 dc.DrawText(_T("Misc hatches"), x + 150, y + 70);
a60b1f5d 452 dc.SetPen( wxPen( wxT("black"), width, wxBDIAGONAL_HATCH) );
696e1ea0 453 dc.DrawLine( x+20, y+70, 100, y+70 );
a60b1f5d 454 dc.SetPen( wxPen( wxT("black"), width, wxCROSSDIAG_HATCH) );
696e1ea0 455 dc.DrawLine( x+20, y+80, 100, y+80 );
a60b1f5d 456 dc.SetPen( wxPen( wxT("black"), width, wxFDIAGONAL_HATCH) );
696e1ea0 457 dc.DrawLine( x+20, y+90, 100, y+90 );
a60b1f5d 458 dc.SetPen( wxPen( wxT("black"), width, wxCROSS_HATCH) );
696e1ea0 459 dc.DrawLine( x+20, y+100, 100, y+100 );
a60b1f5d 460 dc.SetPen( wxPen( wxT("black"), width, wxHORIZONTAL_HATCH) );
696e1ea0 461 dc.DrawLine( x+20, y+110, 100, y+110 );
a60b1f5d 462 dc.SetPen( wxPen( wxT("black"), width, wxVERTICAL_HATCH) );
696e1ea0 463 dc.DrawLine( x+20, y+120, 100, y+120 );
1e7fd311 464
ab1ca7b3 465 dc.DrawText(_T("User dash"), x + 150, y + 140);
a60b1f5d 466 wxPen ud( wxT("black"), width, wxUSER_DASH );
e2a5251d
VZ
467 wxDash dash1[6];
468 dash1[0] = 8; // Long dash <---------+
469 dash1[1] = 2; // Short gap |
470 dash1[2] = 3; // Short dash |
471 dash1[3] = 2; // Short gap |
472 dash1[4] = 3; // Short dash |
473 dash1[5] = 2; // Short gap and repeat +
474 ud.SetDashes( 6, dash1 );
475 dc.SetPen( ud );
696e1ea0 476 dc.DrawLine( x+20, y+140, 100, y+140 );
e2a5251d
VZ
477 dash1[0] = 5; // Make first dash shorter
478 ud.SetDashes( 6, dash1 );
479 dc.SetPen( ud );
696e1ea0 480 dc.DrawLine( x+20, y+150, 100, y+150 );
e2a5251d
VZ
481 dash1[2] = 5; // Make second dash longer
482 ud.SetDashes( 6, dash1 );
483 dc.SetPen( ud );
696e1ea0 484 dc.DrawLine( x+20, y+160, 100, y+160 );
e2a5251d
VZ
485 dash1[4] = 5; // Make third dash longer
486 ud.SetDashes( 6, dash1 );
487 dc.SetPen( ud );
696e1ea0 488 dc.DrawLine( x+20, y+170, 100, y+170 );
b62c3631
RR
489}
490
568708e2 491void MyCanvas::DrawDefault(wxDC& dc)
b62c3631 492{
b62c3631
RR
493 // mark the origin
494 dc.DrawCircle(0, 0, 10);
f88c1a17
JS
495
496 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
497 dc.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID));
498 wxColour tmpColour ;
499 dc.GetPixel(1,1, &tmpColour);
500 dc.FloodFill(1,1, tmpColour, wxFLOOD_SURFACE);
b62c3631 501
cd9da200
VZ
502 dc.DrawCheckMark(5, 80, 15, 15);
503 dc.DrawCheckMark(25, 80, 30, 30);
504 dc.DrawCheckMark(60, 80, 60, 60);
505
0e09f76e 506 // this is the test for "blitting bitmap into DC damages selected brush" bug
0e09f76e 507 wxCoord rectSize = m_std_icon.GetWidth() + 10;
cd9da200 508 wxCoord x = 100;
11f26ea0
VZ
509 dc.SetPen(*wxTRANSPARENT_PEN);
510 dc.SetBrush( *wxGREEN_BRUSH );
cd9da200 511 dc.DrawRectangle(x, 10, rectSize, rectSize);
0e09f76e 512 dc.DrawBitmap(m_std_icon, x + 5, 15, TRUE);
cd9da200
VZ
513 x += rectSize + 10;
514 dc.DrawRectangle(x, 10, rectSize, rectSize);
0e09f76e 515 dc.DrawIcon(m_std_icon, x + 5, 15);
cd9da200
VZ
516 x += rectSize + 10;
517 dc.DrawRectangle(x, 10, rectSize, rectSize);
11f26ea0
VZ
518
519 // test for "transparent" bitmap drawing (it intersects with the last
520 // rectangle above)
521 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
d6f0a4b3 522
0e09f76e
RR
523 if (m_smile_bmp.Ok())
524 dc.DrawBitmap(m_smile_bmp, x + rectSize - 20, rectSize - 10, TRUE);
107a1787 525
ff7c6c9c 526 dc.SetBrush( *wxBLACK_BRUSH );
107a1787
RR
527 dc.DrawRectangle( 0, 160, 1000, 300 );
528
529 // draw lines
530 wxBitmap bitmap(20,70);
531 wxMemoryDC memdc;
532 memdc.SelectObject( bitmap );
533 memdc.SetBrush( *wxBLACK_BRUSH );
534 memdc.SetPen( *wxWHITE_PEN );
535 memdc.DrawRectangle(0,0,20,70);
536 memdc.DrawLine( 10,0,10,70 );
81278df2 537
d4aa3a4b 538 // to the right
4c45f240 539 wxPen pen = *wxRED_PEN;
4c45f240 540 memdc.SetPen(pen);
107a1787
RR
541 memdc.DrawLine( 10, 5,10, 5 );
542 memdc.DrawLine( 10,10,11,10 );
543 memdc.DrawLine( 10,15,12,15 );
544 memdc.DrawLine( 10,20,13,20 );
81278df2 545
d4aa3a4b
RR
546/*
547 memdc.SetPen(*wxRED_PEN);
107a1787
RR
548 memdc.DrawLine( 12, 5,12, 5 );
549 memdc.DrawLine( 12,10,13,10 );
550 memdc.DrawLine( 12,15,14,15 );
551 memdc.DrawLine( 12,20,15,20 );
d4aa3a4b 552*/
81278df2 553
107a1787
RR
554 // same to the left
555 memdc.DrawLine( 10,25,10,25 );
556 memdc.DrawLine( 10,30, 9,30 );
557 memdc.DrawLine( 10,35, 8,35 );
558 memdc.DrawLine( 10,40, 7,40 );
559
560 // XOR draw lines
d4aa3a4b 561 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
562 memdc.SetLogicalFunction( wxINVERT );
563 memdc.SetPen( *wxWHITE_PEN );
564 memdc.DrawLine( 10,50,10,50 );
565 memdc.DrawLine( 10,55,11,55 );
566 memdc.DrawLine( 10,60,12,60 );
567 memdc.DrawLine( 10,65,13,65 );
81278df2 568
107a1787
RR
569 memdc.DrawLine( 12,50,12,50 );
570 memdc.DrawLine( 12,55,13,55 );
571 memdc.DrawLine( 12,60,14,60 );
572 memdc.DrawLine( 12,65,15,65 );
81278df2 573
107a1787
RR
574 memdc.SelectObject( wxNullBitmap );
575 dc.DrawBitmap( bitmap, 10, 170 );
389d906b 576 wxImage image = bitmap.ConvertToImage();
107a1787 577 image.Rescale( 60,210 );
389d906b 578 bitmap = wxBitmap(image);
107a1787 579 dc.DrawBitmap( bitmap, 50, 170 );
81278df2 580
b9de1315 581 // test the rectangle outline drawing - there should be one pixel between
ff7c6c9c
RR
582 // the rect and the lines
583 dc.SetPen(*wxWHITE_PEN);
584 dc.SetBrush( *wxTRANSPARENT_BRUSH );
ff7c6c9c 585 dc.DrawRectangle(150, 170, 49, 29);
107a1787 586 dc.DrawRectangle(200, 170, 49, 29);
ff7c6c9c 587 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
588 dc.DrawLine(250, 210, 250, 170);
589 dc.DrawLine(260, 200, 150, 200);
b9de1315
VZ
590
591 // test the rectangle filled drawing - there should be one pixel between
ff7c6c9c
RR
592 // the rect and the lines
593 dc.SetPen(*wxTRANSPARENT_PEN);
594 dc.SetBrush( *wxWHITE_BRUSH );
595 dc.DrawRectangle(300, 170, 49, 29);
568708e2 596 dc.DrawRectangle(350, 170, 49, 29);
ff7c6c9c 597 dc.SetPen(*wxWHITE_PEN);
b9de1315
VZ
598 dc.DrawLine(400, 170, 400, 210);
599 dc.DrawLine(300, 200, 410, 200);
600
3d2d8da1
RR
601 // a few more tests of this kind
602 dc.SetPen(*wxRED_PEN);
603 dc.SetBrush( *wxWHITE_BRUSH );
604 dc.DrawRectangle(300, 220, 1, 1);
605 dc.DrawRectangle(310, 220, 2, 2);
606 dc.DrawRectangle(320, 220, 3, 3);
607 dc.DrawRectangle(330, 220, 4, 4);
608
609 dc.SetPen(*wxTRANSPARENT_PEN);
610 dc.SetBrush( *wxWHITE_BRUSH );
611 dc.DrawRectangle(300, 230, 1, 1);
612 dc.DrawRectangle(310, 230, 2, 2);
613 dc.DrawRectangle(320, 230, 3, 3);
614 dc.DrawRectangle(330, 230, 4, 4);
615
b9de1315
VZ
616 // and now for filled rect with outline
617 dc.SetPen(*wxRED_PEN);
618 dc.SetBrush( *wxWHITE_BRUSH );
619 dc.DrawRectangle(500, 170, 49, 29);
620 dc.DrawRectangle(550, 170, 49, 29);
621 dc.SetPen(*wxWHITE_PEN);
622 dc.DrawLine(600, 170, 600, 210);
623 dc.DrawLine(500, 200, 610, 200);
624
625 // test the rectangle outline drawing - there should be one pixel between
ff7c6c9c
RR
626 // the rect and the lines
627 dc.SetPen(*wxWHITE_PEN);
628 dc.SetBrush( *wxTRANSPARENT_BRUSH );
ff7c6c9c 629 dc.DrawRoundedRectangle(150, 270, 49, 29, 6);
107a1787 630 dc.DrawRoundedRectangle(200, 270, 49, 29, 6);
ff7c6c9c 631 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
632 dc.DrawLine(250, 270, 250, 310);
633 dc.DrawLine(150, 300, 260, 300);
b9de1315
VZ
634
635 // test the rectangle filled drawing - there should be one pixel between
ff7c6c9c
RR
636 // the rect and the lines
637 dc.SetPen(*wxTRANSPARENT_PEN);
638 dc.SetBrush( *wxWHITE_BRUSH );
639 dc.DrawRoundedRectangle(300, 270, 49, 29, 6);
640 dc.DrawRoundedRectangle(350, 270, 49, 29, 6);
641 dc.SetPen(*wxWHITE_PEN);
b9de1315
VZ
642 dc.DrawLine(400, 270, 400, 310);
643 dc.DrawLine(300, 300, 410, 300);
ff7c6c9c 644
b14c14ff
JS
645 // Added by JACS to demonstrate bizarre behaviour.
646 // With a size of 70, we get a missing red RHS,
647 // and the hight is too small, so we get yellow
648 // showing. With a size of 40, it draws as expected:
649 // it just shows a white rectangle with red outline.
650 int totalWidth = 70;
651 int totalHeight = 70;
652 wxBitmap bitmap2(totalWidth, totalHeight);
653
654 wxMemoryDC memdc2;
655 memdc2.SelectObject(bitmap2);
656
d6f0a4b3
JS
657 wxBrush yellowBrush(wxColour(255, 255, 0), wxSOLID);
658 memdc2.SetBackground(yellowBrush);
659 memdc2.Clear();
b14c14ff 660
d6f0a4b3 661 wxPen yellowPen(wxColour(255, 255, 0), 1, wxSOLID);
b14c14ff
JS
662
663 // Now draw a white rectangle with red outline. It should
664 // entirely eclipse the yellow background.
665 memdc2.SetPen(*wxRED_PEN);
666 memdc2.SetBrush(*wxWHITE_BRUSH);
667
668 memdc2.DrawRectangle(0, 0, totalWidth, totalHeight);
669
b14c14ff
JS
670 memdc2.SetPen(wxNullPen);
671 memdc2.SetBrush(wxNullBrush);
cd9da200 672 memdc2.SelectObject(wxNullBitmap);
b14c14ff
JS
673
674 dc.DrawBitmap(bitmap2, 500, 270);
d6f0a4b3
JS
675
676 // Repeat, but draw directly on dc
677 // Draw a yellow rectangle filling the bitmap
678
679 x = 600; int y = 270;
680 dc.SetPen(yellowPen);
681 dc.SetBrush(yellowBrush);
682 dc.DrawRectangle(x, y, totalWidth, totalHeight);
683
684 // Now draw a white rectangle with red outline. It should
685 // entirely eclipse the yellow background.
686 dc.SetPen(*wxRED_PEN);
687 dc.SetBrush(*wxWHITE_BRUSH);
688
689 dc.DrawRectangle(x, y, totalWidth, totalHeight);
568708e2
VZ
690}
691
692void MyCanvas::DrawText(wxDC& dc)
693{
9a8c7620
VZ
694 // set underlined font for testing
695 dc.SetFont( wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, TRUE) );
ab1ca7b3
MB
696 dc.DrawText( _T("This is text"), 110, 10 );
697 dc.DrawRotatedText( _T("That is text"), 20, 10, -45 );
9a8c7620 698
4770df95
VZ
699 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
700 // under Win9x (it is not TrueType)
701 dc.SetFont( *wxSWISS_FONT );
b62c3631 702
696e1ea0 703 wxString text;
f6bcfd97 704 dc.SetBackgroundMode(wxTRANSPARENT);
696e1ea0
VZ
705
706 for ( int n = -180; n < 180; n += 30 )
707 {
4693b20c 708 text.Printf(wxT(" %d rotated text"), n);
696e1ea0
VZ
709 dc.DrawRotatedText(text , 400, 400, n);
710 }
95724b1a 711
196c87f4 712 dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) );
c45a644e 713
ab1ca7b3 714 dc.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
c45a644e
RR
715
716 long length;
717 long height;
718 long descent;
ab1ca7b3 719 dc.GetTextExtent( _T("This is Swiss 18pt text."), &length, &height, &descent );
4693b20c 720 text.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length, height, descent );
c45a644e
RR
721 dc.DrawText( text, 110, 80 );
722
4693b20c 723 text.Printf( wxT("CharHeight() returns: %d"), dc.GetCharHeight() );
c45a644e
RR
724 dc.DrawText( text, 110, 120 );
725
568708e2 726 dc.DrawRectangle( 100, 40, 4, height );
f6bcfd97
BP
727
728 // test the logical function effect
729 wxCoord y = 150;
730 dc.SetLogicalFunction(wxINVERT);
ab1ca7b3 731 dc.DrawText( _T("There should be no text below"), 110, 150 );
f6bcfd97
BP
732 dc.DrawRectangle( 110, y, 100, height );
733
734 // twice drawn inverted should result in invisible
735 y += height;
ab1ca7b3 736 dc.DrawText( _T("Invisible text"), 110, y );
f6bcfd97 737 dc.DrawRectangle( 110, y, 100, height );
ab1ca7b3 738 dc.DrawText( _T("Invisible text"), 110, y );
f6bcfd97
BP
739 dc.DrawRectangle( 110, y, 100, height );
740 dc.SetLogicalFunction(wxCOPY);
741
742 y += height;
743 dc.DrawRectangle( 110, y, 100, height );
ab1ca7b3 744 dc.DrawText( _T("Visible text"), 110, y );
568708e2
VZ
745}
746
81278df2 747static const struct
568708e2 748{
81278df2
VZ
749 const wxChar *name;
750 int rop;
751} rasterOperations[] =
752{
4693b20c
MB
753 { wxT("wxAND"), wxAND },
754 { wxT("wxAND_INVERT"), wxAND_INVERT },
755 { wxT("wxAND_REVERSE"), wxAND_REVERSE },
756 { wxT("wxCLEAR"), wxCLEAR },
757 { wxT("wxCOPY"), wxCOPY },
758 { wxT("wxEQUIV"), wxEQUIV },
759 { wxT("wxINVERT"), wxINVERT },
760 { wxT("wxNAND"), wxNAND },
761 { wxT("wxNO_OP"), wxNO_OP },
762 { wxT("wxOR"), wxOR },
763 { wxT("wxOR_INVERT"), wxOR_INVERT },
764 { wxT("wxOR_REVERSE"), wxOR_REVERSE },
765 { wxT("wxSET"), wxSET },
766 { wxT("wxSRC_INVERT"), wxSRC_INVERT },
767 { wxT("wxXOR"), wxXOR },
81278df2 768};
568708e2 769
81278df2
VZ
770void MyCanvas::DrawImages(wxDC& dc)
771{
ab1ca7b3 772 dc.DrawText(_T("original image"), 0, 0);
f6bcfd97 773 dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0);
ab1ca7b3 774 dc.DrawText(_T("with colour mask"), 0, 100);
f6bcfd97 775 dc.DrawBitmap(*gs_bmpWithColMask, 0, 120, TRUE);
ab1ca7b3 776 dc.DrawText(_T("the mask image"), 0, 200);
f6bcfd97 777 dc.DrawBitmap(*gs_bmpMask, 0, 220, 0);
ab1ca7b3 778 dc.DrawText(_T("masked image"), 0, 300);
f6bcfd97 779 dc.DrawBitmap(*gs_bmpWithMask, 0, 320, TRUE);
568708e2 780
f6bcfd97
BP
781 int cx = gs_bmpWithColMask->GetWidth(),
782 cy = gs_bmpWithColMask->GetHeight();
568708e2
VZ
783
784 wxMemoryDC memDC;
785 for ( size_t n = 0; n < WXSIZEOF(rasterOperations); n++ )
786 {
787 wxCoord x = 120 + 150*(n%4),
788 y = 20 + 100*(n/4);
4786aabd 789
568708e2 790 dc.DrawText(rasterOperations[n].name, x, y - 20);
f6bcfd97 791 memDC.SelectObject(*gs_bmpWithColMask);
568708e2
VZ
792 dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, TRUE);
793 }
794}
795
81278df2
VZ
796void MyCanvas::DrawWithLogicalOps(wxDC& dc)
797{
798 static const wxCoord w = 60;
799 static const wxCoord h = 60;
800
801 // reuse the text colour here
802 dc.SetPen(wxPen(m_owner->m_colourForeground, 1, wxSOLID));
11f26ea0 803 dc.SetBrush(*wxTRANSPARENT_BRUSH);
81278df2 804
5888ef1e
VZ
805 size_t n;
806 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
81278df2
VZ
807 {
808 wxCoord x = 20 + 150*(n%4),
809 y = 20 + 100*(n/4);
810
811 dc.DrawText(rasterOperations[n].name, x, y - 20);
812 dc.SetLogicalFunction(rasterOperations[n].rop);
11f26ea0 813 dc.DrawRectangle(x, y, w, h);
81278df2
VZ
814 dc.DrawLine(x, y, x + w, y + h);
815 dc.DrawLine(x + w, y, x, y + h);
816 }
c1d139da
GRG
817
818 // now some filled rectangles
819 dc.SetBrush(wxBrush(m_owner->m_colourForeground, wxSOLID));
820
5888ef1e 821 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
c1d139da
GRG
822 {
823 wxCoord x = 20 + 150*(n%4),
824 y = 500 + 100*(n/4);
825
826 dc.DrawText(rasterOperations[n].name, x, y - 20);
827 dc.SetLogicalFunction(rasterOperations[n].rop);
828 dc.DrawRectangle(x, y, w, h);
829 }
81278df2
VZ
830}
831
f6bcfd97
BP
832void MyCanvas::DrawCircles(wxDC& dc)
833{
834 int x = 100,
835 y = 100,
836 r = 20;
837
ab1ca7b3 838 dc.DrawText(_T("Some circles"), 0, y);
f6bcfd97
BP
839 dc.DrawCircle(x, y, r);
840 dc.DrawCircle(x + 2*r, y, r);
841 dc.DrawCircle(x + 4*r, y, r);
842
843 y += 2*r;
ab1ca7b3 844 dc.DrawText(_T("And ellipses"), 0, y);
f6bcfd97
BP
845 dc.DrawEllipse(x - r, y, 2*r, r);
846 dc.DrawEllipse(x + r, y, 2*r, r);
847 dc.DrawEllipse(x + 3*r, y, 2*r, r);
848
849 y += 2*r;
ab1ca7b3 850 dc.DrawText(_T("And arcs"), 0, y);
f6bcfd97
BP
851 dc.DrawArc(x - r, y, x + r, y, x, y);
852 dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y);
853 dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y);
854
855 y += 2*r;
856 dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90);
857 dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
858 dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
859 dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
860}
861
bc3cedfa
RR
862void MyCanvas::DrawRegions(wxDC& dc)
863{
ab1ca7b3
MB
864 dc.DrawText(_T("You should see a red rect partly covered by a cyan one ")
865 _T("on the left"), 10, 5);
866 dc.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
8e0e4b1b 867 10, 5 + dc.GetCharHeight());
ab1ca7b3
MB
868 dc.DrawText(_T("The second copy should be identical but right part of it ")
869 _T("should be offset by 10 pixels."),
4cbcae16 870 10, 5 + 2*dc.GetCharHeight());
8e0e4b1b 871
4cbcae16
VZ
872 DrawRegionsHelper(dc, 10, TRUE);
873 DrawRegionsHelper(dc, 350, FALSE);
8e0e4b1b 874}
c4218a74 875
4cbcae16 876void MyCanvas::DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime)
8e0e4b1b 877{
4cbcae16
VZ
878 wxCoord y = 100;
879
8e0e4b1b 880 dc.DestroyClippingRegion();
bc3cedfa
RR
881 dc.SetBrush( *wxWHITE_BRUSH );
882 dc.SetPen( *wxTRANSPARENT_PEN );
4cbcae16 883 dc.DrawRectangle( x, y, 310, 310 );
c4218a74 884
4cbcae16 885 dc.SetClippingRegion( x + 10, y + 10, 100, 270 );
c4218a74 886
bc3cedfa 887 dc.SetBrush( *wxRED_BRUSH );
4cbcae16 888 dc.DrawRectangle( x, y, 310, 310 );
c4218a74 889
4cbcae16 890 dc.SetClippingRegion( x + 10, y + 10, 100, 100 );
993f97ee 891
993f97ee 892 dc.SetBrush( *wxCYAN_BRUSH );
4cbcae16
VZ
893 dc.DrawRectangle( x, y, 310, 310 );
894
895 dc.DestroyClippingRegion();
896
897 wxRegion region(x + 110, y + 20, 100, 270);
13a2eea0 898#if !defined(__WXMOTIF__) && !defined(__WXMAC__)
4cbcae16
VZ
899 if ( !firstTime )
900 region.Offset(10, 10);
4cae9a20 901#endif
4cbcae16 902 dc.SetClippingRegion(region);
c4218a74 903
bc3cedfa 904 dc.SetBrush( *wxGREY_BRUSH );
4cbcae16 905 dc.DrawRectangle( x, y, 310, 310 );
c4218a74 906
5d25c050
RR
907 if (m_smile_bmp.Ok())
908 {
4cbcae16
VZ
909 dc.DrawBitmap( m_smile_bmp, x + 150, y + 150, TRUE );
910 dc.DrawBitmap( m_smile_bmp, x + 130, y + 10, TRUE );
911 dc.DrawBitmap( m_smile_bmp, x + 130, y + 280, TRUE );
912 dc.DrawBitmap( m_smile_bmp, x + 100, y + 70, TRUE );
913 dc.DrawBitmap( m_smile_bmp, x + 200, y + 70, TRUE );
5d25c050 914 }
bc3cedfa
RR
915}
916
568708e2
VZ
917void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
918{
919 wxPaintDC dc(this);
920 PrepareDC(dc);
c4218a74 921
568708e2
VZ
922 m_owner->PrepareDC(dc);
923
924 dc.SetBackgroundMode( m_owner->m_backgroundMode );
925 if ( m_owner->m_backgroundBrush.Ok() )
926 dc.SetBackground( m_owner->m_backgroundBrush );
927 if ( m_owner->m_colourForeground.Ok() )
928 dc.SetTextForeground( m_owner->m_colourForeground );
929 if ( m_owner->m_colourBackground.Ok() )
930 dc.SetTextBackground( m_owner->m_colourBackground );
4786aabd 931
1edc9f45 932 if ( m_owner->m_textureBackground) {
047473c9 933 if ( ! m_owner->m_backgroundBrush.Ok() ) {
1edc9f45
RD
934 wxBrush b(wxColour(0,128,0), wxSOLID);
935 dc.SetBackground(b);
936 }
047473c9
RD
937 }
938
204dd9a7
VZ
939 if ( m_clip )
940 dc.SetClippingRegion(100, 100, 100, 100);
941
e1208c31 942 dc.Clear();
1edc9f45 943
204dd9a7
VZ
944 if ( m_owner->m_textureBackground )
945 {
1edc9f45 946 dc.SetPen(*wxMEDIUM_GREY_PEN);
204dd9a7 947 for ( int i = 0; i < 200; i++ )
1edc9f45
RD
948 dc.DrawLine(0, i*10, i*10, 0);
949 }
950
568708e2
VZ
951 switch ( m_show )
952 {
953 case Show_Default:
954 DrawDefault(dc);
955 break;
1e7fd311 956
f6bcfd97
BP
957 case Show_Circles:
958 DrawCircles(dc);
959 break;
960
bc3cedfa
RR
961 case Show_Regions:
962 DrawRegions(dc);
963 break;
964
568708e2
VZ
965 case Show_Text:
966 DrawText(dc);
967 break;
1e7fd311 968
568708e2
VZ
969 case Show_Lines:
970 DrawTestLines( 0, 100, 0, dc );
f6bcfd97
BP
971 DrawTestLines( 0, 320, 1, dc );
972 DrawTestLines( 0, 540, 2, dc );
973 DrawTestLines( 0, 760, 6, dc );
568708e2 974 break;
1e7fd311 975
6386110d
VZ
976 case Show_Brushes:
977 DrawTestBrushes(dc);
978 break;
979
568708e2 980 case Show_Polygons:
6386110d 981 DrawTestPoly(dc);
568708e2 982 break;
1e7fd311 983
568708e2
VZ
984 case Show_Mask:
985 DrawImages(dc);
986 break;
81278df2
VZ
987
988 case Show_Ops:
989 DrawWithLogicalOps(dc);
990 break;
568708e2 991 }
b62c3631
RR
992}
993
bf0c00c6
RR
994void MyCanvas::OnMouseMove(wxMouseEvent &event)
995{
996 wxClientDC dc(this);
997 PrepareDC(dc);
998 m_owner->PrepareDC(dc);
999
1000 wxPoint pos = event.GetPosition();
1001 long x = dc.DeviceToLogicalX( pos.x );
1002 long y = dc.DeviceToLogicalY( pos.y );
1003 wxString str;
4693b20c 1004 str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y );
bf0c00c6
RR
1005 m_owner->SetStatusText( str );
1006}
1007
b62c3631
RR
1008// ----------------------------------------------------------------------------
1009// MyFrame
1010// ----------------------------------------------------------------------------
1011
1012// the event tables connect the wxWindows events with the functions (event
1013// handlers) which process them. It can be also done at run-time, but for the
1014// simple menu events like this the static method is much simpler.
1015BEGIN_EVENT_TABLE(MyFrame, wxFrame)
568708e2
VZ
1016 EVT_MENU (File_Quit, MyFrame::OnQuit)
1017 EVT_MENU (File_About, MyFrame::OnAbout)
204dd9a7 1018 EVT_MENU (File_Clip, MyFrame::OnClip)
568708e2
VZ
1019
1020 EVT_MENU_RANGE(MenuShow_First, MenuShow_Last, MyFrame::OnShow)
1021
b62c3631
RR
1022 EVT_MENU_RANGE(MenuOption_First, MenuOption_Last, MyFrame::OnOption)
1023END_EVENT_TABLE()
1024
aba99005
RR
1025// frame constructor
1026MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
c4218a74
VZ
1027 : wxFrame((wxFrame *)NULL, -1, title, pos, size,
1028 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
aba99005
RR
1029{
1030 // set the frame icon
1031 SetIcon(wxICON(mondrian));
1032
1033 wxMenu *menuFile = new wxMenu;
ab1ca7b3
MB
1034 menuFile->Append(File_ShowDefault, _T("&Default screen\tF1"));
1035 menuFile->Append(File_ShowText, _T("&Text screen\tF2"));
1036 menuFile->Append(File_ShowLines, _T("&Lines screen\tF3"));
1037 menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4"));
1038 menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5"));
1039 menuFile->Append(File_ShowMask, _T("&Mask screen\tF6"));
1040 menuFile->Append(File_ShowOps, _T("&ROP screen\tF7"));
1041 menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8"));
1042 menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9"));
568708e2 1043 menuFile->AppendSeparator();
ab1ca7b3 1044 menuFile->AppendCheckItem(File_Clip, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
204dd9a7 1045 menuFile->AppendSeparator();
ab1ca7b3 1046 menuFile->Append(File_About, _T("&About...\tCtrl-A"), _T("Show about dialog"));
aba99005 1047 menuFile->AppendSeparator();
ab1ca7b3 1048 menuFile->Append(File_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
0f0c61d0 1049
aba99005 1050 wxMenu *menuMapMode = new wxMenu;
ab1ca7b3
MB
1051 menuMapMode->Append( MapMode_Text, _T("&TEXT map mode") );
1052 menuMapMode->Append( MapMode_Lometric, _T("&LOMETRIC map mode") );
1053 menuMapMode->Append( MapMode_Twips, _T("T&WIPS map mode") );
1054 menuMapMode->Append( MapMode_Points, _T("&POINTS map mode") );
1055 menuMapMode->Append( MapMode_Metric, _T("&METRIC map mode") );
0f0c61d0 1056
aba99005 1057 wxMenu *menuUserScale = new wxMenu;
ab1ca7b3
MB
1058 menuUserScale->Append( UserScale_StretchHoriz, _T("Stretch &horizontally\tCtrl-H") );
1059 menuUserScale->Append( UserScale_ShrinkHoriz, _T("Shrin&k horizontally\tCtrl-G") );
1060 menuUserScale->Append( UserScale_StretchVertic, _T("Stretch &vertically\tCtrl-V") );
1061 menuUserScale->Append( UserScale_ShrinkVertic, _T("&Shrink vertically\tCtrl-W") );
0f0c61d0 1062 menuUserScale->AppendSeparator();
ab1ca7b3 1063 menuUserScale->Append( UserScale_Restore, _T("&Restore to normal\tCtrl-0") );
0f0c61d0 1064
aba99005 1065 wxMenu *menuAxis = new wxMenu;
ab1ca7b3
MB
1066 menuAxis->Append( AxisMirror_Horiz, _T("Mirror horizontally\tCtrl-M"), _T(""), TRUE );
1067 menuAxis->Append( AxisMirror_Vertic, _T("Mirror vertically\tCtrl-N"), _T(""), TRUE );
0f0c61d0 1068
aba99005 1069 wxMenu *menuLogical = new wxMenu;
ab1ca7b3
MB
1070 menuLogical->Append( LogicalOrigin_MoveDown, _T("Move &down\tCtrl-D") );
1071 menuLogical->Append( LogicalOrigin_MoveUp, _T("Move &up\tCtrl-U") );
1072 menuLogical->Append( LogicalOrigin_MoveLeft, _T("Move &right\tCtrl-L") );
1073 menuLogical->Append( LogicalOrigin_MoveRight, _T("Move &left\tCtrl-R") );
fb576291 1074 menuLogical->AppendSeparator();
ab1ca7b3
MB
1075 menuLogical->Append( LogicalOrigin_Set, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1076 menuLogical->Append( LogicalOrigin_Restore, _T("&Restore to normal\tShift-Ctrl-0") );
aba99005 1077
0f0c61d0 1078 wxMenu *menuColour = new wxMenu;
ab1ca7b3
MB
1079 menuColour->Append( Colour_TextForeground, _T("Text &foreground...") );
1080 menuColour->Append( Colour_TextBackground, _T("Text &background...") );
1081 menuColour->Append( Colour_Background, _T("Background &colour...") );
1082 menuColour->Append( Colour_BackgroundMode, _T("&Opaque/transparent\tCtrl-B"), _T(""), TRUE );
1083 menuColour->Append( Colour_TextureBackgound, _T("Draw textured back&ground\tCtrl-T"), _T(""), TRUE);
0f0c61d0 1084
aba99005
RR
1085 // now append the freshly created menu to the menu bar...
1086 wxMenuBar *menuBar = new wxMenuBar;
ab1ca7b3
MB
1087 menuBar->Append(menuFile, _T("&File"));
1088 menuBar->Append(menuMapMode, _T("&Mode"));
1089 menuBar->Append(menuUserScale, _T("&Scale"));
1090 menuBar->Append(menuAxis, _T("&Axis"));
1091 menuBar->Append(menuLogical, _T("&Origin"));
1092 menuBar->Append(menuColour, _T("&Colours"));
aba99005
RR
1093
1094 // ... and attach this menu bar to the frame
1095 SetMenuBar(menuBar);
1096
1097 // create a status bar just for fun (by default with 1 pane only)
1098 CreateStatusBar(2);
ab1ca7b3 1099 SetStatusText(_T("Welcome to wxWindows!"));
0f0c61d0 1100
aba99005
RR
1101 m_mapMode = wxMM_TEXT;
1102 m_xUserScale = 1.0;
1103 m_yUserScale = 1.0;
1104 m_xLogicalOrigin = 0;
1105 m_yLogicalOrigin = 0;
0f0c61d0
VZ
1106 m_xAxisReversed =
1107 m_yAxisReversed = FALSE;
1108 m_backgroundMode = wxSOLID;
b97fa7cf
VZ
1109 m_colourForeground = *wxRED;
1110 m_colourBackground = *wxBLUE;
1edc9f45 1111 m_textureBackground = FALSE;
aba99005 1112
b62c3631 1113 m_canvas = new MyCanvas( this );
b97fa7cf 1114 m_canvas->SetScrollbars( 10, 10, 100, 240 );
b62c3631 1115}
aba99005
RR
1116
1117// event handlers
1118
1119void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1120{
1121 // TRUE is to force the frame to close
1122 Close(TRUE);
1123}
1124
1125void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1126{
1127 wxString msg;
c916e13b
RR
1128 msg.Printf( wxT("This is the about dialog of the drawing sample.\n")
1129 wxT("This sample tests various primitive drawing functions\n")
6386110d 1130 wxT("(without any attempts to prevent flicker).\n")
c916e13b 1131 wxT("Copyright (c) Robert Roebling 1999")
aba99005
RR
1132 );
1133
ab1ca7b3 1134 wxMessageBox(msg, _T("About Drawing"), wxOK | wxICON_INFORMATION, this);
aba99005
RR
1135}
1136
204dd9a7
VZ
1137void MyFrame::OnClip(wxCommandEvent& event)
1138{
1139 m_canvas->Clip(event.IsChecked());
1140}
1141
568708e2
VZ
1142void MyFrame::OnShow(wxCommandEvent& event)
1143{
3ca6a5f0 1144 m_canvas->Show((ScreenToShow)(event.GetId() - MenuShow_First));
568708e2
VZ
1145}
1146
1147void MyFrame::OnOption(wxCommandEvent& event)
aba99005 1148{
3ca6a5f0 1149 switch (event.GetId())
aba99005
RR
1150 {
1151 case MapMode_Text:
b9857632 1152 m_mapMode = wxMM_TEXT;
0f0c61d0 1153 break;
aba99005
RR
1154 case MapMode_Lometric:
1155 m_mapMode = wxMM_LOMETRIC;
0f0c61d0
VZ
1156 break;
1157 case MapMode_Twips:
aba99005 1158 m_mapMode = wxMM_TWIPS;
0f0c61d0
VZ
1159 break;
1160 case MapMode_Points:
aba99005 1161 m_mapMode = wxMM_POINTS;
0f0c61d0
VZ
1162 break;
1163 case MapMode_Metric:
aba99005 1164 m_mapMode = wxMM_METRIC;
0f0c61d0
VZ
1165 break;
1166
1167 case LogicalOrigin_MoveDown:
1168 m_yLogicalOrigin += 10;
1169 break;
1170 case LogicalOrigin_MoveUp:
1171 m_yLogicalOrigin -= 10;
1172 break;
1173 case LogicalOrigin_MoveLeft:
1174 m_xLogicalOrigin += 10;
1175 break;
1176 case LogicalOrigin_MoveRight:
1177 m_xLogicalOrigin -= 10;
1178 break;
fb576291
VZ
1179 case LogicalOrigin_Set:
1180 m_xLogicalOrigin =
1181 m_yLogicalOrigin = -100;
1182 break;
1183 case LogicalOrigin_Restore:
1184 m_xLogicalOrigin =
1185 m_yLogicalOrigin = 0;
1186 break;
0f0c61d0
VZ
1187
1188 case UserScale_StretchHoriz:
1189 m_xUserScale *= 1.10;
1190 break;
1191 case UserScale_ShrinkHoriz:
1192 m_xUserScale /= 1.10;
1193 break;
1194 case UserScale_StretchVertic:
1195 m_yUserScale *= 1.10;
1196 break;
1197 case UserScale_ShrinkVertic:
1198 m_yUserScale /= 1.10;
1199 break;
1200 case UserScale_Restore:
1201 m_xUserScale =
1202 m_yUserScale = 1.0;
1203 break;
1204
1205 case AxisMirror_Vertic:
1206 m_yAxisReversed = !m_yAxisReversed;
1207 break;
1208 case AxisMirror_Horiz:
1209 m_xAxisReversed = !m_xAxisReversed;
1210 break;
1211
1212 case Colour_TextForeground:
1213 m_colourForeground = SelectColour();
1214 break;
1215 case Colour_TextBackground:
1216 m_colourBackground = SelectColour();
1217 break;
1218 case Colour_Background:
1219 {
1220 wxColour col = SelectColour();
1221 if ( col.Ok() )
1222 {
1223 m_backgroundBrush.SetColour(col);
1224 }
1225 }
1226 break;
1227 case Colour_BackgroundMode:
1228 m_backgroundMode = m_backgroundMode == wxSOLID ? wxTRANSPARENT
1229 : wxSOLID;
1230 break;
1231
1edc9f45
RD
1232 case Colour_TextureBackgound:
1233 m_textureBackground = ! m_textureBackground;
1234 break;
1235
0f0c61d0
VZ
1236 default:
1237 // skip Refresh()
1238 return;
aba99005 1239 }
0f0c61d0 1240
1e7fd311 1241 m_canvas->Refresh();
aba99005
RR
1242}
1243
220af862 1244void MyFrame::PrepareDC(wxDC& dc)
aba99005 1245{
0f0c61d0 1246 dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin );
428db2ea 1247 dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed );
fb576291
VZ
1248 dc.SetUserScale( m_xUserScale, m_yUserScale );
1249 dc.SetMapMode( m_mapMode );
220af862
VZ
1250}
1251
220af862 1252wxColour MyFrame::SelectColour()
0f0c61d0
VZ
1253{
1254 wxColour col;
1255 wxColourData data;
1256 wxColourDialog dialog(this, &data);
1257
1258 if ( dialog.ShowModal() == wxID_OK )
1259 {
428db2ea 1260 col = dialog.GetColourData().GetColour();
0f0c61d0
VZ
1261 }
1262
1263 return col;
aba99005 1264}
253fe8ab 1265