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