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