]> git.saurik.com Git - wxWidgets.git/blame - samples/drawing/drawing.cpp
Mention wxDataViewTreeCtrl in wxDataViewCtrl docs
[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"
0f0c61d0 37
3abcf424 38#define wxTEST_GRAPHICS 1
f31a4cb2
SC
39
40#if wxTEST_GRAPHICS
41#include "wx/graphics.h"
42#if wxUSE_GRAPHICS_CONTEXT == 0
12534a36
SC
43#undef wxTEST_GRAPHICS
44#define wxTEST_GRAPHICS 0
f31a4cb2
SC
45#endif
46#else
47#undef wxUSE_GRAPHICS_CONTEXT
48#define wxUSE_GRAPHICS_CONTEXT 0
49#endif
50
aba99005
RR
51// ----------------------------------------------------------------------------
52// ressources
53// ----------------------------------------------------------------------------
568708e2 54
aba99005 55// the application icon
a11672a4 56#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__)
aba99005
RR
57 #include "mondrian.xpm"
58#endif
59
568708e2
VZ
60// ----------------------------------------------------------------------------
61// constants
62// ----------------------------------------------------------------------------
63
64// what do we show on screen (there are too many shapes to put them all on
65// screen simultaneously)
66enum ScreenToShow
67{
68 Show_Default,
69 Show_Text,
70 Show_Lines,
6386110d 71 Show_Brushes,
568708e2 72 Show_Polygons,
81278df2 73 Show_Mask,
e3b81044 74 Show_Mask_Stretch,
bc3cedfa 75 Show_Ops,
f6bcfd97 76 Show_Regions,
b11729f1 77 Show_Circles,
213ad8e7 78 Show_Splines,
f31a4cb2
SC
79#if wxUSE_GRAPHICS_CONTEXT
80 Show_Alpha,
7a5c82b1 81 Show_Graphics,
f31a4cb2 82#endif
213ad8e7
VZ
83 Show_Gradient,
84 Show_Max
568708e2
VZ
85};
86
87// ----------------------------------------------------------------------------
88// global variables
89// ----------------------------------------------------------------------------
90
f6bcfd97
BP
91static wxBitmap *gs_bmpNoMask = NULL,
92 *gs_bmpWithColMask = NULL,
93 *gs_bmpMask = NULL,
94 *gs_bmpWithMask = NULL,
95 *gs_bmp4 = NULL,
96 *gs_bmp4_mono = NULL,
97 *gs_bmp36 = NULL;
568708e2 98
aba99005
RR
99// ----------------------------------------------------------------------------
100// private classes
101// ----------------------------------------------------------------------------
102
103// Define a new application type, each program should derive a class from wxApp
104class MyApp : public wxApp
105{
106public:
107 // override base class virtuals
108 // ----------------------------
109
110 // this one is called on application startup and is a good place for the app
111 // initialization (doing it here and not in the ctor allows to have an error
112 // return: if OnInit() returns false, the application terminates)
113 virtual bool OnInit();
568708e2 114
f6bcfd97
BP
115 virtual int OnExit() { DeleteBitmaps(); return 0; }
116
568708e2 117protected:
f6bcfd97
BP
118 void DeleteBitmaps();
119
568708e2 120 bool LoadImages();
aba99005
RR
121};
122
b62c3631
RR
123class MyCanvas;
124
aba99005
RR
125// Define a new frame type: this is going to be our main frame
126class MyFrame : public wxFrame
127{
128public:
129 // ctor(s)
130 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
131
132 // event handlers (these functions should _not_ be virtual)
133 void OnQuit(wxCommandEvent& event);
134 void OnAbout(wxCommandEvent& event);
204dd9a7 135 void OnClip(wxCommandEvent& event);
f31a4cb2
SC
136#if wxUSE_GRAPHICS_CONTEXT
137 void OnGraphicContext(wxCommandEvent& event);
138#endif
568708e2 139 void OnShow(wxCommandEvent &event);
aba99005 140 void OnOption(wxCommandEvent &event);
aba99005 141
960a83cc 142#if wxUSE_COLOURDLG
220af862 143 wxColour SelectColour();
960a83cc 144#endif // wxUSE_COLOURDLG
220af862 145 void PrepareDC(wxDC& dc);
0f0c61d0 146
b62c3631 147 int m_backgroundMode;
1edc9f45 148 int m_textureBackground;
b62c3631
RR
149 int m_mapMode;
150 double m_xUserScale;
151 double m_yUserScale;
152 int m_xLogicalOrigin;
153 int m_yLogicalOrigin;
154 bool m_xAxisReversed,
155 m_yAxisReversed;
156 wxColour m_colourForeground, // these are _text_ colours
157 m_colourBackground;
158 wxBrush m_backgroundBrush;
159 MyCanvas *m_canvas;
aba99005
RR
160
161private:
be5a51fb 162 // any class wishing to process wxWidgets events must use this macro
aba99005
RR
163 DECLARE_EVENT_TABLE()
164};
165
b62c3631
RR
166// define a scrollable canvas for drawing onto
167class MyCanvas: public wxScrolledWindow
168{
169public:
170 MyCanvas( MyFrame *parent );
1e7fd311 171
b62c3631 172 void OnPaint(wxPaintEvent &event);
bf0c00c6 173 void OnMouseMove(wxMouseEvent &event);
4786aabd 174
dacaa6f1 175 void ToShow(ScreenToShow show) { m_show = show; Refresh(); }
568708e2 176
204dd9a7
VZ
177 // set or remove the clipping region
178 void Clip(bool clip) { m_clip = clip; Refresh(); }
f31a4cb2
SC
179#if wxUSE_GRAPHICS_CONTEXT
180 void UseGraphicContext(bool use) { m_useContext = use; Refresh(); }
181#endif
204dd9a7 182
b62c3631 183protected:
e3b81044
VZ
184 enum DrawMode
185 {
186 Draw_Normal,
187 Draw_Stretch
188 };
189
568708e2 190 void DrawTestLines( int x, int y, int width, wxDC &dc );
6386110d
VZ
191 void DrawTestPoly(wxDC& dc);
192 void DrawTestBrushes(wxDC& dc);
568708e2 193 void DrawText(wxDC& dc);
e3b81044 194 void DrawImages(wxDC& dc, DrawMode mode);
81278df2 195 void DrawWithLogicalOps(wxDC& dc);
f31a4cb2
SC
196#if wxUSE_GRAPHICS_CONTEXT
197 void DrawAlpha(wxDC& dc);
7a5c82b1 198 void DrawGraphics(wxGraphicsContext* gc);
f31a4cb2 199#endif
bc3cedfa 200 void DrawRegions(wxDC& dc);
f6bcfd97 201 void DrawCircles(wxDC& dc);
b11729f1 202 void DrawSplines(wxDC& dc);
568708e2 203 void DrawDefault(wxDC& dc);
213ad8e7 204 void DrawGradients(wxDC& dc);
4786aabd 205
4cbcae16 206 void DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime);
8e0e4b1b 207
b62c3631 208private:
568708e2
VZ
209 MyFrame *m_owner;
210
211 ScreenToShow m_show;
0e09f76e
RR
212 wxBitmap m_smile_bmp;
213 wxIcon m_std_icon;
204dd9a7 214 bool m_clip;
f31a4cb2
SC
215#if wxUSE_GRAPHICS_CONTEXT
216 bool m_useContext ;
217#endif
568708e2 218
b62c3631
RR
219 DECLARE_EVENT_TABLE()
220};
221
aba99005
RR
222// ----------------------------------------------------------------------------
223// constants
224// ----------------------------------------------------------------------------
225
226// IDs for the controls and the menu commands
227enum
228{
229 // menu items
b11729f1
WS
230 File_Quit = wxID_EXIT,
231 File_About = wxID_ABOUT,
568708e2 232
b11729f1 233 MenuShow_First = wxID_HIGHEST,
568708e2
VZ
234 File_ShowDefault = MenuShow_First,
235 File_ShowText,
236 File_ShowLines,
6386110d 237 File_ShowBrushes,
568708e2
VZ
238 File_ShowPolygons,
239 File_ShowMask,
e3b81044 240 File_ShowMaskStretch,
81278df2 241 File_ShowOps,
bc3cedfa 242 File_ShowRegions,
f6bcfd97 243 File_ShowCircles,
b11729f1 244 File_ShowSplines,
f31a4cb2
SC
245#if wxUSE_GRAPHICS_CONTEXT
246 File_ShowAlpha,
7a5c82b1 247 File_ShowGraphics,
f31a4cb2 248#endif
213ad8e7
VZ
249 File_ShowGradients,
250 MenuShow_Last = File_ShowGradients,
0f0c61d0 251
204dd9a7 252 File_Clip,
f31a4cb2
SC
253#if wxUSE_GRAPHICS_CONTEXT
254 File_GraphicContext,
255#endif
204dd9a7 256
0f0c61d0
VZ
257 MenuOption_First,
258
259 MapMode_Text = MenuOption_First,
aba99005
RR
260 MapMode_Lometric,
261 MapMode_Twips,
262 MapMode_Points,
263 MapMode_Metric,
0f0c61d0 264
aba99005
RR
265 UserScale_StretchHoriz,
266 UserScale_ShrinkHoriz,
267 UserScale_StretchVertic,
268 UserScale_ShrinkVertic,
0f0c61d0
VZ
269 UserScale_Restore,
270
aba99005
RR
271 AxisMirror_Horiz,
272 AxisMirror_Vertic,
0f0c61d0 273
aba99005
RR
274 LogicalOrigin_MoveDown,
275 LogicalOrigin_MoveUp,
276 LogicalOrigin_MoveLeft,
277 LogicalOrigin_MoveRight,
fb576291
VZ
278 LogicalOrigin_Set,
279 LogicalOrigin_Restore,
0f0c61d0 280
960a83cc 281#if wxUSE_COLOURDLG
0f0c61d0
VZ
282 Colour_TextForeground,
283 Colour_TextBackground,
284 Colour_Background,
960a83cc 285#endif // wxUSE_COLOURDLG
0f0c61d0 286 Colour_BackgroundMode,
1edc9f45 287 Colour_TextureBackgound,
0f0c61d0 288
1edc9f45 289 MenuOption_Last = Colour_TextureBackgound
aba99005
RR
290};
291
292// ----------------------------------------------------------------------------
be5a51fb 293// event tables and other macros for wxWidgets
aba99005
RR
294// ----------------------------------------------------------------------------
295
aba99005 296
be5a51fb 297// Create a new application object: this macro will allow wxWidgets to create
aba99005
RR
298// the application object during program execution (it's better than using a
299// static object for many reasons) and also declares the accessor function
300// wxGetApp() which will return the reference of the right type (i.e. MyApp and
301// not wxApp)
302IMPLEMENT_APP(MyApp)
303
304// ============================================================================
305// implementation
306// ============================================================================
307
308// ----------------------------------------------------------------------------
309// the application class
310// ----------------------------------------------------------------------------
311
568708e2
VZ
312bool MyApp::LoadImages()
313{
f6bcfd97
BP
314 gs_bmpNoMask = new wxBitmap;
315 gs_bmpWithColMask = new wxBitmap;
316 gs_bmpMask = new wxBitmap;
317 gs_bmpWithMask = new wxBitmap;
318 gs_bmp4 = new wxBitmap;
319 gs_bmp4_mono = new wxBitmap;
320 gs_bmp36 = new wxBitmap;
321
568708e2 322 wxPathList pathList;
ab1ca7b3
MB
323 pathList.Add(_T("."));
324 pathList.Add(_T(".."));
e3b81044 325 pathList.Add(_T("../.."));
568708e2 326
ab1ca7b3 327 wxString path = pathList.FindValidPath(_T("pat4.bmp"));
568708e2 328 if ( !path )
9da8feef 329 return false;
f6bcfd97 330
e1208c31 331 /* 4 colour bitmap */
f6bcfd97 332 gs_bmp4->LoadFile(path, wxBITMAP_TYPE_BMP);
e1208c31 333 /* turn into mono-bitmap */
f6bcfd97
BP
334 gs_bmp4_mono->LoadFile(path, wxBITMAP_TYPE_BMP);
335 wxMask* mask4 = new wxMask(*gs_bmp4_mono, *wxBLACK);
336 gs_bmp4_mono->SetMask(mask4);
568708e2 337
ab1ca7b3 338 path = pathList.FindValidPath(_T("pat36.bmp"));
568708e2 339 if ( !path )
9da8feef 340 return false;
f6bcfd97
BP
341 gs_bmp36->LoadFile(path, wxBITMAP_TYPE_BMP);
342 wxMask* mask36 = new wxMask(*gs_bmp36, *wxBLACK);
343 gs_bmp36->SetMask(mask36);
568708e2 344
ab1ca7b3 345 path = pathList.FindValidPath(_T("image.bmp"));
568708e2 346 if ( !path )
9da8feef 347 return false;
f6bcfd97
BP
348 gs_bmpNoMask->LoadFile(path, wxBITMAP_TYPE_BMP);
349 gs_bmpWithMask->LoadFile(path, wxBITMAP_TYPE_BMP);
350 gs_bmpWithColMask->LoadFile(path, wxBITMAP_TYPE_BMP);
568708e2 351
ab1ca7b3 352 path = pathList.FindValidPath(_T("mask.bmp"));
568708e2 353 if ( !path )
9da8feef 354 return false;
f6bcfd97 355 gs_bmpMask->LoadFile(path, wxBITMAP_TYPE_BMP);
b9de1315 356
f6bcfd97
BP
357 wxMask *mask = new wxMask(*gs_bmpMask, *wxBLACK);
358 gs_bmpWithMask->SetMask(mask);
568708e2 359
f6bcfd97
BP
360 mask = new wxMask(*gs_bmpWithColMask, *wxWHITE);
361 gs_bmpWithColMask->SetMask(mask);
568708e2 362
9da8feef 363 return true;
568708e2
VZ
364}
365
aba99005
RR
366// `Main program' equivalent: the program execution "starts" here
367bool MyApp::OnInit()
368{
45e6e6f8
VZ
369 if ( !wxApp::OnInit() )
370 return false;
371
aba99005 372 // Create the main application window
ab1ca7b3 373 MyFrame *frame = new MyFrame(_T("Drawing sample"),
b62c3631 374 wxPoint(50, 50), wxSize(550, 340));
aba99005
RR
375
376 // Show it and tell the application that it's our main window
9da8feef 377 frame->Show(true);
aba99005
RR
378 SetTopWindow(frame);
379
568708e2
VZ
380 if ( !LoadImages() )
381 {
4693b20c
MB
382 wxLogError(wxT("Can't load one of the bitmap files needed ")
383 wxT("for this sample from the current or parent ")
384 wxT("directory, please copy them there."));
568708e2
VZ
385
386 // stop here
f6bcfd97
BP
387 DeleteBitmaps();
388
9da8feef 389 return false;
568708e2
VZ
390 }
391
392 // ok, continue
9da8feef 393 return true;
aba99005
RR
394}
395
f6bcfd97
BP
396void MyApp::DeleteBitmaps()
397{
398 delete gs_bmpNoMask;
399 delete gs_bmpWithColMask;
400 delete gs_bmpMask;
401 delete gs_bmpWithMask;
402 delete gs_bmp4;
403 delete gs_bmp4_mono;
404 delete gs_bmp36;
17b898bb
VZ
405
406 gs_bmpNoMask = NULL;
407 gs_bmpWithColMask = NULL;
408 gs_bmpMask = NULL;
409 gs_bmpWithMask = NULL;
410 gs_bmp4 = NULL;
411 gs_bmp4_mono = NULL;
412 gs_bmp36 = NULL;
f6bcfd97
BP
413}
414
aba99005 415// ----------------------------------------------------------------------------
b62c3631 416// MyCanvas
aba99005
RR
417// ----------------------------------------------------------------------------
418
be5a51fb 419// the event tables connect the wxWidgets events with the functions (event
b62c3631
RR
420// handlers) which process them.
421BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
422 EVT_PAINT (MyCanvas::OnPaint)
bf0c00c6 423 EVT_MOTION (MyCanvas::OnMouseMove)
b62c3631
RR
424END_EVENT_TABLE()
425
c4218a74 426#include "smile.xpm"
0e09f76e 427
c4218a74 428MyCanvas::MyCanvas(MyFrame *parent)
9da8feef 429 : wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
c4218a74 430 wxHSCROLL | wxVSCROLL | wxNO_FULL_REPAINT_ON_RESIZE)
b62c3631 431{
b97fa7cf 432 m_owner = parent;
568708e2 433 m_show = Show_Default;
0e09f76e 434 m_smile_bmp = wxBitmap(smile_xpm);
389d906b 435 m_std_icon = wxArtProvider::GetIcon(wxART_INFORMATION);
9da8feef 436 m_clip = 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
4cbcae16 1354 dc.SetClippingRegion(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
568708e2
VZ
1369void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
1370{
f31a4cb2
SC
1371 wxPaintDC pdc(this);
1372
1373#if wxUSE_GRAPHICS_CONTEXT
1374 wxGCDC gdc( pdc ) ;
1375 wxDC &dc = m_useContext ? (wxDC&) gdc : (wxDC&) pdc ;
1376#else
1377 wxDC &dc = pdc ;
1378#endif
1379
568708e2 1380 PrepareDC(dc);
c4218a74 1381
568708e2
VZ
1382 m_owner->PrepareDC(dc);
1383
1384 dc.SetBackgroundMode( m_owner->m_backgroundMode );
1385 if ( m_owner->m_backgroundBrush.Ok() )
1386 dc.SetBackground( m_owner->m_backgroundBrush );
1387 if ( m_owner->m_colourForeground.Ok() )
1388 dc.SetTextForeground( m_owner->m_colourForeground );
1389 if ( m_owner->m_colourBackground.Ok() )
1390 dc.SetTextBackground( m_owner->m_colourBackground );
4786aabd 1391
1edc9f45 1392 if ( m_owner->m_textureBackground) {
047473c9 1393 if ( ! m_owner->m_backgroundBrush.Ok() ) {
925e9792
WS
1394 wxColour clr(0,128,0);
1395 wxBrush b(clr, wxSOLID);
1edc9f45
RD
1396 dc.SetBackground(b);
1397 }
047473c9
RD
1398 }
1399
204dd9a7
VZ
1400 if ( m_clip )
1401 dc.SetClippingRegion(100, 100, 100, 100);
1402
e1208c31 1403 dc.Clear();
1edc9f45 1404
204dd9a7
VZ
1405 if ( m_owner->m_textureBackground )
1406 {
1edc9f45 1407 dc.SetPen(*wxMEDIUM_GREY_PEN);
204dd9a7 1408 for ( int i = 0; i < 200; i++ )
1edc9f45
RD
1409 dc.DrawLine(0, i*10, i*10, 0);
1410 }
1411
568708e2
VZ
1412 switch ( m_show )
1413 {
1414 case Show_Default:
1415 DrawDefault(dc);
1416 break;
1e7fd311 1417
f6bcfd97
BP
1418 case Show_Circles:
1419 DrawCircles(dc);
1420 break;
1421
b11729f1
WS
1422 case Show_Splines:
1423 DrawSplines(dc);
1424 break;
1425
bc3cedfa
RR
1426 case Show_Regions:
1427 DrawRegions(dc);
1428 break;
1429
568708e2
VZ
1430 case Show_Text:
1431 DrawText(dc);
1432 break;
1e7fd311 1433
568708e2
VZ
1434 case Show_Lines:
1435 DrawTestLines( 0, 100, 0, dc );
f6bcfd97
BP
1436 DrawTestLines( 0, 320, 1, dc );
1437 DrawTestLines( 0, 540, 2, dc );
1438 DrawTestLines( 0, 760, 6, dc );
568708e2 1439 break;
1e7fd311 1440
6386110d
VZ
1441 case Show_Brushes:
1442 DrawTestBrushes(dc);
1443 break;
1444
568708e2 1445 case Show_Polygons:
6386110d 1446 DrawTestPoly(dc);
568708e2 1447 break;
1e7fd311 1448
568708e2 1449 case Show_Mask:
e3b81044
VZ
1450 DrawImages(dc, Draw_Normal);
1451 break;
1452
1453 case Show_Mask_Stretch:
1454 DrawImages(dc, Draw_Stretch);
568708e2 1455 break;
81278df2
VZ
1456
1457 case Show_Ops:
1458 DrawWithLogicalOps(dc);
1459 break;
e3b81044 1460
f31a4cb2
SC
1461#if wxUSE_GRAPHICS_CONTEXT
1462 case Show_Alpha:
1463 DrawAlpha(dc);
1464 break;
7a5c82b1
SC
1465 case Show_Graphics:
1466 DrawGraphics(gdc.GetGraphicsContext());
1467 break;
f31a4cb2 1468#endif
213ad8e7
VZ
1469
1470 case Show_Gradient:
1471 DrawGradients(dc);
1472 break;
e95c145c
WS
1473
1474 default:
1475 break;
568708e2 1476 }
b62c3631
RR
1477}
1478
bf0c00c6
RR
1479void MyCanvas::OnMouseMove(wxMouseEvent &event)
1480{
960a83cc 1481#if wxUSE_STATUSBAR
bf0c00c6
RR
1482 wxClientDC dc(this);
1483 PrepareDC(dc);
1484 m_owner->PrepareDC(dc);
1485
1486 wxPoint pos = event.GetPosition();
1487 long x = dc.DeviceToLogicalX( pos.x );
1488 long y = dc.DeviceToLogicalY( pos.y );
1489 wxString str;
4693b20c 1490 str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y );
bf0c00c6 1491 m_owner->SetStatusText( str );
960a83cc
WS
1492#else
1493 wxUnusedVar(event);
1494#endif // wxUSE_STATUSBAR
bf0c00c6
RR
1495}
1496
b62c3631
RR
1497// ----------------------------------------------------------------------------
1498// MyFrame
1499// ----------------------------------------------------------------------------
1500
be5a51fb 1501// the event tables connect the wxWidgets events with the functions (event
b62c3631
RR
1502// handlers) which process them. It can be also done at run-time, but for the
1503// simple menu events like this the static method is much simpler.
1504BEGIN_EVENT_TABLE(MyFrame, wxFrame)
568708e2
VZ
1505 EVT_MENU (File_Quit, MyFrame::OnQuit)
1506 EVT_MENU (File_About, MyFrame::OnAbout)
204dd9a7 1507 EVT_MENU (File_Clip, MyFrame::OnClip)
f31a4cb2
SC
1508#if wxUSE_GRAPHICS_CONTEXT
1509 EVT_MENU (File_GraphicContext, MyFrame::OnGraphicContext)
1510#endif
568708e2
VZ
1511
1512 EVT_MENU_RANGE(MenuShow_First, MenuShow_Last, MyFrame::OnShow)
1513
b62c3631
RR
1514 EVT_MENU_RANGE(MenuOption_First, MenuOption_Last, MyFrame::OnOption)
1515END_EVENT_TABLE()
1516
aba99005
RR
1517// frame constructor
1518MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
9da8feef 1519 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size,
c4218a74 1520 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
aba99005
RR
1521{
1522 // set the frame icon
1523 SetIcon(wxICON(mondrian));
1524
1525 wxMenu *menuFile = new wxMenu;
ab1ca7b3
MB
1526 menuFile->Append(File_ShowDefault, _T("&Default screen\tF1"));
1527 menuFile->Append(File_ShowText, _T("&Text screen\tF2"));
1528 menuFile->Append(File_ShowLines, _T("&Lines screen\tF3"));
1529 menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4"));
1530 menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5"));
1531 menuFile->Append(File_ShowMask, _T("&Mask screen\tF6"));
e3b81044 1532 menuFile->Append(File_ShowMaskStretch, _T("1/&2 scaled mask\tShift-F6"));
ab1ca7b3
MB
1533 menuFile->Append(File_ShowOps, _T("&ROP screen\tF7"));
1534 menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8"));
1535 menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9"));
f31a4cb2
SC
1536#if wxUSE_GRAPHICS_CONTEXT
1537 menuFile->Append(File_ShowAlpha, _T("&Alpha screen\tF10"));
1538#endif
213ad8e7
VZ
1539 menuFile->Append(File_ShowSplines, _T("&Splines screen\tF11"));
1540 menuFile->Append(File_ShowGradients, _T("&Gradients screen\tF12"));
7a5c82b1
SC
1541#if wxUSE_GRAPHICS_CONTEXT
1542 menuFile->Append(File_ShowGraphics, _T("&Graphics screen\tF13"));
1543#endif
568708e2 1544 menuFile->AppendSeparator();
ab1ca7b3 1545 menuFile->AppendCheckItem(File_Clip, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
f31a4cb2
SC
1546#if wxUSE_GRAPHICS_CONTEXT
1547 menuFile->AppendCheckItem(File_GraphicContext, _T("&Use GraphicContext\tCtrl-Y"), _T("Use GraphicContext"));
1548#endif
204dd9a7 1549 menuFile->AppendSeparator();
ab1ca7b3 1550 menuFile->Append(File_About, _T("&About...\tCtrl-A"), _T("Show about dialog"));
aba99005 1551 menuFile->AppendSeparator();
ab1ca7b3 1552 menuFile->Append(File_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
0f0c61d0 1553
aba99005 1554 wxMenu *menuMapMode = new wxMenu;
ab1ca7b3
MB
1555 menuMapMode->Append( MapMode_Text, _T("&TEXT map mode") );
1556 menuMapMode->Append( MapMode_Lometric, _T("&LOMETRIC map mode") );
1557 menuMapMode->Append( MapMode_Twips, _T("T&WIPS map mode") );
1558 menuMapMode->Append( MapMode_Points, _T("&POINTS map mode") );
1559 menuMapMode->Append( MapMode_Metric, _T("&METRIC map mode") );
0f0c61d0 1560
aba99005 1561 wxMenu *menuUserScale = new wxMenu;
ab1ca7b3
MB
1562 menuUserScale->Append( UserScale_StretchHoriz, _T("Stretch &horizontally\tCtrl-H") );
1563 menuUserScale->Append( UserScale_ShrinkHoriz, _T("Shrin&k horizontally\tCtrl-G") );
1564 menuUserScale->Append( UserScale_StretchVertic, _T("Stretch &vertically\tCtrl-V") );
1565 menuUserScale->Append( UserScale_ShrinkVertic, _T("&Shrink vertically\tCtrl-W") );
0f0c61d0 1566 menuUserScale->AppendSeparator();
ab1ca7b3 1567 menuUserScale->Append( UserScale_Restore, _T("&Restore to normal\tCtrl-0") );
0f0c61d0 1568
aba99005 1569 wxMenu *menuAxis = new wxMenu;
2153bf89
DS
1570 menuAxis->AppendCheckItem( AxisMirror_Horiz, _T("Mirror horizontally\tCtrl-M") );
1571 menuAxis->AppendCheckItem( AxisMirror_Vertic, _T("Mirror vertically\tCtrl-N") );
0f0c61d0 1572
aba99005 1573 wxMenu *menuLogical = new wxMenu;
ab1ca7b3
MB
1574 menuLogical->Append( LogicalOrigin_MoveDown, _T("Move &down\tCtrl-D") );
1575 menuLogical->Append( LogicalOrigin_MoveUp, _T("Move &up\tCtrl-U") );
1576 menuLogical->Append( LogicalOrigin_MoveLeft, _T("Move &right\tCtrl-L") );
1577 menuLogical->Append( LogicalOrigin_MoveRight, _T("Move &left\tCtrl-R") );
fb576291 1578 menuLogical->AppendSeparator();
ab1ca7b3
MB
1579 menuLogical->Append( LogicalOrigin_Set, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1580 menuLogical->Append( LogicalOrigin_Restore, _T("&Restore to normal\tShift-Ctrl-0") );
aba99005 1581
0f0c61d0 1582 wxMenu *menuColour = new wxMenu;
960a83cc 1583#if wxUSE_COLOURDLG
ab1ca7b3
MB
1584 menuColour->Append( Colour_TextForeground, _T("Text &foreground...") );
1585 menuColour->Append( Colour_TextBackground, _T("Text &background...") );
1586 menuColour->Append( Colour_Background, _T("Background &colour...") );
960a83cc 1587#endif // wxUSE_COLOURDLG
2153bf89
DS
1588 menuColour->AppendCheckItem( Colour_BackgroundMode, _T("&Opaque/transparent\tCtrl-B") );
1589 menuColour->AppendCheckItem( Colour_TextureBackgound, _T("Draw textured back&ground\tCtrl-T") );
0f0c61d0 1590
aba99005
RR
1591 // now append the freshly created menu to the menu bar...
1592 wxMenuBar *menuBar = new wxMenuBar;
ab1ca7b3
MB
1593 menuBar->Append(menuFile, _T("&File"));
1594 menuBar->Append(menuMapMode, _T("&Mode"));
1595 menuBar->Append(menuUserScale, _T("&Scale"));
1596 menuBar->Append(menuAxis, _T("&Axis"));
1597 menuBar->Append(menuLogical, _T("&Origin"));
1598 menuBar->Append(menuColour, _T("&Colours"));
aba99005
RR
1599
1600 // ... and attach this menu bar to the frame
1601 SetMenuBar(menuBar);
1602
960a83cc 1603#if wxUSE_STATUSBAR
aba99005 1604 CreateStatusBar(2);
be5a51fb 1605 SetStatusText(_T("Welcome to wxWidgets!"));
960a83cc 1606#endif // wxUSE_STATUSBAR
0f0c61d0 1607
aba99005
RR
1608 m_mapMode = wxMM_TEXT;
1609 m_xUserScale = 1.0;
1610 m_yUserScale = 1.0;
1611 m_xLogicalOrigin = 0;
1612 m_yLogicalOrigin = 0;
0f0c61d0 1613 m_xAxisReversed =
9da8feef 1614 m_yAxisReversed = false;
0f0c61d0 1615 m_backgroundMode = wxSOLID;
b97fa7cf
VZ
1616 m_colourForeground = *wxRED;
1617 m_colourBackground = *wxBLUE;
9da8feef 1618 m_textureBackground = false;
aba99005 1619
b62c3631 1620 m_canvas = new MyCanvas( this );
b97fa7cf 1621 m_canvas->SetScrollbars( 10, 10, 100, 240 );
b62c3631 1622}
aba99005
RR
1623
1624// event handlers
1625
1626void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1627{
9da8feef
WS
1628 // true is to force the frame to close
1629 Close(true);
aba99005
RR
1630}
1631
1632void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1633{
1634 wxString msg;
c916e13b
RR
1635 msg.Printf( wxT("This is the about dialog of the drawing sample.\n")
1636 wxT("This sample tests various primitive drawing functions\n")
6386110d 1637 wxT("(without any attempts to prevent flicker).\n")
c916e13b 1638 wxT("Copyright (c) Robert Roebling 1999")
aba99005
RR
1639 );
1640
ab1ca7b3 1641 wxMessageBox(msg, _T("About Drawing"), wxOK | wxICON_INFORMATION, this);
aba99005
RR
1642}
1643
204dd9a7
VZ
1644void MyFrame::OnClip(wxCommandEvent& event)
1645{
1646 m_canvas->Clip(event.IsChecked());
1647}
1648
f31a4cb2
SC
1649#if wxUSE_GRAPHICS_CONTEXT
1650void MyFrame::OnGraphicContext(wxCommandEvent& event)
1651{
1652 m_canvas->UseGraphicContext(event.IsChecked());
1653}
1654#endif
1655
568708e2
VZ
1656void MyFrame::OnShow(wxCommandEvent& event)
1657{
dacaa6f1 1658 m_canvas->ToShow((ScreenToShow)(event.GetId() - MenuShow_First));
568708e2
VZ
1659}
1660
1661void MyFrame::OnOption(wxCommandEvent& event)
aba99005 1662{
3ca6a5f0 1663 switch (event.GetId())
aba99005
RR
1664 {
1665 case MapMode_Text:
b9857632 1666 m_mapMode = wxMM_TEXT;
0f0c61d0 1667 break;
aba99005
RR
1668 case MapMode_Lometric:
1669 m_mapMode = wxMM_LOMETRIC;
0f0c61d0
VZ
1670 break;
1671 case MapMode_Twips:
aba99005 1672 m_mapMode = wxMM_TWIPS;
0f0c61d0
VZ
1673 break;
1674 case MapMode_Points:
aba99005 1675 m_mapMode = wxMM_POINTS;
0f0c61d0
VZ
1676 break;
1677 case MapMode_Metric:
aba99005 1678 m_mapMode = wxMM_METRIC;
0f0c61d0
VZ
1679 break;
1680
1681 case LogicalOrigin_MoveDown:
1682 m_yLogicalOrigin += 10;
1683 break;
1684 case LogicalOrigin_MoveUp:
1685 m_yLogicalOrigin -= 10;
1686 break;
1687 case LogicalOrigin_MoveLeft:
1688 m_xLogicalOrigin += 10;
1689 break;
1690 case LogicalOrigin_MoveRight:
1691 m_xLogicalOrigin -= 10;
1692 break;
fb576291
VZ
1693 case LogicalOrigin_Set:
1694 m_xLogicalOrigin =
1695 m_yLogicalOrigin = -100;
1696 break;
1697 case LogicalOrigin_Restore:
1698 m_xLogicalOrigin =
1699 m_yLogicalOrigin = 0;
1700 break;
0f0c61d0
VZ
1701
1702 case UserScale_StretchHoriz:
1703 m_xUserScale *= 1.10;
1704 break;
1705 case UserScale_ShrinkHoriz:
1706 m_xUserScale /= 1.10;
1707 break;
1708 case UserScale_StretchVertic:
1709 m_yUserScale *= 1.10;
1710 break;
1711 case UserScale_ShrinkVertic:
1712 m_yUserScale /= 1.10;
1713 break;
1714 case UserScale_Restore:
1715 m_xUserScale =
1716 m_yUserScale = 1.0;
1717 break;
1718
1719 case AxisMirror_Vertic:
1720 m_yAxisReversed = !m_yAxisReversed;
1721 break;
1722 case AxisMirror_Horiz:
1723 m_xAxisReversed = !m_xAxisReversed;
1724 break;
1725
960a83cc 1726#if wxUSE_COLOURDLG
0f0c61d0
VZ
1727 case Colour_TextForeground:
1728 m_colourForeground = SelectColour();
1729 break;
1730 case Colour_TextBackground:
1731 m_colourBackground = SelectColour();
1732 break;
1733 case Colour_Background:
1734 {
1735 wxColour col = SelectColour();
1736 if ( col.Ok() )
1737 {
1738 m_backgroundBrush.SetColour(col);
1739 }
1740 }
1741 break;
960a83cc
WS
1742#endif // wxUSE_COLOURDLG
1743
0f0c61d0
VZ
1744 case Colour_BackgroundMode:
1745 m_backgroundMode = m_backgroundMode == wxSOLID ? wxTRANSPARENT
1746 : wxSOLID;
1747 break;
1748
1edc9f45
RD
1749 case Colour_TextureBackgound:
1750 m_textureBackground = ! m_textureBackground;
1751 break;
1752
0f0c61d0
VZ
1753 default:
1754 // skip Refresh()
1755 return;
aba99005 1756 }
0f0c61d0 1757
1e7fd311 1758 m_canvas->Refresh();
aba99005
RR
1759}
1760
220af862 1761void MyFrame::PrepareDC(wxDC& dc)
aba99005 1762{
0f0c61d0 1763 dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin );
428db2ea 1764 dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed );
fb576291
VZ
1765 dc.SetUserScale( m_xUserScale, m_yUserScale );
1766 dc.SetMapMode( m_mapMode );
220af862
VZ
1767}
1768
960a83cc 1769#if wxUSE_COLOURDLG
220af862 1770wxColour MyFrame::SelectColour()
0f0c61d0
VZ
1771{
1772 wxColour col;
1773 wxColourData data;
1774 wxColourDialog dialog(this, &data);
1775
1776 if ( dialog.ShowModal() == wxID_OK )
1777 {
428db2ea 1778 col = dialog.GetColourData().GetColour();
0f0c61d0
VZ
1779 }
1780
1781 return col;
aba99005 1782}
960a83cc 1783#endif // wxUSE_COLOURDLG