]> git.saurik.com Git - wxWidgets.git/blob - docs/doxygen/overviews/xrc.h
added images for topic overviews
[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 There are several advantages to using XRC resources.
20
21
22 Recompiling and linking an application is not necessary if the
23 resources change.
24 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 You can choose between different alternative resource files at run time, if necessary.
28 The XRC format uses sizers for flexibility, allowing dialogs to be resizable
29 and highly portable.
30 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 @ref xrcconcepts_overview
37 @ref binaryresourcefiles_overview
38 @ref embeddedresource_overview
39 @ref xrccppsample_overview
40 @ref xrcsample_overview
41 @ref xrcfileformat_overview
42 @ref xrccppheader_overview
43 @ref newresourcehandlers_overview
44
45
46 @section xrcconcepts XRC concepts
47
48 These are the typical steps for using XRC files in your application.
49
50
51 Include the appropriate headers: normally "wx/xrc/xmlres.h" will suffice;
52 If you are going to use @ref binaryresourcefiles_overview, install
53 wxFileSystem archive handler first with @c wxFileSystem::AddHandler(new wxArchiveFSHandler);
54 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 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 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
62 To create an XRC file, you can use one of the following methods.
63
64
65 Create the file by hand;
66 use #wxDesigner, a commercial dialog designer/RAD tool;
67 use #DialogBlocks, a commercial dialog editor;
68 use #XRCed, a wxPython-based
69 dialog editor that you can find in the @c wxPython/tools subdirectory of the wxWidgets
70 CVS archive;
71 use #wxGlade, a GUI designer written in wxPython. At the moment it can generate Python, C++ and XRC;
72
73
74 A complete list of third-party tools that write to XRC can be found at #www.wxwidgets.org/lnk_tool.htm.
75 It is highly recommended that you use a resource editing tool, since it's fiddly writing
76 XRC files by hand.
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 You can also use @ref embeddedresource_overview
81
82 @section binaryresourcefiles Using binary resource files
83
84 To compile binary resource files, use the command-line wxrc utility. It takes one or more file parameters
85 (the input XRC files) and the following switches and options:
86
87
88 -h (--help): show a help message
89 -v (--verbose): show verbose logging information
90 -c (--cpp-code): write C++ source rather than a XRS file
91 -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 -u (--uncompressed): do not compress XML files (C++ only)
94 -g (--gettext): output underscore-wrapped strings that poEdit or gettext can scan. Outputs to stdout, or a file if -o is used
95 -n (--function) name: specify C++ function name (use with -c)
96 -o (--output) filename: specify the output file, such as resource.xrs or resource.cpp
97 -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 @b 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
114 @code
115 #include wx/filesys.h
116 #include wx/fs_arc.h
117 ...
118 wxFileSystem::AddHandler(new wxArchiveFSHandler);
119 @endcode
120
121
122 @section embeddedresource Using embedded resources
123
124 It is sometimes useful to embed resources in the executable itself instead
125 of loading an external file (e.g. when your app is small and consists only of one
126 exe file). XRC provides means to convert resources into regular C++ file that
127 can be compiled and included in the executable.
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 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 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 xrcfileformat XRC file format
430
431 Please see Technical Note 14 (docs/tech/tn0014.txt) in your wxWidgets
432 distribution.
433
434 @section 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 For each top level window defined in the XRC file a C++ class definition is
443 generated, containing as class members the named widgets of the window.
444 A default constructor for each class is also generated. Inside the constructor
445 all XRC loading is done and all class members representing widgets are initialized.
446 A simple example will help understand how the scheme works. Suppose you have
447 a XRC file defining a top level window @c TestWnd_Base, which subclasses @c wxFrame (any
448 other class like @c wxDialog will do also), and has subwidgets @c wxTextCtrl A and @c wxButton B.
449 The XRC file and corresponding class definition in the header file will be something like:
450
451 @code
452 ?xml version="1.0"?
453 resource version="2.3.0.1"
454 object class="wxFrame" name="TestWnd_Base"
455 size-1,-1/size
456 titleTest/title
457 object class="wxBoxSizer"
458 orientwxHORIZONTAL/orient
459 object class="sizeritem"
460 object class="wxTextCtrl" name="A"
461 labelTest label/label
462 /object
463 /object
464 object class="sizeritem"
465 object class="wxButton" name="B"
466 labelTest button/label
467 /object
468 /object
469 /object
470 /object
471 /resource
472
473
474 class TestWnd_Base : public wxFrame {
475 protected:
476 wxTextCtrl* A;
477 wxButton* B;
478
479 private:
480 void InitWidgetsFromXRC(){
481 wxXmlResource::Get()-LoadObject(this,@NULL,"TestWnd","wxFrame");
482 A = XRCCTRL(*this,"A",wxTextCtrl);
483 B = XRCCTRL(*this,"B",wxButton);
484 }
485 public:
486 TestWnd::TestWnd(){
487 InitWidgetsFromXRC();
488 }
489 };
490 @endcode
491
492 The generated window class can be used as basis for the full window class. The
493 class members which represent widgets may be accessed by name instead of using
494 @c XRCCTRL every time you wish to reference them (note that they are @c protected class members),
495 though you must still use @c XRCID to refer to widget IDs in the event
496 table.
497 Example:
498
499 @code
500 #include "resource.h"
501
502 class TestWnd : public TestWnd_Base {
503 public:
504 TestWnd(){
505 // A, B already initialised at this point
506 A-SetValue("Updated in TestWnd::TestWnd");
507 B-SetValue("Nice :)");
508 }
509 void OnBPressed(wxEvent& event){
510 Close();
511 }
512 DECLARE_EVENT_TABLE();
513 };
514
515 BEGIN_EVENT_TABLE(TestWnd,TestWnd_Base)
516 EVT_BUTTON(XRCID("B"),TestWnd::OnBPressed)
517 END_EVENT_TABLE()
518 @endcode
519
520 It is also possible to access the wxSizerItem of a sizer that is part of
521 a resource. This can be done using @c XRCSIZERITEM as shown. The
522 resource file can have something like this for a sizer item.
523
524 @code
525 object class="spacer" name="area"
526 size400, 300/size
527 /object
528 @endcode
529
530 The code can then access the sizer item by using @c XRCSIZERITEM and
531 @c XRCID together.
532
533 @code
534 wxSizerItem* item = XRCSIZERITEM(*this, "area");
535 @endcode
536
537
538 @section newresourcehandlers Adding new resource handlers
539
540 Adding a new resource handler is pretty easy.
541 Typically, to add an handler for the @c MyControl class, you'll want to create
542 the @c xh_mycontrol.h @c xh_mycontrol.cpp files.
543 The header needs to contains the @c MyControlXmlHandler class definition:
544
545 @code
546 class MyControlXmlHandler : public wxXmlResourceHandler
547 {
548 public:
549
550 // Constructor.
551 MyControlXmlHandler();
552
553 // Creates the control and returns a pointer to it.
554 virtual wxObject *DoCreateResource();
555
556 // Returns @true if we know how to create a control for the given node.
557 virtual bool CanHandle(wxXmlNode *node);
558
559 // Register with wxWidgets' dynamic class subsystem.
560 DECLARE_DYNAMIC_CLASS(MyControlXmlHandler)
561 };
562 @endcode
563
564 The implementation of your custom XML handler will typically look as:
565
566 @code
567 // Register with wxWidgets' dynamic class subsystem.
568 IMPLEMENT_DYNAMIC_CLASS(MyControlXmlHandler, wxXmlResourceHandler)
569
570 MyControlXmlHandler::MyControlXmlHandler()
571 {
572 // this call adds support for all wxWindows class styles
573 // (e.g. wxBORDER_SIMPLE, wxBORDER_SUNKEN, wxWS_EX_* etc etc)
574 AddWindowStyles();
575
576 // if MyControl class supports e.g. MYCONTROL_DEFAULT_STYLE
577 // you should use:
578 // XRC_ADD_STYLE(MYCONTROL_DEFAULT_STYLE);
579 }
580
581 wxObject *MyControlXmlHandler::DoCreateResource()
582 {
583 // the following macro will init a pointer named "control"
584 // with a new instance of the MyControl class, but will NOT
585 // Create() it!
586 XRC_MAKE_INSTANCE(control, MyControl)
587
588 // this is the point where you'll typically need to do the most
589 // important changes: here the control is created and initialized.
590 // You'll want to use the wxXmlResourceHandler's getters to
591 // do most of your work.
592 // If e.g. the MyControl::Create function looks like:
593 //
594 // bool MyControl::Create(wxWindow *parent, int id,
595 // const wxBitmap , const wxPoint ,
596 // const wxBitmap , const wxPoint ,
597 // const wxString , const wxFont ,
598 // const wxPoint , const wxSize ,
599 // long style = MYCONTROL_DEFAULT_STYLE,
600 // const wxString = wxT("MyControl"));
601 //
602 // then the XRC for your component should look like:
603 //
604 // object class="MyControl" name="some_name"
605 // first-bitmapfirst.xpm/first-bitmap
606 // second-bitmaptext.xpm/second-bitmap
607 // first-pos3,3/first-pos
608 // second-pos4,4/second-pos
609 // the-titlea title/the-title
610 // title-font
611 // !-- the standard XRC tags for describing a font: size, style, weight, etc --
612 // /title-font
613 // !-- XRC also accepts other usual tags for wxWindow-derived classes:
614 // like e.g. name, style, size, position, etc --
615 // /object
616 //
617 // and the code to read your custom tags from the XRC file is just:
618 control-Create(m_parentAsWindow, GetID(),
619 GetBitmap(wxT("first-bitmap")),
620 GetPosition(wxT("first-pos")),
621 GetBitmap(wxT("second-bitmap")),
622 GetPosition(wxT("second-pos")),
623 GetText(wxT("the-title")),
624 GetFont(wxT("title-font")),
625 GetPosition(), GetSize(), GetStyle(), GetName());
626
627 SetupWindow(control);
628
629 return control;
630 }
631
632 bool MyControlXmlHandler::CanHandle(wxXmlNode *node)
633 {
634 // this function tells XRC system that this handler can parse
635 // the object class="MyControl" tags
636 return IsOfClass(node, wxT("MyControl"));
637 }
638 @endcode
639
640 You may want to check the #wxXmlResourceHandler documentation
641 to see how many built-in getters it contains. It's very easy to retrieve also complex structures
642 out of XRC files using them.
643
644 */
645
646