]> git.saurik.com Git - wxWidgets.git/blob - docs/doxygen/overviews/xrc.h
fixed anchor link naming, indentation in some places, added the <hr> divisor, fixed...
[wxWidgets.git] / docs / doxygen / overviews / xrc.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: xrc.h
3 // Purpose: topic overview
4 // Author: wxWidgets team
5 // RCS-ID: $Id$
6 // Licence: wxWindows license
7 /////////////////////////////////////////////////////////////////////////////
8
9 /*!
10
11 @page overview_xrc XML-based resource system overview
12
13 Classes: #wxXmlResource, #wxXmlResourceHandler
14
15 The XML-based resource system, known as XRC, allows user interface elements such
16 as dialogs, menu bars and toolbars, to be stored in text files and loaded into
17 the application at run-time. XRC files can also be compiled into binary XRS files
18 or C++ code (the former makes it possible to store all resources in a single file
19 and the latter is useful when you want to embed the resources into the executable).
20
21 There are several advantages to using XRC resources.
22
23 @li Recompiling and linking an application is not necessary if the
24 resources change.
25 @li If you use a dialog designer that generates C++ code, it can be hard
26 to reintegrate this into existing C++ code. Separation of resources and code
27 is a more elegant solution.
28 @li You can choose between different alternative resource files at run time,
29 if necessary.
30 @li The XRC format uses sizers for flexibility, allowing dialogs to be resizable
31 and highly portable.
32 @li The XRC format is a wxWidgets standard,
33 and can be generated or postprocessed by any program that understands it.
34 As it is basedon the XML standard, existing XML editors can be used for
35 simple editing purposes.
36
37 XRC was written by Vaclav Slavik.
38
39 @li @ref overview_xrc_concepts
40 @li @ref overview_xrc_binaryresourcefiles
41 @li @ref overview_xrc_embeddedresource
42 @li @ref overview_xrc_cppsample
43 @li @ref overview_xrc_sample
44 @li @ref overview_xrc_fileformat
45 @li @ref overview_xrc_cppheader
46 @li @ref overview_xrc_newresourcehandlers
47
48
49 <hr>
50
51
52 @section overview_xrc_concepts XRC concepts
53
54 These are the typical steps for using XRC files in your application.
55
56 @li Include the appropriate headers: normally "wx/xrc/xmlres.h" will suffice;
57 @li If you are going to use XRS files (see @ref overview_xrc_binaryresourcefiles), install
58 wxFileSystem archive handler first with @c wxFileSystem::AddHandler(new wxArchiveFSHandler);
59 @li call @c wxXmlResource::Get()->InitAllHandlers() from your wxApp::OnInit function,
60 and then call @c wxXmlResource::Get()->Load("myfile.xrc") to load the resource file;
61 @li to create a dialog from a resource, create it using the default constructor, and then
62 load it using for example @c wxXmlResource::Get()->LoadDialog(dlg, this, "dlg1");
63 @li set up event tables as usual but use the @c XRCID(str) macro to translate from XRC string names
64 to a suitable integer identifier, for example <tt>EVT_MENU(XRCID("quit"), MyFrame::OnQuit)</tt>.
65
66 To create an XRC file, you can use one of the following methods.
67
68 @li Create the file by hand;
69 @li use wxDesigner (http://www.roebling.de), a commercial dialog designer/RAD tool;
70 @li use DialogBlocks (http://www.anthemion.co.uk/dialogblocks), a commercial dialog editor;
71 @li use XRCed (http://xrced.sf.net), a wxPython-based dialog editor that you can find in the
72 @c wxPython/tools subdirectory of the wxWidgets SVN archive;
73 @li use wxGlade (http://wxglade.sf.net), a GUI designer written in wxPython.
74 At the moment it can generate Python, C++ and XRC;
75
76 A complete list of third-party tools that write to XRC can be found at
77 http://www.wxwidgets.org/wiki/index.php/Tools.
78
79 It is highly recommended that you use a resource editing tool, since it's fiddly
80 writing XRC files by hand.
81
82 You can use wxXmlResource::Load in a number of ways.
83 You can pass an XRC file (XML-based text resource file) or a zip-compressed file
84 (see @ref overview_xrc_binaryresourcefiles), with extension ZIP or XRS, containing
85 other XRC.
86
87 You can also use embedded C++ resources (see @ref overview_xrc_embeddedresource).
88
89
90 @section overview_xrc_binaryresourcefiles Using binary resource files
91
92 To compile binary resource files, use the command-line @c wxrc utility.
93 It takes one or more file parameters (the input XRC files) and the following
94 switches and options:
95
96 @li -h (--help): show a help message
97 @li -v (--verbose): show verbose logging information
98 @li -c (--cpp-code): write C++ source rather than a XRS file
99 @li -e (--extra-cpp-code): if used together with -c, generates C++ header file
100 containing class definitions for the windows defined by the XRC file
101 (see special subsection)
102 @li -u (--uncompressed): do not compress XML files (C++ only)
103 @li -g (--gettext): output underscore-wrapped strings that poEdit or gettext can scan.
104 Outputs to stdout, or a file if -o is used
105 @li -n (--function) name: specify C++ function name (use with -c)
106 @li -o (--output) filename: specify the output file, such as resource.xrs or resource.cpp
107 @li -l (--list-of-handlers) filename: output a list of necessary handlers to this file
108
109 For example:
110
111 @code
112 % wxrc resource.xrc
113 % wxrc resource.xrc -o resource.xrs
114 % wxrc resource.xrc -v -c -o resource.cpp
115 @endcode
116
117 @note
118 XRS file is essentially a renamed ZIP archive which means that you can manipulate
119 it with standard ZIP tools. Note that if you are using XRS files, you have
120 to initialize the #wxFileSystem archive handler first! It is a simple
121 thing to do:
122
123 @code
124 #include wx/filesys.h
125 #include wx/fs_arc.h
126 ...
127 wxFileSystem::AddHandler(new wxArchiveFSHandler);
128 @endcode
129
130
131 @section overview_xrc_embeddedresource Using embedded resources
132
133 It is sometimes useful to embed resources in the executable itself instead
134 of loading an external file (e.g. when your app is small and consists only of one
135 exe file). XRC provides means to convert resources into regular C++ file that
136 can be compiled and included in the executable.
137
138 Use the @c -c switch to
139 @c wxrc utility to produce C++ file with embedded resources. This file will
140 contain a function called @e InitXmlResource (unless you override this with
141 a command line switch). Use it to load the resource:
142
143 @code
144 extern void InitXmlResource(); // defined in generated file
145 ...
146 wxXmlResource::Get()-InitAllHandlers();
147 InitXmlResource();
148 ...
149 @endcode
150
151
152 @section overview_xrc_cppsample XRC C++ sample
153
154 This is the C++ source file (xrcdemo.cpp) for the XRC sample.
155
156 @code
157 #include "wx/wx.h"
158 #include "wx/image.h"
159 #include "wx/xrc/xmlres.h"
160
161 // the application icon
162 #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__)
163 #include "rc/appicon.xpm"
164 #endif
165
166 // ----------------------------------------------------------------------------
167 // private classes
168 // ----------------------------------------------------------------------------
169
170 // Define a new application type, each program should derive a class from wxApp
171 class MyApp : public wxApp
172 {
173 public:
174 // override base class virtuals
175 // ----------------------------
176
177 // this one is called on application startup and is a good place for the app
178 // initialization (doing it here and not in the ctor allows to have an error
179 // return: if OnInit() returns @false, the application terminates)
180 virtual bool OnInit();
181 };
182
183 // Define a new frame type: this is going to be our main frame
184 class MyFrame : public wxFrame
185 {
186 public:
187 // ctor(s)
188 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
189
190 // event handlers (these functions should _not_ be virtual)
191 void OnQuit(wxCommandEvent& event);
192 void OnAbout(wxCommandEvent& event);
193 void OnDlg1(wxCommandEvent& event);
194 void OnDlg2(wxCommandEvent& event);
195
196 private:
197 // any class wishing to process wxWidgets events must use this macro
198 DECLARE_EVENT_TABLE()
199 };
200
201 // ----------------------------------------------------------------------------
202 // event tables and other macros for wxWidgets
203 // ----------------------------------------------------------------------------
204
205 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
206 EVT_MENU(XRCID("menu_quit"), MyFrame::OnQuit)
207 EVT_MENU(XRCID("menu_about"), MyFrame::OnAbout)
208 EVT_MENU(XRCID("menu_dlg1"), MyFrame::OnDlg1)
209 EVT_MENU(XRCID("menu_dlg2"), MyFrame::OnDlg2)
210 END_EVENT_TABLE()
211
212 IMPLEMENT_APP(MyApp)
213
214 // ----------------------------------------------------------------------------
215 // the application class
216 // ----------------------------------------------------------------------------
217
218 // 'Main program' equivalent: the program execution "starts" here
219 bool MyApp::OnInit()
220 {
221 wxImage::AddHandler(new wxGIFHandler);
222 wxXmlResource::Get()->InitAllHandlers();
223 wxXmlResource::Get()->Load("rc/resource.xrc");
224
225 MyFrame *frame = new MyFrame("XML resources demo",
226 wxPoint(50, 50), wxSize(450, 340));
227 frame->Show(true);
228 return true;
229 }
230
231 // ----------------------------------------------------------------------------
232 // main frame
233 // ----------------------------------------------------------------------------
234
235 // frame constructor
236 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
237 : wxFrame((wxFrame *)NULL, -1, title, pos, size)
238 {
239 SetIcon(wxICON(appicon));
240
241 SetMenuBar(wxXmlResource::Get()->LoadMenuBar("mainmenu"));
242 SetToolBar(wxXmlResource::Get()->LoadToolBar(this, "toolbar"));
243 }
244
245 // event handlers
246 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
247 {
248 // true is to force the frame to close
249 Close(true);
250 }
251
252 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
253 {
254 wxString msg;
255 msg.Printf( _T("This is the about dialog of XML resources demo.\n")
256 _T("Welcome to %s"), wxVERSION_STRING);
257
258 wxMessageBox(msg, "About XML resources demo", wxOK | wxICON_INFORMATION, this);
259 }
260
261 void MyFrame::OnDlg1(wxCommandEvent& WXUNUSED(event))
262 {
263 wxDialog dlg;
264 wxXmlResource::Get()->LoadDialog(&dlg, this, "dlg1");
265 dlg.ShowModal();
266 }
267
268 void MyFrame::OnDlg2(wxCommandEvent& WXUNUSED(event))
269 {
270 wxDialog dlg;
271 wxXmlResource::Get()->LoadDialog(&dlg, this, "dlg2");
272 dlg.ShowModal();
273 }
274 @endcode
275
276
277 @section overview_xrc_sample XRC resource file sample
278
279 This is the XML file (resource.xrc) for the XRC sample.
280
281 @code
282 <?xml version="1.0"?>
283 <resource version="2.3.0.1">
284 <object class="wxMenuBar" name="mainmenu">
285 <style>wxMB_DOCKABLE</style>
286 <object class="wxMenu" name="menu_file">
287 <label>_File</label>
288 <style>wxMENU_TEAROFF</style>
289 <object class="wxMenuItem" name="menu_about">
290 <label>_About...</label>
291 <bitmap>filesave.gif</bitmap>
292 </object>
293 <object class="separator"/>
294 <object class="wxMenuItem" name="menu_dlg1">
295 <label>Dialog 1</label>
296 </object>
297 <object class="wxMenuItem" name="menu_dlg2">
298 <label>Dialog 2</label>
299 </object>
300 <object class="separator"/>
301 <object class="wxMenuItem" name="menu_quit">
302 <label>E_xit\tAlt-X</label>
303 </object>
304 </object>
305 </object>
306 <object class="wxToolBar" name="toolbar">
307 <style>wxTB_FLAT|wxTB_DOCKABLE</style>
308 <margins>2,2</margins>
309 <object class="tool" name="menu_open">
310 <bitmap>fileopen.gif</bitmap>
311 <tooltip>Open catalog</tooltip>
312 </object>
313 <object class="tool" name="menu_save">
314 <bitmap>filesave.gif</bitmap>
315 <tooltip>Save catalog</tooltip>
316 </object>
317 <object class="tool" name="menu_update">
318 <bitmap>update.gif</bitmap>
319 <tooltip>Update catalog - synchronize it with sources</tooltip>
320 </object>
321 <separator/>
322 <object class="tool" name="menu_quotes">
323 <bitmap>quotes.gif</bitmap>
324 <toggle>1</toggle>
325 <tooltip>Display quotes around the string?</tooltip>
326 </object>
327 <object class="separator"/>
328 <object class="tool" name="menu_fuzzy">
329 <bitmap>fuzzy.gif</bitmap>
330 <tooltip>Toggled if selected string is fuzzy translation</tooltip>
331 <toggle>1</toggle>
332 </object>
333 </object>
334 <object class="wxDialog" name="dlg1">
335 <object class="wxBoxSizer">
336 <object class="sizeritem">
337 <object class="wxBitmapButton">
338 <bitmap>fuzzy.gif</bitmap>
339 <focus>fileopen.gif</focus>
340 </object>
341 </object>
342 <object class="sizeritem">
343 <object class="wxPanel">
344 <object class="wxStaticText">
345 <label>fdgdfgdfgdfg</label>
346 </object>
347 <style>wxBORDER\_SUNKEN</style>
348 </object>
349 <flag>wxALIGN_CENTER</flag>
350 </object>
351 <object class="sizeritem">
352 <object class="wxButton">
353 <label>Buttonek</label>
354 </object>
355 <border>10d</border>
356 <flag>wxALL</flag>
357 </object>
358 <object class="sizeritem">
359 <object class="wxHtmlWindow">
360 <htmlcode>&lt;h1&gt;Hi,&lt;/h1&gt;man</htmlcode>
361 <size>100,45d</size>
362 </object>
363 </object>
364 <object class="sizeritem">
365 <object class="wxNotebook">
366 <object class="notebookpage">
367 <object class="wxPanel">
368 <object class="wxBoxSizer">
369 <object class="sizeritem">
370 <object class="wxHtmlWindow">
371 <htmlcode>Hello, we are inside a &lt;u&gt;NOTEBOOK&lt;/u&gt;...</htmlcode>
372 <size>50,50d</size>
373 </object>
374 <option>1</option>
375 </object>
376 </object>
377 </object>
378 <label>Page</label>
379 </object>
380 <object class="notebookpage">
381 <object class="wxPanel">
382 <object class="wxBoxSizer">
383 <object class="sizeritem">
384 <object class="wxHtmlWindow">
385 <htmlcode>Hello, we are inside a &lt;u&gt;NOTEBOOK&lt;/u&gt;...</htmlcode>
386 <size>50,50d</size>
387 </object>
388 </object>
389 </object>
390 </object>
391 <label>Page 2</label>
392 </object>
393 <usenotebooksizer>1</usenotebooksizer>
394 </object>
395 <flag>wxEXPAND</flag>
396 </object>
397 <orient>wxVERTICAL</orient>
398 </object>
399 </object>
400 <object class="wxDialog" name="dlg2">
401 <object class="wxBoxSizer">
402 <orient>wxVERTICAL</orient>
403 <object class="sizeritem" name="dfgdfg">
404 <object class="wxTextCtrl">
405 <size>200,200d</size>
406 <style>wxTE_MULTILINE|wxBORDER_SUNKEN</style>
407 <value>Hello, this is an ordinary multiline\n textctrl....</value>
408 </object>
409 <option>1</option>
410 <flag>wxEXPAND|wxALL</flag>
411 <border>10</border>
412 </object>
413 <object class="sizeritem">
414 <object class="wxBoxSizer">
415 <object class="sizeritem">
416 <object class="wxButton" name="wxID_OK">
417 <label>Ok</label>
418 <default>1</default>
419 </object>
420 </object>
421 <object class="sizeritem">
422 <object class="wxButton" name="wxID_CANCEL">
423 <label>Cancel</label>
424 </object>
425 <border>10</border>
426 <flag>wxLEFT</flag>
427 </object>
428 </object>
429 <flag>wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_RIGHT</flag>
430 <border>10</border>
431 </object>
432 </object>
433 <title>Second testing dialog</title>
434 </object>
435 </resource>
436 @endcode
437
438
439 @section overview_xrc_fileformat XRC file format
440
441 Please see Technical Note 14 (docs/tech/tn0014.txt) in your wxWidgets
442 distribution.
443
444
445 @section overview_xrc_cppheader C++ header file generation
446
447 Using the @c -e switch together with @c -c, a C++ header file is written
448 containing class definitions for the GUI windows defined in the XRC file.
449 This code generation can make it easier to use XRC and automate program
450 development.
451 The classes can be used as basis for development, freeing the
452 programmer from dealing with most of the XRC specifics (e.g. @c XRCCTRL).
453
454 For each top level window defined in the XRC file a C++ class definition is
455 generated, containing as class members the named widgets of the window.
456 A default constructor for each class is also generated. Inside the constructor
457 all XRC loading is done and all class members representing widgets are initialized.
458
459 A simple example will help understand how the scheme works. Suppose you have
460 a XRC file defining a top level window @c TestWnd_Base, which subclasses @c wxFrame
461 (any other class like @c wxDialog will do also), and has subwidgets @c wxTextCtrl A
462 and @c wxButton B.
463
464 The XRC file and corresponding class definition in the header file will
465 be something like:
466
467 @code
468 <?xml version="1.0"?>
469 <resource version="2.3.0.1">
470 <object class="wxFrame" name="TestWnd_Base">
471 <size>-1,-1</size>
472 <title>Test</title>
473 <object class="wxBoxSizer">
474 <orient>wxHORIZONTAL</orient>
475 <object class="sizeritem">
476 <object class="wxTextCtrl" name="A">
477 <label>Test label</label>
478 </object>
479 </object>
480 <object class="sizeritem">
481 <object class="wxButton" name="B">
482 <label>Test button</label>
483 </object>
484 </object>
485 </object>
486 </object>
487 </resource>
488
489
490 class TestWnd_Base : public wxFrame {
491 protected:
492 wxTextCtrl* A;
493 wxButton* B;
494
495 private:
496 void InitWidgetsFromXRC(){
497 wxXmlResource::Get()->LoadObject(this,NULL,"TestWnd","wxFrame");
498 A = XRCCTRL(*this,"A",wxTextCtrl);
499 B = XRCCTRL(*this,"B",wxButton);
500 }
501 public:
502 TestWnd::TestWnd(){
503 InitWidgetsFromXRC();
504 }
505 };
506 @endcode
507
508 The generated window class can be used as basis for the full window class. The
509 class members which represent widgets may be accessed by name instead of using
510 @c XRCCTRL every time you wish to reference them (note that they are @c protected
511 class members), though you must still use @c XRCID to refer to widget IDs in the
512 event table.
513
514 Example:
515
516 @code
517 #include "resource.h"
518
519 class TestWnd : public TestWnd_Base {
520 public:
521 TestWnd(){
522 // A, B already initialised at this point
523 A->SetValue("Updated in TestWnd::TestWnd");
524 B->SetValue("Nice :)");
525 }
526 void OnBPressed(wxEvent& event){
527 Close();
528 }
529 DECLARE_EVENT_TABLE();
530 };
531
532 BEGIN_EVENT_TABLE(TestWnd,TestWnd_Base)
533 EVT_BUTTON(XRCID("B"),TestWnd::OnBPressed)
534 END_EVENT_TABLE()
535 @endcode
536
537 It is also possible to access the wxSizerItem of a sizer that is part of
538 a resource. This can be done using @c XRCSIZERITEM as shown.
539
540 The resource file can have something like this for a sizer item.
541
542 @code
543 <object class="spacer" name="area">
544 <size>400, 300</size>
545 </object>
546 @endcode
547
548 The code can then access the sizer item by using @c XRCSIZERITEM and
549 @c XRCID together.
550
551 @code
552 wxSizerItem* item = XRCSIZERITEM(*this, "area");
553 @endcode
554
555
556 @section overview_xrc_newresourcehandlers Adding new resource handlers
557
558 Adding a new resource handler is pretty easy.
559
560 Typically, to add an handler for the @c MyControl class, you'll want to create
561 the @c xh_mycontrol.h and @c xh_mycontrol.cpp files.
562
563 The header needs to contains the @c MyControlXmlHandler class definition:
564
565 @code
566 class MyControlXmlHandler : public wxXmlResourceHandler
567 {
568 public:
569
570 // Constructor.
571 MyControlXmlHandler();
572
573 // Creates the control and returns a pointer to it.
574 virtual wxObject *DoCreateResource();
575
576 // Returns @true if we know how to create a control for the given node.
577 virtual bool CanHandle(wxXmlNode *node);
578
579 // Register with wxWidgets' dynamic class subsystem.
580 DECLARE_DYNAMIC_CLASS(MyControlXmlHandler)
581 };
582 @endcode
583
584 The implementation of your custom XML handler will typically look as:
585
586 @code
587 // Register with wxWidgets' dynamic class subsystem.
588 IMPLEMENT_DYNAMIC_CLASS(MyControlXmlHandler, wxXmlResourceHandler)
589
590 MyControlXmlHandler::MyControlXmlHandler()
591 {
592 // this call adds support for all wxWindows class styles
593 // (e.g. wxBORDER_SIMPLE, wxBORDER_SUNKEN, wxWS_EX_* etc etc)
594 AddWindowStyles();
595
596 // if MyControl class supports e.g. MYCONTROL_DEFAULT_STYLE
597 // you should use:
598 // XRC_ADD_STYLE(MYCONTROL_DEFAULT_STYLE);
599 }
600
601 wxObject *MyControlXmlHandler::DoCreateResource()
602 {
603 // the following macro will init a pointer named "control"
604 // with a new instance of the MyControl class, but will NOT
605 // Create() it!
606 XRC_MAKE_INSTANCE(control, MyControl)
607
608 // this is the point where you'll typically need to do the most
609 // important changes: here the control is created and initialized.
610 // You'll want to use the wxXmlResourceHandler's getters to
611 // do most of your work.
612 // If e.g. the MyControl::Create function looks like:
613 //
614 // bool MyControl::Create(wxWindow *parent, int id,
615 // const wxBitmap , const wxPoint ,
616 // const wxBitmap , const wxPoint ,
617 // const wxString , const wxFont ,
618 // const wxPoint , const wxSize ,
619 // long style = MYCONTROL_DEFAULT_STYLE,
620 // const wxString = wxT("MyControl"));
621 //
622 // then the XRC for your component should look like:
623 //
624 // <object class="MyControl" name="some_name">
625 // <first-bitmap>first.xpm</first-bitmap>
626 // <second-bitmap>text.xpm</second-bitmap>
627 // <first-pos>3,3</first-pos>
628 // <second-pos>4,4</second-pos>
629 // <the-title>a title</the-title>
630 // <title-font>
631 // <!-- the standard XRC tags for describing a font: <size>, <style>, <weight>, etc -->
632 // </title-font>
633 // <!-- XRC also accepts other usual tags for wxWindow-derived classes:
634 // like e.g. <name>, <style>, <size>, <position>, etc -->
635 // </object>
636 //
637 // and the code to read your custom tags from the XRC file is just:
638 control->Create(m_parentAsWindow, GetID(),
639 GetBitmap(wxT("first-bitmap")),
640 GetPosition(wxT("first-pos")),
641 GetBitmap(wxT("second-bitmap")),
642 GetPosition(wxT("second-pos")),
643 GetText(wxT("the-title")),
644 GetFont(wxT("title-font")),
645 GetPosition(), GetSize(), GetStyle(), GetName());
646
647 SetupWindow(control);
648
649 return control;
650 }
651
652 bool MyControlXmlHandler::CanHandle(wxXmlNode *node)
653 {
654 // this function tells XRC system that this handler can parse
655 // the object class="MyControl" tags
656 return IsOfClass(node, wxT("MyControl"));
657 }
658 @endcode
659
660 You may want to check the #wxXmlResourceHandler documentation
661 to see how many built-in getters it contains. It's very easy to retrieve also
662 complex structures out of XRC files using them.
663
664 */
665