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