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