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