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 if ( !wxApp::OnInit() )
359 // Create the main application window
360 MyFrame
*frame
= new MyFrame(_T("Drawing sample"),
361 wxPoint(50, 50), wxSize(550, 340));
363 // Show it and tell the application that it's our main window
369 wxLogError(wxT("Can't load one of the bitmap files needed ")
370 wxT("for this sample from the current or parent ")
371 wxT("directory, please copy them there."));
383 void MyApp::DeleteBitmaps()
386 delete gs_bmpWithColMask
;
388 delete gs_bmpWithMask
;
394 gs_bmpWithColMask
= NULL
;
396 gs_bmpWithMask
= NULL
;
402 // ----------------------------------------------------------------------------
404 // ----------------------------------------------------------------------------
406 // the event tables connect the wxWidgets events with the functions (event
407 // handlers) which process them.
408 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
409 EVT_PAINT (MyCanvas::OnPaint
)
410 EVT_MOTION (MyCanvas::OnMouseMove
)
415 MyCanvas::MyCanvas(MyFrame
*parent
)
416 : wxScrolledWindow(parent
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
417 wxHSCROLL
| wxVSCROLL
| wxNO_FULL_REPAINT_ON_RESIZE
)
420 m_show
= Show_Default
;
421 m_smile_bmp
= wxBitmap(smile_xpm
);
422 m_std_icon
= wxArtProvider::GetIcon(wxART_INFORMATION
);
424 #if wxUSE_GRAPHICS_CONTEXT
425 m_useContext
= false;
429 void MyCanvas::DrawTestBrushes(wxDC
& dc
)
431 static const wxCoord WIDTH
= 200;
432 static const wxCoord HEIGHT
= 80;
437 dc
.SetBrush(wxBrush(*wxGREEN
, wxSOLID
));
438 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
439 dc
.DrawText(_T("Solid green"), x
+ 10, y
+ 10);
442 dc
.SetBrush(wxBrush(*wxRED
, wxCROSSDIAG_HATCH
));
443 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
444 dc
.DrawText(_T("Hatched red"), x
+ 10, y
+ 10);
447 dc
.SetBrush(wxBrush(*gs_bmpMask
));
448 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
449 dc
.DrawText(_T("Stipple mono"), x
+ 10, y
+ 10);
452 dc
.SetBrush(wxBrush(*gs_bmpNoMask
));
453 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
454 dc
.DrawText(_T("Stipple colour"), x
+ 10, y
+ 10);
457 void MyCanvas::DrawTestPoly(wxDC
& dc
)
459 wxBrush
brushHatch(*wxRED
, wxFDIAGONAL_HATCH
);
460 dc
.SetBrush(brushHatch
);
463 star
[0] = wxPoint(100, 60);
464 star
[1] = wxPoint(60, 150);
465 star
[2] = wxPoint(160, 100);
466 star
[3] = wxPoint(40, 100);
467 star
[4] = wxPoint(140, 150);
469 dc
.DrawText(_T("You should see two (irregular) stars below, the left one ")
470 _T("hatched"), 10, 10);
471 dc
.DrawText(_T("except for the central region and the right ")
472 _T("one entirely hatched"), 10, 30);
473 dc
.DrawText(_T("The third star only has a hatched outline"), 10, 50);
475 dc
.DrawPolygon(WXSIZEOF(star
), star
, 0, 30);
476 dc
.DrawPolygon(WXSIZEOF(star
), star
, 160, 30, wxWINDING_RULE
);
479 star2
[0] = wxPoint(0, 100);
480 star2
[1] = wxPoint(-59, -81);
481 star2
[2] = wxPoint(95, 31);
482 star2
[3] = wxPoint(-95, 31);
483 star2
[4] = wxPoint(59, -81);
484 star2
[5] = wxPoint(0, 80);
485 star2
[6] = wxPoint(-47, -64);
486 star2
[7] = wxPoint(76, 24);
487 star2
[8] = wxPoint(-76, 24);
488 star2
[9] = wxPoint(47, -64);
489 int count
[2] = {5, 5};
491 dc
.DrawPolyPolygon(WXSIZEOF(count
), count
, star2
, 450, 150);
494 void MyCanvas::DrawTestLines( int x
, int y
, int width
, wxDC
&dc
)
496 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
497 dc
.SetBrush( *wxRED_BRUSH
);
498 dc
.DrawText(wxString::Format(wxT("Testing lines of width %d"), width
), x
+ 10, y
- 10);
499 dc
.DrawRectangle( x
+10, y
+10, 100, 190 );
501 dc
.DrawText(_T("Solid/dot/short dash/long dash/dot dash"), x
+ 150, y
+ 10);
502 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
503 dc
.DrawLine( x
+20, y
+20, 100, y
+20 );
504 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT
) );
505 dc
.DrawLine( x
+20, y
+30, 100, y
+30 );
506 dc
.SetPen( wxPen( wxT("black"), width
, wxSHORT_DASH
) );
507 dc
.DrawLine( x
+20, y
+40, 100, y
+40 );
508 dc
.SetPen( wxPen( wxT("black"), width
, wxLONG_DASH
) );
509 dc
.DrawLine( x
+20, y
+50, 100, y
+50 );
510 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT_DASH
) );
511 dc
.DrawLine( x
+20, y
+60, 100, y
+60 );
513 dc
.DrawText(_T("Misc hatches"), x
+ 150, y
+ 70);
514 dc
.SetPen( wxPen( wxT("black"), width
, wxBDIAGONAL_HATCH
) );
515 dc
.DrawLine( x
+20, y
+70, 100, y
+70 );
516 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSSDIAG_HATCH
) );
517 dc
.DrawLine( x
+20, y
+80, 100, y
+80 );
518 dc
.SetPen( wxPen( wxT("black"), width
, wxFDIAGONAL_HATCH
) );
519 dc
.DrawLine( x
+20, y
+90, 100, y
+90 );
520 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSS_HATCH
) );
521 dc
.DrawLine( x
+20, y
+100, 100, y
+100 );
522 dc
.SetPen( wxPen( wxT("black"), width
, wxHORIZONTAL_HATCH
) );
523 dc
.DrawLine( x
+20, y
+110, 100, y
+110 );
524 dc
.SetPen( wxPen( wxT("black"), width
, wxVERTICAL_HATCH
) );
525 dc
.DrawLine( x
+20, y
+120, 100, y
+120 );
527 dc
.DrawText(_T("User dash"), x
+ 150, y
+ 140);
528 wxPen
ud( wxT("black"), width
, wxUSER_DASH
);
530 dash1
[0] = 8; // Long dash <---------+
531 dash1
[1] = 2; // Short gap |
532 dash1
[2] = 3; // Short dash |
533 dash1
[3] = 2; // Short gap |
534 dash1
[4] = 3; // Short dash |
535 dash1
[5] = 2; // Short gap and repeat +
536 ud
.SetDashes( 6, dash1
);
538 dc
.DrawLine( x
+20, y
+140, 100, y
+140 );
539 dash1
[0] = 5; // Make first dash shorter
540 ud
.SetDashes( 6, dash1
);
542 dc
.DrawLine( x
+20, y
+150, 100, y
+150 );
543 dash1
[2] = 5; // Make second dash longer
544 ud
.SetDashes( 6, dash1
);
546 dc
.DrawLine( x
+20, y
+160, 100, y
+160 );
547 dash1
[4] = 5; // Make third dash longer
548 ud
.SetDashes( 6, dash1
);
550 dc
.DrawLine( x
+20, y
+170, 100, y
+170 );
553 void MyCanvas::DrawDefault(wxDC
& dc
)
556 dc
.DrawCircle(0, 0, 10);
558 #if !defined(wxMAC_USE_CORE_GRAPHICS) || !wxMAC_USE_CORE_GRAPHICS
559 // GetPixel and FloodFill not supported by Mac OS X CoreGraphics
560 // (FloodFill uses Blit from a non-wxMemoryDC)
561 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
562 dc
.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID
));
565 dc
.GetPixel(1,1, &tmpColour
);
566 dc
.FloodFill(1,1, tmpColour
, wxFLOOD_SURFACE
);
569 dc
.DrawCheckMark(5, 80, 15, 15);
570 dc
.DrawCheckMark(25, 80, 30, 30);
571 dc
.DrawCheckMark(60, 80, 60, 60);
573 // this is the test for "blitting bitmap into DC damages selected brush" bug
574 wxCoord rectSize
= m_std_icon
.GetWidth() + 10;
576 dc
.SetPen(*wxTRANSPARENT_PEN
);
577 dc
.SetBrush( *wxGREEN_BRUSH
);
578 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
579 dc
.DrawBitmap(m_std_icon
, x
+ 5, 15, true);
581 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
582 dc
.DrawIcon(m_std_icon
, x
+ 5, 15);
584 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
586 // test for "transparent" bitmap drawing (it intersects with the last
588 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
590 if (m_smile_bmp
.Ok())
591 dc
.DrawBitmap(m_smile_bmp
, x
+ rectSize
- 20, rectSize
- 10, true);
593 dc
.SetBrush( *wxBLACK_BRUSH
);
594 dc
.DrawRectangle( 0, 160, 1000, 300 );
597 wxBitmap
bitmap(20,70);
599 memdc
.SelectObject( bitmap
);
600 memdc
.SetBrush( *wxBLACK_BRUSH
);
601 memdc
.SetPen( *wxWHITE_PEN
);
602 memdc
.DrawRectangle(0,0,20,70);
603 memdc
.DrawLine( 10,0,10,70 );
606 wxPen pen
= *wxRED_PEN
;
608 memdc
.DrawLine( 10, 5,10, 5 );
609 memdc
.DrawLine( 10,10,11,10 );
610 memdc
.DrawLine( 10,15,12,15 );
611 memdc
.DrawLine( 10,20,13,20 );
614 memdc.SetPen(*wxRED_PEN);
615 memdc.DrawLine( 12, 5,12, 5 );
616 memdc.DrawLine( 12,10,13,10 );
617 memdc.DrawLine( 12,15,14,15 );
618 memdc.DrawLine( 12,20,15,20 );
622 memdc
.DrawLine( 10,25,10,25 );
623 memdc
.DrawLine( 10,30, 9,30 );
624 memdc
.DrawLine( 10,35, 8,35 );
625 memdc
.DrawLine( 10,40, 7,40 );
628 dc
.SetPen(*wxWHITE_PEN
);
629 memdc
.SetLogicalFunction( wxINVERT
);
630 memdc
.SetPen( *wxWHITE_PEN
);
631 memdc
.DrawLine( 10,50,10,50 );
632 memdc
.DrawLine( 10,55,11,55 );
633 memdc
.DrawLine( 10,60,12,60 );
634 memdc
.DrawLine( 10,65,13,65 );
636 memdc
.DrawLine( 12,50,12,50 );
637 memdc
.DrawLine( 12,55,13,55 );
638 memdc
.DrawLine( 12,60,14,60 );
639 memdc
.DrawLine( 12,65,15,65 );
641 memdc
.SelectObject( wxNullBitmap
);
642 dc
.DrawBitmap( bitmap
, 10, 170 );
643 wxImage image
= bitmap
.ConvertToImage();
644 image
.Rescale( 60,210 );
645 bitmap
= wxBitmap(image
);
646 dc
.DrawBitmap( bitmap
, 50, 170 );
648 // test the rectangle outline drawing - there should be one pixel between
649 // the rect and the lines
650 dc
.SetPen(*wxWHITE_PEN
);
651 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
652 dc
.DrawRectangle(150, 170, 49, 29);
653 dc
.DrawRectangle(200, 170, 49, 29);
654 dc
.SetPen(*wxWHITE_PEN
);
655 dc
.DrawLine(250, 210, 250, 170);
656 dc
.DrawLine(260, 200, 150, 200);
658 // test the rectangle filled drawing - there should be one pixel between
659 // the rect and the lines
660 dc
.SetPen(*wxTRANSPARENT_PEN
);
661 dc
.SetBrush( *wxWHITE_BRUSH
);
662 dc
.DrawRectangle(300, 170, 49, 29);
663 dc
.DrawRectangle(350, 170, 49, 29);
664 dc
.SetPen(*wxWHITE_PEN
);
665 dc
.DrawLine(400, 170, 400, 210);
666 dc
.DrawLine(300, 200, 410, 200);
668 // a few more tests of this kind
669 dc
.SetPen(*wxRED_PEN
);
670 dc
.SetBrush( *wxWHITE_BRUSH
);
671 dc
.DrawRectangle(300, 220, 1, 1);
672 dc
.DrawRectangle(310, 220, 2, 2);
673 dc
.DrawRectangle(320, 220, 3, 3);
674 dc
.DrawRectangle(330, 220, 4, 4);
676 dc
.SetPen(*wxTRANSPARENT_PEN
);
677 dc
.SetBrush( *wxWHITE_BRUSH
);
678 dc
.DrawRectangle(300, 230, 1, 1);
679 dc
.DrawRectangle(310, 230, 2, 2);
680 dc
.DrawRectangle(320, 230, 3, 3);
681 dc
.DrawRectangle(330, 230, 4, 4);
683 // and now for filled rect with outline
684 dc
.SetPen(*wxRED_PEN
);
685 dc
.SetBrush( *wxWHITE_BRUSH
);
686 dc
.DrawRectangle(500, 170, 49, 29);
687 dc
.DrawRectangle(550, 170, 49, 29);
688 dc
.SetPen(*wxWHITE_PEN
);
689 dc
.DrawLine(600, 170, 600, 210);
690 dc
.DrawLine(500, 200, 610, 200);
692 // test the rectangle outline drawing - there should be one pixel between
693 // the rect and the lines
694 dc
.SetPen(*wxWHITE_PEN
);
695 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
696 dc
.DrawRoundedRectangle(150, 270, 49, 29, 6);
697 dc
.DrawRoundedRectangle(200, 270, 49, 29, 6);
698 dc
.SetPen(*wxWHITE_PEN
);
699 dc
.DrawLine(250, 270, 250, 310);
700 dc
.DrawLine(150, 300, 260, 300);
702 // test the rectangle filled drawing - there should be one pixel between
703 // the rect and the lines
704 dc
.SetPen(*wxTRANSPARENT_PEN
);
705 dc
.SetBrush( *wxWHITE_BRUSH
);
706 dc
.DrawRoundedRectangle(300, 270, 49, 29, 6);
707 dc
.DrawRoundedRectangle(350, 270, 49, 29, 6);
708 dc
.SetPen(*wxWHITE_PEN
);
709 dc
.DrawLine(400, 270, 400, 310);
710 dc
.DrawLine(300, 300, 410, 300);
712 // Added by JACS to demonstrate bizarre behaviour.
713 // With a size of 70, we get a missing red RHS,
714 // and the height is too small, so we get yellow
715 // showing. With a size of 40, it draws as expected:
716 // it just shows a white rectangle with red outline.
718 int totalHeight
= 70;
719 wxBitmap
bitmap2(totalWidth
, totalHeight
);
722 memdc2
.SelectObject(bitmap2
);
724 wxColour
clr(255, 255, 0);
725 wxBrush
yellowBrush(clr
, wxSOLID
);
726 memdc2
.SetBackground(yellowBrush
);
729 wxPen
yellowPen(clr
, 1, wxSOLID
);
731 // Now draw a white rectangle with red outline. It should
732 // entirely eclipse the yellow background.
733 memdc2
.SetPen(*wxRED_PEN
);
734 memdc2
.SetBrush(*wxWHITE_BRUSH
);
736 memdc2
.DrawRectangle(0, 0, totalWidth
, totalHeight
);
738 memdc2
.SetPen(wxNullPen
);
739 memdc2
.SetBrush(wxNullBrush
);
740 memdc2
.SelectObject(wxNullBitmap
);
742 dc
.DrawBitmap(bitmap2
, 500, 270);
744 // Repeat, but draw directly on dc
745 // Draw a yellow rectangle filling the bitmap
747 x
= 600; int y
= 270;
748 dc
.SetPen(yellowPen
);
749 dc
.SetBrush(yellowBrush
);
750 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
752 // Now draw a white rectangle with red outline. It should
753 // entirely eclipse the yellow background.
754 dc
.SetPen(*wxRED_PEN
);
755 dc
.SetBrush(*wxWHITE_BRUSH
);
757 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
760 void MyCanvas::DrawText(wxDC
& dc
)
762 // set underlined font for testing
763 dc
.SetFont( wxFont(12, wxMODERN
, wxNORMAL
, wxNORMAL
, true) );
764 dc
.DrawText( _T("This is text"), 110, 10 );
765 dc
.DrawRotatedText( _T("That is text"), 20, 10, -45 );
767 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
768 // under Win9x (it is not TrueType)
769 dc
.SetFont( *wxSWISS_FONT
);
772 dc
.SetBackgroundMode(wxTRANSPARENT
);
774 for ( int n
= -180; n
< 180; n
+= 30 )
776 text
.Printf(wxT(" %d rotated text"), n
);
777 dc
.DrawRotatedText(text
, 400, 400, n
);
780 dc
.SetFont( wxFont( 18, wxSWISS
, wxNORMAL
, wxNORMAL
) );
782 dc
.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
787 dc
.GetTextExtent( _T("This is Swiss 18pt text."), &length
, &height
, &descent
);
788 text
.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length
, height
, descent
);
789 dc
.DrawText( text
, 110, 80 );
791 text
.Printf( wxT("CharHeight() returns: %d"), dc
.GetCharHeight() );
792 dc
.DrawText( text
, 110, 120 );
794 dc
.DrawRectangle( 100, 40, 4, height
);
796 // test the logical function effect
798 dc
.SetLogicalFunction(wxINVERT
);
799 dc
.DrawText( _T("There should be no text below"), 110, 150 );
800 dc
.DrawRectangle( 110, y
, 100, height
);
802 // twice drawn inverted should result in invisible
804 dc
.DrawText( _T("Invisible text"), 110, y
);
805 dc
.DrawRectangle( 110, y
, 100, height
);
806 dc
.DrawText( _T("Invisible text"), 110, y
);
807 dc
.DrawRectangle( 110, y
, 100, height
);
808 dc
.SetLogicalFunction(wxCOPY
);
811 dc
.DrawRectangle( 110, y
, 100, height
);
812 dc
.DrawText( _T("Visible text"), 110, y
);
819 } rasterOperations
[] =
821 { wxT("wxAND"), wxAND
},
822 { wxT("wxAND_INVERT"), wxAND_INVERT
},
823 { wxT("wxAND_REVERSE"), wxAND_REVERSE
},
824 { wxT("wxCLEAR"), wxCLEAR
},
825 { wxT("wxCOPY"), wxCOPY
},
826 { wxT("wxEQUIV"), wxEQUIV
},
827 { wxT("wxINVERT"), wxINVERT
},
828 { wxT("wxNAND"), wxNAND
},
829 { wxT("wxNO_OP"), wxNO_OP
},
830 { wxT("wxOR"), wxOR
},
831 { wxT("wxOR_INVERT"), wxOR_INVERT
},
832 { wxT("wxOR_REVERSE"), wxOR_REVERSE
},
833 { wxT("wxSET"), wxSET
},
834 { wxT("wxSRC_INVERT"), wxSRC_INVERT
},
835 { wxT("wxXOR"), wxXOR
},
838 void MyCanvas::DrawImages(wxDC
& dc
)
840 dc
.DrawText(_T("original image"), 0, 0);
841 dc
.DrawBitmap(*gs_bmpNoMask
, 0, 20, 0);
842 dc
.DrawText(_T("with colour mask"), 0, 100);
843 dc
.DrawBitmap(*gs_bmpWithColMask
, 0, 120, true);
844 dc
.DrawText(_T("the mask image"), 0, 200);
845 dc
.DrawBitmap(*gs_bmpMask
, 0, 220, 0);
846 dc
.DrawText(_T("masked image"), 0, 300);
847 dc
.DrawBitmap(*gs_bmpWithMask
, 0, 320, true);
849 int cx
= gs_bmpWithColMask
->GetWidth(),
850 cy
= gs_bmpWithColMask
->GetHeight();
853 for ( size_t n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
855 wxCoord x
= 120 + 150*(n%4
),
858 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
859 memDC
.SelectObject(*gs_bmpWithColMask
);
860 dc
.Blit(x
, y
, cx
, cy
, &memDC
, 0, 0, rasterOperations
[n
].rop
, true);
864 void MyCanvas::DrawWithLogicalOps(wxDC
& dc
)
866 static const wxCoord w
= 60;
867 static const wxCoord h
= 60;
869 // reuse the text colour here
870 dc
.SetPen(wxPen(m_owner
->m_colourForeground
, 1, wxSOLID
));
871 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
874 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
876 wxCoord x
= 20 + 150*(n%4
),
879 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
880 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
881 dc
.DrawRectangle(x
, y
, w
, h
);
882 dc
.DrawLine(x
, y
, x
+ w
, y
+ h
);
883 dc
.DrawLine(x
+ w
, y
, x
, y
+ h
);
886 // now some filled rectangles
887 dc
.SetBrush(wxBrush(m_owner
->m_colourForeground
, wxSOLID
));
889 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
891 wxCoord x
= 20 + 150*(n%4
),
894 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
895 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
896 dc
.DrawRectangle(x
, y
, w
, h
);
900 #if wxUSE_GRAPHICS_CONTEXT
902 void MyCanvas::DrawAlpha(wxDC
& no_dc
)
904 void MyCanvas::DrawAlpha(wxDC
& dc
)
912 wxDouble margin
= 20 ;
913 wxDouble width
= 180 ;
914 wxDouble radius
= 30 ;
916 dc
.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID
));
917 dc
.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID
));
919 wxRect
r(margin
,margin
+width
*0.66,width
,width
) ;
921 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
923 dc
.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID
));
924 dc
.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID
));
926 r
.Offset( width
* 0.8 , - width
* 0.66 ) ;
928 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
930 dc
.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID
));
931 dc
.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID
));
933 r
.Offset( width
* 0.8 , width
*0.5 ) ;
935 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
937 dc
.SetPen( *wxTRANSPARENT_PEN
) ;
938 dc
.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
939 dc
.DrawRoundedRectangle( 0 , margin
+ width
/ 2 , width
* 3 , 100 , radius
) ;
941 dc
.SetTextForeground( wxColour(255,255,0,128) );
942 dc
.SetFont( wxFont( 40, wxFONTFAMILY_SWISS
, wxFONTSTYLE_ITALIC
, wxFONTWEIGHT_NORMAL
) );
943 dc
.DrawText( wxT("Hello!"), 120, 80 );
948 void MyCanvas::DrawCircles(wxDC
& dc
)
954 dc
.SetPen( *wxRED_PEN
);
955 dc
.SetBrush( *wxGREEN_BRUSH
);
957 dc
.DrawText(_T("Some circles"), 0, y
);
958 dc
.DrawCircle(x
, y
, r
);
959 dc
.DrawCircle(x
+ 2*r
, y
, r
);
960 dc
.DrawCircle(x
+ 4*r
, y
, r
);
963 dc
.DrawText(_T("And ellipses"), 0, y
);
964 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
965 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
966 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
969 dc
.DrawText(_T("And arcs"), 0, y
);
970 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
971 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
972 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
975 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
976 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
977 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
978 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
980 // same as above, just transparent brush
982 dc
.SetPen( *wxRED_PEN
);
983 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
986 dc
.DrawText(_T("Some circles"), 0, y
);
987 dc
.DrawCircle(x
, y
, r
);
988 dc
.DrawCircle(x
+ 2*r
, y
, r
);
989 dc
.DrawCircle(x
+ 4*r
, y
, r
);
992 dc
.DrawText(_T("And ellipses"), 0, y
);
993 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
994 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
995 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
998 dc
.DrawText(_T("And arcs"), 0, y
);
999 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
1000 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
1001 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
1004 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
1005 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
1006 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
1007 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
1011 void MyCanvas::DrawSplines(wxDC
& dc
)
1014 dc
.DrawText(_T("Some splines"), 10, 5);
1016 // values are hardcoded rather than randomly generated
1017 // so the output can be compared between native
1018 // implementations on platforms with different random
1022 const wxPoint
center( R
+ 20, R
+ 20 );
1023 const int angles
[7] = { 0, 10, 33, 77, 13, 145, 90 };
1024 const int radii
[5] = { 100 , 59, 85, 33, 90 };
1028 // background spline calculation
1029 unsigned int radius_pos
= 0;
1030 unsigned int angle_pos
= 0;
1032 for ( int i
= 0; i
< n
; i
++ )
1034 angle
+= angles
[ angle_pos
];
1035 int r
= R
* radii
[ radius_pos
] / 100;
1036 pts
[ i
].x
= center
.x
+ (wxCoord
)( r
* cos( M_PI
* angle
/ 180.0) );
1037 pts
[ i
].y
= center
.y
+ (wxCoord
)( r
* sin( M_PI
* angle
/ 180.0) );
1040 if ( angle_pos
>= WXSIZEOF(angles
) ) angle_pos
= 0;
1043 if ( radius_pos
>= WXSIZEOF(radii
) ) radius_pos
= 0;
1046 // background spline drawing
1047 dc
.SetPen(*wxRED_PEN
);
1048 dc
.DrawSpline(WXSIZEOF(pts
), pts
);
1050 // less detailed spline calculation
1051 wxPoint letters
[4][5];
1053 letters
[0][0] = wxPoint( 0,1); // O O
1054 letters
[0][1] = wxPoint( 1,3); // * *
1055 letters
[0][2] = wxPoint( 2,2); // * O *
1056 letters
[0][3] = wxPoint( 3,3); // * * * *
1057 letters
[0][4] = wxPoint( 4,1); // O O
1059 letters
[1][0] = wxPoint( 5,1); // O*O
1060 letters
[1][1] = wxPoint( 6,1); // *
1061 letters
[1][2] = wxPoint( 7,2); // O
1062 letters
[1][3] = wxPoint( 8,3); // *
1063 letters
[1][4] = wxPoint( 9,3); // O*O
1065 letters
[2][0] = wxPoint( 5,3); // O*O
1066 letters
[2][1] = wxPoint( 6,3); // *
1067 letters
[2][2] = wxPoint( 7,2); // O
1068 letters
[2][3] = wxPoint( 8,1); // *
1069 letters
[2][4] = wxPoint( 9,1); // O*O
1071 letters
[3][0] = wxPoint(10,0); // O O
1072 letters
[3][1] = wxPoint(11,3); // * *
1073 letters
[3][2] = wxPoint(12,1); // * O *
1074 letters
[3][3] = wxPoint(13,3); // * * * *
1075 letters
[3][4] = wxPoint(14,0); // O O
1077 const int dx
= 2 * R
/ letters
[3][4].x
;
1078 const int h
[4] = { -R
/2, 0, R
/4, R
/2 };
1080 for ( int m
= 0; m
< 4; m
++ )
1082 for ( int n
= 0; n
< 5; n
++ )
1084 letters
[m
][n
].x
= center
.x
- R
+ letters
[m
][n
].x
* dx
;
1085 letters
[m
][n
].y
= center
.y
+ h
[ letters
[m
][n
].y
];
1088 dc
.SetPen( wxPen( wxT("blue"), 1, wxDOT
) );
1089 dc
.DrawLines(5, letters
[m
]);
1090 dc
.SetPen( wxPen( wxT("black"), 4, wxSOLID
) );
1091 dc
.DrawSpline(5, letters
[m
]);
1095 dc
.DrawText(_T("Splines not supported."), 10, 5);
1099 void MyCanvas::DrawGradients(wxDC
& dc
)
1101 static const int TEXT_HEIGHT
= 15;
1104 wxRect
r(10, 10, 50, 50);
1105 dc
.DrawText(_T("wxRIGHT"), r
.x
, r
.y
);
1106 r
.Offset(0, TEXT_HEIGHT
);
1107 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxRIGHT
);
1109 r
.Offset(0, r
.height
+ 10);
1110 dc
.DrawText(_T("wxLEFT"), r
.x
, r
.y
);
1111 r
.Offset(0, TEXT_HEIGHT
);
1112 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxLEFT
);
1114 r
.Offset(0, r
.height
+ 10);
1115 dc
.DrawText(_T("wxDOWN"), r
.x
, r
.y
);
1116 r
.Offset(0, TEXT_HEIGHT
);
1117 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxDOWN
);
1119 r
.Offset(0, r
.height
+ 10);
1120 dc
.DrawText(_T("wxUP"), r
.x
, r
.y
);
1121 r
.Offset(0, TEXT_HEIGHT
);
1122 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxUP
);
1126 r
= wxRect(200, 10, 50, 50);
1127 dc
.DrawText(_T("Blue inside"), r
.x
, r
.y
);
1128 r
.Offset(0, TEXT_HEIGHT
);
1129 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
);
1131 r
.Offset(0, r
.height
+ 10);
1132 dc
.DrawText(_T("White inside"), r
.x
, r
.y
);
1133 r
.Offset(0, TEXT_HEIGHT
);
1134 dc
.GradientFillConcentric(r
, *wxWHITE
, *wxBLUE
);
1136 r
.Offset(0, r
.height
+ 10);
1137 dc
.DrawText(_T("Blue in top left corner"), r
.x
, r
.y
);
1138 r
.Offset(0, TEXT_HEIGHT
);
1139 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(0, 0));
1141 r
.Offset(0, r
.height
+ 10);
1142 dc
.DrawText(_T("Blue in bottom right corner"), r
.x
, r
.y
);
1143 r
.Offset(0, TEXT_HEIGHT
);
1144 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(r
.width
, r
.height
));
1147 void MyCanvas::DrawRegions(wxDC
& dc
)
1149 dc
.DrawText(_T("You should see a red rect partly covered by a cyan one ")
1150 _T("on the left"), 10, 5);
1151 dc
.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
1152 10, 5 + dc
.GetCharHeight());
1153 dc
.DrawText(_T("The second copy should be identical but right part of it ")
1154 _T("should be offset by 10 pixels."),
1155 10, 5 + 2*dc
.GetCharHeight());
1157 DrawRegionsHelper(dc
, 10, true);
1158 DrawRegionsHelper(dc
, 350, false);
1161 void MyCanvas::DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
)
1165 dc
.DestroyClippingRegion();
1166 dc
.SetBrush( *wxWHITE_BRUSH
);
1167 dc
.SetPen( *wxTRANSPARENT_PEN
);
1168 dc
.DrawRectangle( x
, y
, 310, 310 );
1170 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 270 );
1172 dc
.SetBrush( *wxRED_BRUSH
);
1173 dc
.DrawRectangle( x
, y
, 310, 310 );
1175 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 100 );
1177 dc
.SetBrush( *wxCYAN_BRUSH
);
1178 dc
.DrawRectangle( x
, y
, 310, 310 );
1180 dc
.DestroyClippingRegion();
1182 wxRegion
region(x
+ 110, y
+ 20, 100, 270);
1183 #if !defined(__WXMOTIF__) && !defined(__WXMAC__)
1185 region
.Offset(10, 10);
1187 dc
.SetClippingRegion(region
);
1189 dc
.SetBrush( *wxGREY_BRUSH
);
1190 dc
.DrawRectangle( x
, y
, 310, 310 );
1192 if (m_smile_bmp
.Ok())
1194 dc
.DrawBitmap( m_smile_bmp
, x
+ 150, y
+ 150, true );
1195 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 10, true );
1196 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 280, true );
1197 dc
.DrawBitmap( m_smile_bmp
, x
+ 100, y
+ 70, true );
1198 dc
.DrawBitmap( m_smile_bmp
, x
+ 200, y
+ 70, true );
1202 void MyCanvas::OnPaint(wxPaintEvent
&WXUNUSED(event
))
1204 wxPaintDC
pdc(this);
1206 #if wxUSE_GRAPHICS_CONTEXT
1208 wxDC
&dc
= m_useContext
? (wxDC
&) gdc
: (wxDC
&) pdc
;
1215 m_owner
->PrepareDC(dc
);
1217 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
1218 if ( m_owner
->m_backgroundBrush
.Ok() )
1219 dc
.SetBackground( m_owner
->m_backgroundBrush
);
1220 if ( m_owner
->m_colourForeground
.Ok() )
1221 dc
.SetTextForeground( m_owner
->m_colourForeground
);
1222 if ( m_owner
->m_colourBackground
.Ok() )
1223 dc
.SetTextBackground( m_owner
->m_colourBackground
);
1225 if ( m_owner
->m_textureBackground
) {
1226 if ( ! m_owner
->m_backgroundBrush
.Ok() ) {
1227 wxColour
clr(0,128,0);
1228 wxBrush
b(clr
, wxSOLID
);
1229 dc
.SetBackground(b
);
1234 dc
.SetClippingRegion(100, 100, 100, 100);
1238 if ( m_owner
->m_textureBackground
)
1240 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
1241 for ( int i
= 0; i
< 200; i
++ )
1242 dc
.DrawLine(0, i
*10, i
*10, 0);
1268 DrawTestLines( 0, 100, 0, dc
);
1269 DrawTestLines( 0, 320, 1, dc
);
1270 DrawTestLines( 0, 540, 2, dc
);
1271 DrawTestLines( 0, 760, 6, dc
);
1275 DrawTestBrushes(dc
);
1287 DrawWithLogicalOps(dc
);
1290 #if wxUSE_GRAPHICS_CONTEXT
1305 void MyCanvas::OnMouseMove(wxMouseEvent
&event
)
1308 wxClientDC
dc(this);
1310 m_owner
->PrepareDC(dc
);
1312 wxPoint pos
= event
.GetPosition();
1313 long x
= dc
.DeviceToLogicalX( pos
.x
);
1314 long y
= dc
.DeviceToLogicalY( pos
.y
);
1316 str
.Printf( wxT("Current mouse position: %d,%d"), (int)x
, (int)y
);
1317 m_owner
->SetStatusText( str
);
1320 #endif // wxUSE_STATUSBAR
1323 // ----------------------------------------------------------------------------
1325 // ----------------------------------------------------------------------------
1327 // the event tables connect the wxWidgets events with the functions (event
1328 // handlers) which process them. It can be also done at run-time, but for the
1329 // simple menu events like this the static method is much simpler.
1330 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
1331 EVT_MENU (File_Quit
, MyFrame::OnQuit
)
1332 EVT_MENU (File_About
, MyFrame::OnAbout
)
1333 EVT_MENU (File_Clip
, MyFrame::OnClip
)
1334 #if wxUSE_GRAPHICS_CONTEXT
1335 EVT_MENU (File_GraphicContext
, MyFrame::OnGraphicContext
)
1338 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame::OnShow
)
1340 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame::OnOption
)
1343 // frame constructor
1344 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
1345 : wxFrame((wxFrame
*)NULL
, wxID_ANY
, title
, pos
, size
,
1346 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
1348 // set the frame icon
1349 SetIcon(wxICON(mondrian
));
1351 wxMenu
*menuFile
= new wxMenu
;
1352 menuFile
->Append(File_ShowDefault
, _T("&Default screen\tF1"));
1353 menuFile
->Append(File_ShowText
, _T("&Text screen\tF2"));
1354 menuFile
->Append(File_ShowLines
, _T("&Lines screen\tF3"));
1355 menuFile
->Append(File_ShowBrushes
, _T("&Brushes screen\tF4"));
1356 menuFile
->Append(File_ShowPolygons
, _T("&Polygons screen\tF5"));
1357 menuFile
->Append(File_ShowMask
, _T("&Mask screen\tF6"));
1358 menuFile
->Append(File_ShowOps
, _T("&ROP screen\tF7"));
1359 menuFile
->Append(File_ShowRegions
, _T("Re&gions screen\tF8"));
1360 menuFile
->Append(File_ShowCircles
, _T("&Circles screen\tF9"));
1361 #if wxUSE_GRAPHICS_CONTEXT
1362 menuFile
->Append(File_ShowAlpha
, _T("&Alpha screen\tF10"));
1364 menuFile
->Append(File_ShowSplines
, _T("&Splines screen\tF11"));
1365 menuFile
->Append(File_ShowGradients
, _T("&Gradients screen\tF12"));
1366 menuFile
->AppendSeparator();
1367 menuFile
->AppendCheckItem(File_Clip
, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
1368 #if wxUSE_GRAPHICS_CONTEXT
1369 menuFile
->AppendCheckItem(File_GraphicContext
, _T("&Use GraphicContext\tCtrl-Y"), _T("Use GraphicContext"));
1371 menuFile
->AppendSeparator();
1372 menuFile
->Append(File_About
, _T("&About...\tCtrl-A"), _T("Show about dialog"));
1373 menuFile
->AppendSeparator();
1374 menuFile
->Append(File_Quit
, _T("E&xit\tAlt-X"), _T("Quit this program"));
1376 wxMenu
*menuMapMode
= new wxMenu
;
1377 menuMapMode
->Append( MapMode_Text
, _T("&TEXT map mode") );
1378 menuMapMode
->Append( MapMode_Lometric
, _T("&LOMETRIC map mode") );
1379 menuMapMode
->Append( MapMode_Twips
, _T("T&WIPS map mode") );
1380 menuMapMode
->Append( MapMode_Points
, _T("&POINTS map mode") );
1381 menuMapMode
->Append( MapMode_Metric
, _T("&METRIC map mode") );
1383 wxMenu
*menuUserScale
= new wxMenu
;
1384 menuUserScale
->Append( UserScale_StretchHoriz
, _T("Stretch &horizontally\tCtrl-H") );
1385 menuUserScale
->Append( UserScale_ShrinkHoriz
, _T("Shrin&k horizontally\tCtrl-G") );
1386 menuUserScale
->Append( UserScale_StretchVertic
, _T("Stretch &vertically\tCtrl-V") );
1387 menuUserScale
->Append( UserScale_ShrinkVertic
, _T("&Shrink vertically\tCtrl-W") );
1388 menuUserScale
->AppendSeparator();
1389 menuUserScale
->Append( UserScale_Restore
, _T("&Restore to normal\tCtrl-0") );
1391 wxMenu
*menuAxis
= new wxMenu
;
1392 menuAxis
->AppendCheckItem( AxisMirror_Horiz
, _T("Mirror horizontally\tCtrl-M") );
1393 menuAxis
->AppendCheckItem( AxisMirror_Vertic
, _T("Mirror vertically\tCtrl-N") );
1395 wxMenu
*menuLogical
= new wxMenu
;
1396 menuLogical
->Append( LogicalOrigin_MoveDown
, _T("Move &down\tCtrl-D") );
1397 menuLogical
->Append( LogicalOrigin_MoveUp
, _T("Move &up\tCtrl-U") );
1398 menuLogical
->Append( LogicalOrigin_MoveLeft
, _T("Move &right\tCtrl-L") );
1399 menuLogical
->Append( LogicalOrigin_MoveRight
, _T("Move &left\tCtrl-R") );
1400 menuLogical
->AppendSeparator();
1401 menuLogical
->Append( LogicalOrigin_Set
, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1402 menuLogical
->Append( LogicalOrigin_Restore
, _T("&Restore to normal\tShift-Ctrl-0") );
1404 wxMenu
*menuColour
= new wxMenu
;
1406 menuColour
->Append( Colour_TextForeground
, _T("Text &foreground...") );
1407 menuColour
->Append( Colour_TextBackground
, _T("Text &background...") );
1408 menuColour
->Append( Colour_Background
, _T("Background &colour...") );
1409 #endif // wxUSE_COLOURDLG
1410 menuColour
->AppendCheckItem( Colour_BackgroundMode
, _T("&Opaque/transparent\tCtrl-B") );
1411 menuColour
->AppendCheckItem( Colour_TextureBackgound
, _T("Draw textured back&ground\tCtrl-T") );
1413 // now append the freshly created menu to the menu bar...
1414 wxMenuBar
*menuBar
= new wxMenuBar
;
1415 menuBar
->Append(menuFile
, _T("&File"));
1416 menuBar
->Append(menuMapMode
, _T("&Mode"));
1417 menuBar
->Append(menuUserScale
, _T("&Scale"));
1418 menuBar
->Append(menuAxis
, _T("&Axis"));
1419 menuBar
->Append(menuLogical
, _T("&Origin"));
1420 menuBar
->Append(menuColour
, _T("&Colours"));
1422 // ... and attach this menu bar to the frame
1423 SetMenuBar(menuBar
);
1427 SetStatusText(_T("Welcome to wxWidgets!"));
1428 #endif // wxUSE_STATUSBAR
1430 m_mapMode
= wxMM_TEXT
;
1433 m_xLogicalOrigin
= 0;
1434 m_yLogicalOrigin
= 0;
1436 m_yAxisReversed
= false;
1437 m_backgroundMode
= wxSOLID
;
1438 m_colourForeground
= *wxRED
;
1439 m_colourBackground
= *wxBLUE
;
1440 m_textureBackground
= false;
1442 m_canvas
= new MyCanvas( this );
1443 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1448 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1450 // true is to force the frame to close
1454 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1457 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1458 wxT("This sample tests various primitive drawing functions\n")
1459 wxT("(without any attempts to prevent flicker).\n")
1460 wxT("Copyright (c) Robert Roebling 1999")
1463 wxMessageBox(msg
, _T("About Drawing"), wxOK
| wxICON_INFORMATION
, this);
1466 void MyFrame::OnClip(wxCommandEvent
& event
)
1468 m_canvas
->Clip(event
.IsChecked());
1471 #if wxUSE_GRAPHICS_CONTEXT
1472 void MyFrame::OnGraphicContext(wxCommandEvent
& event
)
1474 m_canvas
->UseGraphicContext(event
.IsChecked());
1478 void MyFrame::OnShow(wxCommandEvent
& event
)
1480 m_canvas
->ToShow((ScreenToShow
)(event
.GetId() - MenuShow_First
));
1483 void MyFrame::OnOption(wxCommandEvent
& event
)
1485 switch (event
.GetId())
1488 m_mapMode
= wxMM_TEXT
;
1490 case MapMode_Lometric
:
1491 m_mapMode
= wxMM_LOMETRIC
;
1494 m_mapMode
= wxMM_TWIPS
;
1496 case MapMode_Points
:
1497 m_mapMode
= wxMM_POINTS
;
1499 case MapMode_Metric
:
1500 m_mapMode
= wxMM_METRIC
;
1503 case LogicalOrigin_MoveDown
:
1504 m_yLogicalOrigin
+= 10;
1506 case LogicalOrigin_MoveUp
:
1507 m_yLogicalOrigin
-= 10;
1509 case LogicalOrigin_MoveLeft
:
1510 m_xLogicalOrigin
+= 10;
1512 case LogicalOrigin_MoveRight
:
1513 m_xLogicalOrigin
-= 10;
1515 case LogicalOrigin_Set
:
1517 m_yLogicalOrigin
= -100;
1519 case LogicalOrigin_Restore
:
1521 m_yLogicalOrigin
= 0;
1524 case UserScale_StretchHoriz
:
1525 m_xUserScale
*= 1.10;
1527 case UserScale_ShrinkHoriz
:
1528 m_xUserScale
/= 1.10;
1530 case UserScale_StretchVertic
:
1531 m_yUserScale
*= 1.10;
1533 case UserScale_ShrinkVertic
:
1534 m_yUserScale
/= 1.10;
1536 case UserScale_Restore
:
1541 case AxisMirror_Vertic
:
1542 m_yAxisReversed
= !m_yAxisReversed
;
1544 case AxisMirror_Horiz
:
1545 m_xAxisReversed
= !m_xAxisReversed
;
1549 case Colour_TextForeground
:
1550 m_colourForeground
= SelectColour();
1552 case Colour_TextBackground
:
1553 m_colourBackground
= SelectColour();
1555 case Colour_Background
:
1557 wxColour col
= SelectColour();
1560 m_backgroundBrush
.SetColour(col
);
1564 #endif // wxUSE_COLOURDLG
1566 case Colour_BackgroundMode
:
1567 m_backgroundMode
= m_backgroundMode
== wxSOLID
? wxTRANSPARENT
1571 case Colour_TextureBackgound
:
1572 m_textureBackground
= ! m_textureBackground
;
1580 m_canvas
->Refresh();
1583 void MyFrame::PrepareDC(wxDC
& dc
)
1585 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
1586 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
1587 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
1588 dc
.SetMapMode( m_mapMode
);
1592 wxColour
MyFrame::SelectColour()
1596 wxColourDialog
dialog(this, &data
);
1598 if ( dialog
.ShowModal() == wxID_OK
)
1600 col
= dialog
.GetColourData().GetColour();
1605 #endif // wxUSE_COLOURDLG