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 0
40 #include "wx/graphics.h"
41 #if wxUSE_GRAPHICS_CONTEXT == 0
42 #error wxUSE_GRAPHICS_CONTEXT must be defined to 1 for testing
45 #undef wxUSE_GRAPHICS_CONTEXT
46 #define wxUSE_GRAPHICS_CONTEXT 0
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 // the application icon
54 #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__)
55 #include "mondrian.xpm"
58 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
62 // what do we show on screen (there are too many shapes to put them all on
63 // screen simultaneously)
76 #if wxUSE_GRAPHICS_CONTEXT
83 // ----------------------------------------------------------------------------
85 // ----------------------------------------------------------------------------
87 static wxBitmap
*gs_bmpNoMask
= NULL
,
88 *gs_bmpWithColMask
= NULL
,
90 *gs_bmpWithMask
= NULL
,
95 // ----------------------------------------------------------------------------
97 // ----------------------------------------------------------------------------
99 // Define a new application type, each program should derive a class from wxApp
100 class MyApp
: public wxApp
103 // override base class virtuals
104 // ----------------------------
106 // this one is called on application startup and is a good place for the app
107 // initialization (doing it here and not in the ctor allows to have an error
108 // return: if OnInit() returns false, the application terminates)
109 virtual bool OnInit();
111 virtual int OnExit() { DeleteBitmaps(); return 0; }
114 void DeleteBitmaps();
121 // Define a new frame type: this is going to be our main frame
122 class MyFrame
: public wxFrame
126 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
128 // event handlers (these functions should _not_ be virtual)
129 void OnQuit(wxCommandEvent
& event
);
130 void OnAbout(wxCommandEvent
& event
);
131 void OnClip(wxCommandEvent
& event
);
132 #if wxUSE_GRAPHICS_CONTEXT
133 void OnGraphicContext(wxCommandEvent
& event
);
135 void OnShow(wxCommandEvent
&event
);
136 void OnOption(wxCommandEvent
&event
);
139 wxColour
SelectColour();
140 #endif // wxUSE_COLOURDLG
141 void PrepareDC(wxDC
& dc
);
143 int m_backgroundMode
;
144 int m_textureBackground
;
148 int m_xLogicalOrigin
;
149 int m_yLogicalOrigin
;
150 bool m_xAxisReversed
,
152 wxColour m_colourForeground
, // these are _text_ colours
154 wxBrush m_backgroundBrush
;
158 // any class wishing to process wxWidgets events must use this macro
159 DECLARE_EVENT_TABLE()
162 // define a scrollable canvas for drawing onto
163 class MyCanvas
: public wxScrolledWindow
166 MyCanvas( MyFrame
*parent
);
168 void OnPaint(wxPaintEvent
&event
);
169 void OnMouseMove(wxMouseEvent
&event
);
171 void ToShow(ScreenToShow show
) { m_show
= show
; Refresh(); }
173 // set or remove the clipping region
174 void Clip(bool clip
) { m_clip
= clip
; Refresh(); }
175 #if wxUSE_GRAPHICS_CONTEXT
176 void UseGraphicContext(bool use
) { m_useContext
= use
; Refresh(); }
180 void DrawTestLines( int x
, int y
, int width
, wxDC
&dc
);
181 void DrawTestPoly(wxDC
& dc
);
182 void DrawTestBrushes(wxDC
& dc
);
183 void DrawText(wxDC
& dc
);
184 void DrawImages(wxDC
& dc
);
185 void DrawWithLogicalOps(wxDC
& dc
);
186 #if wxUSE_GRAPHICS_CONTEXT
187 void DrawAlpha(wxDC
& dc
);
189 void DrawRegions(wxDC
& dc
);
190 void DrawCircles(wxDC
& dc
);
191 void DrawSplines(wxDC
& dc
);
192 void DrawDefault(wxDC
& dc
);
193 void DrawGradients(wxDC
& dc
);
195 void DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
);
201 wxBitmap m_smile_bmp
;
204 #if wxUSE_GRAPHICS_CONTEXT
208 DECLARE_EVENT_TABLE()
211 // ----------------------------------------------------------------------------
213 // ----------------------------------------------------------------------------
215 // IDs for the controls and the menu commands
219 File_Quit
= wxID_EXIT
,
220 File_About
= wxID_ABOUT
,
222 MenuShow_First
= wxID_HIGHEST
,
223 File_ShowDefault
= MenuShow_First
,
233 #if wxUSE_GRAPHICS_CONTEXT
237 MenuShow_Last
= File_ShowGradients
,
240 #if wxUSE_GRAPHICS_CONTEXT
246 MapMode_Text
= MenuOption_First
,
252 UserScale_StretchHoriz
,
253 UserScale_ShrinkHoriz
,
254 UserScale_StretchVertic
,
255 UserScale_ShrinkVertic
,
261 LogicalOrigin_MoveDown
,
262 LogicalOrigin_MoveUp
,
263 LogicalOrigin_MoveLeft
,
264 LogicalOrigin_MoveRight
,
266 LogicalOrigin_Restore
,
269 Colour_TextForeground
,
270 Colour_TextBackground
,
272 #endif // wxUSE_COLOURDLG
273 Colour_BackgroundMode
,
274 Colour_TextureBackgound
,
276 MenuOption_Last
= Colour_TextureBackgound
279 // ----------------------------------------------------------------------------
280 // event tables and other macros for wxWidgets
281 // ----------------------------------------------------------------------------
284 // Create a new application object: this macro will allow wxWidgets to create
285 // the application object during program execution (it's better than using a
286 // static object for many reasons) and also declares the accessor function
287 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
291 // ============================================================================
293 // ============================================================================
295 // ----------------------------------------------------------------------------
296 // the application class
297 // ----------------------------------------------------------------------------
299 bool MyApp::LoadImages()
301 gs_bmpNoMask
= new wxBitmap
;
302 gs_bmpWithColMask
= new wxBitmap
;
303 gs_bmpMask
= new wxBitmap
;
304 gs_bmpWithMask
= new wxBitmap
;
305 gs_bmp4
= new wxBitmap
;
306 gs_bmp4_mono
= new wxBitmap
;
307 gs_bmp36
= new wxBitmap
;
310 pathList
.Add(_T("."));
311 pathList
.Add(_T(".."));
313 wxString path
= pathList
.FindValidPath(_T("pat4.bmp"));
317 /* 4 colour bitmap */
318 gs_bmp4
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
319 /* turn into mono-bitmap */
320 gs_bmp4_mono
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
321 wxMask
* mask4
= new wxMask(*gs_bmp4_mono
, *wxBLACK
);
322 gs_bmp4_mono
->SetMask(mask4
);
324 path
= pathList
.FindValidPath(_T("pat36.bmp"));
327 gs_bmp36
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
328 wxMask
* mask36
= new wxMask(*gs_bmp36
, *wxBLACK
);
329 gs_bmp36
->SetMask(mask36
);
331 path
= pathList
.FindValidPath(_T("image.bmp"));
334 gs_bmpNoMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
335 gs_bmpWithMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
336 gs_bmpWithColMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
338 path
= pathList
.FindValidPath(_T("mask.bmp"));
341 gs_bmpMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
343 wxMask
*mask
= new wxMask(*gs_bmpMask
, *wxBLACK
);
344 gs_bmpWithMask
->SetMask(mask
);
346 mask
= new wxMask(*gs_bmpWithColMask
, *wxWHITE
);
347 gs_bmpWithColMask
->SetMask(mask
);
352 // `Main program' equivalent: the program execution "starts" here
355 // Create the main application window
356 MyFrame
*frame
= new MyFrame(_T("Drawing sample"),
357 wxPoint(50, 50), wxSize(550, 340));
359 // Show it and tell the application that it's our main window
365 wxLogError(wxT("Can't load one of the bitmap files needed ")
366 wxT("for this sample from the current or parent ")
367 wxT("directory, please copy them there."));
379 void MyApp::DeleteBitmaps()
382 delete gs_bmpWithColMask
;
384 delete gs_bmpWithMask
;
390 gs_bmpWithColMask
= NULL
;
392 gs_bmpWithMask
= NULL
;
398 // ----------------------------------------------------------------------------
400 // ----------------------------------------------------------------------------
402 // the event tables connect the wxWidgets events with the functions (event
403 // handlers) which process them.
404 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
405 EVT_PAINT (MyCanvas::OnPaint
)
406 EVT_MOTION (MyCanvas::OnMouseMove
)
411 MyCanvas::MyCanvas(MyFrame
*parent
)
412 : wxScrolledWindow(parent
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
413 wxHSCROLL
| wxVSCROLL
| wxNO_FULL_REPAINT_ON_RESIZE
)
416 m_show
= Show_Default
;
417 m_smile_bmp
= wxBitmap(smile_xpm
);
418 m_std_icon
= wxArtProvider::GetIcon(wxART_INFORMATION
);
420 #if wxUSE_GRAPHICS_CONTEXT
421 m_useContext
= false;
425 void MyCanvas::DrawTestBrushes(wxDC
& dc
)
427 static const wxCoord WIDTH
= 200;
428 static const wxCoord HEIGHT
= 80;
433 dc
.SetBrush(wxBrush(*wxGREEN
, wxSOLID
));
434 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
435 dc
.DrawText(_T("Solid green"), x
+ 10, y
+ 10);
438 dc
.SetBrush(wxBrush(*wxRED
, wxCROSSDIAG_HATCH
));
439 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
440 dc
.DrawText(_T("Hatched red"), x
+ 10, y
+ 10);
443 dc
.SetBrush(wxBrush(*gs_bmpMask
));
444 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
445 dc
.DrawText(_T("Stipple mono"), x
+ 10, y
+ 10);
448 dc
.SetBrush(wxBrush(*gs_bmpNoMask
));
449 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
450 dc
.DrawText(_T("Stipple colour"), x
+ 10, y
+ 10);
453 void MyCanvas::DrawTestPoly(wxDC
& dc
)
455 wxBrush
brushHatch(*wxRED
, wxFDIAGONAL_HATCH
);
456 dc
.SetBrush(brushHatch
);
459 star
[0] = wxPoint(100, 60);
460 star
[1] = wxPoint(60, 150);
461 star
[2] = wxPoint(160, 100);
462 star
[3] = wxPoint(40, 100);
463 star
[4] = wxPoint(140, 150);
465 dc
.DrawText(_T("You should see two (irregular) stars below, the left one ")
466 _T("hatched"), 10, 10);
467 dc
.DrawText(_T("except for the central region and the right ")
468 _T("one entirely hatched"), 10, 30);
469 dc
.DrawText(_T("The third star only has a hatched outline"), 10, 50);
471 dc
.DrawPolygon(WXSIZEOF(star
), star
, 0, 30);
472 dc
.DrawPolygon(WXSIZEOF(star
), star
, 160, 30, wxWINDING_RULE
);
475 star2
[0] = wxPoint(0, 100);
476 star2
[1] = wxPoint(-59, -81);
477 star2
[2] = wxPoint(95, 31);
478 star2
[3] = wxPoint(-95, 31);
479 star2
[4] = wxPoint(59, -81);
480 star2
[5] = wxPoint(0, 80);
481 star2
[6] = wxPoint(-47, -64);
482 star2
[7] = wxPoint(76, 24);
483 star2
[8] = wxPoint(-76, 24);
484 star2
[9] = wxPoint(47, -64);
485 int count
[2] = {5, 5};
487 dc
.DrawPolyPolygon(WXSIZEOF(count
), count
, star2
, 450, 150);
490 void MyCanvas::DrawTestLines( int x
, int y
, int width
, wxDC
&dc
)
492 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
493 dc
.SetBrush( *wxRED_BRUSH
);
494 dc
.DrawText(wxString::Format(wxT("Testing lines of width %d"), width
), x
+ 10, y
- 10);
495 dc
.DrawRectangle( x
+10, y
+10, 100, 190 );
497 dc
.DrawText(_T("Solid/dot/short dash/long dash/dot dash"), x
+ 150, y
+ 10);
498 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
499 dc
.DrawLine( x
+20, y
+20, 100, y
+20 );
500 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT
) );
501 dc
.DrawLine( x
+20, y
+30, 100, y
+30 );
502 dc
.SetPen( wxPen( wxT("black"), width
, wxSHORT_DASH
) );
503 dc
.DrawLine( x
+20, y
+40, 100, y
+40 );
504 dc
.SetPen( wxPen( wxT("black"), width
, wxLONG_DASH
) );
505 dc
.DrawLine( x
+20, y
+50, 100, y
+50 );
506 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT_DASH
) );
507 dc
.DrawLine( x
+20, y
+60, 100, y
+60 );
509 dc
.DrawText(_T("Misc hatches"), x
+ 150, y
+ 70);
510 dc
.SetPen( wxPen( wxT("black"), width
, wxBDIAGONAL_HATCH
) );
511 dc
.DrawLine( x
+20, y
+70, 100, y
+70 );
512 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSSDIAG_HATCH
) );
513 dc
.DrawLine( x
+20, y
+80, 100, y
+80 );
514 dc
.SetPen( wxPen( wxT("black"), width
, wxFDIAGONAL_HATCH
) );
515 dc
.DrawLine( x
+20, y
+90, 100, y
+90 );
516 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSS_HATCH
) );
517 dc
.DrawLine( x
+20, y
+100, 100, y
+100 );
518 dc
.SetPen( wxPen( wxT("black"), width
, wxHORIZONTAL_HATCH
) );
519 dc
.DrawLine( x
+20, y
+110, 100, y
+110 );
520 dc
.SetPen( wxPen( wxT("black"), width
, wxVERTICAL_HATCH
) );
521 dc
.DrawLine( x
+20, y
+120, 100, y
+120 );
523 dc
.DrawText(_T("User dash"), x
+ 150, y
+ 140);
524 wxPen
ud( wxT("black"), width
, wxUSER_DASH
);
526 dash1
[0] = 8; // Long dash <---------+
527 dash1
[1] = 2; // Short gap |
528 dash1
[2] = 3; // Short dash |
529 dash1
[3] = 2; // Short gap |
530 dash1
[4] = 3; // Short dash |
531 dash1
[5] = 2; // Short gap and repeat +
532 ud
.SetDashes( 6, dash1
);
534 dc
.DrawLine( x
+20, y
+140, 100, y
+140 );
535 dash1
[0] = 5; // Make first dash shorter
536 ud
.SetDashes( 6, dash1
);
538 dc
.DrawLine( x
+20, y
+150, 100, y
+150 );
539 dash1
[2] = 5; // Make second dash longer
540 ud
.SetDashes( 6, dash1
);
542 dc
.DrawLine( x
+20, y
+160, 100, y
+160 );
543 dash1
[4] = 5; // Make third dash longer
544 ud
.SetDashes( 6, dash1
);
546 dc
.DrawLine( x
+20, y
+170, 100, y
+170 );
549 void MyCanvas::DrawDefault(wxDC
& dc
)
552 dc
.DrawCircle(0, 0, 10);
554 #if !defined(wxMAC_USE_CORE_GRAPHICS) || !wxMAC_USE_CORE_GRAPHICS
555 // GetPixel and FloodFill not supported by Mac OS X CoreGraphics
556 // (FloodFill uses Blit from a non-wxMemoryDC)
557 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
558 dc
.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID
));
561 dc
.GetPixel(1,1, &tmpColour
);
562 dc
.FloodFill(1,1, tmpColour
, wxFLOOD_SURFACE
);
565 dc
.DrawCheckMark(5, 80, 15, 15);
566 dc
.DrawCheckMark(25, 80, 30, 30);
567 dc
.DrawCheckMark(60, 80, 60, 60);
569 // this is the test for "blitting bitmap into DC damages selected brush" bug
570 wxCoord rectSize
= m_std_icon
.GetWidth() + 10;
572 dc
.SetPen(*wxTRANSPARENT_PEN
);
573 dc
.SetBrush( *wxGREEN_BRUSH
);
574 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
575 dc
.DrawBitmap(m_std_icon
, x
+ 5, 15, true);
577 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
578 dc
.DrawIcon(m_std_icon
, x
+ 5, 15);
580 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
582 // test for "transparent" bitmap drawing (it intersects with the last
584 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
586 if (m_smile_bmp
.Ok())
587 dc
.DrawBitmap(m_smile_bmp
, x
+ rectSize
- 20, rectSize
- 10, true);
589 dc
.SetBrush( *wxBLACK_BRUSH
);
590 dc
.DrawRectangle( 0, 160, 1000, 300 );
593 wxBitmap
bitmap(20,70);
595 memdc
.SelectObject( bitmap
);
596 memdc
.SetBrush( *wxBLACK_BRUSH
);
597 memdc
.SetPen( *wxWHITE_PEN
);
598 memdc
.DrawRectangle(0,0,20,70);
599 memdc
.DrawLine( 10,0,10,70 );
602 wxPen pen
= *wxRED_PEN
;
604 memdc
.DrawLine( 10, 5,10, 5 );
605 memdc
.DrawLine( 10,10,11,10 );
606 memdc
.DrawLine( 10,15,12,15 );
607 memdc
.DrawLine( 10,20,13,20 );
610 memdc.SetPen(*wxRED_PEN);
611 memdc.DrawLine( 12, 5,12, 5 );
612 memdc.DrawLine( 12,10,13,10 );
613 memdc.DrawLine( 12,15,14,15 );
614 memdc.DrawLine( 12,20,15,20 );
618 memdc
.DrawLine( 10,25,10,25 );
619 memdc
.DrawLine( 10,30, 9,30 );
620 memdc
.DrawLine( 10,35, 8,35 );
621 memdc
.DrawLine( 10,40, 7,40 );
624 dc
.SetPen(*wxWHITE_PEN
);
625 memdc
.SetLogicalFunction( wxINVERT
);
626 memdc
.SetPen( *wxWHITE_PEN
);
627 memdc
.DrawLine( 10,50,10,50 );
628 memdc
.DrawLine( 10,55,11,55 );
629 memdc
.DrawLine( 10,60,12,60 );
630 memdc
.DrawLine( 10,65,13,65 );
632 memdc
.DrawLine( 12,50,12,50 );
633 memdc
.DrawLine( 12,55,13,55 );
634 memdc
.DrawLine( 12,60,14,60 );
635 memdc
.DrawLine( 12,65,15,65 );
637 memdc
.SelectObject( wxNullBitmap
);
638 dc
.DrawBitmap( bitmap
, 10, 170 );
639 wxImage image
= bitmap
.ConvertToImage();
640 image
.Rescale( 60,210 );
641 bitmap
= wxBitmap(image
);
642 dc
.DrawBitmap( bitmap
, 50, 170 );
644 // test the rectangle outline drawing - there should be one pixel between
645 // the rect and the lines
646 dc
.SetPen(*wxWHITE_PEN
);
647 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
648 dc
.DrawRectangle(150, 170, 49, 29);
649 dc
.DrawRectangle(200, 170, 49, 29);
650 dc
.SetPen(*wxWHITE_PEN
);
651 dc
.DrawLine(250, 210, 250, 170);
652 dc
.DrawLine(260, 200, 150, 200);
654 // test the rectangle filled drawing - there should be one pixel between
655 // the rect and the lines
656 dc
.SetPen(*wxTRANSPARENT_PEN
);
657 dc
.SetBrush( *wxWHITE_BRUSH
);
658 dc
.DrawRectangle(300, 170, 49, 29);
659 dc
.DrawRectangle(350, 170, 49, 29);
660 dc
.SetPen(*wxWHITE_PEN
);
661 dc
.DrawLine(400, 170, 400, 210);
662 dc
.DrawLine(300, 200, 410, 200);
664 // a few more tests of this kind
665 dc
.SetPen(*wxRED_PEN
);
666 dc
.SetBrush( *wxWHITE_BRUSH
);
667 dc
.DrawRectangle(300, 220, 1, 1);
668 dc
.DrawRectangle(310, 220, 2, 2);
669 dc
.DrawRectangle(320, 220, 3, 3);
670 dc
.DrawRectangle(330, 220, 4, 4);
672 dc
.SetPen(*wxTRANSPARENT_PEN
);
673 dc
.SetBrush( *wxWHITE_BRUSH
);
674 dc
.DrawRectangle(300, 230, 1, 1);
675 dc
.DrawRectangle(310, 230, 2, 2);
676 dc
.DrawRectangle(320, 230, 3, 3);
677 dc
.DrawRectangle(330, 230, 4, 4);
679 // and now for filled rect with outline
680 dc
.SetPen(*wxRED_PEN
);
681 dc
.SetBrush( *wxWHITE_BRUSH
);
682 dc
.DrawRectangle(500, 170, 49, 29);
683 dc
.DrawRectangle(550, 170, 49, 29);
684 dc
.SetPen(*wxWHITE_PEN
);
685 dc
.DrawLine(600, 170, 600, 210);
686 dc
.DrawLine(500, 200, 610, 200);
688 // test the rectangle outline drawing - there should be one pixel between
689 // the rect and the lines
690 dc
.SetPen(*wxWHITE_PEN
);
691 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
692 dc
.DrawRoundedRectangle(150, 270, 49, 29, 6);
693 dc
.DrawRoundedRectangle(200, 270, 49, 29, 6);
694 dc
.SetPen(*wxWHITE_PEN
);
695 dc
.DrawLine(250, 270, 250, 310);
696 dc
.DrawLine(150, 300, 260, 300);
698 // test the rectangle filled drawing - there should be one pixel between
699 // the rect and the lines
700 dc
.SetPen(*wxTRANSPARENT_PEN
);
701 dc
.SetBrush( *wxWHITE_BRUSH
);
702 dc
.DrawRoundedRectangle(300, 270, 49, 29, 6);
703 dc
.DrawRoundedRectangle(350, 270, 49, 29, 6);
704 dc
.SetPen(*wxWHITE_PEN
);
705 dc
.DrawLine(400, 270, 400, 310);
706 dc
.DrawLine(300, 300, 410, 300);
708 // Added by JACS to demonstrate bizarre behaviour.
709 // With a size of 70, we get a missing red RHS,
710 // and the height is too small, so we get yellow
711 // showing. With a size of 40, it draws as expected:
712 // it just shows a white rectangle with red outline.
714 int totalHeight
= 70;
715 wxBitmap
bitmap2(totalWidth
, totalHeight
);
718 memdc2
.SelectObject(bitmap2
);
720 wxColour
clr(255, 255, 0);
721 wxBrush
yellowBrush(clr
, wxSOLID
);
722 memdc2
.SetBackground(yellowBrush
);
725 wxPen
yellowPen(clr
, 1, wxSOLID
);
727 // Now draw a white rectangle with red outline. It should
728 // entirely eclipse the yellow background.
729 memdc2
.SetPen(*wxRED_PEN
);
730 memdc2
.SetBrush(*wxWHITE_BRUSH
);
732 memdc2
.DrawRectangle(0, 0, totalWidth
, totalHeight
);
734 memdc2
.SetPen(wxNullPen
);
735 memdc2
.SetBrush(wxNullBrush
);
736 memdc2
.SelectObject(wxNullBitmap
);
738 dc
.DrawBitmap(bitmap2
, 500, 270);
740 // Repeat, but draw directly on dc
741 // Draw a yellow rectangle filling the bitmap
743 x
= 600; int y
= 270;
744 dc
.SetPen(yellowPen
);
745 dc
.SetBrush(yellowBrush
);
746 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
748 // Now draw a white rectangle with red outline. It should
749 // entirely eclipse the yellow background.
750 dc
.SetPen(*wxRED_PEN
);
751 dc
.SetBrush(*wxWHITE_BRUSH
);
753 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
756 void MyCanvas::DrawText(wxDC
& dc
)
758 // set underlined font for testing
759 dc
.SetFont( wxFont(12, wxMODERN
, wxNORMAL
, wxNORMAL
, true) );
760 dc
.DrawText( _T("This is text"), 110, 10 );
761 dc
.DrawRotatedText( _T("That is text"), 20, 10, -45 );
763 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
764 // under Win9x (it is not TrueType)
765 dc
.SetFont( *wxSWISS_FONT
);
768 dc
.SetBackgroundMode(wxTRANSPARENT
);
770 for ( int n
= -180; n
< 180; n
+= 30 )
772 text
.Printf(wxT(" %d rotated text"), n
);
773 dc
.DrawRotatedText(text
, 400, 400, n
);
776 dc
.SetFont( wxFont( 18, wxSWISS
, wxNORMAL
, wxNORMAL
) );
778 dc
.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
783 dc
.GetTextExtent( _T("This is Swiss 18pt text."), &length
, &height
, &descent
);
784 text
.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length
, height
, descent
);
785 dc
.DrawText( text
, 110, 80 );
787 text
.Printf( wxT("CharHeight() returns: %d"), dc
.GetCharHeight() );
788 dc
.DrawText( text
, 110, 120 );
790 dc
.DrawRectangle( 100, 40, 4, height
);
792 // test the logical function effect
794 dc
.SetLogicalFunction(wxINVERT
);
795 dc
.DrawText( _T("There should be no text below"), 110, 150 );
796 dc
.DrawRectangle( 110, y
, 100, height
);
798 // twice drawn inverted should result in invisible
800 dc
.DrawText( _T("Invisible text"), 110, y
);
801 dc
.DrawRectangle( 110, y
, 100, height
);
802 dc
.DrawText( _T("Invisible text"), 110, y
);
803 dc
.DrawRectangle( 110, y
, 100, height
);
804 dc
.SetLogicalFunction(wxCOPY
);
807 dc
.DrawRectangle( 110, y
, 100, height
);
808 dc
.DrawText( _T("Visible text"), 110, y
);
815 } rasterOperations
[] =
817 { wxT("wxAND"), wxAND
},
818 { wxT("wxAND_INVERT"), wxAND_INVERT
},
819 { wxT("wxAND_REVERSE"), wxAND_REVERSE
},
820 { wxT("wxCLEAR"), wxCLEAR
},
821 { wxT("wxCOPY"), wxCOPY
},
822 { wxT("wxEQUIV"), wxEQUIV
},
823 { wxT("wxINVERT"), wxINVERT
},
824 { wxT("wxNAND"), wxNAND
},
825 { wxT("wxNO_OP"), wxNO_OP
},
826 { wxT("wxOR"), wxOR
},
827 { wxT("wxOR_INVERT"), wxOR_INVERT
},
828 { wxT("wxOR_REVERSE"), wxOR_REVERSE
},
829 { wxT("wxSET"), wxSET
},
830 { wxT("wxSRC_INVERT"), wxSRC_INVERT
},
831 { wxT("wxXOR"), wxXOR
},
834 void MyCanvas::DrawImages(wxDC
& dc
)
836 dc
.DrawText(_T("original image"), 0, 0);
837 dc
.DrawBitmap(*gs_bmpNoMask
, 0, 20, 0);
838 dc
.DrawText(_T("with colour mask"), 0, 100);
839 dc
.DrawBitmap(*gs_bmpWithColMask
, 0, 120, true);
840 dc
.DrawText(_T("the mask image"), 0, 200);
841 dc
.DrawBitmap(*gs_bmpMask
, 0, 220, 0);
842 dc
.DrawText(_T("masked image"), 0, 300);
843 dc
.DrawBitmap(*gs_bmpWithMask
, 0, 320, true);
845 int cx
= gs_bmpWithColMask
->GetWidth(),
846 cy
= gs_bmpWithColMask
->GetHeight();
849 for ( size_t n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
851 wxCoord x
= 120 + 150*(n%4
),
854 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
855 memDC
.SelectObject(*gs_bmpWithColMask
);
856 dc
.Blit(x
, y
, cx
, cy
, &memDC
, 0, 0, rasterOperations
[n
].rop
, true);
860 void MyCanvas::DrawWithLogicalOps(wxDC
& dc
)
862 static const wxCoord w
= 60;
863 static const wxCoord h
= 60;
865 // reuse the text colour here
866 dc
.SetPen(wxPen(m_owner
->m_colourForeground
, 1, wxSOLID
));
867 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
870 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
872 wxCoord x
= 20 + 150*(n%4
),
875 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
876 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
877 dc
.DrawRectangle(x
, y
, w
, h
);
878 dc
.DrawLine(x
, y
, x
+ w
, y
+ h
);
879 dc
.DrawLine(x
+ w
, y
, x
, y
+ h
);
882 // now some filled rectangles
883 dc
.SetBrush(wxBrush(m_owner
->m_colourForeground
, wxSOLID
));
885 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
887 wxCoord x
= 20 + 150*(n%4
),
890 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
891 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
892 dc
.DrawRectangle(x
, y
, w
, h
);
896 #if wxUSE_GRAPHICS_CONTEXT
897 void MyCanvas::DrawAlpha(wxDC
& dc
)
899 wxDouble margin
= 20 ;
900 wxDouble width
= 180 ;
901 wxDouble radius
= 30 ;
903 dc
.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID
));
904 dc
.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID
));
906 wxRect
r(margin
,margin
+width
*0.66,width
,width
) ;
908 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
910 dc
.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID
));
911 dc
.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID
));
913 r
.Offset( width
* 0.8 , - width
* 0.66 ) ;
915 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
917 dc
.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID
));
918 dc
.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID
));
920 r
.Offset( width
* 0.8 , width
*0.5 ) ;
922 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
924 dc
.SetPen( *wxTRANSPARENT_PEN
) ;
925 dc
.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
926 dc
.DrawRoundedRectangle( 0 , margin
+ width
/ 2 , width
* 3 , 100 , radius
) ;
931 void MyCanvas::DrawCircles(wxDC
& dc
)
937 dc
.SetPen( *wxRED_PEN
);
938 dc
.SetBrush( *wxGREEN_BRUSH
);
940 dc
.DrawText(_T("Some circles"), 0, y
);
941 dc
.DrawCircle(x
, y
, r
);
942 dc
.DrawCircle(x
+ 2*r
, y
, r
);
943 dc
.DrawCircle(x
+ 4*r
, y
, r
);
946 dc
.DrawText(_T("And ellipses"), 0, y
);
947 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
948 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
949 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
952 dc
.DrawText(_T("And arcs"), 0, y
);
953 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
954 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
955 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
958 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
959 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
960 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
961 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
963 // same as above, just transparent brush
965 dc
.SetPen( *wxRED_PEN
);
966 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
969 dc
.DrawText(_T("Some circles"), 0, y
);
970 dc
.DrawCircle(x
, y
, r
);
971 dc
.DrawCircle(x
+ 2*r
, y
, r
);
972 dc
.DrawCircle(x
+ 4*r
, y
, r
);
975 dc
.DrawText(_T("And ellipses"), 0, y
);
976 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
977 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
978 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
981 dc
.DrawText(_T("And arcs"), 0, y
);
982 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
983 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
984 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
987 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
988 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
989 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
990 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
994 void MyCanvas::DrawSplines(wxDC
& dc
)
997 dc
.DrawText(_T("Some splines"), 10, 5);
999 // values are hardcoded rather than randomly generated
1000 // so the output can be compared between native
1001 // implementations on platforms with different random
1005 const wxPoint
center( R
+ 20, R
+ 20 );
1006 const int angles
[7] = { 0, 10, 33, 77, 13, 145, 90 };
1007 const int radii
[5] = { 100 , 59, 85, 33, 90 };
1011 // background spline calculation
1012 unsigned int radius_pos
= 0;
1013 unsigned int angle_pos
= 0;
1015 for ( int i
= 0; i
< n
; i
++ )
1017 angle
+= angles
[ angle_pos
];
1018 int r
= R
* radii
[ radius_pos
] / 100;
1019 pts
[ i
].x
= center
.x
+ (wxCoord
)( r
* cos( M_PI
* angle
/ 180.0) );
1020 pts
[ i
].y
= center
.y
+ (wxCoord
)( r
* sin( M_PI
* angle
/ 180.0) );
1023 if ( angle_pos
>= WXSIZEOF(angles
) ) angle_pos
= 0;
1026 if ( radius_pos
>= WXSIZEOF(radii
) ) radius_pos
= 0;
1029 // background spline drawing
1030 dc
.SetPen(*wxRED_PEN
);
1031 dc
.DrawSpline(WXSIZEOF(pts
), pts
);
1033 // less detailed spline calculation
1034 wxPoint letters
[4][5];
1036 letters
[0][0] = wxPoint( 0,1); // O O
1037 letters
[0][1] = wxPoint( 1,3); // * *
1038 letters
[0][2] = wxPoint( 2,2); // * O *
1039 letters
[0][3] = wxPoint( 3,3); // * * * *
1040 letters
[0][4] = wxPoint( 4,1); // O O
1042 letters
[1][0] = wxPoint( 5,1); // O*O
1043 letters
[1][1] = wxPoint( 6,1); // *
1044 letters
[1][2] = wxPoint( 7,2); // O
1045 letters
[1][3] = wxPoint( 8,3); // *
1046 letters
[1][4] = wxPoint( 9,3); // O*O
1048 letters
[2][0] = wxPoint( 5,3); // O*O
1049 letters
[2][1] = wxPoint( 6,3); // *
1050 letters
[2][2] = wxPoint( 7,2); // O
1051 letters
[2][3] = wxPoint( 8,1); // *
1052 letters
[2][4] = wxPoint( 9,1); // O*O
1054 letters
[3][0] = wxPoint(10,0); // O O
1055 letters
[3][1] = wxPoint(11,3); // * *
1056 letters
[3][2] = wxPoint(12,1); // * O *
1057 letters
[3][3] = wxPoint(13,3); // * * * *
1058 letters
[3][4] = wxPoint(14,0); // O O
1060 const int dx
= 2 * R
/ letters
[3][4].x
;
1061 const int h
[4] = { -R
/2, 0, R
/4, R
/2 };
1063 for ( int m
= 0; m
< 4; m
++ )
1065 for ( int n
= 0; n
< 5; n
++ )
1067 letters
[m
][n
].x
= center
.x
- R
+ letters
[m
][n
].x
* dx
;
1068 letters
[m
][n
].y
= center
.y
+ h
[ letters
[m
][n
].y
];
1071 dc
.SetPen( wxPen( wxT("blue"), 1, wxDOT
) );
1072 dc
.DrawLines(5, letters
[m
]);
1073 dc
.SetPen( wxPen( wxT("black"), 4, wxSOLID
) );
1074 dc
.DrawSpline(5, letters
[m
]);
1078 dc
.DrawText(_T("Splines not supported."), 10, 5);
1082 void MyCanvas::DrawGradients(wxDC
& dc
)
1085 wxRect
r(10, 10, 100, 100);
1086 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxRIGHT
);
1089 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxLEFT
);
1092 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxDOWN
);
1095 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxUP
);
1099 r
= wxRect(200, 10, 100, 100);
1100 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
);
1103 dc
.GradientFillConcentric(r
, *wxWHITE
, *wxBLUE
);
1106 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(0, 0));
1109 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(100, 100));
1112 void MyCanvas::DrawRegions(wxDC
& dc
)
1114 dc
.DrawText(_T("You should see a red rect partly covered by a cyan one ")
1115 _T("on the left"), 10, 5);
1116 dc
.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
1117 10, 5 + dc
.GetCharHeight());
1118 dc
.DrawText(_T("The second copy should be identical but right part of it ")
1119 _T("should be offset by 10 pixels."),
1120 10, 5 + 2*dc
.GetCharHeight());
1122 DrawRegionsHelper(dc
, 10, true);
1123 DrawRegionsHelper(dc
, 350, false);
1126 void MyCanvas::DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
)
1130 dc
.DestroyClippingRegion();
1131 dc
.SetBrush( *wxWHITE_BRUSH
);
1132 dc
.SetPen( *wxTRANSPARENT_PEN
);
1133 dc
.DrawRectangle( x
, y
, 310, 310 );
1135 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 270 );
1137 dc
.SetBrush( *wxRED_BRUSH
);
1138 dc
.DrawRectangle( x
, y
, 310, 310 );
1140 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 100 );
1142 dc
.SetBrush( *wxCYAN_BRUSH
);
1143 dc
.DrawRectangle( x
, y
, 310, 310 );
1145 dc
.DestroyClippingRegion();
1147 wxRegion
region(x
+ 110, y
+ 20, 100, 270);
1148 #if !defined(__WXMOTIF__) && !defined(__WXMAC__)
1150 region
.Offset(10, 10);
1152 dc
.SetClippingRegion(region
);
1154 dc
.SetBrush( *wxGREY_BRUSH
);
1155 dc
.DrawRectangle( x
, y
, 310, 310 );
1157 if (m_smile_bmp
.Ok())
1159 dc
.DrawBitmap( m_smile_bmp
, x
+ 150, y
+ 150, true );
1160 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 10, true );
1161 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 280, true );
1162 dc
.DrawBitmap( m_smile_bmp
, x
+ 100, y
+ 70, true );
1163 dc
.DrawBitmap( m_smile_bmp
, x
+ 200, y
+ 70, true );
1167 void MyCanvas::OnPaint(wxPaintEvent
&WXUNUSED(event
))
1169 wxPaintDC
pdc(this);
1171 #if wxUSE_GRAPHICS_CONTEXT
1173 wxDC
&dc
= m_useContext
? (wxDC
&) gdc
: (wxDC
&) pdc
;
1180 m_owner
->PrepareDC(dc
);
1182 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
1183 if ( m_owner
->m_backgroundBrush
.Ok() )
1184 dc
.SetBackground( m_owner
->m_backgroundBrush
);
1185 if ( m_owner
->m_colourForeground
.Ok() )
1186 dc
.SetTextForeground( m_owner
->m_colourForeground
);
1187 if ( m_owner
->m_colourBackground
.Ok() )
1188 dc
.SetTextBackground( m_owner
->m_colourBackground
);
1190 if ( m_owner
->m_textureBackground
) {
1191 if ( ! m_owner
->m_backgroundBrush
.Ok() ) {
1192 wxColour
clr(0,128,0);
1193 wxBrush
b(clr
, wxSOLID
);
1194 dc
.SetBackground(b
);
1199 dc
.SetClippingRegion(100, 100, 100, 100);
1203 if ( m_owner
->m_textureBackground
)
1205 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
1206 for ( int i
= 0; i
< 200; i
++ )
1207 dc
.DrawLine(0, i
*10, i
*10, 0);
1233 DrawTestLines( 0, 100, 0, dc
);
1234 DrawTestLines( 0, 320, 1, dc
);
1235 DrawTestLines( 0, 540, 2, dc
);
1236 DrawTestLines( 0, 760, 6, dc
);
1240 DrawTestBrushes(dc
);
1252 DrawWithLogicalOps(dc
);
1255 #if wxUSE_GRAPHICS_CONTEXT
1270 void MyCanvas::OnMouseMove(wxMouseEvent
&event
)
1273 wxClientDC
dc(this);
1275 m_owner
->PrepareDC(dc
);
1277 wxPoint pos
= event
.GetPosition();
1278 long x
= dc
.DeviceToLogicalX( pos
.x
);
1279 long y
= dc
.DeviceToLogicalY( pos
.y
);
1281 str
.Printf( wxT("Current mouse position: %d,%d"), (int)x
, (int)y
);
1282 m_owner
->SetStatusText( str
);
1285 #endif // wxUSE_STATUSBAR
1288 // ----------------------------------------------------------------------------
1290 // ----------------------------------------------------------------------------
1292 // the event tables connect the wxWidgets events with the functions (event
1293 // handlers) which process them. It can be also done at run-time, but for the
1294 // simple menu events like this the static method is much simpler.
1295 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
1296 EVT_MENU (File_Quit
, MyFrame::OnQuit
)
1297 EVT_MENU (File_About
, MyFrame::OnAbout
)
1298 EVT_MENU (File_Clip
, MyFrame::OnClip
)
1299 #if wxUSE_GRAPHICS_CONTEXT
1300 EVT_MENU (File_GraphicContext
, MyFrame::OnGraphicContext
)
1303 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame::OnShow
)
1305 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame::OnOption
)
1308 // frame constructor
1309 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
1310 : wxFrame((wxFrame
*)NULL
, wxID_ANY
, title
, pos
, size
,
1311 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
1313 // set the frame icon
1314 SetIcon(wxICON(mondrian
));
1316 wxMenu
*menuFile
= new wxMenu
;
1317 menuFile
->Append(File_ShowDefault
, _T("&Default screen\tF1"));
1318 menuFile
->Append(File_ShowText
, _T("&Text screen\tF2"));
1319 menuFile
->Append(File_ShowLines
, _T("&Lines screen\tF3"));
1320 menuFile
->Append(File_ShowBrushes
, _T("&Brushes screen\tF4"));
1321 menuFile
->Append(File_ShowPolygons
, _T("&Polygons screen\tF5"));
1322 menuFile
->Append(File_ShowMask
, _T("&Mask screen\tF6"));
1323 menuFile
->Append(File_ShowOps
, _T("&ROP screen\tF7"));
1324 menuFile
->Append(File_ShowRegions
, _T("Re&gions screen\tF8"));
1325 menuFile
->Append(File_ShowCircles
, _T("&Circles screen\tF9"));
1326 #if wxUSE_GRAPHICS_CONTEXT
1327 menuFile
->Append(File_ShowAlpha
, _T("&Alpha screen\tF10"));
1329 menuFile
->Append(File_ShowSplines
, _T("&Splines screen\tF11"));
1330 menuFile
->Append(File_ShowGradients
, _T("&Gradients screen\tF12"));
1331 menuFile
->AppendSeparator();
1332 menuFile
->AppendCheckItem(File_Clip
, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
1333 #if wxUSE_GRAPHICS_CONTEXT
1334 menuFile
->AppendCheckItem(File_GraphicContext
, _T("&Use GraphicContext\tCtrl-Y"), _T("Use GraphicContext"));
1336 menuFile
->AppendSeparator();
1337 menuFile
->Append(File_About
, _T("&About...\tCtrl-A"), _T("Show about dialog"));
1338 menuFile
->AppendSeparator();
1339 menuFile
->Append(File_Quit
, _T("E&xit\tAlt-X"), _T("Quit this program"));
1341 wxMenu
*menuMapMode
= new wxMenu
;
1342 menuMapMode
->Append( MapMode_Text
, _T("&TEXT map mode") );
1343 menuMapMode
->Append( MapMode_Lometric
, _T("&LOMETRIC map mode") );
1344 menuMapMode
->Append( MapMode_Twips
, _T("T&WIPS map mode") );
1345 menuMapMode
->Append( MapMode_Points
, _T("&POINTS map mode") );
1346 menuMapMode
->Append( MapMode_Metric
, _T("&METRIC map mode") );
1348 wxMenu
*menuUserScale
= new wxMenu
;
1349 menuUserScale
->Append( UserScale_StretchHoriz
, _T("Stretch &horizontally\tCtrl-H") );
1350 menuUserScale
->Append( UserScale_ShrinkHoriz
, _T("Shrin&k horizontally\tCtrl-G") );
1351 menuUserScale
->Append( UserScale_StretchVertic
, _T("Stretch &vertically\tCtrl-V") );
1352 menuUserScale
->Append( UserScale_ShrinkVertic
, _T("&Shrink vertically\tCtrl-W") );
1353 menuUserScale
->AppendSeparator();
1354 menuUserScale
->Append( UserScale_Restore
, _T("&Restore to normal\tCtrl-0") );
1356 wxMenu
*menuAxis
= new wxMenu
;
1357 menuAxis
->AppendCheckItem( AxisMirror_Horiz
, _T("Mirror horizontally\tCtrl-M") );
1358 menuAxis
->AppendCheckItem( AxisMirror_Vertic
, _T("Mirror vertically\tCtrl-N") );
1360 wxMenu
*menuLogical
= new wxMenu
;
1361 menuLogical
->Append( LogicalOrigin_MoveDown
, _T("Move &down\tCtrl-D") );
1362 menuLogical
->Append( LogicalOrigin_MoveUp
, _T("Move &up\tCtrl-U") );
1363 menuLogical
->Append( LogicalOrigin_MoveLeft
, _T("Move &right\tCtrl-L") );
1364 menuLogical
->Append( LogicalOrigin_MoveRight
, _T("Move &left\tCtrl-R") );
1365 menuLogical
->AppendSeparator();
1366 menuLogical
->Append( LogicalOrigin_Set
, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1367 menuLogical
->Append( LogicalOrigin_Restore
, _T("&Restore to normal\tShift-Ctrl-0") );
1369 wxMenu
*menuColour
= new wxMenu
;
1371 menuColour
->Append( Colour_TextForeground
, _T("Text &foreground...") );
1372 menuColour
->Append( Colour_TextBackground
, _T("Text &background...") );
1373 menuColour
->Append( Colour_Background
, _T("Background &colour...") );
1374 #endif // wxUSE_COLOURDLG
1375 menuColour
->AppendCheckItem( Colour_BackgroundMode
, _T("&Opaque/transparent\tCtrl-B") );
1376 menuColour
->AppendCheckItem( Colour_TextureBackgound
, _T("Draw textured back&ground\tCtrl-T") );
1378 // now append the freshly created menu to the menu bar...
1379 wxMenuBar
*menuBar
= new wxMenuBar
;
1380 menuBar
->Append(menuFile
, _T("&File"));
1381 menuBar
->Append(menuMapMode
, _T("&Mode"));
1382 menuBar
->Append(menuUserScale
, _T("&Scale"));
1383 menuBar
->Append(menuAxis
, _T("&Axis"));
1384 menuBar
->Append(menuLogical
, _T("&Origin"));
1385 menuBar
->Append(menuColour
, _T("&Colours"));
1387 // ... and attach this menu bar to the frame
1388 SetMenuBar(menuBar
);
1392 SetStatusText(_T("Welcome to wxWidgets!"));
1393 #endif // wxUSE_STATUSBAR
1395 m_mapMode
= wxMM_TEXT
;
1398 m_xLogicalOrigin
= 0;
1399 m_yLogicalOrigin
= 0;
1401 m_yAxisReversed
= false;
1402 m_backgroundMode
= wxSOLID
;
1403 m_colourForeground
= *wxRED
;
1404 m_colourBackground
= *wxBLUE
;
1405 m_textureBackground
= false;
1407 m_canvas
= new MyCanvas( this );
1408 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1413 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1415 // true is to force the frame to close
1419 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1422 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1423 wxT("This sample tests various primitive drawing functions\n")
1424 wxT("(without any attempts to prevent flicker).\n")
1425 wxT("Copyright (c) Robert Roebling 1999")
1428 wxMessageBox(msg
, _T("About Drawing"), wxOK
| wxICON_INFORMATION
, this);
1431 void MyFrame::OnClip(wxCommandEvent
& event
)
1433 m_canvas
->Clip(event
.IsChecked());
1436 #if wxUSE_GRAPHICS_CONTEXT
1437 void MyFrame::OnGraphicContext(wxCommandEvent
& event
)
1439 m_canvas
->UseGraphicContext(event
.IsChecked());
1443 void MyFrame::OnShow(wxCommandEvent
& event
)
1445 m_canvas
->ToShow((ScreenToShow
)(event
.GetId() - MenuShow_First
));
1448 void MyFrame::OnOption(wxCommandEvent
& event
)
1450 switch (event
.GetId())
1453 m_mapMode
= wxMM_TEXT
;
1455 case MapMode_Lometric
:
1456 m_mapMode
= wxMM_LOMETRIC
;
1459 m_mapMode
= wxMM_TWIPS
;
1461 case MapMode_Points
:
1462 m_mapMode
= wxMM_POINTS
;
1464 case MapMode_Metric
:
1465 m_mapMode
= wxMM_METRIC
;
1468 case LogicalOrigin_MoveDown
:
1469 m_yLogicalOrigin
+= 10;
1471 case LogicalOrigin_MoveUp
:
1472 m_yLogicalOrigin
-= 10;
1474 case LogicalOrigin_MoveLeft
:
1475 m_xLogicalOrigin
+= 10;
1477 case LogicalOrigin_MoveRight
:
1478 m_xLogicalOrigin
-= 10;
1480 case LogicalOrigin_Set
:
1482 m_yLogicalOrigin
= -100;
1484 case LogicalOrigin_Restore
:
1486 m_yLogicalOrigin
= 0;
1489 case UserScale_StretchHoriz
:
1490 m_xUserScale
*= 1.10;
1492 case UserScale_ShrinkHoriz
:
1493 m_xUserScale
/= 1.10;
1495 case UserScale_StretchVertic
:
1496 m_yUserScale
*= 1.10;
1498 case UserScale_ShrinkVertic
:
1499 m_yUserScale
/= 1.10;
1501 case UserScale_Restore
:
1506 case AxisMirror_Vertic
:
1507 m_yAxisReversed
= !m_yAxisReversed
;
1509 case AxisMirror_Horiz
:
1510 m_xAxisReversed
= !m_xAxisReversed
;
1514 case Colour_TextForeground
:
1515 m_colourForeground
= SelectColour();
1517 case Colour_TextBackground
:
1518 m_colourBackground
= SelectColour();
1520 case Colour_Background
:
1522 wxColour col
= SelectColour();
1525 m_backgroundBrush
.SetColour(col
);
1529 #endif // wxUSE_COLOURDLG
1531 case Colour_BackgroundMode
:
1532 m_backgroundMode
= m_backgroundMode
== wxSOLID
? wxTRANSPARENT
1536 case Colour_TextureBackgound
:
1537 m_textureBackground
= ! m_textureBackground
;
1545 m_canvas
->Refresh();
1548 void MyFrame::PrepareDC(wxDC
& dc
)
1550 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
1551 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
1552 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
1553 dc
.SetMapMode( m_mapMode
);
1557 wxColour
MyFrame::SelectColour()
1561 wxColourDialog
dialog(this, &data
);
1563 if ( dialog
.ShowModal() == wxID_OK
)
1565 col
= dialog
.GetColourData().GetColour();
1570 #endif // wxUSE_COLOURDLG