]> git.saurik.com Git - wxWidgets.git/blame - samples/drawing/drawing.cpp
Corrections to wxTextCtrl::HitTest() documentation.
[wxWidgets.git] / samples / drawing / drawing.cpp
CommitLineData
aba99005 1/////////////////////////////////////////////////////////////////////////////
b11729f1 2// Name: samples/drawing/drawing.cpp
0f0c61d0 3// Purpose: shows and tests wxDC features
aba99005
RR
4// Author: Robert Roebling
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Robert Roebling
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
568708e2 19
aba99005
RR
20// For compilers that support precompilation, includes "wx/wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27// for all others, include the necessary headers (this file is usually all you
be5a51fb 28// need because it includes almost all "standard" wxWidgets headers
aba99005
RR
29#ifndef WX_PRECOMP
30 #include "wx/wx.h"
31#endif
32
0f0c61d0 33#include "wx/colordlg.h"
107a1787 34#include "wx/image.h"
389d906b 35#include "wx/artprov.h"
888dde65 36#include "wx/dcgraph.h"
8a021e00 37#include "wx/overlay.h"
795b5a8b 38#include "wx/graphics.h"
e0ac7d94 39#include "wx/filename.h"
f31a4cb2 40
8a021e00
SC
41#define TEST_CAIRO_EVERYWHERE 0
42
aba99005 43// ----------------------------------------------------------------------------
795b5a8b 44// resources
aba99005 45// ----------------------------------------------------------------------------
568708e2 46
aba99005 47// the application icon
3cb332c1
VZ
48#if !defined(__WXMSW__) && !defined(__WXPM__)
49 #include "../sample.xpm"
aba99005
RR
50#endif
51
568708e2
VZ
52// ----------------------------------------------------------------------------
53// global variables
54// ----------------------------------------------------------------------------
55
f6bcfd97
BP
56static wxBitmap *gs_bmpNoMask = NULL,
57 *gs_bmpWithColMask = NULL,
58 *gs_bmpMask = NULL,
59 *gs_bmpWithMask = NULL,
60 *gs_bmp4 = NULL,
61 *gs_bmp4_mono = NULL,
62 *gs_bmp36 = NULL;
568708e2 63
aba99005
RR
64// ----------------------------------------------------------------------------
65// private classes
66// ----------------------------------------------------------------------------
67
68// Define a new application type, each program should derive a class from wxApp
69class MyApp : public wxApp
70{
71public:
72 // override base class virtuals
73 // ----------------------------
74
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();
568708e2 79
f6bcfd97
BP
80 virtual int OnExit() { DeleteBitmaps(); return 0; }
81
568708e2 82protected:
f6bcfd97
BP
83 void DeleteBitmaps();
84
568708e2 85 bool LoadImages();
aba99005
RR
86};
87
b62c3631
RR
88class MyCanvas;
89
aba99005
RR
90// Define a new frame type: this is going to be our main frame
91class MyFrame : public wxFrame
92{
93public:
94 // ctor(s)
95 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
96
97 // event handlers (these functions should _not_ be virtual)
98 void OnQuit(wxCommandEvent& event);
99 void OnAbout(wxCommandEvent& event);
204dd9a7 100 void OnClip(wxCommandEvent& event);
f31a4cb2
SC
101#if wxUSE_GRAPHICS_CONTEXT
102 void OnGraphicContext(wxCommandEvent& event);
103#endif
568708e2 104 void OnShow(wxCommandEvent &event);
aba99005 105 void OnOption(wxCommandEvent &event);
aba99005 106
960a83cc 107#if wxUSE_COLOURDLG
220af862 108 wxColour SelectColour();
960a83cc 109#endif // wxUSE_COLOURDLG
220af862 110 void PrepareDC(wxDC& dc);
0f0c61d0 111
b62c3631 112 int m_backgroundMode;
1edc9f45 113 int m_textureBackground;
89efaf2b 114 wxMappingMode m_mapMode;
b62c3631
RR
115 double m_xUserScale;
116 double m_yUserScale;
117 int m_xLogicalOrigin;
118 int m_yLogicalOrigin;
119 bool m_xAxisReversed,
120 m_yAxisReversed;
121 wxColour m_colourForeground, // these are _text_ colours
122 m_colourBackground;
123 wxBrush m_backgroundBrush;
124 MyCanvas *m_canvas;
aba99005
RR
125
126private:
be5a51fb 127 // any class wishing to process wxWidgets events must use this macro
aba99005
RR
128 DECLARE_EVENT_TABLE()
129};
130
b62c3631
RR
131// define a scrollable canvas for drawing onto
132class MyCanvas: public wxScrolledWindow
133{
134public:
135 MyCanvas( MyFrame *parent );
1e7fd311 136
b62c3631 137 void OnPaint(wxPaintEvent &event);
bf0c00c6 138 void OnMouseMove(wxMouseEvent &event);
8a021e00
SC
139 void OnMouseDown(wxMouseEvent &event);
140 void OnMouseUp(wxMouseEvent &event);
4786aabd 141
f65e33a3 142 void ToShow(int show) { m_show = show; Refresh(); }
568708e2 143
204dd9a7
VZ
144 // set or remove the clipping region
145 void Clip(bool clip) { m_clip = clip; Refresh(); }
f31a4cb2
SC
146#if wxUSE_GRAPHICS_CONTEXT
147 void UseGraphicContext(bool use) { m_useContext = use; Refresh(); }
148#endif
204dd9a7 149
b62c3631 150protected:
e3b81044
VZ
151 enum DrawMode
152 {
153 Draw_Normal,
154 Draw_Stretch
155 };
156
568708e2 157 void DrawTestLines( int x, int y, int width, wxDC &dc );
6386110d
VZ
158 void DrawTestPoly(wxDC& dc);
159 void DrawTestBrushes(wxDC& dc);
568708e2 160 void DrawText(wxDC& dc);
e3b81044 161 void DrawImages(wxDC& dc, DrawMode mode);
81278df2 162 void DrawWithLogicalOps(wxDC& dc);
f31a4cb2
SC
163#if wxUSE_GRAPHICS_CONTEXT
164 void DrawAlpha(wxDC& dc);
7a5c82b1 165 void DrawGraphics(wxGraphicsContext* gc);
f31a4cb2 166#endif
bc3cedfa 167 void DrawRegions(wxDC& dc);
f6bcfd97 168 void DrawCircles(wxDC& dc);
b11729f1 169 void DrawSplines(wxDC& dc);
568708e2 170 void DrawDefault(wxDC& dc);
213ad8e7 171 void DrawGradients(wxDC& dc);
4786aabd 172
4cbcae16 173 void DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime);
8e0e4b1b 174
b62c3631 175private:
568708e2
VZ
176 MyFrame *m_owner;
177
f65e33a3 178 int m_show;
0e09f76e
RR
179 wxBitmap m_smile_bmp;
180 wxIcon m_std_icon;
204dd9a7 181 bool m_clip;
8a021e00
SC
182 wxOverlay m_overlay;
183 bool m_rubberBand;
184 wxPoint m_anchorpoint;
185 wxPoint m_currentpoint;
f31a4cb2
SC
186#if wxUSE_GRAPHICS_CONTEXT
187 bool m_useContext ;
188#endif
568708e2 189
b62c3631
RR
190 DECLARE_EVENT_TABLE()
191};
192
aba99005
RR
193// ----------------------------------------------------------------------------
194// constants
195// ----------------------------------------------------------------------------
196
197// IDs for the controls and the menu commands
198enum
199{
200 // menu items
b11729f1
WS
201 File_Quit = wxID_EXIT,
202 File_About = wxID_ABOUT,
568708e2 203
b11729f1 204 MenuShow_First = wxID_HIGHEST,
568708e2
VZ
205 File_ShowDefault = MenuShow_First,
206 File_ShowText,
207 File_ShowLines,
6386110d 208 File_ShowBrushes,
568708e2
VZ
209 File_ShowPolygons,
210 File_ShowMask,
e3b81044 211 File_ShowMaskStretch,
81278df2 212 File_ShowOps,
bc3cedfa 213 File_ShowRegions,
f6bcfd97 214 File_ShowCircles,
b11729f1 215 File_ShowSplines,
f31a4cb2
SC
216#if wxUSE_GRAPHICS_CONTEXT
217 File_ShowAlpha,
7a5c82b1 218 File_ShowGraphics,
f31a4cb2 219#endif
213ad8e7
VZ
220 File_ShowGradients,
221 MenuShow_Last = File_ShowGradients,
0f0c61d0 222
204dd9a7 223 File_Clip,
f31a4cb2
SC
224#if wxUSE_GRAPHICS_CONTEXT
225 File_GraphicContext,
226#endif
204dd9a7 227
0f0c61d0
VZ
228 MenuOption_First,
229
230 MapMode_Text = MenuOption_First,
aba99005
RR
231 MapMode_Lometric,
232 MapMode_Twips,
233 MapMode_Points,
234 MapMode_Metric,
0f0c61d0 235
aba99005
RR
236 UserScale_StretchHoriz,
237 UserScale_ShrinkHoriz,
238 UserScale_StretchVertic,
239 UserScale_ShrinkVertic,
0f0c61d0
VZ
240 UserScale_Restore,
241
aba99005
RR
242 AxisMirror_Horiz,
243 AxisMirror_Vertic,
0f0c61d0 244
aba99005
RR
245 LogicalOrigin_MoveDown,
246 LogicalOrigin_MoveUp,
247 LogicalOrigin_MoveLeft,
248 LogicalOrigin_MoveRight,
fb576291
VZ
249 LogicalOrigin_Set,
250 LogicalOrigin_Restore,
0f0c61d0 251
960a83cc 252#if wxUSE_COLOURDLG
0f0c61d0
VZ
253 Colour_TextForeground,
254 Colour_TextBackground,
255 Colour_Background,
960a83cc 256#endif // wxUSE_COLOURDLG
0f0c61d0 257 Colour_BackgroundMode,
1edc9f45 258 Colour_TextureBackgound,
0f0c61d0 259
1edc9f45 260 MenuOption_Last = Colour_TextureBackgound
aba99005
RR
261};
262
263// ----------------------------------------------------------------------------
be5a51fb 264// event tables and other macros for wxWidgets
aba99005
RR
265// ----------------------------------------------------------------------------
266
aba99005 267
be5a51fb 268// Create a new application object: this macro will allow wxWidgets to create
aba99005
RR
269// the application object during program execution (it's better than using a
270// static object for many reasons) and also declares the accessor function
271// wxGetApp() which will return the reference of the right type (i.e. MyApp and
272// not wxApp)
273IMPLEMENT_APP(MyApp)
274
275// ============================================================================
276// implementation
277// ============================================================================
278
279// ----------------------------------------------------------------------------
280// the application class
281// ----------------------------------------------------------------------------
282
568708e2
VZ
283bool MyApp::LoadImages()
284{
f6bcfd97
BP
285 gs_bmpNoMask = new wxBitmap;
286 gs_bmpWithColMask = new wxBitmap;
287 gs_bmpMask = new wxBitmap;
288 gs_bmpWithMask = new wxBitmap;
289 gs_bmp4 = new wxBitmap;
290 gs_bmp4_mono = new wxBitmap;
291 gs_bmp36 = new wxBitmap;
292
568708e2 293 wxPathList pathList;
e0ac7d94
VZ
294 // special hack for Unix in-tree sample build, don't do this in real
295 // programs, use wxStandardPaths instead
296 pathList.Add(wxFileName(argv[0]).GetPath());
9a83f860
VZ
297 pathList.Add(wxT("."));
298 pathList.Add(wxT(".."));
299 pathList.Add(wxT("../.."));
568708e2 300
9a83f860 301 wxString path = pathList.FindValidPath(wxT("pat4.bmp"));
568708e2 302 if ( !path )
9da8feef 303 return false;
f6bcfd97 304
e1208c31 305 /* 4 colour bitmap */
f6bcfd97 306 gs_bmp4->LoadFile(path, wxBITMAP_TYPE_BMP);
e1208c31 307 /* turn into mono-bitmap */
f6bcfd97
BP
308 gs_bmp4_mono->LoadFile(path, wxBITMAP_TYPE_BMP);
309 wxMask* mask4 = new wxMask(*gs_bmp4_mono, *wxBLACK);
310 gs_bmp4_mono->SetMask(mask4);
568708e2 311
9a83f860 312 path = pathList.FindValidPath(wxT("pat36.bmp"));
568708e2 313 if ( !path )
9da8feef 314 return false;
f6bcfd97
BP
315 gs_bmp36->LoadFile(path, wxBITMAP_TYPE_BMP);
316 wxMask* mask36 = new wxMask(*gs_bmp36, *wxBLACK);
317 gs_bmp36->SetMask(mask36);
568708e2 318
9a83f860 319 path = pathList.FindValidPath(wxT("image.bmp"));
568708e2 320 if ( !path )
9da8feef 321 return false;
f6bcfd97
BP
322 gs_bmpNoMask->LoadFile(path, wxBITMAP_TYPE_BMP);
323 gs_bmpWithMask->LoadFile(path, wxBITMAP_TYPE_BMP);
324 gs_bmpWithColMask->LoadFile(path, wxBITMAP_TYPE_BMP);
568708e2 325
9a83f860 326 path = pathList.FindValidPath(wxT("mask.bmp"));
568708e2 327 if ( !path )
9da8feef 328 return false;
f6bcfd97 329 gs_bmpMask->LoadFile(path, wxBITMAP_TYPE_BMP);
b9de1315 330
f6bcfd97
BP
331 wxMask *mask = new wxMask(*gs_bmpMask, *wxBLACK);
332 gs_bmpWithMask->SetMask(mask);
568708e2 333
f6bcfd97
BP
334 mask = new wxMask(*gs_bmpWithColMask, *wxWHITE);
335 gs_bmpWithColMask->SetMask(mask);
568708e2 336
9da8feef 337 return true;
568708e2
VZ
338}
339
aba99005
RR
340// `Main program' equivalent: the program execution "starts" here
341bool MyApp::OnInit()
342{
45e6e6f8
VZ
343 if ( !wxApp::OnInit() )
344 return false;
345
aba99005 346 // Create the main application window
9a83f860 347 MyFrame *frame = new MyFrame(wxT("Drawing sample"),
5db56cd2 348 wxDefaultPosition, wxSize(550, 840));
aba99005 349
18f42b94 350 // Show it
9da8feef 351 frame->Show(true);
aba99005 352
568708e2
VZ
353 if ( !LoadImages() )
354 {
4693b20c
MB
355 wxLogError(wxT("Can't load one of the bitmap files needed ")
356 wxT("for this sample from the current or parent ")
357 wxT("directory, please copy them there."));
568708e2 358
e0ac7d94
VZ
359 // still continue, the sample can be used without images too if they're
360 // missing for whatever reason
568708e2
VZ
361 }
362
9da8feef 363 return true;
aba99005
RR
364}
365
f6bcfd97
BP
366void MyApp::DeleteBitmaps()
367{
5276b0a5
VZ
368 wxDELETE(gs_bmpNoMask);
369 wxDELETE(gs_bmpWithColMask);
370 wxDELETE(gs_bmpMask);
371 wxDELETE(gs_bmpWithMask);
372 wxDELETE(gs_bmp4);
373 wxDELETE(gs_bmp4_mono);
374 wxDELETE(gs_bmp36);
f6bcfd97
BP
375}
376
aba99005 377// ----------------------------------------------------------------------------
b62c3631 378// MyCanvas
aba99005
RR
379// ----------------------------------------------------------------------------
380
be5a51fb 381// the event tables connect the wxWidgets events with the functions (event
b62c3631
RR
382// handlers) which process them.
383BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
384 EVT_PAINT (MyCanvas::OnPaint)
bf0c00c6 385 EVT_MOTION (MyCanvas::OnMouseMove)
8a021e00
SC
386 EVT_LEFT_DOWN (MyCanvas::OnMouseDown)
387 EVT_LEFT_UP (MyCanvas::OnMouseUp)
b62c3631
RR
388END_EVENT_TABLE()
389
c4218a74 390#include "smile.xpm"
0e09f76e 391
c4218a74 392MyCanvas::MyCanvas(MyFrame *parent)
9da8feef 393 : wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
c4218a74 394 wxHSCROLL | wxVSCROLL | wxNO_FULL_REPAINT_ON_RESIZE)
b62c3631 395{
b97fa7cf 396 m_owner = parent;
f65e33a3 397 m_show = File_ShowDefault;
0e09f76e 398 m_smile_bmp = wxBitmap(smile_xpm);
389d906b 399 m_std_icon = wxArtProvider::GetIcon(wxART_INFORMATION);
9da8feef 400 m_clip = false;
8a021e00 401 m_rubberBand = false;
f31a4cb2
SC
402#if wxUSE_GRAPHICS_CONTEXT
403 m_useContext = false;
404#endif
b97fa7cf
VZ
405}
406
6386110d 407void MyCanvas::DrawTestBrushes(wxDC& dc)
b97fa7cf 408{
6386110d
VZ
409 static const wxCoord WIDTH = 200;
410 static const wxCoord HEIGHT = 80;
411
412 wxCoord x = 10,
413 y = 10;
414
415 dc.SetBrush(wxBrush(*wxGREEN, wxSOLID));
416 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
9a83f860 417 dc.DrawText(wxT("Solid green"), x + 10, y + 10);
6386110d
VZ
418
419 y += HEIGHT;
420 dc.SetBrush(wxBrush(*wxRED, wxCROSSDIAG_HATCH));
421 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
9a83f860 422 dc.DrawText(wxT("Hatched red"), x + 10, y + 10);
6386110d
VZ
423
424 y += HEIGHT;
425 dc.SetBrush(wxBrush(*gs_bmpMask));
426 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
9a83f860 427 dc.DrawText(wxT("Stipple mono"), x + 10, y + 10);
6386110d
VZ
428
429 y += HEIGHT;
430 dc.SetBrush(wxBrush(*gs_bmpNoMask));
431 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
9a83f860 432 dc.DrawText(wxT("Stipple colour"), x + 10, y + 10);
6386110d 433}
b97fa7cf 434
6386110d
VZ
435void MyCanvas::DrawTestPoly(wxDC& dc)
436{
437 wxBrush brushHatch(*wxRED, wxFDIAGONAL_HATCH);
438 dc.SetBrush(brushHatch);
439
440 wxPoint star[5];
441 star[0] = wxPoint(100, 60);
442 star[1] = wxPoint(60, 150);
443 star[2] = wxPoint(160, 100);
444 star[3] = wxPoint(40, 100);
445 star[4] = wxPoint(140, 150);
446
9a83f860
VZ
447 dc.DrawText(wxT("You should see two (irregular) stars below, the left one ")
448 wxT("hatched"), 10, 10);
449 dc.DrawText(wxT("except for the central region and the right ")
450 wxT("one entirely hatched"), 10, 30);
451 dc.DrawText(wxT("The third star only has a hatched outline"), 10, 50);
163dc80e
VZ
452
453 dc.DrawPolygon(WXSIZEOF(star), star, 0, 30);
454 dc.DrawPolygon(WXSIZEOF(star), star, 160, 30, wxWINDING_RULE);
455
456 wxPoint star2[10];
457 star2[0] = wxPoint(0, 100);
458 star2[1] = wxPoint(-59, -81);
459 star2[2] = wxPoint(95, 31);
460 star2[3] = wxPoint(-95, 31);
461 star2[4] = wxPoint(59, -81);
462 star2[5] = wxPoint(0, 80);
463 star2[6] = wxPoint(-47, -64);
464 star2[7] = wxPoint(76, 24);
465 star2[8] = wxPoint(-76, 24);
466 star2[9] = wxPoint(47, -64);
467 int count[2] = {5, 5};
468
469 dc.DrawPolyPolygon(WXSIZEOF(count), count, star2, 450, 150);
b62c3631
RR
470}
471
1e7fd311 472void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc )
b62c3631 473{
a60b1f5d 474 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
1e7fd311 475 dc.SetBrush( *wxRED_BRUSH );
4693b20c 476 dc.DrawText(wxString::Format(wxT("Testing lines of width %d"), width), x + 10, y - 10);
9a8c7620 477 dc.DrawRectangle( x+10, y+10, 100, 190 );
4786aabd 478
9a83f860 479 dc.DrawText(wxT("Solid/dot/short dash/long dash/dot dash"), x + 150, y + 10);
a60b1f5d 480 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
696e1ea0 481 dc.DrawLine( x+20, y+20, 100, y+20 );
a60b1f5d 482 dc.SetPen( wxPen( wxT("black"), width, wxDOT) );
696e1ea0 483 dc.DrawLine( x+20, y+30, 100, y+30 );
a60b1f5d 484 dc.SetPen( wxPen( wxT("black"), width, wxSHORT_DASH) );
696e1ea0 485 dc.DrawLine( x+20, y+40, 100, y+40 );
a60b1f5d 486 dc.SetPen( wxPen( wxT("black"), width, wxLONG_DASH) );
696e1ea0 487 dc.DrawLine( x+20, y+50, 100, y+50 );
a60b1f5d 488 dc.SetPen( wxPen( wxT("black"), width, wxDOT_DASH) );
696e1ea0 489 dc.DrawLine( x+20, y+60, 100, y+60 );
1e7fd311 490
9a83f860 491 dc.DrawText(wxT("Misc hatches"), x + 150, y + 70);
a60b1f5d 492 dc.SetPen( wxPen( wxT("black"), width, wxBDIAGONAL_HATCH) );
696e1ea0 493 dc.DrawLine( x+20, y+70, 100, y+70 );
a60b1f5d 494 dc.SetPen( wxPen( wxT("black"), width, wxCROSSDIAG_HATCH) );
696e1ea0 495 dc.DrawLine( x+20, y+80, 100, y+80 );
a60b1f5d 496 dc.SetPen( wxPen( wxT("black"), width, wxFDIAGONAL_HATCH) );
696e1ea0 497 dc.DrawLine( x+20, y+90, 100, y+90 );
a60b1f5d 498 dc.SetPen( wxPen( wxT("black"), width, wxCROSS_HATCH) );
696e1ea0 499 dc.DrawLine( x+20, y+100, 100, y+100 );
a60b1f5d 500 dc.SetPen( wxPen( wxT("black"), width, wxHORIZONTAL_HATCH) );
696e1ea0 501 dc.DrawLine( x+20, y+110, 100, y+110 );
a60b1f5d 502 dc.SetPen( wxPen( wxT("black"), width, wxVERTICAL_HATCH) );
696e1ea0 503 dc.DrawLine( x+20, y+120, 100, y+120 );
1e7fd311 504
9a83f860 505 dc.DrawText(wxT("User dash"), x + 150, y + 140);
a60b1f5d 506 wxPen ud( wxT("black"), width, wxUSER_DASH );
e2a5251d
VZ
507 wxDash dash1[6];
508 dash1[0] = 8; // Long dash <---------+
509 dash1[1] = 2; // Short gap |
510 dash1[2] = 3; // Short dash |
511 dash1[3] = 2; // Short gap |
512 dash1[4] = 3; // Short dash |
513 dash1[5] = 2; // Short gap and repeat +
514 ud.SetDashes( 6, dash1 );
515 dc.SetPen( ud );
696e1ea0 516 dc.DrawLine( x+20, y+140, 100, y+140 );
e2a5251d
VZ
517 dash1[0] = 5; // Make first dash shorter
518 ud.SetDashes( 6, dash1 );
519 dc.SetPen( ud );
696e1ea0 520 dc.DrawLine( x+20, y+150, 100, y+150 );
e2a5251d
VZ
521 dash1[2] = 5; // Make second dash longer
522 ud.SetDashes( 6, dash1 );
523 dc.SetPen( ud );
696e1ea0 524 dc.DrawLine( x+20, y+160, 100, y+160 );
e2a5251d
VZ
525 dash1[4] = 5; // Make third dash longer
526 ud.SetDashes( 6, dash1 );
527 dc.SetPen( ud );
696e1ea0 528 dc.DrawLine( x+20, y+170, 100, y+170 );
b62c3631
RR
529}
530
568708e2 531void MyCanvas::DrawDefault(wxDC& dc)
b62c3631 532{
b62c3631
RR
533 // mark the origin
534 dc.DrawCircle(0, 0, 10);
f88c1a17 535
e95c145c 536#if !defined(wxMAC_USE_CORE_GRAPHICS) || !wxMAC_USE_CORE_GRAPHICS
f1e5c798
JS
537 // GetPixel and FloodFill not supported by Mac OS X CoreGraphics
538 // (FloodFill uses Blit from a non-wxMemoryDC)
f88c1a17
JS
539 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
540 dc.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID));
f1e5c798 541
f88c1a17
JS
542 wxColour tmpColour ;
543 dc.GetPixel(1,1, &tmpColour);
544 dc.FloodFill(1,1, tmpColour, wxFLOOD_SURFACE);
f1e5c798 545#endif
11fdee42 546
cd9da200
VZ
547 dc.DrawCheckMark(5, 80, 15, 15);
548 dc.DrawCheckMark(25, 80, 30, 30);
549 dc.DrawCheckMark(60, 80, 60, 60);
550
0e09f76e 551 // this is the test for "blitting bitmap into DC damages selected brush" bug
0e09f76e 552 wxCoord rectSize = m_std_icon.GetWidth() + 10;
cd9da200 553 wxCoord x = 100;
11f26ea0
VZ
554 dc.SetPen(*wxTRANSPARENT_PEN);
555 dc.SetBrush( *wxGREEN_BRUSH );
cd9da200 556 dc.DrawRectangle(x, 10, rectSize, rectSize);
9da8feef 557 dc.DrawBitmap(m_std_icon, x + 5, 15, true);
cd9da200
VZ
558 x += rectSize + 10;
559 dc.DrawRectangle(x, 10, rectSize, rectSize);
0e09f76e 560 dc.DrawIcon(m_std_icon, x + 5, 15);
cd9da200
VZ
561 x += rectSize + 10;
562 dc.DrawRectangle(x, 10, rectSize, rectSize);
11f26ea0
VZ
563
564 // test for "transparent" bitmap drawing (it intersects with the last
565 // rectangle above)
566 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
d6f0a4b3 567
0e09f76e 568 if (m_smile_bmp.Ok())
9da8feef 569 dc.DrawBitmap(m_smile_bmp, x + rectSize - 20, rectSize - 10, true);
107a1787 570
ff7c6c9c 571 dc.SetBrush( *wxBLACK_BRUSH );
107a1787
RR
572 dc.DrawRectangle( 0, 160, 1000, 300 );
573
574 // draw lines
575 wxBitmap bitmap(20,70);
576 wxMemoryDC memdc;
577 memdc.SelectObject( bitmap );
578 memdc.SetBrush( *wxBLACK_BRUSH );
579 memdc.SetPen( *wxWHITE_PEN );
580 memdc.DrawRectangle(0,0,20,70);
581 memdc.DrawLine( 10,0,10,70 );
81278df2 582
d4aa3a4b 583 // to the right
4c45f240 584 wxPen pen = *wxRED_PEN;
4c45f240 585 memdc.SetPen(pen);
107a1787
RR
586 memdc.DrawLine( 10, 5,10, 5 );
587 memdc.DrawLine( 10,10,11,10 );
588 memdc.DrawLine( 10,15,12,15 );
589 memdc.DrawLine( 10,20,13,20 );
81278df2 590
d4aa3a4b
RR
591/*
592 memdc.SetPen(*wxRED_PEN);
107a1787
RR
593 memdc.DrawLine( 12, 5,12, 5 );
594 memdc.DrawLine( 12,10,13,10 );
595 memdc.DrawLine( 12,15,14,15 );
596 memdc.DrawLine( 12,20,15,20 );
d4aa3a4b 597*/
81278df2 598
107a1787
RR
599 // same to the left
600 memdc.DrawLine( 10,25,10,25 );
601 memdc.DrawLine( 10,30, 9,30 );
602 memdc.DrawLine( 10,35, 8,35 );
603 memdc.DrawLine( 10,40, 7,40 );
604
605 // XOR draw lines
d4aa3a4b 606 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
607 memdc.SetLogicalFunction( wxINVERT );
608 memdc.SetPen( *wxWHITE_PEN );
609 memdc.DrawLine( 10,50,10,50 );
610 memdc.DrawLine( 10,55,11,55 );
611 memdc.DrawLine( 10,60,12,60 );
612 memdc.DrawLine( 10,65,13,65 );
81278df2 613
107a1787
RR
614 memdc.DrawLine( 12,50,12,50 );
615 memdc.DrawLine( 12,55,13,55 );
616 memdc.DrawLine( 12,60,14,60 );
617 memdc.DrawLine( 12,65,15,65 );
81278df2 618
107a1787
RR
619 memdc.SelectObject( wxNullBitmap );
620 dc.DrawBitmap( bitmap, 10, 170 );
389d906b 621 wxImage image = bitmap.ConvertToImage();
107a1787 622 image.Rescale( 60,210 );
389d906b 623 bitmap = wxBitmap(image);
107a1787 624 dc.DrawBitmap( bitmap, 50, 170 );
81278df2 625
b9de1315 626 // test the rectangle outline drawing - there should be one pixel between
ff7c6c9c
RR
627 // the rect and the lines
628 dc.SetPen(*wxWHITE_PEN);
629 dc.SetBrush( *wxTRANSPARENT_BRUSH );
ff7c6c9c 630 dc.DrawRectangle(150, 170, 49, 29);
107a1787 631 dc.DrawRectangle(200, 170, 49, 29);
ff7c6c9c 632 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
633 dc.DrawLine(250, 210, 250, 170);
634 dc.DrawLine(260, 200, 150, 200);
b9de1315
VZ
635
636 // test the rectangle filled drawing - there should be one pixel between
ff7c6c9c
RR
637 // the rect and the lines
638 dc.SetPen(*wxTRANSPARENT_PEN);
639 dc.SetBrush( *wxWHITE_BRUSH );
640 dc.DrawRectangle(300, 170, 49, 29);
568708e2 641 dc.DrawRectangle(350, 170, 49, 29);
ff7c6c9c 642 dc.SetPen(*wxWHITE_PEN);
b9de1315
VZ
643 dc.DrawLine(400, 170, 400, 210);
644 dc.DrawLine(300, 200, 410, 200);
645
3d2d8da1
RR
646 // a few more tests of this kind
647 dc.SetPen(*wxRED_PEN);
648 dc.SetBrush( *wxWHITE_BRUSH );
649 dc.DrawRectangle(300, 220, 1, 1);
650 dc.DrawRectangle(310, 220, 2, 2);
651 dc.DrawRectangle(320, 220, 3, 3);
652 dc.DrawRectangle(330, 220, 4, 4);
653
654 dc.SetPen(*wxTRANSPARENT_PEN);
655 dc.SetBrush( *wxWHITE_BRUSH );
656 dc.DrawRectangle(300, 230, 1, 1);
657 dc.DrawRectangle(310, 230, 2, 2);
658 dc.DrawRectangle(320, 230, 3, 3);
659 dc.DrawRectangle(330, 230, 4, 4);
660
b9de1315
VZ
661 // and now for filled rect with outline
662 dc.SetPen(*wxRED_PEN);
663 dc.SetBrush( *wxWHITE_BRUSH );
664 dc.DrawRectangle(500, 170, 49, 29);
665 dc.DrawRectangle(550, 170, 49, 29);
666 dc.SetPen(*wxWHITE_PEN);
667 dc.DrawLine(600, 170, 600, 210);
668 dc.DrawLine(500, 200, 610, 200);
669
670 // test the rectangle outline drawing - there should be one pixel between
ff7c6c9c
RR
671 // the rect and the lines
672 dc.SetPen(*wxWHITE_PEN);
673 dc.SetBrush( *wxTRANSPARENT_BRUSH );
ff7c6c9c 674 dc.DrawRoundedRectangle(150, 270, 49, 29, 6);
107a1787 675 dc.DrawRoundedRectangle(200, 270, 49, 29, 6);
ff7c6c9c 676 dc.SetPen(*wxWHITE_PEN);
107a1787
RR
677 dc.DrawLine(250, 270, 250, 310);
678 dc.DrawLine(150, 300, 260, 300);
b9de1315
VZ
679
680 // test the rectangle filled drawing - there should be one pixel between
ff7c6c9c
RR
681 // the rect and the lines
682 dc.SetPen(*wxTRANSPARENT_PEN);
683 dc.SetBrush( *wxWHITE_BRUSH );
684 dc.DrawRoundedRectangle(300, 270, 49, 29, 6);
685 dc.DrawRoundedRectangle(350, 270, 49, 29, 6);
686 dc.SetPen(*wxWHITE_PEN);
b9de1315
VZ
687 dc.DrawLine(400, 270, 400, 310);
688 dc.DrawLine(300, 300, 410, 300);
ff7c6c9c 689
b14c14ff
JS
690 // Added by JACS to demonstrate bizarre behaviour.
691 // With a size of 70, we get a missing red RHS,
3103e8a9 692 // and the height is too small, so we get yellow
b14c14ff
JS
693 // showing. With a size of 40, it draws as expected:
694 // it just shows a white rectangle with red outline.
695 int totalWidth = 70;
696 int totalHeight = 70;
697 wxBitmap bitmap2(totalWidth, totalHeight);
698
699 wxMemoryDC memdc2;
700 memdc2.SelectObject(bitmap2);
701
925e9792
WS
702 wxColour clr(255, 255, 0);
703 wxBrush yellowBrush(clr, wxSOLID);
d6f0a4b3
JS
704 memdc2.SetBackground(yellowBrush);
705 memdc2.Clear();
b14c14ff 706
925e9792 707 wxPen yellowPen(clr, 1, wxSOLID);
b14c14ff
JS
708
709 // Now draw a white rectangle with red outline. It should
710 // entirely eclipse the yellow background.
711 memdc2.SetPen(*wxRED_PEN);
712 memdc2.SetBrush(*wxWHITE_BRUSH);
713
714 memdc2.DrawRectangle(0, 0, totalWidth, totalHeight);
715
b14c14ff
JS
716 memdc2.SetPen(wxNullPen);
717 memdc2.SetBrush(wxNullBrush);
cd9da200 718 memdc2.SelectObject(wxNullBitmap);
b14c14ff
JS
719
720 dc.DrawBitmap(bitmap2, 500, 270);
d6f0a4b3
JS
721
722 // Repeat, but draw directly on dc
723 // Draw a yellow rectangle filling the bitmap
724
725 x = 600; int y = 270;
726 dc.SetPen(yellowPen);
727 dc.SetBrush(yellowBrush);
728 dc.DrawRectangle(x, y, totalWidth, totalHeight);
729
730 // Now draw a white rectangle with red outline. It should
731 // entirely eclipse the yellow background.
732 dc.SetPen(*wxRED_PEN);
733 dc.SetBrush(*wxWHITE_BRUSH);
734
735 dc.DrawRectangle(x, y, totalWidth, totalHeight);
568708e2
VZ
736}
737
738void MyCanvas::DrawText(wxDC& dc)
739{
9a8c7620 740 // set underlined font for testing
9da8feef 741 dc.SetFont( wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, true) );
9a83f860
VZ
742 dc.DrawText( wxT("This is text"), 110, 10 );
743 dc.DrawRotatedText( wxT("That is text"), 20, 10, -45 );
9a8c7620 744
4770df95
VZ
745 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
746 // under Win9x (it is not TrueType)
747 dc.SetFont( *wxSWISS_FONT );
b62c3631 748
696e1ea0 749 wxString text;
f6bcfd97 750 dc.SetBackgroundMode(wxTRANSPARENT);
696e1ea0
VZ
751
752 for ( int n = -180; n < 180; n += 30 )
753 {
4693b20c 754 text.Printf(wxT(" %d rotated text"), n);
696e1ea0
VZ
755 dc.DrawRotatedText(text , 400, 400, n);
756 }
95724b1a 757
196c87f4 758 dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) );
c45a644e 759
9a83f860 760 dc.DrawText( wxT("This is Swiss 18pt text."), 110, 40 );
c45a644e 761
6f207e66
VS
762 wxCoord length;
763 wxCoord height;
764 wxCoord descent;
9a83f860 765 dc.GetTextExtent( wxT("This is Swiss 18pt text."), &length, &height, &descent );
e22fa4d7 766 text.Printf( wxT("Dimensions are length %d, height %d, descent %d"), length, height, descent );
c45a644e
RR
767 dc.DrawText( text, 110, 80 );
768
4693b20c 769 text.Printf( wxT("CharHeight() returns: %d"), dc.GetCharHeight() );
c45a644e
RR
770 dc.DrawText( text, 110, 120 );
771
568708e2 772 dc.DrawRectangle( 100, 40, 4, height );
f6bcfd97
BP
773
774 // test the logical function effect
775 wxCoord y = 150;
776 dc.SetLogicalFunction(wxINVERT);
e928566f 777 // text drawing should ignore logical function
9a83f860 778 dc.DrawText( wxT("There should be a text below"), 110, 150 );
f6bcfd97
BP
779 dc.DrawRectangle( 110, y, 100, height );
780
f6bcfd97 781 y += height;
9a83f860 782 dc.DrawText( wxT("Visible text"), 110, y );
f6bcfd97 783 dc.DrawRectangle( 110, y, 100, height );
9a83f860 784 dc.DrawText( wxT("Visible text"), 110, y );
f6bcfd97
BP
785 dc.DrawRectangle( 110, y, 100, height );
786 dc.SetLogicalFunction(wxCOPY);
787
788 y += height;
789 dc.DrawRectangle( 110, y, 100, height );
9a83f860 790 dc.DrawText( wxT("Another visible text"), 110, y );
a5bb4514
VZ
791
792 y += height;
793 dc.DrawText("And\nmore\ntext on\nmultiple\nlines", 110, y);
568708e2
VZ
794}
795
81278df2 796static const struct
568708e2 797{
81278df2 798 const wxChar *name;
89efaf2b 799 wxRasterOperationMode rop;
81278df2
VZ
800} rasterOperations[] =
801{
4693b20c
MB
802 { wxT("wxAND"), wxAND },
803 { wxT("wxAND_INVERT"), wxAND_INVERT },
804 { wxT("wxAND_REVERSE"), wxAND_REVERSE },
805 { wxT("wxCLEAR"), wxCLEAR },
806 { wxT("wxCOPY"), wxCOPY },
807 { wxT("wxEQUIV"), wxEQUIV },
808 { wxT("wxINVERT"), wxINVERT },
809 { wxT("wxNAND"), wxNAND },
810 { wxT("wxNO_OP"), wxNO_OP },
811 { wxT("wxOR"), wxOR },
812 { wxT("wxOR_INVERT"), wxOR_INVERT },
813 { wxT("wxOR_REVERSE"), wxOR_REVERSE },
814 { wxT("wxSET"), wxSET },
815 { wxT("wxSRC_INVERT"), wxSRC_INVERT },
816 { wxT("wxXOR"), wxXOR },
81278df2 817};
568708e2 818
e3b81044 819void MyCanvas::DrawImages(wxDC& dc, DrawMode mode)
81278df2 820{
9a83f860 821 dc.DrawText(wxT("original image"), 0, 0);
f6bcfd97 822 dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0);
9a83f860 823 dc.DrawText(wxT("with colour mask"), 0, 100);
9da8feef 824 dc.DrawBitmap(*gs_bmpWithColMask, 0, 120, true);
9a83f860 825 dc.DrawText(wxT("the mask image"), 0, 200);
f6bcfd97 826 dc.DrawBitmap(*gs_bmpMask, 0, 220, 0);
9a83f860 827 dc.DrawText(wxT("masked image"), 0, 300);
9da8feef 828 dc.DrawBitmap(*gs_bmpWithMask, 0, 320, true);
568708e2 829
f6bcfd97
BP
830 int cx = gs_bmpWithColMask->GetWidth(),
831 cy = gs_bmpWithColMask->GetHeight();
568708e2
VZ
832
833 wxMemoryDC memDC;
834 for ( size_t n = 0; n < WXSIZEOF(rasterOperations); n++ )
835 {
836 wxCoord x = 120 + 150*(n%4),
837 y = 20 + 100*(n/4);
4786aabd 838
568708e2 839 dc.DrawText(rasterOperations[n].name, x, y - 20);
f6bcfd97 840 memDC.SelectObject(*gs_bmpWithColMask);
e3b81044
VZ
841 if ( mode == Draw_Stretch )
842 {
843 dc.StretchBlit(x, y, cx, cy, &memDC, 0, 0, cx/2, cy/2,
844 rasterOperations[n].rop, true);
845 }
846 else
847 {
848 dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, true);
849 }
568708e2
VZ
850 }
851}
852
81278df2
VZ
853void MyCanvas::DrawWithLogicalOps(wxDC& dc)
854{
855 static const wxCoord w = 60;
856 static const wxCoord h = 60;
857
858 // reuse the text colour here
859 dc.SetPen(wxPen(m_owner->m_colourForeground, 1, wxSOLID));
11f26ea0 860 dc.SetBrush(*wxTRANSPARENT_BRUSH);
81278df2 861
5888ef1e
VZ
862 size_t n;
863 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
81278df2
VZ
864 {
865 wxCoord x = 20 + 150*(n%4),
866 y = 20 + 100*(n/4);
867
868 dc.DrawText(rasterOperations[n].name, x, y - 20);
869 dc.SetLogicalFunction(rasterOperations[n].rop);
11f26ea0 870 dc.DrawRectangle(x, y, w, h);
81278df2
VZ
871 dc.DrawLine(x, y, x + w, y + h);
872 dc.DrawLine(x + w, y, x, y + h);
873 }
c1d139da
GRG
874
875 // now some filled rectangles
876 dc.SetBrush(wxBrush(m_owner->m_colourForeground, wxSOLID));
877
5888ef1e 878 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
c1d139da
GRG
879 {
880 wxCoord x = 20 + 150*(n%4),
881 y = 500 + 100*(n/4);
882
883 dc.DrawText(rasterOperations[n].name, x, y - 20);
884 dc.SetLogicalFunction(rasterOperations[n].rop);
885 dc.DrawRectangle(x, y, w, h);
886 }
81278df2
VZ
887}
888
f31a4cb2 889#if wxUSE_GRAPHICS_CONTEXT
ad0b4329 890#ifdef __WXGTK20__
84e0e526 891void MyCanvas::DrawAlpha(wxDC& WXUNUSED(dummyDC))
ad0b4329 892#else
f31a4cb2 893void MyCanvas::DrawAlpha(wxDC& dc)
ad0b4329 894#endif
f31a4cb2 895{
ad0b4329
RR
896#ifdef __WXGTK__
897 wxGCDC dc( this );
898 PrepareDC( dc );
899#endif
900
f31a4cb2
SC
901 wxDouble margin = 20 ;
902 wxDouble width = 180 ;
903 wxDouble radius = 30 ;
e3b81044 904
f31a4cb2
SC
905 dc.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID));
906 dc.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID));
e3b81044 907
f31a4cb2 908 wxRect r(margin,margin+width*0.66,width,width) ;
e3b81044 909
f31a4cb2 910 dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
e3b81044 911
f31a4cb2
SC
912 dc.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID));
913 dc.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID));
e3b81044 914
f31a4cb2 915 r.Offset( width * 0.8 , - width * 0.66 ) ;
e3b81044 916
f31a4cb2 917 dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
e3b81044 918
f31a4cb2
SC
919 dc.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID));
920 dc.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID));
921
922 r.Offset( width * 0.8 , width *0.5 ) ;
e3b81044 923
f31a4cb2 924 dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
e3b81044 925
f31a4cb2
SC
926 dc.SetPen( *wxTRANSPARENT_PEN ) ;
927 dc.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
928 dc.DrawRoundedRectangle( 0 , margin + width / 2 , width * 3 , 100 , radius) ;
e3b81044 929
ad0b4329
RR
930 dc.SetTextForeground( wxColour(255,255,0,128) );
931 dc.SetFont( wxFont( 40, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL ) );
932 dc.DrawText( wxT("Hello!"), 120, 80 );
f31a4cb2
SC
933}
934
935#endif
936
7a5c82b1
SC
937#if wxUSE_GRAPHICS_CONTEXT
938
939const int BASE = 80.0;
940const int BASE2 = BASE/2;
941const int BASE4 = BASE/4;
942
943static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
944
945
946// modeled along Robin Dunn's GraphicsContext.py sample
947
948void MyCanvas::DrawGraphics(wxGraphicsContext* gc)
949{
950 wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
951 gc->SetFont(font,*wxBLACK);
4ee4c7b9 952
7a5c82b1
SC
953 // make a path that contains a circle and some lines, centered at 0,0
954 wxGraphicsPath path = gc->CreatePath() ;
955 path.AddCircle( 0, 0, BASE2 );
956 path.MoveToPoint(0, -BASE2);
957 path.AddLineToPoint(0, BASE2);
958 path.MoveToPoint(-BASE2, 0);
959 path.AddLineToPoint(BASE2, 0);
960 path.CloseSubpath();
961 path.AddRectangle(-BASE4, -BASE4/2, BASE2, BASE4);
4ee4c7b9 962
7a5c82b1 963 // Now use that path to demonstrate various capbilites of the grpahics context
4ee4c7b9 964 gc->PushState(); // save current translation/scale/other state
7a5c82b1
SC
965 gc->Translate(60, 75); // reposition the context origin
966
967 gc->SetPen(wxPen("navy", 1));
968 gc->SetBrush(wxBrush("pink"));
4ee4c7b9 969
7a5c82b1
SC
970 for( int i = 0 ; i < 3 ; ++i )
971 {
972 wxString label;
973 switch( i )
974 {
975 case 0 :
976 label = "StrokePath";
977 break;
978 case 1 :
979 label = "FillPath";
980 break;
981 case 2 :
982 label = "DrawPath";
983 break;
984 }
985 wxDouble w, h;
986 gc->GetTextExtent(label, &w, &h, NULL, NULL);
987 gc->DrawText(label, -w/2, -BASE2-h-4);
988 switch( i )
989 {
990 case 0 :
991 gc->StrokePath(path);
992 break;
993 case 1 :
994 gc->FillPath(path);
995 break;
996 case 2 :
997 gc->DrawPath(path);
998 break;
999 }
1000 gc->Translate(2*BASE, 0);
1001 }
4ee4c7b9 1002
7a5c82b1
SC
1003 gc->PopState(); // restore saved state
1004 gc->PushState(); // save it again
1005 gc->Translate(60, 200); // offset to the lower part of the window
4ee4c7b9 1006
7a5c82b1
SC
1007 gc->DrawText("Scale", 0, -BASE2);
1008 gc->Translate(0, 20);
1009
1010 gc->SetBrush(wxBrush(wxColour(178, 34, 34, 128)));// 128 == half transparent
1011 for( int i = 0 ; i < 8 ; ++i )
1012 {
1013 gc->Scale(1.08, 1.08); // increase scale by 8%
4ee4c7b9 1014 gc->Translate(5,5);
7a5c82b1
SC
1015 gc->DrawPath(path);
1016 }
1017
1018 gc->PopState(); // restore saved state
1019 gc->PushState(); // save it again
4ee4c7b9
VZ
1020 gc->Translate(400, 200);
1021
7a5c82b1
SC
1022 gc->DrawText("Rotate", 0, -BASE2);
1023
1024 // Move the origin over to the next location
1025 gc->Translate(0, 75);
1026
1027 // draw our path again, rotating it about the central point,
1028 // and changing colors as we go
1029 for ( int angle = 0 ; angle < 360 ; angle += 30 )
1030 {
4ee4c7b9 1031 gc->PushState(); // save this new current state so we can
7a5c82b1
SC
1032 // pop back to it at the end of the loop
1033 wxImage::RGBValue val = wxImage::HSVtoRGB(wxImage::HSVValue(float(angle)/360, 1, 1));
1034 gc->SetBrush(wxBrush(wxColour(val.red, val.green, val.blue, 64)));
1035 gc->SetPen(wxPen(wxColour(val.red, val.green, val.blue, 128)));
4ee4c7b9 1036
7a5c82b1
SC
1037 // use translate to artfully reposition each drawn path
1038 gc->Translate(1.5 * BASE2 * cos(DegToRad(angle)),
1039 1.5 * BASE2 * sin(DegToRad(angle)));
4ee4c7b9 1040
7a5c82b1
SC
1041 // use Rotate to rotate the path
1042 gc->Rotate(DegToRad(angle));
1043
1044 // now draw it
1045 gc->DrawPath(path);
1046 gc->PopState();
1047 }
1048 gc->PopState();
ce6b1014
VZ
1049
1050 gc->PushState();
1051 gc->Translate(60, 400);
1052 gc->DrawText("Scaled smiley inside a square", 0, 0);
1053 gc->DrawRectangle(BASE2, BASE2, 100, 100);
1054 gc->DrawBitmap(m_smile_bmp, BASE2, BASE2, 100, 100);
1055 gc->PopState();
7a5c82b1 1056}
ce6b1014 1057#endif // wxUSE_GRAPHICS_CONTEXT
7a5c82b1 1058
f6bcfd97
BP
1059void MyCanvas::DrawCircles(wxDC& dc)
1060{
1061 int x = 100,
1062 y = 100,
1063 r = 20;
1064
d9d2dcd8
RR
1065 dc.SetPen( *wxRED_PEN );
1066 dc.SetBrush( *wxGREEN_BRUSH );
1067
9a83f860 1068 dc.DrawText(wxT("Some circles"), 0, y);
d9d2dcd8
RR
1069 dc.DrawCircle(x, y, r);
1070 dc.DrawCircle(x + 2*r, y, r);
1071 dc.DrawCircle(x + 4*r, y, r);
1072
1073 y += 2*r;
9a83f860 1074 dc.DrawText(wxT("And ellipses"), 0, y);
d9d2dcd8
RR
1075 dc.DrawEllipse(x - r, y, 2*r, r);
1076 dc.DrawEllipse(x + r, y, 2*r, r);
1077 dc.DrawEllipse(x + 3*r, y, 2*r, r);
1078
1079 y += 2*r;
9a83f860 1080 dc.DrawText(wxT("And arcs"), 0, y);
d9d2dcd8
RR
1081 dc.DrawArc(x - r, y, x + r, y, x, y);
1082 dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y);
1083 dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y);
1084
1085 y += 2*r;
1086 dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90);
1087 dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
1088 dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
1089 dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
e3b81044 1090
d9d2dcd8 1091 // same as above, just transparent brush
e3b81044 1092
d9d2dcd8
RR
1093 dc.SetPen( *wxRED_PEN );
1094 dc.SetBrush( *wxTRANSPARENT_BRUSH );
1095
1096 y += 2*r;
9a83f860 1097 dc.DrawText(wxT("Some circles"), 0, y);
f6bcfd97
BP
1098 dc.DrawCircle(x, y, r);
1099 dc.DrawCircle(x + 2*r, y, r);
1100 dc.DrawCircle(x + 4*r, y, r);
1101
1102 y += 2*r;
9a83f860 1103 dc.DrawText(wxT("And ellipses"), 0, y);
f6bcfd97
BP
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);
1107
1108 y += 2*r;
9a83f860 1109 dc.DrawText(wxT("And arcs"), 0, y);
f6bcfd97
BP
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);
1113
1114 y += 2*r;
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);
e3b81044 1119
f6bcfd97
BP
1120}
1121
b11729f1
WS
1122void MyCanvas::DrawSplines(wxDC& dc)
1123{
1124#if wxUSE_SPLINES
9a83f860 1125 dc.DrawText(wxT("Some splines"), 10, 5);
b11729f1
WS
1126
1127 // values are hardcoded rather than randomly generated
1128 // so the output can be compared between native
1129 // implementations on platforms with different random
1130 // generators
1131
1132 const int R = 300;
1133 const wxPoint center( R + 20, R + 20 );
1134 const int angles[7] = { 0, 10, 33, 77, 13, 145, 90 };
1135 const int radii[5] = { 100 , 59, 85, 33, 90 };
1136 const int n = 200;
1137 wxPoint pts[n];
1138
1139 // background spline calculation
1140 unsigned int radius_pos = 0;
1141 unsigned int angle_pos = 0;
1142 int angle = 0;
1143 for ( int i = 0; i < n; i++ )
1144 {
1145 angle += angles[ angle_pos ];
1146 int r = R * radii[ radius_pos ] / 100;
1147 pts[ i ].x = center.x + (wxCoord)( r * cos( M_PI * angle / 180.0) );
1148 pts[ i ].y = center.y + (wxCoord)( r * sin( M_PI * angle / 180.0) );
1149
1150 angle_pos++;
1151 if ( angle_pos >= WXSIZEOF(angles) ) angle_pos = 0;
1152
1153 radius_pos++;
1154 if ( radius_pos >= WXSIZEOF(radii) ) radius_pos = 0;
1155 }
1156
1157 // background spline drawing
1158 dc.SetPen(*wxRED_PEN);
1159 dc.DrawSpline(WXSIZEOF(pts), pts);
1160
1161 // less detailed spline calculation
1162 wxPoint letters[4][5];
1163 // w
1164 letters[0][0] = wxPoint( 0,1); // O O
1165 letters[0][1] = wxPoint( 1,3); // * *
1166 letters[0][2] = wxPoint( 2,2); // * O *
1167 letters[0][3] = wxPoint( 3,3); // * * * *
1168 letters[0][4] = wxPoint( 4,1); // O O
1169 // x1
1170 letters[1][0] = wxPoint( 5,1); // O*O
1171 letters[1][1] = wxPoint( 6,1); // *
1172 letters[1][2] = wxPoint( 7,2); // O
1173 letters[1][3] = wxPoint( 8,3); // *
1174 letters[1][4] = wxPoint( 9,3); // O*O
1175 // x2
1176 letters[2][0] = wxPoint( 5,3); // O*O
1177 letters[2][1] = wxPoint( 6,3); // *
1178 letters[2][2] = wxPoint( 7,2); // O
1179 letters[2][3] = wxPoint( 8,1); // *
1180 letters[2][4] = wxPoint( 9,1); // O*O
1181 // W
1182 letters[3][0] = wxPoint(10,0); // O O
1183 letters[3][1] = wxPoint(11,3); // * *
1184 letters[3][2] = wxPoint(12,1); // * O *
1185 letters[3][3] = wxPoint(13,3); // * * * *
1186 letters[3][4] = wxPoint(14,0); // O O
1187
1188 const int dx = 2 * R / letters[3][4].x;
1189 const int h[4] = { -R/2, 0, R/4, R/2 };
1190
1191 for ( int m = 0; m < 4; m++ )
1192 {
1193 for ( int n = 0; n < 5; n++ )
1194 {
1195 letters[m][n].x = center.x - R + letters[m][n].x * dx;
1196 letters[m][n].y = center.y + h[ letters[m][n].y ];
1197 }
1198
1199 dc.SetPen( wxPen( wxT("blue"), 1, wxDOT) );
1200 dc.DrawLines(5, letters[m]);
1201 dc.SetPen( wxPen( wxT("black"), 4, wxSOLID) );
1202 dc.DrawSpline(5, letters[m]);
1203 }
1204
1205#else
9a83f860 1206 dc.DrawText(wxT("Splines not supported."), 10, 5);
b11729f1
WS
1207#endif
1208}
1209
213ad8e7
VZ
1210void MyCanvas::DrawGradients(wxDC& dc)
1211{
2c8f21f8
VZ
1212 static const int TEXT_HEIGHT = 15;
1213
213ad8e7 1214 // LHS: linear
2c8f21f8 1215 wxRect r(10, 10, 50, 50);
9a83f860 1216 dc.DrawText(wxT("wxRIGHT"), r.x, r.y);
2c8f21f8 1217 r.Offset(0, TEXT_HEIGHT);
213ad8e7
VZ
1218 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxRIGHT);
1219
2c8f21f8 1220 r.Offset(0, r.height + 10);
9a83f860 1221 dc.DrawText(wxT("wxLEFT"), r.x, r.y);
2c8f21f8 1222 r.Offset(0, TEXT_HEIGHT);
213ad8e7
VZ
1223 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxLEFT);
1224
2c8f21f8 1225 r.Offset(0, r.height + 10);
9a83f860 1226 dc.DrawText(wxT("wxDOWN"), r.x, r.y);
2c8f21f8 1227 r.Offset(0, TEXT_HEIGHT);
213ad8e7
VZ
1228 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxDOWN);
1229
2c8f21f8 1230 r.Offset(0, r.height + 10);
9a83f860 1231 dc.DrawText(wxT("wxUP"), r.x, r.y);
2c8f21f8 1232 r.Offset(0, TEXT_HEIGHT);
213ad8e7
VZ
1233 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxUP);
1234
4ee4c7b9 1235 wxRect gfr = wxRect(r);
213ad8e7
VZ
1236
1237 // RHS: concentric
2c8f21f8 1238 r = wxRect(200, 10, 50, 50);
9a83f860 1239 dc.DrawText(wxT("Blue inside"), r.x, r.y);
2c8f21f8 1240 r.Offset(0, TEXT_HEIGHT);
213ad8e7
VZ
1241 dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE);
1242
2c8f21f8 1243 r.Offset(0, r.height + 10);
9a83f860 1244 dc.DrawText(wxT("White inside"), r.x, r.y);
2c8f21f8 1245 r.Offset(0, TEXT_HEIGHT);
213ad8e7
VZ
1246 dc.GradientFillConcentric(r, *wxWHITE, *wxBLUE);
1247
2c8f21f8 1248 r.Offset(0, r.height + 10);
9a83f860 1249 dc.DrawText(wxT("Blue in top left corner"), r.x, r.y);
2c8f21f8 1250 r.Offset(0, TEXT_HEIGHT);
213ad8e7
VZ
1251 dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE, wxPoint(0, 0));
1252
2c8f21f8 1253 r.Offset(0, r.height + 10);
9a83f860 1254 dc.DrawText(wxT("Blue in bottom right corner"), r.x, r.y);
2c8f21f8
VZ
1255 r.Offset(0, TEXT_HEIGHT);
1256 dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE, wxPoint(r.width, r.height));
5f77ee3b
VZ
1257
1258 // check that the area filled by the gradient is exactly the interior of
1259 // the rectangle
1260 r.x = 350;
1261 r.y = 30;
1262 dc.DrawText("The interior should be filled but", r.x, r.y);
1263 r.y += 15;
1264 dc.DrawText(" the red border should remain visible:", r.x, r.y);
1265 r.y += 15;
1266
1267 r.width =
1268 r.height = 50;
1269 wxRect r2 = r;
1270 r2.x += 60;
1271 wxRect r3 = r;
1272 r3.y += 60;
1273 wxRect r4 = r2;
1274 r4.y += 60;
1275 dc.SetPen(wxPen(wxColour(255, 0, 0)));
1276 dc.DrawRectangle(r);
1277 r.Deflate(1);
1278 dc.GradientFillLinear(r, wxColour(0,255,0), wxColour(0,0,0), wxNORTH);
1279 dc.DrawRectangle(r2);
1280 r2.Deflate(1);
1281 dc.GradientFillLinear(r2, wxColour(0,0,0), wxColour(0,255,0), wxSOUTH);
1282 dc.DrawRectangle(r3);
1283 r3.Deflate(1);
1284 dc.GradientFillLinear(r3, wxColour(0,255,0), wxColour(0,0,0), wxEAST);
1285 dc.DrawRectangle(r4);
1286 r4.Deflate(1);
1287 dc.GradientFillLinear(r4, wxColour(0,0,0), wxColour(0,255,0), wxWEST);
4ee4c7b9
VZ
1288
1289#if wxUSE_GRAPHICS_CONTEXT
1290 if (m_useContext)
1291 {
1292 wxGCDC &gdc = (wxGCDC&)dc;
1293 wxGraphicsContext *gc = gdc.GetGraphicsContext();
1294 wxGraphicsPath pth;
1295 wxGraphicsGradientStops stops;
1296
1297 gfr.Offset(0, gfr.height + 10);
1298 dc.DrawText(wxT("Linear Gradient with Stops"), gfr.x, gfr.y);
1299 gfr.Offset(0, TEXT_HEIGHT);
1300
1301 stops = wxGraphicsGradientStops(wxColour(255,0,0), wxColour(0,0,255));
1302 stops.Add(wxColour(255,255,0), 0.33f);
1303 stops.Add(wxColour(0,255,0), 0.67f);
1304
1305 gc->SetBrush(gc->CreateLinearGradientBrush(gfr.x, gfr.y,
1306 gfr.x + gfr.width, gfr.y + gfr.height,
1307 stops));
1308 pth = gc->CreatePath();
1309 pth.MoveToPoint(gfr.x,gfr.y);
1310 pth.AddLineToPoint(gfr.x + gfr.width,gfr.y);
1311 pth.AddLineToPoint(gfr.x + gfr.width,gfr.y+gfr.height);
1312 pth.AddLineToPoint(gfr.x,gfr.y+gfr.height);
1313 pth.CloseSubpath();
1314 gc->FillPath(pth);
1315
1316 gfr.Offset(0, gfr.height + 10);
1317 dc.DrawText(wxT("Radial Gradient with Stops"), gfr.x, gfr.y);
1318 gfr.Offset(0, TEXT_HEIGHT);
1319
1320 gc->SetBrush(gc->CreateRadialGradientBrush(gfr.x + gfr.width / 2,
1321 gfr.y + gfr.height / 2,
1322 gfr.x + gfr.width / 2,
1323 gfr.y + gfr.height / 2,
1324 gfr.width / 2,
1325 stops));
1326 pth = gc->CreatePath();
1327 pth.MoveToPoint(gfr.x,gfr.y);
1328 pth.AddLineToPoint(gfr.x + gfr.width,gfr.y);
1329 pth.AddLineToPoint(gfr.x + gfr.width,gfr.y+gfr.height);
1330 pth.AddLineToPoint(gfr.x,gfr.y+gfr.height);
1331 pth.CloseSubpath();
1332 gc->FillPath(pth);
1333
1334 gfr.Offset(0, gfr.height + 10);
1335 dc.DrawText(wxT("Linear Gradient with Stops and Gaps"), gfr.x, gfr.y);
1336 gfr.Offset(0, TEXT_HEIGHT);
1337
1338 stops = wxGraphicsGradientStops(wxColour(255,0,0), wxColour(0,0,255));
1339 stops.Add(wxColour(255,255,0), 0.33f);
1340 stops.Add(wxTransparentColour, 0.33f);
1341 stops.Add(wxTransparentColour, 0.67f);
1342 stops.Add(wxColour(0,255,0), 0.67f);
1343
1344 gc->SetBrush(gc->CreateLinearGradientBrush(gfr.x, gfr.y + gfr.height,
1345 gfr.x + gfr.width, gfr.y,
1346 stops));
1347 pth = gc->CreatePath();
1348 pth.MoveToPoint(gfr.x,gfr.y);
1349 pth.AddLineToPoint(gfr.x + gfr.width,gfr.y);
1350 pth.AddLineToPoint(gfr.x + gfr.width,gfr.y+gfr.height);
1351 pth.AddLineToPoint(gfr.x,gfr.y+gfr.height);
1352 pth.CloseSubpath();
1353 gc->FillPath(pth);
1354
1355 gfr.Offset(0, gfr.height + 10);
1356 dc.DrawText(wxT("Radial Gradient with Stops and Gaps"), gfr.x, gfr.y);
1357 gfr.Offset(0, TEXT_HEIGHT);
1358
1359 gc->SetBrush(gc->CreateRadialGradientBrush(gfr.x + gfr.width / 2,
1360 gfr.y + gfr.height / 2,
1361 gfr.x + gfr.width / 2,
1362 gfr.y + gfr.height / 2,
1363 gfr.width / 2,
1364 stops));
1365 pth = gc->CreatePath();
1366 pth.MoveToPoint(gfr.x,gfr.y);
1367 pth.AddLineToPoint(gfr.x + gfr.width,gfr.y);
1368 pth.AddLineToPoint(gfr.x + gfr.width,gfr.y+gfr.height);
1369 pth.AddLineToPoint(gfr.x,gfr.y+gfr.height);
1370 pth.CloseSubpath();
1371 gc->FillPath(pth);
1372
1373 gfr.Offset(0, gfr.height + 10);
1374 dc.DrawText(wxT("Gradients with Stops and Transparency"), gfr.x, gfr.y);
1375 gfr.Offset(0, TEXT_HEIGHT);
1376
1377 stops = wxGraphicsGradientStops(wxColour(255,0,0), wxTransparentColour);
1378 stops.Add(wxColour(255,0,0), 0.33f);
1379 stops.Add(wxTransparentColour, 0.33f);
1380 stops.Add(wxTransparentColour, 0.67f);
1381 stops.Add(wxColour(0,0,255), 0.67f);
1382 stops.Add(wxColour(0,0,255), 1.0f);
1383
1384 pth = gc->CreatePath();
1385 pth.MoveToPoint(gfr.x,gfr.y);
1386 pth.AddLineToPoint(gfr.x + gfr.width,gfr.y);
1387 pth.AddLineToPoint(gfr.x + gfr.width,gfr.y+gfr.height);
1388 pth.AddLineToPoint(gfr.x,gfr.y+gfr.height);
1389 pth.CloseSubpath();
1390
1391 gc->SetBrush(gc->CreateRadialGradientBrush(gfr.x + gfr.width / 2,
1392 gfr.y + gfr.height / 2,
1393 gfr.x + gfr.width / 2,
1394 gfr.y + gfr.height / 2,
1395 gfr.width / 2,
1396 stops));
1397 gc->FillPath(pth);
1398
1399 stops = wxGraphicsGradientStops(wxColour(255,0,0, 128), wxColour(0,0,255, 128));
1400 stops.Add(wxColour(255,255,0,128), 0.33f);
1401 stops.Add(wxColour(0,255,0,128), 0.67f);
1402
1403 gc->SetBrush(gc->CreateLinearGradientBrush(gfr.x, gfr.y,
1404 gfr.x + gfr.width, gfr.y,
1405 stops));
1406 gc->FillPath(pth);
1407 }
1408#endif // wxUSE_GRAPHICS_CONTEXT
213ad8e7
VZ
1409}
1410
bc3cedfa
RR
1411void MyCanvas::DrawRegions(wxDC& dc)
1412{
9a83f860
VZ
1413 dc.DrawText(wxT("You should see a red rect partly covered by a cyan one ")
1414 wxT("on the left"), 10, 5);
1415 dc.DrawText(wxT("and 5 smileys from which 4 are partially clipped on the right"),
8e0e4b1b 1416 10, 5 + dc.GetCharHeight());
9a83f860
VZ
1417 dc.DrawText(wxT("The second copy should be identical but right part of it ")
1418 wxT("should be offset by 10 pixels."),
4cbcae16 1419 10, 5 + 2*dc.GetCharHeight());
8e0e4b1b 1420
9da8feef
WS
1421 DrawRegionsHelper(dc, 10, true);
1422 DrawRegionsHelper(dc, 350, false);
8e0e4b1b 1423}
c4218a74 1424
4cbcae16 1425void MyCanvas::DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime)
8e0e4b1b 1426{
4cbcae16
VZ
1427 wxCoord y = 100;
1428
8e0e4b1b 1429 dc.DestroyClippingRegion();
bc3cedfa
RR
1430 dc.SetBrush( *wxWHITE_BRUSH );
1431 dc.SetPen( *wxTRANSPARENT_PEN );
4cbcae16 1432 dc.DrawRectangle( x, y, 310, 310 );
c4218a74 1433
4cbcae16 1434 dc.SetClippingRegion( x + 10, y + 10, 100, 270 );
c4218a74 1435
bc3cedfa 1436 dc.SetBrush( *wxRED_BRUSH );
4cbcae16 1437 dc.DrawRectangle( x, y, 310, 310 );
c4218a74 1438
4cbcae16 1439 dc.SetClippingRegion( x + 10, y + 10, 100, 100 );
993f97ee 1440
993f97ee 1441 dc.SetBrush( *wxCYAN_BRUSH );
4cbcae16
VZ
1442 dc.DrawRectangle( x, y, 310, 310 );
1443
1444 dc.DestroyClippingRegion();
1445
1446 wxRegion region(x + 110, y + 20, 100, 270);
8a28bf76 1447#if !defined(__WXMOTIF__)
4cbcae16
VZ
1448 if ( !firstTime )
1449 region.Offset(10, 10);
4cae9a20 1450#endif
795b5a8b 1451 dc.SetDeviceClippingRegion(region);
c4218a74 1452
bc3cedfa 1453 dc.SetBrush( *wxGREY_BRUSH );
4cbcae16 1454 dc.DrawRectangle( x, y, 310, 310 );
c4218a74 1455
5d25c050
RR
1456 if (m_smile_bmp.Ok())
1457 {
9da8feef
WS
1458 dc.DrawBitmap( m_smile_bmp, x + 150, y + 150, true );
1459 dc.DrawBitmap( m_smile_bmp, x + 130, y + 10, true );
1460 dc.DrawBitmap( m_smile_bmp, x + 130, y + 280, true );
1461 dc.DrawBitmap( m_smile_bmp, x + 100, y + 70, true );
1462 dc.DrawBitmap( m_smile_bmp, x + 200, y + 70, true );
5d25c050 1463 }
bc3cedfa
RR
1464}
1465
8a021e00
SC
1466#if TEST_CAIRO_EVERYWHERE
1467extern wxGraphicsRenderer* gCairoRenderer;
1468#endif
1469
568708e2
VZ
1470void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
1471{
f31a4cb2
SC
1472 wxPaintDC pdc(this);
1473
1474#if wxUSE_GRAPHICS_CONTEXT
8a021e00
SC
1475#if TEST_CAIRO_EVERYWHERE
1476 wxGCDC gdc;
1477 gdc.SetGraphicsContext( gCairoRenderer->CreateContext( pdc ) );
1478#else
f31a4cb2 1479 wxGCDC gdc( pdc ) ;
8a021e00 1480#endif
f31a4cb2
SC
1481 wxDC &dc = m_useContext ? (wxDC&) gdc : (wxDC&) pdc ;
1482#else
1483 wxDC &dc = pdc ;
1484#endif
1485
568708e2 1486 PrepareDC(dc);
c4218a74 1487
568708e2
VZ
1488 m_owner->PrepareDC(dc);
1489
1490 dc.SetBackgroundMode( m_owner->m_backgroundMode );
1491 if ( m_owner->m_backgroundBrush.Ok() )
1492 dc.SetBackground( m_owner->m_backgroundBrush );
1493 if ( m_owner->m_colourForeground.Ok() )
1494 dc.SetTextForeground( m_owner->m_colourForeground );
1495 if ( m_owner->m_colourBackground.Ok() )
1496 dc.SetTextBackground( m_owner->m_colourBackground );
4786aabd 1497
1edc9f45 1498 if ( m_owner->m_textureBackground) {
047473c9 1499 if ( ! m_owner->m_backgroundBrush.Ok() ) {
925e9792
WS
1500 wxColour clr(0,128,0);
1501 wxBrush b(clr, wxSOLID);
1edc9f45
RD
1502 dc.SetBackground(b);
1503 }
047473c9
RD
1504 }
1505
204dd9a7
VZ
1506 if ( m_clip )
1507 dc.SetClippingRegion(100, 100, 100, 100);
1508
e1208c31 1509 dc.Clear();
1edc9f45 1510
204dd9a7
VZ
1511 if ( m_owner->m_textureBackground )
1512 {
1edc9f45 1513 dc.SetPen(*wxMEDIUM_GREY_PEN);
204dd9a7 1514 for ( int i = 0; i < 200; i++ )
1edc9f45
RD
1515 dc.DrawLine(0, i*10, i*10, 0);
1516 }
1517
568708e2
VZ
1518 switch ( m_show )
1519 {
f65e33a3 1520 case File_ShowDefault:
568708e2
VZ
1521 DrawDefault(dc);
1522 break;
1e7fd311 1523
f65e33a3 1524 case File_ShowCircles:
f6bcfd97
BP
1525 DrawCircles(dc);
1526 break;
1527
f65e33a3 1528 case File_ShowSplines:
b11729f1
WS
1529 DrawSplines(dc);
1530 break;
1531
f65e33a3 1532 case File_ShowRegions:
bc3cedfa
RR
1533 DrawRegions(dc);
1534 break;
1535
f65e33a3 1536 case File_ShowText:
568708e2
VZ
1537 DrawText(dc);
1538 break;
1e7fd311 1539
f65e33a3 1540 case File_ShowLines:
568708e2 1541 DrawTestLines( 0, 100, 0, dc );
f6bcfd97
BP
1542 DrawTestLines( 0, 320, 1, dc );
1543 DrawTestLines( 0, 540, 2, dc );
1544 DrawTestLines( 0, 760, 6, dc );
568708e2 1545 break;
1e7fd311 1546
f65e33a3 1547 case File_ShowBrushes:
6386110d
VZ
1548 DrawTestBrushes(dc);
1549 break;
1550
f65e33a3 1551 case File_ShowPolygons:
6386110d 1552 DrawTestPoly(dc);
568708e2 1553 break;
1e7fd311 1554
f65e33a3 1555 case File_ShowMask:
e3b81044
VZ
1556 DrawImages(dc, Draw_Normal);
1557 break;
1558
f65e33a3 1559 case File_ShowMaskStretch:
e3b81044 1560 DrawImages(dc, Draw_Stretch);
568708e2 1561 break;
81278df2 1562
f65e33a3 1563 case File_ShowOps:
81278df2
VZ
1564 DrawWithLogicalOps(dc);
1565 break;
e3b81044 1566
f31a4cb2 1567#if wxUSE_GRAPHICS_CONTEXT
f65e33a3 1568 case File_ShowAlpha:
f31a4cb2
SC
1569 DrawAlpha(dc);
1570 break;
f65e33a3 1571 case File_ShowGraphics:
7a5c82b1
SC
1572 DrawGraphics(gdc.GetGraphicsContext());
1573 break;
f31a4cb2 1574#endif
213ad8e7 1575
f65e33a3 1576 case File_ShowGradients:
213ad8e7
VZ
1577 DrawGradients(dc);
1578 break;
e95c145c
WS
1579
1580 default:
1581 break;
568708e2 1582 }
b62c3631
RR
1583}
1584
bf0c00c6
RR
1585void MyCanvas::OnMouseMove(wxMouseEvent &event)
1586{
960a83cc 1587#if wxUSE_STATUSBAR
8a021e00
SC
1588 {
1589 wxClientDC dc(this);
1590 PrepareDC(dc);
1591 m_owner->PrepareDC(dc);
1592
1593 wxPoint pos = event.GetPosition();
1594 long x = dc.DeviceToLogicalX( pos.x );
1595 long y = dc.DeviceToLogicalY( pos.y );
1596 wxString str;
1597 str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y );
1598 m_owner->SetStatusText( str );
1599 }
4ee4c7b9 1600
8a021e00
SC
1601 if ( m_rubberBand )
1602 {
1603 int x,y, xx, yy ;
1604 event.GetPosition(&x,&y);
1605 CalcUnscrolledPosition( x, y, &xx, &yy );
1606 m_currentpoint = wxPoint( xx , yy ) ;
1607 wxRect newrect ( m_anchorpoint , m_currentpoint ) ;
1608
1609 wxClientDC dc( this ) ;
1610 PrepareDC( dc ) ;
1611
1612 wxDCOverlay overlaydc( m_overlay, &dc );
1613 overlaydc.Clear();
e630cd04 1614#ifdef __WXMAC__
8a021e00
SC
1615 dc.SetPen( *wxGREY_PEN );
1616 dc.SetBrush( wxColour( 192,192,192,64 ) );
1617#else
1618 dc.SetPen( wxPen( *wxLIGHT_GREY, 2, wxSOLID ) );
1619 dc.SetBrush( *wxTRANSPARENT_BRUSH );
1620#endif
1621 dc.DrawRectangle( newrect );
1622 }
960a83cc
WS
1623#else
1624 wxUnusedVar(event);
1625#endif // wxUSE_STATUSBAR
bf0c00c6
RR
1626}
1627
8a021e00
SC
1628void MyCanvas::OnMouseDown(wxMouseEvent &event)
1629{
4ee4c7b9
VZ
1630 int x,y,xx,yy ;
1631 event.GetPosition(&x,&y);
8a021e00
SC
1632 CalcUnscrolledPosition( x, y, &xx, &yy );
1633 m_anchorpoint = wxPoint( xx , yy ) ;
1634 m_currentpoint = m_anchorpoint ;
1635 m_rubberBand = true ;
1636 CaptureMouse() ;
1637}
1638
1639void MyCanvas::OnMouseUp(wxMouseEvent &event)
1640{
1641 if ( m_rubberBand )
1642 {
5f0d3411 1643 ReleaseMouse();
8a021e00
SC
1644 {
1645 wxClientDC dc( this );
1646 PrepareDC( dc );
1647 wxDCOverlay overlaydc( m_overlay, &dc );
1648 overlaydc.Clear();
1649 }
1650 m_overlay.Reset();
1651 m_rubberBand = false;
1652
1653 int x,y,xx,yy ;
1654 event.GetPosition(&x,&y);
1655 CalcUnscrolledPosition( x, y, &xx, &yy );
4ee4c7b9 1656
8a021e00 1657 wxString str;
4ee4c7b9 1658 str.Printf( wxT("Rectangle selection from %d,%d to %d,%d"),
8a021e00
SC
1659 m_anchorpoint.x, m_anchorpoint.y , (int)xx, (int)yy );
1660 wxMessageBox( str , wxT("Rubber-Banding") );
1661
1662 }
1663}
1664
b62c3631
RR
1665// ----------------------------------------------------------------------------
1666// MyFrame
1667// ----------------------------------------------------------------------------
1668
be5a51fb 1669// the event tables connect the wxWidgets events with the functions (event
b62c3631
RR
1670// handlers) which process them. It can be also done at run-time, but for the
1671// simple menu events like this the static method is much simpler.
1672BEGIN_EVENT_TABLE(MyFrame, wxFrame)
568708e2
VZ
1673 EVT_MENU (File_Quit, MyFrame::OnQuit)
1674 EVT_MENU (File_About, MyFrame::OnAbout)
204dd9a7 1675 EVT_MENU (File_Clip, MyFrame::OnClip)
f31a4cb2
SC
1676#if wxUSE_GRAPHICS_CONTEXT
1677 EVT_MENU (File_GraphicContext, MyFrame::OnGraphicContext)
1678#endif
568708e2
VZ
1679
1680 EVT_MENU_RANGE(MenuShow_First, MenuShow_Last, MyFrame::OnShow)
1681
b62c3631
RR
1682 EVT_MENU_RANGE(MenuOption_First, MenuOption_Last, MyFrame::OnOption)
1683END_EVENT_TABLE()
1684
aba99005
RR
1685// frame constructor
1686MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
9da8feef 1687 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size,
c4218a74 1688 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
aba99005
RR
1689{
1690 // set the frame icon
3cb332c1 1691 SetIcon(wxICON(sample));
aba99005
RR
1692
1693 wxMenu *menuFile = new wxMenu;
9a83f860
VZ
1694 menuFile->Append(File_ShowDefault, wxT("&Default screen\tF1"));
1695 menuFile->Append(File_ShowText, wxT("&Text screen\tF2"));
1696 menuFile->Append(File_ShowLines, wxT("&Lines screen\tF3"));
1697 menuFile->Append(File_ShowBrushes, wxT("&Brushes screen\tF4"));
1698 menuFile->Append(File_ShowPolygons, wxT("&Polygons screen\tF5"));
1699 menuFile->Append(File_ShowMask, wxT("&Mask screen\tF6"));
1700 menuFile->Append(File_ShowMaskStretch, wxT("1/&2 scaled mask\tShift-F6"));
1701 menuFile->Append(File_ShowOps, wxT("&Raster operations screen\tF7"));
1702 menuFile->Append(File_ShowRegions, wxT("Re&gions screen\tF8"));
1703 menuFile->Append(File_ShowCircles, wxT("&Circles screen\tF9"));
f31a4cb2 1704#if wxUSE_GRAPHICS_CONTEXT
9a83f860 1705 menuFile->Append(File_ShowAlpha, wxT("&Alpha screen\tF10"));
f31a4cb2 1706#endif
9a83f860
VZ
1707 menuFile->Append(File_ShowSplines, wxT("&Splines screen\tF11"));
1708 menuFile->Append(File_ShowGradients, wxT("&Gradients screen\tF12"));
7a5c82b1 1709#if wxUSE_GRAPHICS_CONTEXT
9a83f860 1710 menuFile->Append(File_ShowGraphics, wxT("&Graphics screen"));
7a5c82b1 1711#endif
568708e2 1712 menuFile->AppendSeparator();
9a83f860 1713 menuFile->AppendCheckItem(File_Clip, wxT("&Clip\tCtrl-C"), wxT("Clip/unclip drawing"));
f31a4cb2 1714#if wxUSE_GRAPHICS_CONTEXT
9a83f860 1715 menuFile->AppendCheckItem(File_GraphicContext, wxT("&Use GraphicContext\tCtrl-Y"), wxT("Use GraphicContext"));
f31a4cb2 1716#endif
204dd9a7 1717 menuFile->AppendSeparator();
9a83f860 1718 menuFile->Append(File_About, wxT("&About...\tCtrl-A"), wxT("Show about dialog"));
aba99005 1719 menuFile->AppendSeparator();
9a83f860 1720 menuFile->Append(File_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
0f0c61d0 1721
aba99005 1722 wxMenu *menuMapMode = new wxMenu;
9a83f860
VZ
1723 menuMapMode->Append( MapMode_Text, wxT("&TEXT map mode") );
1724 menuMapMode->Append( MapMode_Lometric, wxT("&LOMETRIC map mode") );
1725 menuMapMode->Append( MapMode_Twips, wxT("T&WIPS map mode") );
1726 menuMapMode->Append( MapMode_Points, wxT("&POINTS map mode") );
1727 menuMapMode->Append( MapMode_Metric, wxT("&METRIC map mode") );
0f0c61d0 1728
aba99005 1729 wxMenu *menuUserScale = new wxMenu;
9a83f860
VZ
1730 menuUserScale->Append( UserScale_StretchHoriz, wxT("Stretch &horizontally\tCtrl-H") );
1731 menuUserScale->Append( UserScale_ShrinkHoriz, wxT("Shrin&k horizontally\tCtrl-G") );
1732 menuUserScale->Append( UserScale_StretchVertic, wxT("Stretch &vertically\tCtrl-V") );
1733 menuUserScale->Append( UserScale_ShrinkVertic, wxT("&Shrink vertically\tCtrl-W") );
0f0c61d0 1734 menuUserScale->AppendSeparator();
9a83f860 1735 menuUserScale->Append( UserScale_Restore, wxT("&Restore to normal\tCtrl-0") );
0f0c61d0 1736
aba99005 1737 wxMenu *menuAxis = new wxMenu;
9a83f860
VZ
1738 menuAxis->AppendCheckItem( AxisMirror_Horiz, wxT("Mirror horizontally\tCtrl-M") );
1739 menuAxis->AppendCheckItem( AxisMirror_Vertic, wxT("Mirror vertically\tCtrl-N") );
0f0c61d0 1740
aba99005 1741 wxMenu *menuLogical = new wxMenu;
9a83f860
VZ
1742 menuLogical->Append( LogicalOrigin_MoveDown, wxT("Move &down\tCtrl-D") );
1743 menuLogical->Append( LogicalOrigin_MoveUp, wxT("Move &up\tCtrl-U") );
1744 menuLogical->Append( LogicalOrigin_MoveLeft, wxT("Move &right\tCtrl-L") );
1745 menuLogical->Append( LogicalOrigin_MoveRight, wxT("Move &left\tCtrl-R") );
fb576291 1746 menuLogical->AppendSeparator();
9a83f860
VZ
1747 menuLogical->Append( LogicalOrigin_Set, wxT("Set to (&100, 100)\tShift-Ctrl-1") );
1748 menuLogical->Append( LogicalOrigin_Restore, wxT("&Restore to normal\tShift-Ctrl-0") );
aba99005 1749
0f0c61d0 1750 wxMenu *menuColour = new wxMenu;
960a83cc 1751#if wxUSE_COLOURDLG
9a83f860
VZ
1752 menuColour->Append( Colour_TextForeground, wxT("Text &foreground...") );
1753 menuColour->Append( Colour_TextBackground, wxT("Text &background...") );
1754 menuColour->Append( Colour_Background, wxT("Background &colour...") );
960a83cc 1755#endif // wxUSE_COLOURDLG
9a83f860
VZ
1756 menuColour->AppendCheckItem( Colour_BackgroundMode, wxT("&Opaque/transparent\tCtrl-B") );
1757 menuColour->AppendCheckItem( Colour_TextureBackgound, wxT("Draw textured back&ground\tCtrl-T") );
0f0c61d0 1758
aba99005
RR
1759 // now append the freshly created menu to the menu bar...
1760 wxMenuBar *menuBar = new wxMenuBar;
9a83f860
VZ
1761 menuBar->Append(menuFile, wxT("&File"));
1762 menuBar->Append(menuMapMode, wxT("&Mode"));
1763 menuBar->Append(menuUserScale, wxT("&Scale"));
1764 menuBar->Append(menuAxis, wxT("&Axis"));
1765 menuBar->Append(menuLogical, wxT("&Origin"));
1766 menuBar->Append(menuColour, wxT("&Colours"));
aba99005
RR
1767
1768 // ... and attach this menu bar to the frame
1769 SetMenuBar(menuBar);
1770
960a83cc 1771#if wxUSE_STATUSBAR
aba99005 1772 CreateStatusBar(2);
9a83f860 1773 SetStatusText(wxT("Welcome to wxWidgets!"));
960a83cc 1774#endif // wxUSE_STATUSBAR
0f0c61d0 1775
aba99005
RR
1776 m_mapMode = wxMM_TEXT;
1777 m_xUserScale = 1.0;
1778 m_yUserScale = 1.0;
1779 m_xLogicalOrigin = 0;
1780 m_yLogicalOrigin = 0;
0f0c61d0 1781 m_xAxisReversed =
9da8feef 1782 m_yAxisReversed = false;
0f0c61d0 1783 m_backgroundMode = wxSOLID;
4ee4c7b9
VZ
1784 m_colourForeground = *wxBLACK;
1785 m_colourBackground = *wxLIGHT_GREY;
9da8feef 1786 m_textureBackground = false;
aba99005 1787
b62c3631 1788 m_canvas = new MyCanvas( this );
b97fa7cf 1789 m_canvas->SetScrollbars( 10, 10, 100, 240 );
b62c3631 1790}
aba99005
RR
1791
1792// event handlers
1793
1794void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1795{
9da8feef
WS
1796 // true is to force the frame to close
1797 Close(true);
aba99005
RR
1798}
1799
1800void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1801{
1802 wxString msg;
c916e13b
RR
1803 msg.Printf( wxT("This is the about dialog of the drawing sample.\n")
1804 wxT("This sample tests various primitive drawing functions\n")
6386110d 1805 wxT("(without any attempts to prevent flicker).\n")
c916e13b 1806 wxT("Copyright (c) Robert Roebling 1999")
aba99005
RR
1807 );
1808
9a83f860 1809 wxMessageBox(msg, wxT("About Drawing"), wxOK | wxICON_INFORMATION, this);
aba99005
RR
1810}
1811
204dd9a7
VZ
1812void MyFrame::OnClip(wxCommandEvent& event)
1813{
1814 m_canvas->Clip(event.IsChecked());
1815}
1816
f31a4cb2
SC
1817#if wxUSE_GRAPHICS_CONTEXT
1818void MyFrame::OnGraphicContext(wxCommandEvent& event)
1819{
1820 m_canvas->UseGraphicContext(event.IsChecked());
1821}
1822#endif
1823
568708e2
VZ
1824void MyFrame::OnShow(wxCommandEvent& event)
1825{
f65e33a3 1826 m_canvas->ToShow(event.GetId());
568708e2
VZ
1827}
1828
1829void MyFrame::OnOption(wxCommandEvent& event)
aba99005 1830{
3ca6a5f0 1831 switch (event.GetId())
aba99005
RR
1832 {
1833 case MapMode_Text:
b9857632 1834 m_mapMode = wxMM_TEXT;
0f0c61d0 1835 break;
aba99005
RR
1836 case MapMode_Lometric:
1837 m_mapMode = wxMM_LOMETRIC;
0f0c61d0
VZ
1838 break;
1839 case MapMode_Twips:
aba99005 1840 m_mapMode = wxMM_TWIPS;
0f0c61d0
VZ
1841 break;
1842 case MapMode_Points:
aba99005 1843 m_mapMode = wxMM_POINTS;
0f0c61d0
VZ
1844 break;
1845 case MapMode_Metric:
aba99005 1846 m_mapMode = wxMM_METRIC;
0f0c61d0
VZ
1847 break;
1848
1849 case LogicalOrigin_MoveDown:
1850 m_yLogicalOrigin += 10;
1851 break;
1852 case LogicalOrigin_MoveUp:
1853 m_yLogicalOrigin -= 10;
1854 break;
1855 case LogicalOrigin_MoveLeft:
1856 m_xLogicalOrigin += 10;
1857 break;
1858 case LogicalOrigin_MoveRight:
1859 m_xLogicalOrigin -= 10;
1860 break;
fb576291
VZ
1861 case LogicalOrigin_Set:
1862 m_xLogicalOrigin =
1863 m_yLogicalOrigin = -100;
1864 break;
1865 case LogicalOrigin_Restore:
1866 m_xLogicalOrigin =
1867 m_yLogicalOrigin = 0;
1868 break;
0f0c61d0
VZ
1869
1870 case UserScale_StretchHoriz:
1871 m_xUserScale *= 1.10;
1872 break;
1873 case UserScale_ShrinkHoriz:
1874 m_xUserScale /= 1.10;
1875 break;
1876 case UserScale_StretchVertic:
1877 m_yUserScale *= 1.10;
1878 break;
1879 case UserScale_ShrinkVertic:
1880 m_yUserScale /= 1.10;
1881 break;
1882 case UserScale_Restore:
1883 m_xUserScale =
1884 m_yUserScale = 1.0;
1885 break;
1886
1887 case AxisMirror_Vertic:
1888 m_yAxisReversed = !m_yAxisReversed;
1889 break;
1890 case AxisMirror_Horiz:
1891 m_xAxisReversed = !m_xAxisReversed;
1892 break;
1893
960a83cc 1894#if wxUSE_COLOURDLG
0f0c61d0
VZ
1895 case Colour_TextForeground:
1896 m_colourForeground = SelectColour();
1897 break;
1898 case Colour_TextBackground:
1899 m_colourBackground = SelectColour();
1900 break;
1901 case Colour_Background:
1902 {
1903 wxColour col = SelectColour();
1904 if ( col.Ok() )
1905 {
1906 m_backgroundBrush.SetColour(col);
1907 }
1908 }
1909 break;
960a83cc
WS
1910#endif // wxUSE_COLOURDLG
1911
0f0c61d0
VZ
1912 case Colour_BackgroundMode:
1913 m_backgroundMode = m_backgroundMode == wxSOLID ? wxTRANSPARENT
1914 : wxSOLID;
1915 break;
1916
1edc9f45
RD
1917 case Colour_TextureBackgound:
1918 m_textureBackground = ! m_textureBackground;
1919 break;
1920
0f0c61d0
VZ
1921 default:
1922 // skip Refresh()
1923 return;
aba99005 1924 }
0f0c61d0 1925
1e7fd311 1926 m_canvas->Refresh();
aba99005
RR
1927}
1928
220af862 1929void MyFrame::PrepareDC(wxDC& dc)
aba99005 1930{
0f0c61d0 1931 dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin );
428db2ea 1932 dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed );
fb576291
VZ
1933 dc.SetUserScale( m_xUserScale, m_yUserScale );
1934 dc.SetMapMode( m_mapMode );
220af862
VZ
1935}
1936
960a83cc 1937#if wxUSE_COLOURDLG
220af862 1938wxColour MyFrame::SelectColour()
0f0c61d0
VZ
1939{
1940 wxColour col;
1941 wxColourData data;
1942 wxColourDialog dialog(this, &data);
1943
1944 if ( dialog.ShowModal() == wxID_OK )
1945 {
428db2ea 1946 col = dialog.GetColourData().GetColour();
0f0c61d0
VZ
1947 }
1948
1949 return col;
aba99005 1950}
960a83cc 1951#endif // wxUSE_COLOURDLG