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