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