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