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