]> git.saurik.com Git - wxWidgets.git/blame - src/xrc/xh_sizer.cpp
splitted wxApp docs in wxApp+wxAppConsole docs; fix the signature of the documented...
[wxWidgets.git] / src / xrc / xh_sizer.cpp
CommitLineData
78d14f80 1/////////////////////////////////////////////////////////////////////////////
1c067fe3 2// Name: src/xrc/xh_sizer.cpp
b5d6954b 3// Purpose: XRC resource for wxBoxSizer
78d14f80
VS
4// Author: Vaclav Slavik
5// Created: 2000/03/21
6// RCS-ID: $Id$
7// Copyright: (c) 2000 Vaclav Slavik
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
f80ea77b 10
78d14f80
VS
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
621be1ec 18#if wxUSE_XRC
a1e4ec87 19
78d14f80 20#include "wx/xrc/xh_sizer.h"
e4db172a
WS
21
22#ifndef WX_PRECOMP
23 #include "wx/log.h"
8e609c82 24 #include "wx/panel.h"
876cd6f7 25 #include "wx/statbox.h"
ed2fbeb8 26 #include "wx/sizer.h"
4107600f
MW
27 #include "wx/frame.h"
28 #include "wx/dialog.h"
29 #include "wx/button.h"
5e1a9f05 30 #include "wx/scrolwin.h"
e4db172a
WS
31#endif
32
0d077b41 33#include "wx/gbsizer.h"
78d14f80
VS
34#include "wx/notebook.h"
35#include "wx/tokenzr.h"
36
78d14f80 37
172541f6
VS
38//-----------------------------------------------------------------------------
39// wxSizerXmlHandler
40//-----------------------------------------------------------------------------
78d14f80 41
0d077b41 42IMPLEMENT_DYNAMIC_CLASS(wxSizerXmlHandler, wxXmlResourceHandler)
78d14f80 43
f80ea77b 44wxSizerXmlHandler::wxSizerXmlHandler()
ed2fbeb8
WS
45 :wxXmlResourceHandler(),
46 m_isInside(false),
47 m_isGBS(false),
48 m_parentSizer(NULL)
78d14f80 49{
544fee32
VS
50 XRC_ADD_STYLE(wxHORIZONTAL);
51 XRC_ADD_STYLE(wxVERTICAL);
78d14f80
VS
52
53 // and flags
544fee32
VS
54 XRC_ADD_STYLE(wxLEFT);
55 XRC_ADD_STYLE(wxRIGHT);
56 XRC_ADD_STYLE(wxTOP);
57 XRC_ADD_STYLE(wxBOTTOM);
58 XRC_ADD_STYLE(wxNORTH);
59 XRC_ADD_STYLE(wxSOUTH);
60 XRC_ADD_STYLE(wxEAST);
61 XRC_ADD_STYLE(wxWEST);
62 XRC_ADD_STYLE(wxALL);
78d14f80 63
544fee32
VS
64 XRC_ADD_STYLE(wxGROW);
65 XRC_ADD_STYLE(wxEXPAND);
66 XRC_ADD_STYLE(wxSHAPED);
67 XRC_ADD_STYLE(wxSTRETCH_NOT);
78d14f80 68
544fee32
VS
69 XRC_ADD_STYLE(wxALIGN_CENTER);
70 XRC_ADD_STYLE(wxALIGN_CENTRE);
71 XRC_ADD_STYLE(wxALIGN_LEFT);
72 XRC_ADD_STYLE(wxALIGN_TOP);
73 XRC_ADD_STYLE(wxALIGN_RIGHT);
74 XRC_ADD_STYLE(wxALIGN_BOTTOM);
75 XRC_ADD_STYLE(wxALIGN_CENTER_HORIZONTAL);
76 XRC_ADD_STYLE(wxALIGN_CENTRE_HORIZONTAL);
77 XRC_ADD_STYLE(wxALIGN_CENTER_VERTICAL);
78 XRC_ADD_STYLE(wxALIGN_CENTRE_VERTICAL);
f80ea77b 79
c66b63e5 80 XRC_ADD_STYLE(wxFIXED_MINSIZE);
a575238f 81 XRC_ADD_STYLE(wxRESERVE_SPACE_EVEN_IF_HIDDEN);
78d14f80
VS
82}
83
84
85
0d077b41
RD
86bool wxSizerXmlHandler::CanHandle(wxXmlNode *node)
87{
88 return ( (!m_isInside && IsSizerNode(node)) ||
89 (m_isInside && IsOfClass(node, wxT("sizeritem"))) ||
f80ea77b 90 (m_isInside && IsOfClass(node, wxT("spacer")))
0d077b41
RD
91 );
92}
93
f80ea77b 94
0d077b41 95wxObject* wxSizerXmlHandler::DoCreateResource()
f80ea77b 96{
78d14f80 97 if (m_class == wxT("sizeritem"))
0d077b41 98 return Handle_sizeritem();
f80ea77b 99
78d14f80 100 else if (m_class == wxT("spacer"))
0d077b41
RD
101 return Handle_spacer();
102
103 else
104 return Handle_sizer();
105}
106
107
108
109
110bool wxSizerXmlHandler::IsSizerNode(wxXmlNode *node)
111{
112 return (IsOfClass(node, wxT("wxBoxSizer"))) ||
113 (IsOfClass(node, wxT("wxStaticBoxSizer"))) ||
114 (IsOfClass(node, wxT("wxGridSizer"))) ||
115 (IsOfClass(node, wxT("wxFlexGridSizer"))) ||
116 (IsOfClass(node, wxT("wxGridBagSizer")));
117}
118
119
120wxObject* wxSizerXmlHandler::Handle_sizeritem()
121{
122 // find the item to be managed by this sizeritem
123 wxXmlNode *n = GetParamNode(wxT("object"));
124 if ( !n )
125 n = GetParamNode(wxT("object_ref"));
126
127 // did we find one?
128 if (n)
129 {
130 // create a sizer item for it
131 wxSizerItem* sitem = MakeSizerItem();
f80ea77b 132
0d077b41
RD
133 // now fetch the item to be managed
134 bool old_gbs = m_isGBS;
135 bool old_ins = m_isInside;
136 wxSizer *old_par = m_parentSizer;
f80ea77b
WS
137 m_isInside = false;
138 if (!IsSizerNode(n)) m_parentSizer = NULL;
0d077b41
RD
139 wxObject *item = CreateResFromNode(n, m_parent, NULL);
140 m_isInside = old_ins;
141 m_parentSizer = old_par;
142 m_isGBS = old_gbs;
143
144 // and figure out what type it is
145 wxSizer *sizer = wxDynamicCast(item, wxSizer);
146 wxWindow *wnd = wxDynamicCast(item, wxWindow);
f80ea77b 147
0d077b41 148 if (sizer)
a50cf60e 149 sitem->AssignSizer(sizer);
0d077b41 150 else if (wnd)
a50cf60e 151 sitem->AssignWindow(wnd);
f80ea77b 152 else
0d077b41
RD
153 wxLogError(wxT("Error in resource."));
154
1eba2193
RD
155 // finally, set other wxSizerItem attributes
156 SetSizerItemAttributes(sitem);
157
0d077b41
RD
158 AddSizerItem(sitem);
159 return item;
160 }
161 else /*n == NULL*/
78d14f80 162 {
0d077b41 163 wxLogError(wxT("Error in resource: no window/sizer/spacer within sizeritem object."));
78d14f80
VS
164 return NULL;
165 }
0d077b41
RD
166}
167
168
169wxObject* wxSizerXmlHandler::Handle_spacer()
170{
171 wxCHECK_MSG(m_parentSizer, NULL, wxT("Incorrect syntax of XRC resource: spacer not within sizer!"));
172
173 wxSizerItem* sitem = MakeSizerItem();
174 SetSizerItemAttributes(sitem);
a50cf60e 175 sitem->AssignSpacer(GetSize());
f80ea77b 176 AddSizerItem(sitem);
0d077b41
RD
177 return NULL;
178}
179
78d14f80 180
0d077b41
RD
181wxObject* wxSizerXmlHandler::Handle_sizer()
182{
183 wxSizer *sizer = NULL;
f80ea77b 184
0d077b41 185 wxXmlNode *parentNode = m_node->GetParent();
78d14f80 186
0d077b41 187 wxCHECK_MSG(m_parentSizer != NULL ||
0a904ad4 188 (parentNode && parentNode->GetType() == wxXML_ELEMENT_NODE &&
35386afc
VZ
189 m_parentAsWindow), NULL,
190 wxT("Sizer must have a window parent node"));
78d14f80 191
0d077b41
RD
192 if (m_class == wxT("wxBoxSizer"))
193 sizer = Handle_wxBoxSizer();
194
627ddac9 195#if wxUSE_STATBOX
0d077b41
RD
196 else if (m_class == wxT("wxStaticBoxSizer"))
197 sizer = Handle_wxStaticBoxSizer();
627ddac9 198#endif
f80ea77b 199
0d077b41
RD
200 else if (m_class == wxT("wxGridSizer"))
201 sizer = Handle_wxGridSizer();
f80ea77b 202
0d077b41
RD
203 else if (m_class == wxT("wxFlexGridSizer"))
204 sizer = Handle_wxFlexGridSizer();
78d14f80 205
0d077b41
RD
206 else if (m_class == wxT("wxGridBagSizer"))
207 sizer = Handle_wxGridBagSizer();
78d14f80 208
641c5f1a
VZ
209 if ( !sizer )
210 {
211 wxLogError(_T("Failed to create size of class \"%s\""), m_class.c_str());
212 return NULL;
213 }
f80ea77b 214
0d077b41
RD
215 wxSize minsize = GetSize(wxT("minsize"));
216 if (!(minsize == wxDefaultSize))
217 sizer->SetMinSize(minsize);
218
219 // save state
220 wxSizer *old_par = m_parentSizer;
221 bool old_ins = m_isInside;
0d077b41
RD
222
223 // set new state
224 m_parentSizer = sizer;
f80ea77b 225 m_isInside = true;
0d077b41 226 m_isGBS = (m_class == wxT("wxGridBagSizer"));
f80ea77b
WS
227
228 CreateChildren(m_parent, true/*only this handler*/);
0d077b41
RD
229
230 // restore state
0d077b41
RD
231 m_isInside = old_ins;
232 m_parentSizer = old_par;
233
234 if (m_parentSizer == NULL) // setup window:
235 {
0d077b41
RD
236 m_parentAsWindow->SetSizer(sizer);
237
238 wxXmlNode *nd = m_node;
239 m_node = parentNode;
240 if (GetSize() == wxDefaultSize)
5e1a9f05
VS
241 {
242 if ( wxDynamicCast(m_parentAsWindow, wxScrolledWindow) != NULL )
243 {
244 sizer->FitInside(m_parentAsWindow);
245 }
246 else
247 {
248 sizer->Fit(m_parentAsWindow);
249 }
250 }
0d077b41
RD
251 m_node = nd;
252
ea813d91
VS
253 if (m_parentAsWindow->IsTopLevel())
254 {
0d077b41 255 sizer->SetSizeHints(m_parentAsWindow);
ea813d91 256 }
0d077b41 257 }
f80ea77b 258
0d077b41
RD
259 return sizer;
260}
261
262
263wxSizer* wxSizerXmlHandler::Handle_wxBoxSizer()
264{
265 return new wxBoxSizer(GetStyle(wxT("orient"), wxHORIZONTAL));
f80ea77b
WS
266}
267
627ddac9 268#if wxUSE_STATBOX
0d077b41
RD
269wxSizer* wxSizerXmlHandler::Handle_wxStaticBoxSizer()
270{
271 return new wxStaticBoxSizer(
272 new wxStaticBox(m_parentAsWindow,
273 GetID(),
274 GetText(wxT("label")),
275 wxDefaultPosition, wxDefaultSize,
276 0/*style*/,
277 GetName()),
278 GetStyle(wxT("orient"), wxHORIZONTAL));
279}
627ddac9 280#endif // wxUSE_STATBOX
f80ea77b 281
0d077b41
RD
282wxSizer* wxSizerXmlHandler::Handle_wxGridSizer()
283{
284 return new wxGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
285 GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
286}
287
288
289wxSizer* wxSizerXmlHandler::Handle_wxFlexGridSizer()
290{
f80ea77b 291 wxFlexGridSizer *sizer =
0d077b41
RD
292 new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
293 GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
294 SetGrowables(sizer, wxT("growablerows"), true);
295 SetGrowables(sizer, wxT("growablecols"), false);
296 return sizer;
297}
298
299
300wxSizer* wxSizerXmlHandler::Handle_wxGridBagSizer()
301{
f80ea77b 302 wxGridBagSizer *sizer =
0d077b41
RD
303 new wxGridBagSizer(GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
304 SetGrowables(sizer, wxT("growablerows"), true);
305 SetGrowables(sizer, wxT("growablecols"), false);
306 return sizer;
307}
308
309
310
311
312void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer* sizer,
313 const wxChar* param,
314 bool rows)
315{
316 wxStringTokenizer tkn;
317 unsigned long l;
318 tkn.SetString(GetParamValue(param), wxT(","));
319 while (tkn.HasMoreTokens())
320 {
321 if (!tkn.GetNextToken().ToULong(&l))
322 wxLogError(wxT("growable[rows|cols] must be comma-separated list of row numbers"));
323 else {
324 if (rows)
325 sizer->AddGrowableRow(l);
326 else
327 sizer->AddGrowableCol(l);
78d14f80 328 }
78d14f80
VS
329 }
330}
331
332
0d077b41
RD
333wxGBPosition wxSizerXmlHandler::GetGBPos(const wxString& param)
334{
335 wxSize sz = GetSize(param);
336 if (sz.x < 0) sz.x = 0;
337 if (sz.y < 0) sz.y = 0;
338 return wxGBPosition(sz.x, sz.y);
339}
78d14f80 340
0d077b41
RD
341wxGBSpan wxSizerXmlHandler::GetGBSpan(const wxString& param)
342{
343 wxSize sz = GetSize(param);
344 if (sz.x < 1) sz.x = 1;
345 if (sz.y < 1) sz.y = 1;
346 return wxGBSpan(sz.x, sz.y);
347}
348
349
350
351wxSizerItem* wxSizerXmlHandler::MakeSizerItem()
352{
353 if (m_isGBS)
354 return new wxGBSizerItem();
355 else
356 return new wxSizerItem();
357}
358
359void wxSizerXmlHandler::SetSizerItemAttributes(wxSizerItem* sitem)
360{
361 sitem->SetProportion(GetLong(wxT("option"))); // Should this check for "proportion" too?
362 sitem->SetFlag(GetStyle(wxT("flag")));
363 sitem->SetBorder(GetDimension(wxT("border")));
364 wxSize sz = GetSize(wxT("minsize"));
365 if (!(sz == wxDefaultSize))
1eba2193 366 sitem->SetMinSize(sz);
0d077b41
RD
367 sz = GetSize(wxT("ratio"));
368 if (!(sz == wxDefaultSize))
369 sitem->SetRatio(sz);
f80ea77b 370
0d077b41
RD
371 if (m_isGBS)
372 {
373 wxGBSizerItem* gbsitem = (wxGBSizerItem*)sitem;
ea0d8ca6
RD
374 gbsitem->SetPos(GetGBPos(wxT("cellpos")));
375 gbsitem->SetSpan(GetGBSpan(wxT("cellspan")));
f80ea77b 376 }
86909f4c
VZ
377
378 // record the id of the item, if any, for use by XRCSIZERITEM()
379 sitem->SetId(GetID());
0d077b41
RD
380}
381
382void wxSizerXmlHandler::AddSizerItem(wxSizerItem* sitem)
78d14f80 383{
0d077b41
RD
384 if (m_isGBS)
385 ((wxGridBagSizer*)m_parentSizer)->Add((wxGBSizerItem*)sitem);
386 else
387 m_parentSizer->Add(sitem);
78d14f80 388}
f80ea77b 389
172541f6
VS
390
391
392//-----------------------------------------------------------------------------
393// wxStdDialogButtonSizerXmlHandler
394//-----------------------------------------------------------------------------
dd47af27 395#if wxUSE_BUTTON
172541f6
VS
396
397IMPLEMENT_DYNAMIC_CLASS(wxStdDialogButtonSizerXmlHandler, wxXmlResourceHandler)
398
399wxStdDialogButtonSizerXmlHandler::wxStdDialogButtonSizerXmlHandler()
400 : m_isInside(false), m_parentSizer(NULL)
401{
402}
403
404wxObject *wxStdDialogButtonSizerXmlHandler::DoCreateResource()
405{
406 if (m_class == wxT("wxStdDialogButtonSizer"))
407 {
408 wxASSERT( !m_parentSizer );
409
410 wxSizer *s = m_parentSizer = new wxStdDialogButtonSizer;
411 m_isInside = true;
412
413 CreateChildren(m_parent, true/*only this handler*/);
414
415 m_parentSizer->Realize();
416
417 m_isInside = false;
418 m_parentSizer = NULL;
419
420 return s;
421 }
422 else // m_class == "button"
423 {
424 wxASSERT( m_parentSizer );
425
426 // find the item to be managed by this sizeritem
427 wxXmlNode *n = GetParamNode(wxT("object"));
428 if ( !n )
429 n = GetParamNode(wxT("object_ref"));
430
431 // did we find one?
432 if (n)
433 {
434 wxObject *item = CreateResFromNode(n, m_parent, NULL);
435 wxButton *button = wxDynamicCast(item, wxButton);
436
437 if (button)
438 m_parentSizer->AddButton(button);
439 else
440 wxLogError(wxT("Error in resource - expected button."));
441
442 return item;
443 }
444 else /*n == NULL*/
445 {
446 wxLogError(wxT("Error in resource: no button within wxStdDialogButtonSizer."));
447 return NULL;
448 }
449 }
450}
451
452bool wxStdDialogButtonSizerXmlHandler::CanHandle(wxXmlNode *node)
453{
454 return (!m_isInside && IsOfClass(node, wxT("wxStdDialogButtonSizer"))) ||
455 (m_isInside && IsOfClass(node, wxT("button")));
456}
dd47af27 457#endif // wxUSE_BUTTON
172541f6 458
621be1ec 459#endif // wxUSE_XRC