]> git.saurik.com Git - wxWidgets.git/blame - samples/drawing/drawing.cpp
compilation fix for Watcom
[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;
336}
337
aba99005 338// ----------------------------------------------------------------------------
b62c3631 339// MyCanvas
aba99005
RR
340// ----------------------------------------------------------------------------
341
b62c3631
RR
342// the event tables connect the wxWindows events with the functions (event
343// handlers) which process them.
344BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
345 EVT_PAINT (MyCanvas::OnPaint)
bf0c00c6 346 EVT_MOTION (MyCanvas::OnMouseMove)
b62c3631
RR
347END_EVENT_TABLE()
348
c4218a74 349#include "smile.xpm"
0e09f76e 350
c4218a74
VZ
351MyCanvas::MyCanvas(MyFrame *parent)
352 : wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize,
353 wxHSCROLL | wxVSCROLL | wxNO_FULL_REPAINT_ON_RESIZE)
b62c3631 354{
b97fa7cf 355 m_owner = parent;
568708e2 356 m_show = Show_Default;
0e09f76e
RR
357 m_smile_bmp = wxBitmap(smile_xpm);
358 m_std_icon = wxTheApp->GetStdIcon(wxICON_INFORMATION);
b97fa7cf
VZ
359}
360
e1208c31
RR
361// Draw a polygon and an overlapping rectangle
362// If transparent is 1, the fill pattern is made transparent.
363// If transparent is 2, the fill pattern is made transparent but inversed
364// If is transparent is 0 the text for and background color will be used to represent/map
365// the colors of the monochrome bitmap pixels to the fillpattern
b97fa7cf 366//
e1208c31 367// I abused the the menu items for setting so called back and fore ground color
c4218a74
VZ
368// just to show how the those colors do influence the fillpatterns just play
369// with those, and with the code variations are endless using other logical
e1208c31
RR
370// functions.
371
b97fa7cf
VZ
372void MyCanvas::DrawTestPoly( int x, int y,wxDC &dc,int transparent )
373{
3ca6a5f0
BP
374// wxBrush* brush4 = new wxBrush(*gs_bmp4);
375 wxBrush* brush4 = new wxBrush(*wxBLACK,wxFDIAGONAL_HATCH);
f6bcfd97
BP
376 wxBrush* brush4_mono = new wxBrush(*gs_bmp4_mono);
377 wxBrush* brush36 = new wxBrush(*gs_bmp36);
b97fa7cf
VZ
378
379 wxPoint todraw[5];
380 todraw[0].x=(long)x+100;
381 todraw[0].y=(long)y+100;
382 todraw[1].x=(long)x+300;
383 todraw[1].y=(long)y+100;
384 todraw[2].x=(long)x+300;
385 todraw[2].y=(long)y+300;
386 todraw[3].x=(long)x+150;
387 todraw[3].y=(long)y+350;
388 todraw[4].x=(long)x+100;
389 todraw[4].y=(long)y+300;
390
391 wxPoint todraw2[5];
392 todraw2[0].x=100;
393 todraw2[0].y=100;
394 todraw2[1].x=300;
395 todraw2[1].y=100;
396 todraw2[2].x=300;
397 todraw2[2].y=300;
398 todraw2[3].x=150;
399 todraw2[3].y=350;
400 todraw2[4].x=100;
401 todraw2[4].y=300;
402
403 switch (transparent)
404 {
405 case 0:
406 {
e1208c31
RR
407 dc.SetLogicalFunction(wxCOPY);
408
a60b1f5d 409 dc.SetPen( wxPen( wxT("black"), 4, wxSOLID) );
568708e2 410 dc.SetBrush( *brush4 );
b97fa7cf
VZ
411 dc.DrawPolygon(5,todraw,0,0,wxWINDING_RULE);
412
a60b1f5d 413 dc.SetPen( wxPen( wxT("red"), 4, wxSOLID) );
568708e2 414 dc.SetBrush( *brush36 );
b97fa7cf 415 dc.SetTextForeground(*wxCYAN);
b97fa7cf 416 dc.SetTextBackground(m_owner->m_colourBackground);
b97fa7cf 417 dc.DrawRectangle( x+10, y+10, 200, 200 );
c4218a74 418
a60b1f5d 419 dc.SetPen( wxPen( wxT("green"), 4, wxSOLID) );
e1208c31
RR
420 dc.SetBrush( *brush4_mono );
421 dc.SetTextForeground(*wxCYAN);
422 dc.SetTextBackground(m_owner->m_colourBackground);
423 dc.DrawRectangle( x+50, y+50, 200, 200 );
c4218a74 424
a56fcaaf 425 dc.DrawCircle( x+400, y+50, 130 );
c4218a74 426
b97fa7cf
VZ
427 dc.SetBrush(wxNullBrush);
428 dc.SetPen(wxNullPen);
429 break;
430 }
431 case 1: //now with transparent fillpatterns
432 {
433
568708e2
VZ
434 wxBitmap* bmpBlit = new wxBitmap(600,400);
435 wxMemoryDC* memDC= new wxMemoryDC();
b97fa7cf
VZ
436 // wxBrush _clearbrush(*wxGREEN,wxSOLID);
437 wxBrush _clearbrush(*wxBLACK,wxSOLID);
568708e2
VZ
438 memDC->SelectObject(*bmpBlit);
439 memDC->BeginDrawing();
440 memDC->SetBackground(_clearbrush);
441 memDC->Clear();
442 memDC->SetBackground(wxNullBrush);
443
a60b1f5d 444 memDC->SetPen( wxPen( wxT("black"), 4, wxSOLID) );
568708e2
VZ
445 memDC->SetBrush( wxNullBrush);
446 memDC->SetBrush( *brush4 );
447 memDC->SetTextForeground(*wxBLACK); // 0s --> 0x000000 (black)
448 memDC->SetTextBackground(*wxWHITE); // 1s --> 0xFFFFFF (white)
449 memDC->SetLogicalFunction(wxAND_INVERT);
b97fa7cf
VZ
450
451 // BLACK OUT the opaque pixels and leave the rest as is
568708e2 452 memDC->DrawPolygon(5,todraw2,0,0,wxWINDING_RULE);
b97fa7cf
VZ
453
454 // Set background and foreground colors for fill pattern
455 //the previous blacked out pixels are now merged with the layer color
456 //while the non blacked out pixels stay as they are.
568708e2 457 memDC->SetTextForeground(*wxBLACK); // 0s --> 0x000000 (black)
b97fa7cf
VZ
458
459 //now define what will be the color of the fillpattern parts that are not transparent
568708e2
VZ
460 // memDC->SetTextBackground(*wxBLUE);
461 memDC->SetTextBackground(m_owner->m_colourForeground);
462 memDC->SetLogicalFunction(wxOR);
b97fa7cf
VZ
463
464
465 //don't understand how but the outline is also depending on logicalfunction
a60b1f5d 466 memDC->SetPen( wxPen( wxT("red"), 4, wxSOLID) );
568708e2 467 memDC->DrawPolygon(5,todraw2,0,0,wxWINDING_RULE);
b97fa7cf 468
568708e2 469 memDC->SetLogicalFunction(wxCOPY);
b97fa7cf 470
a60b1f5d 471 memDC->SetPen( wxPen( wxT("black"), 4, wxSOLID) );
568708e2
VZ
472 memDC->SetBrush( wxNullBrush);
473 memDC->SetBrush( *brush36 );
474 memDC->SetTextForeground(*wxBLACK); // 0s --> 0x000000 (black)
475 memDC->SetTextBackground(*wxWHITE); // 1s --> 0xFFFFFF (white)
476 memDC->SetLogicalFunction(wxAND_INVERT);
b97fa7cf 477
568708e2 478 memDC->DrawRectangle( 10, 10, 200, 200 );
b97fa7cf
VZ
479
480 // Set background and foreground colors for fill pattern
481 //the previous blacked out pixels are now merged with the layer color
482 //while the non blacked out pixels stay as they are.
568708e2 483 memDC->SetTextForeground(*wxBLACK); // 0s --> 0x000000 (black)
b97fa7cf 484 //now define what will be the color of the fillpattern parts that are not transparent
568708e2
VZ
485 // memDC->SetTextBackground(*wxRED);
486 memDC->SetTextBackground(m_owner->m_colourBackground);
487 memDC->SetLogicalFunction(wxOR);
b97fa7cf
VZ
488
489 //don't understand how but the outline is also depending on logicalfunction
a60b1f5d 490 memDC->SetPen( wxPen( wxT("yellow"), 4, wxSOLID) );
568708e2 491 memDC->DrawRectangle( 10, 10, 200, 200 );
b97fa7cf 492
568708e2
VZ
493 memDC->SetBrush(wxNullBrush);
494 memDC->SetPen(wxNullPen);
b97fa7cf 495
568708e2
VZ
496 memDC->EndDrawing();
497 dc.Blit(x,y,600,400,memDC,0,0,wxCOPY);
498 delete bmpBlit;
499 delete memDC;
b97fa7cf
VZ
500 break;
501 }
502 case 2: //now with transparent inversed fillpatterns
503 {
568708e2
VZ
504 wxBitmap* bmpBlit = new wxBitmap(600,400);
505 wxMemoryDC* memDC= new wxMemoryDC();
b97fa7cf 506 wxBrush _clearbrush(*wxWHITE,wxSOLID);
568708e2
VZ
507 memDC->SelectObject(*bmpBlit);
508 memDC->BeginDrawing();
509 memDC->SetBackground(_clearbrush);
510 memDC->Clear();
511 memDC->SetBackground(wxNullBrush);
512
a60b1f5d 513 memDC->SetPen( wxPen( wxT("black"), 4, wxSOLID) );
568708e2
VZ
514 memDC->SetBrush( *brush4 );
515 memDC->SetTextBackground(*wxBLACK); // 0s --> 0x000000 (black)
516 memDC->SetTextForeground(*wxWHITE); // 1s --> 0xFFFFFF (white)
517 memDC->SetLogicalFunction(wxAND_INVERT);
b97fa7cf
VZ
518
519 // BLACK OUT the opaque pixels and leave the rest as is
568708e2 520 memDC->DrawPolygon(5,todraw2,0,0,wxWINDING_RULE);
b97fa7cf
VZ
521
522 // Set background and foreground colors for fill pattern
523 //the previous blacked out pixels are now merged with the layer color
524 //while the non blacked out pixels stay as they are.
568708e2 525 memDC->SetTextBackground(*wxBLACK); // 0s --> 0x000000 (black)
b97fa7cf
VZ
526
527 //now define what will be the color of the fillpattern parts that are not transparent
568708e2
VZ
528 memDC->SetTextForeground(m_owner->m_colourForeground);
529 memDC->SetLogicalFunction(wxOR);
b97fa7cf
VZ
530
531
532 //don't understand how but the outline is also depending on logicalfunction
a60b1f5d 533 memDC->SetPen( wxPen( wxT("red"), 4, wxSOLID) );
568708e2 534 memDC->DrawPolygon(5,todraw2,0,0,wxWINDING_RULE);
b97fa7cf 535
568708e2 536 memDC->SetLogicalFunction(wxCOPY);
b97fa7cf 537
a60b1f5d 538 memDC->SetPen( wxPen( wxT("black"), 4, wxSOLID) );
568708e2
VZ
539 memDC->SetBrush( *brush36 );
540 memDC->SetTextBackground(*wxBLACK); // 0s --> 0x000000 (black)
541 memDC->SetTextForeground(*wxWHITE); // 1s --> 0xFFFFFF (white)
542 memDC->SetLogicalFunction(wxAND_INVERT);
b97fa7cf 543
568708e2 544 memDC->DrawRectangle( 10,10, 200, 200 );
b97fa7cf
VZ
545
546 // Set background and foreground colors for fill pattern
547 //the previous blacked out pixels are now merged with the layer color
548 //while the non blacked out pixels stay as they are.
568708e2 549 memDC->SetTextBackground(*wxBLACK); // 0s --> 0x000000 (black)
b97fa7cf 550 //now define what will be the color of the fillpattern parts that are not transparent
568708e2
VZ
551 memDC->SetTextForeground(m_owner->m_colourBackground);
552 memDC->SetLogicalFunction(wxOR);
b97fa7cf
VZ
553
554 //don't understand how but the outline is also depending on logicalfunction
a60b1f5d 555 memDC->SetPen( wxPen( wxT("yellow"), 4, wxSOLID) );
568708e2
VZ
556 memDC->DrawRectangle( 10, 10, 200, 200 );
557
558 memDC->SetBrush(wxNullBrush);
559 memDC->SetPen(wxNullPen);
560 dc.Blit(x,y,600,400,memDC,0,0,wxCOPY);
561 delete bmpBlit;
562 delete memDC;
b97fa7cf
VZ
563 }
564 }
565
568708e2 566 delete brush4;
e1208c31 567 delete brush4_mono;
568708e2 568 delete brush36;
b62c3631
RR
569}
570
1e7fd311 571void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc )
b62c3631 572{
a60b1f5d 573 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
1e7fd311 574 dc.SetBrush( *wxRED_BRUSH );
4693b20c 575 dc.DrawText(wxString::Format(wxT("Testing lines of width %d"), width), x + 10, y - 10);
9a8c7620 576 dc.DrawRectangle( x+10, y+10, 100, 190 );
4786aabd 577
f6bcfd97 578 dc.DrawText("Solid/dot/short dash/long dash/dot dash", x + 150, y + 10);
a60b1f5d 579 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
696e1ea0 580 dc.DrawLine( x+20, y+20, 100, y+20 );
a60b1f5d 581 dc.SetPen( wxPen( wxT("black"), width, wxDOT) );
696e1ea0 582 dc.DrawLine( x+20, y+30, 100, y+30 );
a60b1f5d 583 dc.SetPen( wxPen( wxT("black"), width, wxSHORT_DASH) );
696e1ea0 584 dc.DrawLine( x+20, y+40, 100, y+40 );
a60b1f5d 585 dc.SetPen( wxPen( wxT("black"), width, wxLONG_DASH) );
696e1ea0 586 dc.DrawLine( x+20, y+50, 100, y+50 );
a60b1f5d 587 dc.SetPen( wxPen( wxT("black"), width, wxDOT_DASH) );
696e1ea0 588 dc.DrawLine( x+20, y+60, 100, y+60 );
1e7fd311 589
f6bcfd97 590 dc.DrawText("Misc hatches", x + 150, y + 70);
a60b1f5d 591 dc.SetPen( wxPen( wxT("black"), width, wxBDIAGONAL_HATCH) );
696e1ea0 592 dc.DrawLine( x+20, y+70, 100, y+70 );
a60b1f5d 593 dc.SetPen( wxPen( wxT("black"), width, wxCROSSDIAG_HATCH) );
696e1ea0 594 dc.DrawLine( x+20, y+80, 100, y+80 );
a60b1f5d 595 dc.SetPen( wxPen( wxT("black"), width, wxFDIAGONAL_HATCH) );
696e1ea0 596 dc.DrawLine( x+20, y+90, 100, y+90 );
a60b1f5d 597 dc.SetPen( wxPen( wxT("black"), width, wxCROSS_HATCH) );
696e1ea0 598 dc.DrawLine( x+20, y+100, 100, y+100 );
a60b1f5d 599 dc.SetPen( wxPen( wxT("black"), width, wxHORIZONTAL_HATCH) );
696e1ea0 600 dc.DrawLine( x+20, y+110, 100, y+110 );
a60b1f5d 601 dc.SetPen( wxPen( wxT("black"), width, wxVERTICAL_HATCH) );
696e1ea0 602 dc.DrawLine( x+20, y+120, 100, y+120 );
1e7fd311 603
f6bcfd97 604 dc.DrawText("User dash", x + 150, y + 140);
a60b1f5d 605 wxPen ud( wxT("black"), width, wxUSER_DASH );
1e7fd311
RR
606 wxDash dash1[1];
607 dash1[0] = 0;
608 ud.SetDashes( 1, dash1 );
696e1ea0 609 dc.DrawLine( x+20, y+140, 100, y+140 );
1e7fd311
RR
610 dash1[0] = 1;
611 ud.SetDashes( 1, dash1 );
696e1ea0 612 dc.DrawLine( x+20, y+150, 100, y+150 );
1e7fd311
RR
613 dash1[0] = 2;
614 ud.SetDashes( 1, dash1 );
696e1ea0 615 dc.DrawLine( x+20, y+160, 100, y+160 );
f6bcfd97 616 dash1[0] = 0x7F;
1e7fd311 617 ud.SetDashes( 1, dash1 );
696e1ea0 618 dc.DrawLine( x+20, y+170, 100, y+170 );
b62c3631
RR
619}
620
568708e2 621void MyCanvas::DrawDefault(wxDC& dc)
b62c3631 622{
b62c3631
RR
623 // mark the origin
624 dc.DrawCircle(0, 0, 10);
bc6abe52 625#if !(defined __WXGTK__) && !(defined __WXMOTIF__) && !(defined __WXMGL__)
70bdacfc 626 // not implemented in wxGTK or wxMOTIF :-(
b62c3631 627 dc.FloodFill(0, 0, wxColour(255, 0, 0));
70bdacfc 628#endif //
b62c3631 629
cd9da200
VZ
630 dc.DrawCheckMark(5, 80, 15, 15);
631 dc.DrawCheckMark(25, 80, 30, 30);
632 dc.DrawCheckMark(60, 80, 60, 60);
633
0e09f76e 634 // this is the test for "blitting bitmap into DC damages selected brush" bug
0e09f76e 635 wxCoord rectSize = m_std_icon.GetWidth() + 10;
cd9da200 636 wxCoord x = 100;
11f26ea0
VZ
637 dc.SetPen(*wxTRANSPARENT_PEN);
638 dc.SetBrush( *wxGREEN_BRUSH );
cd9da200 639 dc.DrawRectangle(x, 10, rectSize, rectSize);
0e09f76e 640 dc.DrawBitmap(m_std_icon, x + 5, 15, TRUE);
cd9da200
VZ
641 x += rectSize + 10;
642 dc.DrawRectangle(x, 10, rectSize, rectSize);
0e09f76e 643 dc.DrawIcon(m_std_icon, x + 5, 15);
cd9da200
VZ
644 x += rectSize + 10;
645 dc.DrawRectangle(x, 10, rectSize, rectSize);
11f26ea0
VZ
646
647 // test for "transparent" bitmap drawing (it intersects with the last
648 // rectangle above)
649 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
d6f0a4b3 650
0e09f76e
RR
651 if (m_smile_bmp.Ok())
652 dc.DrawBitmap(m_smile_bmp, x + rectSize - 20, rectSize - 10, TRUE);
107a1787 653
ff7c6c9c 654 dc.SetBrush( *wxBLACK_BRUSH );
107a1787
RR
655 dc.DrawRectangle( 0, 160, 1000, 300 );
656
657 // draw lines
658 wxBitmap bitmap(20,70);
659 wxMemoryDC memdc;
660 memdc.SelectObject( bitmap );
661 memdc.SetBrush( *wxBLACK_BRUSH );
662 memdc.SetPen( *wxWHITE_PEN );
663 memdc.DrawRectangle(0,0,20,70);
664 memdc.DrawLine( 10,0,10,70 );
81278df2 665
d4aa3a4b 666 // to the right
4c45f240 667 wxPen pen = *wxRED_PEN;
4c45f240 668 memdc.SetPen(pen);
107a1787
RR
669 memdc.DrawLine( 10, 5,10, 5 );
670 memdc.DrawLine( 10,10,11,10 );
671 memdc.DrawLine( 10,15,12,15 );
672 memdc.DrawLine( 10,20,13,20 );
81278df2 673
d4aa3a4b
RR
674/*
675 memdc.SetPen(*wxRED_PEN);
107a1787
RR
676 memdc.DrawLine( 12, 5,12, 5 );
677 memdc.DrawLine( 12,10,13,10 );
678 memdc.DrawLine( 12,15,14,15 );
679 memdc.DrawLine( 12,20,15,20 );
d4aa3a4b 680*/
81278df2 681
107a1787
RR
682 // same to the left
683 memdc.DrawLine( 10,25,10,25 );
684 memdc.DrawLine( 10,30, 9,30 );
685 memdc.DrawLine( 10,35, 8,35 );
686 memdc.DrawLine( 10,40, 7,40 );
687
688 // XOR draw lines
d4aa3a4b 689 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
690 memdc.SetLogicalFunction( wxINVERT );
691 memdc.SetPen( *wxWHITE_PEN );
692 memdc.DrawLine( 10,50,10,50 );
693 memdc.DrawLine( 10,55,11,55 );
694 memdc.DrawLine( 10,60,12,60 );
695 memdc.DrawLine( 10,65,13,65 );
81278df2 696
107a1787
RR
697 memdc.DrawLine( 12,50,12,50 );
698 memdc.DrawLine( 12,55,13,55 );
699 memdc.DrawLine( 12,60,14,60 );
700 memdc.DrawLine( 12,65,15,65 );
81278df2 701
107a1787
RR
702 memdc.SelectObject( wxNullBitmap );
703 dc.DrawBitmap( bitmap, 10, 170 );
704 wxImage image( bitmap );
705 image.Rescale( 60,210 );
706 bitmap = image.ConvertToBitmap();
707 dc.DrawBitmap( bitmap, 50, 170 );
81278df2 708
b9de1315 709 // test the rectangle outline drawing - there should be one pixel between
ff7c6c9c
RR
710 // the rect and the lines
711 dc.SetPen(*wxWHITE_PEN);
712 dc.SetBrush( *wxTRANSPARENT_BRUSH );
ff7c6c9c 713 dc.DrawRectangle(150, 170, 49, 29);
107a1787 714 dc.DrawRectangle(200, 170, 49, 29);
ff7c6c9c 715 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
716 dc.DrawLine(250, 210, 250, 170);
717 dc.DrawLine(260, 200, 150, 200);
b9de1315
VZ
718
719 // test the rectangle filled drawing - there should be one pixel between
ff7c6c9c
RR
720 // the rect and the lines
721 dc.SetPen(*wxTRANSPARENT_PEN);
722 dc.SetBrush( *wxWHITE_BRUSH );
723 dc.DrawRectangle(300, 170, 49, 29);
568708e2 724 dc.DrawRectangle(350, 170, 49, 29);
ff7c6c9c 725 dc.SetPen(*wxWHITE_PEN);
b9de1315
VZ
726 dc.DrawLine(400, 170, 400, 210);
727 dc.DrawLine(300, 200, 410, 200);
728
3d2d8da1
RR
729 // a few more tests of this kind
730 dc.SetPen(*wxRED_PEN);
731 dc.SetBrush( *wxWHITE_BRUSH );
732 dc.DrawRectangle(300, 220, 1, 1);
733 dc.DrawRectangle(310, 220, 2, 2);
734 dc.DrawRectangle(320, 220, 3, 3);
735 dc.DrawRectangle(330, 220, 4, 4);
736
737 dc.SetPen(*wxTRANSPARENT_PEN);
738 dc.SetBrush( *wxWHITE_BRUSH );
739 dc.DrawRectangle(300, 230, 1, 1);
740 dc.DrawRectangle(310, 230, 2, 2);
741 dc.DrawRectangle(320, 230, 3, 3);
742 dc.DrawRectangle(330, 230, 4, 4);
743
b9de1315
VZ
744 // and now for filled rect with outline
745 dc.SetPen(*wxRED_PEN);
746 dc.SetBrush( *wxWHITE_BRUSH );
747 dc.DrawRectangle(500, 170, 49, 29);
748 dc.DrawRectangle(550, 170, 49, 29);
749 dc.SetPen(*wxWHITE_PEN);
750 dc.DrawLine(600, 170, 600, 210);
751 dc.DrawLine(500, 200, 610, 200);
752
753 // test the rectangle outline drawing - there should be one pixel between
ff7c6c9c
RR
754 // the rect and the lines
755 dc.SetPen(*wxWHITE_PEN);
756 dc.SetBrush( *wxTRANSPARENT_BRUSH );
ff7c6c9c 757 dc.DrawRoundedRectangle(150, 270, 49, 29, 6);
107a1787 758 dc.DrawRoundedRectangle(200, 270, 49, 29, 6);
ff7c6c9c 759 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
760 dc.DrawLine(250, 270, 250, 310);
761 dc.DrawLine(150, 300, 260, 300);
b9de1315
VZ
762
763 // test the rectangle filled drawing - there should be one pixel between
ff7c6c9c
RR
764 // the rect and the lines
765 dc.SetPen(*wxTRANSPARENT_PEN);
766 dc.SetBrush( *wxWHITE_BRUSH );
767 dc.DrawRoundedRectangle(300, 270, 49, 29, 6);
768 dc.DrawRoundedRectangle(350, 270, 49, 29, 6);
769 dc.SetPen(*wxWHITE_PEN);
b9de1315
VZ
770 dc.DrawLine(400, 270, 400, 310);
771 dc.DrawLine(300, 300, 410, 300);
ff7c6c9c 772
b14c14ff
JS
773 // Added by JACS to demonstrate bizarre behaviour.
774 // With a size of 70, we get a missing red RHS,
775 // and the hight is too small, so we get yellow
776 // showing. With a size of 40, it draws as expected:
777 // it just shows a white rectangle with red outline.
778 int totalWidth = 70;
779 int totalHeight = 70;
780 wxBitmap bitmap2(totalWidth, totalHeight);
781
782 wxMemoryDC memdc2;
783 memdc2.SelectObject(bitmap2);
784
d6f0a4b3
JS
785 wxBrush yellowBrush(wxColour(255, 255, 0), wxSOLID);
786 memdc2.SetBackground(yellowBrush);
787 memdc2.Clear();
b14c14ff 788
d6f0a4b3 789 wxPen yellowPen(wxColour(255, 255, 0), 1, wxSOLID);
b14c14ff
JS
790
791 // Now draw a white rectangle with red outline. It should
792 // entirely eclipse the yellow background.
793 memdc2.SetPen(*wxRED_PEN);
794 memdc2.SetBrush(*wxWHITE_BRUSH);
795
796 memdc2.DrawRectangle(0, 0, totalWidth, totalHeight);
797
b14c14ff
JS
798 memdc2.SetPen(wxNullPen);
799 memdc2.SetBrush(wxNullBrush);
cd9da200 800 memdc2.SelectObject(wxNullBitmap);
b14c14ff
JS
801
802 dc.DrawBitmap(bitmap2, 500, 270);
d6f0a4b3
JS
803
804 // Repeat, but draw directly on dc
805 // Draw a yellow rectangle filling the bitmap
806
807 x = 600; int y = 270;
808 dc.SetPen(yellowPen);
809 dc.SetBrush(yellowBrush);
810 dc.DrawRectangle(x, y, totalWidth, totalHeight);
811
812 // Now draw a white rectangle with red outline. It should
813 // entirely eclipse the yellow background.
814 dc.SetPen(*wxRED_PEN);
815 dc.SetBrush(*wxWHITE_BRUSH);
816
817 dc.DrawRectangle(x, y, totalWidth, totalHeight);
568708e2
VZ
818}
819
820void MyCanvas::DrawText(wxDC& dc)
821{
9a8c7620
VZ
822 // set underlined font for testing
823 dc.SetFont( wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, TRUE) );
b62c3631 824 dc.DrawText( "This is text", 110, 10 );
4786aabd 825 dc.DrawRotatedText( "That is text", 20, 10, -45 );
9a8c7620 826
4770df95
VZ
827 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
828 // under Win9x (it is not TrueType)
829 dc.SetFont( *wxSWISS_FONT );
b62c3631 830
696e1ea0 831 wxString text;
f6bcfd97 832 dc.SetBackgroundMode(wxTRANSPARENT);
696e1ea0
VZ
833
834 for ( int n = -180; n < 180; n += 30 )
835 {
4693b20c 836 text.Printf(wxT(" %d rotated text"), n);
696e1ea0
VZ
837 dc.DrawRotatedText(text , 400, 400, n);
838 }
95724b1a 839
196c87f4 840 dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) );
c45a644e
RR
841
842 dc.DrawText( "This is Swiss 18pt text.", 110, 40 );
843
844 long length;
845 long height;
846 long descent;
847 dc.GetTextExtent( "This is Swiss 18pt text.", &length, &height, &descent );
4693b20c 848 text.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length, height, descent );
c45a644e
RR
849 dc.DrawText( text, 110, 80 );
850
4693b20c 851 text.Printf( wxT("CharHeight() returns: %d"), dc.GetCharHeight() );
c45a644e
RR
852 dc.DrawText( text, 110, 120 );
853
568708e2 854 dc.DrawRectangle( 100, 40, 4, height );
f6bcfd97
BP
855
856 // test the logical function effect
857 wxCoord y = 150;
858 dc.SetLogicalFunction(wxINVERT);
859 dc.DrawText( "There should be no text below", 110, 150 );
860 dc.DrawRectangle( 110, y, 100, height );
861
862 // twice drawn inverted should result in invisible
863 y += height;
864 dc.DrawText( "Invisible text", 110, y );
865 dc.DrawRectangle( 110, y, 100, height );
866 dc.DrawText( "Invisible text", 110, y );
867 dc.DrawRectangle( 110, y, 100, height );
868 dc.SetLogicalFunction(wxCOPY);
869
870 y += height;
871 dc.DrawRectangle( 110, y, 100, height );
872 dc.DrawText( "Visible text", 110, y );
568708e2
VZ
873}
874
81278df2 875static const struct
568708e2 876{
81278df2
VZ
877 const wxChar *name;
878 int rop;
879} rasterOperations[] =
880{
4693b20c
MB
881 { wxT("wxAND"), wxAND },
882 { wxT("wxAND_INVERT"), wxAND_INVERT },
883 { wxT("wxAND_REVERSE"), wxAND_REVERSE },
884 { wxT("wxCLEAR"), wxCLEAR },
885 { wxT("wxCOPY"), wxCOPY },
886 { wxT("wxEQUIV"), wxEQUIV },
887 { wxT("wxINVERT"), wxINVERT },
888 { wxT("wxNAND"), wxNAND },
889 { wxT("wxNO_OP"), wxNO_OP },
890 { wxT("wxOR"), wxOR },
891 { wxT("wxOR_INVERT"), wxOR_INVERT },
892 { wxT("wxOR_REVERSE"), wxOR_REVERSE },
893 { wxT("wxSET"), wxSET },
894 { wxT("wxSRC_INVERT"), wxSRC_INVERT },
895 { wxT("wxXOR"), wxXOR },
81278df2 896};
568708e2 897
81278df2
VZ
898void MyCanvas::DrawImages(wxDC& dc)
899{
568708e2 900 dc.DrawText("original image", 0, 0);
f6bcfd97 901 dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0);
568708e2 902 dc.DrawText("with colour mask", 0, 100);
f6bcfd97 903 dc.DrawBitmap(*gs_bmpWithColMask, 0, 120, TRUE);
568708e2 904 dc.DrawText("the mask image", 0, 200);
f6bcfd97 905 dc.DrawBitmap(*gs_bmpMask, 0, 220, 0);
568708e2 906 dc.DrawText("masked image", 0, 300);
f6bcfd97 907 dc.DrawBitmap(*gs_bmpWithMask, 0, 320, TRUE);
568708e2 908
f6bcfd97
BP
909 int cx = gs_bmpWithColMask->GetWidth(),
910 cy = gs_bmpWithColMask->GetHeight();
568708e2
VZ
911
912 wxMemoryDC memDC;
913 for ( size_t n = 0; n < WXSIZEOF(rasterOperations); n++ )
914 {
915 wxCoord x = 120 + 150*(n%4),
916 y = 20 + 100*(n/4);
4786aabd 917
568708e2 918 dc.DrawText(rasterOperations[n].name, x, y - 20);
f6bcfd97 919 memDC.SelectObject(*gs_bmpWithColMask);
568708e2
VZ
920 dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, TRUE);
921 }
922}
923
81278df2
VZ
924void MyCanvas::DrawWithLogicalOps(wxDC& dc)
925{
926 static const wxCoord w = 60;
927 static const wxCoord h = 60;
928
929 // reuse the text colour here
930 dc.SetPen(wxPen(m_owner->m_colourForeground, 1, wxSOLID));
11f26ea0 931 dc.SetBrush(*wxTRANSPARENT_BRUSH);
81278df2 932
5888ef1e
VZ
933 size_t n;
934 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
81278df2
VZ
935 {
936 wxCoord x = 20 + 150*(n%4),
937 y = 20 + 100*(n/4);
938
939 dc.DrawText(rasterOperations[n].name, x, y - 20);
940 dc.SetLogicalFunction(rasterOperations[n].rop);
11f26ea0 941 dc.DrawRectangle(x, y, w, h);
81278df2
VZ
942 dc.DrawLine(x, y, x + w, y + h);
943 dc.DrawLine(x + w, y, x, y + h);
944 }
c1d139da
GRG
945
946 // now some filled rectangles
947 dc.SetBrush(wxBrush(m_owner->m_colourForeground, wxSOLID));
948
5888ef1e 949 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
c1d139da
GRG
950 {
951 wxCoord x = 20 + 150*(n%4),
952 y = 500 + 100*(n/4);
953
954 dc.DrawText(rasterOperations[n].name, x, y - 20);
955 dc.SetLogicalFunction(rasterOperations[n].rop);
956 dc.DrawRectangle(x, y, w, h);
957 }
81278df2
VZ
958}
959
f6bcfd97
BP
960void MyCanvas::DrawCircles(wxDC& dc)
961{
962 int x = 100,
963 y = 100,
964 r = 20;
965
966 dc.DrawText("Some circles", 0, y);
967 dc.DrawCircle(x, y, r);
968 dc.DrawCircle(x + 2*r, y, r);
969 dc.DrawCircle(x + 4*r, y, r);
970
971 y += 2*r;
972 dc.DrawText("And ellipses", 0, y);
973 dc.DrawEllipse(x - r, y, 2*r, r);
974 dc.DrawEllipse(x + r, y, 2*r, r);
975 dc.DrawEllipse(x + 3*r, y, 2*r, r);
976
977 y += 2*r;
978 dc.DrawText("And arcs", 0, y);
979 dc.DrawArc(x - r, y, x + r, y, x, y);
980 dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y);
981 dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y);
982
983 y += 2*r;
984 dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90);
985 dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
986 dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
987 dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
988}
989
bc3cedfa
RR
990void MyCanvas::DrawRegions(wxDC& dc)
991{
c4218a74
VZ
992 dc.DrawText("You should see a red rect partly covered by a cyan one "
993 "on the left", 10, 5);
994 dc.DrawText("and 5 smileys from which 4 are partially clipped on the "
8e0e4b1b
VZ
995 "right (2 copies should be identical)",
996 10, 5 + dc.GetCharHeight());
997
998 DrawRegionsHelper(dc, 10);
999 DrawRegionsHelper(dc, 350);
1000}
c4218a74 1001
8e0e4b1b
VZ
1002void MyCanvas::DrawRegionsHelper(wxDC& dc, wxCoord x)
1003{
1004 dc.DestroyClippingRegion();
bc3cedfa
RR
1005 dc.SetBrush( *wxWHITE_BRUSH );
1006 dc.SetPen( *wxTRANSPARENT_PEN );
8e0e4b1b 1007 dc.DrawRectangle( x,50,310,310 );
c4218a74 1008
8e0e4b1b 1009 dc.SetClippingRegion( x+10,60,100,270 );
c4218a74 1010
bc3cedfa 1011 dc.SetBrush( *wxRED_BRUSH );
8e0e4b1b 1012 dc.DrawRectangle( x,50,310,310 );
c4218a74 1013
8e0e4b1b 1014 dc.SetClippingRegion( x+10,60,100,100 );
993f97ee 1015
993f97ee 1016 dc.SetBrush( *wxCYAN_BRUSH );
8e0e4b1b 1017 dc.DrawRectangle( x,50,310,310 );
993f97ee 1018
8e0e4b1b
VZ
1019 // when drawing the left half, destroy the clipping region, when drawing
1020 // the right one - leave it
1021 //
1022 // normally it shouldn't make any difference as SetClippingRegion()
1023 // replaces the old clipping region
1024 if ( x < 300 )
1025 dc.DestroyClippingRegion();
1026 dc.SetClippingRegion( x+110,70,100,270 );
c4218a74 1027
bc3cedfa 1028 dc.SetBrush( *wxGREY_BRUSH );
8e0e4b1b 1029 dc.DrawRectangle( x,50,310,310 );
c4218a74 1030
5d25c050
RR
1031 if (m_smile_bmp.Ok())
1032 {
8e0e4b1b
VZ
1033 dc.DrawBitmap( m_smile_bmp, x+150, 200, TRUE );
1034 dc.DrawBitmap( m_smile_bmp, x+130, 60, TRUE );
1035 dc.DrawBitmap( m_smile_bmp, x+130, 330, TRUE );
1036 dc.DrawBitmap( m_smile_bmp, x+100, 120, TRUE );
1037 dc.DrawBitmap( m_smile_bmp, x+200, 120, TRUE );
5d25c050 1038 }
bc3cedfa
RR
1039}
1040
568708e2
VZ
1041void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
1042{
1043 wxPaintDC dc(this);
1044 PrepareDC(dc);
c4218a74 1045
568708e2
VZ
1046 m_owner->PrepareDC(dc);
1047
1048 dc.SetBackgroundMode( m_owner->m_backgroundMode );
1049 if ( m_owner->m_backgroundBrush.Ok() )
1050 dc.SetBackground( m_owner->m_backgroundBrush );
1051 if ( m_owner->m_colourForeground.Ok() )
1052 dc.SetTextForeground( m_owner->m_colourForeground );
1053 if ( m_owner->m_colourBackground.Ok() )
1054 dc.SetTextBackground( m_owner->m_colourBackground );
4786aabd 1055
1edc9f45 1056 if ( m_owner->m_textureBackground) {
047473c9 1057 if ( ! m_owner->m_backgroundBrush.Ok() ) {
1edc9f45
RD
1058 wxBrush b(wxColour(0,128,0), wxSOLID);
1059 dc.SetBackground(b);
1060 }
047473c9
RD
1061 }
1062
e1208c31 1063 dc.Clear();
1edc9f45 1064
047473c9 1065 if ( m_owner->m_textureBackground) {
1edc9f45
RD
1066 dc.SetPen(*wxMEDIUM_GREY_PEN);
1067 for (int i=0; i<200; i++)
1068 dc.DrawLine(0, i*10, i*10, 0);
1069 }
1070
568708e2
VZ
1071 switch ( m_show )
1072 {
1073 case Show_Default:
1074 DrawDefault(dc);
1075 break;
1e7fd311 1076
f6bcfd97
BP
1077 case Show_Circles:
1078 DrawCircles(dc);
1079 break;
1080
bc3cedfa
RR
1081 case Show_Regions:
1082 DrawRegions(dc);
1083 break;
1084
568708e2
VZ
1085 case Show_Text:
1086 DrawText(dc);
1087 break;
1e7fd311 1088
568708e2
VZ
1089 case Show_Lines:
1090 DrawTestLines( 0, 100, 0, dc );
f6bcfd97
BP
1091 DrawTestLines( 0, 320, 1, dc );
1092 DrawTestLines( 0, 540, 2, dc );
1093 DrawTestLines( 0, 760, 6, dc );
568708e2 1094 break;
1e7fd311 1095
568708e2
VZ
1096 case Show_Polygons:
1097 DrawTestPoly( 0, 100, dc, 0 );
e1208c31 1098/*
568708e2
VZ
1099 DrawTestPoly( 33, 500, dc, 1 );
1100 DrawTestPoly( 43, 1000, dc, 2 );
e1208c31 1101*/
568708e2 1102 break;
1e7fd311 1103
568708e2
VZ
1104 case Show_Mask:
1105 DrawImages(dc);
1106 break;
81278df2
VZ
1107
1108 case Show_Ops:
1109 DrawWithLogicalOps(dc);
1110 break;
c4218a74 1111
3ca6a5f0
BP
1112 default:
1113 {
1114 dc.SetPen( *wxBLACK_PEN );
1115 dc.DrawLine( 0,0,100,100 );
1116 }
c4218a74 1117
568708e2 1118 }
b62c3631
RR
1119}
1120
bf0c00c6
RR
1121void MyCanvas::OnMouseMove(wxMouseEvent &event)
1122{
1123 wxClientDC dc(this);
1124 PrepareDC(dc);
1125 m_owner->PrepareDC(dc);
1126
1127 wxPoint pos = event.GetPosition();
1128 long x = dc.DeviceToLogicalX( pos.x );
1129 long y = dc.DeviceToLogicalY( pos.y );
1130 wxString str;
4693b20c 1131 str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y );
bf0c00c6
RR
1132 m_owner->SetStatusText( str );
1133}
1134
b62c3631
RR
1135// ----------------------------------------------------------------------------
1136// MyFrame
1137// ----------------------------------------------------------------------------
1138
1139// the event tables connect the wxWindows events with the functions (event
1140// handlers) which process them. It can be also done at run-time, but for the
1141// simple menu events like this the static method is much simpler.
1142BEGIN_EVENT_TABLE(MyFrame, wxFrame)
568708e2
VZ
1143 EVT_MENU (File_Quit, MyFrame::OnQuit)
1144 EVT_MENU (File_About, MyFrame::OnAbout)
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)
c4218a74
VZ
1153 : wxFrame((wxFrame *)NULL, -1, title, pos, size,
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;
568708e2
VZ
1160 menuFile->Append(File_ShowDefault, "&Default screen\tF1");
1161 menuFile->Append(File_ShowText, "&Text screen\tF2");
1162 menuFile->Append(File_ShowLines, "&Lines screen\tF3");
1163 menuFile->Append(File_ShowPolygons, "&Polygons screen\tF4");
1164 menuFile->Append(File_ShowMask, "wx&Mask screen\tF5");
81278df2 1165 menuFile->Append(File_ShowOps, "&ROP screen\tF6");
f6bcfd97
BP
1166 menuFile->Append(File_ShowRegions, "Re&gions screen\tF7");
1167 menuFile->Append(File_ShowCircles, "&Circles screen\tF8");
568708e2
VZ
1168 menuFile->AppendSeparator();
1169 menuFile->Append(File_About, "&About...\tCtrl-A", "Show about dialog");
aba99005 1170 menuFile->AppendSeparator();
568708e2 1171 menuFile->Append(File_Quit, "E&xit\tAlt-X", "Quit this program");
0f0c61d0 1172
aba99005
RR
1173 wxMenu *menuMapMode = new wxMenu;
1174 menuMapMode->Append( MapMode_Text, "&TEXT map mode" );
1175 menuMapMode->Append( MapMode_Lometric, "&LOMETRIC map mode" );
1176 menuMapMode->Append( MapMode_Twips, "T&WIPS map mode" );
1177 menuMapMode->Append( MapMode_Points, "&POINTS map mode" );
1178 menuMapMode->Append( MapMode_Metric, "&METRIC map mode" );
0f0c61d0 1179
aba99005 1180 wxMenu *menuUserScale = new wxMenu;
ed43910d
RR
1181 menuUserScale->Append( UserScale_StretchHoriz, "Stretch horizontally\tCtrl-H" );
1182 menuUserScale->Append( UserScale_ShrinkHoriz, "Shrink horizontally\tCtrl-G" );
1183 menuUserScale->Append( UserScale_StretchVertic, "Stretch vertically\tCtrl-V" );
1184 menuUserScale->Append( UserScale_ShrinkVertic, "Shrink vertically\tCtrl-W" );
0f0c61d0
VZ
1185 menuUserScale->AppendSeparator();
1186 menuUserScale->Append( UserScale_Restore, "Restore to normal\tCtrl-0" );
1187
aba99005 1188 wxMenu *menuAxis = new wxMenu;
220af862
VZ
1189 menuAxis->Append( AxisMirror_Horiz, "Mirror horizontally\tCtrl-M", "", TRUE );
1190 menuAxis->Append( AxisMirror_Vertic, "Mirror vertically\tCtrl-N", "", TRUE );
0f0c61d0 1191
aba99005
RR
1192 wxMenu *menuLogical = new wxMenu;
1193 menuLogical->Append( LogicalOrigin_MoveDown, "Move &down\tCtrl-D" );
1194 menuLogical->Append( LogicalOrigin_MoveUp, "Move &up\tCtrl-U" );
1195 menuLogical->Append( LogicalOrigin_MoveLeft, "Move &right\tCtrl-L" );
1196 menuLogical->Append( LogicalOrigin_MoveRight, "Move &left\tCtrl-R" );
1197
0f0c61d0
VZ
1198 wxMenu *menuColour = new wxMenu;
1199 menuColour->Append( Colour_TextForeground, "Text foreground..." );
1200 menuColour->Append( Colour_TextBackground, "Text background..." );
1201 menuColour->Append( Colour_Background, "Background colour..." );
1202 menuColour->Append( Colour_BackgroundMode, "Opaque/transparent\tCtrl-B", "", TRUE );
1edc9f45 1203 menuColour->Append( Colour_TextureBackgound, "Draw textured background\tCtrl-T", "", TRUE);
0f0c61d0 1204
aba99005
RR
1205 // now append the freshly created menu to the menu bar...
1206 wxMenuBar *menuBar = new wxMenuBar;
1207 menuBar->Append(menuFile, "&File");
1208 menuBar->Append(menuMapMode, "&MapMode");
1209 menuBar->Append(menuUserScale, "&UserScale");
1210 menuBar->Append(menuAxis, "&Axis");
1211 menuBar->Append(menuLogical, "&LogicalOrigin");
0f0c61d0 1212 menuBar->Append(menuColour, "&Colours");
aba99005
RR
1213
1214 // ... and attach this menu bar to the frame
1215 SetMenuBar(menuBar);
1216
1217 // create a status bar just for fun (by default with 1 pane only)
1218 CreateStatusBar(2);
1219 SetStatusText("Welcome to wxWindows!");
0f0c61d0 1220
aba99005
RR
1221 m_mapMode = wxMM_TEXT;
1222 m_xUserScale = 1.0;
1223 m_yUserScale = 1.0;
1224 m_xLogicalOrigin = 0;
1225 m_yLogicalOrigin = 0;
0f0c61d0
VZ
1226 m_xAxisReversed =
1227 m_yAxisReversed = FALSE;
1228 m_backgroundMode = wxSOLID;
b97fa7cf
VZ
1229 m_colourForeground = *wxRED;
1230 m_colourBackground = *wxBLUE;
1edc9f45 1231 m_textureBackground = FALSE;
aba99005 1232
b62c3631 1233 m_canvas = new MyCanvas( this );
b97fa7cf 1234 m_canvas->SetScrollbars( 10, 10, 100, 240 );
b62c3631 1235}
aba99005
RR
1236
1237// event handlers
1238
1239void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1240{
1241 // TRUE is to force the frame to close
1242 Close(TRUE);
1243}
1244
1245void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1246{
1247 wxString msg;
c916e13b
RR
1248 msg.Printf( wxT("This is the about dialog of the drawing sample.\n")
1249 wxT("This sample tests various primitive drawing functions\n")
1250 wxT("without any tests to prevent flicker.\n")
1251 wxT("Copyright (c) Robert Roebling 1999")
aba99005
RR
1252 );
1253
1254 wxMessageBox(msg, "About Drawing", wxOK | wxICON_INFORMATION, this);
1255}
1256
568708e2
VZ
1257void MyFrame::OnShow(wxCommandEvent& event)
1258{
3ca6a5f0 1259 m_canvas->Show((ScreenToShow)(event.GetId() - MenuShow_First));
568708e2
VZ
1260}
1261
1262void MyFrame::OnOption(wxCommandEvent& event)
aba99005 1263{
3ca6a5f0 1264 switch (event.GetId())
aba99005
RR
1265 {
1266 case MapMode_Text:
b9857632 1267 m_mapMode = wxMM_TEXT;
0f0c61d0 1268 break;
aba99005
RR
1269 case MapMode_Lometric:
1270 m_mapMode = wxMM_LOMETRIC;
0f0c61d0
VZ
1271 break;
1272 case MapMode_Twips:
aba99005 1273 m_mapMode = wxMM_TWIPS;
0f0c61d0
VZ
1274 break;
1275 case MapMode_Points:
aba99005 1276 m_mapMode = wxMM_POINTS;
0f0c61d0
VZ
1277 break;
1278 case MapMode_Metric:
aba99005 1279 m_mapMode = wxMM_METRIC;
0f0c61d0
VZ
1280 break;
1281
1282 case LogicalOrigin_MoveDown:
1283 m_yLogicalOrigin += 10;
1284 break;
1285 case LogicalOrigin_MoveUp:
1286 m_yLogicalOrigin -= 10;
1287 break;
1288 case LogicalOrigin_MoveLeft:
1289 m_xLogicalOrigin += 10;
1290 break;
1291 case LogicalOrigin_MoveRight:
1292 m_xLogicalOrigin -= 10;
1293 break;
1294
1295 case UserScale_StretchHoriz:
1296 m_xUserScale *= 1.10;
1297 break;
1298 case UserScale_ShrinkHoriz:
1299 m_xUserScale /= 1.10;
1300 break;
1301 case UserScale_StretchVertic:
1302 m_yUserScale *= 1.10;
1303 break;
1304 case UserScale_ShrinkVertic:
1305 m_yUserScale /= 1.10;
1306 break;
1307 case UserScale_Restore:
1308 m_xUserScale =
1309 m_yUserScale = 1.0;
1310 break;
1311
1312 case AxisMirror_Vertic:
1313 m_yAxisReversed = !m_yAxisReversed;
1314 break;
1315 case AxisMirror_Horiz:
1316 m_xAxisReversed = !m_xAxisReversed;
1317 break;
1318
1319 case Colour_TextForeground:
1320 m_colourForeground = SelectColour();
1321 break;
1322 case Colour_TextBackground:
1323 m_colourBackground = SelectColour();
1324 break;
1325 case Colour_Background:
1326 {
1327 wxColour col = SelectColour();
1328 if ( col.Ok() )
1329 {
1330 m_backgroundBrush.SetColour(col);
1331 }
1332 }
1333 break;
1334 case Colour_BackgroundMode:
1335 m_backgroundMode = m_backgroundMode == wxSOLID ? wxTRANSPARENT
1336 : wxSOLID;
1337 break;
1338
1edc9f45
RD
1339 case Colour_TextureBackgound:
1340 m_textureBackground = ! m_textureBackground;
1341 break;
1342
0f0c61d0
VZ
1343 default:
1344 // skip Refresh()
1345 return;
aba99005 1346 }
0f0c61d0 1347
1e7fd311 1348 m_canvas->Refresh();
aba99005
RR
1349}
1350
220af862 1351void MyFrame::PrepareDC(wxDC& dc)
aba99005 1352{
0f0c61d0
VZ
1353 dc.SetMapMode( m_mapMode );
1354 dc.SetUserScale( m_xUserScale, m_yUserScale );
1355 dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin );
428db2ea 1356 dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed );
220af862
VZ
1357}
1358
220af862 1359wxColour MyFrame::SelectColour()
0f0c61d0
VZ
1360{
1361 wxColour col;
1362 wxColourData data;
1363 wxColourDialog dialog(this, &data);
1364
1365 if ( dialog.ShowModal() == wxID_OK )
1366 {
428db2ea 1367 col = dialog.GetColourData().GetColour();
0f0c61d0
VZ
1368 }
1369
1370 return col;
aba99005 1371}