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