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