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