1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/drawing/drawing.cpp
3 // Purpose: shows and tests wxDC features
4 // Author: Robert Roebling
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers
33 #include "wx/colordlg.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 #include "wx/metafile.h"
42 #define TEST_CAIRO_EVERYWHERE 0
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 // the application icon
49 #ifndef wxHAS_IMAGES_IN_RESOURCES
50 #include "../sample.xpm"
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 static wxBitmap
*gs_bmpNoMask
= NULL
,
58 *gs_bmpWithColMask
= NULL
,
60 *gs_bmpWithMask
= NULL
,
65 // ----------------------------------------------------------------------------
67 // ----------------------------------------------------------------------------
69 // Define a new application type, each program should derive a class from wxApp
70 class MyApp
: public wxApp
73 // override base class virtuals
74 // ----------------------------
76 // this one is called on application startup and is a good place for the app
77 // initialization (doing it here and not in the ctor allows to have an error
78 // return: if OnInit() returns false, the application terminates)
79 virtual bool OnInit();
81 virtual int OnExit() { DeleteBitmaps(); return 0; }
91 // Define a new frame type: this is going to be our main frame
92 class MyFrame
: public wxFrame
96 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
98 // event handlers (these functions should _not_ be virtual)
99 void OnQuit(wxCommandEvent
& event
);
100 void OnAbout(wxCommandEvent
& event
);
101 void OnClip(wxCommandEvent
& event
);
102 #if wxUSE_GRAPHICS_CONTEXT
103 void OnGraphicContext(wxCommandEvent
& event
);
105 void OnCopy(wxCommandEvent
& event
);
106 void OnSave(wxCommandEvent
& event
);
107 void OnShow(wxCommandEvent
&event
);
108 void OnOption(wxCommandEvent
&event
);
111 wxColour
SelectColour();
112 #endif // wxUSE_COLOURDLG
113 void PrepareDC(wxDC
& dc
);
115 int m_backgroundMode
;
116 int m_textureBackground
;
117 wxMappingMode m_mapMode
;
120 int m_xLogicalOrigin
;
121 int m_yLogicalOrigin
;
122 bool m_xAxisReversed
,
124 wxColour m_colourForeground
, // these are _text_ colours
126 wxBrush m_backgroundBrush
;
130 // any class wishing to process wxWidgets events must use this macro
131 DECLARE_EVENT_TABLE()
134 // define a scrollable canvas for drawing onto
135 class MyCanvas
: public wxScrolledWindow
138 MyCanvas( MyFrame
*parent
);
140 void OnPaint(wxPaintEvent
&event
);
141 void OnMouseMove(wxMouseEvent
&event
);
142 void OnMouseDown(wxMouseEvent
&event
);
143 void OnMouseUp(wxMouseEvent
&event
);
145 void ToShow(int show
) { m_show
= show
; Refresh(); }
147 // set or remove the clipping region
148 void Clip(bool clip
) { m_clip
= clip
; Refresh(); }
149 #if wxUSE_GRAPHICS_CONTEXT
150 void UseGraphicContext(bool use
) { m_useContext
= use
; Refresh(); }
161 void DrawTestLines( int x
, int y
, int width
, wxDC
&dc
);
162 void DrawTestPoly(wxDC
& dc
);
163 void DrawTestBrushes(wxDC
& dc
);
164 void DrawText(wxDC
& dc
);
165 void DrawImages(wxDC
& dc
, DrawMode mode
);
166 void DrawWithLogicalOps(wxDC
& dc
);
167 #if wxUSE_GRAPHICS_CONTEXT
168 void DrawAlpha(wxDC
& dc
);
169 void DrawGraphics(wxGraphicsContext
* gc
);
171 void DrawRegions(wxDC
& dc
);
172 void DrawCircles(wxDC
& dc
);
173 void DrawSplines(wxDC
& dc
);
174 void DrawDefault(wxDC
& dc
);
175 void DrawGradients(wxDC
& dc
);
177 void DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
);
183 wxBitmap m_smile_bmp
;
188 wxPoint m_anchorpoint
;
189 wxPoint m_currentpoint
;
190 #if wxUSE_GRAPHICS_CONTEXT
194 DECLARE_EVENT_TABLE()
197 // ----------------------------------------------------------------------------
199 // ----------------------------------------------------------------------------
201 // IDs for the controls and the menu commands
205 File_Quit
= wxID_EXIT
,
206 File_About
= wxID_ABOUT
,
208 MenuShow_First
= wxID_HIGHEST
,
209 File_ShowDefault
= MenuShow_First
,
215 File_ShowMaskStretch
,
220 #if wxUSE_GRAPHICS_CONTEXT
225 MenuShow_Last
= File_ShowGradients
,
228 #if wxUSE_GRAPHICS_CONTEXT
236 MapMode_Text
= MenuOption_First
,
242 UserScale_StretchHoriz
,
243 UserScale_ShrinkHoriz
,
244 UserScale_StretchVertic
,
245 UserScale_ShrinkVertic
,
251 LogicalOrigin_MoveDown
,
252 LogicalOrigin_MoveUp
,
253 LogicalOrigin_MoveLeft
,
254 LogicalOrigin_MoveRight
,
256 LogicalOrigin_Restore
,
259 Colour_TextForeground
,
260 Colour_TextBackground
,
262 #endif // wxUSE_COLOURDLG
263 Colour_BackgroundMode
,
264 Colour_TextureBackgound
,
266 MenuOption_Last
= Colour_TextureBackgound
269 // ----------------------------------------------------------------------------
270 // event tables and other macros for wxWidgets
271 // ----------------------------------------------------------------------------
274 // Create a new application object: this macro will allow wxWidgets to create
275 // the application object during program execution (it's better than using a
276 // static object for many reasons) and also declares the accessor function
277 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
281 // ============================================================================
283 // ============================================================================
285 // ----------------------------------------------------------------------------
286 // the application class
287 // ----------------------------------------------------------------------------
289 bool MyApp::LoadImages()
291 gs_bmpNoMask
= new wxBitmap
;
292 gs_bmpWithColMask
= new wxBitmap
;
293 gs_bmpMask
= new wxBitmap
;
294 gs_bmpWithMask
= new wxBitmap
;
295 gs_bmp4
= new wxBitmap
;
296 gs_bmp4_mono
= new wxBitmap
;
297 gs_bmp36
= new wxBitmap
;
300 // special hack for Unix in-tree sample build, don't do this in real
301 // programs, use wxStandardPaths instead
302 pathList
.Add(wxFileName(argv
[0]).GetPath());
303 pathList
.Add(wxT("."));
304 pathList
.Add(wxT(".."));
305 pathList
.Add(wxT("../.."));
307 wxString path
= pathList
.FindValidPath(wxT("pat4.bmp"));
311 /* 4 colour bitmap */
312 gs_bmp4
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
313 /* turn into mono-bitmap */
314 gs_bmp4_mono
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
315 wxMask
* mask4
= new wxMask(*gs_bmp4_mono
, *wxBLACK
);
316 gs_bmp4_mono
->SetMask(mask4
);
318 path
= pathList
.FindValidPath(wxT("pat36.bmp"));
321 gs_bmp36
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
322 wxMask
* mask36
= new wxMask(*gs_bmp36
, *wxBLACK
);
323 gs_bmp36
->SetMask(mask36
);
325 path
= pathList
.FindValidPath(wxT("image.bmp"));
328 gs_bmpNoMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
329 gs_bmpWithMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
330 gs_bmpWithColMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
332 path
= pathList
.FindValidPath(wxT("mask.bmp"));
335 gs_bmpMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
337 wxMask
*mask
= new wxMask(*gs_bmpMask
, *wxBLACK
);
338 gs_bmpWithMask
->SetMask(mask
);
340 mask
= new wxMask(*gs_bmpWithColMask
, *wxWHITE
);
341 gs_bmpWithColMask
->SetMask(mask
);
346 // `Main program' equivalent: the program execution "starts" here
349 if ( !wxApp::OnInit() )
352 // Create the main application window
353 MyFrame
*frame
= new MyFrame(wxT("Drawing sample"),
354 wxDefaultPosition
, wxSize(550, 840));
361 wxLogError(wxT("Can't load one of the bitmap files needed ")
362 wxT("for this sample from the current or parent ")
363 wxT("directory, please copy them there."));
365 // still continue, the sample can be used without images too if they're
366 // missing for whatever reason
369 wxImage::AddHandler( new wxPNGHandler
);
375 void MyApp::DeleteBitmaps()
377 wxDELETE(gs_bmpNoMask
);
378 wxDELETE(gs_bmpWithColMask
);
379 wxDELETE(gs_bmpMask
);
380 wxDELETE(gs_bmpWithMask
);
382 wxDELETE(gs_bmp4_mono
);
386 // ----------------------------------------------------------------------------
388 // ----------------------------------------------------------------------------
390 // the event tables connect the wxWidgets events with the functions (event
391 // handlers) which process them.
392 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
393 EVT_PAINT (MyCanvas::OnPaint
)
394 EVT_MOTION (MyCanvas::OnMouseMove
)
395 EVT_LEFT_DOWN (MyCanvas::OnMouseDown
)
396 EVT_LEFT_UP (MyCanvas::OnMouseUp
)
401 MyCanvas::MyCanvas(MyFrame
*parent
)
402 : wxScrolledWindow(parent
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
403 wxHSCROLL
| wxVSCROLL
| wxNO_FULL_REPAINT_ON_RESIZE
)
406 m_show
= File_ShowDefault
;
407 m_smile_bmp
= wxBitmap(smile_xpm
);
408 m_std_icon
= wxArtProvider::GetIcon(wxART_INFORMATION
);
410 m_rubberBand
= false;
411 #if wxUSE_GRAPHICS_CONTEXT
412 m_useContext
= false;
416 void MyCanvas::DrawTestBrushes(wxDC
& dc
)
418 static const wxCoord WIDTH
= 200;
419 static const wxCoord HEIGHT
= 80;
424 dc
.SetBrush(*wxGREEN_BRUSH
);
425 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
426 dc
.DrawText(wxT("Solid green"), x
+ 10, y
+ 10);
429 dc
.SetBrush(wxBrush(*wxRED
, wxBRUSHSTYLE_CROSSDIAG_HATCH
));
430 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
431 dc
.DrawText(wxT("Diagonally hatched red"), x
+ 10, y
+ 10);
434 dc
.SetBrush(wxBrush(*wxBLUE
, wxBRUSHSTYLE_CROSS_HATCH
));
435 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
436 dc
.DrawText(wxT("Cross hatched blue"), x
+ 10, y
+ 10);
439 dc
.SetBrush(wxBrush(*wxCYAN
, wxBRUSHSTYLE_VERTICAL_HATCH
));
440 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
441 dc
.DrawText(wxT("Vertically hatched cyan"), x
+ 10, y
+ 10);
444 dc
.SetBrush(wxBrush(*wxBLACK
, wxBRUSHSTYLE_HORIZONTAL_HATCH
));
445 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
446 dc
.DrawText(wxT("Horizontally hatched black"), x
+ 10, y
+ 10);
449 dc
.SetBrush(wxBrush(*gs_bmpMask
));
450 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
451 dc
.DrawText(wxT("Stipple mono"), x
+ 10, y
+ 10);
454 dc
.SetBrush(wxBrush(*gs_bmpNoMask
));
455 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
456 dc
.DrawText(wxT("Stipple colour"), x
+ 10, y
+ 10);
459 void MyCanvas::DrawTestPoly(wxDC
& dc
)
461 wxBrush
brushHatch(*wxRED
, wxBRUSHSTYLE_FDIAGONAL_HATCH
);
462 dc
.SetBrush(brushHatch
);
465 star
[0] = wxPoint(100, 60);
466 star
[1] = wxPoint(60, 150);
467 star
[2] = wxPoint(160, 100);
468 star
[3] = wxPoint(40, 100);
469 star
[4] = wxPoint(140, 150);
471 dc
.DrawText(wxT("You should see two (irregular) stars below, the left one ")
472 wxT("hatched"), 10, 10);
473 dc
.DrawText(wxT("except for the central region and the right ")
474 wxT("one entirely hatched"), 10, 30);
475 dc
.DrawText(wxT("The third star only has a hatched outline"), 10, 50);
477 dc
.DrawPolygon(WXSIZEOF(star
), star
, 0, 30);
478 dc
.DrawPolygon(WXSIZEOF(star
), star
, 160, 30, wxWINDING_RULE
);
481 star2
[0] = wxPoint(0, 100);
482 star2
[1] = wxPoint(-59, -81);
483 star2
[2] = wxPoint(95, 31);
484 star2
[3] = wxPoint(-95, 31);
485 star2
[4] = wxPoint(59, -81);
486 star2
[5] = wxPoint(0, 80);
487 star2
[6] = wxPoint(-47, -64);
488 star2
[7] = wxPoint(76, 24);
489 star2
[8] = wxPoint(-76, 24);
490 star2
[9] = wxPoint(47, -64);
491 int count
[2] = {5, 5};
493 dc
.DrawPolyPolygon(WXSIZEOF(count
), count
, star2
, 450, 150);
496 void MyCanvas::DrawTestLines( int x
, int y
, int width
, wxDC
&dc
)
498 dc
.SetPen( wxPen( *wxBLACK
, width
) );
499 dc
.SetBrush( *wxRED_BRUSH
);
500 dc
.DrawText(wxString::Format(wxT("Testing lines of width %d"), width
), x
+ 10, y
- 10);
501 dc
.DrawRectangle( x
+10, y
+10, 100, 190 );
503 dc
.DrawText(wxT("Solid/dot/short dash/long dash/dot dash"), x
+ 150, y
+ 10);
504 dc
.SetPen( wxPen( *wxBLACK
, width
) );
505 dc
.DrawLine( x
+20, y
+20, 100, y
+20 );
506 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_DOT
) );
507 dc
.DrawLine( x
+20, y
+30, 100, y
+30 );
508 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_SHORT_DASH
) );
509 dc
.DrawLine( x
+20, y
+40, 100, y
+40 );
510 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_LONG_DASH
) );
511 dc
.DrawLine( x
+20, y
+50, 100, y
+50 );
512 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_DOT_DASH
) );
513 dc
.DrawLine( x
+20, y
+60, 100, y
+60 );
515 dc
.DrawText(wxT("Misc hatches"), x
+ 150, y
+ 70);
516 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_BDIAGONAL_HATCH
) );
517 dc
.DrawLine( x
+20, y
+70, 100, y
+70 );
518 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_CROSSDIAG_HATCH
) );
519 dc
.DrawLine( x
+20, y
+80, 100, y
+80 );
520 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_FDIAGONAL_HATCH
) );
521 dc
.DrawLine( x
+20, y
+90, 100, y
+90 );
522 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_CROSS_HATCH
) );
523 dc
.DrawLine( x
+20, y
+100, 100, y
+100 );
524 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_HORIZONTAL_HATCH
) );
525 dc
.DrawLine( x
+20, y
+110, 100, y
+110 );
526 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_VERTICAL_HATCH
) );
527 dc
.DrawLine( x
+20, y
+120, 100, y
+120 );
529 dc
.DrawText(wxT("User dash"), x
+ 150, y
+ 140);
530 wxPen
ud( *wxBLACK
, width
, wxPENSTYLE_USER_DASH
);
532 dash1
[0] = 8; // Long dash <---------+
533 dash1
[1] = 2; // Short gap |
534 dash1
[2] = 3; // Short dash |
535 dash1
[3] = 2; // Short gap |
536 dash1
[4] = 3; // Short dash |
537 dash1
[5] = 2; // Short gap and repeat +
538 ud
.SetDashes( 6, dash1
);
540 dc
.DrawLine( x
+20, y
+140, 100, y
+140 );
541 dash1
[0] = 5; // Make first dash shorter
542 ud
.SetDashes( 6, dash1
);
544 dc
.DrawLine( x
+20, y
+150, 100, y
+150 );
545 dash1
[2] = 5; // Make second dash longer
546 ud
.SetDashes( 6, dash1
);
548 dc
.DrawLine( x
+20, y
+160, 100, y
+160 );
549 dash1
[4] = 5; // Make third dash longer
550 ud
.SetDashes( 6, dash1
);
552 dc
.DrawLine( x
+20, y
+170, 100, y
+170 );
555 void MyCanvas::DrawDefault(wxDC
& dc
)
557 // Draw circle centered at the origin, then flood fill it with a different
558 // color. Done with a wxMemoryDC because Blit (used by generic
559 // wxDoFloodFill) from a window that is being painted gives unpredictable
562 wxImage
img(21, 21, false);
567 mdc
.SetBrush(dc
.GetBrush());
568 mdc
.SetPen(dc
.GetPen());
569 mdc
.DrawCircle(10, 10, 10);
571 if (mdc
.GetPixel(11, 11, &c
))
573 mdc
.SetBrush(wxColour(128, 128, 0));
574 mdc
.FloodFill(11, 11, c
, wxFLOOD_SURFACE
);
577 bmp
.SetMask(new wxMask(bmp
, wxColour(1, 1, 1)));
578 dc
.DrawBitmap(bmp
, -10, -10, true);
581 dc
.DrawCheckMark(5, 80, 15, 15);
582 dc
.DrawCheckMark(25, 80, 30, 30);
583 dc
.DrawCheckMark(60, 80, 60, 60);
585 // this is the test for "blitting bitmap into DC damages selected brush" bug
586 wxCoord rectSize
= m_std_icon
.GetWidth() + 10;
588 dc
.SetPen(*wxTRANSPARENT_PEN
);
589 dc
.SetBrush( *wxGREEN_BRUSH
);
590 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
591 dc
.DrawBitmap(m_std_icon
, x
+ 5, 15, true);
593 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
594 dc
.DrawIcon(m_std_icon
, x
+ 5, 15);
596 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
598 // test for "transparent" bitmap drawing (it intersects with the last
600 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
602 if (m_smile_bmp
.IsOk())
603 dc
.DrawBitmap(m_smile_bmp
, x
+ rectSize
- 20, rectSize
- 10, true);
605 dc
.SetBrush( *wxBLACK_BRUSH
);
606 dc
.DrawRectangle( 0, 160, 1000, 300 );
609 wxBitmap
bitmap(20,70);
611 memdc
.SelectObject( bitmap
);
612 memdc
.SetBrush( *wxBLACK_BRUSH
);
613 memdc
.SetPen( *wxWHITE_PEN
);
614 memdc
.DrawRectangle(0,0,20,70);
615 memdc
.DrawLine( 10,0,10,70 );
618 wxPen pen
= *wxRED_PEN
;
620 memdc
.DrawLine( 10, 5,10, 5 );
621 memdc
.DrawLine( 10,10,11,10 );
622 memdc
.DrawLine( 10,15,12,15 );
623 memdc
.DrawLine( 10,20,13,20 );
626 memdc.SetPen(*wxRED_PEN);
627 memdc.DrawLine( 12, 5,12, 5 );
628 memdc.DrawLine( 12,10,13,10 );
629 memdc.DrawLine( 12,15,14,15 );
630 memdc.DrawLine( 12,20,15,20 );
634 memdc
.DrawLine( 10,25,10,25 );
635 memdc
.DrawLine( 10,30, 9,30 );
636 memdc
.DrawLine( 10,35, 8,35 );
637 memdc
.DrawLine( 10,40, 7,40 );
640 dc
.SetPen(*wxWHITE_PEN
);
641 memdc
.SetLogicalFunction( wxINVERT
);
642 memdc
.SetPen( *wxWHITE_PEN
);
643 memdc
.DrawLine( 10,50,10,50 );
644 memdc
.DrawLine( 10,55,11,55 );
645 memdc
.DrawLine( 10,60,12,60 );
646 memdc
.DrawLine( 10,65,13,65 );
648 memdc
.DrawLine( 12,50,12,50 );
649 memdc
.DrawLine( 12,55,13,55 );
650 memdc
.DrawLine( 12,60,14,60 );
651 memdc
.DrawLine( 12,65,15,65 );
653 memdc
.SelectObject( wxNullBitmap
);
654 dc
.DrawBitmap( bitmap
, 10, 170 );
655 wxImage image
= bitmap
.ConvertToImage();
656 image
.Rescale( 60,210 );
657 bitmap
= wxBitmap(image
);
658 dc
.DrawBitmap( bitmap
, 50, 170 );
660 // test the rectangle outline drawing - there should be one pixel between
661 // the rect and the lines
662 dc
.SetPen(*wxWHITE_PEN
);
663 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
664 dc
.DrawRectangle(150, 170, 49, 29);
665 dc
.DrawRectangle(200, 170, 49, 29);
666 dc
.SetPen(*wxWHITE_PEN
);
667 dc
.DrawLine(250, 210, 250, 170);
668 dc
.DrawLine(260, 200, 150, 200);
670 // test the rectangle filled drawing - there should be one pixel between
671 // the rect and the lines
672 dc
.SetPen(*wxTRANSPARENT_PEN
);
673 dc
.SetBrush( *wxWHITE_BRUSH
);
674 dc
.DrawRectangle(300, 170, 49, 29);
675 dc
.DrawRectangle(350, 170, 49, 29);
676 dc
.SetPen(*wxWHITE_PEN
);
677 dc
.DrawLine(400, 170, 400, 210);
678 dc
.DrawLine(300, 200, 410, 200);
680 // a few more tests of this kind
681 dc
.SetPen(*wxRED_PEN
);
682 dc
.SetBrush( *wxWHITE_BRUSH
);
683 dc
.DrawRectangle(300, 220, 1, 1);
684 dc
.DrawRectangle(310, 220, 2, 2);
685 dc
.DrawRectangle(320, 220, 3, 3);
686 dc
.DrawRectangle(330, 220, 4, 4);
688 dc
.SetPen(*wxTRANSPARENT_PEN
);
689 dc
.SetBrush( *wxWHITE_BRUSH
);
690 dc
.DrawRectangle(300, 230, 1, 1);
691 dc
.DrawRectangle(310, 230, 2, 2);
692 dc
.DrawRectangle(320, 230, 3, 3);
693 dc
.DrawRectangle(330, 230, 4, 4);
695 // and now for filled rect with outline
696 dc
.SetPen(*wxRED_PEN
);
697 dc
.SetBrush( *wxWHITE_BRUSH
);
698 dc
.DrawRectangle(500, 170, 49, 29);
699 dc
.DrawRectangle(550, 170, 49, 29);
700 dc
.SetPen(*wxWHITE_PEN
);
701 dc
.DrawLine(600, 170, 600, 210);
702 dc
.DrawLine(500, 200, 610, 200);
704 // test the rectangle outline drawing - there should be one pixel between
705 // the rect and the lines
706 dc
.SetPen(*wxWHITE_PEN
);
707 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
708 dc
.DrawRoundedRectangle(150, 270, 49, 29, 6);
709 dc
.DrawRoundedRectangle(200, 270, 49, 29, 6);
710 dc
.SetPen(*wxWHITE_PEN
);
711 dc
.DrawLine(250, 270, 250, 310);
712 dc
.DrawLine(150, 300, 260, 300);
714 // test the rectangle filled drawing - there should be one pixel between
715 // the rect and the lines
716 dc
.SetPen(*wxTRANSPARENT_PEN
);
717 dc
.SetBrush( *wxWHITE_BRUSH
);
718 dc
.DrawRoundedRectangle(300, 270, 49, 29, 6);
719 dc
.DrawRoundedRectangle(350, 270, 49, 29, 6);
720 dc
.SetPen(*wxWHITE_PEN
);
721 dc
.DrawLine(400, 270, 400, 310);
722 dc
.DrawLine(300, 300, 410, 300);
724 // Added by JACS to demonstrate bizarre behaviour.
725 // With a size of 70, we get a missing red RHS,
726 // and the height is too small, so we get yellow
727 // showing. With a size of 40, it draws as expected:
728 // it just shows a white rectangle with red outline.
730 int totalHeight
= 70;
731 wxBitmap
bitmap2(totalWidth
, totalHeight
);
734 memdc2
.SelectObject(bitmap2
);
736 memdc2
.SetBackground(*wxYELLOW_BRUSH
);
739 // Now draw a white rectangle with red outline. It should
740 // entirely eclipse the yellow background.
741 memdc2
.SetPen(*wxRED_PEN
);
742 memdc2
.SetBrush(*wxWHITE_BRUSH
);
744 memdc2
.DrawRectangle(0, 0, totalWidth
, totalHeight
);
746 memdc2
.SetPen(wxNullPen
);
747 memdc2
.SetBrush(wxNullBrush
);
748 memdc2
.SelectObject(wxNullBitmap
);
750 dc
.DrawBitmap(bitmap2
, 500, 270);
752 // Repeat, but draw directly on dc
753 // Draw a yellow rectangle filling the bitmap
755 x
= 600; int y
= 270;
756 dc
.SetPen(*wxYELLOW_PEN
);
757 dc
.SetBrush(*wxYELLOW_BRUSH
);
758 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
760 // Now draw a white rectangle with red outline. It should
761 // entirely eclipse the yellow background.
762 dc
.SetPen(*wxRED_PEN
);
763 dc
.SetBrush(*wxWHITE_BRUSH
);
765 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
768 void MyCanvas::DrawText(wxDC
& dc
)
770 // set underlined font for testing
771 dc
.SetFont( wxFont(12, wxMODERN
, wxNORMAL
, wxNORMAL
, true) );
772 dc
.DrawText( wxT("This is text"), 110, 10 );
773 dc
.DrawRotatedText( wxT("That is text"), 20, 10, -45 );
775 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
776 // under Win9x (it is not TrueType)
777 dc
.SetFont( *wxSWISS_FONT
);
780 dc
.SetBackgroundMode(wxTRANSPARENT
);
782 for ( int n
= -180; n
< 180; n
+= 30 )
784 text
.Printf(wxT(" %d rotated text"), n
);
785 dc
.DrawRotatedText(text
, 400, 400, n
);
788 dc
.SetFont( wxFont( 18, wxSWISS
, wxNORMAL
, wxNORMAL
) );
790 dc
.DrawText( wxT("This is Swiss 18pt text."), 110, 40 );
795 dc
.GetTextExtent( wxT("This is Swiss 18pt text."), &length
, &height
, &descent
);
796 text
.Printf( wxT("Dimensions are length %d, height %d, descent %d"), length
, height
, descent
);
797 dc
.DrawText( text
, 110, 80 );
799 text
.Printf( wxT("CharHeight() returns: %d"), dc
.GetCharHeight() );
800 dc
.DrawText( text
, 110, 120 );
802 dc
.DrawRectangle( 100, 40, 4, height
);
804 // test the logical function effect
806 dc
.SetLogicalFunction(wxINVERT
);
807 // text drawing should ignore logical function
808 dc
.DrawText( wxT("There should be a text below"), 110, 150 );
809 dc
.DrawRectangle( 110, y
, 100, height
);
812 dc
.DrawText( wxT("Visible text"), 110, y
);
813 dc
.DrawRectangle( 110, y
, 100, height
);
814 dc
.DrawText( wxT("Visible text"), 110, y
);
815 dc
.DrawRectangle( 110, y
, 100, height
);
816 dc
.SetLogicalFunction(wxCOPY
);
819 dc
.DrawRectangle( 110, y
, 100, height
);
820 dc
.DrawText( wxT("Another visible text"), 110, y
);
823 dc
.DrawText("And\nmore\ntext on\nmultiple\nlines", 110, y
);
829 wxRasterOperationMode rop
;
830 } rasterOperations
[] =
832 { wxT("wxAND"), wxAND
},
833 { wxT("wxAND_INVERT"), wxAND_INVERT
},
834 { wxT("wxAND_REVERSE"), wxAND_REVERSE
},
835 { wxT("wxCLEAR"), wxCLEAR
},
836 { wxT("wxCOPY"), wxCOPY
},
837 { wxT("wxEQUIV"), wxEQUIV
},
838 { wxT("wxINVERT"), wxINVERT
},
839 { wxT("wxNAND"), wxNAND
},
840 { wxT("wxNO_OP"), wxNO_OP
},
841 { wxT("wxOR"), wxOR
},
842 { wxT("wxOR_INVERT"), wxOR_INVERT
},
843 { wxT("wxOR_REVERSE"), wxOR_REVERSE
},
844 { wxT("wxSET"), wxSET
},
845 { wxT("wxSRC_INVERT"), wxSRC_INVERT
},
846 { wxT("wxXOR"), wxXOR
},
849 void MyCanvas::DrawImages(wxDC
& dc
, DrawMode mode
)
851 dc
.DrawText(wxT("original image"), 0, 0);
852 dc
.DrawBitmap(*gs_bmpNoMask
, 0, 20, 0);
853 dc
.DrawText(wxT("with colour mask"), 0, 100);
854 dc
.DrawBitmap(*gs_bmpWithColMask
, 0, 120, true);
855 dc
.DrawText(wxT("the mask image"), 0, 200);
856 dc
.DrawBitmap(*gs_bmpMask
, 0, 220, 0);
857 dc
.DrawText(wxT("masked image"), 0, 300);
858 dc
.DrawBitmap(*gs_bmpWithMask
, 0, 320, true);
860 int cx
= gs_bmpWithColMask
->GetWidth(),
861 cy
= gs_bmpWithColMask
->GetHeight();
864 for ( size_t n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
866 wxCoord x
= 120 + 150*(n%4
),
869 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
870 memDC
.SelectObject(*gs_bmpWithColMask
);
871 if ( mode
== Draw_Stretch
)
873 dc
.StretchBlit(x
, y
, cx
, cy
, &memDC
, 0, 0, cx
/2, cy
/2,
874 rasterOperations
[n
].rop
, true);
878 dc
.Blit(x
, y
, cx
, cy
, &memDC
, 0, 0, rasterOperations
[n
].rop
, true);
883 void MyCanvas::DrawWithLogicalOps(wxDC
& dc
)
885 static const wxCoord w
= 60;
886 static const wxCoord h
= 60;
888 // reuse the text colour here
889 dc
.SetPen(wxPen(m_owner
->m_colourForeground
));
890 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
893 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
895 wxCoord x
= 20 + 150*(n%4
),
898 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
899 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
900 dc
.DrawRectangle(x
, y
, w
, h
);
901 dc
.DrawLine(x
, y
, x
+ w
, y
+ h
);
902 dc
.DrawLine(x
+ w
, y
, x
, y
+ h
);
905 // now some filled rectangles
906 dc
.SetBrush(wxBrush(m_owner
->m_colourForeground
));
908 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
910 wxCoord x
= 20 + 150*(n%4
),
913 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
914 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
915 dc
.DrawRectangle(x
, y
, w
, h
);
919 #if wxUSE_GRAPHICS_CONTEXT
921 void MyCanvas::DrawAlpha(wxDC
& WXUNUSED(dummyDC
))
923 void MyCanvas::DrawAlpha(wxDC
& dc
)
931 wxDouble margin
= 20 ;
932 wxDouble width
= 180 ;
933 wxDouble radius
= 30 ;
935 dc
.SetPen( wxPen( wxColour( 128, 0, 0 ), 12 ));
936 dc
.SetBrush(*wxRED_BRUSH
);
938 wxRect
r(margin
,margin
+width
*0.66,width
,width
) ;
940 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
942 dc
.SetPen( wxPen( wxColour( 0, 0, 128 ), 12));
943 dc
.SetBrush(*wxBLUE_BRUSH
);
945 r
.Offset( width
* 0.8 , - width
* 0.66 ) ;
947 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
949 dc
.SetPen( wxPen( wxColour( 128, 128, 0 ), 12));
950 dc
.SetBrush( wxBrush( wxColour( 192, 192, 0)));
952 r
.Offset( width
* 0.8 , width
*0.5 ) ;
954 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
956 dc
.SetPen( *wxTRANSPARENT_PEN
) ;
957 dc
.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
958 dc
.DrawRoundedRectangle( 0 , margin
+ width
/ 2 , width
* 3 , 100 , radius
) ;
960 dc
.SetTextForeground( wxColour(255,255,0,128) );
961 dc
.SetFont( wxFont( 40, wxFONTFAMILY_SWISS
, wxFONTSTYLE_ITALIC
, wxFONTWEIGHT_NORMAL
) );
962 dc
.DrawText( wxT("Hello!"), 120, 80 );
967 #if wxUSE_GRAPHICS_CONTEXT
969 const int BASE
= 80.0;
970 const int BASE2
= BASE
/2;
971 const int BASE4
= BASE
/4;
973 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
976 // modeled along Robin Dunn's GraphicsContext.py sample
978 void MyCanvas::DrawGraphics(wxGraphicsContext
* gc
)
980 wxFont font
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
981 gc
->SetFont(font
,*wxBLACK
);
983 // make a path that contains a circle and some lines, centered at 0,0
984 wxGraphicsPath path
= gc
->CreatePath() ;
985 path
.AddCircle( 0, 0, BASE2
);
986 path
.MoveToPoint(0, -BASE2
);
987 path
.AddLineToPoint(0, BASE2
);
988 path
.MoveToPoint(-BASE2
, 0);
989 path
.AddLineToPoint(BASE2
, 0);
991 path
.AddRectangle(-BASE4
, -BASE4
/2, BASE2
, BASE4
);
993 // Now use that path to demonstrate various capbilites of the grpahics context
994 gc
->PushState(); // save current translation/scale/other state
995 gc
->Translate(60, 75); // reposition the context origin
997 gc
->SetPen(wxPen("navy"));
998 gc
->SetBrush(wxBrush("pink"));
1000 for( int i
= 0 ; i
< 3 ; ++i
)
1006 label
= "StrokePath";
1016 gc
->GetTextExtent(label
, &w
, &h
, NULL
, NULL
);
1017 gc
->DrawText(label
, -w
/2, -BASE2
-h
-4);
1021 gc
->StrokePath(path
);
1030 gc
->Translate(2*BASE
, 0);
1033 gc
->PopState(); // restore saved state
1034 gc
->PushState(); // save it again
1035 gc
->Translate(60, 200); // offset to the lower part of the window
1037 gc
->DrawText("Scale", 0, -BASE2
);
1038 gc
->Translate(0, 20);
1040 gc
->SetBrush(wxBrush(wxColour(178, 34, 34, 128)));// 128 == half transparent
1041 for( int i
= 0 ; i
< 8 ; ++i
)
1043 gc
->Scale(1.08, 1.08); // increase scale by 8%
1048 gc
->PopState(); // restore saved state
1049 gc
->PushState(); // save it again
1050 gc
->Translate(400, 200);
1052 gc
->DrawText("Rotate", 0, -BASE2
);
1054 // Move the origin over to the next location
1055 gc
->Translate(0, 75);
1057 // draw our path again, rotating it about the central point,
1058 // and changing colors as we go
1059 for ( int angle
= 0 ; angle
< 360 ; angle
+= 30 )
1061 gc
->PushState(); // save this new current state so we can
1062 // pop back to it at the end of the loop
1063 wxImage::RGBValue val
= wxImage::HSVtoRGB(wxImage::HSVValue(float(angle
)/360, 1, 1));
1064 gc
->SetBrush(wxBrush(wxColour(val
.red
, val
.green
, val
.blue
, 64)));
1065 gc
->SetPen(wxPen(wxColour(val
.red
, val
.green
, val
.blue
, 128)));
1067 // use translate to artfully reposition each drawn path
1068 gc
->Translate(1.5 * BASE2
* cos(DegToRad(angle
)),
1069 1.5 * BASE2
* sin(DegToRad(angle
)));
1071 // use Rotate to rotate the path
1072 gc
->Rotate(DegToRad(angle
));
1081 gc
->Translate(60, 400);
1082 gc
->DrawText("Scaled smiley inside a square", 0, 0);
1083 gc
->DrawRectangle(BASE2
, BASE2
, 100, 100);
1084 gc
->DrawBitmap(m_smile_bmp
, BASE2
, BASE2
, 100, 100);
1087 #endif // wxUSE_GRAPHICS_CONTEXT
1089 void MyCanvas::DrawCircles(wxDC
& dc
)
1095 dc
.SetPen( *wxRED_PEN
);
1096 dc
.SetBrush( *wxGREEN_BRUSH
);
1098 dc
.DrawText(wxT("Some circles"), 0, y
);
1099 dc
.DrawCircle(x
, y
, r
);
1100 dc
.DrawCircle(x
+ 2*r
, y
, r
);
1101 dc
.DrawCircle(x
+ 4*r
, y
, r
);
1104 dc
.DrawText(wxT("And ellipses"), 0, y
);
1105 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
1106 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
1107 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
1110 dc
.DrawText(wxT("And arcs"), 0, y
);
1111 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
1112 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
1113 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
1116 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
1117 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
1118 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
1119 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
1121 // same as above, just transparent brush
1123 dc
.SetPen( *wxRED_PEN
);
1124 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
1127 dc
.DrawText(wxT("Some circles"), 0, y
);
1128 dc
.DrawCircle(x
, y
, r
);
1129 dc
.DrawCircle(x
+ 2*r
, y
, r
);
1130 dc
.DrawCircle(x
+ 4*r
, y
, r
);
1133 dc
.DrawText(wxT("And ellipses"), 0, y
);
1134 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
1135 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
1136 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
1139 dc
.DrawText(wxT("And arcs"), 0, y
);
1140 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
1141 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
1142 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
1145 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
1146 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
1147 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
1148 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
1152 void MyCanvas::DrawSplines(wxDC
& dc
)
1155 dc
.DrawText(wxT("Some splines"), 10, 5);
1157 // values are hardcoded rather than randomly generated
1158 // so the output can be compared between native
1159 // implementations on platforms with different random
1163 const wxPoint
center( R
+ 20, R
+ 20 );
1164 const int angles
[7] = { 0, 10, 33, 77, 13, 145, 90 };
1165 const int radii
[5] = { 100 , 59, 85, 33, 90 };
1169 // background spline calculation
1170 unsigned int radius_pos
= 0;
1171 unsigned int angle_pos
= 0;
1173 for ( int i
= 0; i
< n
; i
++ )
1175 angle
+= angles
[ angle_pos
];
1176 int r
= R
* radii
[ radius_pos
] / 100;
1177 pts
[ i
].x
= center
.x
+ (wxCoord
)( r
* cos( M_PI
* angle
/ 180.0) );
1178 pts
[ i
].y
= center
.y
+ (wxCoord
)( r
* sin( M_PI
* angle
/ 180.0) );
1181 if ( angle_pos
>= WXSIZEOF(angles
) ) angle_pos
= 0;
1184 if ( radius_pos
>= WXSIZEOF(radii
) ) radius_pos
= 0;
1187 // background spline drawing
1188 dc
.SetPen(*wxRED_PEN
);
1189 dc
.DrawSpline(WXSIZEOF(pts
), pts
);
1191 // less detailed spline calculation
1192 wxPoint letters
[4][5];
1194 letters
[0][0] = wxPoint( 0,1); // O O
1195 letters
[0][1] = wxPoint( 1,3); // * *
1196 letters
[0][2] = wxPoint( 2,2); // * O *
1197 letters
[0][3] = wxPoint( 3,3); // * * * *
1198 letters
[0][4] = wxPoint( 4,1); // O O
1200 letters
[1][0] = wxPoint( 5,1); // O*O
1201 letters
[1][1] = wxPoint( 6,1); // *
1202 letters
[1][2] = wxPoint( 7,2); // O
1203 letters
[1][3] = wxPoint( 8,3); // *
1204 letters
[1][4] = wxPoint( 9,3); // O*O
1206 letters
[2][0] = wxPoint( 5,3); // O*O
1207 letters
[2][1] = wxPoint( 6,3); // *
1208 letters
[2][2] = wxPoint( 7,2); // O
1209 letters
[2][3] = wxPoint( 8,1); // *
1210 letters
[2][4] = wxPoint( 9,1); // O*O
1212 letters
[3][0] = wxPoint(10,0); // O O
1213 letters
[3][1] = wxPoint(11,3); // * *
1214 letters
[3][2] = wxPoint(12,1); // * O *
1215 letters
[3][3] = wxPoint(13,3); // * * * *
1216 letters
[3][4] = wxPoint(14,0); // O O
1218 const int dx
= 2 * R
/ letters
[3][4].x
;
1219 const int h
[4] = { -R
/2, 0, R
/4, R
/2 };
1221 for ( int m
= 0; m
< 4; m
++ )
1223 for ( int n
= 0; n
< 5; n
++ )
1225 letters
[m
][n
].x
= center
.x
- R
+ letters
[m
][n
].x
* dx
;
1226 letters
[m
][n
].y
= center
.y
+ h
[ letters
[m
][n
].y
];
1229 dc
.SetPen( wxPen( *wxBLUE
, 1, wxDOT
) );
1230 dc
.DrawLines(5, letters
[m
]);
1231 dc
.SetPen( wxPen( *wxBLACK
, 4) );
1232 dc
.DrawSpline(5, letters
[m
]);
1236 dc
.DrawText(wxT("Splines not supported."), 10, 5);
1240 void MyCanvas::DrawGradients(wxDC
& dc
)
1242 static const int TEXT_HEIGHT
= 15;
1245 wxRect
r(10, 10, 50, 50);
1246 dc
.DrawText(wxT("wxRIGHT"), r
.x
, r
.y
);
1247 r
.Offset(0, TEXT_HEIGHT
);
1248 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxRIGHT
);
1250 r
.Offset(0, r
.height
+ 10);
1251 dc
.DrawText(wxT("wxLEFT"), r
.x
, r
.y
);
1252 r
.Offset(0, TEXT_HEIGHT
);
1253 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxLEFT
);
1255 r
.Offset(0, r
.height
+ 10);
1256 dc
.DrawText(wxT("wxDOWN"), r
.x
, r
.y
);
1257 r
.Offset(0, TEXT_HEIGHT
);
1258 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxDOWN
);
1260 r
.Offset(0, r
.height
+ 10);
1261 dc
.DrawText(wxT("wxUP"), r
.x
, r
.y
);
1262 r
.Offset(0, TEXT_HEIGHT
);
1263 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxUP
);
1265 wxRect gfr
= wxRect(r
);
1268 r
= wxRect(200, 10, 50, 50);
1269 dc
.DrawText(wxT("Blue inside"), r
.x
, r
.y
);
1270 r
.Offset(0, TEXT_HEIGHT
);
1271 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
);
1273 r
.Offset(0, r
.height
+ 10);
1274 dc
.DrawText(wxT("White inside"), r
.x
, r
.y
);
1275 r
.Offset(0, TEXT_HEIGHT
);
1276 dc
.GradientFillConcentric(r
, *wxWHITE
, *wxBLUE
);
1278 r
.Offset(0, r
.height
+ 10);
1279 dc
.DrawText(wxT("Blue in top left corner"), r
.x
, r
.y
);
1280 r
.Offset(0, TEXT_HEIGHT
);
1281 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(0, 0));
1283 r
.Offset(0, r
.height
+ 10);
1284 dc
.DrawText(wxT("Blue in bottom right corner"), r
.x
, r
.y
);
1285 r
.Offset(0, TEXT_HEIGHT
);
1286 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(r
.width
, r
.height
));
1288 // check that the area filled by the gradient is exactly the interior of
1292 dc
.DrawText("The interior should be filled but", r
.x
, r
.y
);
1294 dc
.DrawText(" the red border should remain visible:", r
.x
, r
.y
);
1305 dc
.SetPen(*wxRED_PEN
);
1306 dc
.DrawRectangle(r
);
1308 dc
.GradientFillLinear(r
, *wxGREEN
, *wxBLACK
, wxNORTH
);
1309 dc
.DrawRectangle(r2
);
1311 dc
.GradientFillLinear(r2
, *wxBLACK
, *wxGREEN
, wxSOUTH
);
1312 dc
.DrawRectangle(r3
);
1314 dc
.GradientFillLinear(r3
, *wxGREEN
, *wxBLACK
, wxEAST
);
1315 dc
.DrawRectangle(r4
);
1317 dc
.GradientFillLinear(r4
, *wxBLACK
, *wxGREEN
, wxWEST
);
1319 #if wxUSE_GRAPHICS_CONTEXT
1322 wxGCDC
&gdc
= (wxGCDC
&)dc
;
1323 wxGraphicsContext
*gc
= gdc
.GetGraphicsContext();
1325 wxGraphicsGradientStops stops
;
1327 gfr
.Offset(0, gfr
.height
+ 10);
1328 dc
.DrawText(wxT("Linear Gradient with Stops"), gfr
.x
, gfr
.y
);
1329 gfr
.Offset(0, TEXT_HEIGHT
);
1331 stops
= wxGraphicsGradientStops(*wxRED
, *wxBLUE
);
1332 stops
.Add(wxColour(255,255,0), 0.33f
);
1333 stops
.Add(*wxGREEN
, 0.67f
);
1335 gc
->SetBrush(gc
->CreateLinearGradientBrush(gfr
.x
, gfr
.y
,
1336 gfr
.x
+ gfr
.width
, gfr
.y
+ gfr
.height
,
1338 pth
= gc
->CreatePath();
1339 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1340 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1341 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1342 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1346 gfr
.Offset(0, gfr
.height
+ 10);
1347 dc
.DrawText(wxT("Radial Gradient with Stops"), gfr
.x
, gfr
.y
);
1348 gfr
.Offset(0, TEXT_HEIGHT
);
1350 gc
->SetBrush(gc
->CreateRadialGradientBrush(gfr
.x
+ gfr
.width
/ 2,
1351 gfr
.y
+ gfr
.height
/ 2,
1352 gfr
.x
+ gfr
.width
/ 2,
1353 gfr
.y
+ gfr
.height
/ 2,
1356 pth
= gc
->CreatePath();
1357 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1358 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1359 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1360 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1364 gfr
.Offset(0, gfr
.height
+ 10);
1365 dc
.DrawText(wxT("Linear Gradient with Stops and Gaps"), gfr
.x
, gfr
.y
);
1366 gfr
.Offset(0, TEXT_HEIGHT
);
1368 stops
= wxGraphicsGradientStops(*wxRED
, *wxBLUE
);
1369 stops
.Add(wxColour(255,255,0), 0.33f
);
1370 stops
.Add(wxTransparentColour
, 0.33f
);
1371 stops
.Add(wxTransparentColour
, 0.67f
);
1372 stops
.Add(*wxGREEN
, 0.67f
);
1374 gc
->SetBrush(gc
->CreateLinearGradientBrush(gfr
.x
, gfr
.y
+ gfr
.height
,
1375 gfr
.x
+ gfr
.width
, gfr
.y
,
1377 pth
= gc
->CreatePath();
1378 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1379 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1380 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1381 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1385 gfr
.Offset(0, gfr
.height
+ 10);
1386 dc
.DrawText(wxT("Radial Gradient with Stops and Gaps"), gfr
.x
, gfr
.y
);
1387 gfr
.Offset(0, TEXT_HEIGHT
);
1389 gc
->SetBrush(gc
->CreateRadialGradientBrush(gfr
.x
+ gfr
.width
/ 2,
1390 gfr
.y
+ gfr
.height
/ 2,
1391 gfr
.x
+ gfr
.width
/ 2,
1392 gfr
.y
+ gfr
.height
/ 2,
1395 pth
= gc
->CreatePath();
1396 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1397 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1398 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1399 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1403 gfr
.Offset(0, gfr
.height
+ 10);
1404 dc
.DrawText(wxT("Gradients with Stops and Transparency"), gfr
.x
, gfr
.y
);
1405 gfr
.Offset(0, TEXT_HEIGHT
);
1407 stops
= wxGraphicsGradientStops(*wxRED
, wxTransparentColour
);
1408 stops
.Add(*wxRED
, 0.33f
);
1409 stops
.Add(wxTransparentColour
, 0.33f
);
1410 stops
.Add(wxTransparentColour
, 0.67f
);
1411 stops
.Add(*wxBLUE
, 0.67f
);
1412 stops
.Add(*wxBLUE
, 1.0f
);
1414 pth
= gc
->CreatePath();
1415 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1416 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1417 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1418 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1421 gc
->SetBrush(gc
->CreateRadialGradientBrush(gfr
.x
+ gfr
.width
/ 2,
1422 gfr
.y
+ gfr
.height
/ 2,
1423 gfr
.x
+ gfr
.width
/ 2,
1424 gfr
.y
+ gfr
.height
/ 2,
1429 stops
= wxGraphicsGradientStops(wxColour(255,0,0, 128), wxColour(0,0,255, 128));
1430 stops
.Add(wxColour(255,255,0,128), 0.33f
);
1431 stops
.Add(wxColour(0,255,0,128), 0.67f
);
1433 gc
->SetBrush(gc
->CreateLinearGradientBrush(gfr
.x
, gfr
.y
,
1434 gfr
.x
+ gfr
.width
, gfr
.y
,
1438 #endif // wxUSE_GRAPHICS_CONTEXT
1441 void MyCanvas::DrawRegions(wxDC
& dc
)
1443 dc
.DrawText(wxT("You should see a red rect partly covered by a cyan one ")
1444 wxT("on the left"), 10, 5);
1445 dc
.DrawText(wxT("and 5 smileys from which 4 are partially clipped on the right"),
1446 10, 5 + dc
.GetCharHeight());
1447 dc
.DrawText(wxT("The second copy should be identical but right part of it ")
1448 wxT("should be offset by 10 pixels."),
1449 10, 5 + 2*dc
.GetCharHeight());
1451 DrawRegionsHelper(dc
, 10, true);
1452 DrawRegionsHelper(dc
, 350, false);
1455 void MyCanvas::DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
)
1459 dc
.DestroyClippingRegion();
1460 dc
.SetBrush( *wxWHITE_BRUSH
);
1461 dc
.SetPen( *wxTRANSPARENT_PEN
);
1462 dc
.DrawRectangle( x
, y
, 310, 310 );
1464 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 270 );
1466 dc
.SetBrush( *wxRED_BRUSH
);
1467 dc
.DrawRectangle( x
, y
, 310, 310 );
1469 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 100 );
1471 dc
.SetBrush( *wxCYAN_BRUSH
);
1472 dc
.DrawRectangle( x
, y
, 310, 310 );
1474 dc
.DestroyClippingRegion();
1476 wxRegion
region(x
+ 110, y
+ 20, 100, 270);
1477 #if !defined(__WXMOTIF__)
1479 region
.Offset(10, 10);
1481 dc
.SetDeviceClippingRegion(region
);
1483 dc
.SetBrush( *wxGREY_BRUSH
);
1484 dc
.DrawRectangle( x
, y
, 310, 310 );
1486 if (m_smile_bmp
.IsOk())
1488 dc
.DrawBitmap( m_smile_bmp
, x
+ 150, y
+ 150, true );
1489 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 10, true );
1490 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 280, true );
1491 dc
.DrawBitmap( m_smile_bmp
, x
+ 100, y
+ 70, true );
1492 dc
.DrawBitmap( m_smile_bmp
, x
+ 200, y
+ 70, true );
1496 void MyCanvas::OnPaint(wxPaintEvent
&WXUNUSED(event
))
1498 wxPaintDC
pdc(this);
1502 void MyCanvas::Draw(wxDC
& pdc
)
1504 #if wxUSE_GRAPHICS_CONTEXT
1506 wxGraphicsRenderer
* const renderer
= wxGraphicsRenderer::
1507 #if TEST_CAIRO_EVERYWHERE
1510 GetDefaultRenderer()
1514 wxGraphicsContext
* context
;
1515 if ( wxPaintDC
*paintdc
= wxDynamicCast(&pdc
, wxPaintDC
) )
1517 context
= renderer
->CreateContext(*paintdc
);
1519 else if ( wxMemoryDC
*memdc
= wxDynamicCast(&pdc
, wxMemoryDC
) )
1521 context
= renderer
->CreateContext(*memdc
);
1523 #if wxUSE_METAFILE && defined(wxMETAFILE_IS_ENH)
1524 else if ( wxMetafileDC
*metadc
= wxDynamicCast(&pdc
, wxMetafileDC
) )
1526 context
= renderer
->CreateContext(*metadc
);
1531 wxFAIL_MSG( "Unknown wxDC kind" );
1535 gdc
.SetGraphicsContext(context
);
1537 wxDC
&dc
= m_useContext
? (wxDC
&) gdc
: (wxDC
&) pdc
;
1544 m_owner
->PrepareDC(dc
);
1546 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
1547 if ( m_owner
->m_backgroundBrush
.IsOk() )
1548 dc
.SetBackground( m_owner
->m_backgroundBrush
);
1549 if ( m_owner
->m_colourForeground
.IsOk() )
1550 dc
.SetTextForeground( m_owner
->m_colourForeground
);
1551 if ( m_owner
->m_colourBackground
.IsOk() )
1552 dc
.SetTextBackground( m_owner
->m_colourBackground
);
1554 if ( m_owner
->m_textureBackground
) {
1555 if ( ! m_owner
->m_backgroundBrush
.IsOk() ) {
1556 dc
.SetBackground(wxBrush(wxColour(0, 128, 0)));
1561 dc
.SetClippingRegion(100, 100, 100, 100);
1565 if ( m_owner
->m_textureBackground
)
1567 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
1568 for ( int i
= 0; i
< 200; i
++ )
1569 dc
.DrawLine(0, i
*10, i
*10, 0);
1574 case File_ShowDefault
:
1578 case File_ShowCircles
:
1582 case File_ShowSplines
:
1586 case File_ShowRegions
:
1594 case File_ShowLines
:
1595 DrawTestLines( 0, 100, 0, dc
);
1596 DrawTestLines( 0, 320, 1, dc
);
1597 DrawTestLines( 0, 540, 2, dc
);
1598 DrawTestLines( 0, 760, 6, dc
);
1601 case File_ShowBrushes
:
1602 DrawTestBrushes(dc
);
1605 case File_ShowPolygons
:
1610 DrawImages(dc
, Draw_Normal
);
1613 case File_ShowMaskStretch
:
1614 DrawImages(dc
, Draw_Stretch
);
1618 DrawWithLogicalOps(dc
);
1621 #if wxUSE_GRAPHICS_CONTEXT
1622 case File_ShowAlpha
:
1625 case File_ShowGraphics
:
1626 DrawGraphics(gdc
.GetGraphicsContext());
1630 case File_ShowGradients
:
1639 void MyCanvas::OnMouseMove(wxMouseEvent
&event
)
1643 wxClientDC
dc(this);
1645 m_owner
->PrepareDC(dc
);
1647 wxPoint pos
= event
.GetPosition();
1648 long x
= dc
.DeviceToLogicalX( pos
.x
);
1649 long y
= dc
.DeviceToLogicalY( pos
.y
);
1651 str
.Printf( wxT("Current mouse position: %d,%d"), (int)x
, (int)y
);
1652 m_owner
->SetStatusText( str
);
1658 event
.GetPosition(&x
,&y
);
1659 CalcUnscrolledPosition( x
, y
, &xx
, &yy
);
1660 m_currentpoint
= wxPoint( xx
, yy
) ;
1661 wxRect
newrect ( m_anchorpoint
, m_currentpoint
) ;
1663 wxClientDC
dc( this ) ;
1666 wxDCOverlay
overlaydc( m_overlay
, &dc
);
1669 dc
.SetPen( *wxGREY_PEN
);
1670 dc
.SetBrush( wxColour( 192,192,192,64 ) );
1672 dc
.SetPen( wxPen( *wxLIGHT_GREY
, 2 ) );
1673 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
1675 dc
.DrawRectangle( newrect
);
1679 #endif // wxUSE_STATUSBAR
1682 void MyCanvas::OnMouseDown(wxMouseEvent
&event
)
1685 event
.GetPosition(&x
,&y
);
1686 CalcUnscrolledPosition( x
, y
, &xx
, &yy
);
1687 m_anchorpoint
= wxPoint( xx
, yy
) ;
1688 m_currentpoint
= m_anchorpoint
;
1689 m_rubberBand
= true ;
1693 void MyCanvas::OnMouseUp(wxMouseEvent
&event
)
1699 wxClientDC
dc( this );
1701 wxDCOverlay
overlaydc( m_overlay
, &dc
);
1705 m_rubberBand
= false;
1707 wxPoint endpoint
= CalcUnscrolledPosition(event
.GetPosition());
1709 // Don't pop up the message box if nothing was actually selected.
1710 if ( endpoint
!= m_anchorpoint
)
1712 wxLogMessage("Selected rectangle from (%d, %d) to (%d, %d)",
1713 m_anchorpoint
.x
, m_anchorpoint
.y
,
1714 endpoint
.x
, endpoint
.y
);
1719 // ----------------------------------------------------------------------------
1721 // ----------------------------------------------------------------------------
1723 // the event tables connect the wxWidgets events with the functions (event
1724 // handlers) which process them. It can be also done at run-time, but for the
1725 // simple menu events like this the static method is much simpler.
1726 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
1727 EVT_MENU (File_Quit
, MyFrame::OnQuit
)
1728 EVT_MENU (File_About
, MyFrame::OnAbout
)
1729 EVT_MENU (File_Clip
, MyFrame::OnClip
)
1730 #if wxUSE_GRAPHICS_CONTEXT
1731 EVT_MENU (File_GraphicContext
, MyFrame::OnGraphicContext
)
1733 EVT_MENU (File_Copy
, MyFrame::OnCopy
)
1734 EVT_MENU (File_Save
, MyFrame::OnSave
)
1736 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame::OnShow
)
1738 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame::OnOption
)
1741 // frame constructor
1742 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
1743 : wxFrame((wxFrame
*)NULL
, wxID_ANY
, title
, pos
, size
,
1744 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
1746 // set the frame icon
1747 SetIcon(wxICON(sample
));
1749 wxMenu
*menuFile
= new wxMenu
;
1750 menuFile
->Append(File_ShowDefault
, wxT("&Default screen\tF1"));
1751 menuFile
->Append(File_ShowText
, wxT("&Text screen\tF2"));
1752 menuFile
->Append(File_ShowLines
, wxT("&Lines screen\tF3"));
1753 menuFile
->Append(File_ShowBrushes
, wxT("&Brushes screen\tF4"));
1754 menuFile
->Append(File_ShowPolygons
, wxT("&Polygons screen\tF5"));
1755 menuFile
->Append(File_ShowMask
, wxT("&Mask screen\tF6"));
1756 menuFile
->Append(File_ShowMaskStretch
, wxT("1/&2 scaled mask\tShift-F6"));
1757 menuFile
->Append(File_ShowOps
, wxT("&Raster operations screen\tF7"));
1758 menuFile
->Append(File_ShowRegions
, wxT("Re&gions screen\tF8"));
1759 menuFile
->Append(File_ShowCircles
, wxT("&Circles screen\tF9"));
1760 #if wxUSE_GRAPHICS_CONTEXT
1761 menuFile
->Append(File_ShowAlpha
, wxT("&Alpha screen\tF10"));
1763 menuFile
->Append(File_ShowSplines
, wxT("Spl&ines screen\tF11"));
1764 menuFile
->Append(File_ShowGradients
, wxT("&Gradients screen\tF12"));
1765 #if wxUSE_GRAPHICS_CONTEXT
1766 menuFile
->Append(File_ShowGraphics
, wxT("&Graphics screen"));
1768 menuFile
->AppendSeparator();
1769 menuFile
->AppendCheckItem(File_Clip
, wxT("&Clip\tCtrl-C"), wxT("Clip/unclip drawing"));
1770 #if wxUSE_GRAPHICS_CONTEXT
1771 menuFile
->AppendCheckItem(File_GraphicContext
, wxT("&Use GraphicContext\tCtrl-Y"), wxT("Use GraphicContext"));
1773 menuFile
->AppendSeparator();
1774 #if wxUSE_METAFILE && defined(wxMETAFILE_IS_ENH)
1775 menuFile
->Append(File_Copy
, wxT("Copy to clipboard"));
1777 menuFile
->Append(File_Save
, wxT("&Save...\tCtrl-S"), wxT("Save drawing to file"));
1778 menuFile
->AppendSeparator();
1779 menuFile
->Append(File_About
, wxT("&About\tCtrl-A"), wxT("Show about dialog"));
1780 menuFile
->AppendSeparator();
1781 menuFile
->Append(File_Quit
, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
1783 wxMenu
*menuMapMode
= new wxMenu
;
1784 menuMapMode
->Append( MapMode_Text
, wxT("&TEXT map mode") );
1785 menuMapMode
->Append( MapMode_Lometric
, wxT("&LOMETRIC map mode") );
1786 menuMapMode
->Append( MapMode_Twips
, wxT("T&WIPS map mode") );
1787 menuMapMode
->Append( MapMode_Points
, wxT("&POINTS map mode") );
1788 menuMapMode
->Append( MapMode_Metric
, wxT("&METRIC map mode") );
1790 wxMenu
*menuUserScale
= new wxMenu
;
1791 menuUserScale
->Append( UserScale_StretchHoriz
, wxT("Stretch &horizontally\tCtrl-H") );
1792 menuUserScale
->Append( UserScale_ShrinkHoriz
, wxT("Shrin&k horizontally\tCtrl-G") );
1793 menuUserScale
->Append( UserScale_StretchVertic
, wxT("Stretch &vertically\tCtrl-V") );
1794 menuUserScale
->Append( UserScale_ShrinkVertic
, wxT("&Shrink vertically\tCtrl-W") );
1795 menuUserScale
->AppendSeparator();
1796 menuUserScale
->Append( UserScale_Restore
, wxT("&Restore to normal\tCtrl-0") );
1798 wxMenu
*menuAxis
= new wxMenu
;
1799 menuAxis
->AppendCheckItem( AxisMirror_Horiz
, wxT("Mirror horizontally\tCtrl-M") );
1800 menuAxis
->AppendCheckItem( AxisMirror_Vertic
, wxT("Mirror vertically\tCtrl-N") );
1802 wxMenu
*menuLogical
= new wxMenu
;
1803 menuLogical
->Append( LogicalOrigin_MoveDown
, wxT("Move &down\tCtrl-D") );
1804 menuLogical
->Append( LogicalOrigin_MoveUp
, wxT("Move &up\tCtrl-U") );
1805 menuLogical
->Append( LogicalOrigin_MoveLeft
, wxT("Move &right\tCtrl-L") );
1806 menuLogical
->Append( LogicalOrigin_MoveRight
, wxT("Move &left\tCtrl-R") );
1807 menuLogical
->AppendSeparator();
1808 menuLogical
->Append( LogicalOrigin_Set
, wxT("Set to (&100, 100)\tShift-Ctrl-1") );
1809 menuLogical
->Append( LogicalOrigin_Restore
, wxT("&Restore to normal\tShift-Ctrl-0") );
1811 wxMenu
*menuColour
= new wxMenu
;
1813 menuColour
->Append( Colour_TextForeground
, wxT("Text &foreground...") );
1814 menuColour
->Append( Colour_TextBackground
, wxT("Text &background...") );
1815 menuColour
->Append( Colour_Background
, wxT("Background &colour...") );
1816 #endif // wxUSE_COLOURDLG
1817 menuColour
->AppendCheckItem( Colour_BackgroundMode
, wxT("&Opaque/transparent\tCtrl-B") );
1818 menuColour
->AppendCheckItem( Colour_TextureBackgound
, wxT("Draw textured back&ground\tCtrl-T") );
1820 // now append the freshly created menu to the menu bar...
1821 wxMenuBar
*menuBar
= new wxMenuBar
;
1822 menuBar
->Append(menuFile
, wxT("&File"));
1823 menuBar
->Append(menuMapMode
, wxT("&Mode"));
1824 menuBar
->Append(menuUserScale
, wxT("&Scale"));
1825 menuBar
->Append(menuAxis
, wxT("&Axis"));
1826 menuBar
->Append(menuLogical
, wxT("&Origin"));
1827 menuBar
->Append(menuColour
, wxT("&Colours"));
1829 // ... and attach this menu bar to the frame
1830 SetMenuBar(menuBar
);
1834 SetStatusText(wxT("Welcome to wxWidgets!"));
1835 #endif // wxUSE_STATUSBAR
1837 m_mapMode
= wxMM_TEXT
;
1840 m_xLogicalOrigin
= 0;
1841 m_yLogicalOrigin
= 0;
1843 m_yAxisReversed
= false;
1844 m_backgroundMode
= wxSOLID
;
1845 m_colourForeground
= *wxBLACK
;
1846 m_colourBackground
= *wxLIGHT_GREY
;
1847 m_textureBackground
= false;
1849 m_canvas
= new MyCanvas( this );
1850 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1855 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1857 // true is to force the frame to close
1861 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1864 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1865 wxT("This sample tests various primitive drawing functions\n")
1866 wxT("(without any attempts to prevent flicker).\n")
1867 wxT("Copyright (c) Robert Roebling 1999")
1870 wxMessageBox(msg
, wxT("About Drawing"), wxOK
| wxICON_INFORMATION
, this);
1873 void MyFrame::OnClip(wxCommandEvent
& event
)
1875 m_canvas
->Clip(event
.IsChecked());
1878 #if wxUSE_GRAPHICS_CONTEXT
1879 void MyFrame::OnGraphicContext(wxCommandEvent
& event
)
1881 m_canvas
->UseGraphicContext(event
.IsChecked());
1885 void MyFrame::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1887 #if wxUSE_METAFILE && defined(wxMETAFILE_IS_ENH)
1892 wxMetafile
*mf
= dc
.Close();
1900 void MyFrame::OnSave(wxCommandEvent
& WXUNUSED(event
))
1902 wxFileDialog
dlg(this, wxT("Save as bitmap"), wxT(""), wxT(""),
1904 wxT("PNG image (*.png)|*.png;*.PNG|")
1906 wxT("Bitmap image (*.bmp)|*.bmp;*.BMP"),
1907 wxFD_SAVE
| wxFD_OVERWRITE_PROMPT
);
1908 if (dlg
.ShowModal() == wxID_OK
)
1910 wxBitmap
bmp(500, 800);
1911 wxMemoryDC
mdc(bmp
);
1912 m_canvas
->Draw(mdc
);
1913 bmp
.ConvertToImage().SaveFile(dlg
.GetPath());
1917 void MyFrame::OnShow(wxCommandEvent
& event
)
1919 m_canvas
->ToShow(event
.GetId());
1922 void MyFrame::OnOption(wxCommandEvent
& event
)
1924 switch (event
.GetId())
1927 m_mapMode
= wxMM_TEXT
;
1929 case MapMode_Lometric
:
1930 m_mapMode
= wxMM_LOMETRIC
;
1933 m_mapMode
= wxMM_TWIPS
;
1935 case MapMode_Points
:
1936 m_mapMode
= wxMM_POINTS
;
1938 case MapMode_Metric
:
1939 m_mapMode
= wxMM_METRIC
;
1942 case LogicalOrigin_MoveDown
:
1943 m_yLogicalOrigin
+= 10;
1945 case LogicalOrigin_MoveUp
:
1946 m_yLogicalOrigin
-= 10;
1948 case LogicalOrigin_MoveLeft
:
1949 m_xLogicalOrigin
+= 10;
1951 case LogicalOrigin_MoveRight
:
1952 m_xLogicalOrigin
-= 10;
1954 case LogicalOrigin_Set
:
1956 m_yLogicalOrigin
= -100;
1958 case LogicalOrigin_Restore
:
1960 m_yLogicalOrigin
= 0;
1963 case UserScale_StretchHoriz
:
1964 m_xUserScale
*= 1.10;
1966 case UserScale_ShrinkHoriz
:
1967 m_xUserScale
/= 1.10;
1969 case UserScale_StretchVertic
:
1970 m_yUserScale
*= 1.10;
1972 case UserScale_ShrinkVertic
:
1973 m_yUserScale
/= 1.10;
1975 case UserScale_Restore
:
1980 case AxisMirror_Vertic
:
1981 m_yAxisReversed
= !m_yAxisReversed
;
1983 case AxisMirror_Horiz
:
1984 m_xAxisReversed
= !m_xAxisReversed
;
1988 case Colour_TextForeground
:
1989 m_colourForeground
= SelectColour();
1991 case Colour_TextBackground
:
1992 m_colourBackground
= SelectColour();
1994 case Colour_Background
:
1996 wxColour col
= SelectColour();
1999 m_backgroundBrush
.SetColour(col
);
2003 #endif // wxUSE_COLOURDLG
2005 case Colour_BackgroundMode
:
2006 m_backgroundMode
= m_backgroundMode
== wxSOLID
? wxTRANSPARENT
2010 case Colour_TextureBackgound
:
2011 m_textureBackground
= ! m_textureBackground
;
2019 m_canvas
->Refresh();
2022 void MyFrame::PrepareDC(wxDC
& dc
)
2024 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
2025 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
2026 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
2027 dc
.SetMapMode( m_mapMode
);
2031 wxColour
MyFrame::SelectColour()
2035 wxColourDialog
dialog(this, &data
);
2037 if ( dialog
.ShowModal() == wxID_OK
)
2039 col
= dialog
.GetColourData().GetColour();
2044 #endif // wxUSE_COLOURDLG