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