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