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