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