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