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