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"
37 #define wxTEST_GRAPHICS 1
40 #include "wx/graphics.h"
41 #if wxUSE_GRAPHICS_CONTEXT == 0
42 #undef wxTEST_GRAPHICS
43 #define wxTEST_GRAPHICS 0
46 #undef wxUSE_GRAPHICS_CONTEXT
47 #define wxUSE_GRAPHICS_CONTEXT 0
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 // the application icon
55 #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__)
56 #include "mondrian.xpm"
59 // ----------------------------------------------------------------------------
61 // ----------------------------------------------------------------------------
63 // what do we show on screen (there are too many shapes to put them all on
64 // screen simultaneously)
78 #if wxUSE_GRAPHICS_CONTEXT
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 static wxBitmap
*gs_bmpNoMask
= NULL
,
90 *gs_bmpWithColMask
= NULL
,
92 *gs_bmpWithMask
= NULL
,
97 // ----------------------------------------------------------------------------
99 // ----------------------------------------------------------------------------
101 // Define a new application type, each program should derive a class from wxApp
102 class MyApp
: public wxApp
105 // override base class virtuals
106 // ----------------------------
108 // this one is called on application startup and is a good place for the app
109 // initialization (doing it here and not in the ctor allows to have an error
110 // return: if OnInit() returns false, the application terminates)
111 virtual bool OnInit();
113 virtual int OnExit() { DeleteBitmaps(); return 0; }
116 void DeleteBitmaps();
123 // Define a new frame type: this is going to be our main frame
124 class MyFrame
: public wxFrame
128 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
130 // event handlers (these functions should _not_ be virtual)
131 void OnQuit(wxCommandEvent
& event
);
132 void OnAbout(wxCommandEvent
& event
);
133 void OnClip(wxCommandEvent
& event
);
134 #if wxUSE_GRAPHICS_CONTEXT
135 void OnGraphicContext(wxCommandEvent
& event
);
137 void OnShow(wxCommandEvent
&event
);
138 void OnOption(wxCommandEvent
&event
);
141 wxColour
SelectColour();
142 #endif // wxUSE_COLOURDLG
143 void PrepareDC(wxDC
& dc
);
145 int m_backgroundMode
;
146 int m_textureBackground
;
150 int m_xLogicalOrigin
;
151 int m_yLogicalOrigin
;
152 bool m_xAxisReversed
,
154 wxColour m_colourForeground
, // these are _text_ colours
156 wxBrush m_backgroundBrush
;
160 // any class wishing to process wxWidgets events must use this macro
161 DECLARE_EVENT_TABLE()
164 // define a scrollable canvas for drawing onto
165 class MyCanvas
: public wxScrolledWindow
168 MyCanvas( MyFrame
*parent
);
170 void OnPaint(wxPaintEvent
&event
);
171 void OnMouseMove(wxMouseEvent
&event
);
173 void ToShow(ScreenToShow show
) { m_show
= show
; Refresh(); }
175 // set or remove the clipping region
176 void Clip(bool clip
) { m_clip
= clip
; Refresh(); }
177 #if wxUSE_GRAPHICS_CONTEXT
178 void UseGraphicContext(bool use
) { m_useContext
= use
; Refresh(); }
188 void DrawTestLines( int x
, int y
, int width
, wxDC
&dc
);
189 void DrawTestPoly(wxDC
& dc
);
190 void DrawTestBrushes(wxDC
& dc
);
191 void DrawText(wxDC
& dc
);
192 void DrawImages(wxDC
& dc
, DrawMode mode
);
193 void DrawWithLogicalOps(wxDC
& dc
);
194 #if wxUSE_GRAPHICS_CONTEXT
195 void DrawAlpha(wxDC
& dc
);
197 void DrawRegions(wxDC
& dc
);
198 void DrawCircles(wxDC
& dc
);
199 void DrawSplines(wxDC
& dc
);
200 void DrawDefault(wxDC
& dc
);
201 void DrawGradients(wxDC
& dc
);
203 void DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
);
209 wxBitmap m_smile_bmp
;
212 #if wxUSE_GRAPHICS_CONTEXT
216 DECLARE_EVENT_TABLE()
219 // ----------------------------------------------------------------------------
221 // ----------------------------------------------------------------------------
223 // IDs for the controls and the menu commands
227 File_Quit
= wxID_EXIT
,
228 File_About
= wxID_ABOUT
,
230 MenuShow_First
= wxID_HIGHEST
,
231 File_ShowDefault
= MenuShow_First
,
237 File_ShowMaskStretch
,
242 #if wxUSE_GRAPHICS_CONTEXT
246 MenuShow_Last
= File_ShowGradients
,
249 #if wxUSE_GRAPHICS_CONTEXT
255 MapMode_Text
= MenuOption_First
,
261 UserScale_StretchHoriz
,
262 UserScale_ShrinkHoriz
,
263 UserScale_StretchVertic
,
264 UserScale_ShrinkVertic
,
270 LogicalOrigin_MoveDown
,
271 LogicalOrigin_MoveUp
,
272 LogicalOrigin_MoveLeft
,
273 LogicalOrigin_MoveRight
,
275 LogicalOrigin_Restore
,
278 Colour_TextForeground
,
279 Colour_TextBackground
,
281 #endif // wxUSE_COLOURDLG
282 Colour_BackgroundMode
,
283 Colour_TextureBackgound
,
285 MenuOption_Last
= Colour_TextureBackgound
288 // ----------------------------------------------------------------------------
289 // event tables and other macros for wxWidgets
290 // ----------------------------------------------------------------------------
293 // Create a new application object: this macro will allow wxWidgets to create
294 // the application object during program execution (it's better than using a
295 // static object for many reasons) and also declares the accessor function
296 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
300 // ============================================================================
302 // ============================================================================
304 // ----------------------------------------------------------------------------
305 // the application class
306 // ----------------------------------------------------------------------------
308 bool MyApp::LoadImages()
310 gs_bmpNoMask
= new wxBitmap
;
311 gs_bmpWithColMask
= new wxBitmap
;
312 gs_bmpMask
= new wxBitmap
;
313 gs_bmpWithMask
= new wxBitmap
;
314 gs_bmp4
= new wxBitmap
;
315 gs_bmp4_mono
= new wxBitmap
;
316 gs_bmp36
= new wxBitmap
;
319 pathList
.Add(_T("."));
320 pathList
.Add(_T(".."));
321 pathList
.Add(_T("../.."));
323 wxString path
= pathList
.FindValidPath(_T("pat4.bmp"));
327 /* 4 colour bitmap */
328 gs_bmp4
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
329 /* turn into mono-bitmap */
330 gs_bmp4_mono
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
331 wxMask
* mask4
= new wxMask(*gs_bmp4_mono
, *wxBLACK
);
332 gs_bmp4_mono
->SetMask(mask4
);
334 path
= pathList
.FindValidPath(_T("pat36.bmp"));
337 gs_bmp36
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
338 wxMask
* mask36
= new wxMask(*gs_bmp36
, *wxBLACK
);
339 gs_bmp36
->SetMask(mask36
);
341 path
= pathList
.FindValidPath(_T("image.bmp"));
344 gs_bmpNoMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
345 gs_bmpWithMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
346 gs_bmpWithColMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
348 path
= pathList
.FindValidPath(_T("mask.bmp"));
351 gs_bmpMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
353 wxMask
*mask
= new wxMask(*gs_bmpMask
, *wxBLACK
);
354 gs_bmpWithMask
->SetMask(mask
);
356 mask
= new wxMask(*gs_bmpWithColMask
, *wxWHITE
);
357 gs_bmpWithColMask
->SetMask(mask
);
362 // `Main program' equivalent: the program execution "starts" here
365 if ( !wxApp::OnInit() )
368 // Create the main application window
369 MyFrame
*frame
= new MyFrame(_T("Drawing sample"),
370 wxPoint(50, 50), wxSize(550, 340));
372 // Show it and tell the application that it's our main window
378 wxLogError(wxT("Can't load one of the bitmap files needed ")
379 wxT("for this sample from the current or parent ")
380 wxT("directory, please copy them there."));
392 void MyApp::DeleteBitmaps()
395 delete gs_bmpWithColMask
;
397 delete gs_bmpWithMask
;
403 gs_bmpWithColMask
= NULL
;
405 gs_bmpWithMask
= NULL
;
411 // ----------------------------------------------------------------------------
413 // ----------------------------------------------------------------------------
415 // the event tables connect the wxWidgets events with the functions (event
416 // handlers) which process them.
417 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
418 EVT_PAINT (MyCanvas::OnPaint
)
419 EVT_MOTION (MyCanvas::OnMouseMove
)
424 MyCanvas::MyCanvas(MyFrame
*parent
)
425 : wxScrolledWindow(parent
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
426 wxHSCROLL
| wxVSCROLL
| wxNO_FULL_REPAINT_ON_RESIZE
)
429 m_show
= Show_Default
;
430 m_smile_bmp
= wxBitmap(smile_xpm
);
431 m_std_icon
= wxArtProvider::GetIcon(wxART_INFORMATION
);
433 #if wxUSE_GRAPHICS_CONTEXT
434 m_useContext
= false;
438 void MyCanvas::DrawTestBrushes(wxDC
& dc
)
440 static const wxCoord WIDTH
= 200;
441 static const wxCoord HEIGHT
= 80;
446 dc
.SetBrush(wxBrush(*wxGREEN
, wxSOLID
));
447 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
448 dc
.DrawText(_T("Solid green"), x
+ 10, y
+ 10);
451 dc
.SetBrush(wxBrush(*wxRED
, wxCROSSDIAG_HATCH
));
452 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
453 dc
.DrawText(_T("Hatched red"), x
+ 10, y
+ 10);
456 dc
.SetBrush(wxBrush(*gs_bmpMask
));
457 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
458 dc
.DrawText(_T("Stipple mono"), x
+ 10, y
+ 10);
461 dc
.SetBrush(wxBrush(*gs_bmpNoMask
));
462 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
463 dc
.DrawText(_T("Stipple colour"), x
+ 10, y
+ 10);
466 void MyCanvas::DrawTestPoly(wxDC
& dc
)
468 wxBrush
brushHatch(*wxRED
, wxFDIAGONAL_HATCH
);
469 dc
.SetBrush(brushHatch
);
472 star
[0] = wxPoint(100, 60);
473 star
[1] = wxPoint(60, 150);
474 star
[2] = wxPoint(160, 100);
475 star
[3] = wxPoint(40, 100);
476 star
[4] = wxPoint(140, 150);
478 dc
.DrawText(_T("You should see two (irregular) stars below, the left one ")
479 _T("hatched"), 10, 10);
480 dc
.DrawText(_T("except for the central region and the right ")
481 _T("one entirely hatched"), 10, 30);
482 dc
.DrawText(_T("The third star only has a hatched outline"), 10, 50);
484 dc
.DrawPolygon(WXSIZEOF(star
), star
, 0, 30);
485 dc
.DrawPolygon(WXSIZEOF(star
), star
, 160, 30, wxWINDING_RULE
);
488 star2
[0] = wxPoint(0, 100);
489 star2
[1] = wxPoint(-59, -81);
490 star2
[2] = wxPoint(95, 31);
491 star2
[3] = wxPoint(-95, 31);
492 star2
[4] = wxPoint(59, -81);
493 star2
[5] = wxPoint(0, 80);
494 star2
[6] = wxPoint(-47, -64);
495 star2
[7] = wxPoint(76, 24);
496 star2
[8] = wxPoint(-76, 24);
497 star2
[9] = wxPoint(47, -64);
498 int count
[2] = {5, 5};
500 dc
.DrawPolyPolygon(WXSIZEOF(count
), count
, star2
, 450, 150);
503 void MyCanvas::DrawTestLines( int x
, int y
, int width
, wxDC
&dc
)
505 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
506 dc
.SetBrush( *wxRED_BRUSH
);
507 dc
.DrawText(wxString::Format(wxT("Testing lines of width %d"), width
), x
+ 10, y
- 10);
508 dc
.DrawRectangle( x
+10, y
+10, 100, 190 );
510 dc
.DrawText(_T("Solid/dot/short dash/long dash/dot dash"), x
+ 150, y
+ 10);
511 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
512 dc
.DrawLine( x
+20, y
+20, 100, y
+20 );
513 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT
) );
514 dc
.DrawLine( x
+20, y
+30, 100, y
+30 );
515 dc
.SetPen( wxPen( wxT("black"), width
, wxSHORT_DASH
) );
516 dc
.DrawLine( x
+20, y
+40, 100, y
+40 );
517 dc
.SetPen( wxPen( wxT("black"), width
, wxLONG_DASH
) );
518 dc
.DrawLine( x
+20, y
+50, 100, y
+50 );
519 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT_DASH
) );
520 dc
.DrawLine( x
+20, y
+60, 100, y
+60 );
522 dc
.DrawText(_T("Misc hatches"), x
+ 150, y
+ 70);
523 dc
.SetPen( wxPen( wxT("black"), width
, wxBDIAGONAL_HATCH
) );
524 dc
.DrawLine( x
+20, y
+70, 100, y
+70 );
525 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSSDIAG_HATCH
) );
526 dc
.DrawLine( x
+20, y
+80, 100, y
+80 );
527 dc
.SetPen( wxPen( wxT("black"), width
, wxFDIAGONAL_HATCH
) );
528 dc
.DrawLine( x
+20, y
+90, 100, y
+90 );
529 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSS_HATCH
) );
530 dc
.DrawLine( x
+20, y
+100, 100, y
+100 );
531 dc
.SetPen( wxPen( wxT("black"), width
, wxHORIZONTAL_HATCH
) );
532 dc
.DrawLine( x
+20, y
+110, 100, y
+110 );
533 dc
.SetPen( wxPen( wxT("black"), width
, wxVERTICAL_HATCH
) );
534 dc
.DrawLine( x
+20, y
+120, 100, y
+120 );
536 dc
.DrawText(_T("User dash"), x
+ 150, y
+ 140);
537 wxPen
ud( wxT("black"), width
, wxUSER_DASH
);
539 dash1
[0] = 8; // Long dash <---------+
540 dash1
[1] = 2; // Short gap |
541 dash1
[2] = 3; // Short dash |
542 dash1
[3] = 2; // Short gap |
543 dash1
[4] = 3; // Short dash |
544 dash1
[5] = 2; // Short gap and repeat +
545 ud
.SetDashes( 6, dash1
);
547 dc
.DrawLine( x
+20, y
+140, 100, y
+140 );
548 dash1
[0] = 5; // Make first dash shorter
549 ud
.SetDashes( 6, dash1
);
551 dc
.DrawLine( x
+20, y
+150, 100, y
+150 );
552 dash1
[2] = 5; // Make second dash longer
553 ud
.SetDashes( 6, dash1
);
555 dc
.DrawLine( x
+20, y
+160, 100, y
+160 );
556 dash1
[4] = 5; // Make third dash longer
557 ud
.SetDashes( 6, dash1
);
559 dc
.DrawLine( x
+20, y
+170, 100, y
+170 );
562 void MyCanvas::DrawDefault(wxDC
& dc
)
565 dc
.DrawCircle(0, 0, 10);
567 #if !defined(wxMAC_USE_CORE_GRAPHICS) || !wxMAC_USE_CORE_GRAPHICS
568 // GetPixel and FloodFill not supported by Mac OS X CoreGraphics
569 // (FloodFill uses Blit from a non-wxMemoryDC)
570 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
571 dc
.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID
));
574 dc
.GetPixel(1,1, &tmpColour
);
575 dc
.FloodFill(1,1, tmpColour
, wxFLOOD_SURFACE
);
578 dc
.DrawCheckMark(5, 80, 15, 15);
579 dc
.DrawCheckMark(25, 80, 30, 30);
580 dc
.DrawCheckMark(60, 80, 60, 60);
582 // this is the test for "blitting bitmap into DC damages selected brush" bug
583 wxCoord rectSize
= m_std_icon
.GetWidth() + 10;
585 dc
.SetPen(*wxTRANSPARENT_PEN
);
586 dc
.SetBrush( *wxGREEN_BRUSH
);
587 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
588 dc
.DrawBitmap(m_std_icon
, x
+ 5, 15, true);
590 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
591 dc
.DrawIcon(m_std_icon
, x
+ 5, 15);
593 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
595 // test for "transparent" bitmap drawing (it intersects with the last
597 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
599 if (m_smile_bmp
.Ok())
600 dc
.DrawBitmap(m_smile_bmp
, x
+ rectSize
- 20, rectSize
- 10, true);
602 dc
.SetBrush( *wxBLACK_BRUSH
);
603 dc
.DrawRectangle( 0, 160, 1000, 300 );
606 wxBitmap
bitmap(20,70);
608 memdc
.SelectObject( bitmap
);
609 memdc
.SetBrush( *wxBLACK_BRUSH
);
610 memdc
.SetPen( *wxWHITE_PEN
);
611 memdc
.DrawRectangle(0,0,20,70);
612 memdc
.DrawLine( 10,0,10,70 );
615 wxPen pen
= *wxRED_PEN
;
617 memdc
.DrawLine( 10, 5,10, 5 );
618 memdc
.DrawLine( 10,10,11,10 );
619 memdc
.DrawLine( 10,15,12,15 );
620 memdc
.DrawLine( 10,20,13,20 );
623 memdc.SetPen(*wxRED_PEN);
624 memdc.DrawLine( 12, 5,12, 5 );
625 memdc.DrawLine( 12,10,13,10 );
626 memdc.DrawLine( 12,15,14,15 );
627 memdc.DrawLine( 12,20,15,20 );
631 memdc
.DrawLine( 10,25,10,25 );
632 memdc
.DrawLine( 10,30, 9,30 );
633 memdc
.DrawLine( 10,35, 8,35 );
634 memdc
.DrawLine( 10,40, 7,40 );
637 dc
.SetPen(*wxWHITE_PEN
);
638 memdc
.SetLogicalFunction( wxINVERT
);
639 memdc
.SetPen( *wxWHITE_PEN
);
640 memdc
.DrawLine( 10,50,10,50 );
641 memdc
.DrawLine( 10,55,11,55 );
642 memdc
.DrawLine( 10,60,12,60 );
643 memdc
.DrawLine( 10,65,13,65 );
645 memdc
.DrawLine( 12,50,12,50 );
646 memdc
.DrawLine( 12,55,13,55 );
647 memdc
.DrawLine( 12,60,14,60 );
648 memdc
.DrawLine( 12,65,15,65 );
650 memdc
.SelectObject( wxNullBitmap
);
651 dc
.DrawBitmap( bitmap
, 10, 170 );
652 wxImage image
= bitmap
.ConvertToImage();
653 image
.Rescale( 60,210 );
654 bitmap
= wxBitmap(image
);
655 dc
.DrawBitmap( bitmap
, 50, 170 );
657 // test the rectangle outline drawing - there should be one pixel between
658 // the rect and the lines
659 dc
.SetPen(*wxWHITE_PEN
);
660 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
661 dc
.DrawRectangle(150, 170, 49, 29);
662 dc
.DrawRectangle(200, 170, 49, 29);
663 dc
.SetPen(*wxWHITE_PEN
);
664 dc
.DrawLine(250, 210, 250, 170);
665 dc
.DrawLine(260, 200, 150, 200);
667 // test the rectangle filled drawing - there should be one pixel between
668 // the rect and the lines
669 dc
.SetPen(*wxTRANSPARENT_PEN
);
670 dc
.SetBrush( *wxWHITE_BRUSH
);
671 dc
.DrawRectangle(300, 170, 49, 29);
672 dc
.DrawRectangle(350, 170, 49, 29);
673 dc
.SetPen(*wxWHITE_PEN
);
674 dc
.DrawLine(400, 170, 400, 210);
675 dc
.DrawLine(300, 200, 410, 200);
677 // a few more tests of this kind
678 dc
.SetPen(*wxRED_PEN
);
679 dc
.SetBrush( *wxWHITE_BRUSH
);
680 dc
.DrawRectangle(300, 220, 1, 1);
681 dc
.DrawRectangle(310, 220, 2, 2);
682 dc
.DrawRectangle(320, 220, 3, 3);
683 dc
.DrawRectangle(330, 220, 4, 4);
685 dc
.SetPen(*wxTRANSPARENT_PEN
);
686 dc
.SetBrush( *wxWHITE_BRUSH
);
687 dc
.DrawRectangle(300, 230, 1, 1);
688 dc
.DrawRectangle(310, 230, 2, 2);
689 dc
.DrawRectangle(320, 230, 3, 3);
690 dc
.DrawRectangle(330, 230, 4, 4);
692 // and now for filled rect with outline
693 dc
.SetPen(*wxRED_PEN
);
694 dc
.SetBrush( *wxWHITE_BRUSH
);
695 dc
.DrawRectangle(500, 170, 49, 29);
696 dc
.DrawRectangle(550, 170, 49, 29);
697 dc
.SetPen(*wxWHITE_PEN
);
698 dc
.DrawLine(600, 170, 600, 210);
699 dc
.DrawLine(500, 200, 610, 200);
701 // test the rectangle outline drawing - there should be one pixel between
702 // the rect and the lines
703 dc
.SetPen(*wxWHITE_PEN
);
704 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
705 dc
.DrawRoundedRectangle(150, 270, 49, 29, 6);
706 dc
.DrawRoundedRectangle(200, 270, 49, 29, 6);
707 dc
.SetPen(*wxWHITE_PEN
);
708 dc
.DrawLine(250, 270, 250, 310);
709 dc
.DrawLine(150, 300, 260, 300);
711 // test the rectangle filled drawing - there should be one pixel between
712 // the rect and the lines
713 dc
.SetPen(*wxTRANSPARENT_PEN
);
714 dc
.SetBrush( *wxWHITE_BRUSH
);
715 dc
.DrawRoundedRectangle(300, 270, 49, 29, 6);
716 dc
.DrawRoundedRectangle(350, 270, 49, 29, 6);
717 dc
.SetPen(*wxWHITE_PEN
);
718 dc
.DrawLine(400, 270, 400, 310);
719 dc
.DrawLine(300, 300, 410, 300);
721 // Added by JACS to demonstrate bizarre behaviour.
722 // With a size of 70, we get a missing red RHS,
723 // and the height is too small, so we get yellow
724 // showing. With a size of 40, it draws as expected:
725 // it just shows a white rectangle with red outline.
727 int totalHeight
= 70;
728 wxBitmap
bitmap2(totalWidth
, totalHeight
);
731 memdc2
.SelectObject(bitmap2
);
733 wxColour
clr(255, 255, 0);
734 wxBrush
yellowBrush(clr
, wxSOLID
);
735 memdc2
.SetBackground(yellowBrush
);
738 wxPen
yellowPen(clr
, 1, wxSOLID
);
740 // Now draw a white rectangle with red outline. It should
741 // entirely eclipse the yellow background.
742 memdc2
.SetPen(*wxRED_PEN
);
743 memdc2
.SetBrush(*wxWHITE_BRUSH
);
745 memdc2
.DrawRectangle(0, 0, totalWidth
, totalHeight
);
747 memdc2
.SetPen(wxNullPen
);
748 memdc2
.SetBrush(wxNullBrush
);
749 memdc2
.SelectObject(wxNullBitmap
);
751 dc
.DrawBitmap(bitmap2
, 500, 270);
753 // Repeat, but draw directly on dc
754 // Draw a yellow rectangle filling the bitmap
756 x
= 600; int y
= 270;
757 dc
.SetPen(yellowPen
);
758 dc
.SetBrush(yellowBrush
);
759 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
761 // Now draw a white rectangle with red outline. It should
762 // entirely eclipse the yellow background.
763 dc
.SetPen(*wxRED_PEN
);
764 dc
.SetBrush(*wxWHITE_BRUSH
);
766 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
769 void MyCanvas::DrawText(wxDC
& dc
)
771 // set underlined font for testing
772 dc
.SetFont( wxFont(12, wxMODERN
, wxNORMAL
, wxNORMAL
, true) );
773 dc
.DrawText( _T("This is text"), 110, 10 );
774 dc
.DrawRotatedText( _T("That is text"), 20, 10, -45 );
776 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
777 // under Win9x (it is not TrueType)
778 dc
.SetFont( *wxSWISS_FONT
);
781 dc
.SetBackgroundMode(wxTRANSPARENT
);
783 for ( int n
= -180; n
< 180; n
+= 30 )
785 text
.Printf(wxT(" %d rotated text"), n
);
786 dc
.DrawRotatedText(text
, 400, 400, n
);
789 dc
.SetFont( wxFont( 18, wxSWISS
, wxNORMAL
, wxNORMAL
) );
791 dc
.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
796 dc
.GetTextExtent( _T("This is Swiss 18pt text."), &length
, &height
, &descent
);
797 text
.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length
, height
, descent
);
798 dc
.DrawText( text
, 110, 80 );
800 text
.Printf( wxT("CharHeight() returns: %d"), dc
.GetCharHeight() );
801 dc
.DrawText( text
, 110, 120 );
803 dc
.DrawRectangle( 100, 40, 4, height
);
805 // test the logical function effect
807 dc
.SetLogicalFunction(wxINVERT
);
808 dc
.DrawText( _T("There should be no text below"), 110, 150 );
809 dc
.DrawRectangle( 110, y
, 100, height
);
811 // twice drawn inverted should result in invisible
813 dc
.DrawText( _T("Invisible text"), 110, y
);
814 dc
.DrawRectangle( 110, y
, 100, height
);
815 dc
.DrawText( _T("Invisible text"), 110, y
);
816 dc
.DrawRectangle( 110, y
, 100, height
);
817 dc
.SetLogicalFunction(wxCOPY
);
820 dc
.DrawRectangle( 110, y
, 100, height
);
821 dc
.DrawText( _T("Visible text"), 110, y
);
828 } rasterOperations
[] =
830 { wxT("wxAND"), wxAND
},
831 { wxT("wxAND_INVERT"), wxAND_INVERT
},
832 { wxT("wxAND_REVERSE"), wxAND_REVERSE
},
833 { wxT("wxCLEAR"), wxCLEAR
},
834 { wxT("wxCOPY"), wxCOPY
},
835 { wxT("wxEQUIV"), wxEQUIV
},
836 { wxT("wxINVERT"), wxINVERT
},
837 { wxT("wxNAND"), wxNAND
},
838 { wxT("wxNO_OP"), wxNO_OP
},
839 { wxT("wxOR"), wxOR
},
840 { wxT("wxOR_INVERT"), wxOR_INVERT
},
841 { wxT("wxOR_REVERSE"), wxOR_REVERSE
},
842 { wxT("wxSET"), wxSET
},
843 { wxT("wxSRC_INVERT"), wxSRC_INVERT
},
844 { wxT("wxXOR"), wxXOR
},
847 void MyCanvas::DrawImages(wxDC
& dc
, DrawMode mode
)
849 dc
.DrawText(_T("original image"), 0, 0);
850 dc
.DrawBitmap(*gs_bmpNoMask
, 0, 20, 0);
851 dc
.DrawText(_T("with colour mask"), 0, 100);
852 dc
.DrawBitmap(*gs_bmpWithColMask
, 0, 120, true);
853 dc
.DrawText(_T("the mask image"), 0, 200);
854 dc
.DrawBitmap(*gs_bmpMask
, 0, 220, 0);
855 dc
.DrawText(_T("masked image"), 0, 300);
856 dc
.DrawBitmap(*gs_bmpWithMask
, 0, 320, true);
858 int cx
= gs_bmpWithColMask
->GetWidth(),
859 cy
= gs_bmpWithColMask
->GetHeight();
862 for ( size_t n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
864 wxCoord x
= 120 + 150*(n%4
),
867 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
868 memDC
.SelectObject(*gs_bmpWithColMask
);
869 if ( mode
== Draw_Stretch
)
871 dc
.StretchBlit(x
, y
, cx
, cy
, &memDC
, 0, 0, cx
/2, cy
/2,
872 rasterOperations
[n
].rop
, true);
876 dc
.Blit(x
, y
, cx
, cy
, &memDC
, 0, 0, rasterOperations
[n
].rop
, true);
881 void MyCanvas::DrawWithLogicalOps(wxDC
& dc
)
883 static const wxCoord w
= 60;
884 static const wxCoord h
= 60;
886 // reuse the text colour here
887 dc
.SetPen(wxPen(m_owner
->m_colourForeground
, 1, wxSOLID
));
888 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
891 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
893 wxCoord x
= 20 + 150*(n%4
),
896 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
897 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
898 dc
.DrawRectangle(x
, y
, w
, h
);
899 dc
.DrawLine(x
, y
, x
+ w
, y
+ h
);
900 dc
.DrawLine(x
+ w
, y
, x
, y
+ h
);
903 // now some filled rectangles
904 dc
.SetBrush(wxBrush(m_owner
->m_colourForeground
, wxSOLID
));
906 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
908 wxCoord x
= 20 + 150*(n%4
),
911 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
912 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
913 dc
.DrawRectangle(x
, y
, w
, h
);
917 #if wxUSE_GRAPHICS_CONTEXT
919 void MyCanvas::DrawAlpha(wxDC
& no_dc
)
921 void MyCanvas::DrawAlpha(wxDC
& dc
)
929 wxDouble margin
= 20 ;
930 wxDouble width
= 180 ;
931 wxDouble radius
= 30 ;
933 dc
.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID
));
934 dc
.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID
));
936 wxRect
r(margin
,margin
+width
*0.66,width
,width
) ;
938 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
940 dc
.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID
));
941 dc
.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID
));
943 r
.Offset( width
* 0.8 , - width
* 0.66 ) ;
945 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
947 dc
.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID
));
948 dc
.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID
));
950 r
.Offset( width
* 0.8 , width
*0.5 ) ;
952 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
954 dc
.SetPen( *wxTRANSPARENT_PEN
) ;
955 dc
.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
956 dc
.DrawRoundedRectangle( 0 , margin
+ width
/ 2 , width
* 3 , 100 , radius
) ;
958 dc
.SetTextForeground( wxColour(255,255,0,128) );
959 dc
.SetFont( wxFont( 40, wxFONTFAMILY_SWISS
, wxFONTSTYLE_ITALIC
, wxFONTWEIGHT_NORMAL
) );
960 dc
.DrawText( wxT("Hello!"), 120, 80 );
965 void MyCanvas::DrawCircles(wxDC
& dc
)
971 dc
.SetPen( *wxRED_PEN
);
972 dc
.SetBrush( *wxGREEN_BRUSH
);
974 dc
.DrawText(_T("Some circles"), 0, y
);
975 dc
.DrawCircle(x
, y
, r
);
976 dc
.DrawCircle(x
+ 2*r
, y
, r
);
977 dc
.DrawCircle(x
+ 4*r
, y
, r
);
980 dc
.DrawText(_T("And ellipses"), 0, y
);
981 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
982 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
983 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
986 dc
.DrawText(_T("And arcs"), 0, y
);
987 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
988 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
989 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
992 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
993 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
994 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
995 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
997 // same as above, just transparent brush
999 dc
.SetPen( *wxRED_PEN
);
1000 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
1003 dc
.DrawText(_T("Some circles"), 0, y
);
1004 dc
.DrawCircle(x
, y
, r
);
1005 dc
.DrawCircle(x
+ 2*r
, y
, r
);
1006 dc
.DrawCircle(x
+ 4*r
, y
, r
);
1009 dc
.DrawText(_T("And ellipses"), 0, y
);
1010 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
1011 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
1012 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
1015 dc
.DrawText(_T("And arcs"), 0, y
);
1016 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
1017 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
1018 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
1021 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
1022 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
1023 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
1024 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
1028 void MyCanvas::DrawSplines(wxDC
& dc
)
1031 dc
.DrawText(_T("Some splines"), 10, 5);
1033 // values are hardcoded rather than randomly generated
1034 // so the output can be compared between native
1035 // implementations on platforms with different random
1039 const wxPoint
center( R
+ 20, R
+ 20 );
1040 const int angles
[7] = { 0, 10, 33, 77, 13, 145, 90 };
1041 const int radii
[5] = { 100 , 59, 85, 33, 90 };
1045 // background spline calculation
1046 unsigned int radius_pos
= 0;
1047 unsigned int angle_pos
= 0;
1049 for ( int i
= 0; i
< n
; i
++ )
1051 angle
+= angles
[ angle_pos
];
1052 int r
= R
* radii
[ radius_pos
] / 100;
1053 pts
[ i
].x
= center
.x
+ (wxCoord
)( r
* cos( M_PI
* angle
/ 180.0) );
1054 pts
[ i
].y
= center
.y
+ (wxCoord
)( r
* sin( M_PI
* angle
/ 180.0) );
1057 if ( angle_pos
>= WXSIZEOF(angles
) ) angle_pos
= 0;
1060 if ( radius_pos
>= WXSIZEOF(radii
) ) radius_pos
= 0;
1063 // background spline drawing
1064 dc
.SetPen(*wxRED_PEN
);
1065 dc
.DrawSpline(WXSIZEOF(pts
), pts
);
1067 // less detailed spline calculation
1068 wxPoint letters
[4][5];
1070 letters
[0][0] = wxPoint( 0,1); // O O
1071 letters
[0][1] = wxPoint( 1,3); // * *
1072 letters
[0][2] = wxPoint( 2,2); // * O *
1073 letters
[0][3] = wxPoint( 3,3); // * * * *
1074 letters
[0][4] = wxPoint( 4,1); // O O
1076 letters
[1][0] = wxPoint( 5,1); // O*O
1077 letters
[1][1] = wxPoint( 6,1); // *
1078 letters
[1][2] = wxPoint( 7,2); // O
1079 letters
[1][3] = wxPoint( 8,3); // *
1080 letters
[1][4] = wxPoint( 9,3); // O*O
1082 letters
[2][0] = wxPoint( 5,3); // O*O
1083 letters
[2][1] = wxPoint( 6,3); // *
1084 letters
[2][2] = wxPoint( 7,2); // O
1085 letters
[2][3] = wxPoint( 8,1); // *
1086 letters
[2][4] = wxPoint( 9,1); // O*O
1088 letters
[3][0] = wxPoint(10,0); // O O
1089 letters
[3][1] = wxPoint(11,3); // * *
1090 letters
[3][2] = wxPoint(12,1); // * O *
1091 letters
[3][3] = wxPoint(13,3); // * * * *
1092 letters
[3][4] = wxPoint(14,0); // O O
1094 const int dx
= 2 * R
/ letters
[3][4].x
;
1095 const int h
[4] = { -R
/2, 0, R
/4, R
/2 };
1097 for ( int m
= 0; m
< 4; m
++ )
1099 for ( int n
= 0; n
< 5; n
++ )
1101 letters
[m
][n
].x
= center
.x
- R
+ letters
[m
][n
].x
* dx
;
1102 letters
[m
][n
].y
= center
.y
+ h
[ letters
[m
][n
].y
];
1105 dc
.SetPen( wxPen( wxT("blue"), 1, wxDOT
) );
1106 dc
.DrawLines(5, letters
[m
]);
1107 dc
.SetPen( wxPen( wxT("black"), 4, wxSOLID
) );
1108 dc
.DrawSpline(5, letters
[m
]);
1112 dc
.DrawText(_T("Splines not supported."), 10, 5);
1116 void MyCanvas::DrawGradients(wxDC
& dc
)
1118 static const int TEXT_HEIGHT
= 15;
1121 wxRect
r(10, 10, 50, 50);
1122 dc
.DrawText(_T("wxRIGHT"), r
.x
, r
.y
);
1123 r
.Offset(0, TEXT_HEIGHT
);
1124 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxRIGHT
);
1126 r
.Offset(0, r
.height
+ 10);
1127 dc
.DrawText(_T("wxLEFT"), r
.x
, r
.y
);
1128 r
.Offset(0, TEXT_HEIGHT
);
1129 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxLEFT
);
1131 r
.Offset(0, r
.height
+ 10);
1132 dc
.DrawText(_T("wxDOWN"), r
.x
, r
.y
);
1133 r
.Offset(0, TEXT_HEIGHT
);
1134 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxDOWN
);
1136 r
.Offset(0, r
.height
+ 10);
1137 dc
.DrawText(_T("wxUP"), r
.x
, r
.y
);
1138 r
.Offset(0, TEXT_HEIGHT
);
1139 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxUP
);
1143 r
= wxRect(200, 10, 50, 50);
1144 dc
.DrawText(_T("Blue inside"), r
.x
, r
.y
);
1145 r
.Offset(0, TEXT_HEIGHT
);
1146 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
);
1148 r
.Offset(0, r
.height
+ 10);
1149 dc
.DrawText(_T("White inside"), r
.x
, r
.y
);
1150 r
.Offset(0, TEXT_HEIGHT
);
1151 dc
.GradientFillConcentric(r
, *wxWHITE
, *wxBLUE
);
1153 r
.Offset(0, r
.height
+ 10);
1154 dc
.DrawText(_T("Blue in top left corner"), r
.x
, r
.y
);
1155 r
.Offset(0, TEXT_HEIGHT
);
1156 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(0, 0));
1158 r
.Offset(0, r
.height
+ 10);
1159 dc
.DrawText(_T("Blue in bottom right corner"), r
.x
, r
.y
);
1160 r
.Offset(0, TEXT_HEIGHT
);
1161 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(r
.width
, r
.height
));
1163 // check that the area filled by the gradient is exactly the interior of
1167 dc
.DrawText("The interior should be filled but", r
.x
, r
.y
);
1169 dc
.DrawText(" the red border should remain visible:", r
.x
, r
.y
);
1180 dc
.SetPen(wxPen(wxColour(255, 0, 0)));
1181 dc
.DrawRectangle(r
);
1183 dc
.GradientFillLinear(r
, wxColour(0,255,0), wxColour(0,0,0), wxNORTH
);
1184 dc
.DrawRectangle(r2
);
1186 dc
.GradientFillLinear(r2
, wxColour(0,0,0), wxColour(0,255,0), wxSOUTH
);
1187 dc
.DrawRectangle(r3
);
1189 dc
.GradientFillLinear(r3
, wxColour(0,255,0), wxColour(0,0,0), wxEAST
);
1190 dc
.DrawRectangle(r4
);
1192 dc
.GradientFillLinear(r4
, wxColour(0,0,0), wxColour(0,255,0), wxWEST
);
1195 void MyCanvas::DrawRegions(wxDC
& dc
)
1197 dc
.DrawText(_T("You should see a red rect partly covered by a cyan one ")
1198 _T("on the left"), 10, 5);
1199 dc
.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
1200 10, 5 + dc
.GetCharHeight());
1201 dc
.DrawText(_T("The second copy should be identical but right part of it ")
1202 _T("should be offset by 10 pixels."),
1203 10, 5 + 2*dc
.GetCharHeight());
1205 DrawRegionsHelper(dc
, 10, true);
1206 DrawRegionsHelper(dc
, 350, false);
1209 void MyCanvas::DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
)
1213 dc
.DestroyClippingRegion();
1214 dc
.SetBrush( *wxWHITE_BRUSH
);
1215 dc
.SetPen( *wxTRANSPARENT_PEN
);
1216 dc
.DrawRectangle( x
, y
, 310, 310 );
1218 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 270 );
1220 dc
.SetBrush( *wxRED_BRUSH
);
1221 dc
.DrawRectangle( x
, y
, 310, 310 );
1223 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 100 );
1225 dc
.SetBrush( *wxCYAN_BRUSH
);
1226 dc
.DrawRectangle( x
, y
, 310, 310 );
1228 dc
.DestroyClippingRegion();
1230 wxRegion
region(x
+ 110, y
+ 20, 100, 270);
1231 #if !defined(__WXMOTIF__) && !defined(__WXMAC__)
1233 region
.Offset(10, 10);
1235 dc
.SetClippingRegion(region
);
1237 dc
.SetBrush( *wxGREY_BRUSH
);
1238 dc
.DrawRectangle( x
, y
, 310, 310 );
1240 if (m_smile_bmp
.Ok())
1242 dc
.DrawBitmap( m_smile_bmp
, x
+ 150, y
+ 150, true );
1243 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 10, true );
1244 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 280, true );
1245 dc
.DrawBitmap( m_smile_bmp
, x
+ 100, y
+ 70, true );
1246 dc
.DrawBitmap( m_smile_bmp
, x
+ 200, y
+ 70, true );
1250 void MyCanvas::OnPaint(wxPaintEvent
&WXUNUSED(event
))
1252 wxPaintDC
pdc(this);
1254 #if wxUSE_GRAPHICS_CONTEXT
1256 wxDC
&dc
= m_useContext
? (wxDC
&) gdc
: (wxDC
&) pdc
;
1263 m_owner
->PrepareDC(dc
);
1265 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
1266 if ( m_owner
->m_backgroundBrush
.Ok() )
1267 dc
.SetBackground( m_owner
->m_backgroundBrush
);
1268 if ( m_owner
->m_colourForeground
.Ok() )
1269 dc
.SetTextForeground( m_owner
->m_colourForeground
);
1270 if ( m_owner
->m_colourBackground
.Ok() )
1271 dc
.SetTextBackground( m_owner
->m_colourBackground
);
1273 if ( m_owner
->m_textureBackground
) {
1274 if ( ! m_owner
->m_backgroundBrush
.Ok() ) {
1275 wxColour
clr(0,128,0);
1276 wxBrush
b(clr
, wxSOLID
);
1277 dc
.SetBackground(b
);
1282 dc
.SetClippingRegion(100, 100, 100, 100);
1286 if ( m_owner
->m_textureBackground
)
1288 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
1289 for ( int i
= 0; i
< 200; i
++ )
1290 dc
.DrawLine(0, i
*10, i
*10, 0);
1316 DrawTestLines( 0, 100, 0, dc
);
1317 DrawTestLines( 0, 320, 1, dc
);
1318 DrawTestLines( 0, 540, 2, dc
);
1319 DrawTestLines( 0, 760, 6, dc
);
1323 DrawTestBrushes(dc
);
1331 DrawImages(dc
, Draw_Normal
);
1334 case Show_Mask_Stretch
:
1335 DrawImages(dc
, Draw_Stretch
);
1339 DrawWithLogicalOps(dc
);
1342 #if wxUSE_GRAPHICS_CONTEXT
1357 void MyCanvas::OnMouseMove(wxMouseEvent
&event
)
1360 wxClientDC
dc(this);
1362 m_owner
->PrepareDC(dc
);
1364 wxPoint pos
= event
.GetPosition();
1365 long x
= dc
.DeviceToLogicalX( pos
.x
);
1366 long y
= dc
.DeviceToLogicalY( pos
.y
);
1368 str
.Printf( wxT("Current mouse position: %d,%d"), (int)x
, (int)y
);
1369 m_owner
->SetStatusText( str
);
1372 #endif // wxUSE_STATUSBAR
1375 // ----------------------------------------------------------------------------
1377 // ----------------------------------------------------------------------------
1379 // the event tables connect the wxWidgets events with the functions (event
1380 // handlers) which process them. It can be also done at run-time, but for the
1381 // simple menu events like this the static method is much simpler.
1382 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
1383 EVT_MENU (File_Quit
, MyFrame::OnQuit
)
1384 EVT_MENU (File_About
, MyFrame::OnAbout
)
1385 EVT_MENU (File_Clip
, MyFrame::OnClip
)
1386 #if wxUSE_GRAPHICS_CONTEXT
1387 EVT_MENU (File_GraphicContext
, MyFrame::OnGraphicContext
)
1390 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame::OnShow
)
1392 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame::OnOption
)
1395 // frame constructor
1396 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
1397 : wxFrame((wxFrame
*)NULL
, wxID_ANY
, title
, pos
, size
,
1398 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
1400 // set the frame icon
1401 SetIcon(wxICON(mondrian
));
1403 wxMenu
*menuFile
= new wxMenu
;
1404 menuFile
->Append(File_ShowDefault
, _T("&Default screen\tF1"));
1405 menuFile
->Append(File_ShowText
, _T("&Text screen\tF2"));
1406 menuFile
->Append(File_ShowLines
, _T("&Lines screen\tF3"));
1407 menuFile
->Append(File_ShowBrushes
, _T("&Brushes screen\tF4"));
1408 menuFile
->Append(File_ShowPolygons
, _T("&Polygons screen\tF5"));
1409 menuFile
->Append(File_ShowMask
, _T("&Mask screen\tF6"));
1410 menuFile
->Append(File_ShowMaskStretch
, _T("1/&2 scaled mask\tShift-F6"));
1411 menuFile
->Append(File_ShowOps
, _T("&ROP screen\tF7"));
1412 menuFile
->Append(File_ShowRegions
, _T("Re&gions screen\tF8"));
1413 menuFile
->Append(File_ShowCircles
, _T("&Circles screen\tF9"));
1414 #if wxUSE_GRAPHICS_CONTEXT
1415 menuFile
->Append(File_ShowAlpha
, _T("&Alpha screen\tF10"));
1417 menuFile
->Append(File_ShowSplines
, _T("&Splines screen\tF11"));
1418 menuFile
->Append(File_ShowGradients
, _T("&Gradients screen\tF12"));
1419 menuFile
->AppendSeparator();
1420 menuFile
->AppendCheckItem(File_Clip
, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
1421 #if wxUSE_GRAPHICS_CONTEXT
1422 menuFile
->AppendCheckItem(File_GraphicContext
, _T("&Use GraphicContext\tCtrl-Y"), _T("Use GraphicContext"));
1424 menuFile
->AppendSeparator();
1425 menuFile
->Append(File_About
, _T("&About...\tCtrl-A"), _T("Show about dialog"));
1426 menuFile
->AppendSeparator();
1427 menuFile
->Append(File_Quit
, _T("E&xit\tAlt-X"), _T("Quit this program"));
1429 wxMenu
*menuMapMode
= new wxMenu
;
1430 menuMapMode
->Append( MapMode_Text
, _T("&TEXT map mode") );
1431 menuMapMode
->Append( MapMode_Lometric
, _T("&LOMETRIC map mode") );
1432 menuMapMode
->Append( MapMode_Twips
, _T("T&WIPS map mode") );
1433 menuMapMode
->Append( MapMode_Points
, _T("&POINTS map mode") );
1434 menuMapMode
->Append( MapMode_Metric
, _T("&METRIC map mode") );
1436 wxMenu
*menuUserScale
= new wxMenu
;
1437 menuUserScale
->Append( UserScale_StretchHoriz
, _T("Stretch &horizontally\tCtrl-H") );
1438 menuUserScale
->Append( UserScale_ShrinkHoriz
, _T("Shrin&k horizontally\tCtrl-G") );
1439 menuUserScale
->Append( UserScale_StretchVertic
, _T("Stretch &vertically\tCtrl-V") );
1440 menuUserScale
->Append( UserScale_ShrinkVertic
, _T("&Shrink vertically\tCtrl-W") );
1441 menuUserScale
->AppendSeparator();
1442 menuUserScale
->Append( UserScale_Restore
, _T("&Restore to normal\tCtrl-0") );
1444 wxMenu
*menuAxis
= new wxMenu
;
1445 menuAxis
->AppendCheckItem( AxisMirror_Horiz
, _T("Mirror horizontally\tCtrl-M") );
1446 menuAxis
->AppendCheckItem( AxisMirror_Vertic
, _T("Mirror vertically\tCtrl-N") );
1448 wxMenu
*menuLogical
= new wxMenu
;
1449 menuLogical
->Append( LogicalOrigin_MoveDown
, _T("Move &down\tCtrl-D") );
1450 menuLogical
->Append( LogicalOrigin_MoveUp
, _T("Move &up\tCtrl-U") );
1451 menuLogical
->Append( LogicalOrigin_MoveLeft
, _T("Move &right\tCtrl-L") );
1452 menuLogical
->Append( LogicalOrigin_MoveRight
, _T("Move &left\tCtrl-R") );
1453 menuLogical
->AppendSeparator();
1454 menuLogical
->Append( LogicalOrigin_Set
, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1455 menuLogical
->Append( LogicalOrigin_Restore
, _T("&Restore to normal\tShift-Ctrl-0") );
1457 wxMenu
*menuColour
= new wxMenu
;
1459 menuColour
->Append( Colour_TextForeground
, _T("Text &foreground...") );
1460 menuColour
->Append( Colour_TextBackground
, _T("Text &background...") );
1461 menuColour
->Append( Colour_Background
, _T("Background &colour...") );
1462 #endif // wxUSE_COLOURDLG
1463 menuColour
->AppendCheckItem( Colour_BackgroundMode
, _T("&Opaque/transparent\tCtrl-B") );
1464 menuColour
->AppendCheckItem( Colour_TextureBackgound
, _T("Draw textured back&ground\tCtrl-T") );
1466 // now append the freshly created menu to the menu bar...
1467 wxMenuBar
*menuBar
= new wxMenuBar
;
1468 menuBar
->Append(menuFile
, _T("&File"));
1469 menuBar
->Append(menuMapMode
, _T("&Mode"));
1470 menuBar
->Append(menuUserScale
, _T("&Scale"));
1471 menuBar
->Append(menuAxis
, _T("&Axis"));
1472 menuBar
->Append(menuLogical
, _T("&Origin"));
1473 menuBar
->Append(menuColour
, _T("&Colours"));
1475 // ... and attach this menu bar to the frame
1476 SetMenuBar(menuBar
);
1480 SetStatusText(_T("Welcome to wxWidgets!"));
1481 #endif // wxUSE_STATUSBAR
1483 m_mapMode
= wxMM_TEXT
;
1486 m_xLogicalOrigin
= 0;
1487 m_yLogicalOrigin
= 0;
1489 m_yAxisReversed
= false;
1490 m_backgroundMode
= wxSOLID
;
1491 m_colourForeground
= *wxRED
;
1492 m_colourBackground
= *wxBLUE
;
1493 m_textureBackground
= false;
1495 m_canvas
= new MyCanvas( this );
1496 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1501 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1503 // true is to force the frame to close
1507 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1510 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1511 wxT("This sample tests various primitive drawing functions\n")
1512 wxT("(without any attempts to prevent flicker).\n")
1513 wxT("Copyright (c) Robert Roebling 1999")
1516 wxMessageBox(msg
, _T("About Drawing"), wxOK
| wxICON_INFORMATION
, this);
1519 void MyFrame::OnClip(wxCommandEvent
& event
)
1521 m_canvas
->Clip(event
.IsChecked());
1524 #if wxUSE_GRAPHICS_CONTEXT
1525 void MyFrame::OnGraphicContext(wxCommandEvent
& event
)
1527 m_canvas
->UseGraphicContext(event
.IsChecked());
1531 void MyFrame::OnShow(wxCommandEvent
& event
)
1533 m_canvas
->ToShow((ScreenToShow
)(event
.GetId() - MenuShow_First
));
1536 void MyFrame::OnOption(wxCommandEvent
& event
)
1538 switch (event
.GetId())
1541 m_mapMode
= wxMM_TEXT
;
1543 case MapMode_Lometric
:
1544 m_mapMode
= wxMM_LOMETRIC
;
1547 m_mapMode
= wxMM_TWIPS
;
1549 case MapMode_Points
:
1550 m_mapMode
= wxMM_POINTS
;
1552 case MapMode_Metric
:
1553 m_mapMode
= wxMM_METRIC
;
1556 case LogicalOrigin_MoveDown
:
1557 m_yLogicalOrigin
+= 10;
1559 case LogicalOrigin_MoveUp
:
1560 m_yLogicalOrigin
-= 10;
1562 case LogicalOrigin_MoveLeft
:
1563 m_xLogicalOrigin
+= 10;
1565 case LogicalOrigin_MoveRight
:
1566 m_xLogicalOrigin
-= 10;
1568 case LogicalOrigin_Set
:
1570 m_yLogicalOrigin
= -100;
1572 case LogicalOrigin_Restore
:
1574 m_yLogicalOrigin
= 0;
1577 case UserScale_StretchHoriz
:
1578 m_xUserScale
*= 1.10;
1580 case UserScale_ShrinkHoriz
:
1581 m_xUserScale
/= 1.10;
1583 case UserScale_StretchVertic
:
1584 m_yUserScale
*= 1.10;
1586 case UserScale_ShrinkVertic
:
1587 m_yUserScale
/= 1.10;
1589 case UserScale_Restore
:
1594 case AxisMirror_Vertic
:
1595 m_yAxisReversed
= !m_yAxisReversed
;
1597 case AxisMirror_Horiz
:
1598 m_xAxisReversed
= !m_xAxisReversed
;
1602 case Colour_TextForeground
:
1603 m_colourForeground
= SelectColour();
1605 case Colour_TextBackground
:
1606 m_colourBackground
= SelectColour();
1608 case Colour_Background
:
1610 wxColour col
= SelectColour();
1613 m_backgroundBrush
.SetColour(col
);
1617 #endif // wxUSE_COLOURDLG
1619 case Colour_BackgroundMode
:
1620 m_backgroundMode
= m_backgroundMode
== wxSOLID
? wxTRANSPARENT
1624 case Colour_TextureBackgound
:
1625 m_textureBackground
= ! m_textureBackground
;
1633 m_canvas
->Refresh();
1636 void MyFrame::PrepareDC(wxDC
& dc
)
1638 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
1639 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
1640 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
1641 dc
.SetMapMode( m_mapMode
);
1645 wxColour
MyFrame::SelectColour()
1649 wxColourDialog
dialog(this, &data
);
1651 if ( dialog
.ShowModal() == wxID_OK
)
1653 col
= dialog
.GetColourData().GetColour();
1658 #endif // wxUSE_COLOURDLG