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