docs and example for wxDC::DrawPolyPolygon() (patch 882189)
[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 #if defined(__GNUG__) && !defined(__APPLE__)
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 ToShow(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(_T("."));
272 pathList.Add(_T(".."));
273
274 wxString path = pathList.FindValidPath(_T("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(_T("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(_T("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(_T("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(_T("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 m_clip = FALSE;
381 }
382
383 void MyCanvas::DrawTestBrushes(wxDC& dc)
384 {
385 static const wxCoord WIDTH = 200;
386 static const wxCoord HEIGHT = 80;
387
388 wxCoord x = 10,
389 y = 10;
390
391 dc.SetBrush(wxBrush(*wxGREEN, wxSOLID));
392 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
393 dc.DrawText(_T("Solid green"), x + 10, y + 10);
394
395 y += HEIGHT;
396 dc.SetBrush(wxBrush(*wxRED, wxCROSSDIAG_HATCH));
397 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
398 dc.DrawText(_T("Hatched red"), x + 10, y + 10);
399
400 y += HEIGHT;
401 dc.SetBrush(wxBrush(*gs_bmpMask));
402 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
403 dc.DrawText(_T("Stipple mono"), x + 10, y + 10);
404
405 y += HEIGHT;
406 dc.SetBrush(wxBrush(*gs_bmpNoMask));
407 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
408 dc.DrawText(_T("Stipple colour"), x + 10, y + 10);
409 }
410
411 void MyCanvas::DrawTestPoly(wxDC& dc)
412 {
413 wxBrush brushHatch(*wxRED, wxFDIAGONAL_HATCH);
414 dc.SetBrush(brushHatch);
415
416 wxPoint star[5];
417 star[0] = wxPoint(100, 60);
418 star[1] = wxPoint(60, 150);
419 star[2] = wxPoint(160, 100);
420 star[3] = wxPoint(40, 100);
421 star[4] = wxPoint(140, 150);
422
423 dc.DrawText(_T("You should see two (irregular) stars below, the left one ")
424 _T("hatched"), 10, 10);
425 dc.DrawText(_T("except for the central region and the right ")
426 _T("one entirely hatched"), 10, 30);
427 dc.DrawText(_T("The third star only has a hatched outline"), 10, 50);
428
429 dc.DrawPolygon(WXSIZEOF(star), star, 0, 30);
430 dc.DrawPolygon(WXSIZEOF(star), star, 160, 30, wxWINDING_RULE);
431
432 wxPoint star2[10];
433 star2[0] = wxPoint(0, 100);
434 star2[1] = wxPoint(-59, -81);
435 star2[2] = wxPoint(95, 31);
436 star2[3] = wxPoint(-95, 31);
437 star2[4] = wxPoint(59, -81);
438 star2[5] = wxPoint(0, 80);
439 star2[6] = wxPoint(-47, -64);
440 star2[7] = wxPoint(76, 24);
441 star2[8] = wxPoint(-76, 24);
442 star2[9] = wxPoint(47, -64);
443 int count[2] = {5, 5};
444
445 dc.DrawPolyPolygon(WXSIZEOF(count), count, star2, 450, 150);
446 }
447
448 void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc )
449 {
450 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
451 dc.SetBrush( *wxRED_BRUSH );
452 dc.DrawText(wxString::Format(wxT("Testing lines of width %d"), width), x + 10, y - 10);
453 dc.DrawRectangle( x+10, y+10, 100, 190 );
454
455 dc.DrawText(_T("Solid/dot/short dash/long dash/dot dash"), x + 150, y + 10);
456 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
457 dc.DrawLine( x+20, y+20, 100, y+20 );
458 dc.SetPen( wxPen( wxT("black"), width, wxDOT) );
459 dc.DrawLine( x+20, y+30, 100, y+30 );
460 dc.SetPen( wxPen( wxT("black"), width, wxSHORT_DASH) );
461 dc.DrawLine( x+20, y+40, 100, y+40 );
462 dc.SetPen( wxPen( wxT("black"), width, wxLONG_DASH) );
463 dc.DrawLine( x+20, y+50, 100, y+50 );
464 dc.SetPen( wxPen( wxT("black"), width, wxDOT_DASH) );
465 dc.DrawLine( x+20, y+60, 100, y+60 );
466
467 dc.DrawText(_T("Misc hatches"), x + 150, y + 70);
468 dc.SetPen( wxPen( wxT("black"), width, wxBDIAGONAL_HATCH) );
469 dc.DrawLine( x+20, y+70, 100, y+70 );
470 dc.SetPen( wxPen( wxT("black"), width, wxCROSSDIAG_HATCH) );
471 dc.DrawLine( x+20, y+80, 100, y+80 );
472 dc.SetPen( wxPen( wxT("black"), width, wxFDIAGONAL_HATCH) );
473 dc.DrawLine( x+20, y+90, 100, y+90 );
474 dc.SetPen( wxPen( wxT("black"), width, wxCROSS_HATCH) );
475 dc.DrawLine( x+20, y+100, 100, y+100 );
476 dc.SetPen( wxPen( wxT("black"), width, wxHORIZONTAL_HATCH) );
477 dc.DrawLine( x+20, y+110, 100, y+110 );
478 dc.SetPen( wxPen( wxT("black"), width, wxVERTICAL_HATCH) );
479 dc.DrawLine( x+20, y+120, 100, y+120 );
480
481 dc.DrawText(_T("User dash"), x + 150, y + 140);
482 wxPen ud( wxT("black"), width, wxUSER_DASH );
483 wxDash dash1[6];
484 dash1[0] = 8; // Long dash <---------+
485 dash1[1] = 2; // Short gap |
486 dash1[2] = 3; // Short dash |
487 dash1[3] = 2; // Short gap |
488 dash1[4] = 3; // Short dash |
489 dash1[5] = 2; // Short gap and repeat +
490 ud.SetDashes( 6, dash1 );
491 dc.SetPen( ud );
492 dc.DrawLine( x+20, y+140, 100, y+140 );
493 dash1[0] = 5; // Make first dash shorter
494 ud.SetDashes( 6, dash1 );
495 dc.SetPen( ud );
496 dc.DrawLine( x+20, y+150, 100, y+150 );
497 dash1[2] = 5; // Make second dash longer
498 ud.SetDashes( 6, dash1 );
499 dc.SetPen( ud );
500 dc.DrawLine( x+20, y+160, 100, y+160 );
501 dash1[4] = 5; // Make third dash longer
502 ud.SetDashes( 6, dash1 );
503 dc.SetPen( ud );
504 dc.DrawLine( x+20, y+170, 100, y+170 );
505 }
506
507 void MyCanvas::DrawDefault(wxDC& dc)
508 {
509 // mark the origin
510 dc.DrawCircle(0, 0, 10);
511
512 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
513 dc.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID));
514 wxColour tmpColour ;
515 dc.GetPixel(1,1, &tmpColour);
516 dc.FloodFill(1,1, tmpColour, wxFLOOD_SURFACE);
517
518 dc.DrawCheckMark(5, 80, 15, 15);
519 dc.DrawCheckMark(25, 80, 30, 30);
520 dc.DrawCheckMark(60, 80, 60, 60);
521
522 // this is the test for "blitting bitmap into DC damages selected brush" bug
523 wxCoord rectSize = m_std_icon.GetWidth() + 10;
524 wxCoord x = 100;
525 dc.SetPen(*wxTRANSPARENT_PEN);
526 dc.SetBrush( *wxGREEN_BRUSH );
527 dc.DrawRectangle(x, 10, rectSize, rectSize);
528 dc.DrawBitmap(m_std_icon, x + 5, 15, TRUE);
529 x += rectSize + 10;
530 dc.DrawRectangle(x, 10, rectSize, rectSize);
531 dc.DrawIcon(m_std_icon, x + 5, 15);
532 x += rectSize + 10;
533 dc.DrawRectangle(x, 10, rectSize, rectSize);
534
535 // test for "transparent" bitmap drawing (it intersects with the last
536 // rectangle above)
537 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
538
539 if (m_smile_bmp.Ok())
540 dc.DrawBitmap(m_smile_bmp, x + rectSize - 20, rectSize - 10, TRUE);
541
542 dc.SetBrush( *wxBLACK_BRUSH );
543 dc.DrawRectangle( 0, 160, 1000, 300 );
544
545 // draw lines
546 wxBitmap bitmap(20,70);
547 wxMemoryDC memdc;
548 memdc.SelectObject( bitmap );
549 memdc.SetBrush( *wxBLACK_BRUSH );
550 memdc.SetPen( *wxWHITE_PEN );
551 memdc.DrawRectangle(0,0,20,70);
552 memdc.DrawLine( 10,0,10,70 );
553
554 // to the right
555 wxPen pen = *wxRED_PEN;
556 memdc.SetPen(pen);
557 memdc.DrawLine( 10, 5,10, 5 );
558 memdc.DrawLine( 10,10,11,10 );
559 memdc.DrawLine( 10,15,12,15 );
560 memdc.DrawLine( 10,20,13,20 );
561
562 /*
563 memdc.SetPen(*wxRED_PEN);
564 memdc.DrawLine( 12, 5,12, 5 );
565 memdc.DrawLine( 12,10,13,10 );
566 memdc.DrawLine( 12,15,14,15 );
567 memdc.DrawLine( 12,20,15,20 );
568 */
569
570 // same to the left
571 memdc.DrawLine( 10,25,10,25 );
572 memdc.DrawLine( 10,30, 9,30 );
573 memdc.DrawLine( 10,35, 8,35 );
574 memdc.DrawLine( 10,40, 7,40 );
575
576 // XOR draw lines
577 dc.SetPen(*wxWHITE_PEN);
578 memdc.SetLogicalFunction( wxINVERT );
579 memdc.SetPen( *wxWHITE_PEN );
580 memdc.DrawLine( 10,50,10,50 );
581 memdc.DrawLine( 10,55,11,55 );
582 memdc.DrawLine( 10,60,12,60 );
583 memdc.DrawLine( 10,65,13,65 );
584
585 memdc.DrawLine( 12,50,12,50 );
586 memdc.DrawLine( 12,55,13,55 );
587 memdc.DrawLine( 12,60,14,60 );
588 memdc.DrawLine( 12,65,15,65 );
589
590 memdc.SelectObject( wxNullBitmap );
591 dc.DrawBitmap( bitmap, 10, 170 );
592 wxImage image = bitmap.ConvertToImage();
593 image.Rescale( 60,210 );
594 bitmap = wxBitmap(image);
595 dc.DrawBitmap( bitmap, 50, 170 );
596
597 // test the rectangle outline drawing - there should be one pixel between
598 // the rect and the lines
599 dc.SetPen(*wxWHITE_PEN);
600 dc.SetBrush( *wxTRANSPARENT_BRUSH );
601 dc.DrawRectangle(150, 170, 49, 29);
602 dc.DrawRectangle(200, 170, 49, 29);
603 dc.SetPen(*wxWHITE_PEN);
604 dc.DrawLine(250, 210, 250, 170);
605 dc.DrawLine(260, 200, 150, 200);
606
607 // test the rectangle filled drawing - there should be one pixel between
608 // the rect and the lines
609 dc.SetPen(*wxTRANSPARENT_PEN);
610 dc.SetBrush( *wxWHITE_BRUSH );
611 dc.DrawRectangle(300, 170, 49, 29);
612 dc.DrawRectangle(350, 170, 49, 29);
613 dc.SetPen(*wxWHITE_PEN);
614 dc.DrawLine(400, 170, 400, 210);
615 dc.DrawLine(300, 200, 410, 200);
616
617 // a few more tests of this kind
618 dc.SetPen(*wxRED_PEN);
619 dc.SetBrush( *wxWHITE_BRUSH );
620 dc.DrawRectangle(300, 220, 1, 1);
621 dc.DrawRectangle(310, 220, 2, 2);
622 dc.DrawRectangle(320, 220, 3, 3);
623 dc.DrawRectangle(330, 220, 4, 4);
624
625 dc.SetPen(*wxTRANSPARENT_PEN);
626 dc.SetBrush( *wxWHITE_BRUSH );
627 dc.DrawRectangle(300, 230, 1, 1);
628 dc.DrawRectangle(310, 230, 2, 2);
629 dc.DrawRectangle(320, 230, 3, 3);
630 dc.DrawRectangle(330, 230, 4, 4);
631
632 // and now for filled rect with outline
633 dc.SetPen(*wxRED_PEN);
634 dc.SetBrush( *wxWHITE_BRUSH );
635 dc.DrawRectangle(500, 170, 49, 29);
636 dc.DrawRectangle(550, 170, 49, 29);
637 dc.SetPen(*wxWHITE_PEN);
638 dc.DrawLine(600, 170, 600, 210);
639 dc.DrawLine(500, 200, 610, 200);
640
641 // test the rectangle outline drawing - there should be one pixel between
642 // the rect and the lines
643 dc.SetPen(*wxWHITE_PEN);
644 dc.SetBrush( *wxTRANSPARENT_BRUSH );
645 dc.DrawRoundedRectangle(150, 270, 49, 29, 6);
646 dc.DrawRoundedRectangle(200, 270, 49, 29, 6);
647 dc.SetPen(*wxWHITE_PEN);
648 dc.DrawLine(250, 270, 250, 310);
649 dc.DrawLine(150, 300, 260, 300);
650
651 // test the rectangle filled drawing - there should be one pixel between
652 // the rect and the lines
653 dc.SetPen(*wxTRANSPARENT_PEN);
654 dc.SetBrush( *wxWHITE_BRUSH );
655 dc.DrawRoundedRectangle(300, 270, 49, 29, 6);
656 dc.DrawRoundedRectangle(350, 270, 49, 29, 6);
657 dc.SetPen(*wxWHITE_PEN);
658 dc.DrawLine(400, 270, 400, 310);
659 dc.DrawLine(300, 300, 410, 300);
660
661 // Added by JACS to demonstrate bizarre behaviour.
662 // With a size of 70, we get a missing red RHS,
663 // and the hight is too small, so we get yellow
664 // showing. With a size of 40, it draws as expected:
665 // it just shows a white rectangle with red outline.
666 int totalWidth = 70;
667 int totalHeight = 70;
668 wxBitmap bitmap2(totalWidth, totalHeight);
669
670 wxMemoryDC memdc2;
671 memdc2.SelectObject(bitmap2);
672
673 wxBrush yellowBrush(wxColour(255, 255, 0), wxSOLID);
674 memdc2.SetBackground(yellowBrush);
675 memdc2.Clear();
676
677 wxPen yellowPen(wxColour(255, 255, 0), 1, wxSOLID);
678
679 // Now draw a white rectangle with red outline. It should
680 // entirely eclipse the yellow background.
681 memdc2.SetPen(*wxRED_PEN);
682 memdc2.SetBrush(*wxWHITE_BRUSH);
683
684 memdc2.DrawRectangle(0, 0, totalWidth, totalHeight);
685
686 memdc2.SetPen(wxNullPen);
687 memdc2.SetBrush(wxNullBrush);
688 memdc2.SelectObject(wxNullBitmap);
689
690 dc.DrawBitmap(bitmap2, 500, 270);
691
692 // Repeat, but draw directly on dc
693 // Draw a yellow rectangle filling the bitmap
694
695 x = 600; int y = 270;
696 dc.SetPen(yellowPen);
697 dc.SetBrush(yellowBrush);
698 dc.DrawRectangle(x, y, totalWidth, totalHeight);
699
700 // Now draw a white rectangle with red outline. It should
701 // entirely eclipse the yellow background.
702 dc.SetPen(*wxRED_PEN);
703 dc.SetBrush(*wxWHITE_BRUSH);
704
705 dc.DrawRectangle(x, y, totalWidth, totalHeight);
706 }
707
708 void MyCanvas::DrawText(wxDC& dc)
709 {
710 // set underlined font for testing
711 dc.SetFont( wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, TRUE) );
712 dc.DrawText( _T("This is text"), 110, 10 );
713 dc.DrawRotatedText( _T("That is text"), 20, 10, -45 );
714
715 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
716 // under Win9x (it is not TrueType)
717 dc.SetFont( *wxSWISS_FONT );
718
719 wxString text;
720 dc.SetBackgroundMode(wxTRANSPARENT);
721
722 for ( int n = -180; n < 180; n += 30 )
723 {
724 text.Printf(wxT(" %d rotated text"), n);
725 dc.DrawRotatedText(text , 400, 400, n);
726 }
727
728 dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) );
729
730 dc.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
731
732 long length;
733 long height;
734 long descent;
735 dc.GetTextExtent( _T("This is Swiss 18pt text."), &length, &height, &descent );
736 text.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length, height, descent );
737 dc.DrawText( text, 110, 80 );
738
739 text.Printf( wxT("CharHeight() returns: %d"), dc.GetCharHeight() );
740 dc.DrawText( text, 110, 120 );
741
742 dc.DrawRectangle( 100, 40, 4, height );
743
744 // test the logical function effect
745 wxCoord y = 150;
746 dc.SetLogicalFunction(wxINVERT);
747 dc.DrawText( _T("There should be no text below"), 110, 150 );
748 dc.DrawRectangle( 110, y, 100, height );
749
750 // twice drawn inverted should result in invisible
751 y += height;
752 dc.DrawText( _T("Invisible text"), 110, y );
753 dc.DrawRectangle( 110, y, 100, height );
754 dc.DrawText( _T("Invisible text"), 110, y );
755 dc.DrawRectangle( 110, y, 100, height );
756 dc.SetLogicalFunction(wxCOPY);
757
758 y += height;
759 dc.DrawRectangle( 110, y, 100, height );
760 dc.DrawText( _T("Visible text"), 110, y );
761 }
762
763 static const struct
764 {
765 const wxChar *name;
766 int rop;
767 } rasterOperations[] =
768 {
769 { wxT("wxAND"), wxAND },
770 { wxT("wxAND_INVERT"), wxAND_INVERT },
771 { wxT("wxAND_REVERSE"), wxAND_REVERSE },
772 { wxT("wxCLEAR"), wxCLEAR },
773 { wxT("wxCOPY"), wxCOPY },
774 { wxT("wxEQUIV"), wxEQUIV },
775 { wxT("wxINVERT"), wxINVERT },
776 { wxT("wxNAND"), wxNAND },
777 { wxT("wxNO_OP"), wxNO_OP },
778 { wxT("wxOR"), wxOR },
779 { wxT("wxOR_INVERT"), wxOR_INVERT },
780 { wxT("wxOR_REVERSE"), wxOR_REVERSE },
781 { wxT("wxSET"), wxSET },
782 { wxT("wxSRC_INVERT"), wxSRC_INVERT },
783 { wxT("wxXOR"), wxXOR },
784 };
785
786 void MyCanvas::DrawImages(wxDC& dc)
787 {
788 dc.DrawText(_T("original image"), 0, 0);
789 dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0);
790 dc.DrawText(_T("with colour mask"), 0, 100);
791 dc.DrawBitmap(*gs_bmpWithColMask, 0, 120, TRUE);
792 dc.DrawText(_T("the mask image"), 0, 200);
793 dc.DrawBitmap(*gs_bmpMask, 0, 220, 0);
794 dc.DrawText(_T("masked image"), 0, 300);
795 dc.DrawBitmap(*gs_bmpWithMask, 0, 320, TRUE);
796
797 int cx = gs_bmpWithColMask->GetWidth(),
798 cy = gs_bmpWithColMask->GetHeight();
799
800 wxMemoryDC memDC;
801 for ( size_t n = 0; n < WXSIZEOF(rasterOperations); n++ )
802 {
803 wxCoord x = 120 + 150*(n%4),
804 y = 20 + 100*(n/4);
805
806 dc.DrawText(rasterOperations[n].name, x, y - 20);
807 memDC.SelectObject(*gs_bmpWithColMask);
808 dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, TRUE);
809 }
810 }
811
812 void MyCanvas::DrawWithLogicalOps(wxDC& dc)
813 {
814 static const wxCoord w = 60;
815 static const wxCoord h = 60;
816
817 // reuse the text colour here
818 dc.SetPen(wxPen(m_owner->m_colourForeground, 1, wxSOLID));
819 dc.SetBrush(*wxTRANSPARENT_BRUSH);
820
821 size_t n;
822 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
823 {
824 wxCoord x = 20 + 150*(n%4),
825 y = 20 + 100*(n/4);
826
827 dc.DrawText(rasterOperations[n].name, x, y - 20);
828 dc.SetLogicalFunction(rasterOperations[n].rop);
829 dc.DrawRectangle(x, y, w, h);
830 dc.DrawLine(x, y, x + w, y + h);
831 dc.DrawLine(x + w, y, x, y + h);
832 }
833
834 // now some filled rectangles
835 dc.SetBrush(wxBrush(m_owner->m_colourForeground, wxSOLID));
836
837 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
838 {
839 wxCoord x = 20 + 150*(n%4),
840 y = 500 + 100*(n/4);
841
842 dc.DrawText(rasterOperations[n].name, x, y - 20);
843 dc.SetLogicalFunction(rasterOperations[n].rop);
844 dc.DrawRectangle(x, y, w, h);
845 }
846 }
847
848 void MyCanvas::DrawCircles(wxDC& dc)
849 {
850 int x = 100,
851 y = 100,
852 r = 20;
853
854 dc.DrawText(_T("Some circles"), 0, y);
855 dc.DrawCircle(x, y, r);
856 dc.DrawCircle(x + 2*r, y, r);
857 dc.DrawCircle(x + 4*r, y, r);
858
859 y += 2*r;
860 dc.DrawText(_T("And ellipses"), 0, y);
861 dc.DrawEllipse(x - r, y, 2*r, r);
862 dc.DrawEllipse(x + r, y, 2*r, r);
863 dc.DrawEllipse(x + 3*r, y, 2*r, r);
864
865 y += 2*r;
866 dc.DrawText(_T("And arcs"), 0, y);
867 dc.DrawArc(x - r, y, x + r, y, x, y);
868 dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y);
869 dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y);
870
871 y += 2*r;
872 dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90);
873 dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
874 dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
875 dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
876 }
877
878 void MyCanvas::DrawRegions(wxDC& dc)
879 {
880 dc.DrawText(_T("You should see a red rect partly covered by a cyan one ")
881 _T("on the left"), 10, 5);
882 dc.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
883 10, 5 + dc.GetCharHeight());
884 dc.DrawText(_T("The second copy should be identical but right part of it ")
885 _T("should be offset by 10 pixels."),
886 10, 5 + 2*dc.GetCharHeight());
887
888 DrawRegionsHelper(dc, 10, TRUE);
889 DrawRegionsHelper(dc, 350, FALSE);
890 }
891
892 void MyCanvas::DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime)
893 {
894 wxCoord y = 100;
895
896 dc.DestroyClippingRegion();
897 dc.SetBrush( *wxWHITE_BRUSH );
898 dc.SetPen( *wxTRANSPARENT_PEN );
899 dc.DrawRectangle( x, y, 310, 310 );
900
901 dc.SetClippingRegion( x + 10, y + 10, 100, 270 );
902
903 dc.SetBrush( *wxRED_BRUSH );
904 dc.DrawRectangle( x, y, 310, 310 );
905
906 dc.SetClippingRegion( x + 10, y + 10, 100, 100 );
907
908 dc.SetBrush( *wxCYAN_BRUSH );
909 dc.DrawRectangle( x, y, 310, 310 );
910
911 dc.DestroyClippingRegion();
912
913 wxRegion region(x + 110, y + 20, 100, 270);
914 #if !defined(__WXMOTIF__) && !defined(__WXMAC__)
915 if ( !firstTime )
916 region.Offset(10, 10);
917 #endif
918 dc.SetClippingRegion(region);
919
920 dc.SetBrush( *wxGREY_BRUSH );
921 dc.DrawRectangle( x, y, 310, 310 );
922
923 if (m_smile_bmp.Ok())
924 {
925 dc.DrawBitmap( m_smile_bmp, x + 150, y + 150, TRUE );
926 dc.DrawBitmap( m_smile_bmp, x + 130, y + 10, TRUE );
927 dc.DrawBitmap( m_smile_bmp, x + 130, y + 280, TRUE );
928 dc.DrawBitmap( m_smile_bmp, x + 100, y + 70, TRUE );
929 dc.DrawBitmap( m_smile_bmp, x + 200, y + 70, TRUE );
930 }
931 }
932
933 void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
934 {
935 wxPaintDC dc(this);
936 PrepareDC(dc);
937
938 m_owner->PrepareDC(dc);
939
940 dc.SetBackgroundMode( m_owner->m_backgroundMode );
941 if ( m_owner->m_backgroundBrush.Ok() )
942 dc.SetBackground( m_owner->m_backgroundBrush );
943 if ( m_owner->m_colourForeground.Ok() )
944 dc.SetTextForeground( m_owner->m_colourForeground );
945 if ( m_owner->m_colourBackground.Ok() )
946 dc.SetTextBackground( m_owner->m_colourBackground );
947
948 if ( m_owner->m_textureBackground) {
949 if ( ! m_owner->m_backgroundBrush.Ok() ) {
950 wxBrush b(wxColour(0,128,0), wxSOLID);
951 dc.SetBackground(b);
952 }
953 }
954
955 if ( m_clip )
956 dc.SetClippingRegion(100, 100, 100, 100);
957
958 dc.Clear();
959
960 if ( m_owner->m_textureBackground )
961 {
962 dc.SetPen(*wxMEDIUM_GREY_PEN);
963 for ( int i = 0; i < 200; i++ )
964 dc.DrawLine(0, i*10, i*10, 0);
965 }
966
967 switch ( m_show )
968 {
969 case Show_Default:
970 DrawDefault(dc);
971 break;
972
973 case Show_Circles:
974 DrawCircles(dc);
975 break;
976
977 case Show_Regions:
978 DrawRegions(dc);
979 break;
980
981 case Show_Text:
982 DrawText(dc);
983 break;
984
985 case Show_Lines:
986 DrawTestLines( 0, 100, 0, dc );
987 DrawTestLines( 0, 320, 1, dc );
988 DrawTestLines( 0, 540, 2, dc );
989 DrawTestLines( 0, 760, 6, dc );
990 break;
991
992 case Show_Brushes:
993 DrawTestBrushes(dc);
994 break;
995
996 case Show_Polygons:
997 DrawTestPoly(dc);
998 break;
999
1000 case Show_Mask:
1001 DrawImages(dc);
1002 break;
1003
1004 case Show_Ops:
1005 DrawWithLogicalOps(dc);
1006 break;
1007 }
1008 }
1009
1010 void MyCanvas::OnMouseMove(wxMouseEvent &event)
1011 {
1012 wxClientDC dc(this);
1013 PrepareDC(dc);
1014 m_owner->PrepareDC(dc);
1015
1016 wxPoint pos = event.GetPosition();
1017 long x = dc.DeviceToLogicalX( pos.x );
1018 long y = dc.DeviceToLogicalY( pos.y );
1019 wxString str;
1020 str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y );
1021 m_owner->SetStatusText( str );
1022 }
1023
1024 // ----------------------------------------------------------------------------
1025 // MyFrame
1026 // ----------------------------------------------------------------------------
1027
1028 // the event tables connect the wxWindows events with the functions (event
1029 // handlers) which process them. It can be also done at run-time, but for the
1030 // simple menu events like this the static method is much simpler.
1031 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
1032 EVT_MENU (File_Quit, MyFrame::OnQuit)
1033 EVT_MENU (File_About, MyFrame::OnAbout)
1034 EVT_MENU (File_Clip, MyFrame::OnClip)
1035
1036 EVT_MENU_RANGE(MenuShow_First, MenuShow_Last, MyFrame::OnShow)
1037
1038 EVT_MENU_RANGE(MenuOption_First, MenuOption_Last, MyFrame::OnOption)
1039 END_EVENT_TABLE()
1040
1041 // frame constructor
1042 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
1043 : wxFrame((wxFrame *)NULL, -1, title, pos, size,
1044 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
1045 {
1046 // set the frame icon
1047 SetIcon(wxICON(mondrian));
1048
1049 wxMenu *menuFile = new wxMenu;
1050 menuFile->Append(File_ShowDefault, _T("&Default screen\tF1"));
1051 menuFile->Append(File_ShowText, _T("&Text screen\tF2"));
1052 menuFile->Append(File_ShowLines, _T("&Lines screen\tF3"));
1053 menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4"));
1054 menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5"));
1055 menuFile->Append(File_ShowMask, _T("&Mask screen\tF6"));
1056 menuFile->Append(File_ShowOps, _T("&ROP screen\tF7"));
1057 menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8"));
1058 menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9"));
1059 menuFile->AppendSeparator();
1060 menuFile->AppendCheckItem(File_Clip, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
1061 menuFile->AppendSeparator();
1062 menuFile->Append(File_About, _T("&About...\tCtrl-A"), _T("Show about dialog"));
1063 menuFile->AppendSeparator();
1064 menuFile->Append(File_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
1065
1066 wxMenu *menuMapMode = new wxMenu;
1067 menuMapMode->Append( MapMode_Text, _T("&TEXT map mode") );
1068 menuMapMode->Append( MapMode_Lometric, _T("&LOMETRIC map mode") );
1069 menuMapMode->Append( MapMode_Twips, _T("T&WIPS map mode") );
1070 menuMapMode->Append( MapMode_Points, _T("&POINTS map mode") );
1071 menuMapMode->Append( MapMode_Metric, _T("&METRIC map mode") );
1072
1073 wxMenu *menuUserScale = new wxMenu;
1074 menuUserScale->Append( UserScale_StretchHoriz, _T("Stretch &horizontally\tCtrl-H") );
1075 menuUserScale->Append( UserScale_ShrinkHoriz, _T("Shrin&k horizontally\tCtrl-G") );
1076 menuUserScale->Append( UserScale_StretchVertic, _T("Stretch &vertically\tCtrl-V") );
1077 menuUserScale->Append( UserScale_ShrinkVertic, _T("&Shrink vertically\tCtrl-W") );
1078 menuUserScale->AppendSeparator();
1079 menuUserScale->Append( UserScale_Restore, _T("&Restore to normal\tCtrl-0") );
1080
1081 wxMenu *menuAxis = new wxMenu;
1082 menuAxis->Append( AxisMirror_Horiz, _T("Mirror horizontally\tCtrl-M"), _T(""), TRUE );
1083 menuAxis->Append( AxisMirror_Vertic, _T("Mirror vertically\tCtrl-N"), _T(""), TRUE );
1084
1085 wxMenu *menuLogical = new wxMenu;
1086 menuLogical->Append( LogicalOrigin_MoveDown, _T("Move &down\tCtrl-D") );
1087 menuLogical->Append( LogicalOrigin_MoveUp, _T("Move &up\tCtrl-U") );
1088 menuLogical->Append( LogicalOrigin_MoveLeft, _T("Move &right\tCtrl-L") );
1089 menuLogical->Append( LogicalOrigin_MoveRight, _T("Move &left\tCtrl-R") );
1090 menuLogical->AppendSeparator();
1091 menuLogical->Append( LogicalOrigin_Set, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1092 menuLogical->Append( LogicalOrigin_Restore, _T("&Restore to normal\tShift-Ctrl-0") );
1093
1094 wxMenu *menuColour = new wxMenu;
1095 menuColour->Append( Colour_TextForeground, _T("Text &foreground...") );
1096 menuColour->Append( Colour_TextBackground, _T("Text &background...") );
1097 menuColour->Append( Colour_Background, _T("Background &colour...") );
1098 menuColour->Append( Colour_BackgroundMode, _T("&Opaque/transparent\tCtrl-B"), _T(""), TRUE );
1099 menuColour->Append( Colour_TextureBackgound, _T("Draw textured back&ground\tCtrl-T"), _T(""), TRUE);
1100
1101 // now append the freshly created menu to the menu bar...
1102 wxMenuBar *menuBar = new wxMenuBar;
1103 menuBar->Append(menuFile, _T("&File"));
1104 menuBar->Append(menuMapMode, _T("&Mode"));
1105 menuBar->Append(menuUserScale, _T("&Scale"));
1106 menuBar->Append(menuAxis, _T("&Axis"));
1107 menuBar->Append(menuLogical, _T("&Origin"));
1108 menuBar->Append(menuColour, _T("&Colours"));
1109
1110 // ... and attach this menu bar to the frame
1111 SetMenuBar(menuBar);
1112
1113 // create a status bar just for fun (by default with 1 pane only)
1114 CreateStatusBar(2);
1115 SetStatusText(_T("Welcome to wxWindows!"));
1116
1117 m_mapMode = wxMM_TEXT;
1118 m_xUserScale = 1.0;
1119 m_yUserScale = 1.0;
1120 m_xLogicalOrigin = 0;
1121 m_yLogicalOrigin = 0;
1122 m_xAxisReversed =
1123 m_yAxisReversed = FALSE;
1124 m_backgroundMode = wxSOLID;
1125 m_colourForeground = *wxRED;
1126 m_colourBackground = *wxBLUE;
1127 m_textureBackground = FALSE;
1128
1129 m_canvas = new MyCanvas( this );
1130 m_canvas->SetScrollbars( 10, 10, 100, 240 );
1131 }
1132
1133 // event handlers
1134
1135 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1136 {
1137 // TRUE is to force the frame to close
1138 Close(TRUE);
1139 }
1140
1141 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1142 {
1143 wxString msg;
1144 msg.Printf( wxT("This is the about dialog of the drawing sample.\n")
1145 wxT("This sample tests various primitive drawing functions\n")
1146 wxT("(without any attempts to prevent flicker).\n")
1147 wxT("Copyright (c) Robert Roebling 1999")
1148 );
1149
1150 wxMessageBox(msg, _T("About Drawing"), wxOK | wxICON_INFORMATION, this);
1151 }
1152
1153 void MyFrame::OnClip(wxCommandEvent& event)
1154 {
1155 m_canvas->Clip(event.IsChecked());
1156 }
1157
1158 void MyFrame::OnShow(wxCommandEvent& event)
1159 {
1160 m_canvas->ToShow((ScreenToShow)(event.GetId() - MenuShow_First));
1161 }
1162
1163 void MyFrame::OnOption(wxCommandEvent& event)
1164 {
1165 switch (event.GetId())
1166 {
1167 case MapMode_Text:
1168 m_mapMode = wxMM_TEXT;
1169 break;
1170 case MapMode_Lometric:
1171 m_mapMode = wxMM_LOMETRIC;
1172 break;
1173 case MapMode_Twips:
1174 m_mapMode = wxMM_TWIPS;
1175 break;
1176 case MapMode_Points:
1177 m_mapMode = wxMM_POINTS;
1178 break;
1179 case MapMode_Metric:
1180 m_mapMode = wxMM_METRIC;
1181 break;
1182
1183 case LogicalOrigin_MoveDown:
1184 m_yLogicalOrigin += 10;
1185 break;
1186 case LogicalOrigin_MoveUp:
1187 m_yLogicalOrigin -= 10;
1188 break;
1189 case LogicalOrigin_MoveLeft:
1190 m_xLogicalOrigin += 10;
1191 break;
1192 case LogicalOrigin_MoveRight:
1193 m_xLogicalOrigin -= 10;
1194 break;
1195 case LogicalOrigin_Set:
1196 m_xLogicalOrigin =
1197 m_yLogicalOrigin = -100;
1198 break;
1199 case LogicalOrigin_Restore:
1200 m_xLogicalOrigin =
1201 m_yLogicalOrigin = 0;
1202 break;
1203
1204 case UserScale_StretchHoriz:
1205 m_xUserScale *= 1.10;
1206 break;
1207 case UserScale_ShrinkHoriz:
1208 m_xUserScale /= 1.10;
1209 break;
1210 case UserScale_StretchVertic:
1211 m_yUserScale *= 1.10;
1212 break;
1213 case UserScale_ShrinkVertic:
1214 m_yUserScale /= 1.10;
1215 break;
1216 case UserScale_Restore:
1217 m_xUserScale =
1218 m_yUserScale = 1.0;
1219 break;
1220
1221 case AxisMirror_Vertic:
1222 m_yAxisReversed = !m_yAxisReversed;
1223 break;
1224 case AxisMirror_Horiz:
1225 m_xAxisReversed = !m_xAxisReversed;
1226 break;
1227
1228 case Colour_TextForeground:
1229 m_colourForeground = SelectColour();
1230 break;
1231 case Colour_TextBackground:
1232 m_colourBackground = SelectColour();
1233 break;
1234 case Colour_Background:
1235 {
1236 wxColour col = SelectColour();
1237 if ( col.Ok() )
1238 {
1239 m_backgroundBrush.SetColour(col);
1240 }
1241 }
1242 break;
1243 case Colour_BackgroundMode:
1244 m_backgroundMode = m_backgroundMode == wxSOLID ? wxTRANSPARENT
1245 : wxSOLID;
1246 break;
1247
1248 case Colour_TextureBackgound:
1249 m_textureBackground = ! m_textureBackground;
1250 break;
1251
1252 default:
1253 // skip Refresh()
1254 return;
1255 }
1256
1257 m_canvas->Refresh();
1258 }
1259
1260 void MyFrame::PrepareDC(wxDC& dc)
1261 {
1262 dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin );
1263 dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed );
1264 dc.SetUserScale( m_xUserScale, m_yUserScale );
1265 dc.SetMapMode( m_mapMode );
1266 }
1267
1268 wxColour MyFrame::SelectColour()
1269 {
1270 wxColour col;
1271 wxColourData data;
1272 wxColourDialog dialog(this, &data);
1273
1274 if ( dialog.ShowModal() == wxID_OK )
1275 {
1276 col = dialog.GetColourData().GetColour();
1277 }
1278
1279 return col;
1280 }
1281