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