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