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