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