forgot to release capture
[wxWidgets.git] / samples / drawing / drawing.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/drawing/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 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers
29 #ifndef WX_PRECOMP
30 #include "wx/wx.h"
31 #endif
32
33 #include "wx/colordlg.h"
34 #include "wx/image.h"
35 #include "wx/artprov.h"
36 #include "wx/dcgraph.h"
37 #include "wx/overlay.h"
38
39 #define wxTEST_GRAPHICS 1
40
41 #define TEST_CAIRO_EVERYWHERE 0
42
43 #if wxTEST_GRAPHICS
44 #include "wx/graphics.h"
45 #include "wx/dcgraph.h"
46 #if wxUSE_GRAPHICS_CONTEXT == 0
47 #undef wxTEST_GRAPHICS
48 #define wxTEST_GRAPHICS 0
49 #endif
50 #else
51 #undef wxUSE_GRAPHICS_CONTEXT
52 #define wxUSE_GRAPHICS_CONTEXT 0
53 #endif
54
55 // ----------------------------------------------------------------------------
56 // ressources
57 // ----------------------------------------------------------------------------
58
59 // the application icon
60 #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__)
61 #include "mondrian.xpm"
62 #endif
63
64 // ----------------------------------------------------------------------------
65 // constants
66 // ----------------------------------------------------------------------------
67
68 // what do we show on screen (there are too many shapes to put them all on
69 // screen simultaneously)
70 enum ScreenToShow
71 {
72 Show_Default,
73 Show_Text,
74 Show_Lines,
75 Show_Brushes,
76 Show_Polygons,
77 Show_Mask,
78 Show_Mask_Stretch,
79 Show_Ops,
80 Show_Regions,
81 Show_Circles,
82 Show_Splines,
83 #if wxUSE_GRAPHICS_CONTEXT
84 Show_Alpha,
85 Show_Graphics,
86 #endif
87 Show_Gradient,
88 Show_Max
89 };
90
91 // ----------------------------------------------------------------------------
92 // global variables
93 // ----------------------------------------------------------------------------
94
95 static wxBitmap *gs_bmpNoMask = NULL,
96 *gs_bmpWithColMask = NULL,
97 *gs_bmpMask = NULL,
98 *gs_bmpWithMask = NULL,
99 *gs_bmp4 = NULL,
100 *gs_bmp4_mono = NULL,
101 *gs_bmp36 = NULL;
102
103 // ----------------------------------------------------------------------------
104 // private classes
105 // ----------------------------------------------------------------------------
106
107 // Define a new application type, each program should derive a class from wxApp
108 class MyApp : public wxApp
109 {
110 public:
111 // override base class virtuals
112 // ----------------------------
113
114 // this one is called on application startup and is a good place for the app
115 // initialization (doing it here and not in the ctor allows to have an error
116 // return: if OnInit() returns false, the application terminates)
117 virtual bool OnInit();
118
119 virtual int OnExit() { DeleteBitmaps(); return 0; }
120
121 protected:
122 void DeleteBitmaps();
123
124 bool LoadImages();
125 };
126
127 class MyCanvas;
128
129 // Define a new frame type: this is going to be our main frame
130 class MyFrame : public wxFrame
131 {
132 public:
133 // ctor(s)
134 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
135
136 // event handlers (these functions should _not_ be virtual)
137 void OnQuit(wxCommandEvent& event);
138 void OnAbout(wxCommandEvent& event);
139 void OnClip(wxCommandEvent& event);
140 #if wxUSE_GRAPHICS_CONTEXT
141 void OnGraphicContext(wxCommandEvent& event);
142 #endif
143 void OnShow(wxCommandEvent &event);
144 void OnOption(wxCommandEvent &event);
145
146 #if wxUSE_COLOURDLG
147 wxColour SelectColour();
148 #endif // wxUSE_COLOURDLG
149 void PrepareDC(wxDC& dc);
150
151 int m_backgroundMode;
152 int m_textureBackground;
153 int m_mapMode;
154 double m_xUserScale;
155 double m_yUserScale;
156 int m_xLogicalOrigin;
157 int m_yLogicalOrigin;
158 bool m_xAxisReversed,
159 m_yAxisReversed;
160 wxColour m_colourForeground, // these are _text_ colours
161 m_colourBackground;
162 wxBrush m_backgroundBrush;
163 MyCanvas *m_canvas;
164
165 private:
166 // any class wishing to process wxWidgets events must use this macro
167 DECLARE_EVENT_TABLE()
168 };
169
170 // define a scrollable canvas for drawing onto
171 class MyCanvas: public wxScrolledWindow
172 {
173 public:
174 MyCanvas( MyFrame *parent );
175
176 void OnPaint(wxPaintEvent &event);
177 void OnMouseMove(wxMouseEvent &event);
178 void OnMouseDown(wxMouseEvent &event);
179 void OnMouseUp(wxMouseEvent &event);
180
181 void ToShow(ScreenToShow show) { m_show = show; Refresh(); }
182
183 // set or remove the clipping region
184 void Clip(bool clip) { m_clip = clip; Refresh(); }
185 #if wxUSE_GRAPHICS_CONTEXT
186 void UseGraphicContext(bool use) { m_useContext = use; Refresh(); }
187 #endif
188
189 protected:
190 enum DrawMode
191 {
192 Draw_Normal,
193 Draw_Stretch
194 };
195
196 void DrawTestLines( int x, int y, int width, wxDC &dc );
197 void DrawTestPoly(wxDC& dc);
198 void DrawTestBrushes(wxDC& dc);
199 void DrawText(wxDC& dc);
200 void DrawImages(wxDC& dc, DrawMode mode);
201 void DrawWithLogicalOps(wxDC& dc);
202 #if wxUSE_GRAPHICS_CONTEXT
203 void DrawAlpha(wxDC& dc);
204 void DrawGraphics(wxGraphicsContext* gc);
205 #endif
206 void DrawRegions(wxDC& dc);
207 void DrawCircles(wxDC& dc);
208 void DrawSplines(wxDC& dc);
209 void DrawDefault(wxDC& dc);
210 void DrawGradients(wxDC& dc);
211
212 void DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime);
213
214 private:
215 MyFrame *m_owner;
216
217 ScreenToShow m_show;
218 wxBitmap m_smile_bmp;
219 wxIcon m_std_icon;
220 bool m_clip;
221 wxOverlay m_overlay;
222 bool m_rubberBand;
223 wxPoint m_anchorpoint;
224 wxPoint m_currentpoint;
225 #if wxUSE_GRAPHICS_CONTEXT
226 bool m_useContext ;
227 #endif
228
229 DECLARE_EVENT_TABLE()
230 };
231
232 // ----------------------------------------------------------------------------
233 // constants
234 // ----------------------------------------------------------------------------
235
236 // IDs for the controls and the menu commands
237 enum
238 {
239 // menu items
240 File_Quit = wxID_EXIT,
241 File_About = wxID_ABOUT,
242
243 MenuShow_First = wxID_HIGHEST,
244 File_ShowDefault = MenuShow_First,
245 File_ShowText,
246 File_ShowLines,
247 File_ShowBrushes,
248 File_ShowPolygons,
249 File_ShowMask,
250 File_ShowMaskStretch,
251 File_ShowOps,
252 File_ShowRegions,
253 File_ShowCircles,
254 File_ShowSplines,
255 #if wxUSE_GRAPHICS_CONTEXT
256 File_ShowAlpha,
257 File_ShowGraphics,
258 #endif
259 File_ShowGradients,
260 MenuShow_Last = File_ShowGradients,
261
262 File_Clip,
263 #if wxUSE_GRAPHICS_CONTEXT
264 File_GraphicContext,
265 #endif
266
267 MenuOption_First,
268
269 MapMode_Text = MenuOption_First,
270 MapMode_Lometric,
271 MapMode_Twips,
272 MapMode_Points,
273 MapMode_Metric,
274
275 UserScale_StretchHoriz,
276 UserScale_ShrinkHoriz,
277 UserScale_StretchVertic,
278 UserScale_ShrinkVertic,
279 UserScale_Restore,
280
281 AxisMirror_Horiz,
282 AxisMirror_Vertic,
283
284 LogicalOrigin_MoveDown,
285 LogicalOrigin_MoveUp,
286 LogicalOrigin_MoveLeft,
287 LogicalOrigin_MoveRight,
288 LogicalOrigin_Set,
289 LogicalOrigin_Restore,
290
291 #if wxUSE_COLOURDLG
292 Colour_TextForeground,
293 Colour_TextBackground,
294 Colour_Background,
295 #endif // wxUSE_COLOURDLG
296 Colour_BackgroundMode,
297 Colour_TextureBackgound,
298
299 MenuOption_Last = Colour_TextureBackgound
300 };
301
302 // ----------------------------------------------------------------------------
303 // event tables and other macros for wxWidgets
304 // ----------------------------------------------------------------------------
305
306
307 // Create a new application object: this macro will allow wxWidgets to create
308 // the application object during program execution (it's better than using a
309 // static object for many reasons) and also declares the accessor function
310 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
311 // not wxApp)
312 IMPLEMENT_APP(MyApp)
313
314 // ============================================================================
315 // implementation
316 // ============================================================================
317
318 // ----------------------------------------------------------------------------
319 // the application class
320 // ----------------------------------------------------------------------------
321
322 bool MyApp::LoadImages()
323 {
324 gs_bmpNoMask = new wxBitmap;
325 gs_bmpWithColMask = new wxBitmap;
326 gs_bmpMask = new wxBitmap;
327 gs_bmpWithMask = new wxBitmap;
328 gs_bmp4 = new wxBitmap;
329 gs_bmp4_mono = new wxBitmap;
330 gs_bmp36 = new wxBitmap;
331
332 wxPathList pathList;
333 pathList.Add(_T("."));
334 pathList.Add(_T(".."));
335 pathList.Add(_T("../.."));
336
337 wxString path = pathList.FindValidPath(_T("pat4.bmp"));
338 if ( !path )
339 return false;
340
341 /* 4 colour bitmap */
342 gs_bmp4->LoadFile(path, wxBITMAP_TYPE_BMP);
343 /* turn into mono-bitmap */
344 gs_bmp4_mono->LoadFile(path, wxBITMAP_TYPE_BMP);
345 wxMask* mask4 = new wxMask(*gs_bmp4_mono, *wxBLACK);
346 gs_bmp4_mono->SetMask(mask4);
347
348 path = pathList.FindValidPath(_T("pat36.bmp"));
349 if ( !path )
350 return false;
351 gs_bmp36->LoadFile(path, wxBITMAP_TYPE_BMP);
352 wxMask* mask36 = new wxMask(*gs_bmp36, *wxBLACK);
353 gs_bmp36->SetMask(mask36);
354
355 path = pathList.FindValidPath(_T("image.bmp"));
356 if ( !path )
357 return false;
358 gs_bmpNoMask->LoadFile(path, wxBITMAP_TYPE_BMP);
359 gs_bmpWithMask->LoadFile(path, wxBITMAP_TYPE_BMP);
360 gs_bmpWithColMask->LoadFile(path, wxBITMAP_TYPE_BMP);
361
362 path = pathList.FindValidPath(_T("mask.bmp"));
363 if ( !path )
364 return false;
365 gs_bmpMask->LoadFile(path, wxBITMAP_TYPE_BMP);
366
367 wxMask *mask = new wxMask(*gs_bmpMask, *wxBLACK);
368 gs_bmpWithMask->SetMask(mask);
369
370 mask = new wxMask(*gs_bmpWithColMask, *wxWHITE);
371 gs_bmpWithColMask->SetMask(mask);
372
373 return true;
374 }
375
376 // `Main program' equivalent: the program execution "starts" here
377 bool MyApp::OnInit()
378 {
379 if ( !wxApp::OnInit() )
380 return false;
381
382 // Create the main application window
383 MyFrame *frame = new MyFrame(_T("Drawing sample"),
384 wxPoint(50, 50), wxSize(550, 340));
385
386 // Show it and tell the application that it's our main window
387 frame->Show(true);
388 SetTopWindow(frame);
389
390 if ( !LoadImages() )
391 {
392 wxLogError(wxT("Can't load one of the bitmap files needed ")
393 wxT("for this sample from the current or parent ")
394 wxT("directory, please copy them there."));
395
396 // stop here
397 DeleteBitmaps();
398
399 return false;
400 }
401
402 // ok, continue
403 return true;
404 }
405
406 void MyApp::DeleteBitmaps()
407 {
408 delete gs_bmpNoMask;
409 delete gs_bmpWithColMask;
410 delete gs_bmpMask;
411 delete gs_bmpWithMask;
412 delete gs_bmp4;
413 delete gs_bmp4_mono;
414 delete gs_bmp36;
415
416 gs_bmpNoMask = NULL;
417 gs_bmpWithColMask = NULL;
418 gs_bmpMask = NULL;
419 gs_bmpWithMask = NULL;
420 gs_bmp4 = NULL;
421 gs_bmp4_mono = NULL;
422 gs_bmp36 = NULL;
423 }
424
425 // ----------------------------------------------------------------------------
426 // MyCanvas
427 // ----------------------------------------------------------------------------
428
429 // the event tables connect the wxWidgets events with the functions (event
430 // handlers) which process them.
431 BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
432 EVT_PAINT (MyCanvas::OnPaint)
433 EVT_MOTION (MyCanvas::OnMouseMove)
434 EVT_LEFT_DOWN (MyCanvas::OnMouseDown)
435 EVT_LEFT_UP (MyCanvas::OnMouseUp)
436 END_EVENT_TABLE()
437
438 #include "smile.xpm"
439
440 MyCanvas::MyCanvas(MyFrame *parent)
441 : wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
442 wxHSCROLL | wxVSCROLL | wxNO_FULL_REPAINT_ON_RESIZE)
443 {
444 m_owner = parent;
445 m_show = Show_Default;
446 m_smile_bmp = wxBitmap(smile_xpm);
447 m_std_icon = wxArtProvider::GetIcon(wxART_INFORMATION);
448 m_clip = false;
449 m_rubberBand = false;
450 #if wxUSE_GRAPHICS_CONTEXT
451 m_useContext = false;
452 #endif
453 }
454
455 void MyCanvas::DrawTestBrushes(wxDC& dc)
456 {
457 static const wxCoord WIDTH = 200;
458 static const wxCoord HEIGHT = 80;
459
460 wxCoord x = 10,
461 y = 10;
462
463 dc.SetBrush(wxBrush(*wxGREEN, wxSOLID));
464 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
465 dc.DrawText(_T("Solid green"), x + 10, y + 10);
466
467 y += HEIGHT;
468 dc.SetBrush(wxBrush(*wxRED, wxCROSSDIAG_HATCH));
469 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
470 dc.DrawText(_T("Hatched red"), x + 10, y + 10);
471
472 y += HEIGHT;
473 dc.SetBrush(wxBrush(*gs_bmpMask));
474 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
475 dc.DrawText(_T("Stipple mono"), x + 10, y + 10);
476
477 y += HEIGHT;
478 dc.SetBrush(wxBrush(*gs_bmpNoMask));
479 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
480 dc.DrawText(_T("Stipple colour"), x + 10, y + 10);
481 }
482
483 void MyCanvas::DrawTestPoly(wxDC& dc)
484 {
485 wxBrush brushHatch(*wxRED, wxFDIAGONAL_HATCH);
486 dc.SetBrush(brushHatch);
487
488 wxPoint star[5];
489 star[0] = wxPoint(100, 60);
490 star[1] = wxPoint(60, 150);
491 star[2] = wxPoint(160, 100);
492 star[3] = wxPoint(40, 100);
493 star[4] = wxPoint(140, 150);
494
495 dc.DrawText(_T("You should see two (irregular) stars below, the left one ")
496 _T("hatched"), 10, 10);
497 dc.DrawText(_T("except for the central region and the right ")
498 _T("one entirely hatched"), 10, 30);
499 dc.DrawText(_T("The third star only has a hatched outline"), 10, 50);
500
501 dc.DrawPolygon(WXSIZEOF(star), star, 0, 30);
502 dc.DrawPolygon(WXSIZEOF(star), star, 160, 30, wxWINDING_RULE);
503
504 wxPoint star2[10];
505 star2[0] = wxPoint(0, 100);
506 star2[1] = wxPoint(-59, -81);
507 star2[2] = wxPoint(95, 31);
508 star2[3] = wxPoint(-95, 31);
509 star2[4] = wxPoint(59, -81);
510 star2[5] = wxPoint(0, 80);
511 star2[6] = wxPoint(-47, -64);
512 star2[7] = wxPoint(76, 24);
513 star2[8] = wxPoint(-76, 24);
514 star2[9] = wxPoint(47, -64);
515 int count[2] = {5, 5};
516
517 dc.DrawPolyPolygon(WXSIZEOF(count), count, star2, 450, 150);
518 }
519
520 void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc )
521 {
522 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
523 dc.SetBrush( *wxRED_BRUSH );
524 dc.DrawText(wxString::Format(wxT("Testing lines of width %d"), width), x + 10, y - 10);
525 dc.DrawRectangle( x+10, y+10, 100, 190 );
526
527 dc.DrawText(_T("Solid/dot/short dash/long dash/dot dash"), x + 150, y + 10);
528 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
529 dc.DrawLine( x+20, y+20, 100, y+20 );
530 dc.SetPen( wxPen( wxT("black"), width, wxDOT) );
531 dc.DrawLine( x+20, y+30, 100, y+30 );
532 dc.SetPen( wxPen( wxT("black"), width, wxSHORT_DASH) );
533 dc.DrawLine( x+20, y+40, 100, y+40 );
534 dc.SetPen( wxPen( wxT("black"), width, wxLONG_DASH) );
535 dc.DrawLine( x+20, y+50, 100, y+50 );
536 dc.SetPen( wxPen( wxT("black"), width, wxDOT_DASH) );
537 dc.DrawLine( x+20, y+60, 100, y+60 );
538
539 dc.DrawText(_T("Misc hatches"), x + 150, y + 70);
540 dc.SetPen( wxPen( wxT("black"), width, wxBDIAGONAL_HATCH) );
541 dc.DrawLine( x+20, y+70, 100, y+70 );
542 dc.SetPen( wxPen( wxT("black"), width, wxCROSSDIAG_HATCH) );
543 dc.DrawLine( x+20, y+80, 100, y+80 );
544 dc.SetPen( wxPen( wxT("black"), width, wxFDIAGONAL_HATCH) );
545 dc.DrawLine( x+20, y+90, 100, y+90 );
546 dc.SetPen( wxPen( wxT("black"), width, wxCROSS_HATCH) );
547 dc.DrawLine( x+20, y+100, 100, y+100 );
548 dc.SetPen( wxPen( wxT("black"), width, wxHORIZONTAL_HATCH) );
549 dc.DrawLine( x+20, y+110, 100, y+110 );
550 dc.SetPen( wxPen( wxT("black"), width, wxVERTICAL_HATCH) );
551 dc.DrawLine( x+20, y+120, 100, y+120 );
552
553 dc.DrawText(_T("User dash"), x + 150, y + 140);
554 wxPen ud( wxT("black"), width, wxUSER_DASH );
555 wxDash dash1[6];
556 dash1[0] = 8; // Long dash <---------+
557 dash1[1] = 2; // Short gap |
558 dash1[2] = 3; // Short dash |
559 dash1[3] = 2; // Short gap |
560 dash1[4] = 3; // Short dash |
561 dash1[5] = 2; // Short gap and repeat +
562 ud.SetDashes( 6, dash1 );
563 dc.SetPen( ud );
564 dc.DrawLine( x+20, y+140, 100, y+140 );
565 dash1[0] = 5; // Make first dash shorter
566 ud.SetDashes( 6, dash1 );
567 dc.SetPen( ud );
568 dc.DrawLine( x+20, y+150, 100, y+150 );
569 dash1[2] = 5; // Make second dash longer
570 ud.SetDashes( 6, dash1 );
571 dc.SetPen( ud );
572 dc.DrawLine( x+20, y+160, 100, y+160 );
573 dash1[4] = 5; // Make third dash longer
574 ud.SetDashes( 6, dash1 );
575 dc.SetPen( ud );
576 dc.DrawLine( x+20, y+170, 100, y+170 );
577 }
578
579 void MyCanvas::DrawDefault(wxDC& dc)
580 {
581 // mark the origin
582 dc.DrawCircle(0, 0, 10);
583
584 #if !defined(wxMAC_USE_CORE_GRAPHICS) || !wxMAC_USE_CORE_GRAPHICS
585 // GetPixel and FloodFill not supported by Mac OS X CoreGraphics
586 // (FloodFill uses Blit from a non-wxMemoryDC)
587 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
588 dc.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID));
589
590 wxColour tmpColour ;
591 dc.GetPixel(1,1, &tmpColour);
592 dc.FloodFill(1,1, tmpColour, wxFLOOD_SURFACE);
593 #endif
594
595 dc.DrawCheckMark(5, 80, 15, 15);
596 dc.DrawCheckMark(25, 80, 30, 30);
597 dc.DrawCheckMark(60, 80, 60, 60);
598
599 // this is the test for "blitting bitmap into DC damages selected brush" bug
600 wxCoord rectSize = m_std_icon.GetWidth() + 10;
601 wxCoord x = 100;
602 dc.SetPen(*wxTRANSPARENT_PEN);
603 dc.SetBrush( *wxGREEN_BRUSH );
604 dc.DrawRectangle(x, 10, rectSize, rectSize);
605 dc.DrawBitmap(m_std_icon, x + 5, 15, true);
606 x += rectSize + 10;
607 dc.DrawRectangle(x, 10, rectSize, rectSize);
608 dc.DrawIcon(m_std_icon, x + 5, 15);
609 x += rectSize + 10;
610 dc.DrawRectangle(x, 10, rectSize, rectSize);
611
612 // test for "transparent" bitmap drawing (it intersects with the last
613 // rectangle above)
614 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
615
616 if (m_smile_bmp.Ok())
617 dc.DrawBitmap(m_smile_bmp, x + rectSize - 20, rectSize - 10, true);
618
619 dc.SetBrush( *wxBLACK_BRUSH );
620 dc.DrawRectangle( 0, 160, 1000, 300 );
621
622 // draw lines
623 wxBitmap bitmap(20,70);
624 wxMemoryDC memdc;
625 memdc.SelectObject( bitmap );
626 memdc.SetBrush( *wxBLACK_BRUSH );
627 memdc.SetPen( *wxWHITE_PEN );
628 memdc.DrawRectangle(0,0,20,70);
629 memdc.DrawLine( 10,0,10,70 );
630
631 // to the right
632 wxPen pen = *wxRED_PEN;
633 memdc.SetPen(pen);
634 memdc.DrawLine( 10, 5,10, 5 );
635 memdc.DrawLine( 10,10,11,10 );
636 memdc.DrawLine( 10,15,12,15 );
637 memdc.DrawLine( 10,20,13,20 );
638
639 /*
640 memdc.SetPen(*wxRED_PEN);
641 memdc.DrawLine( 12, 5,12, 5 );
642 memdc.DrawLine( 12,10,13,10 );
643 memdc.DrawLine( 12,15,14,15 );
644 memdc.DrawLine( 12,20,15,20 );
645 */
646
647 // same to the left
648 memdc.DrawLine( 10,25,10,25 );
649 memdc.DrawLine( 10,30, 9,30 );
650 memdc.DrawLine( 10,35, 8,35 );
651 memdc.DrawLine( 10,40, 7,40 );
652
653 // XOR draw lines
654 dc.SetPen(*wxWHITE_PEN);
655 memdc.SetLogicalFunction( wxINVERT );
656 memdc.SetPen( *wxWHITE_PEN );
657 memdc.DrawLine( 10,50,10,50 );
658 memdc.DrawLine( 10,55,11,55 );
659 memdc.DrawLine( 10,60,12,60 );
660 memdc.DrawLine( 10,65,13,65 );
661
662 memdc.DrawLine( 12,50,12,50 );
663 memdc.DrawLine( 12,55,13,55 );
664 memdc.DrawLine( 12,60,14,60 );
665 memdc.DrawLine( 12,65,15,65 );
666
667 memdc.SelectObject( wxNullBitmap );
668 dc.DrawBitmap( bitmap, 10, 170 );
669 wxImage image = bitmap.ConvertToImage();
670 image.Rescale( 60,210 );
671 bitmap = wxBitmap(image);
672 dc.DrawBitmap( bitmap, 50, 170 );
673
674 // test the rectangle outline drawing - there should be one pixel between
675 // the rect and the lines
676 dc.SetPen(*wxWHITE_PEN);
677 dc.SetBrush( *wxTRANSPARENT_BRUSH );
678 dc.DrawRectangle(150, 170, 49, 29);
679 dc.DrawRectangle(200, 170, 49, 29);
680 dc.SetPen(*wxWHITE_PEN);
681 dc.DrawLine(250, 210, 250, 170);
682 dc.DrawLine(260, 200, 150, 200);
683
684 // test the rectangle filled drawing - there should be one pixel between
685 // the rect and the lines
686 dc.SetPen(*wxTRANSPARENT_PEN);
687 dc.SetBrush( *wxWHITE_BRUSH );
688 dc.DrawRectangle(300, 170, 49, 29);
689 dc.DrawRectangle(350, 170, 49, 29);
690 dc.SetPen(*wxWHITE_PEN);
691 dc.DrawLine(400, 170, 400, 210);
692 dc.DrawLine(300, 200, 410, 200);
693
694 // a few more tests of this kind
695 dc.SetPen(*wxRED_PEN);
696 dc.SetBrush( *wxWHITE_BRUSH );
697 dc.DrawRectangle(300, 220, 1, 1);
698 dc.DrawRectangle(310, 220, 2, 2);
699 dc.DrawRectangle(320, 220, 3, 3);
700 dc.DrawRectangle(330, 220, 4, 4);
701
702 dc.SetPen(*wxTRANSPARENT_PEN);
703 dc.SetBrush( *wxWHITE_BRUSH );
704 dc.DrawRectangle(300, 230, 1, 1);
705 dc.DrawRectangle(310, 230, 2, 2);
706 dc.DrawRectangle(320, 230, 3, 3);
707 dc.DrawRectangle(330, 230, 4, 4);
708
709 // and now for filled rect with outline
710 dc.SetPen(*wxRED_PEN);
711 dc.SetBrush( *wxWHITE_BRUSH );
712 dc.DrawRectangle(500, 170, 49, 29);
713 dc.DrawRectangle(550, 170, 49, 29);
714 dc.SetPen(*wxWHITE_PEN);
715 dc.DrawLine(600, 170, 600, 210);
716 dc.DrawLine(500, 200, 610, 200);
717
718 // test the rectangle outline drawing - there should be one pixel between
719 // the rect and the lines
720 dc.SetPen(*wxWHITE_PEN);
721 dc.SetBrush( *wxTRANSPARENT_BRUSH );
722 dc.DrawRoundedRectangle(150, 270, 49, 29, 6);
723 dc.DrawRoundedRectangle(200, 270, 49, 29, 6);
724 dc.SetPen(*wxWHITE_PEN);
725 dc.DrawLine(250, 270, 250, 310);
726 dc.DrawLine(150, 300, 260, 300);
727
728 // test the rectangle filled drawing - there should be one pixel between
729 // the rect and the lines
730 dc.SetPen(*wxTRANSPARENT_PEN);
731 dc.SetBrush( *wxWHITE_BRUSH );
732 dc.DrawRoundedRectangle(300, 270, 49, 29, 6);
733 dc.DrawRoundedRectangle(350, 270, 49, 29, 6);
734 dc.SetPen(*wxWHITE_PEN);
735 dc.DrawLine(400, 270, 400, 310);
736 dc.DrawLine(300, 300, 410, 300);
737
738 // Added by JACS to demonstrate bizarre behaviour.
739 // With a size of 70, we get a missing red RHS,
740 // and the height is too small, so we get yellow
741 // showing. With a size of 40, it draws as expected:
742 // it just shows a white rectangle with red outline.
743 int totalWidth = 70;
744 int totalHeight = 70;
745 wxBitmap bitmap2(totalWidth, totalHeight);
746
747 wxMemoryDC memdc2;
748 memdc2.SelectObject(bitmap2);
749
750 wxColour clr(255, 255, 0);
751 wxBrush yellowBrush(clr, wxSOLID);
752 memdc2.SetBackground(yellowBrush);
753 memdc2.Clear();
754
755 wxPen yellowPen(clr, 1, wxSOLID);
756
757 // Now draw a white rectangle with red outline. It should
758 // entirely eclipse the yellow background.
759 memdc2.SetPen(*wxRED_PEN);
760 memdc2.SetBrush(*wxWHITE_BRUSH);
761
762 memdc2.DrawRectangle(0, 0, totalWidth, totalHeight);
763
764 memdc2.SetPen(wxNullPen);
765 memdc2.SetBrush(wxNullBrush);
766 memdc2.SelectObject(wxNullBitmap);
767
768 dc.DrawBitmap(bitmap2, 500, 270);
769
770 // Repeat, but draw directly on dc
771 // Draw a yellow rectangle filling the bitmap
772
773 x = 600; int y = 270;
774 dc.SetPen(yellowPen);
775 dc.SetBrush(yellowBrush);
776 dc.DrawRectangle(x, y, totalWidth, totalHeight);
777
778 // Now draw a white rectangle with red outline. It should
779 // entirely eclipse the yellow background.
780 dc.SetPen(*wxRED_PEN);
781 dc.SetBrush(*wxWHITE_BRUSH);
782
783 dc.DrawRectangle(x, y, totalWidth, totalHeight);
784 }
785
786 void MyCanvas::DrawText(wxDC& dc)
787 {
788 // set underlined font for testing
789 dc.SetFont( wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, true) );
790 dc.DrawText( _T("This is text"), 110, 10 );
791 dc.DrawRotatedText( _T("That is text"), 20, 10, -45 );
792
793 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
794 // under Win9x (it is not TrueType)
795 dc.SetFont( *wxSWISS_FONT );
796
797 wxString text;
798 dc.SetBackgroundMode(wxTRANSPARENT);
799
800 for ( int n = -180; n < 180; n += 30 )
801 {
802 text.Printf(wxT(" %d rotated text"), n);
803 dc.DrawRotatedText(text , 400, 400, n);
804 }
805
806 dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) );
807
808 dc.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
809
810 wxCoord length;
811 wxCoord height;
812 wxCoord descent;
813 dc.GetTextExtent( _T("This is Swiss 18pt text."), &length, &height, &descent );
814 text.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length, height, descent );
815 dc.DrawText( text, 110, 80 );
816
817 text.Printf( wxT("CharHeight() returns: %d"), dc.GetCharHeight() );
818 dc.DrawText( text, 110, 120 );
819
820 dc.DrawRectangle( 100, 40, 4, height );
821
822 // test the logical function effect
823 wxCoord y = 150;
824 dc.SetLogicalFunction(wxINVERT);
825 dc.DrawText( _T("There should be no text below"), 110, 150 );
826 dc.DrawRectangle( 110, y, 100, height );
827
828 // twice drawn inverted should result in invisible
829 y += height;
830 dc.DrawText( _T("Invisible text"), 110, y );
831 dc.DrawRectangle( 110, y, 100, height );
832 dc.DrawText( _T("Invisible text"), 110, y );
833 dc.DrawRectangle( 110, y, 100, height );
834 dc.SetLogicalFunction(wxCOPY);
835
836 y += height;
837 dc.DrawRectangle( 110, y, 100, height );
838 dc.DrawText( _T("Visible text"), 110, y );
839 }
840
841 static const struct
842 {
843 const wxChar *name;
844 int rop;
845 } rasterOperations[] =
846 {
847 { wxT("wxAND"), wxAND },
848 { wxT("wxAND_INVERT"), wxAND_INVERT },
849 { wxT("wxAND_REVERSE"), wxAND_REVERSE },
850 { wxT("wxCLEAR"), wxCLEAR },
851 { wxT("wxCOPY"), wxCOPY },
852 { wxT("wxEQUIV"), wxEQUIV },
853 { wxT("wxINVERT"), wxINVERT },
854 { wxT("wxNAND"), wxNAND },
855 { wxT("wxNO_OP"), wxNO_OP },
856 { wxT("wxOR"), wxOR },
857 { wxT("wxOR_INVERT"), wxOR_INVERT },
858 { wxT("wxOR_REVERSE"), wxOR_REVERSE },
859 { wxT("wxSET"), wxSET },
860 { wxT("wxSRC_INVERT"), wxSRC_INVERT },
861 { wxT("wxXOR"), wxXOR },
862 };
863
864 void MyCanvas::DrawImages(wxDC& dc, DrawMode mode)
865 {
866 dc.DrawText(_T("original image"), 0, 0);
867 dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0);
868 dc.DrawText(_T("with colour mask"), 0, 100);
869 dc.DrawBitmap(*gs_bmpWithColMask, 0, 120, true);
870 dc.DrawText(_T("the mask image"), 0, 200);
871 dc.DrawBitmap(*gs_bmpMask, 0, 220, 0);
872 dc.DrawText(_T("masked image"), 0, 300);
873 dc.DrawBitmap(*gs_bmpWithMask, 0, 320, true);
874
875 int cx = gs_bmpWithColMask->GetWidth(),
876 cy = gs_bmpWithColMask->GetHeight();
877
878 wxMemoryDC memDC;
879 for ( size_t n = 0; n < WXSIZEOF(rasterOperations); n++ )
880 {
881 wxCoord x = 120 + 150*(n%4),
882 y = 20 + 100*(n/4);
883
884 dc.DrawText(rasterOperations[n].name, x, y - 20);
885 memDC.SelectObject(*gs_bmpWithColMask);
886 if ( mode == Draw_Stretch )
887 {
888 dc.StretchBlit(x, y, cx, cy, &memDC, 0, 0, cx/2, cy/2,
889 rasterOperations[n].rop, true);
890 }
891 else
892 {
893 dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, true);
894 }
895 }
896 }
897
898 void MyCanvas::DrawWithLogicalOps(wxDC& dc)
899 {
900 static const wxCoord w = 60;
901 static const wxCoord h = 60;
902
903 // reuse the text colour here
904 dc.SetPen(wxPen(m_owner->m_colourForeground, 1, wxSOLID));
905 dc.SetBrush(*wxTRANSPARENT_BRUSH);
906
907 size_t n;
908 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
909 {
910 wxCoord x = 20 + 150*(n%4),
911 y = 20 + 100*(n/4);
912
913 dc.DrawText(rasterOperations[n].name, x, y - 20);
914 dc.SetLogicalFunction(rasterOperations[n].rop);
915 dc.DrawRectangle(x, y, w, h);
916 dc.DrawLine(x, y, x + w, y + h);
917 dc.DrawLine(x + w, y, x, y + h);
918 }
919
920 // now some filled rectangles
921 dc.SetBrush(wxBrush(m_owner->m_colourForeground, wxSOLID));
922
923 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
924 {
925 wxCoord x = 20 + 150*(n%4),
926 y = 500 + 100*(n/4);
927
928 dc.DrawText(rasterOperations[n].name, x, y - 20);
929 dc.SetLogicalFunction(rasterOperations[n].rop);
930 dc.DrawRectangle(x, y, w, h);
931 }
932 }
933
934 #if wxUSE_GRAPHICS_CONTEXT
935 #ifdef __WXGTK20__
936 void MyCanvas::DrawAlpha(wxDC& no_dc)
937 #else
938 void MyCanvas::DrawAlpha(wxDC& dc)
939 #endif
940 {
941 #ifdef __WXGTK__
942 wxGCDC dc( this );
943 PrepareDC( dc );
944 #endif
945
946 wxDouble margin = 20 ;
947 wxDouble width = 180 ;
948 wxDouble radius = 30 ;
949
950 dc.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID));
951 dc.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID));
952
953 wxRect r(margin,margin+width*0.66,width,width) ;
954
955 dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
956
957 dc.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID));
958 dc.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID));
959
960 r.Offset( width * 0.8 , - width * 0.66 ) ;
961
962 dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
963
964 dc.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID));
965 dc.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID));
966
967 r.Offset( width * 0.8 , width *0.5 ) ;
968
969 dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
970
971 dc.SetPen( *wxTRANSPARENT_PEN ) ;
972 dc.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
973 dc.DrawRoundedRectangle( 0 , margin + width / 2 , width * 3 , 100 , radius) ;
974
975 dc.SetTextForeground( wxColour(255,255,0,128) );
976 dc.SetFont( wxFont( 40, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL ) );
977 dc.DrawText( wxT("Hello!"), 120, 80 );
978 }
979
980 #endif
981
982 #if wxUSE_GRAPHICS_CONTEXT
983
984 const int BASE = 80.0;
985 const int BASE2 = BASE/2;
986 const int BASE4 = BASE/4;
987
988 static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
989
990
991 // modeled along Robin Dunn's GraphicsContext.py sample
992
993 void MyCanvas::DrawGraphics(wxGraphicsContext* gc)
994 {
995 wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
996 gc->SetFont(font,*wxBLACK);
997
998 // make a path that contains a circle and some lines, centered at 0,0
999 wxGraphicsPath path = gc->CreatePath() ;
1000 path.AddCircle( 0, 0, BASE2 );
1001 path.MoveToPoint(0, -BASE2);
1002 path.AddLineToPoint(0, BASE2);
1003 path.MoveToPoint(-BASE2, 0);
1004 path.AddLineToPoint(BASE2, 0);
1005 path.CloseSubpath();
1006 path.AddRectangle(-BASE4, -BASE4/2, BASE2, BASE4);
1007
1008 // Now use that path to demonstrate various capbilites of the grpahics context
1009 gc->PushState(); // save current translation/scale/other state
1010 gc->Translate(60, 75); // reposition the context origin
1011
1012 gc->SetPen(wxPen("navy", 1));
1013 gc->SetBrush(wxBrush("pink"));
1014
1015 for( int i = 0 ; i < 3 ; ++i )
1016 {
1017 wxString label;
1018 switch( i )
1019 {
1020 case 0 :
1021 label = "StrokePath";
1022 break;
1023 case 1 :
1024 label = "FillPath";
1025 break;
1026 case 2 :
1027 label = "DrawPath";
1028 break;
1029 }
1030 wxDouble w, h;
1031 gc->GetTextExtent(label, &w, &h, NULL, NULL);
1032 gc->DrawText(label, -w/2, -BASE2-h-4);
1033 switch( i )
1034 {
1035 case 0 :
1036 gc->StrokePath(path);
1037 break;
1038 case 1 :
1039 gc->FillPath(path);
1040 break;
1041 case 2 :
1042 gc->DrawPath(path);
1043 break;
1044 }
1045 gc->Translate(2*BASE, 0);
1046 }
1047
1048 gc->PopState(); // restore saved state
1049 gc->PushState(); // save it again
1050 gc->Translate(60, 200); // offset to the lower part of the window
1051
1052 gc->DrawText("Scale", 0, -BASE2);
1053 gc->Translate(0, 20);
1054
1055 gc->SetBrush(wxBrush(wxColour(178, 34, 34, 128)));// 128 == half transparent
1056 for( int i = 0 ; i < 8 ; ++i )
1057 {
1058 gc->Scale(1.08, 1.08); // increase scale by 8%
1059 gc->Translate(5,5);
1060 gc->DrawPath(path);
1061 }
1062
1063 gc->PopState(); // restore saved state
1064 gc->PushState(); // save it again
1065 gc->Translate(400, 200);
1066
1067 gc->DrawText("Rotate", 0, -BASE2);
1068
1069 // Move the origin over to the next location
1070 gc->Translate(0, 75);
1071
1072 // draw our path again, rotating it about the central point,
1073 // and changing colors as we go
1074 for ( int angle = 0 ; angle < 360 ; angle += 30 )
1075 {
1076 gc->PushState(); // save this new current state so we can
1077 // pop back to it at the end of the loop
1078 wxImage::RGBValue val = wxImage::HSVtoRGB(wxImage::HSVValue(float(angle)/360, 1, 1));
1079 gc->SetBrush(wxBrush(wxColour(val.red, val.green, val.blue, 64)));
1080 gc->SetPen(wxPen(wxColour(val.red, val.green, val.blue, 128)));
1081
1082 // use translate to artfully reposition each drawn path
1083 gc->Translate(1.5 * BASE2 * cos(DegToRad(angle)),
1084 1.5 * BASE2 * sin(DegToRad(angle)));
1085
1086 // use Rotate to rotate the path
1087 gc->Rotate(DegToRad(angle));
1088
1089 // now draw it
1090 gc->DrawPath(path);
1091 gc->PopState();
1092 }
1093 gc->PopState();
1094 }
1095 #endif
1096
1097 void MyCanvas::DrawCircles(wxDC& dc)
1098 {
1099 int x = 100,
1100 y = 100,
1101 r = 20;
1102
1103 dc.SetPen( *wxRED_PEN );
1104 dc.SetBrush( *wxGREEN_BRUSH );
1105
1106 dc.DrawText(_T("Some circles"), 0, y);
1107 dc.DrawCircle(x, y, r);
1108 dc.DrawCircle(x + 2*r, y, r);
1109 dc.DrawCircle(x + 4*r, y, r);
1110
1111 y += 2*r;
1112 dc.DrawText(_T("And ellipses"), 0, y);
1113 dc.DrawEllipse(x - r, y, 2*r, r);
1114 dc.DrawEllipse(x + r, y, 2*r, r);
1115 dc.DrawEllipse(x + 3*r, y, 2*r, r);
1116
1117 y += 2*r;
1118 dc.DrawText(_T("And arcs"), 0, y);
1119 dc.DrawArc(x - r, y, x + r, y, x, y);
1120 dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y);
1121 dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y);
1122
1123 y += 2*r;
1124 dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90);
1125 dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
1126 dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
1127 dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
1128
1129 // same as above, just transparent brush
1130
1131 dc.SetPen( *wxRED_PEN );
1132 dc.SetBrush( *wxTRANSPARENT_BRUSH );
1133
1134 y += 2*r;
1135 dc.DrawText(_T("Some circles"), 0, y);
1136 dc.DrawCircle(x, y, r);
1137 dc.DrawCircle(x + 2*r, y, r);
1138 dc.DrawCircle(x + 4*r, y, r);
1139
1140 y += 2*r;
1141 dc.DrawText(_T("And ellipses"), 0, y);
1142 dc.DrawEllipse(x - r, y, 2*r, r);
1143 dc.DrawEllipse(x + r, y, 2*r, r);
1144 dc.DrawEllipse(x + 3*r, y, 2*r, r);
1145
1146 y += 2*r;
1147 dc.DrawText(_T("And arcs"), 0, y);
1148 dc.DrawArc(x - r, y, x + r, y, x, y);
1149 dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y);
1150 dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y);
1151
1152 y += 2*r;
1153 dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90);
1154 dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
1155 dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
1156 dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
1157
1158 }
1159
1160 void MyCanvas::DrawSplines(wxDC& dc)
1161 {
1162 #if wxUSE_SPLINES
1163 dc.DrawText(_T("Some splines"), 10, 5);
1164
1165 // values are hardcoded rather than randomly generated
1166 // so the output can be compared between native
1167 // implementations on platforms with different random
1168 // generators
1169
1170 const int R = 300;
1171 const wxPoint center( R + 20, R + 20 );
1172 const int angles[7] = { 0, 10, 33, 77, 13, 145, 90 };
1173 const int radii[5] = { 100 , 59, 85, 33, 90 };
1174 const int n = 200;
1175 wxPoint pts[n];
1176
1177 // background spline calculation
1178 unsigned int radius_pos = 0;
1179 unsigned int angle_pos = 0;
1180 int angle = 0;
1181 for ( int i = 0; i < n; i++ )
1182 {
1183 angle += angles[ angle_pos ];
1184 int r = R * radii[ radius_pos ] / 100;
1185 pts[ i ].x = center.x + (wxCoord)( r * cos( M_PI * angle / 180.0) );
1186 pts[ i ].y = center.y + (wxCoord)( r * sin( M_PI * angle / 180.0) );
1187
1188 angle_pos++;
1189 if ( angle_pos >= WXSIZEOF(angles) ) angle_pos = 0;
1190
1191 radius_pos++;
1192 if ( radius_pos >= WXSIZEOF(radii) ) radius_pos = 0;
1193 }
1194
1195 // background spline drawing
1196 dc.SetPen(*wxRED_PEN);
1197 dc.DrawSpline(WXSIZEOF(pts), pts);
1198
1199 // less detailed spline calculation
1200 wxPoint letters[4][5];
1201 // w
1202 letters[0][0] = wxPoint( 0,1); // O O
1203 letters[0][1] = wxPoint( 1,3); // * *
1204 letters[0][2] = wxPoint( 2,2); // * O *
1205 letters[0][3] = wxPoint( 3,3); // * * * *
1206 letters[0][4] = wxPoint( 4,1); // O O
1207 // x1
1208 letters[1][0] = wxPoint( 5,1); // O*O
1209 letters[1][1] = wxPoint( 6,1); // *
1210 letters[1][2] = wxPoint( 7,2); // O
1211 letters[1][3] = wxPoint( 8,3); // *
1212 letters[1][4] = wxPoint( 9,3); // O*O
1213 // x2
1214 letters[2][0] = wxPoint( 5,3); // O*O
1215 letters[2][1] = wxPoint( 6,3); // *
1216 letters[2][2] = wxPoint( 7,2); // O
1217 letters[2][3] = wxPoint( 8,1); // *
1218 letters[2][4] = wxPoint( 9,1); // O*O
1219 // W
1220 letters[3][0] = wxPoint(10,0); // O O
1221 letters[3][1] = wxPoint(11,3); // * *
1222 letters[3][2] = wxPoint(12,1); // * O *
1223 letters[3][3] = wxPoint(13,3); // * * * *
1224 letters[3][4] = wxPoint(14,0); // O O
1225
1226 const int dx = 2 * R / letters[3][4].x;
1227 const int h[4] = { -R/2, 0, R/4, R/2 };
1228
1229 for ( int m = 0; m < 4; m++ )
1230 {
1231 for ( int n = 0; n < 5; n++ )
1232 {
1233 letters[m][n].x = center.x - R + letters[m][n].x * dx;
1234 letters[m][n].y = center.y + h[ letters[m][n].y ];
1235 }
1236
1237 dc.SetPen( wxPen( wxT("blue"), 1, wxDOT) );
1238 dc.DrawLines(5, letters[m]);
1239 dc.SetPen( wxPen( wxT("black"), 4, wxSOLID) );
1240 dc.DrawSpline(5, letters[m]);
1241 }
1242
1243 #else
1244 dc.DrawText(_T("Splines not supported."), 10, 5);
1245 #endif
1246 }
1247
1248 void MyCanvas::DrawGradients(wxDC& dc)
1249 {
1250 static const int TEXT_HEIGHT = 15;
1251
1252 // LHS: linear
1253 wxRect r(10, 10, 50, 50);
1254 dc.DrawText(_T("wxRIGHT"), r.x, r.y);
1255 r.Offset(0, TEXT_HEIGHT);
1256 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxRIGHT);
1257
1258 r.Offset(0, r.height + 10);
1259 dc.DrawText(_T("wxLEFT"), r.x, r.y);
1260 r.Offset(0, TEXT_HEIGHT);
1261 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxLEFT);
1262
1263 r.Offset(0, r.height + 10);
1264 dc.DrawText(_T("wxDOWN"), r.x, r.y);
1265 r.Offset(0, TEXT_HEIGHT);
1266 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxDOWN);
1267
1268 r.Offset(0, r.height + 10);
1269 dc.DrawText(_T("wxUP"), r.x, r.y);
1270 r.Offset(0, TEXT_HEIGHT);
1271 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxUP);
1272
1273
1274 // RHS: concentric
1275 r = wxRect(200, 10, 50, 50);
1276 dc.DrawText(_T("Blue inside"), r.x, r.y);
1277 r.Offset(0, TEXT_HEIGHT);
1278 dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE);
1279
1280 r.Offset(0, r.height + 10);
1281 dc.DrawText(_T("White inside"), r.x, r.y);
1282 r.Offset(0, TEXT_HEIGHT);
1283 dc.GradientFillConcentric(r, *wxWHITE, *wxBLUE);
1284
1285 r.Offset(0, r.height + 10);
1286 dc.DrawText(_T("Blue in top left corner"), r.x, r.y);
1287 r.Offset(0, TEXT_HEIGHT);
1288 dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE, wxPoint(0, 0));
1289
1290 r.Offset(0, r.height + 10);
1291 dc.DrawText(_T("Blue in bottom right corner"), r.x, r.y);
1292 r.Offset(0, TEXT_HEIGHT);
1293 dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE, wxPoint(r.width, r.height));
1294
1295 // check that the area filled by the gradient is exactly the interior of
1296 // the rectangle
1297 r.x = 350;
1298 r.y = 30;
1299 dc.DrawText("The interior should be filled but", r.x, r.y);
1300 r.y += 15;
1301 dc.DrawText(" the red border should remain visible:", r.x, r.y);
1302 r.y += 15;
1303
1304 r.width =
1305 r.height = 50;
1306 wxRect r2 = r;
1307 r2.x += 60;
1308 wxRect r3 = r;
1309 r3.y += 60;
1310 wxRect r4 = r2;
1311 r4.y += 60;
1312 dc.SetPen(wxPen(wxColour(255, 0, 0)));
1313 dc.DrawRectangle(r);
1314 r.Deflate(1);
1315 dc.GradientFillLinear(r, wxColour(0,255,0), wxColour(0,0,0), wxNORTH);
1316 dc.DrawRectangle(r2);
1317 r2.Deflate(1);
1318 dc.GradientFillLinear(r2, wxColour(0,0,0), wxColour(0,255,0), wxSOUTH);
1319 dc.DrawRectangle(r3);
1320 r3.Deflate(1);
1321 dc.GradientFillLinear(r3, wxColour(0,255,0), wxColour(0,0,0), wxEAST);
1322 dc.DrawRectangle(r4);
1323 r4.Deflate(1);
1324 dc.GradientFillLinear(r4, wxColour(0,0,0), wxColour(0,255,0), wxWEST);
1325 }
1326
1327 void MyCanvas::DrawRegions(wxDC& dc)
1328 {
1329 dc.DrawText(_T("You should see a red rect partly covered by a cyan one ")
1330 _T("on the left"), 10, 5);
1331 dc.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
1332 10, 5 + dc.GetCharHeight());
1333 dc.DrawText(_T("The second copy should be identical but right part of it ")
1334 _T("should be offset by 10 pixels."),
1335 10, 5 + 2*dc.GetCharHeight());
1336
1337 DrawRegionsHelper(dc, 10, true);
1338 DrawRegionsHelper(dc, 350, false);
1339 }
1340
1341 void MyCanvas::DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime)
1342 {
1343 wxCoord y = 100;
1344
1345 dc.DestroyClippingRegion();
1346 dc.SetBrush( *wxWHITE_BRUSH );
1347 dc.SetPen( *wxTRANSPARENT_PEN );
1348 dc.DrawRectangle( x, y, 310, 310 );
1349
1350 dc.SetClippingRegion( x + 10, y + 10, 100, 270 );
1351
1352 dc.SetBrush( *wxRED_BRUSH );
1353 dc.DrawRectangle( x, y, 310, 310 );
1354
1355 dc.SetClippingRegion( x + 10, y + 10, 100, 100 );
1356
1357 dc.SetBrush( *wxCYAN_BRUSH );
1358 dc.DrawRectangle( x, y, 310, 310 );
1359
1360 dc.DestroyClippingRegion();
1361
1362 wxRegion region(x + 110, y + 20, 100, 270);
1363 #if !defined(__WXMOTIF__) && !defined(__WXMAC__)
1364 if ( !firstTime )
1365 region.Offset(10, 10);
1366 #endif
1367 dc.SetClippingRegion(region);
1368
1369 dc.SetBrush( *wxGREY_BRUSH );
1370 dc.DrawRectangle( x, y, 310, 310 );
1371
1372 if (m_smile_bmp.Ok())
1373 {
1374 dc.DrawBitmap( m_smile_bmp, x + 150, y + 150, true );
1375 dc.DrawBitmap( m_smile_bmp, x + 130, y + 10, true );
1376 dc.DrawBitmap( m_smile_bmp, x + 130, y + 280, true );
1377 dc.DrawBitmap( m_smile_bmp, x + 100, y + 70, true );
1378 dc.DrawBitmap( m_smile_bmp, x + 200, y + 70, true );
1379 }
1380 }
1381
1382 #if TEST_CAIRO_EVERYWHERE
1383 extern wxGraphicsRenderer* gCairoRenderer;
1384 #endif
1385
1386 void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
1387 {
1388 wxPaintDC pdc(this);
1389
1390 #if wxUSE_GRAPHICS_CONTEXT
1391 #if TEST_CAIRO_EVERYWHERE
1392 wxGCDC gdc;
1393 gdc.SetGraphicsContext( gCairoRenderer->CreateContext( pdc ) );
1394 #else
1395 wxGCDC gdc( pdc ) ;
1396 #endif
1397 wxDC &dc = m_useContext ? (wxDC&) gdc : (wxDC&) pdc ;
1398 #else
1399 wxDC &dc = pdc ;
1400 #endif
1401
1402 PrepareDC(dc);
1403
1404 m_owner->PrepareDC(dc);
1405
1406 dc.SetBackgroundMode( m_owner->m_backgroundMode );
1407 if ( m_owner->m_backgroundBrush.Ok() )
1408 dc.SetBackground( m_owner->m_backgroundBrush );
1409 if ( m_owner->m_colourForeground.Ok() )
1410 dc.SetTextForeground( m_owner->m_colourForeground );
1411 if ( m_owner->m_colourBackground.Ok() )
1412 dc.SetTextBackground( m_owner->m_colourBackground );
1413
1414 if ( m_owner->m_textureBackground) {
1415 if ( ! m_owner->m_backgroundBrush.Ok() ) {
1416 wxColour clr(0,128,0);
1417 wxBrush b(clr, wxSOLID);
1418 dc.SetBackground(b);
1419 }
1420 }
1421
1422 if ( m_clip )
1423 dc.SetClippingRegion(100, 100, 100, 100);
1424
1425 dc.Clear();
1426
1427 if ( m_owner->m_textureBackground )
1428 {
1429 dc.SetPen(*wxMEDIUM_GREY_PEN);
1430 for ( int i = 0; i < 200; i++ )
1431 dc.DrawLine(0, i*10, i*10, 0);
1432 }
1433
1434 switch ( m_show )
1435 {
1436 case Show_Default:
1437 DrawDefault(dc);
1438 break;
1439
1440 case Show_Circles:
1441 DrawCircles(dc);
1442 break;
1443
1444 case Show_Splines:
1445 DrawSplines(dc);
1446 break;
1447
1448 case Show_Regions:
1449 DrawRegions(dc);
1450 break;
1451
1452 case Show_Text:
1453 DrawText(dc);
1454 break;
1455
1456 case Show_Lines:
1457 DrawTestLines( 0, 100, 0, dc );
1458 DrawTestLines( 0, 320, 1, dc );
1459 DrawTestLines( 0, 540, 2, dc );
1460 DrawTestLines( 0, 760, 6, dc );
1461 break;
1462
1463 case Show_Brushes:
1464 DrawTestBrushes(dc);
1465 break;
1466
1467 case Show_Polygons:
1468 DrawTestPoly(dc);
1469 break;
1470
1471 case Show_Mask:
1472 DrawImages(dc, Draw_Normal);
1473 break;
1474
1475 case Show_Mask_Stretch:
1476 DrawImages(dc, Draw_Stretch);
1477 break;
1478
1479 case Show_Ops:
1480 DrawWithLogicalOps(dc);
1481 break;
1482
1483 #if wxUSE_GRAPHICS_CONTEXT
1484 case Show_Alpha:
1485 DrawAlpha(dc);
1486 break;
1487 case Show_Graphics:
1488 DrawGraphics(gdc.GetGraphicsContext());
1489 break;
1490 #endif
1491
1492 case Show_Gradient:
1493 DrawGradients(dc);
1494 break;
1495
1496 default:
1497 break;
1498 }
1499 }
1500
1501 void MyCanvas::OnMouseMove(wxMouseEvent &event)
1502 {
1503 #if wxUSE_STATUSBAR
1504 {
1505 wxClientDC dc(this);
1506 PrepareDC(dc);
1507 m_owner->PrepareDC(dc);
1508
1509 wxPoint pos = event.GetPosition();
1510 long x = dc.DeviceToLogicalX( pos.x );
1511 long y = dc.DeviceToLogicalY( pos.y );
1512 wxString str;
1513 str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y );
1514 m_owner->SetStatusText( str );
1515 }
1516
1517 if ( m_rubberBand )
1518 {
1519 int x,y, xx, yy ;
1520 event.GetPosition(&x,&y);
1521 CalcUnscrolledPosition( x, y, &xx, &yy );
1522 m_currentpoint = wxPoint( xx , yy ) ;
1523 wxRect newrect ( m_anchorpoint , m_currentpoint ) ;
1524
1525 wxClientDC dc( this ) ;
1526 PrepareDC( dc ) ;
1527
1528 wxDCOverlay overlaydc( m_overlay, &dc );
1529 overlaydc.Clear();
1530 #if __WXMAC__
1531 dc.SetPen( *wxGREY_PEN );
1532 dc.SetBrush( wxColour( 192,192,192,64 ) );
1533 #else
1534 dc.SetPen( wxPen( *wxLIGHT_GREY, 2, wxSOLID ) );
1535 dc.SetBrush( *wxTRANSPARENT_BRUSH );
1536 #endif
1537 dc.DrawRectangle( newrect );
1538 }
1539 #else
1540 wxUnusedVar(event);
1541 #endif // wxUSE_STATUSBAR
1542 }
1543
1544 void MyCanvas::OnMouseDown(wxMouseEvent &event)
1545 {
1546 int x,y,xx,yy ;
1547 event.GetPosition(&x,&y);
1548 CalcUnscrolledPosition( x, y, &xx, &yy );
1549 m_anchorpoint = wxPoint( xx , yy ) ;
1550 m_currentpoint = m_anchorpoint ;
1551 m_rubberBand = true ;
1552 CaptureMouse() ;
1553 }
1554
1555 void MyCanvas::OnMouseUp(wxMouseEvent &event)
1556 {
1557 if ( m_rubberBand )
1558 {
1559 ReleaseMouse();
1560 {
1561 wxClientDC dc( this );
1562 PrepareDC( dc );
1563 wxDCOverlay overlaydc( m_overlay, &dc );
1564 overlaydc.Clear();
1565 }
1566 m_overlay.Reset();
1567 m_rubberBand = false;
1568
1569 int x,y,xx,yy ;
1570 event.GetPosition(&x,&y);
1571 CalcUnscrolledPosition( x, y, &xx, &yy );
1572
1573 wxString str;
1574 str.Printf( wxT("Rectangle selection from %d,%d to %d,%d"),
1575 m_anchorpoint.x, m_anchorpoint.y , (int)xx, (int)yy );
1576 wxMessageBox( str , wxT("Rubber-Banding") );
1577
1578 }
1579 }
1580
1581 // ----------------------------------------------------------------------------
1582 // MyFrame
1583 // ----------------------------------------------------------------------------
1584
1585 // the event tables connect the wxWidgets events with the functions (event
1586 // handlers) which process them. It can be also done at run-time, but for the
1587 // simple menu events like this the static method is much simpler.
1588 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
1589 EVT_MENU (File_Quit, MyFrame::OnQuit)
1590 EVT_MENU (File_About, MyFrame::OnAbout)
1591 EVT_MENU (File_Clip, MyFrame::OnClip)
1592 #if wxUSE_GRAPHICS_CONTEXT
1593 EVT_MENU (File_GraphicContext, MyFrame::OnGraphicContext)
1594 #endif
1595
1596 EVT_MENU_RANGE(MenuShow_First, MenuShow_Last, MyFrame::OnShow)
1597
1598 EVT_MENU_RANGE(MenuOption_First, MenuOption_Last, MyFrame::OnOption)
1599 END_EVENT_TABLE()
1600
1601 // frame constructor
1602 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
1603 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size,
1604 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
1605 {
1606 // set the frame icon
1607 SetIcon(wxICON(mondrian));
1608
1609 wxMenu *menuFile = new wxMenu;
1610 menuFile->Append(File_ShowDefault, _T("&Default screen\tF1"));
1611 menuFile->Append(File_ShowText, _T("&Text screen\tF2"));
1612 menuFile->Append(File_ShowLines, _T("&Lines screen\tF3"));
1613 menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4"));
1614 menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5"));
1615 menuFile->Append(File_ShowMask, _T("&Mask screen\tF6"));
1616 menuFile->Append(File_ShowMaskStretch, _T("1/&2 scaled mask\tShift-F6"));
1617 menuFile->Append(File_ShowOps, _T("&ROP screen\tF7"));
1618 menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8"));
1619 menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9"));
1620 #if wxUSE_GRAPHICS_CONTEXT
1621 menuFile->Append(File_ShowAlpha, _T("&Alpha screen\tF10"));
1622 #endif
1623 menuFile->Append(File_ShowSplines, _T("&Splines screen\tF11"));
1624 menuFile->Append(File_ShowGradients, _T("&Gradients screen\tF12"));
1625 #if wxUSE_GRAPHICS_CONTEXT
1626 menuFile->Append(File_ShowGraphics, _T("&Graphics screen\tF13"));
1627 #endif
1628 menuFile->AppendSeparator();
1629 menuFile->AppendCheckItem(File_Clip, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
1630 #if wxUSE_GRAPHICS_CONTEXT
1631 menuFile->AppendCheckItem(File_GraphicContext, _T("&Use GraphicContext\tCtrl-Y"), _T("Use GraphicContext"));
1632 #endif
1633 menuFile->AppendSeparator();
1634 menuFile->Append(File_About, _T("&About...\tCtrl-A"), _T("Show about dialog"));
1635 menuFile->AppendSeparator();
1636 menuFile->Append(File_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
1637
1638 wxMenu *menuMapMode = new wxMenu;
1639 menuMapMode->Append( MapMode_Text, _T("&TEXT map mode") );
1640 menuMapMode->Append( MapMode_Lometric, _T("&LOMETRIC map mode") );
1641 menuMapMode->Append( MapMode_Twips, _T("T&WIPS map mode") );
1642 menuMapMode->Append( MapMode_Points, _T("&POINTS map mode") );
1643 menuMapMode->Append( MapMode_Metric, _T("&METRIC map mode") );
1644
1645 wxMenu *menuUserScale = new wxMenu;
1646 menuUserScale->Append( UserScale_StretchHoriz, _T("Stretch &horizontally\tCtrl-H") );
1647 menuUserScale->Append( UserScale_ShrinkHoriz, _T("Shrin&k horizontally\tCtrl-G") );
1648 menuUserScale->Append( UserScale_StretchVertic, _T("Stretch &vertically\tCtrl-V") );
1649 menuUserScale->Append( UserScale_ShrinkVertic, _T("&Shrink vertically\tCtrl-W") );
1650 menuUserScale->AppendSeparator();
1651 menuUserScale->Append( UserScale_Restore, _T("&Restore to normal\tCtrl-0") );
1652
1653 wxMenu *menuAxis = new wxMenu;
1654 menuAxis->AppendCheckItem( AxisMirror_Horiz, _T("Mirror horizontally\tCtrl-M") );
1655 menuAxis->AppendCheckItem( AxisMirror_Vertic, _T("Mirror vertically\tCtrl-N") );
1656
1657 wxMenu *menuLogical = new wxMenu;
1658 menuLogical->Append( LogicalOrigin_MoveDown, _T("Move &down\tCtrl-D") );
1659 menuLogical->Append( LogicalOrigin_MoveUp, _T("Move &up\tCtrl-U") );
1660 menuLogical->Append( LogicalOrigin_MoveLeft, _T("Move &right\tCtrl-L") );
1661 menuLogical->Append( LogicalOrigin_MoveRight, _T("Move &left\tCtrl-R") );
1662 menuLogical->AppendSeparator();
1663 menuLogical->Append( LogicalOrigin_Set, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1664 menuLogical->Append( LogicalOrigin_Restore, _T("&Restore to normal\tShift-Ctrl-0") );
1665
1666 wxMenu *menuColour = new wxMenu;
1667 #if wxUSE_COLOURDLG
1668 menuColour->Append( Colour_TextForeground, _T("Text &foreground...") );
1669 menuColour->Append( Colour_TextBackground, _T("Text &background...") );
1670 menuColour->Append( Colour_Background, _T("Background &colour...") );
1671 #endif // wxUSE_COLOURDLG
1672 menuColour->AppendCheckItem( Colour_BackgroundMode, _T("&Opaque/transparent\tCtrl-B") );
1673 menuColour->AppendCheckItem( Colour_TextureBackgound, _T("Draw textured back&ground\tCtrl-T") );
1674
1675 // now append the freshly created menu to the menu bar...
1676 wxMenuBar *menuBar = new wxMenuBar;
1677 menuBar->Append(menuFile, _T("&File"));
1678 menuBar->Append(menuMapMode, _T("&Mode"));
1679 menuBar->Append(menuUserScale, _T("&Scale"));
1680 menuBar->Append(menuAxis, _T("&Axis"));
1681 menuBar->Append(menuLogical, _T("&Origin"));
1682 menuBar->Append(menuColour, _T("&Colours"));
1683
1684 // ... and attach this menu bar to the frame
1685 SetMenuBar(menuBar);
1686
1687 #if wxUSE_STATUSBAR
1688 CreateStatusBar(2);
1689 SetStatusText(_T("Welcome to wxWidgets!"));
1690 #endif // wxUSE_STATUSBAR
1691
1692 m_mapMode = wxMM_TEXT;
1693 m_xUserScale = 1.0;
1694 m_yUserScale = 1.0;
1695 m_xLogicalOrigin = 0;
1696 m_yLogicalOrigin = 0;
1697 m_xAxisReversed =
1698 m_yAxisReversed = false;
1699 m_backgroundMode = wxSOLID;
1700 m_colourForeground = *wxRED;
1701 m_colourBackground = *wxBLUE;
1702 m_textureBackground = false;
1703
1704 m_canvas = new MyCanvas( this );
1705 m_canvas->SetScrollbars( 10, 10, 100, 240 );
1706 }
1707
1708 // event handlers
1709
1710 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1711 {
1712 // true is to force the frame to close
1713 Close(true);
1714 }
1715
1716 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1717 {
1718 wxString msg;
1719 msg.Printf( wxT("This is the about dialog of the drawing sample.\n")
1720 wxT("This sample tests various primitive drawing functions\n")
1721 wxT("(without any attempts to prevent flicker).\n")
1722 wxT("Copyright (c) Robert Roebling 1999")
1723 );
1724
1725 wxMessageBox(msg, _T("About Drawing"), wxOK | wxICON_INFORMATION, this);
1726 }
1727
1728 void MyFrame::OnClip(wxCommandEvent& event)
1729 {
1730 m_canvas->Clip(event.IsChecked());
1731 }
1732
1733 #if wxUSE_GRAPHICS_CONTEXT
1734 void MyFrame::OnGraphicContext(wxCommandEvent& event)
1735 {
1736 m_canvas->UseGraphicContext(event.IsChecked());
1737 }
1738 #endif
1739
1740 void MyFrame::OnShow(wxCommandEvent& event)
1741 {
1742 m_canvas->ToShow((ScreenToShow)(event.GetId() - MenuShow_First));
1743 }
1744
1745 void MyFrame::OnOption(wxCommandEvent& event)
1746 {
1747 switch (event.GetId())
1748 {
1749 case MapMode_Text:
1750 m_mapMode = wxMM_TEXT;
1751 break;
1752 case MapMode_Lometric:
1753 m_mapMode = wxMM_LOMETRIC;
1754 break;
1755 case MapMode_Twips:
1756 m_mapMode = wxMM_TWIPS;
1757 break;
1758 case MapMode_Points:
1759 m_mapMode = wxMM_POINTS;
1760 break;
1761 case MapMode_Metric:
1762 m_mapMode = wxMM_METRIC;
1763 break;
1764
1765 case LogicalOrigin_MoveDown:
1766 m_yLogicalOrigin += 10;
1767 break;
1768 case LogicalOrigin_MoveUp:
1769 m_yLogicalOrigin -= 10;
1770 break;
1771 case LogicalOrigin_MoveLeft:
1772 m_xLogicalOrigin += 10;
1773 break;
1774 case LogicalOrigin_MoveRight:
1775 m_xLogicalOrigin -= 10;
1776 break;
1777 case LogicalOrigin_Set:
1778 m_xLogicalOrigin =
1779 m_yLogicalOrigin = -100;
1780 break;
1781 case LogicalOrigin_Restore:
1782 m_xLogicalOrigin =
1783 m_yLogicalOrigin = 0;
1784 break;
1785
1786 case UserScale_StretchHoriz:
1787 m_xUserScale *= 1.10;
1788 break;
1789 case UserScale_ShrinkHoriz:
1790 m_xUserScale /= 1.10;
1791 break;
1792 case UserScale_StretchVertic:
1793 m_yUserScale *= 1.10;
1794 break;
1795 case UserScale_ShrinkVertic:
1796 m_yUserScale /= 1.10;
1797 break;
1798 case UserScale_Restore:
1799 m_xUserScale =
1800 m_yUserScale = 1.0;
1801 break;
1802
1803 case AxisMirror_Vertic:
1804 m_yAxisReversed = !m_yAxisReversed;
1805 break;
1806 case AxisMirror_Horiz:
1807 m_xAxisReversed = !m_xAxisReversed;
1808 break;
1809
1810 #if wxUSE_COLOURDLG
1811 case Colour_TextForeground:
1812 m_colourForeground = SelectColour();
1813 break;
1814 case Colour_TextBackground:
1815 m_colourBackground = SelectColour();
1816 break;
1817 case Colour_Background:
1818 {
1819 wxColour col = SelectColour();
1820 if ( col.Ok() )
1821 {
1822 m_backgroundBrush.SetColour(col);
1823 }
1824 }
1825 break;
1826 #endif // wxUSE_COLOURDLG
1827
1828 case Colour_BackgroundMode:
1829 m_backgroundMode = m_backgroundMode == wxSOLID ? wxTRANSPARENT
1830 : wxSOLID;
1831 break;
1832
1833 case Colour_TextureBackgound:
1834 m_textureBackground = ! m_textureBackground;
1835 break;
1836
1837 default:
1838 // skip Refresh()
1839 return;
1840 }
1841
1842 m_canvas->Refresh();
1843 }
1844
1845 void MyFrame::PrepareDC(wxDC& dc)
1846 {
1847 dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin );
1848 dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed );
1849 dc.SetUserScale( m_xUserScale, m_yUserScale );
1850 dc.SetMapMode( m_mapMode );
1851 }
1852
1853 #if wxUSE_COLOURDLG
1854 wxColour MyFrame::SelectColour()
1855 {
1856 wxColour col;
1857 wxColourData data;
1858 wxColourDialog dialog(this, &data);
1859
1860 if ( dialog.ShowModal() == wxID_OK )
1861 {
1862 col = dialog.GetColourData().GetColour();
1863 }
1864
1865 return col;
1866 }
1867 #endif // wxUSE_COLOURDLG