1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/drawing/drawing.cpp
3 // Purpose: shows and tests wxDC features
4 // Author: Robert Roebling
7 // Copyright: (c) Robert Roebling
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
26 // for all others, include the necessary headers (this file is usually all you
27 // need because it includes almost all "standard" wxWidgets headers
32 #include "wx/colordlg.h"
34 #include "wx/artprov.h"
35 #include "wx/dcgraph.h"
36 #include "wx/overlay.h"
37 #include "wx/graphics.h"
38 #include "wx/filename.h"
39 #include "wx/metafile.h"
41 #define TEST_CAIRO_EVERYWHERE 0
43 // ----------------------------------------------------------------------------
45 // ----------------------------------------------------------------------------
47 // the application icon
48 #ifndef wxHAS_IMAGES_IN_RESOURCES
49 #include "../sample.xpm"
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 static wxBitmap
*gs_bmpNoMask
= NULL
,
57 *gs_bmpWithColMask
= NULL
,
59 *gs_bmpWithMask
= NULL
,
64 // ----------------------------------------------------------------------------
66 // ----------------------------------------------------------------------------
68 // Define a new application type, each program should derive a class from wxApp
69 class MyApp
: public wxApp
72 // override base class virtuals
73 // ----------------------------
75 // this one is called on application startup and is a good place for the app
76 // initialization (doing it here and not in the ctor allows to have an error
77 // return: if OnInit() returns false, the application terminates)
78 virtual bool OnInit();
80 virtual int OnExit() { DeleteBitmaps(); return 0; }
90 // Define a new frame type: this is going to be our main frame
91 class MyFrame
: public wxFrame
95 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
97 // event handlers (these functions should _not_ be virtual)
98 void OnQuit(wxCommandEvent
& event
);
99 void OnAbout(wxCommandEvent
& event
);
100 void OnClip(wxCommandEvent
& event
);
101 #if wxUSE_GRAPHICS_CONTEXT
102 void OnGraphicContext(wxCommandEvent
& event
);
104 void OnCopy(wxCommandEvent
& event
);
105 void OnSave(wxCommandEvent
& event
);
106 void OnShow(wxCommandEvent
&event
);
107 void OnOption(wxCommandEvent
&event
);
110 wxColour
SelectColour();
111 #endif // wxUSE_COLOURDLG
112 void PrepareDC(wxDC
& dc
);
114 int m_backgroundMode
;
115 int m_textureBackground
;
116 wxMappingMode m_mapMode
;
119 int m_xLogicalOrigin
;
120 int m_yLogicalOrigin
;
121 bool m_xAxisReversed
,
123 wxColour m_colourForeground
, // these are _text_ colours
125 wxBrush m_backgroundBrush
;
129 // any class wishing to process wxWidgets events must use this macro
130 DECLARE_EVENT_TABLE()
133 // define a scrollable canvas for drawing onto
134 class MyCanvas
: public wxScrolledWindow
137 MyCanvas( MyFrame
*parent
);
139 void OnPaint(wxPaintEvent
&event
);
140 void OnMouseMove(wxMouseEvent
&event
);
141 void OnMouseDown(wxMouseEvent
&event
);
142 void OnMouseUp(wxMouseEvent
&event
);
144 void ToShow(int show
) { m_show
= show
; Refresh(); }
146 // set or remove the clipping region
147 void Clip(bool clip
) { m_clip
= clip
; Refresh(); }
148 #if wxUSE_GRAPHICS_CONTEXT
149 void UseGraphicContext(bool use
) { m_useContext
= use
; Refresh(); }
160 void DrawTestLines( int x
, int y
, int width
, wxDC
&dc
);
161 void DrawTestPoly(wxDC
& dc
);
162 void DrawTestBrushes(wxDC
& dc
);
163 void DrawText(wxDC
& dc
);
164 void DrawImages(wxDC
& dc
, DrawMode mode
);
165 void DrawWithLogicalOps(wxDC
& dc
);
166 #if wxUSE_GRAPHICS_CONTEXT
167 void DrawAlpha(wxDC
& dc
);
168 void DrawGraphics(wxGraphicsContext
* gc
);
170 void DrawRegions(wxDC
& dc
);
171 void DrawCircles(wxDC
& dc
);
172 void DrawSplines(wxDC
& dc
);
173 void DrawDefault(wxDC
& dc
);
174 void DrawGradients(wxDC
& dc
);
176 void DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
);
182 wxBitmap m_smile_bmp
;
187 wxPoint m_anchorpoint
;
188 wxPoint m_currentpoint
;
189 #if wxUSE_GRAPHICS_CONTEXT
193 DECLARE_EVENT_TABLE()
196 // ----------------------------------------------------------------------------
198 // ----------------------------------------------------------------------------
200 // IDs for the controls and the menu commands
204 File_Quit
= wxID_EXIT
,
205 File_About
= wxID_ABOUT
,
207 MenuShow_First
= wxID_HIGHEST
,
208 File_ShowDefault
= MenuShow_First
,
214 File_ShowMaskStretch
,
219 #if wxUSE_GRAPHICS_CONTEXT
224 MenuShow_Last
= File_ShowGradients
,
227 #if wxUSE_GRAPHICS_CONTEXT
235 MapMode_Text
= MenuOption_First
,
241 UserScale_StretchHoriz
,
242 UserScale_ShrinkHoriz
,
243 UserScale_StretchVertic
,
244 UserScale_ShrinkVertic
,
250 LogicalOrigin_MoveDown
,
251 LogicalOrigin_MoveUp
,
252 LogicalOrigin_MoveLeft
,
253 LogicalOrigin_MoveRight
,
255 LogicalOrigin_Restore
,
258 Colour_TextForeground
,
259 Colour_TextBackground
,
261 #endif // wxUSE_COLOURDLG
262 Colour_BackgroundMode
,
263 Colour_TextureBackgound
,
265 MenuOption_Last
= Colour_TextureBackgound
268 // ----------------------------------------------------------------------------
269 // event tables and other macros for wxWidgets
270 // ----------------------------------------------------------------------------
273 // Create a new application object: this macro will allow wxWidgets to create
274 // the application object during program execution (it's better than using a
275 // static object for many reasons) and also declares the accessor function
276 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
280 // ============================================================================
282 // ============================================================================
284 // ----------------------------------------------------------------------------
285 // the application class
286 // ----------------------------------------------------------------------------
288 bool MyApp::LoadImages()
290 gs_bmpNoMask
= new wxBitmap
;
291 gs_bmpWithColMask
= new wxBitmap
;
292 gs_bmpMask
= new wxBitmap
;
293 gs_bmpWithMask
= new wxBitmap
;
294 gs_bmp4
= new wxBitmap
;
295 gs_bmp4_mono
= new wxBitmap
;
296 gs_bmp36
= new wxBitmap
;
299 // special hack for Unix in-tree sample build, don't do this in real
300 // programs, use wxStandardPaths instead
301 pathList
.Add(wxFileName(argv
[0]).GetPath());
302 pathList
.Add(wxT("."));
303 pathList
.Add(wxT(".."));
304 pathList
.Add(wxT("../.."));
306 wxString path
= pathList
.FindValidPath(wxT("pat4.bmp"));
310 /* 4 colour bitmap */
311 gs_bmp4
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
312 /* turn into mono-bitmap */
313 gs_bmp4_mono
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
314 wxMask
* mask4
= new wxMask(*gs_bmp4_mono
, *wxBLACK
);
315 gs_bmp4_mono
->SetMask(mask4
);
317 path
= pathList
.FindValidPath(wxT("pat36.bmp"));
320 gs_bmp36
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
321 wxMask
* mask36
= new wxMask(*gs_bmp36
, *wxBLACK
);
322 gs_bmp36
->SetMask(mask36
);
324 path
= pathList
.FindValidPath(wxT("image.bmp"));
327 gs_bmpNoMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
328 gs_bmpWithMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
329 gs_bmpWithColMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
331 path
= pathList
.FindValidPath(wxT("mask.bmp"));
334 gs_bmpMask
->LoadFile(path
, wxBITMAP_TYPE_BMP
);
336 wxMask
*mask
= new wxMask(*gs_bmpMask
, *wxBLACK
);
337 gs_bmpWithMask
->SetMask(mask
);
339 mask
= new wxMask(*gs_bmpWithColMask
, *wxWHITE
);
340 gs_bmpWithColMask
->SetMask(mask
);
345 // `Main program' equivalent: the program execution "starts" here
348 if ( !wxApp::OnInit() )
351 // Create the main application window
352 MyFrame
*frame
= new MyFrame(wxT("Drawing sample"),
353 wxDefaultPosition
, wxSize(550, 840));
360 wxLogError(wxT("Can't load one of the bitmap files needed ")
361 wxT("for this sample from the current or parent ")
362 wxT("directory, please copy them there."));
364 // still continue, the sample can be used without images too if they're
365 // missing for whatever reason
368 wxImage::AddHandler( new wxPNGHandler
);
374 void MyApp::DeleteBitmaps()
376 wxDELETE(gs_bmpNoMask
);
377 wxDELETE(gs_bmpWithColMask
);
378 wxDELETE(gs_bmpMask
);
379 wxDELETE(gs_bmpWithMask
);
381 wxDELETE(gs_bmp4_mono
);
385 // ----------------------------------------------------------------------------
387 // ----------------------------------------------------------------------------
389 // the event tables connect the wxWidgets events with the functions (event
390 // handlers) which process them.
391 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
392 EVT_PAINT (MyCanvas::OnPaint
)
393 EVT_MOTION (MyCanvas::OnMouseMove
)
394 EVT_LEFT_DOWN (MyCanvas::OnMouseDown
)
395 EVT_LEFT_UP (MyCanvas::OnMouseUp
)
400 MyCanvas::MyCanvas(MyFrame
*parent
)
401 : wxScrolledWindow(parent
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
402 wxHSCROLL
| wxVSCROLL
| wxNO_FULL_REPAINT_ON_RESIZE
)
405 m_show
= File_ShowDefault
;
406 m_smile_bmp
= wxBitmap(smile_xpm
);
407 m_std_icon
= wxArtProvider::GetIcon(wxART_INFORMATION
);
409 m_rubberBand
= false;
410 #if wxUSE_GRAPHICS_CONTEXT
411 m_useContext
= false;
415 void MyCanvas::DrawTestBrushes(wxDC
& dc
)
417 static const wxCoord WIDTH
= 200;
418 static const wxCoord HEIGHT
= 80;
423 dc
.SetBrush(*wxGREEN_BRUSH
);
424 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
425 dc
.DrawText(wxT("Solid green"), x
+ 10, y
+ 10);
428 dc
.SetBrush(wxBrush(*wxRED
, wxBRUSHSTYLE_CROSSDIAG_HATCH
));
429 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
430 dc
.DrawText(wxT("Diagonally hatched red"), x
+ 10, y
+ 10);
433 dc
.SetBrush(wxBrush(*wxBLUE
, wxBRUSHSTYLE_CROSS_HATCH
));
434 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
435 dc
.DrawText(wxT("Cross hatched blue"), x
+ 10, y
+ 10);
438 dc
.SetBrush(wxBrush(*wxCYAN
, wxBRUSHSTYLE_VERTICAL_HATCH
));
439 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
440 dc
.DrawText(wxT("Vertically hatched cyan"), x
+ 10, y
+ 10);
443 dc
.SetBrush(wxBrush(*wxBLACK
, wxBRUSHSTYLE_HORIZONTAL_HATCH
));
444 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
445 dc
.DrawText(wxT("Horizontally hatched black"), x
+ 10, y
+ 10);
448 dc
.SetBrush(wxBrush(*gs_bmpMask
));
449 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
450 dc
.DrawText(wxT("Stipple mono"), x
+ 10, y
+ 10);
453 dc
.SetBrush(wxBrush(*gs_bmpNoMask
));
454 dc
.DrawRectangle(x
, y
, WIDTH
, HEIGHT
);
455 dc
.DrawText(wxT("Stipple colour"), x
+ 10, y
+ 10);
458 void MyCanvas::DrawTestPoly(wxDC
& dc
)
460 wxBrush
brushHatch(*wxRED
, wxBRUSHSTYLE_FDIAGONAL_HATCH
);
461 dc
.SetBrush(brushHatch
);
464 star
[0] = wxPoint(100, 60);
465 star
[1] = wxPoint(60, 150);
466 star
[2] = wxPoint(160, 100);
467 star
[3] = wxPoint(40, 100);
468 star
[4] = wxPoint(140, 150);
470 dc
.DrawText(wxT("You should see two (irregular) stars below, the left one ")
471 wxT("hatched"), 10, 10);
472 dc
.DrawText(wxT("except for the central region and the right ")
473 wxT("one entirely hatched"), 10, 30);
474 dc
.DrawText(wxT("The third star only has a hatched outline"), 10, 50);
476 dc
.DrawPolygon(WXSIZEOF(star
), star
, 0, 30);
477 dc
.DrawPolygon(WXSIZEOF(star
), star
, 160, 30, wxWINDING_RULE
);
480 star2
[0] = wxPoint(0, 100);
481 star2
[1] = wxPoint(-59, -81);
482 star2
[2] = wxPoint(95, 31);
483 star2
[3] = wxPoint(-95, 31);
484 star2
[4] = wxPoint(59, -81);
485 star2
[5] = wxPoint(0, 80);
486 star2
[6] = wxPoint(-47, -64);
487 star2
[7] = wxPoint(76, 24);
488 star2
[8] = wxPoint(-76, 24);
489 star2
[9] = wxPoint(47, -64);
490 int count
[2] = {5, 5};
492 dc
.DrawPolyPolygon(WXSIZEOF(count
), count
, star2
, 450, 150);
495 void MyCanvas::DrawTestLines( int x
, int y
, int width
, wxDC
&dc
)
497 dc
.SetPen( wxPen( *wxBLACK
, width
) );
498 dc
.SetBrush( *wxRED_BRUSH
);
499 dc
.DrawText(wxString::Format(wxT("Testing lines of width %d"), width
), x
+ 10, y
- 10);
500 dc
.DrawRectangle( x
+10, y
+10, 100, 190 );
502 dc
.DrawText(wxT("Solid/dot/short dash/long dash/dot dash"), x
+ 150, y
+ 10);
503 dc
.SetPen( wxPen( *wxBLACK
, width
) );
504 dc
.DrawLine( x
+20, y
+20, 100, y
+20 );
505 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_DOT
) );
506 dc
.DrawLine( x
+20, y
+30, 100, y
+30 );
507 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_SHORT_DASH
) );
508 dc
.DrawLine( x
+20, y
+40, 100, y
+40 );
509 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_LONG_DASH
) );
510 dc
.DrawLine( x
+20, y
+50, 100, y
+50 );
511 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_DOT_DASH
) );
512 dc
.DrawLine( x
+20, y
+60, 100, y
+60 );
514 dc
.DrawText(wxT("Misc hatches"), x
+ 150, y
+ 70);
515 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_BDIAGONAL_HATCH
) );
516 dc
.DrawLine( x
+20, y
+70, 100, y
+70 );
517 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_CROSSDIAG_HATCH
) );
518 dc
.DrawLine( x
+20, y
+80, 100, y
+80 );
519 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_FDIAGONAL_HATCH
) );
520 dc
.DrawLine( x
+20, y
+90, 100, y
+90 );
521 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_CROSS_HATCH
) );
522 dc
.DrawLine( x
+20, y
+100, 100, y
+100 );
523 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_HORIZONTAL_HATCH
) );
524 dc
.DrawLine( x
+20, y
+110, 100, y
+110 );
525 dc
.SetPen( wxPen( *wxBLACK
, width
, wxPENSTYLE_VERTICAL_HATCH
) );
526 dc
.DrawLine( x
+20, y
+120, 100, y
+120 );
528 dc
.DrawText(wxT("User dash"), x
+ 150, y
+ 140);
529 wxPen
ud( *wxBLACK
, width
, wxPENSTYLE_USER_DASH
);
531 dash1
[0] = 8; // Long dash <---------+
532 dash1
[1] = 2; // Short gap |
533 dash1
[2] = 3; // Short dash |
534 dash1
[3] = 2; // Short gap |
535 dash1
[4] = 3; // Short dash |
536 dash1
[5] = 2; // Short gap and repeat +
537 ud
.SetDashes( 6, dash1
);
539 dc
.DrawLine( x
+20, y
+140, 100, y
+140 );
540 dash1
[0] = 5; // Make first dash shorter
541 ud
.SetDashes( 6, dash1
);
543 dc
.DrawLine( x
+20, y
+150, 100, y
+150 );
544 dash1
[2] = 5; // Make second dash longer
545 ud
.SetDashes( 6, dash1
);
547 dc
.DrawLine( x
+20, y
+160, 100, y
+160 );
548 dash1
[4] = 5; // Make third dash longer
549 ud
.SetDashes( 6, dash1
);
551 dc
.DrawLine( x
+20, y
+170, 100, y
+170 );
554 void MyCanvas::DrawDefault(wxDC
& dc
)
556 // Draw circle centered at the origin, then flood fill it with a different
557 // color. Done with a wxMemoryDC because Blit (used by generic
558 // wxDoFloodFill) from a window that is being painted gives unpredictable
561 wxImage
img(21, 21, false);
566 mdc
.SetBrush(dc
.GetBrush());
567 mdc
.SetPen(dc
.GetPen());
568 mdc
.DrawCircle(10, 10, 10);
570 if (mdc
.GetPixel(11, 11, &c
))
572 mdc
.SetBrush(wxColour(128, 128, 0));
573 mdc
.FloodFill(11, 11, c
, wxFLOOD_SURFACE
);
576 bmp
.SetMask(new wxMask(bmp
, wxColour(1, 1, 1)));
577 dc
.DrawBitmap(bmp
, -10, -10, true);
580 dc
.DrawCheckMark(5, 80, 15, 15);
581 dc
.DrawCheckMark(25, 80, 30, 30);
582 dc
.DrawCheckMark(60, 80, 60, 60);
584 // this is the test for "blitting bitmap into DC damages selected brush" bug
585 wxCoord rectSize
= m_std_icon
.GetWidth() + 10;
587 dc
.SetPen(*wxTRANSPARENT_PEN
);
588 dc
.SetBrush( *wxGREEN_BRUSH
);
589 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
590 dc
.DrawBitmap(m_std_icon
, x
+ 5, 15, true);
592 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
593 dc
.DrawIcon(m_std_icon
, x
+ 5, 15);
595 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
597 // test for "transparent" bitmap drawing (it intersects with the last
599 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
601 if (m_smile_bmp
.IsOk())
602 dc
.DrawBitmap(m_smile_bmp
, x
+ rectSize
- 20, rectSize
- 10, true);
604 dc
.SetBrush( *wxBLACK_BRUSH
);
605 dc
.DrawRectangle( 0, 160, 1000, 300 );
608 wxBitmap
bitmap(20,70);
610 memdc
.SelectObject( bitmap
);
611 memdc
.SetBrush( *wxBLACK_BRUSH
);
612 memdc
.SetPen( *wxWHITE_PEN
);
613 memdc
.DrawRectangle(0,0,20,70);
614 memdc
.DrawLine( 10,0,10,70 );
617 wxPen pen
= *wxRED_PEN
;
619 memdc
.DrawLine( 10, 5,10, 5 );
620 memdc
.DrawLine( 10,10,11,10 );
621 memdc
.DrawLine( 10,15,12,15 );
622 memdc
.DrawLine( 10,20,13,20 );
625 memdc.SetPen(*wxRED_PEN);
626 memdc.DrawLine( 12, 5,12, 5 );
627 memdc.DrawLine( 12,10,13,10 );
628 memdc.DrawLine( 12,15,14,15 );
629 memdc.DrawLine( 12,20,15,20 );
633 memdc
.DrawLine( 10,25,10,25 );
634 memdc
.DrawLine( 10,30, 9,30 );
635 memdc
.DrawLine( 10,35, 8,35 );
636 memdc
.DrawLine( 10,40, 7,40 );
639 dc
.SetPen(*wxWHITE_PEN
);
640 memdc
.SetLogicalFunction( wxINVERT
);
641 memdc
.SetPen( *wxWHITE_PEN
);
642 memdc
.DrawLine( 10,50,10,50 );
643 memdc
.DrawLine( 10,55,11,55 );
644 memdc
.DrawLine( 10,60,12,60 );
645 memdc
.DrawLine( 10,65,13,65 );
647 memdc
.DrawLine( 12,50,12,50 );
648 memdc
.DrawLine( 12,55,13,55 );
649 memdc
.DrawLine( 12,60,14,60 );
650 memdc
.DrawLine( 12,65,15,65 );
652 memdc
.SelectObject( wxNullBitmap
);
653 dc
.DrawBitmap( bitmap
, 10, 170 );
654 wxImage image
= bitmap
.ConvertToImage();
655 image
.Rescale( 60,210 );
656 bitmap
= wxBitmap(image
);
657 dc
.DrawBitmap( bitmap
, 50, 170 );
659 // test the rectangle outline drawing - there should be one pixel between
660 // the rect and the lines
661 dc
.SetPen(*wxWHITE_PEN
);
662 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
663 dc
.DrawRectangle(150, 170, 49, 29);
664 dc
.DrawRectangle(200, 170, 49, 29);
665 dc
.SetPen(*wxWHITE_PEN
);
666 dc
.DrawLine(250, 210, 250, 170);
667 dc
.DrawLine(260, 200, 150, 200);
669 // test the rectangle filled drawing - there should be one pixel between
670 // the rect and the lines
671 dc
.SetPen(*wxTRANSPARENT_PEN
);
672 dc
.SetBrush( *wxWHITE_BRUSH
);
673 dc
.DrawRectangle(300, 170, 49, 29);
674 dc
.DrawRectangle(350, 170, 49, 29);
675 dc
.SetPen(*wxWHITE_PEN
);
676 dc
.DrawLine(400, 170, 400, 210);
677 dc
.DrawLine(300, 200, 410, 200);
679 // a few more tests of this kind
680 dc
.SetPen(*wxRED_PEN
);
681 dc
.SetBrush( *wxWHITE_BRUSH
);
682 dc
.DrawRectangle(300, 220, 1, 1);
683 dc
.DrawRectangle(310, 220, 2, 2);
684 dc
.DrawRectangle(320, 220, 3, 3);
685 dc
.DrawRectangle(330, 220, 4, 4);
687 dc
.SetPen(*wxTRANSPARENT_PEN
);
688 dc
.SetBrush( *wxWHITE_BRUSH
);
689 dc
.DrawRectangle(300, 230, 1, 1);
690 dc
.DrawRectangle(310, 230, 2, 2);
691 dc
.DrawRectangle(320, 230, 3, 3);
692 dc
.DrawRectangle(330, 230, 4, 4);
694 // and now for filled rect with outline
695 dc
.SetPen(*wxRED_PEN
);
696 dc
.SetBrush( *wxWHITE_BRUSH
);
697 dc
.DrawRectangle(500, 170, 49, 29);
698 dc
.DrawRectangle(550, 170, 49, 29);
699 dc
.SetPen(*wxWHITE_PEN
);
700 dc
.DrawLine(600, 170, 600, 210);
701 dc
.DrawLine(500, 200, 610, 200);
703 // test the rectangle outline drawing - there should be one pixel between
704 // the rect and the lines
705 dc
.SetPen(*wxWHITE_PEN
);
706 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
707 dc
.DrawRoundedRectangle(150, 270, 49, 29, 6);
708 dc
.DrawRoundedRectangle(200, 270, 49, 29, 6);
709 dc
.SetPen(*wxWHITE_PEN
);
710 dc
.DrawLine(250, 270, 250, 310);
711 dc
.DrawLine(150, 300, 260, 300);
713 // test the rectangle filled drawing - there should be one pixel between
714 // the rect and the lines
715 dc
.SetPen(*wxTRANSPARENT_PEN
);
716 dc
.SetBrush( *wxWHITE_BRUSH
);
717 dc
.DrawRoundedRectangle(300, 270, 49, 29, 6);
718 dc
.DrawRoundedRectangle(350, 270, 49, 29, 6);
719 dc
.SetPen(*wxWHITE_PEN
);
720 dc
.DrawLine(400, 270, 400, 310);
721 dc
.DrawLine(300, 300, 410, 300);
723 // Added by JACS to demonstrate bizarre behaviour.
724 // With a size of 70, we get a missing red RHS,
725 // and the height is too small, so we get yellow
726 // showing. With a size of 40, it draws as expected:
727 // it just shows a white rectangle with red outline.
729 int totalHeight
= 70;
730 wxBitmap
bitmap2(totalWidth
, totalHeight
);
733 memdc2
.SelectObject(bitmap2
);
735 memdc2
.SetBackground(*wxYELLOW_BRUSH
);
738 // Now draw a white rectangle with red outline. It should
739 // entirely eclipse the yellow background.
740 memdc2
.SetPen(*wxRED_PEN
);
741 memdc2
.SetBrush(*wxWHITE_BRUSH
);
743 memdc2
.DrawRectangle(0, 0, totalWidth
, totalHeight
);
745 memdc2
.SetPen(wxNullPen
);
746 memdc2
.SetBrush(wxNullBrush
);
747 memdc2
.SelectObject(wxNullBitmap
);
749 dc
.DrawBitmap(bitmap2
, 500, 270);
751 // Repeat, but draw directly on dc
752 // Draw a yellow rectangle filling the bitmap
754 x
= 600; int y
= 270;
755 dc
.SetPen(*wxYELLOW_PEN
);
756 dc
.SetBrush(*wxYELLOW_BRUSH
);
757 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
759 // Now draw a white rectangle with red outline. It should
760 // entirely eclipse the yellow background.
761 dc
.SetPen(*wxRED_PEN
);
762 dc
.SetBrush(*wxWHITE_BRUSH
);
764 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
767 void MyCanvas::DrawText(wxDC
& dc
)
769 // set underlined font for testing
770 dc
.SetFont( wxFont(12, wxMODERN
, wxNORMAL
, wxNORMAL
, true) );
771 dc
.DrawText( wxT("This is text"), 110, 10 );
772 dc
.DrawRotatedText( wxT("That is text"), 20, 10, -45 );
774 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
775 // under Win9x (it is not TrueType)
776 dc
.SetFont( *wxSWISS_FONT
);
779 dc
.SetBackgroundMode(wxTRANSPARENT
);
781 for ( int n
= -180; n
< 180; n
+= 30 )
783 text
.Printf(wxT(" %d rotated text"), n
);
784 dc
.DrawRotatedText(text
, 400, 400, n
);
787 dc
.SetFont( wxFont( 18, wxSWISS
, wxNORMAL
, wxNORMAL
) );
789 dc
.DrawText( wxT("This is Swiss 18pt text."), 110, 40 );
794 dc
.GetTextExtent( wxT("This is Swiss 18pt text."), &length
, &height
, &descent
);
795 text
.Printf( wxT("Dimensions are length %d, height %d, descent %d"), length
, height
, descent
);
796 dc
.DrawText( text
, 110, 80 );
798 text
.Printf( wxT("CharHeight() returns: %d"), dc
.GetCharHeight() );
799 dc
.DrawText( text
, 110, 120 );
801 dc
.DrawRectangle( 100, 40, 4, height
);
803 // test the logical function effect
805 dc
.SetLogicalFunction(wxINVERT
);
806 // text drawing should ignore logical function
807 dc
.DrawText( wxT("There should be a text below"), 110, 150 );
808 dc
.DrawRectangle( 110, y
, 100, height
);
811 dc
.DrawText( wxT("Visible text"), 110, y
);
812 dc
.DrawRectangle( 110, y
, 100, height
);
813 dc
.DrawText( wxT("Visible text"), 110, y
);
814 dc
.DrawRectangle( 110, y
, 100, height
);
815 dc
.SetLogicalFunction(wxCOPY
);
818 dc
.DrawRectangle( 110, y
, 100, height
);
819 dc
.DrawText( wxT("Another visible text"), 110, y
);
822 dc
.DrawText("And\nmore\ntext on\nmultiple\nlines", 110, y
);
828 wxRasterOperationMode rop
;
829 } rasterOperations
[] =
831 { wxT("wxAND"), wxAND
},
832 { wxT("wxAND_INVERT"), wxAND_INVERT
},
833 { wxT("wxAND_REVERSE"), wxAND_REVERSE
},
834 { wxT("wxCLEAR"), wxCLEAR
},
835 { wxT("wxCOPY"), wxCOPY
},
836 { wxT("wxEQUIV"), wxEQUIV
},
837 { wxT("wxINVERT"), wxINVERT
},
838 { wxT("wxNAND"), wxNAND
},
839 { wxT("wxNO_OP"), wxNO_OP
},
840 { wxT("wxOR"), wxOR
},
841 { wxT("wxOR_INVERT"), wxOR_INVERT
},
842 { wxT("wxOR_REVERSE"), wxOR_REVERSE
},
843 { wxT("wxSET"), wxSET
},
844 { wxT("wxSRC_INVERT"), wxSRC_INVERT
},
845 { wxT("wxXOR"), wxXOR
},
848 void MyCanvas::DrawImages(wxDC
& dc
, DrawMode mode
)
850 dc
.DrawText(wxT("original image"), 0, 0);
851 dc
.DrawBitmap(*gs_bmpNoMask
, 0, 20, 0);
852 dc
.DrawText(wxT("with colour mask"), 0, 100);
853 dc
.DrawBitmap(*gs_bmpWithColMask
, 0, 120, true);
854 dc
.DrawText(wxT("the mask image"), 0, 200);
855 dc
.DrawBitmap(*gs_bmpMask
, 0, 220, 0);
856 dc
.DrawText(wxT("masked image"), 0, 300);
857 dc
.DrawBitmap(*gs_bmpWithMask
, 0, 320, true);
859 int cx
= gs_bmpWithColMask
->GetWidth(),
860 cy
= gs_bmpWithColMask
->GetHeight();
863 for ( size_t n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
865 wxCoord x
= 120 + 150*(n%4
),
868 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
869 memDC
.SelectObject(*gs_bmpWithColMask
);
870 if ( mode
== Draw_Stretch
)
872 dc
.StretchBlit(x
, y
, cx
, cy
, &memDC
, 0, 0, cx
/2, cy
/2,
873 rasterOperations
[n
].rop
, true);
877 dc
.Blit(x
, y
, cx
, cy
, &memDC
, 0, 0, rasterOperations
[n
].rop
, true);
882 void MyCanvas::DrawWithLogicalOps(wxDC
& dc
)
884 static const wxCoord w
= 60;
885 static const wxCoord h
= 60;
887 // reuse the text colour here
888 dc
.SetPen(wxPen(m_owner
->m_colourForeground
));
889 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
892 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
894 wxCoord x
= 20 + 150*(n%4
),
897 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
898 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
899 dc
.DrawRectangle(x
, y
, w
, h
);
900 dc
.DrawLine(x
, y
, x
+ w
, y
+ h
);
901 dc
.DrawLine(x
+ w
, y
, x
, y
+ h
);
904 // now some filled rectangles
905 dc
.SetBrush(wxBrush(m_owner
->m_colourForeground
));
907 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
909 wxCoord x
= 20 + 150*(n%4
),
912 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
913 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
914 dc
.DrawRectangle(x
, y
, w
, h
);
918 #if wxUSE_GRAPHICS_CONTEXT
920 void MyCanvas::DrawAlpha(wxDC
& WXUNUSED(dummyDC
))
922 void MyCanvas::DrawAlpha(wxDC
& dc
)
930 wxDouble margin
= 20 ;
931 wxDouble width
= 180 ;
932 wxDouble radius
= 30 ;
934 dc
.SetPen( wxPen( wxColour( 128, 0, 0 ), 12 ));
935 dc
.SetBrush(*wxRED_BRUSH
);
937 wxRect
r(margin
,margin
+width
*0.66,width
,width
) ;
939 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
941 dc
.SetPen( wxPen( wxColour( 0, 0, 128 ), 12));
942 dc
.SetBrush(*wxBLUE_BRUSH
);
944 r
.Offset( width
* 0.8 , - width
* 0.66 ) ;
946 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
948 dc
.SetPen( wxPen( wxColour( 128, 128, 0 ), 12));
949 dc
.SetBrush( wxBrush( wxColour( 192, 192, 0)));
951 r
.Offset( width
* 0.8 , width
*0.5 ) ;
953 dc
.DrawRoundedRectangle( r
.x
, r
.y
, r
.width
, r
.width
, radius
) ;
955 dc
.SetPen( *wxTRANSPARENT_PEN
) ;
956 dc
.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
957 dc
.DrawRoundedRectangle( 0 , margin
+ width
/ 2 , width
* 3 , 100 , radius
) ;
959 dc
.SetTextForeground( wxColour(255,255,0,128) );
960 dc
.SetFont( wxFont( 40, wxFONTFAMILY_SWISS
, wxFONTSTYLE_ITALIC
, wxFONTWEIGHT_NORMAL
) );
961 dc
.DrawText( wxT("Hello!"), 120, 80 );
966 #if wxUSE_GRAPHICS_CONTEXT
968 const int BASE
= 80.0;
969 const int BASE2
= BASE
/2;
970 const int BASE4
= BASE
/4;
972 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
975 // modeled along Robin Dunn's GraphicsContext.py sample
977 void MyCanvas::DrawGraphics(wxGraphicsContext
* gc
)
979 wxFont font
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
980 gc
->SetFont(font
,*wxBLACK
);
982 // make a path that contains a circle and some lines, centered at 0,0
983 wxGraphicsPath path
= gc
->CreatePath() ;
984 path
.AddCircle( 0, 0, BASE2
);
985 path
.MoveToPoint(0, -BASE2
);
986 path
.AddLineToPoint(0, BASE2
);
987 path
.MoveToPoint(-BASE2
, 0);
988 path
.AddLineToPoint(BASE2
, 0);
990 path
.AddRectangle(-BASE4
, -BASE4
/2, BASE2
, BASE4
);
992 // Now use that path to demonstrate various capbilites of the grpahics context
993 gc
->PushState(); // save current translation/scale/other state
994 gc
->Translate(60, 75); // reposition the context origin
996 gc
->SetPen(wxPen("navy"));
997 gc
->SetBrush(wxBrush("pink"));
999 for( int i
= 0 ; i
< 3 ; ++i
)
1005 label
= "StrokePath";
1015 gc
->GetTextExtent(label
, &w
, &h
, NULL
, NULL
);
1016 gc
->DrawText(label
, -w
/2, -BASE2
-h
-4);
1020 gc
->StrokePath(path
);
1029 gc
->Translate(2*BASE
, 0);
1032 gc
->PopState(); // restore saved state
1033 gc
->PushState(); // save it again
1034 gc
->Translate(60, 200); // offset to the lower part of the window
1036 gc
->DrawText("Scale", 0, -BASE2
);
1037 gc
->Translate(0, 20);
1039 gc
->SetBrush(wxBrush(wxColour(178, 34, 34, 128)));// 128 == half transparent
1040 for( int i
= 0 ; i
< 8 ; ++i
)
1042 gc
->Scale(1.08, 1.08); // increase scale by 8%
1047 gc
->PopState(); // restore saved state
1048 gc
->PushState(); // save it again
1049 gc
->Translate(400, 200);
1051 gc
->DrawText("Rotate", 0, -BASE2
);
1053 // Move the origin over to the next location
1054 gc
->Translate(0, 75);
1056 // draw our path again, rotating it about the central point,
1057 // and changing colors as we go
1058 for ( int angle
= 0 ; angle
< 360 ; angle
+= 30 )
1060 gc
->PushState(); // save this new current state so we can
1061 // pop back to it at the end of the loop
1062 wxImage::RGBValue val
= wxImage::HSVtoRGB(wxImage::HSVValue(float(angle
)/360, 1, 1));
1063 gc
->SetBrush(wxBrush(wxColour(val
.red
, val
.green
, val
.blue
, 64)));
1064 gc
->SetPen(wxPen(wxColour(val
.red
, val
.green
, val
.blue
, 128)));
1066 // use translate to artfully reposition each drawn path
1067 gc
->Translate(1.5 * BASE2
* cos(DegToRad(angle
)),
1068 1.5 * BASE2
* sin(DegToRad(angle
)));
1070 // use Rotate to rotate the path
1071 gc
->Rotate(DegToRad(angle
));
1080 gc
->Translate(60, 400);
1081 gc
->DrawText("Scaled smiley inside a square", 0, 0);
1082 gc
->DrawRectangle(BASE2
, BASE2
, 100, 100);
1083 gc
->DrawBitmap(m_smile_bmp
, BASE2
, BASE2
, 100, 100);
1086 #endif // wxUSE_GRAPHICS_CONTEXT
1088 void MyCanvas::DrawCircles(wxDC
& dc
)
1094 dc
.SetPen( *wxRED_PEN
);
1095 dc
.SetBrush( *wxGREEN_BRUSH
);
1097 dc
.DrawText(wxT("Some circles"), 0, y
);
1098 dc
.DrawCircle(x
, y
, r
);
1099 dc
.DrawCircle(x
+ 2*r
, y
, r
);
1100 dc
.DrawCircle(x
+ 4*r
, y
, r
);
1103 dc
.DrawText(wxT("And ellipses"), 0, y
);
1104 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
1105 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
1106 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
1109 dc
.DrawText(wxT("And arcs"), 0, y
);
1110 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
1111 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
1112 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
1115 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
1116 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
1117 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
1118 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
1120 // same as above, just transparent brush
1122 dc
.SetPen( *wxRED_PEN
);
1123 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
1126 dc
.DrawText(wxT("Some circles"), 0, y
);
1127 dc
.DrawCircle(x
, y
, r
);
1128 dc
.DrawCircle(x
+ 2*r
, y
, r
);
1129 dc
.DrawCircle(x
+ 4*r
, y
, r
);
1132 dc
.DrawText(wxT("And ellipses"), 0, y
);
1133 dc
.DrawEllipse(x
- r
, y
, 2*r
, r
);
1134 dc
.DrawEllipse(x
+ r
, y
, 2*r
, r
);
1135 dc
.DrawEllipse(x
+ 3*r
, y
, 2*r
, r
);
1138 dc
.DrawText(wxT("And arcs"), 0, y
);
1139 dc
.DrawArc(x
- r
, y
, x
+ r
, y
, x
, y
);
1140 dc
.DrawArc(x
+ 4*r
, y
, x
+ 2*r
, y
, x
+ 3*r
, y
);
1141 dc
.DrawArc(x
+ 5*r
, y
, x
+ 5*r
, y
, x
+ 6*r
, y
);
1144 dc
.DrawEllipticArc(x
- r
, y
, 2*r
, r
, 0, 90);
1145 dc
.DrawEllipticArc(x
+ r
, y
, 2*r
, r
, 90, 180);
1146 dc
.DrawEllipticArc(x
+ 3*r
, y
, 2*r
, r
, 180, 270);
1147 dc
.DrawEllipticArc(x
+ 5*r
, y
, 2*r
, r
, 270, 360);
1151 void MyCanvas::DrawSplines(wxDC
& dc
)
1154 dc
.DrawText(wxT("Some splines"), 10, 5);
1156 // values are hardcoded rather than randomly generated
1157 // so the output can be compared between native
1158 // implementations on platforms with different random
1162 const wxPoint
center( R
+ 20, R
+ 20 );
1163 const int angles
[7] = { 0, 10, 33, 77, 13, 145, 90 };
1164 const int radii
[5] = { 100 , 59, 85, 33, 90 };
1168 // background spline calculation
1169 unsigned int radius_pos
= 0;
1170 unsigned int angle_pos
= 0;
1172 for ( int i
= 0; i
< n
; i
++ )
1174 angle
+= angles
[ angle_pos
];
1175 int r
= R
* radii
[ radius_pos
] / 100;
1176 pts
[ i
].x
= center
.x
+ (wxCoord
)( r
* cos( M_PI
* angle
/ 180.0) );
1177 pts
[ i
].y
= center
.y
+ (wxCoord
)( r
* sin( M_PI
* angle
/ 180.0) );
1180 if ( angle_pos
>= WXSIZEOF(angles
) ) angle_pos
= 0;
1183 if ( radius_pos
>= WXSIZEOF(radii
) ) radius_pos
= 0;
1186 // background spline drawing
1187 dc
.SetPen(*wxRED_PEN
);
1188 dc
.DrawSpline(WXSIZEOF(pts
), pts
);
1190 // less detailed spline calculation
1191 wxPoint letters
[4][5];
1193 letters
[0][0] = wxPoint( 0,1); // O O
1194 letters
[0][1] = wxPoint( 1,3); // * *
1195 letters
[0][2] = wxPoint( 2,2); // * O *
1196 letters
[0][3] = wxPoint( 3,3); // * * * *
1197 letters
[0][4] = wxPoint( 4,1); // O O
1199 letters
[1][0] = wxPoint( 5,1); // O*O
1200 letters
[1][1] = wxPoint( 6,1); // *
1201 letters
[1][2] = wxPoint( 7,2); // O
1202 letters
[1][3] = wxPoint( 8,3); // *
1203 letters
[1][4] = wxPoint( 9,3); // O*O
1205 letters
[2][0] = wxPoint( 5,3); // O*O
1206 letters
[2][1] = wxPoint( 6,3); // *
1207 letters
[2][2] = wxPoint( 7,2); // O
1208 letters
[2][3] = wxPoint( 8,1); // *
1209 letters
[2][4] = wxPoint( 9,1); // O*O
1211 letters
[3][0] = wxPoint(10,0); // O O
1212 letters
[3][1] = wxPoint(11,3); // * *
1213 letters
[3][2] = wxPoint(12,1); // * O *
1214 letters
[3][3] = wxPoint(13,3); // * * * *
1215 letters
[3][4] = wxPoint(14,0); // O O
1217 const int dx
= 2 * R
/ letters
[3][4].x
;
1218 const int h
[4] = { -R
/2, 0, R
/4, R
/2 };
1220 for ( int m
= 0; m
< 4; m
++ )
1222 for ( int n
= 0; n
< 5; n
++ )
1224 letters
[m
][n
].x
= center
.x
- R
+ letters
[m
][n
].x
* dx
;
1225 letters
[m
][n
].y
= center
.y
+ h
[ letters
[m
][n
].y
];
1228 dc
.SetPen( wxPen( *wxBLUE
, 1, wxDOT
) );
1229 dc
.DrawLines(5, letters
[m
]);
1230 dc
.SetPen( wxPen( *wxBLACK
, 4) );
1231 dc
.DrawSpline(5, letters
[m
]);
1235 dc
.DrawText(wxT("Splines not supported."), 10, 5);
1239 void MyCanvas::DrawGradients(wxDC
& dc
)
1241 static const int TEXT_HEIGHT
= 15;
1244 wxRect
r(10, 10, 50, 50);
1245 dc
.DrawText(wxT("wxRIGHT"), r
.x
, r
.y
);
1246 r
.Offset(0, TEXT_HEIGHT
);
1247 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxRIGHT
);
1249 r
.Offset(0, r
.height
+ 10);
1250 dc
.DrawText(wxT("wxLEFT"), r
.x
, r
.y
);
1251 r
.Offset(0, TEXT_HEIGHT
);
1252 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxLEFT
);
1254 r
.Offset(0, r
.height
+ 10);
1255 dc
.DrawText(wxT("wxDOWN"), r
.x
, r
.y
);
1256 r
.Offset(0, TEXT_HEIGHT
);
1257 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxDOWN
);
1259 r
.Offset(0, r
.height
+ 10);
1260 dc
.DrawText(wxT("wxUP"), r
.x
, r
.y
);
1261 r
.Offset(0, TEXT_HEIGHT
);
1262 dc
.GradientFillLinear(r
, *wxWHITE
, *wxBLUE
, wxUP
);
1264 wxRect gfr
= wxRect(r
);
1267 r
= wxRect(200, 10, 50, 50);
1268 dc
.DrawText(wxT("Blue inside"), r
.x
, r
.y
);
1269 r
.Offset(0, TEXT_HEIGHT
);
1270 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
);
1272 r
.Offset(0, r
.height
+ 10);
1273 dc
.DrawText(wxT("White inside"), r
.x
, r
.y
);
1274 r
.Offset(0, TEXT_HEIGHT
);
1275 dc
.GradientFillConcentric(r
, *wxWHITE
, *wxBLUE
);
1277 r
.Offset(0, r
.height
+ 10);
1278 dc
.DrawText(wxT("Blue in top left corner"), r
.x
, r
.y
);
1279 r
.Offset(0, TEXT_HEIGHT
);
1280 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(0, 0));
1282 r
.Offset(0, r
.height
+ 10);
1283 dc
.DrawText(wxT("Blue in bottom right corner"), r
.x
, r
.y
);
1284 r
.Offset(0, TEXT_HEIGHT
);
1285 dc
.GradientFillConcentric(r
, *wxBLUE
, *wxWHITE
, wxPoint(r
.width
, r
.height
));
1287 // check that the area filled by the gradient is exactly the interior of
1291 dc
.DrawText("The interior should be filled but", r
.x
, r
.y
);
1293 dc
.DrawText(" the red border should remain visible:", r
.x
, r
.y
);
1304 dc
.SetPen(*wxRED_PEN
);
1305 dc
.DrawRectangle(r
);
1307 dc
.GradientFillLinear(r
, *wxGREEN
, *wxBLACK
, wxNORTH
);
1308 dc
.DrawRectangle(r2
);
1310 dc
.GradientFillLinear(r2
, *wxBLACK
, *wxGREEN
, wxSOUTH
);
1311 dc
.DrawRectangle(r3
);
1313 dc
.GradientFillLinear(r3
, *wxGREEN
, *wxBLACK
, wxEAST
);
1314 dc
.DrawRectangle(r4
);
1316 dc
.GradientFillLinear(r4
, *wxBLACK
, *wxGREEN
, wxWEST
);
1318 #if wxUSE_GRAPHICS_CONTEXT
1321 wxGCDC
&gdc
= (wxGCDC
&)dc
;
1322 wxGraphicsContext
*gc
= gdc
.GetGraphicsContext();
1324 wxGraphicsGradientStops stops
;
1326 gfr
.Offset(0, gfr
.height
+ 10);
1327 dc
.DrawText(wxT("Linear Gradient with Stops"), gfr
.x
, gfr
.y
);
1328 gfr
.Offset(0, TEXT_HEIGHT
);
1330 stops
= wxGraphicsGradientStops(*wxRED
, *wxBLUE
);
1331 stops
.Add(wxColour(255,255,0), 0.33f
);
1332 stops
.Add(*wxGREEN
, 0.67f
);
1334 gc
->SetBrush(gc
->CreateLinearGradientBrush(gfr
.x
, gfr
.y
,
1335 gfr
.x
+ gfr
.width
, gfr
.y
+ gfr
.height
,
1337 pth
= gc
->CreatePath();
1338 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1339 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1340 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1341 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1345 gfr
.Offset(0, gfr
.height
+ 10);
1346 dc
.DrawText(wxT("Radial Gradient with Stops"), gfr
.x
, gfr
.y
);
1347 gfr
.Offset(0, TEXT_HEIGHT
);
1349 gc
->SetBrush(gc
->CreateRadialGradientBrush(gfr
.x
+ gfr
.width
/ 2,
1350 gfr
.y
+ gfr
.height
/ 2,
1351 gfr
.x
+ gfr
.width
/ 2,
1352 gfr
.y
+ gfr
.height
/ 2,
1355 pth
= gc
->CreatePath();
1356 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1357 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1358 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1359 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1363 gfr
.Offset(0, gfr
.height
+ 10);
1364 dc
.DrawText(wxT("Linear Gradient with Stops and Gaps"), gfr
.x
, gfr
.y
);
1365 gfr
.Offset(0, TEXT_HEIGHT
);
1367 stops
= wxGraphicsGradientStops(*wxRED
, *wxBLUE
);
1368 stops
.Add(wxColour(255,255,0), 0.33f
);
1369 stops
.Add(wxTransparentColour
, 0.33f
);
1370 stops
.Add(wxTransparentColour
, 0.67f
);
1371 stops
.Add(*wxGREEN
, 0.67f
);
1373 gc
->SetBrush(gc
->CreateLinearGradientBrush(gfr
.x
, gfr
.y
+ gfr
.height
,
1374 gfr
.x
+ gfr
.width
, gfr
.y
,
1376 pth
= gc
->CreatePath();
1377 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1378 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1379 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1380 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1384 gfr
.Offset(0, gfr
.height
+ 10);
1385 dc
.DrawText(wxT("Radial Gradient with Stops and Gaps"), gfr
.x
, gfr
.y
);
1386 gfr
.Offset(0, TEXT_HEIGHT
);
1388 gc
->SetBrush(gc
->CreateRadialGradientBrush(gfr
.x
+ gfr
.width
/ 2,
1389 gfr
.y
+ gfr
.height
/ 2,
1390 gfr
.x
+ gfr
.width
/ 2,
1391 gfr
.y
+ gfr
.height
/ 2,
1394 pth
= gc
->CreatePath();
1395 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1396 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1397 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1398 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1402 gfr
.Offset(0, gfr
.height
+ 10);
1403 dc
.DrawText(wxT("Gradients with Stops and Transparency"), gfr
.x
, gfr
.y
);
1404 gfr
.Offset(0, TEXT_HEIGHT
);
1406 stops
= wxGraphicsGradientStops(*wxRED
, wxTransparentColour
);
1407 stops
.Add(*wxRED
, 0.33f
);
1408 stops
.Add(wxTransparentColour
, 0.33f
);
1409 stops
.Add(wxTransparentColour
, 0.67f
);
1410 stops
.Add(*wxBLUE
, 0.67f
);
1411 stops
.Add(*wxBLUE
, 1.0f
);
1413 pth
= gc
->CreatePath();
1414 pth
.MoveToPoint(gfr
.x
,gfr
.y
);
1415 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
);
1416 pth
.AddLineToPoint(gfr
.x
+ gfr
.width
,gfr
.y
+gfr
.height
);
1417 pth
.AddLineToPoint(gfr
.x
,gfr
.y
+gfr
.height
);
1420 gc
->SetBrush(gc
->CreateRadialGradientBrush(gfr
.x
+ gfr
.width
/ 2,
1421 gfr
.y
+ gfr
.height
/ 2,
1422 gfr
.x
+ gfr
.width
/ 2,
1423 gfr
.y
+ gfr
.height
/ 2,
1428 stops
= wxGraphicsGradientStops(wxColour(255,0,0, 128), wxColour(0,0,255, 128));
1429 stops
.Add(wxColour(255,255,0,128), 0.33f
);
1430 stops
.Add(wxColour(0,255,0,128), 0.67f
);
1432 gc
->SetBrush(gc
->CreateLinearGradientBrush(gfr
.x
, gfr
.y
,
1433 gfr
.x
+ gfr
.width
, gfr
.y
,
1437 #endif // wxUSE_GRAPHICS_CONTEXT
1440 void MyCanvas::DrawRegions(wxDC
& dc
)
1442 dc
.DrawText(wxT("You should see a red rect partly covered by a cyan one ")
1443 wxT("on the left"), 10, 5);
1444 dc
.DrawText(wxT("and 5 smileys from which 4 are partially clipped on the right"),
1445 10, 5 + dc
.GetCharHeight());
1446 dc
.DrawText(wxT("The second copy should be identical but right part of it ")
1447 wxT("should be offset by 10 pixels."),
1448 10, 5 + 2*dc
.GetCharHeight());
1450 DrawRegionsHelper(dc
, 10, true);
1451 DrawRegionsHelper(dc
, 350, false);
1454 void MyCanvas::DrawRegionsHelper(wxDC
& dc
, wxCoord x
, bool firstTime
)
1458 dc
.DestroyClippingRegion();
1459 dc
.SetBrush( *wxWHITE_BRUSH
);
1460 dc
.SetPen( *wxTRANSPARENT_PEN
);
1461 dc
.DrawRectangle( x
, y
, 310, 310 );
1463 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 270 );
1465 dc
.SetBrush( *wxRED_BRUSH
);
1466 dc
.DrawRectangle( x
, y
, 310, 310 );
1468 dc
.SetClippingRegion( x
+ 10, y
+ 10, 100, 100 );
1470 dc
.SetBrush( *wxCYAN_BRUSH
);
1471 dc
.DrawRectangle( x
, y
, 310, 310 );
1473 dc
.DestroyClippingRegion();
1475 wxRegion
region(x
+ 110, y
+ 20, 100, 270);
1476 #if !defined(__WXMOTIF__)
1478 region
.Offset(10, 10);
1480 dc
.SetDeviceClippingRegion(region
);
1482 dc
.SetBrush( *wxGREY_BRUSH
);
1483 dc
.DrawRectangle( x
, y
, 310, 310 );
1485 if (m_smile_bmp
.IsOk())
1487 dc
.DrawBitmap( m_smile_bmp
, x
+ 150, y
+ 150, true );
1488 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 10, true );
1489 dc
.DrawBitmap( m_smile_bmp
, x
+ 130, y
+ 280, true );
1490 dc
.DrawBitmap( m_smile_bmp
, x
+ 100, y
+ 70, true );
1491 dc
.DrawBitmap( m_smile_bmp
, x
+ 200, y
+ 70, true );
1495 void MyCanvas::OnPaint(wxPaintEvent
&WXUNUSED(event
))
1497 wxPaintDC
pdc(this);
1501 void MyCanvas::Draw(wxDC
& pdc
)
1503 #if wxUSE_GRAPHICS_CONTEXT
1505 wxGraphicsRenderer
* const renderer
= wxGraphicsRenderer::
1506 #if TEST_CAIRO_EVERYWHERE
1509 GetDefaultRenderer()
1513 wxGraphicsContext
* context
;
1514 if ( wxPaintDC
*paintdc
= wxDynamicCast(&pdc
, wxPaintDC
) )
1516 context
= renderer
->CreateContext(*paintdc
);
1518 else if ( wxMemoryDC
*memdc
= wxDynamicCast(&pdc
, wxMemoryDC
) )
1520 context
= renderer
->CreateContext(*memdc
);
1522 #if wxUSE_METAFILE && defined(wxMETAFILE_IS_ENH)
1523 else if ( wxMetafileDC
*metadc
= wxDynamicCast(&pdc
, wxMetafileDC
) )
1525 context
= renderer
->CreateContext(*metadc
);
1530 wxFAIL_MSG( "Unknown wxDC kind" );
1534 gdc
.SetGraphicsContext(context
);
1536 wxDC
&dc
= m_useContext
? (wxDC
&) gdc
: (wxDC
&) pdc
;
1543 m_owner
->PrepareDC(dc
);
1545 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
1546 if ( m_owner
->m_backgroundBrush
.IsOk() )
1547 dc
.SetBackground( m_owner
->m_backgroundBrush
);
1548 if ( m_owner
->m_colourForeground
.IsOk() )
1549 dc
.SetTextForeground( m_owner
->m_colourForeground
);
1550 if ( m_owner
->m_colourBackground
.IsOk() )
1551 dc
.SetTextBackground( m_owner
->m_colourBackground
);
1553 if ( m_owner
->m_textureBackground
) {
1554 if ( ! m_owner
->m_backgroundBrush
.IsOk() ) {
1555 dc
.SetBackground(wxBrush(wxColour(0, 128, 0)));
1560 dc
.SetClippingRegion(100, 100, 100, 100);
1564 if ( m_owner
->m_textureBackground
)
1566 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
1567 for ( int i
= 0; i
< 200; i
++ )
1568 dc
.DrawLine(0, i
*10, i
*10, 0);
1573 case File_ShowDefault
:
1577 case File_ShowCircles
:
1581 case File_ShowSplines
:
1585 case File_ShowRegions
:
1593 case File_ShowLines
:
1594 DrawTestLines( 0, 100, 0, dc
);
1595 DrawTestLines( 0, 320, 1, dc
);
1596 DrawTestLines( 0, 540, 2, dc
);
1597 DrawTestLines( 0, 760, 6, dc
);
1600 case File_ShowBrushes
:
1601 DrawTestBrushes(dc
);
1604 case File_ShowPolygons
:
1609 DrawImages(dc
, Draw_Normal
);
1612 case File_ShowMaskStretch
:
1613 DrawImages(dc
, Draw_Stretch
);
1617 DrawWithLogicalOps(dc
);
1620 #if wxUSE_GRAPHICS_CONTEXT
1621 case File_ShowAlpha
:
1624 case File_ShowGraphics
:
1625 DrawGraphics(gdc
.GetGraphicsContext());
1629 case File_ShowGradients
:
1638 void MyCanvas::OnMouseMove(wxMouseEvent
&event
)
1642 wxClientDC
dc(this);
1644 m_owner
->PrepareDC(dc
);
1646 wxPoint pos
= event
.GetPosition();
1647 long x
= dc
.DeviceToLogicalX( pos
.x
);
1648 long y
= dc
.DeviceToLogicalY( pos
.y
);
1650 str
.Printf( wxT("Current mouse position: %d,%d"), (int)x
, (int)y
);
1651 m_owner
->SetStatusText( str
);
1657 event
.GetPosition(&x
,&y
);
1658 CalcUnscrolledPosition( x
, y
, &xx
, &yy
);
1659 m_currentpoint
= wxPoint( xx
, yy
) ;
1660 wxRect
newrect ( m_anchorpoint
, m_currentpoint
) ;
1662 wxClientDC
dc( this ) ;
1665 wxDCOverlay
overlaydc( m_overlay
, &dc
);
1668 dc
.SetPen( *wxGREY_PEN
);
1669 dc
.SetBrush( wxColour( 192,192,192,64 ) );
1671 dc
.SetPen( wxPen( *wxLIGHT_GREY
, 2 ) );
1672 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
1674 dc
.DrawRectangle( newrect
);
1678 #endif // wxUSE_STATUSBAR
1681 void MyCanvas::OnMouseDown(wxMouseEvent
&event
)
1684 event
.GetPosition(&x
,&y
);
1685 CalcUnscrolledPosition( x
, y
, &xx
, &yy
);
1686 m_anchorpoint
= wxPoint( xx
, yy
) ;
1687 m_currentpoint
= m_anchorpoint
;
1688 m_rubberBand
= true ;
1692 void MyCanvas::OnMouseUp(wxMouseEvent
&event
)
1698 wxClientDC
dc( this );
1700 wxDCOverlay
overlaydc( m_overlay
, &dc
);
1704 m_rubberBand
= false;
1706 wxPoint endpoint
= CalcUnscrolledPosition(event
.GetPosition());
1708 // Don't pop up the message box if nothing was actually selected.
1709 if ( endpoint
!= m_anchorpoint
)
1711 wxLogMessage("Selected rectangle from (%d, %d) to (%d, %d)",
1712 m_anchorpoint
.x
, m_anchorpoint
.y
,
1713 endpoint
.x
, endpoint
.y
);
1718 // ----------------------------------------------------------------------------
1720 // ----------------------------------------------------------------------------
1722 // the event tables connect the wxWidgets events with the functions (event
1723 // handlers) which process them. It can be also done at run-time, but for the
1724 // simple menu events like this the static method is much simpler.
1725 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
1726 EVT_MENU (File_Quit
, MyFrame::OnQuit
)
1727 EVT_MENU (File_About
, MyFrame::OnAbout
)
1728 EVT_MENU (File_Clip
, MyFrame::OnClip
)
1729 #if wxUSE_GRAPHICS_CONTEXT
1730 EVT_MENU (File_GraphicContext
, MyFrame::OnGraphicContext
)
1732 EVT_MENU (File_Copy
, MyFrame::OnCopy
)
1733 EVT_MENU (File_Save
, MyFrame::OnSave
)
1735 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame::OnShow
)
1737 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame::OnOption
)
1740 // frame constructor
1741 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
1742 : wxFrame((wxFrame
*)NULL
, wxID_ANY
, title
, pos
, size
,
1743 wxDEFAULT_FRAME_STYLE
| wxNO_FULL_REPAINT_ON_RESIZE
)
1745 // set the frame icon
1746 SetIcon(wxICON(sample
));
1748 wxMenu
*menuFile
= new wxMenu
;
1749 menuFile
->Append(File_ShowDefault
, wxT("&Default screen\tF1"));
1750 menuFile
->Append(File_ShowText
, wxT("&Text screen\tF2"));
1751 menuFile
->Append(File_ShowLines
, wxT("&Lines screen\tF3"));
1752 menuFile
->Append(File_ShowBrushes
, wxT("&Brushes screen\tF4"));
1753 menuFile
->Append(File_ShowPolygons
, wxT("&Polygons screen\tF5"));
1754 menuFile
->Append(File_ShowMask
, wxT("&Mask screen\tF6"));
1755 menuFile
->Append(File_ShowMaskStretch
, wxT("1/&2 scaled mask\tShift-F6"));
1756 menuFile
->Append(File_ShowOps
, wxT("&Raster operations screen\tF7"));
1757 menuFile
->Append(File_ShowRegions
, wxT("Re&gions screen\tF8"));
1758 menuFile
->Append(File_ShowCircles
, wxT("&Circles screen\tF9"));
1759 #if wxUSE_GRAPHICS_CONTEXT
1760 menuFile
->Append(File_ShowAlpha
, wxT("&Alpha screen\tF10"));
1762 menuFile
->Append(File_ShowSplines
, wxT("Spl&ines screen\tF11"));
1763 menuFile
->Append(File_ShowGradients
, wxT("&Gradients screen\tF12"));
1764 #if wxUSE_GRAPHICS_CONTEXT
1765 menuFile
->Append(File_ShowGraphics
, wxT("&Graphics screen"));
1767 menuFile
->AppendSeparator();
1768 menuFile
->AppendCheckItem(File_Clip
, wxT("&Clip\tCtrl-C"), wxT("Clip/unclip drawing"));
1769 #if wxUSE_GRAPHICS_CONTEXT
1770 menuFile
->AppendCheckItem(File_GraphicContext
, wxT("&Use GraphicContext\tCtrl-Y"), wxT("Use GraphicContext"));
1772 menuFile
->AppendSeparator();
1773 #if wxUSE_METAFILE && defined(wxMETAFILE_IS_ENH)
1774 menuFile
->Append(File_Copy
, wxT("Copy to clipboard"));
1776 menuFile
->Append(File_Save
, wxT("&Save...\tCtrl-S"), wxT("Save drawing to file"));
1777 menuFile
->AppendSeparator();
1778 menuFile
->Append(File_About
, wxT("&About\tCtrl-A"), wxT("Show about dialog"));
1779 menuFile
->AppendSeparator();
1780 menuFile
->Append(File_Quit
, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
1782 wxMenu
*menuMapMode
= new wxMenu
;
1783 menuMapMode
->Append( MapMode_Text
, wxT("&TEXT map mode") );
1784 menuMapMode
->Append( MapMode_Lometric
, wxT("&LOMETRIC map mode") );
1785 menuMapMode
->Append( MapMode_Twips
, wxT("T&WIPS map mode") );
1786 menuMapMode
->Append( MapMode_Points
, wxT("&POINTS map mode") );
1787 menuMapMode
->Append( MapMode_Metric
, wxT("&METRIC map mode") );
1789 wxMenu
*menuUserScale
= new wxMenu
;
1790 menuUserScale
->Append( UserScale_StretchHoriz
, wxT("Stretch &horizontally\tCtrl-H") );
1791 menuUserScale
->Append( UserScale_ShrinkHoriz
, wxT("Shrin&k horizontally\tCtrl-G") );
1792 menuUserScale
->Append( UserScale_StretchVertic
, wxT("Stretch &vertically\tCtrl-V") );
1793 menuUserScale
->Append( UserScale_ShrinkVertic
, wxT("&Shrink vertically\tCtrl-W") );
1794 menuUserScale
->AppendSeparator();
1795 menuUserScale
->Append( UserScale_Restore
, wxT("&Restore to normal\tCtrl-0") );
1797 wxMenu
*menuAxis
= new wxMenu
;
1798 menuAxis
->AppendCheckItem( AxisMirror_Horiz
, wxT("Mirror horizontally\tCtrl-M") );
1799 menuAxis
->AppendCheckItem( AxisMirror_Vertic
, wxT("Mirror vertically\tCtrl-N") );
1801 wxMenu
*menuLogical
= new wxMenu
;
1802 menuLogical
->Append( LogicalOrigin_MoveDown
, wxT("Move &down\tCtrl-D") );
1803 menuLogical
->Append( LogicalOrigin_MoveUp
, wxT("Move &up\tCtrl-U") );
1804 menuLogical
->Append( LogicalOrigin_MoveLeft
, wxT("Move &right\tCtrl-L") );
1805 menuLogical
->Append( LogicalOrigin_MoveRight
, wxT("Move &left\tCtrl-R") );
1806 menuLogical
->AppendSeparator();
1807 menuLogical
->Append( LogicalOrigin_Set
, wxT("Set to (&100, 100)\tShift-Ctrl-1") );
1808 menuLogical
->Append( LogicalOrigin_Restore
, wxT("&Restore to normal\tShift-Ctrl-0") );
1810 wxMenu
*menuColour
= new wxMenu
;
1812 menuColour
->Append( Colour_TextForeground
, wxT("Text &foreground...") );
1813 menuColour
->Append( Colour_TextBackground
, wxT("Text &background...") );
1814 menuColour
->Append( Colour_Background
, wxT("Background &colour...") );
1815 #endif // wxUSE_COLOURDLG
1816 menuColour
->AppendCheckItem( Colour_BackgroundMode
, wxT("&Opaque/transparent\tCtrl-B") );
1817 menuColour
->AppendCheckItem( Colour_TextureBackgound
, wxT("Draw textured back&ground\tCtrl-T") );
1819 // now append the freshly created menu to the menu bar...
1820 wxMenuBar
*menuBar
= new wxMenuBar
;
1821 menuBar
->Append(menuFile
, wxT("&File"));
1822 menuBar
->Append(menuMapMode
, wxT("&Mode"));
1823 menuBar
->Append(menuUserScale
, wxT("&Scale"));
1824 menuBar
->Append(menuAxis
, wxT("&Axis"));
1825 menuBar
->Append(menuLogical
, wxT("&Origin"));
1826 menuBar
->Append(menuColour
, wxT("&Colours"));
1828 // ... and attach this menu bar to the frame
1829 SetMenuBar(menuBar
);
1833 SetStatusText(wxT("Welcome to wxWidgets!"));
1834 #endif // wxUSE_STATUSBAR
1836 m_mapMode
= wxMM_TEXT
;
1839 m_xLogicalOrigin
= 0;
1840 m_yLogicalOrigin
= 0;
1842 m_yAxisReversed
= false;
1843 m_backgroundMode
= wxSOLID
;
1844 m_colourForeground
= *wxBLACK
;
1845 m_colourBackground
= *wxLIGHT_GREY
;
1846 m_textureBackground
= false;
1848 m_canvas
= new MyCanvas( this );
1849 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1854 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1856 // true is to force the frame to close
1860 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1863 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1864 wxT("This sample tests various primitive drawing functions\n")
1865 wxT("(without any attempts to prevent flicker).\n")
1866 wxT("Copyright (c) Robert Roebling 1999")
1869 wxMessageBox(msg
, wxT("About Drawing"), wxOK
| wxICON_INFORMATION
, this);
1872 void MyFrame::OnClip(wxCommandEvent
& event
)
1874 m_canvas
->Clip(event
.IsChecked());
1877 #if wxUSE_GRAPHICS_CONTEXT
1878 void MyFrame::OnGraphicContext(wxCommandEvent
& event
)
1880 m_canvas
->UseGraphicContext(event
.IsChecked());
1884 void MyFrame::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1886 #if wxUSE_METAFILE && defined(wxMETAFILE_IS_ENH)
1891 wxMetafile
*mf
= dc
.Close();
1899 void MyFrame::OnSave(wxCommandEvent
& WXUNUSED(event
))
1901 wxFileDialog
dlg(this, wxT("Save as bitmap"), wxT(""), wxT(""),
1903 wxT("PNG image (*.png)|*.png;*.PNG|")
1905 wxT("Bitmap image (*.bmp)|*.bmp;*.BMP"),
1906 wxFD_SAVE
| wxFD_OVERWRITE_PROMPT
);
1907 if (dlg
.ShowModal() == wxID_OK
)
1909 wxBitmap
bmp(500, 800);
1910 wxMemoryDC
mdc(bmp
);
1911 m_canvas
->Draw(mdc
);
1912 bmp
.ConvertToImage().SaveFile(dlg
.GetPath());
1916 void MyFrame::OnShow(wxCommandEvent
& event
)
1918 m_canvas
->ToShow(event
.GetId());
1921 void MyFrame::OnOption(wxCommandEvent
& event
)
1923 switch (event
.GetId())
1926 m_mapMode
= wxMM_TEXT
;
1928 case MapMode_Lometric
:
1929 m_mapMode
= wxMM_LOMETRIC
;
1932 m_mapMode
= wxMM_TWIPS
;
1934 case MapMode_Points
:
1935 m_mapMode
= wxMM_POINTS
;
1937 case MapMode_Metric
:
1938 m_mapMode
= wxMM_METRIC
;
1941 case LogicalOrigin_MoveDown
:
1942 m_yLogicalOrigin
+= 10;
1944 case LogicalOrigin_MoveUp
:
1945 m_yLogicalOrigin
-= 10;
1947 case LogicalOrigin_MoveLeft
:
1948 m_xLogicalOrigin
+= 10;
1950 case LogicalOrigin_MoveRight
:
1951 m_xLogicalOrigin
-= 10;
1953 case LogicalOrigin_Set
:
1955 m_yLogicalOrigin
= -100;
1957 case LogicalOrigin_Restore
:
1959 m_yLogicalOrigin
= 0;
1962 case UserScale_StretchHoriz
:
1963 m_xUserScale
*= 1.10;
1965 case UserScale_ShrinkHoriz
:
1966 m_xUserScale
/= 1.10;
1968 case UserScale_StretchVertic
:
1969 m_yUserScale
*= 1.10;
1971 case UserScale_ShrinkVertic
:
1972 m_yUserScale
/= 1.10;
1974 case UserScale_Restore
:
1979 case AxisMirror_Vertic
:
1980 m_yAxisReversed
= !m_yAxisReversed
;
1982 case AxisMirror_Horiz
:
1983 m_xAxisReversed
= !m_xAxisReversed
;
1987 case Colour_TextForeground
:
1988 m_colourForeground
= SelectColour();
1990 case Colour_TextBackground
:
1991 m_colourBackground
= SelectColour();
1993 case Colour_Background
:
1995 wxColour col
= SelectColour();
1998 m_backgroundBrush
.SetColour(col
);
2002 #endif // wxUSE_COLOURDLG
2004 case Colour_BackgroundMode
:
2005 m_backgroundMode
= m_backgroundMode
== wxSOLID
? wxTRANSPARENT
2009 case Colour_TextureBackgound
:
2010 m_textureBackground
= ! m_textureBackground
;
2018 m_canvas
->Refresh();
2021 void MyFrame::PrepareDC(wxDC
& dc
)
2023 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
2024 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
2025 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
2026 dc
.SetMapMode( m_mapMode
);
2030 wxColour
MyFrame::SelectColour()
2034 wxColourDialog
dialog(this, &data
);
2036 if ( dialog
.ShowModal() == wxID_OK
)
2038 col
= dialog
.GetColourData().GetColour();
2043 #endif // wxUSE_COLOURDLG