wxSVGDC class test sample
[wxWidgets.git] / samples / svg / svgtest.cpp
1 // biol75@york.ac.uk (Chris Elliott) March 2000
2
3 #ifdef __BIDE__
4 #define _NO_VCL
5 #include "condefs.h"
6 USERC("svg.rc");
7 //---------------------------------------------------------------------------
8 #define WinMain WinMain
9 #endif
10 /////////////////////////////////////////////////////////////////////////////
11 // Name: svgtest.cpp
12 // Purpose: SVG sample
13 // Author: Chris Elliott
14 // Modified by:
15 // RCS-ID: $Id$
16 // Licence: wxWindows license
17 /////////////////////////////////////////////////////////////////////////////
18
19 // ===========================================================================
20 // declarations
21 // ===========================================================================
22
23 // ---------------------------------------------------------------------------
24 // headers
25 // ---------------------------------------------------------------------------
26
27 // For compilers that support precompilation, includes "wx/wx.h".
28 #include "wx/wxprec.h"
29
30 #ifdef __BORLANDC__
31 #pragma hdrstop
32 #endif
33
34 #ifndef WX_PRECOMP
35 #include "wx/wx.h"
36 #include "wx/mdi.h"
37 #endif
38
39 #include <wx/toolbar.h>
40 #include <wx/svg/dcsvg.h>
41
42 #include "bitmaps/new.xpm"
43 #include "bitmaps/save.xpm"
44 #include "bitmaps/help.xpm"
45 #include "SVGlogo24.xpm"
46
47 class MyChild;
48
49 // Define a new application
50 class MyApp : public wxApp
51 {
52 public:
53 bool OnInit();
54 };
55
56 // Define a new frame
57 class MyFrame : public wxMDIParentFrame
58 {
59 public:
60 int nWinCreated;
61
62 wxList m_children;
63
64 MyFrame(wxWindow *parent, const wxWindowID id, const wxString& title,
65 const wxPoint& pos, const wxSize& size, const long style);
66
67 void InitToolBar(wxToolBar* toolBar);
68
69 void OnSize(wxSizeEvent& event);
70 void OnAbout(wxCommandEvent& event);
71 void OnNewWindow(wxCommandEvent& event);
72 void OnQuit(wxCommandEvent& event);
73 void OnClose(wxCloseEvent& event);
74 void FileSavePicture (wxCommandEvent & WXUNUSED(event) ) ;
75
76 DECLARE_EVENT_TABLE()
77 };
78
79
80 class MyCanvas : public wxScrolledWindow
81 {
82 public:
83 int m_index ;
84
85 MyChild * m_child ;
86 MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size);
87 virtual void OnDraw(wxDC& dc);
88
89 DECLARE_EVENT_TABLE()
90 };
91
92 class MyChild: public wxMDIChildFrame
93 {
94 public:
95 MyCanvas *m_canvas;
96 MyFrame *m_frame ;
97
98 //////////////////// Methods
99
100 MyChild(wxMDIParentFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
101 ~MyChild();
102
103 void OnActivate(wxActivateEvent& event);
104 void OnQuit(wxCommandEvent& event);
105 void OnClose(wxCloseEvent& event);
106 bool OnSave(wxString filename) ;
107
108 DECLARE_EVENT_TABLE()
109 };
110
111 // menu items ids
112 enum
113 {
114 MDI_QUIT = 100,
115 MDI_NEW_WINDOW,
116 MDI_SAVE,
117 MDI_REFRESH,
118 MDI_CHILD_QUIT,
119 MDI_ABOUT
120 };
121
122
123 IMPLEMENT_APP(MyApp)
124
125 // ---------------------------------------------------------------------------
126 // global variables
127 // ---------------------------------------------------------------------------
128
129 MyFrame *frame = (MyFrame *) NULL;
130
131 // ---------------------------------------------------------------------------
132 // event tables
133 // ---------------------------------------------------------------------------
134
135 BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
136 EVT_MENU(MDI_ABOUT, MyFrame::OnAbout)
137 EVT_MENU(MDI_NEW_WINDOW, MyFrame::OnNewWindow)
138 EVT_MENU(MDI_QUIT, MyFrame::OnQuit)
139 EVT_MENU (MDI_SAVE, MyFrame::FileSavePicture)
140 EVT_CLOSE(MyFrame::OnClose)
141
142 EVT_SIZE(MyFrame::OnSize)
143 END_EVENT_TABLE()
144
145 // ===========================================================================
146 // implementation
147 // ===========================================================================
148
149 // ---------------------------------------------------------------------------
150 // MyApp
151 // ---------------------------------------------------------------------------
152
153 // Initialise this in OnInit, not statically
154 bool MyApp::OnInit()
155 {
156 // Create the main frame window
157
158 frame = new MyFrame((wxFrame *)NULL, -1, wxT("SVG Demo"),
159 wxPoint(-1, -1), wxSize(500, 400),
160 wxDEFAULT_FRAME_STYLE | wxHSCROLL | wxVSCROLL);
161
162
163 // Make a menubar
164 wxMenu *file_menu = new wxMenu;
165
166 file_menu->Append(MDI_NEW_WINDOW, wxT("&New test\tCtrl+N"));
167 file_menu->Append(MDI_QUIT, wxT("&Exit\tAlt+X"));
168
169 wxMenu *help_menu = new wxMenu;
170 help_menu->Append(MDI_ABOUT, wxT("&About"));
171
172 wxMenuBar *menu_bar = new wxMenuBar;
173
174 menu_bar->Append(file_menu, wxT("&File"));
175 menu_bar->Append(help_menu, wxT("&Help"));
176
177 // Associate the menu bar with the frame
178 frame->SetMenuBar(menu_bar);
179
180 frame->CreateStatusBar();
181
182 frame->Show(TRUE);
183
184 SetTopWindow(frame);
185
186 return TRUE;
187 }
188
189
190 // ---------------------------------------------------------------------------
191 // MyFrame
192 // ---------------------------------------------------------------------------
193
194 // Define my frame constructor
195 MyFrame::MyFrame(wxWindow *parent, const wxWindowID id, const wxString& title,
196 const wxPoint& pos, const wxSize& size, const long style)
197 : wxMDIParentFrame(parent, id, title, pos, size, style)
198 {
199 nWinCreated = 0 ;
200
201 // Give it an icon
202 SetIcon(wxICON(mondrian));
203
204 CreateToolBar(wxNO_BORDER | wxTB_FLAT | wxTB_HORIZONTAL);
205 InitToolBar(GetToolBar());
206
207 }
208
209
210 void MyFrame::OnClose(wxCloseEvent& event)
211 {
212 if ( !event.CanVeto() )
213 {
214 event.Skip();
215 return ;
216 }
217 if ( m_children.Number () < 1 )
218 {
219 event.Skip();
220 return ;
221 }
222 // now try the children
223 wxNode * pNode = m_children.GetFirst ();
224 wxNode * pNext ;
225 MyChild * pChild ;
226 while ( pNode )
227 {
228 pNext = pNode -> GetNext ();
229 pChild = (MyChild*) pNode -> Data ();
230 if (pChild -> Close ())
231 {
232 delete pNode ;
233 }
234 else
235 {
236 event.Veto();
237 return;
238 }
239 pNode = pNext ;
240 }
241 event.Skip();
242 }
243
244
245 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
246 {
247 Close();
248 }
249
250
251 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
252 {
253 (void)wxMessageBox(wxT("wxWindows 2.0 SVG 1.0 Test\n"
254 "Author: Chris Elliott (c) 2002\n"
255 "Usage: svg.exe \nClick File | New to show tests\n\n"), wxT("About SVG Test"));
256 }
257
258
259 void MyFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event) )
260 {
261 // Make another frame, containing a canvas
262 MyChild *subframe ;
263
264 m_children.Append (new MyChild(frame, wxT("SVG Frame"),
265 wxPoint(-1, -1), wxSize(-1, -1),
266 wxDEFAULT_FRAME_STYLE ) ) ;
267
268 subframe = (MyChild *) m_children.GetLast() -> Data ();
269 wxString title;
270 title.Printf(wxT("SVG Test Window %d"), nWinCreated );
271 // counts number of children previously, even if now closed
272 nWinCreated ++ ;
273
274 // Give it a title and icon
275 subframe->SetTitle(title);
276 subframe->SetIcon(wxICON(mondrian));
277
278 // Make a menubar
279 wxMenu *file_menu = new wxMenu;
280
281 file_menu->Append(MDI_NEW_WINDOW, wxT("&Another test\tCtrl+N"));
282 file_menu->Append(MDI_SAVE, wxT("&Save\tCtrl+S"), wxT("Save in SVG format"));
283 file_menu->Append(MDI_CHILD_QUIT, wxT("&Close child\tCtrl+F4"));
284 file_menu->Append(MDI_QUIT, wxT("&Exit\tAlt+X"));
285
286 wxMenu *help_menu = new wxMenu;
287 help_menu->Append(MDI_ABOUT, wxT("&About"));
288
289 wxMenuBar *menu_bar = new wxMenuBar;
290
291 menu_bar->Append(file_menu, wxT("&File"));
292 menu_bar->Append(help_menu, wxT("&Help"));
293
294 // Associate the menu bar with the frame
295 subframe->SetMenuBar(menu_bar);
296
297 subframe->Show(TRUE);
298 }
299
300
301 void MyFrame::OnSize(wxSizeEvent& WXUNUSED(event))
302 {
303 int w, h;
304 GetClientSize(&w, &h);
305
306 GetClientWindow()->SetSize(0, 0, w, h);
307 }
308
309
310 void MyFrame::InitToolBar(wxToolBar* toolBar)
311 {
312 const int maxBitmaps = 3 ;
313 wxBitmap* bitmaps[maxBitmaps];
314
315 bitmaps[0] = new wxBitmap( new_xpm );
316 bitmaps[1] = new wxBitmap( save_xpm );
317 bitmaps[2] = new wxBitmap( help_xpm );
318
319 int width = 16;
320 int currentX = 5;
321
322 toolBar->AddTool( MDI_NEW_WINDOW, *(bitmaps[0]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, wxT("New SVG test window"));
323 currentX += width + 5;
324 toolBar->AddTool( MDI_SAVE, *bitmaps[1], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, wxT("Save test in SVG format"));
325 currentX += width + 5;
326 toolBar->AddSeparator();
327 toolBar->AddTool(MDI_ABOUT, *bitmaps[2], wxNullBitmap, TRUE, currentX, -1, (wxObject *) NULL, wxT("Help"));
328
329 toolBar->Realize();
330
331 int i;
332 for (i = 0; i < maxBitmaps; i++)
333 delete bitmaps[i];
334 }
335
336
337 void MyFrame::FileSavePicture (wxCommandEvent & WXUNUSED(event) )
338 {
339 MyChild * pChild = (MyChild *)GetActiveChild ();
340 if (pChild == NULL)
341 {
342 return ;
343 }
344
345 wxFileDialog dialog(this, wxT("Save Picture as"), wxEmptyString, pChild->GetTitle(),
346 wxT("SVG vector picture files (*.svg)|*.svg"),
347 wxSAVE|wxOVERWRITE_PROMPT);
348
349 if (dialog.ShowModal() == wxID_OK)
350 {
351 if (!pChild -> OnSave ( dialog.GetPath() ))
352 {
353 return ;
354 }
355 }
356 return ;
357 }
358
359
360 // Note that MDI_NEW_WINDOW and MDI_ABOUT commands get passed
361 // to the parent window for processing, so no need to
362 // duplicate event handlers here.
363 BEGIN_EVENT_TABLE(MyChild, wxMDIChildFrame)
364 EVT_MENU(MDI_CHILD_QUIT, MyChild::OnQuit)
365 EVT_CLOSE(MyChild::OnClose)
366 END_EVENT_TABLE()
367
368 BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
369
370 END_EVENT_TABLE()
371
372 // ---------------------------------------------------------------------------
373 // MyCanvas
374 // ---------------------------------------------------------------------------
375
376 // Define a constructor for my canvas
377 MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size)
378 : wxScrolledWindow(parent, -1, pos, size,
379 wxSUNKEN_BORDER|wxVSCROLL|wxHSCROLL)
380 {
381 m_child = (MyChild *) parent ;
382 SetBackgroundColour(wxColour("WHITE"));
383 m_index = m_child->m_frame->nWinCreated % 7 ;
384 }
385
386
387 // Define the repainting behaviour
388 void MyCanvas::OnDraw(wxDC& dc)
389 {
390 // vars to use ...
391 wxString s ;
392 wxPen wP ;
393 wxBrush wB ;
394 wxPoint points[6];
395 wxColour wC;
396 wxFont wF ;
397
398 dc.SetFont(*wxSWISS_FONT);
399 dc.SetPen(*wxGREEN_PEN);
400
401
402 switch (m_index)
403 {
404 default:
405 case 0:
406 // draw lines to make a cross
407 dc.DrawLine(0, 0, 200, 200);
408 dc.DrawLine(200, 0, 0, 200);
409 // draw point colored line and spline
410 wP = *wxCYAN_PEN ;
411 wP.SetWidth(3);
412 dc.SetPen(wP);
413
414 dc.DrawPoint (25,15) ;
415 dc.DrawLine(50, 30, 200, 30);
416 dc.DrawSpline(50, 200, 50, 100, 200, 10);
417 s = wxT("Green Cross, Cyan Line and spline");
418 break ;
419
420 case 1:
421 // draw standard shapes
422 dc.SetBrush(*wxCYAN_BRUSH);
423 dc.SetPen(*wxRED_PEN);
424 dc.DrawRectangle(10, 10, 100, 70);
425 wB = wxBrush ("DARK ORCHID", wxTRANSPARENT);
426 dc.SetBrush (wB);
427 dc.DrawRoundedRectangle(50, 50, 100, 70, 20);
428 dc.SetBrush (wxBrush("GOLDENROD", wxSOLID) );
429 dc.DrawEllipse(100, 100, 100, 50);
430
431 points[0].x = 100; points[0].y = 200;
432 points[1].x = 70; points[1].y = 260;
433 points[2].x = 160; points[2].y = 230;
434 points[3].x = 40; points[3].y = 230;
435 points[4].x = 130; points[4].y = 260;
436 points[5].x = 100; points[5].y = 200;
437
438 dc.DrawPolygon(5, points);
439 dc.DrawLines (6, points, 160);
440 s = wxT("Blue rectangle, red edge, clear rounded rectangle, gold ellipse, gold and clear stars");
441 break ;
442
443 case 2:
444 // draw text in Arial or similar font
445 dc.DrawLine(50,25,50,35);
446 dc.DrawLine(45,30,55,30);
447 dc.DrawText(wxT("This is a Swiss-style string"), 50, 30);
448 wC = dc.GetTextForeground() ;
449 dc.SetTextForeground ("FIREBRICK");
450
451 // no effect in msw ??
452 dc.SetTextBackground ("WHEAT");
453 dc.DrawText(wxT("This is a Red string"), 50, 200);
454 dc.DrawRotatedText(wxT("This is a 45 deg string"), 50, 200, 45);
455 dc.DrawRotatedText(wxT("This is a 90 deg string"), 50, 200, 90);
456 wF = wxFont ( 18, wxROMAN, wxITALIC, wxBOLD, FALSE, wxT("Times New Roman"));
457 dc.SetFont(wF);
458 dc.SetTextForeground (wC) ;
459 dc.DrawText(wxT("This is a Times-style string"), 50, 60);
460 s = wxT("Swiss, Times text; red text, rotated and colored orange");
461 break ;
462
463 case 3 :
464 // four arcs start and end points, center
465 dc.SetBrush(*wxGREEN_BRUSH);
466 dc.DrawArc ( 200,300, 370,230, 300.0,300.0 );
467 dc.SetBrush(*wxBLUE_BRUSH);
468 dc.DrawArc ( 270-50, 270-86, 270-86, 270-50, 270.0,270.0 );
469 dc.SetDeviceOrigin(-10,-10);
470 dc.DrawArc ( 270-50, 270-86, 270-86, 270-50, 270.0,270.0 );
471 dc.SetDeviceOrigin(0,0);
472
473 wP.SetColour ("CADET BLUE");
474 dc.SetPen(wP);
475 dc.DrawArc ( 75,125, 110, 40, 75.0, 75.0 );
476
477 wP.SetColour ("SALMON");
478 dc.SetPen(wP);
479 dc.SetBrush(*wxRED_BRUSH);
480 //top left corner, width and height, start and end angle
481 // 315 same center and x-radius as last pie-arc, half Y radius
482 dc.DrawEllipticArc(25,50,100,50,180.0,45.0) ;
483
484 wP = *wxCYAN_PEN ;
485 wP.SetWidth(3);
486 dc.SetPen(wP);
487 //wxTRANSPARENT));
488 dc.SetBrush (wxBrush ("SALMON",wxSOLID)) ;
489 dc.DrawEllipticArc(300, 0,200,100, 0.0,145.0) ;
490 //same end point
491 dc.DrawEllipticArc(300, 50,200,100,90.0,145.0) ;
492 dc.DrawEllipticArc(300,100,200,100,90.0,345.0) ;
493
494 s = wxT("This is an arc test page");
495 break ;
496
497 case 4:
498 dc.DrawCheckMark ( 30,30,25,25);
499 dc.SetBrush (wxBrush ("SALMON",wxTRANSPARENT));
500 dc.DrawCheckMark ( 80,50,75,75);
501 dc.DrawRectangle ( 80,50,75,75);
502 s = wxT("Two check marks");
503 break ;
504
505 case 5:
506 wF = wxFont ( 18, wxROMAN, wxITALIC, wxBOLD, FALSE, wxT("Times New Roman"));
507 dc.SetFont(wF);
508 dc.DrawLine(0, 0, 200, 200);
509 dc.DrawLine(200, 0, 0, 200);
510 dc.DrawText(wxT("This is an 18pt string"), 50, 60);
511
512 // rescale and draw in blue
513 wP = *wxCYAN_PEN ;
514 dc.SetPen(wP);
515 dc.SetUserScale (2.0,0.5);
516 dc.SetDeviceOrigin(200,0);
517 dc.DrawLine(0, 0, 200, 200);
518 dc.DrawLine(200, 0, 0, 200);
519 dc.DrawText(wxT("This is an 18pt string 2 x 0.5 UserScaled"), 50, 60);
520 dc.SetUserScale (2.0,2.0);
521 dc.SetDeviceOrigin(200,200);
522 dc.DrawText(wxT("This is an 18pt string 2 x 2 UserScaled"), 50, 60);
523
524 wP = *wxRED_PEN ;
525 dc.SetPen(wP);
526 dc.SetUserScale (1.0,1.0);
527 dc.SetDeviceOrigin(0,10);
528 dc.SetMapMode (wxMM_METRIC) ; //svg ignores this
529 dc.DrawLine(0, 0, 200, 200);
530 dc.DrawLine(200, 0, 0, 200);
531 dc.DrawText(wxT("This is an 18pt string in MapMode"), 50, 60);
532 s = wxT("Scaling test page");
533 break ;
534
535 case 6:
536 dc.DrawIcon( wxICON(mondrian), 10, 10 );
537 dc.DrawBitmap ( wxBITMAP (svgbitmap), 50,15);
538 s = wxT("Icon and Bitmap ");
539 break ;
540
541 }
542 m_child->SetStatusText(s);
543 }
544
545
546
547
548 // ---------------------------------------------------------------------------
549 // MyChild
550 // ---------------------------------------------------------------------------
551
552 MyChild::MyChild(wxMDIParentFrame *parent, const wxString& title,
553 const wxPoint& pos, const wxSize& size,
554 const long style)
555 : wxMDIChildFrame(parent, -1, title, pos, size, style)
556 {
557
558 m_frame = (MyFrame *) parent ;
559 CreateStatusBar();
560 SetStatusText(title);
561
562 int w, h ;
563 GetClientSize ( &w, &h );
564 m_canvas = new MyCanvas(this, wxPoint(0, 0), wxSize (w,h) );
565 // Give it scrollbars
566 m_canvas->SetScrollbars(20, 20, 50, 50);
567
568 }
569
570
571 MyChild::~MyChild()
572 {
573 m_frame->m_children.DeleteObject(this);
574 }
575
576
577 void MyChild::OnQuit(wxCommandEvent& WXUNUSED(event))
578 {
579 Close(TRUE);
580 }
581
582
583 bool MyChild::OnSave(wxString filename)
584 {
585 wxSVGFileDC svgDC (filename, 600, 650) ;
586 m_canvas->OnDraw (svgDC);
587 return svgDC.Ok();
588 }
589
590
591
592 void MyChild::OnActivate(wxActivateEvent& event)
593 {
594 if ( event.GetActive() && m_canvas )
595 m_canvas->SetFocus();
596 }
597
598
599 void MyChild::OnClose(wxCloseEvent& event)
600 {
601 event.Skip();
602 }