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"
38 #define wxTEST_GRAPHICS 1
41 #include "wx/graphics.h"
42 #if wxUSE_GRAPHICS_CONTEXT == 0
43 #undef wxTEST_GRAPHICS
44 #define wxTEST_GRAPHICS 0
47 #undef wxUSE_GRAPHICS_CONTEXT
48 #define wxUSE_GRAPHICS_CONTEXT 0
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 // the application icon
56 #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__)
57 #include "mondrian.xpm"
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 // what do we show on screen (there are too many shapes to put them all on
65 // screen simultaneously)
79 #if wxUSE_GRAPHICS_CONTEXT
87 // ----------------------------------------------------------------------------
89 // ----------------------------------------------------------------------------
91 static wxBitmap
*gs_bmpNoMask
= NULL
,
92 *gs_bmpWithColMask
= NULL
,
94 *gs_bmpWithMask
= NULL
,
99 // ----------------------------------------------------------------------------
101 // ----------------------------------------------------------------------------
103 // Define a new application type, each program should derive a class from wxApp
104 class MyApp
: public wxApp
107 // override base class virtuals
108 // ----------------------------
110 // this one is called on application startup and is a good place for the app
111 // initialization (doing it here and not in the ctor allows to have an error
112 // return: if OnInit() returns false, the application terminates)
113 virtual bool OnInit();
115 virtual int OnExit() { DeleteBitmaps(); return 0; }
118 void DeleteBitmaps();
125 // Define a new frame type: this is going to be our main frame
126 class MyFrame
: public wxFrame
130 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
132 // event handlers (these functions should _not_ be virtual)
133 void OnQuit(wxCommandEvent
& event
);
134 void OnAbout(wxCommandEvent
& event
);
135 void OnClip(wxCommandEvent
& event
);
136 #if wxUSE_GRAPHICS_CONTEXT
137 void OnGraphicContext(wxCommandEvent
& event
);
139 void OnShow(wxCommandEvent
&event
);
140 void OnOption(wxCommandEvent
&event
);
143 wxColour
SelectColour();
144 #endif // wxUSE_COLOURDLG
145 void PrepareDC(wxDC
& dc
);
147 int m_backgroundMode
;
148 int m_textureBackground
;
152 int m_xLogicalOrigin
;
153 int m_yLogicalOrigin
;
154 bool m_xAxisReversed
,
156 wxColour m_colourForeground
, // these are _text_ colours
158 wxBrush m_backgroundBrush
;
162 // any class wishing to process wxWidgets events must use this macro
163 DECLARE_EVENT_TABLE()
166 // define a scrollable canvas for drawing onto
167 class MyCanvas
: public wxScrolledWindow
170 MyCanvas( MyFrame
*parent
);
172 void OnPaint(wxPaintEvent
&event
);
173 void OnMouseMove(wxMouseEvent
&event
);
175 void ToShow(ScreenToShow show
) { m_show
= show
; Refresh(); }
177 // set or remove the clipping region
178 void Clip(bool clip
) { m_clip
= clip
; Refresh(); }
179 #if wxUSE_GRAPHICS_CONTEXT
180 void UseGraphicContext(bool use
) { m_useContext
= use
; Refresh(); }
190 void DrawTestLines( int x
, int y
, int width
, wxDC
&dc
);
191 void DrawTestPoly(wxDC
& dc
);
192 void DrawTestBrushes(wxDC
& dc
);
193 void DrawText(wxDC
& dc
);
194 void DrawImages(wxDC
& dc
, DrawMode mode
);
195 void DrawWithLogicalOps(wxDC
& dc
);
196 #if wxUSE_GRAPHICS_CONTEXT
197 void DrawAlpha(wxDC
& dc
);
198 void DrawGraphics(wxGraphicsContext
* gc
);
200 void DrawRegions(wxDC
& dc
);
201 void DrawCircles(wxDC
& dc
);
202 void DrawSplines(wxDC
& dc
);
203 void DrawDefault(wxDC
& dc
);
204 void DrawGradients(wxDC
& dc
);
206 void DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
);
212 wxBitmap m_smile_bmp
;
215 #if wxUSE_GRAPHICS_CONTEXT
219 DECLARE_EVENT_TABLE()
222 // ----------------------------------------------------------------------------
224 // ----------------------------------------------------------------------------
226 // IDs for the controls and the menu commands
230 File_Quit
= wxID_EXIT
,
231 File_About
= wxID_ABOUT
,
233 MenuShow_First
= wxID_HIGHEST
,
234 File_ShowDefault
= MenuShow_First
,
240 File_ShowMaskStretch
,
245 #if wxUSE_GRAPHICS_CONTEXT
250 MenuShow_Last
= File_ShowGradients
,
253 #if wxUSE_GRAPHICS_CONTEXT
259 MapMode_Text
= MenuOption_First
,
265 UserScale_StretchHoriz
,
266 UserScale_ShrinkHoriz
,
267 UserScale_StretchVertic
,
268 UserScale_ShrinkVertic
,
274 LogicalOrigin_MoveDown
,
275 LogicalOrigin_MoveUp
,
276 LogicalOrigin_MoveLeft
,
277 LogicalOrigin_MoveRight
,
279 LogicalOrigin_Restore
,
282 Colour_TextForeground
,
283 Colour_TextBackground
,
285 #endif // wxUSE_COLOURDLG
286 Colour_BackgroundMode
,
287 Colour_TextureBackgound
,
289 MenuOption_Last
= Colour_TextureBackgound
292 // ----------------------------------------------------------------------------
293 // event tables and other macros for wxWidgets
294 // ----------------------------------------------------------------------------
297 // Create a new application object: this macro will allow wxWidgets to create
298 // the application object during program execution (it's better than using a
299 // static object for many reasons) and also declares the accessor function
300 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
304 // ============================================================================
306 // ============================================================================
308 // ----------------------------------------------------------------------------
309 // the application class
310 // ----------------------------------------------------------------------------
312 bool MyApp::LoadImages()
314 gs_bmpNoMask
= new wxBitmap
;
315 gs_bmpWithColMask
= new wxBitmap
;
316 gs_bmpMask
= new wxBitmap
;
317 gs_bmpWithMask
= new wxBitmap
;
318 gs_bmp4
= new wxBitmap
;
319 gs_bmp4_mono
= new wxBitmap
;
320 gs_bmp36
= new wxBitmap
;
323 pathList
.Add(_T("."));
324 pathList
.Add(_T(".."));
325 pathList
.Add(_T("../.."));
327 wxString path
= pathList
.FindValidPath(_T("pat4.bmp"));
331 /* 4 colour bitmap */
332 gs_bmp4
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
333 /* turn into mono-bitmap */
334 gs_bmp4_mono
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
335 wxMask
* mask4
= new wxMask(*gs_bmp4_mono
, *wxBLACK
);
336 gs_bmp4_mono
->SetMask(mask4
);
338 path
= pathList
.FindValidPath(_T("pat36.bmp"));
341 gs_bmp36
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
342 wxMask
* mask36
= new wxMask(*gs_bmp36
, *wxBLACK
);
343 gs_bmp36
->SetMask(mask36
);
345 path
= pathList
.FindValidPath(_T("image.bmp"));
348 gs_bmpNoMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
349 gs_bmpWithMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
350 gs_bmpWithColMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
352 path
= pathList
.FindValidPath(_T("mask.bmp"));
355 gs_bmpMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
357 wxMask
*mask
= new wxMask(*gs_bmpMask
, *wxBLACK
);
358 gs_bmpWithMask
->SetMask(mask
);
360 mask
= new wxMask(*gs_bmpWithColMask
, *wxWHITE
);
361 gs_bmpWithColMask
->SetMask(mask
);
366 // `Main program' equivalent: the program execution "starts" here
369 if ( !wxApp::OnInit() )
372 // Create the main application window
373 MyFrame
*frame
= new MyFrame(_T("Drawing sample"),
374 wxPoint(50, 50), wxSize(550, 340));
376 // Show it and tell the application that it's our main window
382 wxLogError(wxT("Can't load one of the bitmap files needed ")
383 wxT("for this sample from the current or parent ")
384 wxT("directory, please copy them there."));
396 void MyApp::DeleteBitmaps()
399 delete gs_bmpWithColMask
;
401 delete gs_bmpWithMask
;
407 gs_bmpWithColMask
= NULL
;
409 gs_bmpWithMask
= NULL
;
415 // ----------------------------------------------------------------------------
417 // ----------------------------------------------------------------------------
419 // the event tables connect the wxWidgets events with the functions (event
420 // handlers) which process them.
421 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
422 EVT_PAINT (MyCanvas::OnPaint
)
423 EVT_MOTION (MyCanvas::OnMouseMove
)
428 MyCanvas::MyCanvas(MyFrame
*parent
)
429 : wxScrolledWindow(parent
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
430 wxHSCROLL
| wxVSCROLL
| wxNO_FULL_REPAINT_ON_RESIZE
)
433 m_show
= Show_Default
;
434 m_smile_bmp
= wxBitmap(smile_xpm
);
435 m_std_icon
= wxArtProvider::GetIcon(wxART_INFORMATION
);
437 #if wxUSE_GRAPHICS_CONTEXT
438 m_useContext
= false;
442 void MyCanvas::DrawTestBrushes(wxDC
& dc
)
444 static const wxCoord WIDTH
= 200;
445 static const wxCoord HEIGHT
= 80;
450 dc
.SetBrush(wxBrush(*wxGREEN
, wxSOLID
));
451 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
452 dc
.DrawText(_T("Solid green"), x
+ 10, y
+ 10);
455 dc
.SetBrush(wxBrush(*wxRED
, wxCROSSDIAG_HATCH
));
456 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
457 dc
.DrawText(_T("Hatched red"), x
+ 10, y
+ 10);
460 dc
.SetBrush(wxBrush(*gs_bmpMask
));
461 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
462 dc
.DrawText(_T("Stipple mono"), x
+ 10, y
+ 10);
465 dc
.SetBrush(wxBrush(*gs_bmpNoMask
));
466 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
467 dc
.DrawText(_T("Stipple colour"), x
+ 10, y
+ 10);
470 void MyCanvas::DrawTestPoly(wxDC
& dc
)
472 wxBrush
brushHatch(*wxRED
, wxFDIAGONAL_HATCH
);
473 dc
.SetBrush(brushHatch
);
476 star
[0] = wxPoint(100, 60);
477 star
[1] = wxPoint(60, 150);
478 star
[2] = wxPoint(160, 100);
479 star
[3] = wxPoint(40, 100);
480 star
[4] = wxPoint(140, 150);
482 dc
.DrawText(_T("You should see two (irregular) stars below, the left one ")
483 _T("hatched"), 10, 10);
484 dc
.DrawText(_T("except for the central region and the right ")
485 _T("one entirely hatched"), 10, 30);
486 dc
.DrawText(_T("The third star only has a hatched outline"), 10, 50);
488 dc
.DrawPolygon(WXSIZEOF(star
), star
, 0, 30);
489 dc
.DrawPolygon(WXSIZEOF(star
), star
, 160, 30, wxWINDING_RULE
);
492 star2
[0] = wxPoint(0, 100);
493 star2
[1] = wxPoint(-59, -81);
494 star2
[2] = wxPoint(95, 31);
495 star2
[3] = wxPoint(-95, 31);
496 star2
[4] = wxPoint(59, -81);
497 star2
[5] = wxPoint(0, 80);
498 star2
[6] = wxPoint(-47, -64);
499 star2
[7] = wxPoint(76, 24);
500 star2
[8] = wxPoint(-76, 24);
501 star2
[9] = wxPoint(47, -64);
502 int count
[2] = {5, 5};
504 dc
.DrawPolyPolygon(WXSIZEOF(count
), count
, star2
, 450, 150);
507 void MyCanvas::DrawTestLines( int x
, int y
, int width
, wxDC
&dc
)
509 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
510 dc
.SetBrush( *wxRED_BRUSH
);
511 dc
.DrawText(wxString::Format(wxT("Testing lines of width %d"), width
), x
+ 10, y
- 10);
512 dc
.DrawRectangle( x
+10, y
+10, 100, 190 );
514 dc
.DrawText(_T("Solid/dot/short dash/long dash/dot dash"), x
+ 150, y
+ 10);
515 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
516 dc
.DrawLine( x
+20, y
+20, 100, y
+20 );
517 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT
) );
518 dc
.DrawLine( x
+20, y
+30, 100, y
+30 );
519 dc
.SetPen( wxPen( wxT("black"), width
, wxSHORT_DASH
) );
520 dc
.DrawLine( x
+20, y
+40, 100, y
+40 );
521 dc
.SetPen( wxPen( wxT("black"), width
, wxLONG_DASH
) );
522 dc
.DrawLine( x
+20, y
+50, 100, y
+50 );
523 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT_DASH
) );
524 dc
.DrawLine( x
+20, y
+60, 100, y
+60 );
526 dc
.DrawText(_T("Misc hatches"), x
+ 150, y
+ 70);
527 dc
.SetPen( wxPen( wxT("black"), width
, wxBDIAGONAL_HATCH
) );
528 dc
.DrawLine( x
+20, y
+70, 100, y
+70 );
529 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSSDIAG_HATCH
) );
530 dc
.DrawLine( x
+20, y
+80, 100, y
+80 );
531 dc
.SetPen( wxPen( wxT("black"), width
, wxFDIAGONAL_HATCH
) );
532 dc
.DrawLine( x
+20, y
+90, 100, y
+90 );
533 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSS_HATCH
) );
534 dc
.DrawLine( x
+20, y
+100, 100, y
+100 );
535 dc
.SetPen( wxPen( wxT("black"), width
, wxHORIZONTAL_HATCH
) );
536 dc
.DrawLine( x
+20, y
+110, 100, y
+110 );
537 dc
.SetPen( wxPen( wxT("black"), width
, wxVERTICAL_HATCH
) );
538 dc
.DrawLine( x
+20, y
+120, 100, y
+120 );
540 dc
.DrawText(_T("User dash"), x
+ 150, y
+ 140);
541 wxPen
ud( wxT("black"), width
, wxUSER_DASH
);
543 dash1
[0] = 8; // Long dash <---------+
544 dash1
[1] = 2; // Short gap |
545 dash1
[2] = 3; // Short dash |
546 dash1
[3] = 2; // Short gap |
547 dash1
[4] = 3; // Short dash |
548 dash1
[5] = 2; // Short gap and repeat +
549 ud
.SetDashes( 6, dash1
);
551 dc
.DrawLine( x
+20, y
+140, 100, y
+140 );
552 dash1
[0] = 5; // Make first dash shorter
553 ud
.SetDashes( 6, dash1
);
555 dc
.DrawLine( x
+20, y
+150, 100, y
+150 );
556 dash1
[2] = 5; // Make second dash longer
557 ud
.SetDashes( 6, dash1
);
559 dc
.DrawLine( x
+20, y
+160, 100, y
+160 );
560 dash1
[4] = 5; // Make third dash longer
561 ud
.SetDashes( 6, dash1
);
563 dc
.DrawLine( x
+20, y
+170, 100, y
+170 );
566 void MyCanvas::DrawDefault(wxDC
& dc
)
569 dc
.DrawCircle(0, 0, 10);
571 #if !defined(wxMAC_USE_CORE_GRAPHICS) || !wxMAC_USE_CORE_GRAPHICS
572 // GetPixel and FloodFill not supported by Mac OS X CoreGraphics
573 // (FloodFill uses Blit from a non-wxMemoryDC)
574 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
575 dc
.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID
));
578 dc
.GetPixel(1,1, &tmpColour
);
579 dc
.FloodFill(1,1, tmpColour
, wxFLOOD_SURFACE
);
582 dc
.DrawCheckMark(5, 80, 15, 15);
583 dc
.DrawCheckMark(25, 80, 30, 30);
584 dc
.DrawCheckMark(60, 80, 60, 60);
586 // this is the test for "blitting bitmap into DC damages selected brush" bug
587 wxCoord rectSize
= m_std_icon
.GetWidth() + 10;
589 dc
.SetPen(*wxTRANSPARENT_PEN
);
590 dc
.SetBrush( *wxGREEN_BRUSH
);
591 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
592 dc
.DrawBitmap(m_std_icon
, x
+ 5, 15, true);
594 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
595 dc
.DrawIcon(m_std_icon
, x
+ 5, 15);
597 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
599 // test for "transparent" bitmap drawing (it intersects with the last
601 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
603 if (m_smile_bmp
.Ok())
604 dc
.DrawBitmap(m_smile_bmp
, x
+ rectSize
- 20, rectSize
- 10, true);
606 dc
.SetBrush( *wxBLACK_BRUSH
);
607 dc
.DrawRectangle( 0, 160, 1000, 300 );
610 wxBitmap
bitmap(20,70);
612 memdc
.SelectObject( bitmap
);
613 memdc
.SetBrush( *wxBLACK_BRUSH
);
614 memdc
.SetPen( *wxWHITE_PEN
);
615 memdc
.DrawRectangle(0,0,20,70);
616 memdc
.DrawLine( 10,0,10,70 );
619 wxPen pen
= *wxRED_PEN
;
621 memdc
.DrawLine( 10, 5,10, 5 );
622 memdc
.DrawLine( 10,10,11,10 );
623 memdc
.DrawLine( 10,15,12,15 );
624 memdc
.DrawLine( 10,20,13,20 );
627 memdc.SetPen(*wxRED_PEN);
628 memdc.DrawLine( 12, 5,12, 5 );
629 memdc.DrawLine( 12,10,13,10 );
630 memdc.DrawLine( 12,15,14,15 );
631 memdc.DrawLine( 12,20,15,20 );
635 memdc
.DrawLine( 10,25,10,25 );
636 memdc
.DrawLine( 10,30, 9,30 );
637 memdc
.DrawLine( 10,35, 8,35 );
638 memdc
.DrawLine( 10,40, 7,40 );
641 dc
.SetPen(*wxWHITE_PEN
);
642 memdc
.SetLogicalFunction( wxINVERT
);
643 memdc
.SetPen( *wxWHITE_PEN
);
644 memdc
.DrawLine( 10,50,10,50 );
645 memdc
.DrawLine( 10,55,11,55 );
646 memdc
.DrawLine( 10,60,12,60 );
647 memdc
.DrawLine( 10,65,13,65 );
649 memdc
.DrawLine( 12,50,12,50 );
650 memdc
.DrawLine( 12,55,13,55 );
651 memdc
.DrawLine( 12,60,14,60 );
652 memdc
.DrawLine( 12,65,15,65 );
654 memdc
.SelectObject( wxNullBitmap
);
655 dc
.DrawBitmap( bitmap
, 10, 170 );
656 wxImage image
= bitmap
.ConvertToImage();
657 image
.Rescale( 60,210 );
658 bitmap
= wxBitmap(image
);
659 dc
.DrawBitmap( bitmap
, 50, 170 );
661 // test the rectangle outline drawing - there should be one pixel between
662 // the rect and the lines
663 dc
.SetPen(*wxWHITE_PEN
);
664 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
665 dc
.DrawRectangle(150, 170, 49, 29);
666 dc
.DrawRectangle(200, 170, 49, 29);
667 dc
.SetPen(*wxWHITE_PEN
);
668 dc
.DrawLine(250, 210, 250, 170);
669 dc
.DrawLine(260, 200, 150, 200);
671 // test the rectangle filled drawing - there should be one pixel between
672 // the rect and the lines
673 dc
.SetPen(*wxTRANSPARENT_PEN
);
674 dc
.SetBrush( *wxWHITE_BRUSH
);
675 dc
.DrawRectangle(300, 170, 49, 29);
676 dc
.DrawRectangle(350, 170, 49, 29);
677 dc
.SetPen(*wxWHITE_PEN
);
678 dc
.DrawLine(400, 170, 400, 210);
679 dc
.DrawLine(300, 200, 410, 200);
681 // a few more tests of this kind
682 dc
.SetPen(*wxRED_PEN
);
683 dc
.SetBrush( *wxWHITE_BRUSH
);
684 dc
.DrawRectangle(300, 220, 1, 1);
685 dc
.DrawRectangle(310, 220, 2, 2);
686 dc
.DrawRectangle(320, 220, 3, 3);
687 dc
.DrawRectangle(330, 220, 4, 4);
689 dc
.SetPen(*wxTRANSPARENT_PEN
);
690 dc
.SetBrush( *wxWHITE_BRUSH
);
691 dc
.DrawRectangle(300, 230, 1, 1);
692 dc
.DrawRectangle(310, 230, 2, 2);
693 dc
.DrawRectangle(320, 230, 3, 3);
694 dc
.DrawRectangle(330, 230, 4, 4);
696 // and now for filled rect with outline
697 dc
.SetPen(*wxRED_PEN
);
698 dc
.SetBrush( *wxWHITE_BRUSH
);
699 dc
.DrawRectangle(500, 170, 49, 29);
700 dc
.DrawRectangle(550, 170, 49, 29);
701 dc
.SetPen(*wxWHITE_PEN
);
702 dc
.DrawLine(600, 170, 600, 210);
703 dc
.DrawLine(500, 200, 610, 200);
705 // test the rectangle outline drawing - there should be one pixel between
706 // the rect and the lines
707 dc
.SetPen(*wxWHITE_PEN
);
708 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
709 dc
.DrawRoundedRectangle(150, 270, 49, 29, 6);
710 dc
.DrawRoundedRectangle(200, 270, 49, 29, 6);
711 dc
.SetPen(*wxWHITE_PEN
);
712 dc
.DrawLine(250, 270, 250, 310);
713 dc
.DrawLine(150, 300, 260, 300);
715 // test the rectangle filled drawing - there should be one pixel between
716 // the rect and the lines
717 dc
.SetPen(*wxTRANSPARENT_PEN
);
718 dc
.SetBrush( *wxWHITE_BRUSH
);
719 dc
.DrawRoundedRectangle(300, 270, 49, 29, 6);
720 dc
.DrawRoundedRectangle(350, 270, 49, 29, 6);
721 dc
.SetPen(*wxWHITE_PEN
);
722 dc
.DrawLine(400, 270, 400, 310);
723 dc
.DrawLine(300, 300, 410, 300);
725 // Added by JACS to demonstrate bizarre behaviour.
726 // With a size of 70, we get a missing red RHS,
727 // and the height is too small, so we get yellow
728 // showing. With a size of 40, it draws as expected:
729 // it just shows a white rectangle with red outline.
731 int totalHeight
= 70;
732 wxBitmap
bitmap2(totalWidth
, totalHeight
);
735 memdc2
.SelectObject(bitmap2
);
737 wxColour
clr(255, 255, 0);
738 wxBrush
yellowBrush(clr
, wxSOLID
);
739 memdc2
.SetBackground(yellowBrush
);
742 wxPen
yellowPen(clr
, 1, wxSOLID
);
744 // Now draw a white rectangle with red outline. It should
745 // entirely eclipse the yellow background.
746 memdc2
.SetPen(*wxRED_PEN
);
747 memdc2
.SetBrush(*wxWHITE_BRUSH
);
749 memdc2
.DrawRectangle(0, 0, totalWidth
, totalHeight
);
751 memdc2
.SetPen(wxNullPen
);
752 memdc2
.SetBrush(wxNullBrush
);
753 memdc2
.SelectObject(wxNullBitmap
);
755 dc
.DrawBitmap(bitmap2
, 500, 270);
757 // Repeat, but draw directly on dc
758 // Draw a yellow rectangle filling the bitmap
760 x
= 600; int y
= 270;
761 dc
.SetPen(yellowPen
);
762 dc
.SetBrush(yellowBrush
);
763 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
765 // Now draw a white rectangle with red outline. It should
766 // entirely eclipse the yellow background.
767 dc
.SetPen(*wxRED_PEN
);
768 dc
.SetBrush(*wxWHITE_BRUSH
);
770 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
773 void MyCanvas::DrawText(wxDC
& dc
)
775 // set underlined font for testing
776 dc
.SetFont( wxFont(12, wxMODERN
, wxNORMAL
, wxNORMAL
, true) );
777 dc
.DrawText( _T("This is text"), 110, 10 );
778 dc
.DrawRotatedText( _T("That is text"), 20, 10, -45 );
780 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
781 // under Win9x (it is not TrueType)
782 dc
.SetFont( *wxSWISS_FONT
);
785 dc
.SetBackgroundMode(wxTRANSPARENT
);
787 for ( int n
= -180; n
< 180; n
+= 30 )
789 text
.Printf(wxT(" %d rotated text"), n
);
790 dc
.DrawRotatedText(text
, 400, 400, n
);
793 dc
.SetFont( wxFont( 18, wxSWISS
, wxNORMAL
, wxNORMAL
) );
795 dc
.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
800 dc
.GetTextExtent( _T("This is Swiss 18pt text."), &length
, &height
, &descent
);
801 text
.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length
, height
, descent
);
802 dc
.DrawText( text
, 110, 80 );
804 text
.Printf( wxT("CharHeight() returns: %d"), dc
.GetCharHeight() );
805 dc
.DrawText( text
, 110, 120 );
807 dc
.DrawRectangle( 100, 40, 4, height
);
809 // test the logical function effect
811 dc
.SetLogicalFunction(wxINVERT
);
812 dc
.DrawText( _T("There should be no text below"), 110, 150 );
813 dc
.DrawRectangle( 110, y
, 100, height
);
815 // twice drawn inverted should result in invisible
817 dc
.DrawText( _T("Invisible text"), 110, y
);
818 dc
.DrawRectangle( 110, y
, 100, height
);
819 dc
.DrawText( _T("Invisible text"), 110, y
);
820 dc
.DrawRectangle( 110, y
, 100, height
);
821 dc
.SetLogicalFunction(wxCOPY
);
824 dc
.DrawRectangle( 110, y
, 100, height
);
825 dc
.DrawText( _T("Visible text"), 110, y
);
832 } rasterOperations
[] =
834 { wxT("wxAND"), wxAND
},
835 { wxT("wxAND_INVERT"), wxAND_INVERT
},
836 { wxT("wxAND_REVERSE"), wxAND_REVERSE
},
837 { wxT("wxCLEAR"), wxCLEAR
},
838 { wxT("wxCOPY"), wxCOPY
},
839 { wxT("wxEQUIV"), wxEQUIV
},
840 { wxT("wxINVERT"), wxINVERT
},
841 { wxT("wxNAND"), wxNAND
},
842 { wxT("wxNO_OP"), wxNO_OP
},
843 { wxT("wxOR"), wxOR
},
844 { wxT("wxOR_INVERT"), wxOR_INVERT
},
845 { wxT("wxOR_REVERSE"), wxOR_REVERSE
},
846 { wxT("wxSET"), wxSET
},
847 { wxT("wxSRC_INVERT"), wxSRC_INVERT
},
848 { wxT("wxXOR"), wxXOR
},
851 void MyCanvas::DrawImages(wxDC
& dc
, DrawMode mode
)
853 dc
.DrawText(_T("original image"), 0, 0);
854 dc
.DrawBitmap(*gs_bmpNoMask
, 0, 20, 0);
855 dc
.DrawText(_T("with colour mask"), 0, 100);
856 dc
.DrawBitmap(*gs_bmpWithColMask
, 0, 120, true);
857 dc
.DrawText(_T("the mask image"), 0, 200);
858 dc
.DrawBitmap(*gs_bmpMask
, 0, 220, 0);
859 dc
.DrawText(_T("masked image"), 0, 300);
860 dc
.DrawBitmap(*gs_bmpWithMask
, 0, 320, true);
862 int cx
= gs_bmpWithColMask
->GetWidth(),
863 cy
= gs_bmpWithColMask
->GetHeight();
866 for ( size_t n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
868 wxCoord x
= 120 + 150*(n%4
),
871 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
872 memDC
.SelectObject(*gs_bmpWithColMask
);
873 if ( mode
== Draw_Stretch
)
875 dc
.StretchBlit(x
, y
, cx
, cy
, &memDC
, 0, 0, cx
/2, cy
/2,
876 rasterOperations
[n
].rop
, true);
880 dc
.Blit(x
, y
, cx
, cy
, &memDC
, 0, 0, rasterOperations
[n
].rop
, true);
885 void MyCanvas::DrawWithLogicalOps(wxDC
& dc
)
887 static const wxCoord w
= 60;
888 static const wxCoord h
= 60;
890 // reuse the text colour here
891 dc
.SetPen(wxPen(m_owner
->m_colourForeground
, 1, wxSOLID
));
892 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
895 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
897 wxCoord x
= 20 + 150*(n%4
),
900 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
901 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
902 dc
.DrawRectangle(x
, y
, w
, h
);
903 dc
.DrawLine(x
, y
, x
+ w
, y
+ h
);
904 dc
.DrawLine(x
+ w
, y
, x
, y
+ h
);
907 // now some filled rectangles
908 dc
.SetBrush(wxBrush(m_owner
->m_colourForeground
, wxSOLID
));
910 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
912 wxCoord x
= 20 + 150*(n%4
),
915 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
916 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
917 dc
.DrawRectangle(x
, y
, w
, h
);
921 #if wxUSE_GRAPHICS_CONTEXT
923 void MyCanvas::DrawAlpha(wxDC
& no_dc
)
925 void MyCanvas::DrawAlpha(wxDC
& dc
)
933 wxDouble margin
= 20 ;
934 wxDouble width
= 180 ;
935 wxDouble radius
= 30 ;
937 dc
.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID
));
938 dc
.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID
));
940 wxRect
r(margin
,margin
+width
*0.66,width
,width
) ;
942 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
944 dc
.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID
));
945 dc
.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID
));
947 r
.Offset( width
* 0.8 , - width
* 0.66 ) ;
949 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
951 dc
.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID
));
952 dc
.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID
));
954 r
.Offset( width
* 0.8 , width
*0.5 ) ;
956 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
958 dc
.SetPen( *wxTRANSPARENT_PEN
) ;
959 dc
.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
960 dc
.DrawRoundedRectangle( 0 , margin
+ width
/ 2 , width
* 3 , 100 , radius
) ;
962 dc
.SetTextForeground( wxColour(255,255,0,128) );
963 dc
.SetFont( wxFont( 40, wxFONTFAMILY_SWISS
, wxFONTSTYLE_ITALIC
, wxFONTWEIGHT_NORMAL
) );
964 dc
.DrawText( wxT("Hello!"), 120, 80 );
969 #if wxUSE_GRAPHICS_CONTEXT
971 const int BASE
= 80.0;
972 const int BASE2
= BASE
/2;
973 const int BASE4
= BASE
/4;
975 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
978 // modeled along Robin Dunn's GraphicsContext.py sample
980 void MyCanvas::DrawGraphics(wxGraphicsContext
* gc
)
982 wxFont font
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
983 gc
->SetFont(font
,*wxBLACK
);
985 // make a path that contains a circle and some lines, centered at 0,0
986 wxGraphicsPath path
= gc
->CreatePath() ;
987 path
.AddCircle( 0, 0, BASE2
);
988 path
.MoveToPoint(0, -BASE2
);
989 path
.AddLineToPoint(0, BASE2
);
990 path
.MoveToPoint(-BASE2
, 0);
991 path
.AddLineToPoint(BASE2
, 0);
993 path
.AddRectangle(-BASE4
, -BASE4
/2, BASE2
, BASE4
);
995 // Now use that path to demonstrate various capbilites of the grpahics context
996 gc
->PushState(); // save current translation/scale/other state
997 gc
->Translate(60, 75); // reposition the context origin
999 gc
->SetPen(wxPen("navy", 1));
1000 gc
->SetBrush(wxBrush("pink"));
1002 for( int i
= 0 ; i
< 3 ; ++i
)
1008 label
= "StrokePath";
1018 gc
->GetTextExtent(label
, &w
, &h
, NULL
, NULL
);
1019 gc
->DrawText(label
, -w
/2, -BASE2
-h
-4);
1023 gc
->StrokePath(path
);
1032 gc
->Translate(2*BASE
, 0);
1035 gc
->PopState(); // restore saved state
1036 gc
->PushState(); // save it again
1037 gc
->Translate(60, 200); // offset to the lower part of the window
1039 gc
->DrawText("Scale", 0, -BASE2
);
1040 gc
->Translate(0, 20);
1042 gc
->SetBrush(wxBrush(wxColour(178, 34, 34, 128)));// 128 == half transparent
1043 for( int i
= 0 ; i
< 8 ; ++i
)
1045 gc
->Scale(1.08, 1.08); // increase scale by 8%
1050 gc
->PopState(); // restore saved state
1051 gc
->PushState(); // save it again
1052 gc
->Translate(400, 200);
1054 gc
->DrawText("Rotate", 0, -BASE2
);
1056 // Move the origin over to the next location
1057 gc
->Translate(0, 75);
1059 // draw our path again, rotating it about the central point,
1060 // and changing colors as we go
1061 for ( int angle
= 0 ; angle
< 360 ; angle
+= 30 )
1063 gc
->PushState(); // save this new current state so we can
1064 // pop back to it at the end of the loop
1065 wxImage::RGBValue val
= wxImage::HSVtoRGB(wxImage::HSVValue(float(angle
)/360, 1, 1));
1066 gc
->SetBrush(wxBrush(wxColour(val
.red
, val
.green
, val
.blue
, 64)));
1067 gc
->SetPen(wxPen(wxColour(val
.red
, val
.green
, val
.blue
, 128)));
1069 // use translate to artfully reposition each drawn path
1070 gc
->Translate(1.5 * BASE2
* cos(DegToRad(angle
)),
1071 1.5 * BASE2
* sin(DegToRad(angle
)));
1073 // use Rotate to rotate the path
1074 gc
->Rotate(DegToRad(angle
));
1084 void MyCanvas::DrawCircles(wxDC
& dc
)
1090 dc
.SetPen( *wxRED_PEN
);
1091 dc
.SetBrush( *wxGREEN_BRUSH
);
1093 dc
.DrawText(_T("Some circles"), 0, y
);
1094 dc
.DrawCircle(x
, y
, r
);
1095 dc
.DrawCircle(x
+ 2*r
, y
, r
);
1096 dc
.DrawCircle(x
+ 4*r
, y
, r
);
1099 dc
.DrawText(_T("And ellipses"), 0, y
);
1100 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
1101 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
1102 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
1105 dc
.DrawText(_T("And arcs"), 0, y
);
1106 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
1107 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
1108 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
1111 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
1112 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
1113 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
1114 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
1116 // same as above, just transparent brush
1118 dc
.SetPen( *wxRED_PEN
);
1119 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
1122 dc
.DrawText(_T("Some circles"), 0, y
);
1123 dc
.DrawCircle(x
, y
, r
);
1124 dc
.DrawCircle(x
+ 2*r
, y
, r
);
1125 dc
.DrawCircle(x
+ 4*r
, y
, r
);
1128 dc
.DrawText(_T("And ellipses"), 0, y
);
1129 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
1130 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
1131 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
1134 dc
.DrawText(_T("And arcs"), 0, y
);
1135 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
1136 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
1137 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
1140 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
1141 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
1142 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
1143 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
1147 void MyCanvas::DrawSplines(wxDC
& dc
)
1150 dc
.DrawText(_T("Some splines"), 10, 5);
1152 // values are hardcoded rather than randomly generated
1153 // so the output can be compared between native
1154 // implementations on platforms with different random
1158 const wxPoint
center( R
+ 20, R
+ 20 );
1159 const int angles
[7] = { 0, 10, 33, 77, 13, 145, 90 };
1160 const int radii
[5] = { 100 , 59, 85, 33, 90 };
1164 // background spline calculation
1165 unsigned int radius_pos
= 0;
1166 unsigned int angle_pos
= 0;
1168 for ( int i
= 0; i
< n
; i
++ )
1170 angle
+= angles
[ angle_pos
];
1171 int r
= R
* radii
[ radius_pos
] / 100;
1172 pts
[ i
].x
= center
.x
+ (wxCoord
)( r
* cos( M_PI
* angle
/ 180.0) );
1173 pts
[ i
].y
= center
.y
+ (wxCoord
)( r
* sin( M_PI
* angle
/ 180.0) );
1176 if ( angle_pos
>= WXSIZEOF(angles
) ) angle_pos
= 0;
1179 if ( radius_pos
>= WXSIZEOF(radii
) ) radius_pos
= 0;
1182 // background spline drawing
1183 dc
.SetPen(*wxRED_PEN
);
1184 dc
.DrawSpline(WXSIZEOF(pts
), pts
);
1186 // less detailed spline calculation
1187 wxPoint letters
[4][5];
1189 letters
[0][0] = wxPoint( 0,1); // O O
1190 letters
[0][1] = wxPoint( 1,3); // * *
1191 letters
[0][2] = wxPoint( 2,2); // * O *
1192 letters
[0][3] = wxPoint( 3,3); // * * * *
1193 letters
[0][4] = wxPoint( 4,1); // O O
1195 letters
[1][0] = wxPoint( 5,1); // O*O
1196 letters
[1][1] = wxPoint( 6,1); // *
1197 letters
[1][2] = wxPoint( 7,2); // O
1198 letters
[1][3] = wxPoint( 8,3); // *
1199 letters
[1][4] = wxPoint( 9,3); // O*O
1201 letters
[2][0] = wxPoint( 5,3); // O*O
1202 letters
[2][1] = wxPoint( 6,3); // *
1203 letters
[2][2] = wxPoint( 7,2); // O
1204 letters
[2][3] = wxPoint( 8,1); // *
1205 letters
[2][4] = wxPoint( 9,1); // O*O
1207 letters
[3][0] = wxPoint(10,0); // O O
1208 letters
[3][1] = wxPoint(11,3); // * *
1209 letters
[3][2] = wxPoint(12,1); // * O *
1210 letters
[3][3] = wxPoint(13,3); // * * * *
1211 letters
[3][4] = wxPoint(14,0); // O O
1213 const int dx
= 2 * R
/ letters
[3][4].x
;
1214 const int h
[4] = { -R
/2, 0, R
/4, R
/2 };
1216 for ( int m
= 0; m
< 4; m
++ )
1218 for ( int n
= 0; n
< 5; n
++ )
1220 letters
[m
][n
].x
= center
.x
- R
+ letters
[m
][n
].x
* dx
;
1221 letters
[m
][n
].y
= center
.y
+ h
[ letters
[m
][n
].y
];
1224 dc
.SetPen( wxPen( wxT("blue"), 1, wxDOT
) );
1225 dc
.DrawLines(5, letters
[m
]);
1226 dc
.SetPen( wxPen( wxT("black"), 4, wxSOLID
) );
1227 dc
.DrawSpline(5, letters
[m
]);
1231 dc
.DrawText(_T("Splines not supported."), 10, 5);
1235 void MyCanvas::DrawGradients(wxDC
& dc
)
1237 static const int TEXT_HEIGHT
= 15;
1240 wxRect
r(10, 10, 50, 50);
1241 dc
.DrawText(_T("wxRIGHT"), r
.x
, r
.y
);
1242 r
.Offset(0, TEXT_HEIGHT
);
1243 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxRIGHT
);
1245 r
.Offset(0, r
.height
+ 10);
1246 dc
.DrawText(_T("wxLEFT"), r
.x
, r
.y
);
1247 r
.Offset(0, TEXT_HEIGHT
);
1248 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxLEFT
);
1250 r
.Offset(0, r
.height
+ 10);
1251 dc
.DrawText(_T("wxDOWN"), r
.x
, r
.y
);
1252 r
.Offset(0, TEXT_HEIGHT
);
1253 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxDOWN
);
1255 r
.Offset(0, r
.height
+ 10);
1256 dc
.DrawText(_T("wxUP"), r
.x
, r
.y
);
1257 r
.Offset(0, TEXT_HEIGHT
);
1258 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxUP
);
1262 r
= wxRect(200, 10, 50, 50);
1263 dc
.DrawText(_T("Blue inside"), r
.x
, r
.y
);
1264 r
.Offset(0, TEXT_HEIGHT
);
1265 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
);
1267 r
.Offset(0, r
.height
+ 10);
1268 dc
.DrawText(_T("White inside"), r
.x
, r
.y
);
1269 r
.Offset(0, TEXT_HEIGHT
);
1270 dc
.GradientFillConcentric(r
, *wxWHITE
, *wxBLUE
);
1272 r
.Offset(0, r
.height
+ 10);
1273 dc
.DrawText(_T("Blue in top left corner"), r
.x
, r
.y
);
1274 r
.Offset(0, TEXT_HEIGHT
);
1275 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(0, 0));
1277 r
.Offset(0, r
.height
+ 10);
1278 dc
.DrawText(_T("Blue in bottom right corner"), r
.x
, r
.y
);
1279 r
.Offset(0, TEXT_HEIGHT
);
1280 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(r
.width
, r
.height
));
1282 // check that the area filled by the gradient is exactly the interior of
1286 dc
.DrawText("The interior should be filled but", r
.x
, r
.y
);
1288 dc
.DrawText(" the red border should remain visible:", r
.x
, r
.y
);
1299 dc
.SetPen(wxPen(wxColour(255, 0, 0)));
1300 dc
.DrawRectangle(r
);
1302 dc
.GradientFillLinear(r
, wxColour(0,255,0), wxColour(0,0,0), wxNORTH
);
1303 dc
.DrawRectangle(r2
);
1305 dc
.GradientFillLinear(r2
, wxColour(0,0,0), wxColour(0,255,0), wxSOUTH
);
1306 dc
.DrawRectangle(r3
);
1308 dc
.GradientFillLinear(r3
, wxColour(0,255,0), wxColour(0,0,0), wxEAST
);
1309 dc
.DrawRectangle(r4
);
1311 dc
.GradientFillLinear(r4
, wxColour(0,0,0), wxColour(0,255,0), wxWEST
);
1314 void MyCanvas::DrawRegions(wxDC
& dc
)
1316 dc
.DrawText(_T("You should see a red rect partly covered by a cyan one ")
1317 _T("on the left"), 10, 5);
1318 dc
.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
1319 10, 5 + dc
.GetCharHeight());
1320 dc
.DrawText(_T("The second copy should be identical but right part of it ")
1321 _T("should be offset by 10 pixels."),
1322 10, 5 + 2*dc
.GetCharHeight());
1324 DrawRegionsHelper(dc
, 10, true);
1325 DrawRegionsHelper(dc
, 350, false);
1328 void MyCanvas::DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
)
1332 dc
.DestroyClippingRegion();
1333 dc
.SetBrush( *wxWHITE_BRUSH
);
1334 dc
.SetPen( *wxTRANSPARENT_PEN
);
1335 dc
.DrawRectangle( x
, y
, 310, 310 );
1337 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 270 );
1339 dc
.SetBrush( *wxRED_BRUSH
);
1340 dc
.DrawRectangle( x
, y
, 310, 310 );
1342 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 100 );
1344 dc
.SetBrush( *wxCYAN_BRUSH
);
1345 dc
.DrawRectangle( x
, y
, 310, 310 );
1347 dc
.DestroyClippingRegion();
1349 wxRegion
region(x
+ 110, y
+ 20, 100, 270);
1350 #if !defined(__WXMOTIF__) && !defined(__WXMAC__)
1352 region
.Offset(10, 10);
1354 dc
.SetClippingRegion(region
);
1356 dc
.SetBrush( *wxGREY_BRUSH
);
1357 dc
.DrawRectangle( x
, y
, 310, 310 );
1359 if (m_smile_bmp
.Ok())
1361 dc
.DrawBitmap( m_smile_bmp
, x
+ 150, y
+ 150, true );
1362 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 10, true );
1363 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 280, true );
1364 dc
.DrawBitmap( m_smile_bmp
, x
+ 100, y
+ 70, true );
1365 dc
.DrawBitmap( m_smile_bmp
, x
+ 200, y
+ 70, true );
1369 void MyCanvas::OnPaint(wxPaintEvent
&WXUNUSED(event
))
1371 wxPaintDC
pdc(this);
1373 #if wxUSE_GRAPHICS_CONTEXT
1375 wxDC
&dc
= m_useContext
? (wxDC
&) gdc
: (wxDC
&) pdc
;
1382 m_owner
->PrepareDC(dc
);
1384 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
1385 if ( m_owner
->m_backgroundBrush
.Ok() )
1386 dc
.SetBackground( m_owner
->m_backgroundBrush
);
1387 if ( m_owner
->m_colourForeground
.Ok() )
1388 dc
.SetTextForeground( m_owner
->m_colourForeground
);
1389 if ( m_owner
->m_colourBackground
.Ok() )
1390 dc
.SetTextBackground( m_owner
->m_colourBackground
);
1392 if ( m_owner
->m_textureBackground
) {
1393 if ( ! m_owner
->m_backgroundBrush
.Ok() ) {
1394 wxColour
clr(0,128,0);
1395 wxBrush
b(clr
, wxSOLID
);
1396 dc
.SetBackground(b
);
1401 dc
.SetClippingRegion(100, 100, 100, 100);
1405 if ( m_owner
->m_textureBackground
)
1407 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
1408 for ( int i
= 0; i
< 200; i
++ )
1409 dc
.DrawLine(0, i
*10, i
*10, 0);
1435 DrawTestLines( 0, 100, 0, dc
);
1436 DrawTestLines( 0, 320, 1, dc
);
1437 DrawTestLines( 0, 540, 2, dc
);
1438 DrawTestLines( 0, 760, 6, dc
);
1442 DrawTestBrushes(dc
);
1450 DrawImages(dc
, Draw_Normal
);
1453 case Show_Mask_Stretch
:
1454 DrawImages(dc
, Draw_Stretch
);
1458 DrawWithLogicalOps(dc
);
1461 #if wxUSE_GRAPHICS_CONTEXT
1466 DrawGraphics(gdc
.GetGraphicsContext());
1479 void MyCanvas::OnMouseMove(wxMouseEvent
&event
)
1482 wxClientDC
dc(this);
1484 m_owner
->PrepareDC(dc
);
1486 wxPoint pos
= event
.GetPosition();
1487 long x
= dc
.DeviceToLogicalX( pos
.x
);
1488 long y
= dc
.DeviceToLogicalY( pos
.y
);
1490 str
.Printf( wxT("Current mouse position: %d,%d"), (int)x
, (int)y
);
1491 m_owner
->SetStatusText( str
);
1494 #endif // wxUSE_STATUSBAR
1497 // ----------------------------------------------------------------------------
1499 // ----------------------------------------------------------------------------
1501 // the event tables connect the wxWidgets events with the functions (event
1502 // handlers) which process them. It can be also done at run-time, but for the
1503 // simple menu events like this the static method is much simpler.
1504 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
1505 EVT_MENU (File_Quit
, MyFrame::OnQuit
)
1506 EVT_MENU (File_About
, MyFrame::OnAbout
)
1507 EVT_MENU (File_Clip
, MyFrame::OnClip
)
1508 #if wxUSE_GRAPHICS_CONTEXT
1509 EVT_MENU (File_GraphicContext
, MyFrame::OnGraphicContext
)
1512 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame::OnShow
)
1514 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame::OnOption
)
1517 // frame constructor
1518 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
1519 : wxFrame((wxFrame
*)NULL
, wxID_ANY
, title
, pos
, size
,
1520 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
1522 // set the frame icon
1523 SetIcon(wxICON(mondrian
));
1525 wxMenu
*menuFile
= new wxMenu
;
1526 menuFile
->Append(File_ShowDefault
, _T("&Default screen\tF1"));
1527 menuFile
->Append(File_ShowText
, _T("&Text screen\tF2"));
1528 menuFile
->Append(File_ShowLines
, _T("&Lines screen\tF3"));
1529 menuFile
->Append(File_ShowBrushes
, _T("&Brushes screen\tF4"));
1530 menuFile
->Append(File_ShowPolygons
, _T("&Polygons screen\tF5"));
1531 menuFile
->Append(File_ShowMask
, _T("&Mask screen\tF6"));
1532 menuFile
->Append(File_ShowMaskStretch
, _T("1/&2 scaled mask\tShift-F6"));
1533 menuFile
->Append(File_ShowOps
, _T("&ROP screen\tF7"));
1534 menuFile
->Append(File_ShowRegions
, _T("Re&gions screen\tF8"));
1535 menuFile
->Append(File_ShowCircles
, _T("&Circles screen\tF9"));
1536 #if wxUSE_GRAPHICS_CONTEXT
1537 menuFile
->Append(File_ShowAlpha
, _T("&Alpha screen\tF10"));
1539 menuFile
->Append(File_ShowSplines
, _T("&Splines screen\tF11"));
1540 menuFile
->Append(File_ShowGradients
, _T("&Gradients screen\tF12"));
1541 #if wxUSE_GRAPHICS_CONTEXT
1542 menuFile
->Append(File_ShowGraphics
, _T("&Graphics screen\tF13"));
1544 menuFile
->AppendSeparator();
1545 menuFile
->AppendCheckItem(File_Clip
, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
1546 #if wxUSE_GRAPHICS_CONTEXT
1547 menuFile
->AppendCheckItem(File_GraphicContext
, _T("&Use GraphicContext\tCtrl-Y"), _T("Use GraphicContext"));
1549 menuFile
->AppendSeparator();
1550 menuFile
->Append(File_About
, _T("&About...\tCtrl-A"), _T("Show about dialog"));
1551 menuFile
->AppendSeparator();
1552 menuFile
->Append(File_Quit
, _T("E&xit\tAlt-X"), _T("Quit this program"));
1554 wxMenu
*menuMapMode
= new wxMenu
;
1555 menuMapMode
->Append( MapMode_Text
, _T("&TEXT map mode") );
1556 menuMapMode
->Append( MapMode_Lometric
, _T("&LOMETRIC map mode") );
1557 menuMapMode
->Append( MapMode_Twips
, _T("T&WIPS map mode") );
1558 menuMapMode
->Append( MapMode_Points
, _T("&POINTS map mode") );
1559 menuMapMode
->Append( MapMode_Metric
, _T("&METRIC map mode") );
1561 wxMenu
*menuUserScale
= new wxMenu
;
1562 menuUserScale
->Append( UserScale_StretchHoriz
, _T("Stretch &horizontally\tCtrl-H") );
1563 menuUserScale
->Append( UserScale_ShrinkHoriz
, _T("Shrin&k horizontally\tCtrl-G") );
1564 menuUserScale
->Append( UserScale_StretchVertic
, _T("Stretch &vertically\tCtrl-V") );
1565 menuUserScale
->Append( UserScale_ShrinkVertic
, _T("&Shrink vertically\tCtrl-W") );
1566 menuUserScale
->AppendSeparator();
1567 menuUserScale
->Append( UserScale_Restore
, _T("&Restore to normal\tCtrl-0") );
1569 wxMenu
*menuAxis
= new wxMenu
;
1570 menuAxis
->AppendCheckItem( AxisMirror_Horiz
, _T("Mirror horizontally\tCtrl-M") );
1571 menuAxis
->AppendCheckItem( AxisMirror_Vertic
, _T("Mirror vertically\tCtrl-N") );
1573 wxMenu
*menuLogical
= new wxMenu
;
1574 menuLogical
->Append( LogicalOrigin_MoveDown
, _T("Move &down\tCtrl-D") );
1575 menuLogical
->Append( LogicalOrigin_MoveUp
, _T("Move &up\tCtrl-U") );
1576 menuLogical
->Append( LogicalOrigin_MoveLeft
, _T("Move &right\tCtrl-L") );
1577 menuLogical
->Append( LogicalOrigin_MoveRight
, _T("Move &left\tCtrl-R") );
1578 menuLogical
->AppendSeparator();
1579 menuLogical
->Append( LogicalOrigin_Set
, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1580 menuLogical
->Append( LogicalOrigin_Restore
, _T("&Restore to normal\tShift-Ctrl-0") );
1582 wxMenu
*menuColour
= new wxMenu
;
1584 menuColour
->Append( Colour_TextForeground
, _T("Text &foreground...") );
1585 menuColour
->Append( Colour_TextBackground
, _T("Text &background...") );
1586 menuColour
->Append( Colour_Background
, _T("Background &colour...") );
1587 #endif // wxUSE_COLOURDLG
1588 menuColour
->AppendCheckItem( Colour_BackgroundMode
, _T("&Opaque/transparent\tCtrl-B") );
1589 menuColour
->AppendCheckItem( Colour_TextureBackgound
, _T("Draw textured back&ground\tCtrl-T") );
1591 // now append the freshly created menu to the menu bar...
1592 wxMenuBar
*menuBar
= new wxMenuBar
;
1593 menuBar
->Append(menuFile
, _T("&File"));
1594 menuBar
->Append(menuMapMode
, _T("&Mode"));
1595 menuBar
->Append(menuUserScale
, _T("&Scale"));
1596 menuBar
->Append(menuAxis
, _T("&Axis"));
1597 menuBar
->Append(menuLogical
, _T("&Origin"));
1598 menuBar
->Append(menuColour
, _T("&Colours"));
1600 // ... and attach this menu bar to the frame
1601 SetMenuBar(menuBar
);
1605 SetStatusText(_T("Welcome to wxWidgets!"));
1606 #endif // wxUSE_STATUSBAR
1608 m_mapMode
= wxMM_TEXT
;
1611 m_xLogicalOrigin
= 0;
1612 m_yLogicalOrigin
= 0;
1614 m_yAxisReversed
= false;
1615 m_backgroundMode
= wxSOLID
;
1616 m_colourForeground
= *wxRED
;
1617 m_colourBackground
= *wxBLUE
;
1618 m_textureBackground
= false;
1620 m_canvas
= new MyCanvas( this );
1621 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1626 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1628 // true is to force the frame to close
1632 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1635 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1636 wxT("This sample tests various primitive drawing functions\n")
1637 wxT("(without any attempts to prevent flicker).\n")
1638 wxT("Copyright (c) Robert Roebling 1999")
1641 wxMessageBox(msg
, _T("About Drawing"), wxOK
| wxICON_INFORMATION
, this);
1644 void MyFrame::OnClip(wxCommandEvent
& event
)
1646 m_canvas
->Clip(event
.IsChecked());
1649 #if wxUSE_GRAPHICS_CONTEXT
1650 void MyFrame::OnGraphicContext(wxCommandEvent
& event
)
1652 m_canvas
->UseGraphicContext(event
.IsChecked());
1656 void MyFrame::OnShow(wxCommandEvent
& event
)
1658 m_canvas
->ToShow((ScreenToShow
)(event
.GetId() - MenuShow_First
));
1661 void MyFrame::OnOption(wxCommandEvent
& event
)
1663 switch (event
.GetId())
1666 m_mapMode
= wxMM_TEXT
;
1668 case MapMode_Lometric
:
1669 m_mapMode
= wxMM_LOMETRIC
;
1672 m_mapMode
= wxMM_TWIPS
;
1674 case MapMode_Points
:
1675 m_mapMode
= wxMM_POINTS
;
1677 case MapMode_Metric
:
1678 m_mapMode
= wxMM_METRIC
;
1681 case LogicalOrigin_MoveDown
:
1682 m_yLogicalOrigin
+= 10;
1684 case LogicalOrigin_MoveUp
:
1685 m_yLogicalOrigin
-= 10;
1687 case LogicalOrigin_MoveLeft
:
1688 m_xLogicalOrigin
+= 10;
1690 case LogicalOrigin_MoveRight
:
1691 m_xLogicalOrigin
-= 10;
1693 case LogicalOrigin_Set
:
1695 m_yLogicalOrigin
= -100;
1697 case LogicalOrigin_Restore
:
1699 m_yLogicalOrigin
= 0;
1702 case UserScale_StretchHoriz
:
1703 m_xUserScale
*= 1.10;
1705 case UserScale_ShrinkHoriz
:
1706 m_xUserScale
/= 1.10;
1708 case UserScale_StretchVertic
:
1709 m_yUserScale
*= 1.10;
1711 case UserScale_ShrinkVertic
:
1712 m_yUserScale
/= 1.10;
1714 case UserScale_Restore
:
1719 case AxisMirror_Vertic
:
1720 m_yAxisReversed
= !m_yAxisReversed
;
1722 case AxisMirror_Horiz
:
1723 m_xAxisReversed
= !m_xAxisReversed
;
1727 case Colour_TextForeground
:
1728 m_colourForeground
= SelectColour();
1730 case Colour_TextBackground
:
1731 m_colourBackground
= SelectColour();
1733 case Colour_Background
:
1735 wxColour col
= SelectColour();
1738 m_backgroundBrush
.SetColour(col
);
1742 #endif // wxUSE_COLOURDLG
1744 case Colour_BackgroundMode
:
1745 m_backgroundMode
= m_backgroundMode
== wxSOLID
? wxTRANSPARENT
1749 case Colour_TextureBackgound
:
1750 m_textureBackground
= ! m_textureBackground
;
1758 m_canvas
->Refresh();
1761 void MyFrame::PrepareDC(wxDC
& dc
)
1763 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
1764 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
1765 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
1766 dc
.SetMapMode( m_mapMode
);
1770 wxColour
MyFrame::SelectColour()
1774 wxColourDialog
dialog(this, &data
);
1776 if ( dialog
.ShowModal() == wxID_OK
)
1778 col
= dialog
.GetColourData().GetColour();
1783 #endif // wxUSE_COLOURDLG