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