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