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
));
1164 void MyCanvas::DrawRegions(wxDC
& dc
)
1166 dc
.DrawText(_T("You should see a red rect partly covered by a cyan one ")
1167 _T("on the left"), 10, 5);
1168 dc
.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
1169 10, 5 + dc
.GetCharHeight());
1170 dc
.DrawText(_T("The second copy should be identical but right part of it ")
1171 _T("should be offset by 10 pixels."),
1172 10, 5 + 2*dc
.GetCharHeight());
1174 DrawRegionsHelper(dc
, 10, true);
1175 DrawRegionsHelper(dc
, 350, false);
1178 void MyCanvas::DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
)
1182 dc
.DestroyClippingRegion();
1183 dc
.SetBrush( *wxWHITE_BRUSH
);
1184 dc
.SetPen( *wxTRANSPARENT_PEN
);
1185 dc
.DrawRectangle( x
, y
, 310, 310 );
1187 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 270 );
1189 dc
.SetBrush( *wxRED_BRUSH
);
1190 dc
.DrawRectangle( x
, y
, 310, 310 );
1192 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 100 );
1194 dc
.SetBrush( *wxCYAN_BRUSH
);
1195 dc
.DrawRectangle( x
, y
, 310, 310 );
1197 dc
.DestroyClippingRegion();
1199 wxRegion
region(x
+ 110, y
+ 20, 100, 270);
1200 #if !defined(__WXMOTIF__) && !defined(__WXMAC__)
1202 region
.Offset(10, 10);
1204 dc
.SetClippingRegion(region
);
1206 dc
.SetBrush( *wxGREY_BRUSH
);
1207 dc
.DrawRectangle( x
, y
, 310, 310 );
1209 if (m_smile_bmp
.Ok())
1211 dc
.DrawBitmap( m_smile_bmp
, x
+ 150, y
+ 150, true );
1212 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 10, true );
1213 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 280, true );
1214 dc
.DrawBitmap( m_smile_bmp
, x
+ 100, y
+ 70, true );
1215 dc
.DrawBitmap( m_smile_bmp
, x
+ 200, y
+ 70, true );
1219 void MyCanvas::OnPaint(wxPaintEvent
&WXUNUSED(event
))
1221 wxPaintDC
pdc(this);
1223 #if wxUSE_GRAPHICS_CONTEXT
1225 wxDC
&dc
= m_useContext
? (wxDC
&) gdc
: (wxDC
&) pdc
;
1232 m_owner
->PrepareDC(dc
);
1234 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
1235 if ( m_owner
->m_backgroundBrush
.Ok() )
1236 dc
.SetBackground( m_owner
->m_backgroundBrush
);
1237 if ( m_owner
->m_colourForeground
.Ok() )
1238 dc
.SetTextForeground( m_owner
->m_colourForeground
);
1239 if ( m_owner
->m_colourBackground
.Ok() )
1240 dc
.SetTextBackground( m_owner
->m_colourBackground
);
1242 if ( m_owner
->m_textureBackground
) {
1243 if ( ! m_owner
->m_backgroundBrush
.Ok() ) {
1244 wxColour
clr(0,128,0);
1245 wxBrush
b(clr
, wxSOLID
);
1246 dc
.SetBackground(b
);
1251 dc
.SetClippingRegion(100, 100, 100, 100);
1255 if ( m_owner
->m_textureBackground
)
1257 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
1258 for ( int i
= 0; i
< 200; i
++ )
1259 dc
.DrawLine(0, i
*10, i
*10, 0);
1285 DrawTestLines( 0, 100, 0, dc
);
1286 DrawTestLines( 0, 320, 1, dc
);
1287 DrawTestLines( 0, 540, 2, dc
);
1288 DrawTestLines( 0, 760, 6, dc
);
1292 DrawTestBrushes(dc
);
1300 DrawImages(dc
, Draw_Normal
);
1303 case Show_Mask_Stretch
:
1304 DrawImages(dc
, Draw_Stretch
);
1308 DrawWithLogicalOps(dc
);
1311 #if wxUSE_GRAPHICS_CONTEXT
1326 void MyCanvas::OnMouseMove(wxMouseEvent
&event
)
1329 wxClientDC
dc(this);
1331 m_owner
->PrepareDC(dc
);
1333 wxPoint pos
= event
.GetPosition();
1334 long x
= dc
.DeviceToLogicalX( pos
.x
);
1335 long y
= dc
.DeviceToLogicalY( pos
.y
);
1337 str
.Printf( wxT("Current mouse position: %d,%d"), (int)x
, (int)y
);
1338 m_owner
->SetStatusText( str
);
1341 #endif // wxUSE_STATUSBAR
1344 // ----------------------------------------------------------------------------
1346 // ----------------------------------------------------------------------------
1348 // the event tables connect the wxWidgets events with the functions (event
1349 // handlers) which process them. It can be also done at run-time, but for the
1350 // simple menu events like this the static method is much simpler.
1351 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
1352 EVT_MENU (File_Quit
, MyFrame::OnQuit
)
1353 EVT_MENU (File_About
, MyFrame::OnAbout
)
1354 EVT_MENU (File_Clip
, MyFrame::OnClip
)
1355 #if wxUSE_GRAPHICS_CONTEXT
1356 EVT_MENU (File_GraphicContext
, MyFrame::OnGraphicContext
)
1359 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame::OnShow
)
1361 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame::OnOption
)
1364 // frame constructor
1365 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
1366 : wxFrame((wxFrame
*)NULL
, wxID_ANY
, title
, pos
, size
,
1367 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
1369 // set the frame icon
1370 SetIcon(wxICON(mondrian
));
1372 wxMenu
*menuFile
= new wxMenu
;
1373 menuFile
->Append(File_ShowDefault
, _T("&Default screen\tF1"));
1374 menuFile
->Append(File_ShowText
, _T("&Text screen\tF2"));
1375 menuFile
->Append(File_ShowLines
, _T("&Lines screen\tF3"));
1376 menuFile
->Append(File_ShowBrushes
, _T("&Brushes screen\tF4"));
1377 menuFile
->Append(File_ShowPolygons
, _T("&Polygons screen\tF5"));
1378 menuFile
->Append(File_ShowMask
, _T("&Mask screen\tF6"));
1379 menuFile
->Append(File_ShowMaskStretch
, _T("1/&2 scaled mask\tShift-F6"));
1380 menuFile
->Append(File_ShowOps
, _T("&ROP screen\tF7"));
1381 menuFile
->Append(File_ShowRegions
, _T("Re&gions screen\tF8"));
1382 menuFile
->Append(File_ShowCircles
, _T("&Circles screen\tF9"));
1383 #if wxUSE_GRAPHICS_CONTEXT
1384 menuFile
->Append(File_ShowAlpha
, _T("&Alpha screen\tF10"));
1386 menuFile
->Append(File_ShowSplines
, _T("&Splines screen\tF11"));
1387 menuFile
->Append(File_ShowGradients
, _T("&Gradients screen\tF12"));
1388 menuFile
->AppendSeparator();
1389 menuFile
->AppendCheckItem(File_Clip
, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
1390 #if wxUSE_GRAPHICS_CONTEXT
1391 menuFile
->AppendCheckItem(File_GraphicContext
, _T("&Use GraphicContext\tCtrl-Y"), _T("Use GraphicContext"));
1393 menuFile
->AppendSeparator();
1394 menuFile
->Append(File_About
, _T("&About...\tCtrl-A"), _T("Show about dialog"));
1395 menuFile
->AppendSeparator();
1396 menuFile
->Append(File_Quit
, _T("E&xit\tAlt-X"), _T("Quit this program"));
1398 wxMenu
*menuMapMode
= new wxMenu
;
1399 menuMapMode
->Append( MapMode_Text
, _T("&TEXT map mode") );
1400 menuMapMode
->Append( MapMode_Lometric
, _T("&LOMETRIC map mode") );
1401 menuMapMode
->Append( MapMode_Twips
, _T("T&WIPS map mode") );
1402 menuMapMode
->Append( MapMode_Points
, _T("&POINTS map mode") );
1403 menuMapMode
->Append( MapMode_Metric
, _T("&METRIC map mode") );
1405 wxMenu
*menuUserScale
= new wxMenu
;
1406 menuUserScale
->Append( UserScale_StretchHoriz
, _T("Stretch &horizontally\tCtrl-H") );
1407 menuUserScale
->Append( UserScale_ShrinkHoriz
, _T("Shrin&k horizontally\tCtrl-G") );
1408 menuUserScale
->Append( UserScale_StretchVertic
, _T("Stretch &vertically\tCtrl-V") );
1409 menuUserScale
->Append( UserScale_ShrinkVertic
, _T("&Shrink vertically\tCtrl-W") );
1410 menuUserScale
->AppendSeparator();
1411 menuUserScale
->Append( UserScale_Restore
, _T("&Restore to normal\tCtrl-0") );
1413 wxMenu
*menuAxis
= new wxMenu
;
1414 menuAxis
->AppendCheckItem( AxisMirror_Horiz
, _T("Mirror horizontally\tCtrl-M") );
1415 menuAxis
->AppendCheckItem( AxisMirror_Vertic
, _T("Mirror vertically\tCtrl-N") );
1417 wxMenu
*menuLogical
= new wxMenu
;
1418 menuLogical
->Append( LogicalOrigin_MoveDown
, _T("Move &down\tCtrl-D") );
1419 menuLogical
->Append( LogicalOrigin_MoveUp
, _T("Move &up\tCtrl-U") );
1420 menuLogical
->Append( LogicalOrigin_MoveLeft
, _T("Move &right\tCtrl-L") );
1421 menuLogical
->Append( LogicalOrigin_MoveRight
, _T("Move &left\tCtrl-R") );
1422 menuLogical
->AppendSeparator();
1423 menuLogical
->Append( LogicalOrigin_Set
, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1424 menuLogical
->Append( LogicalOrigin_Restore
, _T("&Restore to normal\tShift-Ctrl-0") );
1426 wxMenu
*menuColour
= new wxMenu
;
1428 menuColour
->Append( Colour_TextForeground
, _T("Text &foreground...") );
1429 menuColour
->Append( Colour_TextBackground
, _T("Text &background...") );
1430 menuColour
->Append( Colour_Background
, _T("Background &colour...") );
1431 #endif // wxUSE_COLOURDLG
1432 menuColour
->AppendCheckItem( Colour_BackgroundMode
, _T("&Opaque/transparent\tCtrl-B") );
1433 menuColour
->AppendCheckItem( Colour_TextureBackgound
, _T("Draw textured back&ground\tCtrl-T") );
1435 // now append the freshly created menu to the menu bar...
1436 wxMenuBar
*menuBar
= new wxMenuBar
;
1437 menuBar
->Append(menuFile
, _T("&File"));
1438 menuBar
->Append(menuMapMode
, _T("&Mode"));
1439 menuBar
->Append(menuUserScale
, _T("&Scale"));
1440 menuBar
->Append(menuAxis
, _T("&Axis"));
1441 menuBar
->Append(menuLogical
, _T("&Origin"));
1442 menuBar
->Append(menuColour
, _T("&Colours"));
1444 // ... and attach this menu bar to the frame
1445 SetMenuBar(menuBar
);
1449 SetStatusText(_T("Welcome to wxWidgets!"));
1450 #endif // wxUSE_STATUSBAR
1452 m_mapMode
= wxMM_TEXT
;
1455 m_xLogicalOrigin
= 0;
1456 m_yLogicalOrigin
= 0;
1458 m_yAxisReversed
= false;
1459 m_backgroundMode
= wxSOLID
;
1460 m_colourForeground
= *wxRED
;
1461 m_colourBackground
= *wxBLUE
;
1462 m_textureBackground
= false;
1464 m_canvas
= new MyCanvas( this );
1465 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1470 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1472 // true is to force the frame to close
1476 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1479 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1480 wxT("This sample tests various primitive drawing functions\n")
1481 wxT("(without any attempts to prevent flicker).\n")
1482 wxT("Copyright (c) Robert Roebling 1999")
1485 wxMessageBox(msg
, _T("About Drawing"), wxOK
| wxICON_INFORMATION
, this);
1488 void MyFrame::OnClip(wxCommandEvent
& event
)
1490 m_canvas
->Clip(event
.IsChecked());
1493 #if wxUSE_GRAPHICS_CONTEXT
1494 void MyFrame::OnGraphicContext(wxCommandEvent
& event
)
1496 m_canvas
->UseGraphicContext(event
.IsChecked());
1500 void MyFrame::OnShow(wxCommandEvent
& event
)
1502 m_canvas
->ToShow((ScreenToShow
)(event
.GetId() - MenuShow_First
));
1505 void MyFrame::OnOption(wxCommandEvent
& event
)
1507 switch (event
.GetId())
1510 m_mapMode
= wxMM_TEXT
;
1512 case MapMode_Lometric
:
1513 m_mapMode
= wxMM_LOMETRIC
;
1516 m_mapMode
= wxMM_TWIPS
;
1518 case MapMode_Points
:
1519 m_mapMode
= wxMM_POINTS
;
1521 case MapMode_Metric
:
1522 m_mapMode
= wxMM_METRIC
;
1525 case LogicalOrigin_MoveDown
:
1526 m_yLogicalOrigin
+= 10;
1528 case LogicalOrigin_MoveUp
:
1529 m_yLogicalOrigin
-= 10;
1531 case LogicalOrigin_MoveLeft
:
1532 m_xLogicalOrigin
+= 10;
1534 case LogicalOrigin_MoveRight
:
1535 m_xLogicalOrigin
-= 10;
1537 case LogicalOrigin_Set
:
1539 m_yLogicalOrigin
= -100;
1541 case LogicalOrigin_Restore
:
1543 m_yLogicalOrigin
= 0;
1546 case UserScale_StretchHoriz
:
1547 m_xUserScale
*= 1.10;
1549 case UserScale_ShrinkHoriz
:
1550 m_xUserScale
/= 1.10;
1552 case UserScale_StretchVertic
:
1553 m_yUserScale
*= 1.10;
1555 case UserScale_ShrinkVertic
:
1556 m_yUserScale
/= 1.10;
1558 case UserScale_Restore
:
1563 case AxisMirror_Vertic
:
1564 m_yAxisReversed
= !m_yAxisReversed
;
1566 case AxisMirror_Horiz
:
1567 m_xAxisReversed
= !m_xAxisReversed
;
1571 case Colour_TextForeground
:
1572 m_colourForeground
= SelectColour();
1574 case Colour_TextBackground
:
1575 m_colourBackground
= SelectColour();
1577 case Colour_Background
:
1579 wxColour col
= SelectColour();
1582 m_backgroundBrush
.SetColour(col
);
1586 #endif // wxUSE_COLOURDLG
1588 case Colour_BackgroundMode
:
1589 m_backgroundMode
= m_backgroundMode
== wxSOLID
? wxTRANSPARENT
1593 case Colour_TextureBackgound
:
1594 m_textureBackground
= ! m_textureBackground
;
1602 m_canvas
->Refresh();
1605 void MyFrame::PrepareDC(wxDC
& dc
)
1607 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
1608 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
1609 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
1610 dc
.SetMapMode( m_mapMode
);
1614 wxColour
MyFrame::SelectColour()
1618 wxColourDialog
dialog(this, &data
);
1620 if ( dialog
.ShowModal() == wxID_OK
)
1622 col
= dialog
.GetColourData().GetColour();
1627 #endif // wxUSE_COLOURDLG