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)
77 #if wxUSE_GRAPHICS_CONTEXT
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 static wxBitmap
*gs_bmpNoMask
= NULL
,
89 *gs_bmpWithColMask
= NULL
,
91 *gs_bmpWithMask
= NULL
,
96 // ----------------------------------------------------------------------------
98 // ----------------------------------------------------------------------------
100 // Define a new application type, each program should derive a class from wxApp
101 class MyApp
: public wxApp
104 // override base class virtuals
105 // ----------------------------
107 // this one is called on application startup and is a good place for the app
108 // initialization (doing it here and not in the ctor allows to have an error
109 // return: if OnInit() returns false, the application terminates)
110 virtual bool OnInit();
112 virtual int OnExit() { DeleteBitmaps(); return 0; }
115 void DeleteBitmaps();
122 // Define a new frame type: this is going to be our main frame
123 class MyFrame
: public wxFrame
127 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
129 // event handlers (these functions should _not_ be virtual)
130 void OnQuit(wxCommandEvent
& event
);
131 void OnAbout(wxCommandEvent
& event
);
132 void OnClip(wxCommandEvent
& event
);
133 #if wxUSE_GRAPHICS_CONTEXT
134 void OnGraphicContext(wxCommandEvent
& event
);
136 void OnShow(wxCommandEvent
&event
);
137 void OnOption(wxCommandEvent
&event
);
140 wxColour
SelectColour();
141 #endif // wxUSE_COLOURDLG
142 void PrepareDC(wxDC
& dc
);
144 int m_backgroundMode
;
145 int m_textureBackground
;
149 int m_xLogicalOrigin
;
150 int m_yLogicalOrigin
;
151 bool m_xAxisReversed
,
153 wxColour m_colourForeground
, // these are _text_ colours
155 wxBrush m_backgroundBrush
;
159 // any class wishing to process wxWidgets events must use this macro
160 DECLARE_EVENT_TABLE()
163 // define a scrollable canvas for drawing onto
164 class MyCanvas
: public wxScrolledWindow
167 MyCanvas( MyFrame
*parent
);
169 void OnPaint(wxPaintEvent
&event
);
170 void OnMouseMove(wxMouseEvent
&event
);
172 void ToShow(ScreenToShow show
) { m_show
= show
; Refresh(); }
174 // set or remove the clipping region
175 void Clip(bool clip
) { m_clip
= clip
; Refresh(); }
176 #if wxUSE_GRAPHICS_CONTEXT
177 void UseGraphicContext(bool use
) { m_useContext
= use
; Refresh(); }
181 void DrawTestLines( int x
, int y
, int width
, wxDC
&dc
);
182 void DrawTestPoly(wxDC
& dc
);
183 void DrawTestBrushes(wxDC
& dc
);
184 void DrawText(wxDC
& dc
);
185 void DrawImages(wxDC
& dc
);
186 void DrawWithLogicalOps(wxDC
& dc
);
187 #if wxUSE_GRAPHICS_CONTEXT
188 void DrawAlpha(wxDC
& dc
);
190 void DrawRegions(wxDC
& dc
);
191 void DrawCircles(wxDC
& dc
);
192 void DrawSplines(wxDC
& dc
);
193 void DrawDefault(wxDC
& dc
);
194 void DrawGradients(wxDC
& dc
);
196 void DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
);
202 wxBitmap m_smile_bmp
;
205 #if wxUSE_GRAPHICS_CONTEXT
209 DECLARE_EVENT_TABLE()
212 // ----------------------------------------------------------------------------
214 // ----------------------------------------------------------------------------
216 // IDs for the controls and the menu commands
220 File_Quit
= wxID_EXIT
,
221 File_About
= wxID_ABOUT
,
223 MenuShow_First
= wxID_HIGHEST
,
224 File_ShowDefault
= MenuShow_First
,
234 #if wxUSE_GRAPHICS_CONTEXT
238 MenuShow_Last
= File_ShowGradients
,
241 #if wxUSE_GRAPHICS_CONTEXT
247 MapMode_Text
= MenuOption_First
,
253 UserScale_StretchHoriz
,
254 UserScale_ShrinkHoriz
,
255 UserScale_StretchVertic
,
256 UserScale_ShrinkVertic
,
262 LogicalOrigin_MoveDown
,
263 LogicalOrigin_MoveUp
,
264 LogicalOrigin_MoveLeft
,
265 LogicalOrigin_MoveRight
,
267 LogicalOrigin_Restore
,
270 Colour_TextForeground
,
271 Colour_TextBackground
,
273 #endif // wxUSE_COLOURDLG
274 Colour_BackgroundMode
,
275 Colour_TextureBackgound
,
277 MenuOption_Last
= Colour_TextureBackgound
280 // ----------------------------------------------------------------------------
281 // event tables and other macros for wxWidgets
282 // ----------------------------------------------------------------------------
285 // Create a new application object: this macro will allow wxWidgets to create
286 // the application object during program execution (it's better than using a
287 // static object for many reasons) and also declares the accessor function
288 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
292 // ============================================================================
294 // ============================================================================
296 // ----------------------------------------------------------------------------
297 // the application class
298 // ----------------------------------------------------------------------------
300 bool MyApp::LoadImages()
302 gs_bmpNoMask
= new wxBitmap
;
303 gs_bmpWithColMask
= new wxBitmap
;
304 gs_bmpMask
= new wxBitmap
;
305 gs_bmpWithMask
= new wxBitmap
;
306 gs_bmp4
= new wxBitmap
;
307 gs_bmp4_mono
= new wxBitmap
;
308 gs_bmp36
= new wxBitmap
;
311 pathList
.Add(_T("."));
312 pathList
.Add(_T(".."));
314 wxString path
= pathList
.FindValidPath(_T("pat4.bmp"));
318 /* 4 colour bitmap */
319 gs_bmp4
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
320 /* turn into mono-bitmap */
321 gs_bmp4_mono
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
322 wxMask
* mask4
= new wxMask(*gs_bmp4_mono
, *wxBLACK
);
323 gs_bmp4_mono
->SetMask(mask4
);
325 path
= pathList
.FindValidPath(_T("pat36.bmp"));
328 gs_bmp36
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
329 wxMask
* mask36
= new wxMask(*gs_bmp36
, *wxBLACK
);
330 gs_bmp36
->SetMask(mask36
);
332 path
= pathList
.FindValidPath(_T("image.bmp"));
335 gs_bmpNoMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
336 gs_bmpWithMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
337 gs_bmpWithColMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
339 path
= pathList
.FindValidPath(_T("mask.bmp"));
342 gs_bmpMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
344 wxMask
*mask
= new wxMask(*gs_bmpMask
, *wxBLACK
);
345 gs_bmpWithMask
->SetMask(mask
);
347 mask
= new wxMask(*gs_bmpWithColMask
, *wxWHITE
);
348 gs_bmpWithColMask
->SetMask(mask
);
353 // `Main program' equivalent: the program execution "starts" here
356 // Create the main application window
357 MyFrame
*frame
= new MyFrame(_T("Drawing sample"),
358 wxPoint(50, 50), wxSize(550, 340));
360 // Show it and tell the application that it's our main window
366 wxLogError(wxT("Can't load one of the bitmap files needed ")
367 wxT("for this sample from the current or parent ")
368 wxT("directory, please copy them there."));
380 void MyApp::DeleteBitmaps()
383 delete gs_bmpWithColMask
;
385 delete gs_bmpWithMask
;
391 gs_bmpWithColMask
= NULL
;
393 gs_bmpWithMask
= NULL
;
399 // ----------------------------------------------------------------------------
401 // ----------------------------------------------------------------------------
403 // the event tables connect the wxWidgets events with the functions (event
404 // handlers) which process them.
405 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
406 EVT_PAINT (MyCanvas::OnPaint
)
407 EVT_MOTION (MyCanvas::OnMouseMove
)
412 MyCanvas::MyCanvas(MyFrame
*parent
)
413 : wxScrolledWindow(parent
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
414 wxHSCROLL
| wxVSCROLL
| wxNO_FULL_REPAINT_ON_RESIZE
)
417 m_show
= Show_Default
;
418 m_smile_bmp
= wxBitmap(smile_xpm
);
419 m_std_icon
= wxArtProvider::GetIcon(wxART_INFORMATION
);
421 #if wxUSE_GRAPHICS_CONTEXT
422 m_useContext
= false;
426 void MyCanvas::DrawTestBrushes(wxDC
& dc
)
428 static const wxCoord WIDTH
= 200;
429 static const wxCoord HEIGHT
= 80;
434 dc
.SetBrush(wxBrush(*wxGREEN
, wxSOLID
));
435 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
436 dc
.DrawText(_T("Solid green"), x
+ 10, y
+ 10);
439 dc
.SetBrush(wxBrush(*wxRED
, wxCROSSDIAG_HATCH
));
440 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
441 dc
.DrawText(_T("Hatched red"), x
+ 10, y
+ 10);
444 dc
.SetBrush(wxBrush(*gs_bmpMask
));
445 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
446 dc
.DrawText(_T("Stipple mono"), x
+ 10, y
+ 10);
449 dc
.SetBrush(wxBrush(*gs_bmpNoMask
));
450 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
451 dc
.DrawText(_T("Stipple colour"), x
+ 10, y
+ 10);
454 void MyCanvas::DrawTestPoly(wxDC
& dc
)
456 wxBrush
brushHatch(*wxRED
, wxFDIAGONAL_HATCH
);
457 dc
.SetBrush(brushHatch
);
460 star
[0] = wxPoint(100, 60);
461 star
[1] = wxPoint(60, 150);
462 star
[2] = wxPoint(160, 100);
463 star
[3] = wxPoint(40, 100);
464 star
[4] = wxPoint(140, 150);
466 dc
.DrawText(_T("You should see two (irregular) stars below, the left one ")
467 _T("hatched"), 10, 10);
468 dc
.DrawText(_T("except for the central region and the right ")
469 _T("one entirely hatched"), 10, 30);
470 dc
.DrawText(_T("The third star only has a hatched outline"), 10, 50);
472 dc
.DrawPolygon(WXSIZEOF(star
), star
, 0, 30);
473 dc
.DrawPolygon(WXSIZEOF(star
), star
, 160, 30, wxWINDING_RULE
);
476 star2
[0] = wxPoint(0, 100);
477 star2
[1] = wxPoint(-59, -81);
478 star2
[2] = wxPoint(95, 31);
479 star2
[3] = wxPoint(-95, 31);
480 star2
[4] = wxPoint(59, -81);
481 star2
[5] = wxPoint(0, 80);
482 star2
[6] = wxPoint(-47, -64);
483 star2
[7] = wxPoint(76, 24);
484 star2
[8] = wxPoint(-76, 24);
485 star2
[9] = wxPoint(47, -64);
486 int count
[2] = {5, 5};
488 dc
.DrawPolyPolygon(WXSIZEOF(count
), count
, star2
, 450, 150);
491 void MyCanvas::DrawTestLines( int x
, int y
, int width
, wxDC
&dc
)
493 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
494 dc
.SetBrush( *wxRED_BRUSH
);
495 dc
.DrawText(wxString::Format(wxT("Testing lines of width %d"), width
), x
+ 10, y
- 10);
496 dc
.DrawRectangle( x
+10, y
+10, 100, 190 );
498 dc
.DrawText(_T("Solid/dot/short dash/long dash/dot dash"), x
+ 150, y
+ 10);
499 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
500 dc
.DrawLine( x
+20, y
+20, 100, y
+20 );
501 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT
) );
502 dc
.DrawLine( x
+20, y
+30, 100, y
+30 );
503 dc
.SetPen( wxPen( wxT("black"), width
, wxSHORT_DASH
) );
504 dc
.DrawLine( x
+20, y
+40, 100, y
+40 );
505 dc
.SetPen( wxPen( wxT("black"), width
, wxLONG_DASH
) );
506 dc
.DrawLine( x
+20, y
+50, 100, y
+50 );
507 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT_DASH
) );
508 dc
.DrawLine( x
+20, y
+60, 100, y
+60 );
510 dc
.DrawText(_T("Misc hatches"), x
+ 150, y
+ 70);
511 dc
.SetPen( wxPen( wxT("black"), width
, wxBDIAGONAL_HATCH
) );
512 dc
.DrawLine( x
+20, y
+70, 100, y
+70 );
513 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSSDIAG_HATCH
) );
514 dc
.DrawLine( x
+20, y
+80, 100, y
+80 );
515 dc
.SetPen( wxPen( wxT("black"), width
, wxFDIAGONAL_HATCH
) );
516 dc
.DrawLine( x
+20, y
+90, 100, y
+90 );
517 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSS_HATCH
) );
518 dc
.DrawLine( x
+20, y
+100, 100, y
+100 );
519 dc
.SetPen( wxPen( wxT("black"), width
, wxHORIZONTAL_HATCH
) );
520 dc
.DrawLine( x
+20, y
+110, 100, y
+110 );
521 dc
.SetPen( wxPen( wxT("black"), width
, wxVERTICAL_HATCH
) );
522 dc
.DrawLine( x
+20, y
+120, 100, y
+120 );
524 dc
.DrawText(_T("User dash"), x
+ 150, y
+ 140);
525 wxPen
ud( wxT("black"), width
, wxUSER_DASH
);
527 dash1
[0] = 8; // Long dash <---------+
528 dash1
[1] = 2; // Short gap |
529 dash1
[2] = 3; // Short dash |
530 dash1
[3] = 2; // Short gap |
531 dash1
[4] = 3; // Short dash |
532 dash1
[5] = 2; // Short gap and repeat +
533 ud
.SetDashes( 6, dash1
);
535 dc
.DrawLine( x
+20, y
+140, 100, y
+140 );
536 dash1
[0] = 5; // Make first dash shorter
537 ud
.SetDashes( 6, dash1
);
539 dc
.DrawLine( x
+20, y
+150, 100, y
+150 );
540 dash1
[2] = 5; // Make second dash longer
541 ud
.SetDashes( 6, dash1
);
543 dc
.DrawLine( x
+20, y
+160, 100, y
+160 );
544 dash1
[4] = 5; // Make third dash longer
545 ud
.SetDashes( 6, dash1
);
547 dc
.DrawLine( x
+20, y
+170, 100, y
+170 );
550 void MyCanvas::DrawDefault(wxDC
& dc
)
553 dc
.DrawCircle(0, 0, 10);
555 #if !defined(wxMAC_USE_CORE_GRAPHICS) || !wxMAC_USE_CORE_GRAPHICS
556 // GetPixel and FloodFill not supported by Mac OS X CoreGraphics
557 // (FloodFill uses Blit from a non-wxMemoryDC)
558 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
559 dc
.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID
));
562 dc
.GetPixel(1,1, &tmpColour
);
563 dc
.FloodFill(1,1, tmpColour
, wxFLOOD_SURFACE
);
566 dc
.DrawCheckMark(5, 80, 15, 15);
567 dc
.DrawCheckMark(25, 80, 30, 30);
568 dc
.DrawCheckMark(60, 80, 60, 60);
570 // this is the test for "blitting bitmap into DC damages selected brush" bug
571 wxCoord rectSize
= m_std_icon
.GetWidth() + 10;
573 dc
.SetPen(*wxTRANSPARENT_PEN
);
574 dc
.SetBrush( *wxGREEN_BRUSH
);
575 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
576 dc
.DrawBitmap(m_std_icon
, x
+ 5, 15, true);
578 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
579 dc
.DrawIcon(m_std_icon
, x
+ 5, 15);
581 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
583 // test for "transparent" bitmap drawing (it intersects with the last
585 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
587 if (m_smile_bmp
.Ok())
588 dc
.DrawBitmap(m_smile_bmp
, x
+ rectSize
- 20, rectSize
- 10, true);
590 dc
.SetBrush( *wxBLACK_BRUSH
);
591 dc
.DrawRectangle( 0, 160, 1000, 300 );
594 wxBitmap
bitmap(20,70);
596 memdc
.SelectObject( bitmap
);
597 memdc
.SetBrush( *wxBLACK_BRUSH
);
598 memdc
.SetPen( *wxWHITE_PEN
);
599 memdc
.DrawRectangle(0,0,20,70);
600 memdc
.DrawLine( 10,0,10,70 );
603 wxPen pen
= *wxRED_PEN
;
605 memdc
.DrawLine( 10, 5,10, 5 );
606 memdc
.DrawLine( 10,10,11,10 );
607 memdc
.DrawLine( 10,15,12,15 );
608 memdc
.DrawLine( 10,20,13,20 );
611 memdc.SetPen(*wxRED_PEN);
612 memdc.DrawLine( 12, 5,12, 5 );
613 memdc.DrawLine( 12,10,13,10 );
614 memdc.DrawLine( 12,15,14,15 );
615 memdc.DrawLine( 12,20,15,20 );
619 memdc
.DrawLine( 10,25,10,25 );
620 memdc
.DrawLine( 10,30, 9,30 );
621 memdc
.DrawLine( 10,35, 8,35 );
622 memdc
.DrawLine( 10,40, 7,40 );
625 dc
.SetPen(*wxWHITE_PEN
);
626 memdc
.SetLogicalFunction( wxINVERT
);
627 memdc
.SetPen( *wxWHITE_PEN
);
628 memdc
.DrawLine( 10,50,10,50 );
629 memdc
.DrawLine( 10,55,11,55 );
630 memdc
.DrawLine( 10,60,12,60 );
631 memdc
.DrawLine( 10,65,13,65 );
633 memdc
.DrawLine( 12,50,12,50 );
634 memdc
.DrawLine( 12,55,13,55 );
635 memdc
.DrawLine( 12,60,14,60 );
636 memdc
.DrawLine( 12,65,15,65 );
638 memdc
.SelectObject( wxNullBitmap
);
639 dc
.DrawBitmap( bitmap
, 10, 170 );
640 wxImage image
= bitmap
.ConvertToImage();
641 image
.Rescale( 60,210 );
642 bitmap
= wxBitmap(image
);
643 dc
.DrawBitmap( bitmap
, 50, 170 );
645 // test the rectangle outline drawing - there should be one pixel between
646 // the rect and the lines
647 dc
.SetPen(*wxWHITE_PEN
);
648 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
649 dc
.DrawRectangle(150, 170, 49, 29);
650 dc
.DrawRectangle(200, 170, 49, 29);
651 dc
.SetPen(*wxWHITE_PEN
);
652 dc
.DrawLine(250, 210, 250, 170);
653 dc
.DrawLine(260, 200, 150, 200);
655 // test the rectangle filled drawing - there should be one pixel between
656 // the rect and the lines
657 dc
.SetPen(*wxTRANSPARENT_PEN
);
658 dc
.SetBrush( *wxWHITE_BRUSH
);
659 dc
.DrawRectangle(300, 170, 49, 29);
660 dc
.DrawRectangle(350, 170, 49, 29);
661 dc
.SetPen(*wxWHITE_PEN
);
662 dc
.DrawLine(400, 170, 400, 210);
663 dc
.DrawLine(300, 200, 410, 200);
665 // a few more tests of this kind
666 dc
.SetPen(*wxRED_PEN
);
667 dc
.SetBrush( *wxWHITE_BRUSH
);
668 dc
.DrawRectangle(300, 220, 1, 1);
669 dc
.DrawRectangle(310, 220, 2, 2);
670 dc
.DrawRectangle(320, 220, 3, 3);
671 dc
.DrawRectangle(330, 220, 4, 4);
673 dc
.SetPen(*wxTRANSPARENT_PEN
);
674 dc
.SetBrush( *wxWHITE_BRUSH
);
675 dc
.DrawRectangle(300, 230, 1, 1);
676 dc
.DrawRectangle(310, 230, 2, 2);
677 dc
.DrawRectangle(320, 230, 3, 3);
678 dc
.DrawRectangle(330, 230, 4, 4);
680 // and now for filled rect with outline
681 dc
.SetPen(*wxRED_PEN
);
682 dc
.SetBrush( *wxWHITE_BRUSH
);
683 dc
.DrawRectangle(500, 170, 49, 29);
684 dc
.DrawRectangle(550, 170, 49, 29);
685 dc
.SetPen(*wxWHITE_PEN
);
686 dc
.DrawLine(600, 170, 600, 210);
687 dc
.DrawLine(500, 200, 610, 200);
689 // test the rectangle outline drawing - there should be one pixel between
690 // the rect and the lines
691 dc
.SetPen(*wxWHITE_PEN
);
692 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
693 dc
.DrawRoundedRectangle(150, 270, 49, 29, 6);
694 dc
.DrawRoundedRectangle(200, 270, 49, 29, 6);
695 dc
.SetPen(*wxWHITE_PEN
);
696 dc
.DrawLine(250, 270, 250, 310);
697 dc
.DrawLine(150, 300, 260, 300);
699 // test the rectangle filled drawing - there should be one pixel between
700 // the rect and the lines
701 dc
.SetPen(*wxTRANSPARENT_PEN
);
702 dc
.SetBrush( *wxWHITE_BRUSH
);
703 dc
.DrawRoundedRectangle(300, 270, 49, 29, 6);
704 dc
.DrawRoundedRectangle(350, 270, 49, 29, 6);
705 dc
.SetPen(*wxWHITE_PEN
);
706 dc
.DrawLine(400, 270, 400, 310);
707 dc
.DrawLine(300, 300, 410, 300);
709 // Added by JACS to demonstrate bizarre behaviour.
710 // With a size of 70, we get a missing red RHS,
711 // and the height is too small, so we get yellow
712 // showing. With a size of 40, it draws as expected:
713 // it just shows a white rectangle with red outline.
715 int totalHeight
= 70;
716 wxBitmap
bitmap2(totalWidth
, totalHeight
);
719 memdc2
.SelectObject(bitmap2
);
721 wxColour
clr(255, 255, 0);
722 wxBrush
yellowBrush(clr
, wxSOLID
);
723 memdc2
.SetBackground(yellowBrush
);
726 wxPen
yellowPen(clr
, 1, wxSOLID
);
728 // Now draw a white rectangle with red outline. It should
729 // entirely eclipse the yellow background.
730 memdc2
.SetPen(*wxRED_PEN
);
731 memdc2
.SetBrush(*wxWHITE_BRUSH
);
733 memdc2
.DrawRectangle(0, 0, totalWidth
, totalHeight
);
735 memdc2
.SetPen(wxNullPen
);
736 memdc2
.SetBrush(wxNullBrush
);
737 memdc2
.SelectObject(wxNullBitmap
);
739 dc
.DrawBitmap(bitmap2
, 500, 270);
741 // Repeat, but draw directly on dc
742 // Draw a yellow rectangle filling the bitmap
744 x
= 600; int y
= 270;
745 dc
.SetPen(yellowPen
);
746 dc
.SetBrush(yellowBrush
);
747 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
749 // Now draw a white rectangle with red outline. It should
750 // entirely eclipse the yellow background.
751 dc
.SetPen(*wxRED_PEN
);
752 dc
.SetBrush(*wxWHITE_BRUSH
);
754 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
757 void MyCanvas::DrawText(wxDC
& dc
)
759 // set underlined font for testing
760 dc
.SetFont( wxFont(12, wxMODERN
, wxNORMAL
, wxNORMAL
, true) );
761 dc
.DrawText( _T("This is text"), 110, 10 );
762 dc
.DrawRotatedText( _T("That is text"), 20, 10, -45 );
764 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
765 // under Win9x (it is not TrueType)
766 dc
.SetFont( *wxSWISS_FONT
);
769 dc
.SetBackgroundMode(wxTRANSPARENT
);
771 for ( int n
= -180; n
< 180; n
+= 30 )
773 text
.Printf(wxT(" %d rotated text"), n
);
774 dc
.DrawRotatedText(text
, 400, 400, n
);
777 dc
.SetFont( wxFont( 18, wxSWISS
, wxNORMAL
, wxNORMAL
) );
779 dc
.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
784 dc
.GetTextExtent( _T("This is Swiss 18pt text."), &length
, &height
, &descent
);
785 text
.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length
, height
, descent
);
786 dc
.DrawText( text
, 110, 80 );
788 text
.Printf( wxT("CharHeight() returns: %d"), dc
.GetCharHeight() );
789 dc
.DrawText( text
, 110, 120 );
791 dc
.DrawRectangle( 100, 40, 4, height
);
793 // test the logical function effect
795 dc
.SetLogicalFunction(wxINVERT
);
796 dc
.DrawText( _T("There should be no text below"), 110, 150 );
797 dc
.DrawRectangle( 110, y
, 100, height
);
799 // twice drawn inverted should result in invisible
801 dc
.DrawText( _T("Invisible text"), 110, y
);
802 dc
.DrawRectangle( 110, y
, 100, height
);
803 dc
.DrawText( _T("Invisible text"), 110, y
);
804 dc
.DrawRectangle( 110, y
, 100, height
);
805 dc
.SetLogicalFunction(wxCOPY
);
808 dc
.DrawRectangle( 110, y
, 100, height
);
809 dc
.DrawText( _T("Visible text"), 110, y
);
816 } rasterOperations
[] =
818 { wxT("wxAND"), wxAND
},
819 { wxT("wxAND_INVERT"), wxAND_INVERT
},
820 { wxT("wxAND_REVERSE"), wxAND_REVERSE
},
821 { wxT("wxCLEAR"), wxCLEAR
},
822 { wxT("wxCOPY"), wxCOPY
},
823 { wxT("wxEQUIV"), wxEQUIV
},
824 { wxT("wxINVERT"), wxINVERT
},
825 { wxT("wxNAND"), wxNAND
},
826 { wxT("wxNO_OP"), wxNO_OP
},
827 { wxT("wxOR"), wxOR
},
828 { wxT("wxOR_INVERT"), wxOR_INVERT
},
829 { wxT("wxOR_REVERSE"), wxOR_REVERSE
},
830 { wxT("wxSET"), wxSET
},
831 { wxT("wxSRC_INVERT"), wxSRC_INVERT
},
832 { wxT("wxXOR"), wxXOR
},
835 void MyCanvas::DrawImages(wxDC
& dc
)
837 dc
.DrawText(_T("original image"), 0, 0);
838 dc
.DrawBitmap(*gs_bmpNoMask
, 0, 20, 0);
839 dc
.DrawText(_T("with colour mask"), 0, 100);
840 dc
.DrawBitmap(*gs_bmpWithColMask
, 0, 120, true);
841 dc
.DrawText(_T("the mask image"), 0, 200);
842 dc
.DrawBitmap(*gs_bmpMask
, 0, 220, 0);
843 dc
.DrawText(_T("masked image"), 0, 300);
844 dc
.DrawBitmap(*gs_bmpWithMask
, 0, 320, true);
846 int cx
= gs_bmpWithColMask
->GetWidth(),
847 cy
= gs_bmpWithColMask
->GetHeight();
850 for ( size_t n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
852 wxCoord x
= 120 + 150*(n%4
),
855 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
856 memDC
.SelectObject(*gs_bmpWithColMask
);
857 dc
.Blit(x
, y
, cx
, cy
, &memDC
, 0, 0, rasterOperations
[n
].rop
, true);
861 void MyCanvas::DrawWithLogicalOps(wxDC
& dc
)
863 static const wxCoord w
= 60;
864 static const wxCoord h
= 60;
866 // reuse the text colour here
867 dc
.SetPen(wxPen(m_owner
->m_colourForeground
, 1, wxSOLID
));
868 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
871 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
873 wxCoord x
= 20 + 150*(n%4
),
876 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
877 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
878 dc
.DrawRectangle(x
, y
, w
, h
);
879 dc
.DrawLine(x
, y
, x
+ w
, y
+ h
);
880 dc
.DrawLine(x
+ w
, y
, x
, y
+ h
);
883 // now some filled rectangles
884 dc
.SetBrush(wxBrush(m_owner
->m_colourForeground
, wxSOLID
));
886 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
888 wxCoord x
= 20 + 150*(n%4
),
891 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
892 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
893 dc
.DrawRectangle(x
, y
, w
, h
);
897 #if wxUSE_GRAPHICS_CONTEXT
898 void MyCanvas::DrawAlpha(wxDC
& dc
)
900 wxDouble margin
= 20 ;
901 wxDouble width
= 180 ;
902 wxDouble radius
= 30 ;
904 dc
.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID
));
905 dc
.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID
));
907 wxRect
r(margin
,margin
+width
*0.66,width
,width
) ;
909 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
911 dc
.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID
));
912 dc
.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID
));
914 r
.Offset( width
* 0.8 , - width
* 0.66 ) ;
916 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
918 dc
.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID
));
919 dc
.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID
));
921 r
.Offset( width
* 0.8 , width
*0.5 ) ;
923 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
925 dc
.SetPen( *wxTRANSPARENT_PEN
) ;
926 dc
.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
927 dc
.DrawRoundedRectangle( 0 , margin
+ width
/ 2 , width
* 3 , 100 , radius
) ;
932 void MyCanvas::DrawCircles(wxDC
& dc
)
938 dc
.SetPen( *wxRED_PEN
);
939 dc
.SetBrush( *wxGREEN_BRUSH
);
941 dc
.DrawText(_T("Some circles"), 0, y
);
942 dc
.DrawCircle(x
, y
, r
);
943 dc
.DrawCircle(x
+ 2*r
, y
, r
);
944 dc
.DrawCircle(x
+ 4*r
, y
, r
);
947 dc
.DrawText(_T("And ellipses"), 0, y
);
948 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
949 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
950 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
953 dc
.DrawText(_T("And arcs"), 0, y
);
954 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
955 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
956 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
959 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
960 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
961 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
962 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
964 // same as above, just transparent brush
966 dc
.SetPen( *wxRED_PEN
);
967 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
970 dc
.DrawText(_T("Some circles"), 0, y
);
971 dc
.DrawCircle(x
, y
, r
);
972 dc
.DrawCircle(x
+ 2*r
, y
, r
);
973 dc
.DrawCircle(x
+ 4*r
, y
, r
);
976 dc
.DrawText(_T("And ellipses"), 0, y
);
977 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
978 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
979 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
982 dc
.DrawText(_T("And arcs"), 0, y
);
983 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
984 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
985 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
988 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
989 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
990 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
991 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
995 void MyCanvas::DrawSplines(wxDC
& dc
)
998 dc
.DrawText(_T("Some splines"), 10, 5);
1000 // values are hardcoded rather than randomly generated
1001 // so the output can be compared between native
1002 // implementations on platforms with different random
1006 const wxPoint
center( R
+ 20, R
+ 20 );
1007 const int angles
[7] = { 0, 10, 33, 77, 13, 145, 90 };
1008 const int radii
[5] = { 100 , 59, 85, 33, 90 };
1012 // background spline calculation
1013 unsigned int radius_pos
= 0;
1014 unsigned int angle_pos
= 0;
1016 for ( int i
= 0; i
< n
; i
++ )
1018 angle
+= angles
[ angle_pos
];
1019 int r
= R
* radii
[ radius_pos
] / 100;
1020 pts
[ i
].x
= center
.x
+ (wxCoord
)( r
* cos( M_PI
* angle
/ 180.0) );
1021 pts
[ i
].y
= center
.y
+ (wxCoord
)( r
* sin( M_PI
* angle
/ 180.0) );
1024 if ( angle_pos
>= WXSIZEOF(angles
) ) angle_pos
= 0;
1027 if ( radius_pos
>= WXSIZEOF(radii
) ) radius_pos
= 0;
1030 // background spline drawing
1031 dc
.SetPen(*wxRED_PEN
);
1032 dc
.DrawSpline(WXSIZEOF(pts
), pts
);
1034 // less detailed spline calculation
1035 wxPoint letters
[4][5];
1037 letters
[0][0] = wxPoint( 0,1); // O O
1038 letters
[0][1] = wxPoint( 1,3); // * *
1039 letters
[0][2] = wxPoint( 2,2); // * O *
1040 letters
[0][3] = wxPoint( 3,3); // * * * *
1041 letters
[0][4] = wxPoint( 4,1); // O O
1043 letters
[1][0] = wxPoint( 5,1); // O*O
1044 letters
[1][1] = wxPoint( 6,1); // *
1045 letters
[1][2] = wxPoint( 7,2); // O
1046 letters
[1][3] = wxPoint( 8,3); // *
1047 letters
[1][4] = wxPoint( 9,3); // O*O
1049 letters
[2][0] = wxPoint( 5,3); // O*O
1050 letters
[2][1] = wxPoint( 6,3); // *
1051 letters
[2][2] = wxPoint( 7,2); // O
1052 letters
[2][3] = wxPoint( 8,1); // *
1053 letters
[2][4] = wxPoint( 9,1); // O*O
1055 letters
[3][0] = wxPoint(10,0); // O O
1056 letters
[3][1] = wxPoint(11,3); // * *
1057 letters
[3][2] = wxPoint(12,1); // * O *
1058 letters
[3][3] = wxPoint(13,3); // * * * *
1059 letters
[3][4] = wxPoint(14,0); // O O
1061 const int dx
= 2 * R
/ letters
[3][4].x
;
1062 const int h
[4] = { -R
/2, 0, R
/4, R
/2 };
1064 for ( int m
= 0; m
< 4; m
++ )
1066 for ( int n
= 0; n
< 5; n
++ )
1068 letters
[m
][n
].x
= center
.x
- R
+ letters
[m
][n
].x
* dx
;
1069 letters
[m
][n
].y
= center
.y
+ h
[ letters
[m
][n
].y
];
1072 dc
.SetPen( wxPen( wxT("blue"), 1, wxDOT
) );
1073 dc
.DrawLines(5, letters
[m
]);
1074 dc
.SetPen( wxPen( wxT("black"), 4, wxSOLID
) );
1075 dc
.DrawSpline(5, letters
[m
]);
1079 dc
.DrawText(_T("Splines not supported."), 10, 5);
1083 void MyCanvas::DrawGradients(wxDC
& dc
)
1086 wxRect
r(10, 10, 100, 100);
1087 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxRIGHT
);
1090 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxLEFT
);
1093 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxDOWN
);
1096 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxUP
);
1100 r
= wxRect(200, 10, 100, 100);
1101 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
);
1104 dc
.GradientFillConcentric(r
, *wxWHITE
, *wxBLUE
);
1107 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(0, 0));
1110 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(100, 100));
1113 void MyCanvas::DrawRegions(wxDC
& dc
)
1115 dc
.DrawText(_T("You should see a red rect partly covered by a cyan one ")
1116 _T("on the left"), 10, 5);
1117 dc
.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
1118 10, 5 + dc
.GetCharHeight());
1119 dc
.DrawText(_T("The second copy should be identical but right part of it ")
1120 _T("should be offset by 10 pixels."),
1121 10, 5 + 2*dc
.GetCharHeight());
1123 DrawRegionsHelper(dc
, 10, true);
1124 DrawRegionsHelper(dc
, 350, false);
1127 void MyCanvas::DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
)
1131 dc
.DestroyClippingRegion();
1132 dc
.SetBrush( *wxWHITE_BRUSH
);
1133 dc
.SetPen( *wxTRANSPARENT_PEN
);
1134 dc
.DrawRectangle( x
, y
, 310, 310 );
1136 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 270 );
1138 dc
.SetBrush( *wxRED_BRUSH
);
1139 dc
.DrawRectangle( x
, y
, 310, 310 );
1141 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 100 );
1143 dc
.SetBrush( *wxCYAN_BRUSH
);
1144 dc
.DrawRectangle( x
, y
, 310, 310 );
1146 dc
.DestroyClippingRegion();
1148 wxRegion
region(x
+ 110, y
+ 20, 100, 270);
1149 #if !defined(__WXMOTIF__) && !defined(__WXMAC__)
1151 region
.Offset(10, 10);
1153 dc
.SetClippingRegion(region
);
1155 dc
.SetBrush( *wxGREY_BRUSH
);
1156 dc
.DrawRectangle( x
, y
, 310, 310 );
1158 if (m_smile_bmp
.Ok())
1160 dc
.DrawBitmap( m_smile_bmp
, x
+ 150, y
+ 150, true );
1161 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 10, true );
1162 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 280, true );
1163 dc
.DrawBitmap( m_smile_bmp
, x
+ 100, y
+ 70, true );
1164 dc
.DrawBitmap( m_smile_bmp
, x
+ 200, y
+ 70, true );
1168 void MyCanvas::OnPaint(wxPaintEvent
&WXUNUSED(event
))
1170 wxPaintDC
pdc(this);
1172 #if wxUSE_GRAPHICS_CONTEXT
1174 wxDC
&dc
= m_useContext
? (wxDC
&) gdc
: (wxDC
&) pdc
;
1181 m_owner
->PrepareDC(dc
);
1183 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
1184 if ( m_owner
->m_backgroundBrush
.Ok() )
1185 dc
.SetBackground( m_owner
->m_backgroundBrush
);
1186 if ( m_owner
->m_colourForeground
.Ok() )
1187 dc
.SetTextForeground( m_owner
->m_colourForeground
);
1188 if ( m_owner
->m_colourBackground
.Ok() )
1189 dc
.SetTextBackground( m_owner
->m_colourBackground
);
1191 if ( m_owner
->m_textureBackground
) {
1192 if ( ! m_owner
->m_backgroundBrush
.Ok() ) {
1193 wxColour
clr(0,128,0);
1194 wxBrush
b(clr
, wxSOLID
);
1195 dc
.SetBackground(b
);
1200 dc
.SetClippingRegion(100, 100, 100, 100);
1204 if ( m_owner
->m_textureBackground
)
1206 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
1207 for ( int i
= 0; i
< 200; i
++ )
1208 dc
.DrawLine(0, i
*10, i
*10, 0);
1234 DrawTestLines( 0, 100, 0, dc
);
1235 DrawTestLines( 0, 320, 1, dc
);
1236 DrawTestLines( 0, 540, 2, dc
);
1237 DrawTestLines( 0, 760, 6, dc
);
1241 DrawTestBrushes(dc
);
1253 DrawWithLogicalOps(dc
);
1256 #if wxUSE_GRAPHICS_CONTEXT
1271 void MyCanvas::OnMouseMove(wxMouseEvent
&event
)
1274 wxClientDC
dc(this);
1276 m_owner
->PrepareDC(dc
);
1278 wxPoint pos
= event
.GetPosition();
1279 long x
= dc
.DeviceToLogicalX( pos
.x
);
1280 long y
= dc
.DeviceToLogicalY( pos
.y
);
1282 str
.Printf( wxT("Current mouse position: %d,%d"), (int)x
, (int)y
);
1283 m_owner
->SetStatusText( str
);
1286 #endif // wxUSE_STATUSBAR
1289 // ----------------------------------------------------------------------------
1291 // ----------------------------------------------------------------------------
1293 // the event tables connect the wxWidgets events with the functions (event
1294 // handlers) which process them. It can be also done at run-time, but for the
1295 // simple menu events like this the static method is much simpler.
1296 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
1297 EVT_MENU (File_Quit
, MyFrame::OnQuit
)
1298 EVT_MENU (File_About
, MyFrame::OnAbout
)
1299 EVT_MENU (File_Clip
, MyFrame::OnClip
)
1300 #if wxUSE_GRAPHICS_CONTEXT
1301 EVT_MENU (File_GraphicContext
, MyFrame::OnGraphicContext
)
1304 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame::OnShow
)
1306 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame::OnOption
)
1309 // frame constructor
1310 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
1311 : wxFrame((wxFrame
*)NULL
, wxID_ANY
, title
, pos
, size
,
1312 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
1314 // set the frame icon
1315 SetIcon(wxICON(mondrian
));
1317 wxMenu
*menuFile
= new wxMenu
;
1318 menuFile
->Append(File_ShowDefault
, _T("&Default screen\tF1"));
1319 menuFile
->Append(File_ShowText
, _T("&Text screen\tF2"));
1320 menuFile
->Append(File_ShowLines
, _T("&Lines screen\tF3"));
1321 menuFile
->Append(File_ShowBrushes
, _T("&Brushes screen\tF4"));
1322 menuFile
->Append(File_ShowPolygons
, _T("&Polygons screen\tF5"));
1323 menuFile
->Append(File_ShowMask
, _T("&Mask screen\tF6"));
1324 menuFile
->Append(File_ShowOps
, _T("&ROP screen\tF7"));
1325 menuFile
->Append(File_ShowRegions
, _T("Re&gions screen\tF8"));
1326 menuFile
->Append(File_ShowCircles
, _T("&Circles screen\tF9"));
1327 #if wxUSE_GRAPHICS_CONTEXT
1328 menuFile
->Append(File_ShowAlpha
, _T("&Alpha screen\tF10"));
1330 menuFile
->Append(File_ShowSplines
, _T("&Splines screen\tF11"));
1331 menuFile
->Append(File_ShowGradients
, _T("&Gradients screen\tF12"));
1332 menuFile
->AppendSeparator();
1333 menuFile
->AppendCheckItem(File_Clip
, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
1334 #if wxUSE_GRAPHICS_CONTEXT
1335 menuFile
->AppendCheckItem(File_GraphicContext
, _T("&Use GraphicContext\tCtrl-Y"), _T("Use GraphicContext"));
1337 menuFile
->AppendSeparator();
1338 menuFile
->Append(File_About
, _T("&About...\tCtrl-A"), _T("Show about dialog"));
1339 menuFile
->AppendSeparator();
1340 menuFile
->Append(File_Quit
, _T("E&xit\tAlt-X"), _T("Quit this program"));
1342 wxMenu
*menuMapMode
= new wxMenu
;
1343 menuMapMode
->Append( MapMode_Text
, _T("&TEXT map mode") );
1344 menuMapMode
->Append( MapMode_Lometric
, _T("&LOMETRIC map mode") );
1345 menuMapMode
->Append( MapMode_Twips
, _T("T&WIPS map mode") );
1346 menuMapMode
->Append( MapMode_Points
, _T("&POINTS map mode") );
1347 menuMapMode
->Append( MapMode_Metric
, _T("&METRIC map mode") );
1349 wxMenu
*menuUserScale
= new wxMenu
;
1350 menuUserScale
->Append( UserScale_StretchHoriz
, _T("Stretch &horizontally\tCtrl-H") );
1351 menuUserScale
->Append( UserScale_ShrinkHoriz
, _T("Shrin&k horizontally\tCtrl-G") );
1352 menuUserScale
->Append( UserScale_StretchVertic
, _T("Stretch &vertically\tCtrl-V") );
1353 menuUserScale
->Append( UserScale_ShrinkVertic
, _T("&Shrink vertically\tCtrl-W") );
1354 menuUserScale
->AppendSeparator();
1355 menuUserScale
->Append( UserScale_Restore
, _T("&Restore to normal\tCtrl-0") );
1357 wxMenu
*menuAxis
= new wxMenu
;
1358 menuAxis
->AppendCheckItem( AxisMirror_Horiz
, _T("Mirror horizontally\tCtrl-M") );
1359 menuAxis
->AppendCheckItem( AxisMirror_Vertic
, _T("Mirror vertically\tCtrl-N") );
1361 wxMenu
*menuLogical
= new wxMenu
;
1362 menuLogical
->Append( LogicalOrigin_MoveDown
, _T("Move &down\tCtrl-D") );
1363 menuLogical
->Append( LogicalOrigin_MoveUp
, _T("Move &up\tCtrl-U") );
1364 menuLogical
->Append( LogicalOrigin_MoveLeft
, _T("Move &right\tCtrl-L") );
1365 menuLogical
->Append( LogicalOrigin_MoveRight
, _T("Move &left\tCtrl-R") );
1366 menuLogical
->AppendSeparator();
1367 menuLogical
->Append( LogicalOrigin_Set
, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1368 menuLogical
->Append( LogicalOrigin_Restore
, _T("&Restore to normal\tShift-Ctrl-0") );
1370 wxMenu
*menuColour
= new wxMenu
;
1372 menuColour
->Append( Colour_TextForeground
, _T("Text &foreground...") );
1373 menuColour
->Append( Colour_TextBackground
, _T("Text &background...") );
1374 menuColour
->Append( Colour_Background
, _T("Background &colour...") );
1375 #endif // wxUSE_COLOURDLG
1376 menuColour
->AppendCheckItem( Colour_BackgroundMode
, _T("&Opaque/transparent\tCtrl-B") );
1377 menuColour
->AppendCheckItem( Colour_TextureBackgound
, _T("Draw textured back&ground\tCtrl-T") );
1379 // now append the freshly created menu to the menu bar...
1380 wxMenuBar
*menuBar
= new wxMenuBar
;
1381 menuBar
->Append(menuFile
, _T("&File"));
1382 menuBar
->Append(menuMapMode
, _T("&Mode"));
1383 menuBar
->Append(menuUserScale
, _T("&Scale"));
1384 menuBar
->Append(menuAxis
, _T("&Axis"));
1385 menuBar
->Append(menuLogical
, _T("&Origin"));
1386 menuBar
->Append(menuColour
, _T("&Colours"));
1388 // ... and attach this menu bar to the frame
1389 SetMenuBar(menuBar
);
1393 SetStatusText(_T("Welcome to wxWidgets!"));
1394 #endif // wxUSE_STATUSBAR
1396 m_mapMode
= wxMM_TEXT
;
1399 m_xLogicalOrigin
= 0;
1400 m_yLogicalOrigin
= 0;
1402 m_yAxisReversed
= false;
1403 m_backgroundMode
= wxSOLID
;
1404 m_colourForeground
= *wxRED
;
1405 m_colourBackground
= *wxBLUE
;
1406 m_textureBackground
= false;
1408 m_canvas
= new MyCanvas( this );
1409 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1414 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1416 // true is to force the frame to close
1420 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1423 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1424 wxT("This sample tests various primitive drawing functions\n")
1425 wxT("(without any attempts to prevent flicker).\n")
1426 wxT("Copyright (c) Robert Roebling 1999")
1429 wxMessageBox(msg
, _T("About Drawing"), wxOK
| wxICON_INFORMATION
, this);
1432 void MyFrame::OnClip(wxCommandEvent
& event
)
1434 m_canvas
->Clip(event
.IsChecked());
1437 #if wxUSE_GRAPHICS_CONTEXT
1438 void MyFrame::OnGraphicContext(wxCommandEvent
& event
)
1440 m_canvas
->UseGraphicContext(event
.IsChecked());
1444 void MyFrame::OnShow(wxCommandEvent
& event
)
1446 m_canvas
->ToShow((ScreenToShow
)(event
.GetId() - MenuShow_First
));
1449 void MyFrame::OnOption(wxCommandEvent
& event
)
1451 switch (event
.GetId())
1454 m_mapMode
= wxMM_TEXT
;
1456 case MapMode_Lometric
:
1457 m_mapMode
= wxMM_LOMETRIC
;
1460 m_mapMode
= wxMM_TWIPS
;
1462 case MapMode_Points
:
1463 m_mapMode
= wxMM_POINTS
;
1465 case MapMode_Metric
:
1466 m_mapMode
= wxMM_METRIC
;
1469 case LogicalOrigin_MoveDown
:
1470 m_yLogicalOrigin
+= 10;
1472 case LogicalOrigin_MoveUp
:
1473 m_yLogicalOrigin
-= 10;
1475 case LogicalOrigin_MoveLeft
:
1476 m_xLogicalOrigin
+= 10;
1478 case LogicalOrigin_MoveRight
:
1479 m_xLogicalOrigin
-= 10;
1481 case LogicalOrigin_Set
:
1483 m_yLogicalOrigin
= -100;
1485 case LogicalOrigin_Restore
:
1487 m_yLogicalOrigin
= 0;
1490 case UserScale_StretchHoriz
:
1491 m_xUserScale
*= 1.10;
1493 case UserScale_ShrinkHoriz
:
1494 m_xUserScale
/= 1.10;
1496 case UserScale_StretchVertic
:
1497 m_yUserScale
*= 1.10;
1499 case UserScale_ShrinkVertic
:
1500 m_yUserScale
/= 1.10;
1502 case UserScale_Restore
:
1507 case AxisMirror_Vertic
:
1508 m_yAxisReversed
= !m_yAxisReversed
;
1510 case AxisMirror_Horiz
:
1511 m_xAxisReversed
= !m_xAxisReversed
;
1515 case Colour_TextForeground
:
1516 m_colourForeground
= SelectColour();
1518 case Colour_TextBackground
:
1519 m_colourBackground
= SelectColour();
1521 case Colour_Background
:
1523 wxColour col
= SelectColour();
1526 m_backgroundBrush
.SetColour(col
);
1530 #endif // wxUSE_COLOURDLG
1532 case Colour_BackgroundMode
:
1533 m_backgroundMode
= m_backgroundMode
== wxSOLID
? wxTRANSPARENT
1537 case Colour_TextureBackgound
:
1538 m_textureBackground
= ! m_textureBackground
;
1546 m_canvas
->Refresh();
1549 void MyFrame::PrepareDC(wxDC
& dc
)
1551 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
1552 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
1553 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
1554 dc
.SetMapMode( m_mapMode
);
1558 wxColour
MyFrame::SelectColour()
1562 wxColourDialog
dialog(this, &data
);
1564 if ( dialog
.ShowModal() == wxID_OK
)
1566 col
= dialog
.GetColourData().GetColour();
1571 #endif // wxUSE_COLOURDLG