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"
36 #include "wx/dcgraph.h"
37 #include "wx/overlay.h"
38 #include "wx/graphics.h"
39 #include "wx/filename.h"
40 #include "wx/metafile.h"
42 #define TEST_CAIRO_EVERYWHERE 0
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 // the application icon
49 #if !defined(__WXMSW__) && !defined(__WXPM__)
50 #include "../sample.xpm"
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 static wxBitmap
*gs_bmpNoMask
= NULL
,
58 *gs_bmpWithColMask
= NULL
,
60 *gs_bmpWithMask
= NULL
,
65 // ----------------------------------------------------------------------------
67 // ----------------------------------------------------------------------------
69 // Define a new application type, each program should derive a class from wxApp
70 class MyApp
: public wxApp
73 // override base class virtuals
74 // ----------------------------
76 // this one is called on application startup and is a good place for the app
77 // initialization (doing it here and not in the ctor allows to have an error
78 // return: if OnInit() returns false, the application terminates)
79 virtual bool OnInit();
81 virtual int OnExit() { DeleteBitmaps(); return 0; }
91 // Define a new frame type: this is going to be our main frame
92 class MyFrame
: public wxFrame
96 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
98 // event handlers (these functions should _not_ be virtual)
99 void OnQuit(wxCommandEvent
& event
);
100 void OnAbout(wxCommandEvent
& event
);
101 void OnClip(wxCommandEvent
& event
);
102 #if wxUSE_GRAPHICS_CONTEXT
103 void OnGraphicContext(wxCommandEvent
& event
);
105 void OnCopy(wxCommandEvent
& event
);
106 void OnSave(wxCommandEvent
& event
);
107 void OnShow(wxCommandEvent
&event
);
108 void OnOption(wxCommandEvent
&event
);
111 wxColour
SelectColour();
112 #endif // wxUSE_COLOURDLG
113 void PrepareDC(wxDC
& dc
);
115 int m_backgroundMode
;
116 int m_textureBackground
;
117 wxMappingMode m_mapMode
;
120 int m_xLogicalOrigin
;
121 int m_yLogicalOrigin
;
122 bool m_xAxisReversed
,
124 wxColour m_colourForeground
, // these are _text_ colours
126 wxBrush m_backgroundBrush
;
130 // any class wishing to process wxWidgets events must use this macro
131 DECLARE_EVENT_TABLE()
134 // define a scrollable canvas for drawing onto
135 class MyCanvas
: public wxScrolledWindow
138 MyCanvas( MyFrame
*parent
);
140 void OnPaint(wxPaintEvent
&event
);
141 void OnMouseMove(wxMouseEvent
&event
);
142 void OnMouseDown(wxMouseEvent
&event
);
143 void OnMouseUp(wxMouseEvent
&event
);
145 void ToShow(int show
) { m_show
= show
; Refresh(); }
147 // set or remove the clipping region
148 void Clip(bool clip
) { m_clip
= clip
; Refresh(); }
149 #if wxUSE_GRAPHICS_CONTEXT
150 void UseGraphicContext(bool use
) { m_useContext
= use
; Refresh(); }
161 void DrawTestLines( int x
, int y
, int width
, wxDC
&dc
);
162 void DrawTestPoly(wxDC
& dc
);
163 void DrawTestBrushes(wxDC
& dc
);
164 void DrawText(wxDC
& dc
);
165 void DrawImages(wxDC
& dc
, DrawMode mode
);
166 void DrawWithLogicalOps(wxDC
& dc
);
167 #if wxUSE_GRAPHICS_CONTEXT
168 void DrawAlpha(wxDC
& dc
);
169 void DrawGraphics(wxGraphicsContext
* gc
);
171 void DrawRegions(wxDC
& dc
);
172 void DrawCircles(wxDC
& dc
);
173 void DrawSplines(wxDC
& dc
);
174 void DrawDefault(wxDC
& dc
);
175 void DrawGradients(wxDC
& dc
);
177 void DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
);
183 wxBitmap m_smile_bmp
;
188 wxPoint m_anchorpoint
;
189 wxPoint m_currentpoint
;
190 #if wxUSE_GRAPHICS_CONTEXT
194 DECLARE_EVENT_TABLE()
197 // ----------------------------------------------------------------------------
199 // ----------------------------------------------------------------------------
201 // IDs for the controls and the menu commands
205 File_Quit
= wxID_EXIT
,
206 File_About
= wxID_ABOUT
,
208 MenuShow_First
= wxID_HIGHEST
,
209 File_ShowDefault
= MenuShow_First
,
215 File_ShowMaskStretch
,
220 #if wxUSE_GRAPHICS_CONTEXT
225 MenuShow_Last
= File_ShowGradients
,
228 #if wxUSE_GRAPHICS_CONTEXT
236 MapMode_Text
= MenuOption_First
,
242 UserScale_StretchHoriz
,
243 UserScale_ShrinkHoriz
,
244 UserScale_StretchVertic
,
245 UserScale_ShrinkVertic
,
251 LogicalOrigin_MoveDown
,
252 LogicalOrigin_MoveUp
,
253 LogicalOrigin_MoveLeft
,
254 LogicalOrigin_MoveRight
,
256 LogicalOrigin_Restore
,
259 Colour_TextForeground
,
260 Colour_TextBackground
,
262 #endif // wxUSE_COLOURDLG
263 Colour_BackgroundMode
,
264 Colour_TextureBackgound
,
266 MenuOption_Last
= Colour_TextureBackgound
269 // ----------------------------------------------------------------------------
270 // event tables and other macros for wxWidgets
271 // ----------------------------------------------------------------------------
274 // Create a new application object: this macro will allow wxWidgets to create
275 // the application object during program execution (it's better than using a
276 // static object for many reasons) and also declares the accessor function
277 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
281 // ============================================================================
283 // ============================================================================
285 // ----------------------------------------------------------------------------
286 // the application class
287 // ----------------------------------------------------------------------------
289 bool MyApp::LoadImages()
291 gs_bmpNoMask
= new wxBitmap
;
292 gs_bmpWithColMask
= new wxBitmap
;
293 gs_bmpMask
= new wxBitmap
;
294 gs_bmpWithMask
= new wxBitmap
;
295 gs_bmp4
= new wxBitmap
;
296 gs_bmp4_mono
= new wxBitmap
;
297 gs_bmp36
= new wxBitmap
;
300 // special hack for Unix in-tree sample build, don't do this in real
301 // programs, use wxStandardPaths instead
302 pathList
.Add(wxFileName(argv
[0]).GetPath());
303 pathList
.Add(wxT("."));
304 pathList
.Add(wxT(".."));
305 pathList
.Add(wxT("../.."));
307 wxString path
= pathList
.FindValidPath(wxT("pat4.bmp"));
311 /* 4 colour bitmap */
312 gs_bmp4
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
313 /* turn into mono-bitmap */
314 gs_bmp4_mono
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
315 wxMask
* mask4
= new wxMask(*gs_bmp4_mono
, *wxBLACK
);
316 gs_bmp4_mono
->SetMask(mask4
);
318 path
= pathList
.FindValidPath(wxT("pat36.bmp"));
321 gs_bmp36
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
322 wxMask
* mask36
= new wxMask(*gs_bmp36
, *wxBLACK
);
323 gs_bmp36
->SetMask(mask36
);
325 path
= pathList
.FindValidPath(wxT("image.bmp"));
328 gs_bmpNoMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
329 gs_bmpWithMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
330 gs_bmpWithColMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
332 path
= pathList
.FindValidPath(wxT("mask.bmp"));
335 gs_bmpMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
337 wxMask
*mask
= new wxMask(*gs_bmpMask
, *wxBLACK
);
338 gs_bmpWithMask
->SetMask(mask
);
340 mask
= new wxMask(*gs_bmpWithColMask
, *wxWHITE
);
341 gs_bmpWithColMask
->SetMask(mask
);
346 // `Main program' equivalent: the program execution "starts" here
349 if ( !wxApp::OnInit() )
352 // Create the main application window
353 MyFrame
*frame
= new MyFrame(wxT("Drawing sample"),
354 wxDefaultPosition
, wxSize(550, 840));
361 wxLogError(wxT("Can't load one of the bitmap files needed ")
362 wxT("for this sample from the current or parent ")
363 wxT("directory, please copy them there."));
365 // still continue, the sample can be used without images too if they're
366 // missing for whatever reason
369 wxImage::AddHandler( new wxPNGHandler
);
375 void MyApp::DeleteBitmaps()
377 wxDELETE(gs_bmpNoMask
);
378 wxDELETE(gs_bmpWithColMask
);
379 wxDELETE(gs_bmpMask
);
380 wxDELETE(gs_bmpWithMask
);
382 wxDELETE(gs_bmp4_mono
);
386 // ----------------------------------------------------------------------------
388 // ----------------------------------------------------------------------------
390 // the event tables connect the wxWidgets events with the functions (event
391 // handlers) which process them.
392 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
393 EVT_PAINT (MyCanvas::OnPaint
)
394 EVT_MOTION (MyCanvas::OnMouseMove
)
395 EVT_LEFT_DOWN (MyCanvas::OnMouseDown
)
396 EVT_LEFT_UP (MyCanvas::OnMouseUp
)
401 MyCanvas::MyCanvas(MyFrame
*parent
)
402 : wxScrolledWindow(parent
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
403 wxHSCROLL
| wxVSCROLL
| wxNO_FULL_REPAINT_ON_RESIZE
)
406 m_show
= File_ShowDefault
;
407 m_smile_bmp
= wxBitmap(smile_xpm
);
408 m_std_icon
= wxArtProvider::GetIcon(wxART_INFORMATION
);
410 m_rubberBand
= false;
411 #if wxUSE_GRAPHICS_CONTEXT
412 m_useContext
= false;
416 void MyCanvas::DrawTestBrushes(wxDC
& dc
)
418 static const wxCoord WIDTH
= 200;
419 static const wxCoord HEIGHT
= 80;
424 dc
.SetBrush(wxBrush(*wxGREEN
, wxSOLID
));
425 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
426 dc
.DrawText(wxT("Solid green"), x
+ 10, y
+ 10);
429 dc
.SetBrush(wxBrush(*wxRED
, wxCROSSDIAG_HATCH
));
430 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
431 dc
.DrawText(wxT("Diagonally hatched red"), x
+ 10, y
+ 10);
434 dc
.SetBrush(wxBrush(*wxBLUE
, wxCROSS_HATCH
));
435 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
436 dc
.DrawText(wxT("Cross hatched blue"), x
+ 10, y
+ 10);
439 dc
.SetBrush(wxBrush(*wxCYAN
, wxVERTICAL_HATCH
));
440 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
441 dc
.DrawText(wxT("Vertically hatched cyan"), x
+ 10, y
+ 10);
444 dc
.SetBrush(wxBrush(*wxBLACK
, wxHORIZONTAL_HATCH
));
445 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
446 dc
.DrawText(wxT("Horizontally hatched black"), x
+ 10, y
+ 10);
449 dc
.SetBrush(wxBrush(*gs_bmpMask
));
450 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
451 dc
.DrawText(wxT("Stipple mono"), x
+ 10, y
+ 10);
454 dc
.SetBrush(wxBrush(*gs_bmpNoMask
));
455 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
456 dc
.DrawText(wxT("Stipple colour"), x
+ 10, y
+ 10);
459 void MyCanvas::DrawTestPoly(wxDC
& dc
)
461 wxBrush
brushHatch(*wxRED
, wxFDIAGONAL_HATCH
);
462 dc
.SetBrush(brushHatch
);
465 star
[0] = wxPoint(100, 60);
466 star
[1] = wxPoint(60, 150);
467 star
[2] = wxPoint(160, 100);
468 star
[3] = wxPoint(40, 100);
469 star
[4] = wxPoint(140, 150);
471 dc
.DrawText(wxT("You should see two (irregular) stars below, the left one ")
472 wxT("hatched"), 10, 10);
473 dc
.DrawText(wxT("except for the central region and the right ")
474 wxT("one entirely hatched"), 10, 30);
475 dc
.DrawText(wxT("The third star only has a hatched outline"), 10, 50);
477 dc
.DrawPolygon(WXSIZEOF(star
), star
, 0, 30);
478 dc
.DrawPolygon(WXSIZEOF(star
), star
, 160, 30, wxWINDING_RULE
);
481 star2
[0] = wxPoint(0, 100);
482 star2
[1] = wxPoint(-59, -81);
483 star2
[2] = wxPoint(95, 31);
484 star2
[3] = wxPoint(-95, 31);
485 star2
[4] = wxPoint(59, -81);
486 star2
[5] = wxPoint(0, 80);
487 star2
[6] = wxPoint(-47, -64);
488 star2
[7] = wxPoint(76, 24);
489 star2
[8] = wxPoint(-76, 24);
490 star2
[9] = wxPoint(47, -64);
491 int count
[2] = {5, 5};
493 dc
.DrawPolyPolygon(WXSIZEOF(count
), count
, star2
, 450, 150);
496 void MyCanvas::DrawTestLines( int x
, int y
, int width
, wxDC
&dc
)
498 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
499 dc
.SetBrush( *wxRED_BRUSH
);
500 dc
.DrawText(wxString::Format(wxT("Testing lines of width %d"), width
), x
+ 10, y
- 10);
501 dc
.DrawRectangle( x
+10, y
+10, 100, 190 );
503 dc
.DrawText(wxT("Solid/dot/short dash/long dash/dot dash"), x
+ 150, y
+ 10);
504 dc
.SetPen( wxPen( wxT("black"), width
, wxSOLID
) );
505 dc
.DrawLine( x
+20, y
+20, 100, y
+20 );
506 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT
) );
507 dc
.DrawLine( x
+20, y
+30, 100, y
+30 );
508 dc
.SetPen( wxPen( wxT("black"), width
, wxSHORT_DASH
) );
509 dc
.DrawLine( x
+20, y
+40, 100, y
+40 );
510 dc
.SetPen( wxPen( wxT("black"), width
, wxLONG_DASH
) );
511 dc
.DrawLine( x
+20, y
+50, 100, y
+50 );
512 dc
.SetPen( wxPen( wxT("black"), width
, wxDOT_DASH
) );
513 dc
.DrawLine( x
+20, y
+60, 100, y
+60 );
515 dc
.DrawText(wxT("Misc hatches"), x
+ 150, y
+ 70);
516 dc
.SetPen( wxPen( wxT("black"), width
, wxBDIAGONAL_HATCH
) );
517 dc
.DrawLine( x
+20, y
+70, 100, y
+70 );
518 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSSDIAG_HATCH
) );
519 dc
.DrawLine( x
+20, y
+80, 100, y
+80 );
520 dc
.SetPen( wxPen( wxT("black"), width
, wxFDIAGONAL_HATCH
) );
521 dc
.DrawLine( x
+20, y
+90, 100, y
+90 );
522 dc
.SetPen( wxPen( wxT("black"), width
, wxCROSS_HATCH
) );
523 dc
.DrawLine( x
+20, y
+100, 100, y
+100 );
524 dc
.SetPen( wxPen( wxT("black"), width
, wxHORIZONTAL_HATCH
) );
525 dc
.DrawLine( x
+20, y
+110, 100, y
+110 );
526 dc
.SetPen( wxPen( wxT("black"), width
, wxVERTICAL_HATCH
) );
527 dc
.DrawLine( x
+20, y
+120, 100, y
+120 );
529 dc
.DrawText(wxT("User dash"), x
+ 150, y
+ 140);
530 wxPen
ud( wxT("black"), width
, wxUSER_DASH
);
532 dash1
[0] = 8; // Long dash <---------+
533 dash1
[1] = 2; // Short gap |
534 dash1
[2] = 3; // Short dash |
535 dash1
[3] = 2; // Short gap |
536 dash1
[4] = 3; // Short dash |
537 dash1
[5] = 2; // Short gap and repeat +
538 ud
.SetDashes( 6, dash1
);
540 dc
.DrawLine( x
+20, y
+140, 100, y
+140 );
541 dash1
[0] = 5; // Make first dash shorter
542 ud
.SetDashes( 6, dash1
);
544 dc
.DrawLine( x
+20, y
+150, 100, y
+150 );
545 dash1
[2] = 5; // Make second dash longer
546 ud
.SetDashes( 6, dash1
);
548 dc
.DrawLine( x
+20, y
+160, 100, y
+160 );
549 dash1
[4] = 5; // Make third dash longer
550 ud
.SetDashes( 6, dash1
);
552 dc
.DrawLine( x
+20, y
+170, 100, y
+170 );
555 void MyCanvas::DrawDefault(wxDC
& dc
)
558 dc
.DrawCircle(0, 0, 10);
560 #if !defined(wxMAC_USE_CORE_GRAPHICS) || !wxMAC_USE_CORE_GRAPHICS
561 // GetPixel and FloodFill not supported by Mac OS X CoreGraphics
562 // (FloodFill uses Blit from a non-wxMemoryDC)
563 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
564 dc
.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID
));
567 dc
.GetPixel(1,1, &tmpColour
);
568 dc
.FloodFill(1,1, tmpColour
, wxFLOOD_SURFACE
);
571 dc
.DrawCheckMark(5, 80, 15, 15);
572 dc
.DrawCheckMark(25, 80, 30, 30);
573 dc
.DrawCheckMark(60, 80, 60, 60);
575 // this is the test for "blitting bitmap into DC damages selected brush" bug
576 wxCoord rectSize
= m_std_icon
.GetWidth() + 10;
578 dc
.SetPen(*wxTRANSPARENT_PEN
);
579 dc
.SetBrush( *wxGREEN_BRUSH
);
580 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
581 dc
.DrawBitmap(m_std_icon
, x
+ 5, 15, true);
583 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
584 dc
.DrawIcon(m_std_icon
, x
+ 5, 15);
586 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
588 // test for "transparent" bitmap drawing (it intersects with the last
590 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
592 if (m_smile_bmp
.IsOk())
593 dc
.DrawBitmap(m_smile_bmp
, x
+ rectSize
- 20, rectSize
- 10, true);
595 dc
.SetBrush( *wxBLACK_BRUSH
);
596 dc
.DrawRectangle( 0, 160, 1000, 300 );
599 wxBitmap
bitmap(20,70);
601 memdc
.SelectObject( bitmap
);
602 memdc
.SetBrush( *wxBLACK_BRUSH
);
603 memdc
.SetPen( *wxWHITE_PEN
);
604 memdc
.DrawRectangle(0,0,20,70);
605 memdc
.DrawLine( 10,0,10,70 );
608 wxPen pen
= *wxRED_PEN
;
610 memdc
.DrawLine( 10, 5,10, 5 );
611 memdc
.DrawLine( 10,10,11,10 );
612 memdc
.DrawLine( 10,15,12,15 );
613 memdc
.DrawLine( 10,20,13,20 );
616 memdc.SetPen(*wxRED_PEN);
617 memdc.DrawLine( 12, 5,12, 5 );
618 memdc.DrawLine( 12,10,13,10 );
619 memdc.DrawLine( 12,15,14,15 );
620 memdc.DrawLine( 12,20,15,20 );
624 memdc
.DrawLine( 10,25,10,25 );
625 memdc
.DrawLine( 10,30, 9,30 );
626 memdc
.DrawLine( 10,35, 8,35 );
627 memdc
.DrawLine( 10,40, 7,40 );
630 dc
.SetPen(*wxWHITE_PEN
);
631 memdc
.SetLogicalFunction( wxINVERT
);
632 memdc
.SetPen( *wxWHITE_PEN
);
633 memdc
.DrawLine( 10,50,10,50 );
634 memdc
.DrawLine( 10,55,11,55 );
635 memdc
.DrawLine( 10,60,12,60 );
636 memdc
.DrawLine( 10,65,13,65 );
638 memdc
.DrawLine( 12,50,12,50 );
639 memdc
.DrawLine( 12,55,13,55 );
640 memdc
.DrawLine( 12,60,14,60 );
641 memdc
.DrawLine( 12,65,15,65 );
643 memdc
.SelectObject( wxNullBitmap
);
644 dc
.DrawBitmap( bitmap
, 10, 170 );
645 wxImage image
= bitmap
.ConvertToImage();
646 image
.Rescale( 60,210 );
647 bitmap
= wxBitmap(image
);
648 dc
.DrawBitmap( bitmap
, 50, 170 );
650 // test the rectangle outline drawing - there should be one pixel between
651 // the rect and the lines
652 dc
.SetPen(*wxWHITE_PEN
);
653 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
654 dc
.DrawRectangle(150, 170, 49, 29);
655 dc
.DrawRectangle(200, 170, 49, 29);
656 dc
.SetPen(*wxWHITE_PEN
);
657 dc
.DrawLine(250, 210, 250, 170);
658 dc
.DrawLine(260, 200, 150, 200);
660 // test the rectangle filled drawing - there should be one pixel between
661 // the rect and the lines
662 dc
.SetPen(*wxTRANSPARENT_PEN
);
663 dc
.SetBrush( *wxWHITE_BRUSH
);
664 dc
.DrawRectangle(300, 170, 49, 29);
665 dc
.DrawRectangle(350, 170, 49, 29);
666 dc
.SetPen(*wxWHITE_PEN
);
667 dc
.DrawLine(400, 170, 400, 210);
668 dc
.DrawLine(300, 200, 410, 200);
670 // a few more tests of this kind
671 dc
.SetPen(*wxRED_PEN
);
672 dc
.SetBrush( *wxWHITE_BRUSH
);
673 dc
.DrawRectangle(300, 220, 1, 1);
674 dc
.DrawRectangle(310, 220, 2, 2);
675 dc
.DrawRectangle(320, 220, 3, 3);
676 dc
.DrawRectangle(330, 220, 4, 4);
678 dc
.SetPen(*wxTRANSPARENT_PEN
);
679 dc
.SetBrush( *wxWHITE_BRUSH
);
680 dc
.DrawRectangle(300, 230, 1, 1);
681 dc
.DrawRectangle(310, 230, 2, 2);
682 dc
.DrawRectangle(320, 230, 3, 3);
683 dc
.DrawRectangle(330, 230, 4, 4);
685 // and now for filled rect with outline
686 dc
.SetPen(*wxRED_PEN
);
687 dc
.SetBrush( *wxWHITE_BRUSH
);
688 dc
.DrawRectangle(500, 170, 49, 29);
689 dc
.DrawRectangle(550, 170, 49, 29);
690 dc
.SetPen(*wxWHITE_PEN
);
691 dc
.DrawLine(600, 170, 600, 210);
692 dc
.DrawLine(500, 200, 610, 200);
694 // test the rectangle outline drawing - there should be one pixel between
695 // the rect and the lines
696 dc
.SetPen(*wxWHITE_PEN
);
697 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
698 dc
.DrawRoundedRectangle(150, 270, 49, 29, 6);
699 dc
.DrawRoundedRectangle(200, 270, 49, 29, 6);
700 dc
.SetPen(*wxWHITE_PEN
);
701 dc
.DrawLine(250, 270, 250, 310);
702 dc
.DrawLine(150, 300, 260, 300);
704 // test the rectangle filled drawing - there should be one pixel between
705 // the rect and the lines
706 dc
.SetPen(*wxTRANSPARENT_PEN
);
707 dc
.SetBrush( *wxWHITE_BRUSH
);
708 dc
.DrawRoundedRectangle(300, 270, 49, 29, 6);
709 dc
.DrawRoundedRectangle(350, 270, 49, 29, 6);
710 dc
.SetPen(*wxWHITE_PEN
);
711 dc
.DrawLine(400, 270, 400, 310);
712 dc
.DrawLine(300, 300, 410, 300);
714 // Added by JACS to demonstrate bizarre behaviour.
715 // With a size of 70, we get a missing red RHS,
716 // and the height is too small, so we get yellow
717 // showing. With a size of 40, it draws as expected:
718 // it just shows a white rectangle with red outline.
720 int totalHeight
= 70;
721 wxBitmap
bitmap2(totalWidth
, totalHeight
);
724 memdc2
.SelectObject(bitmap2
);
726 wxColour
clr(255, 255, 0);
727 wxBrush
yellowBrush(clr
, wxSOLID
);
728 memdc2
.SetBackground(yellowBrush
);
731 wxPen
yellowPen(clr
, 1, wxSOLID
);
733 // Now draw a white rectangle with red outline. It should
734 // entirely eclipse the yellow background.
735 memdc2
.SetPen(*wxRED_PEN
);
736 memdc2
.SetBrush(*wxWHITE_BRUSH
);
738 memdc2
.DrawRectangle(0, 0, totalWidth
, totalHeight
);
740 memdc2
.SetPen(wxNullPen
);
741 memdc2
.SetBrush(wxNullBrush
);
742 memdc2
.SelectObject(wxNullBitmap
);
744 dc
.DrawBitmap(bitmap2
, 500, 270);
746 // Repeat, but draw directly on dc
747 // Draw a yellow rectangle filling the bitmap
749 x
= 600; int y
= 270;
750 dc
.SetPen(yellowPen
);
751 dc
.SetBrush(yellowBrush
);
752 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
754 // Now draw a white rectangle with red outline. It should
755 // entirely eclipse the yellow background.
756 dc
.SetPen(*wxRED_PEN
);
757 dc
.SetBrush(*wxWHITE_BRUSH
);
759 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
762 void MyCanvas::DrawText(wxDC
& dc
)
764 // set underlined font for testing
765 dc
.SetFont( wxFont(12, wxMODERN
, wxNORMAL
, wxNORMAL
, true) );
766 dc
.DrawText( wxT("This is text"), 110, 10 );
767 dc
.DrawRotatedText( wxT("That is text"), 20, 10, -45 );
769 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
770 // under Win9x (it is not TrueType)
771 dc
.SetFont( *wxSWISS_FONT
);
774 dc
.SetBackgroundMode(wxTRANSPARENT
);
776 for ( int n
= -180; n
< 180; n
+= 30 )
778 text
.Printf(wxT(" %d rotated text"), n
);
779 dc
.DrawRotatedText(text
, 400, 400, n
);
782 dc
.SetFont( wxFont( 18, wxSWISS
, wxNORMAL
, wxNORMAL
) );
784 dc
.DrawText( wxT("This is Swiss 18pt text."), 110, 40 );
789 dc
.GetTextExtent( wxT("This is Swiss 18pt text."), &length
, &height
, &descent
);
790 text
.Printf( wxT("Dimensions are length %d, height %d, descent %d"), length
, height
, descent
);
791 dc
.DrawText( text
, 110, 80 );
793 text
.Printf( wxT("CharHeight() returns: %d"), dc
.GetCharHeight() );
794 dc
.DrawText( text
, 110, 120 );
796 dc
.DrawRectangle( 100, 40, 4, height
);
798 // test the logical function effect
800 dc
.SetLogicalFunction(wxINVERT
);
801 // text drawing should ignore logical function
802 dc
.DrawText( wxT("There should be a text below"), 110, 150 );
803 dc
.DrawRectangle( 110, y
, 100, height
);
806 dc
.DrawText( wxT("Visible text"), 110, y
);
807 dc
.DrawRectangle( 110, y
, 100, height
);
808 dc
.DrawText( wxT("Visible text"), 110, y
);
809 dc
.DrawRectangle( 110, y
, 100, height
);
810 dc
.SetLogicalFunction(wxCOPY
);
813 dc
.DrawRectangle( 110, y
, 100, height
);
814 dc
.DrawText( wxT("Another visible text"), 110, y
);
817 dc
.DrawText("And\nmore\ntext on\nmultiple\nlines", 110, y
);
823 wxRasterOperationMode rop
;
824 } rasterOperations
[] =
826 { wxT("wxAND"), wxAND
},
827 { wxT("wxAND_INVERT"), wxAND_INVERT
},
828 { wxT("wxAND_REVERSE"), wxAND_REVERSE
},
829 { wxT("wxCLEAR"), wxCLEAR
},
830 { wxT("wxCOPY"), wxCOPY
},
831 { wxT("wxEQUIV"), wxEQUIV
},
832 { wxT("wxINVERT"), wxINVERT
},
833 { wxT("wxNAND"), wxNAND
},
834 { wxT("wxNO_OP"), wxNO_OP
},
835 { wxT("wxOR"), wxOR
},
836 { wxT("wxOR_INVERT"), wxOR_INVERT
},
837 { wxT("wxOR_REVERSE"), wxOR_REVERSE
},
838 { wxT("wxSET"), wxSET
},
839 { wxT("wxSRC_INVERT"), wxSRC_INVERT
},
840 { wxT("wxXOR"), wxXOR
},
843 void MyCanvas::DrawImages(wxDC
& dc
, DrawMode mode
)
845 dc
.DrawText(wxT("original image"), 0, 0);
846 dc
.DrawBitmap(*gs_bmpNoMask
, 0, 20, 0);
847 dc
.DrawText(wxT("with colour mask"), 0, 100);
848 dc
.DrawBitmap(*gs_bmpWithColMask
, 0, 120, true);
849 dc
.DrawText(wxT("the mask image"), 0, 200);
850 dc
.DrawBitmap(*gs_bmpMask
, 0, 220, 0);
851 dc
.DrawText(wxT("masked image"), 0, 300);
852 dc
.DrawBitmap(*gs_bmpWithMask
, 0, 320, true);
854 int cx
= gs_bmpWithColMask
->GetWidth(),
855 cy
= gs_bmpWithColMask
->GetHeight();
858 for ( size_t n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
860 wxCoord x
= 120 + 150*(n%4
),
863 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
864 memDC
.SelectObject(*gs_bmpWithColMask
);
865 if ( mode
== Draw_Stretch
)
867 dc
.StretchBlit(x
, y
, cx
, cy
, &memDC
, 0, 0, cx
/2, cy
/2,
868 rasterOperations
[n
].rop
, true);
872 dc
.Blit(x
, y
, cx
, cy
, &memDC
, 0, 0, rasterOperations
[n
].rop
, true);
877 void MyCanvas::DrawWithLogicalOps(wxDC
& dc
)
879 static const wxCoord w
= 60;
880 static const wxCoord h
= 60;
882 // reuse the text colour here
883 dc
.SetPen(wxPen(m_owner
->m_colourForeground
, 1, wxSOLID
));
884 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
887 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
889 wxCoord x
= 20 + 150*(n%4
),
892 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
893 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
894 dc
.DrawRectangle(x
, y
, w
, h
);
895 dc
.DrawLine(x
, y
, x
+ w
, y
+ h
);
896 dc
.DrawLine(x
+ w
, y
, x
, y
+ h
);
899 // now some filled rectangles
900 dc
.SetBrush(wxBrush(m_owner
->m_colourForeground
, wxSOLID
));
902 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
904 wxCoord x
= 20 + 150*(n%4
),
907 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
908 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
909 dc
.DrawRectangle(x
, y
, w
, h
);
913 #if wxUSE_GRAPHICS_CONTEXT
915 void MyCanvas::DrawAlpha(wxDC
& WXUNUSED(dummyDC
))
917 void MyCanvas::DrawAlpha(wxDC
& dc
)
925 wxDouble margin
= 20 ;
926 wxDouble width
= 180 ;
927 wxDouble radius
= 30 ;
929 dc
.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID
));
930 dc
.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID
));
932 wxRect
r(margin
,margin
+width
*0.66,width
,width
) ;
934 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
936 dc
.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID
));
937 dc
.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID
));
939 r
.Offset( width
* 0.8 , - width
* 0.66 ) ;
941 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
943 dc
.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID
));
944 dc
.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID
));
946 r
.Offset( width
* 0.8 , width
*0.5 ) ;
948 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
950 dc
.SetPen( *wxTRANSPARENT_PEN
) ;
951 dc
.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
952 dc
.DrawRoundedRectangle( 0 , margin
+ width
/ 2 , width
* 3 , 100 , radius
) ;
954 dc
.SetTextForeground( wxColour(255,255,0,128) );
955 dc
.SetFont( wxFont( 40, wxFONTFAMILY_SWISS
, wxFONTSTYLE_ITALIC
, wxFONTWEIGHT_NORMAL
) );
956 dc
.DrawText( wxT("Hello!"), 120, 80 );
961 #if wxUSE_GRAPHICS_CONTEXT
963 const int BASE
= 80.0;
964 const int BASE2
= BASE
/2;
965 const int BASE4
= BASE
/4;
967 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
970 // modeled along Robin Dunn's GraphicsContext.py sample
972 void MyCanvas::DrawGraphics(wxGraphicsContext
* gc
)
974 wxFont font
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
975 gc
->SetFont(font
,*wxBLACK
);
977 // make a path that contains a circle and some lines, centered at 0,0
978 wxGraphicsPath path
= gc
->CreatePath() ;
979 path
.AddCircle( 0, 0, BASE2
);
980 path
.MoveToPoint(0, -BASE2
);
981 path
.AddLineToPoint(0, BASE2
);
982 path
.MoveToPoint(-BASE2
, 0);
983 path
.AddLineToPoint(BASE2
, 0);
985 path
.AddRectangle(-BASE4
, -BASE4
/2, BASE2
, BASE4
);
987 // Now use that path to demonstrate various capbilites of the grpahics context
988 gc
->PushState(); // save current translation/scale/other state
989 gc
->Translate(60, 75); // reposition the context origin
991 gc
->SetPen(wxPen("navy", 1));
992 gc
->SetBrush(wxBrush("pink"));
994 for( int i
= 0 ; i
< 3 ; ++i
)
1000 label
= "StrokePath";
1010 gc
->GetTextExtent(label
, &w
, &h
, NULL
, NULL
);
1011 gc
->DrawText(label
, -w
/2, -BASE2
-h
-4);
1015 gc
->StrokePath(path
);
1024 gc
->Translate(2*BASE
, 0);
1027 gc
->PopState(); // restore saved state
1028 gc
->PushState(); // save it again
1029 gc
->Translate(60, 200); // offset to the lower part of the window
1031 gc
->DrawText("Scale", 0, -BASE2
);
1032 gc
->Translate(0, 20);
1034 gc
->SetBrush(wxBrush(wxColour(178, 34, 34, 128)));// 128 == half transparent
1035 for( int i
= 0 ; i
< 8 ; ++i
)
1037 gc
->Scale(1.08, 1.08); // increase scale by 8%
1042 gc
->PopState(); // restore saved state
1043 gc
->PushState(); // save it again
1044 gc
->Translate(400, 200);
1046 gc
->DrawText("Rotate", 0, -BASE2
);
1048 // Move the origin over to the next location
1049 gc
->Translate(0, 75);
1051 // draw our path again, rotating it about the central point,
1052 // and changing colors as we go
1053 for ( int angle
= 0 ; angle
< 360 ; angle
+= 30 )
1055 gc
->PushState(); // save this new current state so we can
1056 // pop back to it at the end of the loop
1057 wxImage::RGBValue val
= wxImage::HSVtoRGB(wxImage::HSVValue(float(angle
)/360, 1, 1));
1058 gc
->SetBrush(wxBrush(wxColour(val
.red
, val
.green
, val
.blue
, 64)));
1059 gc
->SetPen(wxPen(wxColour(val
.red
, val
.green
, val
.blue
, 128)));
1061 // use translate to artfully reposition each drawn path
1062 gc
->Translate(1.5 * BASE2
* cos(DegToRad(angle
)),
1063 1.5 * BASE2
* sin(DegToRad(angle
)));
1065 // use Rotate to rotate the path
1066 gc
->Rotate(DegToRad(angle
));
1075 gc
->Translate(60, 400);
1076 gc
->DrawText("Scaled smiley inside a square", 0, 0);
1077 gc
->DrawRectangle(BASE2
, BASE2
, 100, 100);
1078 gc
->DrawBitmap(m_smile_bmp
, BASE2
, BASE2
, 100, 100);
1081 #endif // wxUSE_GRAPHICS_CONTEXT
1083 void MyCanvas::DrawCircles(wxDC
& dc
)
1089 dc
.SetPen( *wxRED_PEN
);
1090 dc
.SetBrush( *wxGREEN_BRUSH
);
1092 dc
.DrawText(wxT("Some circles"), 0, y
);
1093 dc
.DrawCircle(x
, y
, r
);
1094 dc
.DrawCircle(x
+ 2*r
, y
, r
);
1095 dc
.DrawCircle(x
+ 4*r
, y
, r
);
1098 dc
.DrawText(wxT("And ellipses"), 0, y
);
1099 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
1100 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
1101 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
1104 dc
.DrawText(wxT("And arcs"), 0, y
);
1105 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
1106 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
1107 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
1110 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
1111 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
1112 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
1113 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
1115 // same as above, just transparent brush
1117 dc
.SetPen( *wxRED_PEN
);
1118 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
1121 dc
.DrawText(wxT("Some circles"), 0, y
);
1122 dc
.DrawCircle(x
, y
, r
);
1123 dc
.DrawCircle(x
+ 2*r
, y
, r
);
1124 dc
.DrawCircle(x
+ 4*r
, y
, r
);
1127 dc
.DrawText(wxT("And ellipses"), 0, y
);
1128 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
1129 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
1130 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
1133 dc
.DrawText(wxT("And arcs"), 0, y
);
1134 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
1135 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
1136 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
1139 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
1140 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
1141 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
1142 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
1146 void MyCanvas::DrawSplines(wxDC
& dc
)
1149 dc
.DrawText(wxT("Some splines"), 10, 5);
1151 // values are hardcoded rather than randomly generated
1152 // so the output can be compared between native
1153 // implementations on platforms with different random
1157 const wxPoint
center( R
+ 20, R
+ 20 );
1158 const int angles
[7] = { 0, 10, 33, 77, 13, 145, 90 };
1159 const int radii
[5] = { 100 , 59, 85, 33, 90 };
1163 // background spline calculation
1164 unsigned int radius_pos
= 0;
1165 unsigned int angle_pos
= 0;
1167 for ( int i
= 0; i
< n
; i
++ )
1169 angle
+= angles
[ angle_pos
];
1170 int r
= R
* radii
[ radius_pos
] / 100;
1171 pts
[ i
].x
= center
.x
+ (wxCoord
)( r
* cos( M_PI
* angle
/ 180.0) );
1172 pts
[ i
].y
= center
.y
+ (wxCoord
)( r
* sin( M_PI
* angle
/ 180.0) );
1175 if ( angle_pos
>= WXSIZEOF(angles
) ) angle_pos
= 0;
1178 if ( radius_pos
>= WXSIZEOF(radii
) ) radius_pos
= 0;
1181 // background spline drawing
1182 dc
.SetPen(*wxRED_PEN
);
1183 dc
.DrawSpline(WXSIZEOF(pts
), pts
);
1185 // less detailed spline calculation
1186 wxPoint letters
[4][5];
1188 letters
[0][0] = wxPoint( 0,1); // O O
1189 letters
[0][1] = wxPoint( 1,3); // * *
1190 letters
[0][2] = wxPoint( 2,2); // * O *
1191 letters
[0][3] = wxPoint( 3,3); // * * * *
1192 letters
[0][4] = wxPoint( 4,1); // O O
1194 letters
[1][0] = wxPoint( 5,1); // O*O
1195 letters
[1][1] = wxPoint( 6,1); // *
1196 letters
[1][2] = wxPoint( 7,2); // O
1197 letters
[1][3] = wxPoint( 8,3); // *
1198 letters
[1][4] = wxPoint( 9,3); // O*O
1200 letters
[2][0] = wxPoint( 5,3); // O*O
1201 letters
[2][1] = wxPoint( 6,3); // *
1202 letters
[2][2] = wxPoint( 7,2); // O
1203 letters
[2][3] = wxPoint( 8,1); // *
1204 letters
[2][4] = wxPoint( 9,1); // O*O
1206 letters
[3][0] = wxPoint(10,0); // O O
1207 letters
[3][1] = wxPoint(11,3); // * *
1208 letters
[3][2] = wxPoint(12,1); // * O *
1209 letters
[3][3] = wxPoint(13,3); // * * * *
1210 letters
[3][4] = wxPoint(14,0); // O O
1212 const int dx
= 2 * R
/ letters
[3][4].x
;
1213 const int h
[4] = { -R
/2, 0, R
/4, R
/2 };
1215 for ( int m
= 0; m
< 4; m
++ )
1217 for ( int n
= 0; n
< 5; n
++ )
1219 letters
[m
][n
].x
= center
.x
- R
+ letters
[m
][n
].x
* dx
;
1220 letters
[m
][n
].y
= center
.y
+ h
[ letters
[m
][n
].y
];
1223 dc
.SetPen( wxPen( wxT("blue"), 1, wxDOT
) );
1224 dc
.DrawLines(5, letters
[m
]);
1225 dc
.SetPen( wxPen( wxT("black"), 4, wxSOLID
) );
1226 dc
.DrawSpline(5, letters
[m
]);
1230 dc
.DrawText(wxT("Splines not supported."), 10, 5);
1234 void MyCanvas::DrawGradients(wxDC
& dc
)
1236 static const int TEXT_HEIGHT
= 15;
1239 wxRect
r(10, 10, 50, 50);
1240 dc
.DrawText(wxT("wxRIGHT"), r
.x
, r
.y
);
1241 r
.Offset(0, TEXT_HEIGHT
);
1242 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxRIGHT
);
1244 r
.Offset(0, r
.height
+ 10);
1245 dc
.DrawText(wxT("wxLEFT"), r
.x
, r
.y
);
1246 r
.Offset(0, TEXT_HEIGHT
);
1247 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxLEFT
);
1249 r
.Offset(0, r
.height
+ 10);
1250 dc
.DrawText(wxT("wxDOWN"), r
.x
, r
.y
);
1251 r
.Offset(0, TEXT_HEIGHT
);
1252 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxDOWN
);
1254 r
.Offset(0, r
.height
+ 10);
1255 dc
.DrawText(wxT("wxUP"), r
.x
, r
.y
);
1256 r
.Offset(0, TEXT_HEIGHT
);
1257 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxUP
);
1259 wxRect gfr
= wxRect(r
);
1262 r
= wxRect(200, 10, 50, 50);
1263 dc
.DrawText(wxT("Blue inside"), r
.x
, r
.y
);
1264 r
.Offset(0, TEXT_HEIGHT
);
1265 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
);
1267 r
.Offset(0, r
.height
+ 10);
1268 dc
.DrawText(wxT("White inside"), r
.x
, r
.y
);
1269 r
.Offset(0, TEXT_HEIGHT
);
1270 dc
.GradientFillConcentric(r
, *wxWHITE
, *wxBLUE
);
1272 r
.Offset(0, r
.height
+ 10);
1273 dc
.DrawText(wxT("Blue in top left corner"), r
.x
, r
.y
);
1274 r
.Offset(0, TEXT_HEIGHT
);
1275 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(0, 0));
1277 r
.Offset(0, r
.height
+ 10);
1278 dc
.DrawText(wxT("Blue in bottom right corner"), r
.x
, r
.y
);
1279 r
.Offset(0, TEXT_HEIGHT
);
1280 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(r
.width
, r
.height
));
1282 // check that the area filled by the gradient is exactly the interior of
1286 dc
.DrawText("The interior should be filled but", r
.x
, r
.y
);
1288 dc
.DrawText(" the red border should remain visible:", r
.x
, r
.y
);
1299 dc
.SetPen(wxPen(wxColour(255, 0, 0)));
1300 dc
.DrawRectangle(r
);
1302 dc
.GradientFillLinear(r
, wxColour(0,255,0), wxColour(0,0,0), wxNORTH
);
1303 dc
.DrawRectangle(r2
);
1305 dc
.GradientFillLinear(r2
, wxColour(0,0,0), wxColour(0,255,0), wxSOUTH
);
1306 dc
.DrawRectangle(r3
);
1308 dc
.GradientFillLinear(r3
, wxColour(0,255,0), wxColour(0,0,0), wxEAST
);
1309 dc
.DrawRectangle(r4
);
1311 dc
.GradientFillLinear(r4
, wxColour(0,0,0), wxColour(0,255,0), wxWEST
);
1313 #if wxUSE_GRAPHICS_CONTEXT
1316 wxGCDC
&gdc
= (wxGCDC
&)dc
;
1317 wxGraphicsContext
*gc
= gdc
.GetGraphicsContext();
1319 wxGraphicsGradientStops stops
;
1321 gfr
.Offset(0, gfr
.height
+ 10);
1322 dc
.DrawText(wxT("Linear Gradient with Stops"), gfr
.x
, gfr
.y
);
1323 gfr
.Offset(0, TEXT_HEIGHT
);
1325 stops
= wxGraphicsGradientStops(wxColour(255,0,0), wxColour(0,0,255));
1326 stops
.Add(wxColour(255,255,0), 0.33f
);
1327 stops
.Add(wxColour(0,255,0), 0.67f
);
1329 gc
->SetBrush(gc
->CreateLinearGradientBrush(gfr
.x
, gfr
.y
,
1330 gfr
.x
+ gfr
.width
, gfr
.y
+ gfr
.height
,
1332 pth
= gc
->CreatePath();
1333 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1334 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1335 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1336 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1340 gfr
.Offset(0, gfr
.height
+ 10);
1341 dc
.DrawText(wxT("Radial Gradient with Stops"), gfr
.x
, gfr
.y
);
1342 gfr
.Offset(0, TEXT_HEIGHT
);
1344 gc
->SetBrush(gc
->CreateRadialGradientBrush(gfr
.x
+ gfr
.width
/ 2,
1345 gfr
.y
+ gfr
.height
/ 2,
1346 gfr
.x
+ gfr
.width
/ 2,
1347 gfr
.y
+ gfr
.height
/ 2,
1350 pth
= gc
->CreatePath();
1351 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1352 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1353 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1354 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1358 gfr
.Offset(0, gfr
.height
+ 10);
1359 dc
.DrawText(wxT("Linear Gradient with Stops and Gaps"), gfr
.x
, gfr
.y
);
1360 gfr
.Offset(0, TEXT_HEIGHT
);
1362 stops
= wxGraphicsGradientStops(wxColour(255,0,0), wxColour(0,0,255));
1363 stops
.Add(wxColour(255,255,0), 0.33f
);
1364 stops
.Add(wxTransparentColour
, 0.33f
);
1365 stops
.Add(wxTransparentColour
, 0.67f
);
1366 stops
.Add(wxColour(0,255,0), 0.67f
);
1368 gc
->SetBrush(gc
->CreateLinearGradientBrush(gfr
.x
, gfr
.y
+ gfr
.height
,
1369 gfr
.x
+ gfr
.width
, gfr
.y
,
1371 pth
= gc
->CreatePath();
1372 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1373 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1374 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1375 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1379 gfr
.Offset(0, gfr
.height
+ 10);
1380 dc
.DrawText(wxT("Radial Gradient with Stops and Gaps"), gfr
.x
, gfr
.y
);
1381 gfr
.Offset(0, TEXT_HEIGHT
);
1383 gc
->SetBrush(gc
->CreateRadialGradientBrush(gfr
.x
+ gfr
.width
/ 2,
1384 gfr
.y
+ gfr
.height
/ 2,
1385 gfr
.x
+ gfr
.width
/ 2,
1386 gfr
.y
+ gfr
.height
/ 2,
1389 pth
= gc
->CreatePath();
1390 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1391 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1392 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1393 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1397 gfr
.Offset(0, gfr
.height
+ 10);
1398 dc
.DrawText(wxT("Gradients with Stops and Transparency"), gfr
.x
, gfr
.y
);
1399 gfr
.Offset(0, TEXT_HEIGHT
);
1401 stops
= wxGraphicsGradientStops(wxColour(255,0,0), wxTransparentColour
);
1402 stops
.Add(wxColour(255,0,0), 0.33f
);
1403 stops
.Add(wxTransparentColour
, 0.33f
);
1404 stops
.Add(wxTransparentColour
, 0.67f
);
1405 stops
.Add(wxColour(0,0,255), 0.67f
);
1406 stops
.Add(wxColour(0,0,255), 1.0f
);
1408 pth
= gc
->CreatePath();
1409 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1410 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1411 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1412 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1415 gc
->SetBrush(gc
->CreateRadialGradientBrush(gfr
.x
+ gfr
.width
/ 2,
1416 gfr
.y
+ gfr
.height
/ 2,
1417 gfr
.x
+ gfr
.width
/ 2,
1418 gfr
.y
+ gfr
.height
/ 2,
1423 stops
= wxGraphicsGradientStops(wxColour(255,0,0, 128), wxColour(0,0,255, 128));
1424 stops
.Add(wxColour(255,255,0,128), 0.33f
);
1425 stops
.Add(wxColour(0,255,0,128), 0.67f
);
1427 gc
->SetBrush(gc
->CreateLinearGradientBrush(gfr
.x
, gfr
.y
,
1428 gfr
.x
+ gfr
.width
, gfr
.y
,
1432 #endif // wxUSE_GRAPHICS_CONTEXT
1435 void MyCanvas::DrawRegions(wxDC
& dc
)
1437 dc
.DrawText(wxT("You should see a red rect partly covered by a cyan one ")
1438 wxT("on the left"), 10, 5);
1439 dc
.DrawText(wxT("and 5 smileys from which 4 are partially clipped on the right"),
1440 10, 5 + dc
.GetCharHeight());
1441 dc
.DrawText(wxT("The second copy should be identical but right part of it ")
1442 wxT("should be offset by 10 pixels."),
1443 10, 5 + 2*dc
.GetCharHeight());
1445 DrawRegionsHelper(dc
, 10, true);
1446 DrawRegionsHelper(dc
, 350, false);
1449 void MyCanvas::DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
)
1453 dc
.DestroyClippingRegion();
1454 dc
.SetBrush( *wxWHITE_BRUSH
);
1455 dc
.SetPen( *wxTRANSPARENT_PEN
);
1456 dc
.DrawRectangle( x
, y
, 310, 310 );
1458 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 270 );
1460 dc
.SetBrush( *wxRED_BRUSH
);
1461 dc
.DrawRectangle( x
, y
, 310, 310 );
1463 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 100 );
1465 dc
.SetBrush( *wxCYAN_BRUSH
);
1466 dc
.DrawRectangle( x
, y
, 310, 310 );
1468 dc
.DestroyClippingRegion();
1470 wxRegion
region(x
+ 110, y
+ 20, 100, 270);
1471 #if !defined(__WXMOTIF__)
1473 region
.Offset(10, 10);
1475 dc
.SetDeviceClippingRegion(region
);
1477 dc
.SetBrush( *wxGREY_BRUSH
);
1478 dc
.DrawRectangle( x
, y
, 310, 310 );
1480 if (m_smile_bmp
.IsOk())
1482 dc
.DrawBitmap( m_smile_bmp
, x
+ 150, y
+ 150, true );
1483 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 10, true );
1484 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 280, true );
1485 dc
.DrawBitmap( m_smile_bmp
, x
+ 100, y
+ 70, true );
1486 dc
.DrawBitmap( m_smile_bmp
, x
+ 200, y
+ 70, true );
1490 void MyCanvas::OnPaint(wxPaintEvent
&WXUNUSED(event
))
1492 wxPaintDC
pdc(this);
1496 void MyCanvas::Draw(wxDC
& pdc
)
1498 #if wxUSE_GRAPHICS_CONTEXT
1500 wxGraphicsRenderer
* const renderer
= wxGraphicsRenderer::
1501 #if TEST_CAIRO_EVERYWHERE
1504 GetDefaultRenderer()
1508 wxGraphicsContext
* context
;
1509 if ( wxPaintDC
*paintdc
= wxDynamicCast(&pdc
, wxPaintDC
) )
1511 context
= renderer
->CreateContext(*paintdc
);
1513 else if ( wxMemoryDC
*memdc
= wxDynamicCast(&pdc
, wxMemoryDC
) )
1515 context
= renderer
->CreateContext(*memdc
);
1517 #if wxUSE_METAFILE && defined(wxMETAFILE_IS_ENH)
1518 else if ( wxMetafileDC
*metadc
= wxDynamicCast(&pdc
, wxMetafileDC
) )
1520 context
= renderer
->CreateContext(*metadc
);
1525 wxFAIL_MSG( "Unknown wxDC kind" );
1529 gdc
.SetGraphicsContext(context
);
1531 wxDC
&dc
= m_useContext
? (wxDC
&) gdc
: (wxDC
&) pdc
;
1538 m_owner
->PrepareDC(dc
);
1540 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
1541 if ( m_owner
->m_backgroundBrush
.IsOk() )
1542 dc
.SetBackground( m_owner
->m_backgroundBrush
);
1543 if ( m_owner
->m_colourForeground
.IsOk() )
1544 dc
.SetTextForeground( m_owner
->m_colourForeground
);
1545 if ( m_owner
->m_colourBackground
.IsOk() )
1546 dc
.SetTextBackground( m_owner
->m_colourBackground
);
1548 if ( m_owner
->m_textureBackground
) {
1549 if ( ! m_owner
->m_backgroundBrush
.IsOk() ) {
1550 wxColour
clr(0,128,0);
1551 wxBrush
b(clr
, wxSOLID
);
1552 dc
.SetBackground(b
);
1557 dc
.SetClippingRegion(100, 100, 100, 100);
1561 if ( m_owner
->m_textureBackground
)
1563 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
1564 for ( int i
= 0; i
< 200; i
++ )
1565 dc
.DrawLine(0, i
*10, i
*10, 0);
1570 case File_ShowDefault
:
1574 case File_ShowCircles
:
1578 case File_ShowSplines
:
1582 case File_ShowRegions
:
1590 case File_ShowLines
:
1591 DrawTestLines( 0, 100, 0, dc
);
1592 DrawTestLines( 0, 320, 1, dc
);
1593 DrawTestLines( 0, 540, 2, dc
);
1594 DrawTestLines( 0, 760, 6, dc
);
1597 case File_ShowBrushes
:
1598 DrawTestBrushes(dc
);
1601 case File_ShowPolygons
:
1606 DrawImages(dc
, Draw_Normal
);
1609 case File_ShowMaskStretch
:
1610 DrawImages(dc
, Draw_Stretch
);
1614 DrawWithLogicalOps(dc
);
1617 #if wxUSE_GRAPHICS_CONTEXT
1618 case File_ShowAlpha
:
1621 case File_ShowGraphics
:
1622 DrawGraphics(gdc
.GetGraphicsContext());
1626 case File_ShowGradients
:
1635 void MyCanvas::OnMouseMove(wxMouseEvent
&event
)
1639 wxClientDC
dc(this);
1641 m_owner
->PrepareDC(dc
);
1643 wxPoint pos
= event
.GetPosition();
1644 long x
= dc
.DeviceToLogicalX( pos
.x
);
1645 long y
= dc
.DeviceToLogicalY( pos
.y
);
1647 str
.Printf( wxT("Current mouse position: %d,%d"), (int)x
, (int)y
);
1648 m_owner
->SetStatusText( str
);
1654 event
.GetPosition(&x
,&y
);
1655 CalcUnscrolledPosition( x
, y
, &xx
, &yy
);
1656 m_currentpoint
= wxPoint( xx
, yy
) ;
1657 wxRect
newrect ( m_anchorpoint
, m_currentpoint
) ;
1659 wxClientDC
dc( this ) ;
1662 wxDCOverlay
overlaydc( m_overlay
, &dc
);
1665 dc
.SetPen( *wxGREY_PEN
);
1666 dc
.SetBrush( wxColour( 192,192,192,64 ) );
1668 dc
.SetPen( wxPen( *wxLIGHT_GREY
, 2, wxSOLID
) );
1669 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
1671 dc
.DrawRectangle( newrect
);
1675 #endif // wxUSE_STATUSBAR
1678 void MyCanvas::OnMouseDown(wxMouseEvent
&event
)
1681 event
.GetPosition(&x
,&y
);
1682 CalcUnscrolledPosition( x
, y
, &xx
, &yy
);
1683 m_anchorpoint
= wxPoint( xx
, yy
) ;
1684 m_currentpoint
= m_anchorpoint
;
1685 m_rubberBand
= true ;
1689 void MyCanvas::OnMouseUp(wxMouseEvent
&event
)
1695 wxClientDC
dc( this );
1697 wxDCOverlay
overlaydc( m_overlay
, &dc
);
1701 m_rubberBand
= false;
1703 wxPoint endpoint
= CalcUnscrolledPosition(event
.GetPosition());
1705 // Don't pop up the message box if nothing was actually selected.
1706 if ( endpoint
!= m_anchorpoint
)
1708 wxLogMessage("Selected rectangle from (%d, %d) to (%d, %d)",
1709 m_anchorpoint
.x
, m_anchorpoint
.y
,
1710 endpoint
.x
, endpoint
.y
);
1715 // ----------------------------------------------------------------------------
1717 // ----------------------------------------------------------------------------
1719 // the event tables connect the wxWidgets events with the functions (event
1720 // handlers) which process them. It can be also done at run-time, but for the
1721 // simple menu events like this the static method is much simpler.
1722 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
1723 EVT_MENU (File_Quit
, MyFrame::OnQuit
)
1724 EVT_MENU (File_About
, MyFrame::OnAbout
)
1725 EVT_MENU (File_Clip
, MyFrame::OnClip
)
1726 #if wxUSE_GRAPHICS_CONTEXT
1727 EVT_MENU (File_GraphicContext
, MyFrame::OnGraphicContext
)
1729 EVT_MENU (File_Copy
, MyFrame::OnCopy
)
1730 EVT_MENU (File_Save
, MyFrame::OnSave
)
1732 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame::OnShow
)
1734 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame::OnOption
)
1737 // frame constructor
1738 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
1739 : wxFrame((wxFrame
*)NULL
, wxID_ANY
, title
, pos
, size
,
1740 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
1742 // set the frame icon
1743 SetIcon(wxICON(sample
));
1745 wxMenu
*menuFile
= new wxMenu
;
1746 menuFile
->Append(File_ShowDefault
, wxT("&Default screen\tF1"));
1747 menuFile
->Append(File_ShowText
, wxT("&Text screen\tF2"));
1748 menuFile
->Append(File_ShowLines
, wxT("&Lines screen\tF3"));
1749 menuFile
->Append(File_ShowBrushes
, wxT("&Brushes screen\tF4"));
1750 menuFile
->Append(File_ShowPolygons
, wxT("&Polygons screen\tF5"));
1751 menuFile
->Append(File_ShowMask
, wxT("&Mask screen\tF6"));
1752 menuFile
->Append(File_ShowMaskStretch
, wxT("1/&2 scaled mask\tShift-F6"));
1753 menuFile
->Append(File_ShowOps
, wxT("&Raster operations screen\tF7"));
1754 menuFile
->Append(File_ShowRegions
, wxT("Re&gions screen\tF8"));
1755 menuFile
->Append(File_ShowCircles
, wxT("&Circles screen\tF9"));
1756 #if wxUSE_GRAPHICS_CONTEXT
1757 menuFile
->Append(File_ShowAlpha
, wxT("&Alpha screen\tF10"));
1759 menuFile
->Append(File_ShowSplines
, wxT("Spl&ines screen\tF11"));
1760 menuFile
->Append(File_ShowGradients
, wxT("&Gradients screen\tF12"));
1761 #if wxUSE_GRAPHICS_CONTEXT
1762 menuFile
->Append(File_ShowGraphics
, wxT("&Graphics screen"));
1764 menuFile
->AppendSeparator();
1765 menuFile
->AppendCheckItem(File_Clip
, wxT("&Clip\tCtrl-C"), wxT("Clip/unclip drawing"));
1766 #if wxUSE_GRAPHICS_CONTEXT
1767 menuFile
->AppendCheckItem(File_GraphicContext
, wxT("&Use GraphicContext\tCtrl-Y"), wxT("Use GraphicContext"));
1769 menuFile
->AppendSeparator();
1770 #if wxUSE_METAFILE && defined(wxMETAFILE_IS_ENH)
1771 menuFile
->Append(File_Copy
, wxT("Copy to clipboard"));
1773 menuFile
->Append(File_Save
, wxT("&Save...\tCtrl-S"), wxT("Save drawing to file"));
1774 menuFile
->AppendSeparator();
1775 menuFile
->Append(File_About
, wxT("&About...\tCtrl-A"), wxT("Show about dialog"));
1776 menuFile
->AppendSeparator();
1777 menuFile
->Append(File_Quit
, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
1779 wxMenu
*menuMapMode
= new wxMenu
;
1780 menuMapMode
->Append( MapMode_Text
, wxT("&TEXT map mode") );
1781 menuMapMode
->Append( MapMode_Lometric
, wxT("&LOMETRIC map mode") );
1782 menuMapMode
->Append( MapMode_Twips
, wxT("T&WIPS map mode") );
1783 menuMapMode
->Append( MapMode_Points
, wxT("&POINTS map mode") );
1784 menuMapMode
->Append( MapMode_Metric
, wxT("&METRIC map mode") );
1786 wxMenu
*menuUserScale
= new wxMenu
;
1787 menuUserScale
->Append( UserScale_StretchHoriz
, wxT("Stretch &horizontally\tCtrl-H") );
1788 menuUserScale
->Append( UserScale_ShrinkHoriz
, wxT("Shrin&k horizontally\tCtrl-G") );
1789 menuUserScale
->Append( UserScale_StretchVertic
, wxT("Stretch &vertically\tCtrl-V") );
1790 menuUserScale
->Append( UserScale_ShrinkVertic
, wxT("&Shrink vertically\tCtrl-W") );
1791 menuUserScale
->AppendSeparator();
1792 menuUserScale
->Append( UserScale_Restore
, wxT("&Restore to normal\tCtrl-0") );
1794 wxMenu
*menuAxis
= new wxMenu
;
1795 menuAxis
->AppendCheckItem( AxisMirror_Horiz
, wxT("Mirror horizontally\tCtrl-M") );
1796 menuAxis
->AppendCheckItem( AxisMirror_Vertic
, wxT("Mirror vertically\tCtrl-N") );
1798 wxMenu
*menuLogical
= new wxMenu
;
1799 menuLogical
->Append( LogicalOrigin_MoveDown
, wxT("Move &down\tCtrl-D") );
1800 menuLogical
->Append( LogicalOrigin_MoveUp
, wxT("Move &up\tCtrl-U") );
1801 menuLogical
->Append( LogicalOrigin_MoveLeft
, wxT("Move &right\tCtrl-L") );
1802 menuLogical
->Append( LogicalOrigin_MoveRight
, wxT("Move &left\tCtrl-R") );
1803 menuLogical
->AppendSeparator();
1804 menuLogical
->Append( LogicalOrigin_Set
, wxT("Set to (&100, 100)\tShift-Ctrl-1") );
1805 menuLogical
->Append( LogicalOrigin_Restore
, wxT("&Restore to normal\tShift-Ctrl-0") );
1807 wxMenu
*menuColour
= new wxMenu
;
1809 menuColour
->Append( Colour_TextForeground
, wxT("Text &foreground...") );
1810 menuColour
->Append( Colour_TextBackground
, wxT("Text &background...") );
1811 menuColour
->Append( Colour_Background
, wxT("Background &colour...") );
1812 #endif // wxUSE_COLOURDLG
1813 menuColour
->AppendCheckItem( Colour_BackgroundMode
, wxT("&Opaque/transparent\tCtrl-B") );
1814 menuColour
->AppendCheckItem( Colour_TextureBackgound
, wxT("Draw textured back&ground\tCtrl-T") );
1816 // now append the freshly created menu to the menu bar...
1817 wxMenuBar
*menuBar
= new wxMenuBar
;
1818 menuBar
->Append(menuFile
, wxT("&File"));
1819 menuBar
->Append(menuMapMode
, wxT("&Mode"));
1820 menuBar
->Append(menuUserScale
, wxT("&Scale"));
1821 menuBar
->Append(menuAxis
, wxT("&Axis"));
1822 menuBar
->Append(menuLogical
, wxT("&Origin"));
1823 menuBar
->Append(menuColour
, wxT("&Colours"));
1825 // ... and attach this menu bar to the frame
1826 SetMenuBar(menuBar
);
1830 SetStatusText(wxT("Welcome to wxWidgets!"));
1831 #endif // wxUSE_STATUSBAR
1833 m_mapMode
= wxMM_TEXT
;
1836 m_xLogicalOrigin
= 0;
1837 m_yLogicalOrigin
= 0;
1839 m_yAxisReversed
= false;
1840 m_backgroundMode
= wxSOLID
;
1841 m_colourForeground
= *wxBLACK
;
1842 m_colourBackground
= *wxLIGHT_GREY
;
1843 m_textureBackground
= false;
1845 m_canvas
= new MyCanvas( this );
1846 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1851 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1853 // true is to force the frame to close
1857 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1860 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1861 wxT("This sample tests various primitive drawing functions\n")
1862 wxT("(without any attempts to prevent flicker).\n")
1863 wxT("Copyright (c) Robert Roebling 1999")
1866 wxMessageBox(msg
, wxT("About Drawing"), wxOK
| wxICON_INFORMATION
, this);
1869 void MyFrame::OnClip(wxCommandEvent
& event
)
1871 m_canvas
->Clip(event
.IsChecked());
1874 #if wxUSE_GRAPHICS_CONTEXT
1875 void MyFrame::OnGraphicContext(wxCommandEvent
& event
)
1877 m_canvas
->UseGraphicContext(event
.IsChecked());
1881 void MyFrame::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1883 #if wxUSE_METAFILE && defined(wxMETAFILE_IS_ENH)
1888 wxMetafile
*mf
= dc
.Close();
1896 void MyFrame::OnSave(wxCommandEvent
& WXUNUSED(event
))
1898 wxFileDialog
dlg(this, wxT("Save as bitmap"), wxT(""), wxT(""),
1900 wxT("PNG image (*.png)|*.png;*.PNG|")
1902 wxT("Bitmap image (*.bmp)|*.bmp;*.BMP"),
1903 wxFD_SAVE
| wxFD_OVERWRITE_PROMPT
);
1904 if (dlg
.ShowModal() == wxID_OK
)
1906 wxBitmap
bmp(500, 800);
1907 wxMemoryDC
mdc(bmp
);
1908 m_canvas
->Draw(mdc
);
1909 bmp
.ConvertToImage().SaveFile(dlg
.GetPath());
1913 void MyFrame::OnShow(wxCommandEvent
& event
)
1915 m_canvas
->ToShow(event
.GetId());
1918 void MyFrame::OnOption(wxCommandEvent
& event
)
1920 switch (event
.GetId())
1923 m_mapMode
= wxMM_TEXT
;
1925 case MapMode_Lometric
:
1926 m_mapMode
= wxMM_LOMETRIC
;
1929 m_mapMode
= wxMM_TWIPS
;
1931 case MapMode_Points
:
1932 m_mapMode
= wxMM_POINTS
;
1934 case MapMode_Metric
:
1935 m_mapMode
= wxMM_METRIC
;
1938 case LogicalOrigin_MoveDown
:
1939 m_yLogicalOrigin
+= 10;
1941 case LogicalOrigin_MoveUp
:
1942 m_yLogicalOrigin
-= 10;
1944 case LogicalOrigin_MoveLeft
:
1945 m_xLogicalOrigin
+= 10;
1947 case LogicalOrigin_MoveRight
:
1948 m_xLogicalOrigin
-= 10;
1950 case LogicalOrigin_Set
:
1952 m_yLogicalOrigin
= -100;
1954 case LogicalOrigin_Restore
:
1956 m_yLogicalOrigin
= 0;
1959 case UserScale_StretchHoriz
:
1960 m_xUserScale
*= 1.10;
1962 case UserScale_ShrinkHoriz
:
1963 m_xUserScale
/= 1.10;
1965 case UserScale_StretchVertic
:
1966 m_yUserScale
*= 1.10;
1968 case UserScale_ShrinkVertic
:
1969 m_yUserScale
/= 1.10;
1971 case UserScale_Restore
:
1976 case AxisMirror_Vertic
:
1977 m_yAxisReversed
= !m_yAxisReversed
;
1979 case AxisMirror_Horiz
:
1980 m_xAxisReversed
= !m_xAxisReversed
;
1984 case Colour_TextForeground
:
1985 m_colourForeground
= SelectColour();
1987 case Colour_TextBackground
:
1988 m_colourBackground
= SelectColour();
1990 case Colour_Background
:
1992 wxColour col
= SelectColour();
1995 m_backgroundBrush
.SetColour(col
);
1999 #endif // wxUSE_COLOURDLG
2001 case Colour_BackgroundMode
:
2002 m_backgroundMode
= m_backgroundMode
== wxSOLID
? wxTRANSPARENT
2006 case Colour_TextureBackgound
:
2007 m_textureBackground
= ! m_textureBackground
;
2015 m_canvas
->Refresh();
2018 void MyFrame::PrepareDC(wxDC
& dc
)
2020 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
2021 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
2022 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
2023 dc
.SetMapMode( m_mapMode
);
2027 wxColour
MyFrame::SelectColour()
2031 wxColourDialog
dialog(this, &data
);
2033 if ( dialog
.ShowModal() == wxID_OK
)
2035 col
= dialog
.GetColourData().GetColour();
2040 #endif // wxUSE_COLOURDLG