1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/xrc/xh_sizer.cpp
3 // Purpose: XRC resource for wxBoxSizer
4 // Author: Vaclav Slavik
7 // Copyright: (c) 2000 Vaclav Slavik
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
20 #include "wx/xrc/xh_sizer.h"
25 #include "wx/statbox.h"
28 #include "wx/dialog.h"
29 #include "wx/button.h"
32 #include "wx/gbsizer.h"
33 #include "wx/notebook.h"
34 #include "wx/tokenzr.h"
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 IMPLEMENT_DYNAMIC_CLASS(wxSizerXmlHandler
, wxXmlResourceHandler
)
43 wxSizerXmlHandler::wxSizerXmlHandler()
44 :wxXmlResourceHandler(),
49 XRC_ADD_STYLE(wxHORIZONTAL
);
50 XRC_ADD_STYLE(wxVERTICAL
);
53 XRC_ADD_STYLE(wxLEFT
);
54 XRC_ADD_STYLE(wxRIGHT
);
56 XRC_ADD_STYLE(wxBOTTOM
);
57 XRC_ADD_STYLE(wxNORTH
);
58 XRC_ADD_STYLE(wxSOUTH
);
59 XRC_ADD_STYLE(wxEAST
);
60 XRC_ADD_STYLE(wxWEST
);
63 XRC_ADD_STYLE(wxGROW
);
64 XRC_ADD_STYLE(wxEXPAND
);
65 XRC_ADD_STYLE(wxSHAPED
);
66 XRC_ADD_STYLE(wxSTRETCH_NOT
);
68 XRC_ADD_STYLE(wxALIGN_CENTER
);
69 XRC_ADD_STYLE(wxALIGN_CENTRE
);
70 XRC_ADD_STYLE(wxALIGN_LEFT
);
71 XRC_ADD_STYLE(wxALIGN_TOP
);
72 XRC_ADD_STYLE(wxALIGN_RIGHT
);
73 XRC_ADD_STYLE(wxALIGN_BOTTOM
);
74 XRC_ADD_STYLE(wxALIGN_CENTER_HORIZONTAL
);
75 XRC_ADD_STYLE(wxALIGN_CENTRE_HORIZONTAL
);
76 XRC_ADD_STYLE(wxALIGN_CENTER_VERTICAL
);
77 XRC_ADD_STYLE(wxALIGN_CENTRE_VERTICAL
);
79 XRC_ADD_STYLE(wxADJUST_MINSIZE
);
80 XRC_ADD_STYLE(wxFIXED_MINSIZE
);
85 bool wxSizerXmlHandler::CanHandle(wxXmlNode
*node
)
87 return ( (!m_isInside
&& IsSizerNode(node
)) ||
88 (m_isInside
&& IsOfClass(node
, wxT("sizeritem"))) ||
89 (m_isInside
&& IsOfClass(node
, wxT("spacer")))
94 wxObject
* wxSizerXmlHandler::DoCreateResource()
96 if (m_class
== wxT("sizeritem"))
97 return Handle_sizeritem();
99 else if (m_class
== wxT("spacer"))
100 return Handle_spacer();
103 return Handle_sizer();
109 bool wxSizerXmlHandler::IsSizerNode(wxXmlNode
*node
)
111 return (IsOfClass(node
, wxT("wxBoxSizer"))) ||
112 (IsOfClass(node
, wxT("wxStaticBoxSizer"))) ||
113 (IsOfClass(node
, wxT("wxGridSizer"))) ||
114 (IsOfClass(node
, wxT("wxFlexGridSizer"))) ||
115 (IsOfClass(node
, wxT("wxGridBagSizer")));
119 wxObject
* wxSizerXmlHandler::Handle_sizeritem()
121 // find the item to be managed by this sizeritem
122 wxXmlNode
*n
= GetParamNode(wxT("object"));
124 n
= GetParamNode(wxT("object_ref"));
129 // create a sizer item for it
130 wxSizerItem
* sitem
= MakeSizerItem();
132 // now fetch the item to be managed
133 bool old_gbs
= m_isGBS
;
134 bool old_ins
= m_isInside
;
135 wxSizer
*old_par
= m_parentSizer
;
137 if (!IsSizerNode(n
)) m_parentSizer
= NULL
;
138 wxObject
*item
= CreateResFromNode(n
, m_parent
, NULL
);
139 m_isInside
= old_ins
;
140 m_parentSizer
= old_par
;
143 // and figure out what type it is
144 wxSizer
*sizer
= wxDynamicCast(item
, wxSizer
);
145 wxWindow
*wnd
= wxDynamicCast(item
, wxWindow
);
148 sitem
->SetSizer(sizer
);
150 sitem
->SetWindow(wnd
);
152 wxLogError(wxT("Error in resource."));
154 // finally, set other wxSizerItem attributes
155 SetSizerItemAttributes(sitem
);
162 wxLogError(wxT("Error in resource: no window/sizer/spacer within sizeritem object."));
168 wxObject
* wxSizerXmlHandler::Handle_spacer()
170 wxCHECK_MSG(m_parentSizer
, NULL
, wxT("Incorrect syntax of XRC resource: spacer not within sizer!"));
172 wxSizerItem
* sitem
= MakeSizerItem();
173 SetSizerItemAttributes(sitem
);
174 sitem
->SetSpacer(GetSize());
180 wxObject
* wxSizerXmlHandler::Handle_sizer()
182 wxSizer
*sizer
= NULL
;
184 wxXmlNode
*parentNode
= m_node
->GetParent();
186 wxCHECK_MSG(m_parentSizer
!= NULL
||
187 (parentNode
&& parentNode
->GetType() == wxXML_ELEMENT_NODE
&&
188 m_parentAsWindow
!= NULL
&&
189 (m_parentAsWindow
->IsKindOf(CLASSINFO(wxPanel
)) ||
190 m_parentAsWindow
->IsKindOf(CLASSINFO(wxFrame
)) ||
191 m_parentAsWindow
->IsKindOf(CLASSINFO(wxDialog
)))
193 wxT("Incorrect use of sizer: parent is not 'wxDialog', 'wxFrame' or 'wxPanel'."));
195 if (m_class
== wxT("wxBoxSizer"))
196 sizer
= Handle_wxBoxSizer();
198 else if (m_class
== wxT("wxStaticBoxSizer"))
199 sizer
= Handle_wxStaticBoxSizer();
201 else if (m_class
== wxT("wxGridSizer"))
202 sizer
= Handle_wxGridSizer();
204 else if (m_class
== wxT("wxFlexGridSizer"))
205 sizer
= Handle_wxFlexGridSizer();
207 else if (m_class
== wxT("wxGridBagSizer"))
208 sizer
= Handle_wxGridBagSizer();
212 wxLogError(_T("Failed to create size of class \"%s\""), m_class
.c_str());
216 wxSize minsize
= GetSize(wxT("minsize"));
217 if (!(minsize
== wxDefaultSize
))
218 sizer
->SetMinSize(minsize
);
221 wxSizer
*old_par
= m_parentSizer
;
222 bool old_ins
= m_isInside
;
225 m_parentSizer
= sizer
;
227 m_isGBS
= (m_class
== wxT("wxGridBagSizer"));
229 CreateChildren(m_parent
, true/*only this handler*/);
232 m_isInside
= old_ins
;
233 m_parentSizer
= old_par
;
235 if (m_parentSizer
== NULL
) // setup window:
237 m_parentAsWindow
->SetSizer(sizer
);
239 wxXmlNode
*nd
= m_node
;
241 if (GetSize() == wxDefaultSize
)
242 sizer
->Fit(m_parentAsWindow
);
245 if (m_parentAsWindow
->GetWindowStyle() & (wxMAXIMIZE_BOX
| wxRESIZE_BORDER
))
246 sizer
->SetSizeHints(m_parentAsWindow
);
253 wxSizer
* wxSizerXmlHandler::Handle_wxBoxSizer()
255 return new wxBoxSizer(GetStyle(wxT("orient"), wxHORIZONTAL
));
258 wxSizer
* wxSizerXmlHandler::Handle_wxStaticBoxSizer()
260 return new wxStaticBoxSizer(
261 new wxStaticBox(m_parentAsWindow
,
263 GetText(wxT("label")),
264 wxDefaultPosition
, wxDefaultSize
,
267 GetStyle(wxT("orient"), wxHORIZONTAL
));
270 wxSizer
* wxSizerXmlHandler::Handle_wxGridSizer()
272 return new wxGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
273 GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
277 wxSizer
* wxSizerXmlHandler::Handle_wxFlexGridSizer()
279 wxFlexGridSizer
*sizer
=
280 new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
281 GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
282 SetGrowables(sizer
, wxT("growablerows"), true);
283 SetGrowables(sizer
, wxT("growablecols"), false);
288 wxSizer
* wxSizerXmlHandler::Handle_wxGridBagSizer()
290 wxGridBagSizer
*sizer
=
291 new wxGridBagSizer(GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
292 SetGrowables(sizer
, wxT("growablerows"), true);
293 SetGrowables(sizer
, wxT("growablecols"), false);
300 void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer
* sizer
,
304 wxStringTokenizer tkn
;
306 tkn
.SetString(GetParamValue(param
), wxT(","));
307 while (tkn
.HasMoreTokens())
309 if (!tkn
.GetNextToken().ToULong(&l
))
310 wxLogError(wxT("growable[rows|cols] must be comma-separated list of row numbers"));
313 sizer
->AddGrowableRow(l
);
315 sizer
->AddGrowableCol(l
);
321 wxGBPosition
wxSizerXmlHandler::GetGBPos(const wxString
& param
)
323 wxSize sz
= GetSize(param
);
324 if (sz
.x
< 0) sz
.x
= 0;
325 if (sz
.y
< 0) sz
.y
= 0;
326 return wxGBPosition(sz
.x
, sz
.y
);
329 wxGBSpan
wxSizerXmlHandler::GetGBSpan(const wxString
& param
)
331 wxSize sz
= GetSize(param
);
332 if (sz
.x
< 1) sz
.x
= 1;
333 if (sz
.y
< 1) sz
.y
= 1;
334 return wxGBSpan(sz
.x
, sz
.y
);
339 wxSizerItem
* wxSizerXmlHandler::MakeSizerItem()
342 return new wxGBSizerItem();
344 return new wxSizerItem();
347 void wxSizerXmlHandler::SetSizerItemAttributes(wxSizerItem
* sitem
)
349 sitem
->SetProportion(GetLong(wxT("option"))); // Should this check for "proportion" too?
350 sitem
->SetFlag(GetStyle(wxT("flag")));
351 sitem
->SetBorder(GetDimension(wxT("border")));
352 wxSize sz
= GetSize(wxT("minsize"));
353 if (!(sz
== wxDefaultSize
))
354 sitem
->SetMinSize(sz
);
355 sz
= GetSize(wxT("ratio"));
356 if (!(sz
== wxDefaultSize
))
361 wxGBSizerItem
* gbsitem
= (wxGBSizerItem
*)sitem
;
362 gbsitem
->SetPos(GetGBPos(wxT("cellpos")));
363 gbsitem
->SetSpan(GetGBSpan(wxT("cellspan")));
367 void wxSizerXmlHandler::AddSizerItem(wxSizerItem
* sitem
)
370 ((wxGridBagSizer
*)m_parentSizer
)->Add((wxGBSizerItem
*)sitem
);
372 m_parentSizer
->Add(sitem
);
377 //-----------------------------------------------------------------------------
378 // wxStdDialogButtonSizerXmlHandler
379 //-----------------------------------------------------------------------------
381 IMPLEMENT_DYNAMIC_CLASS(wxStdDialogButtonSizerXmlHandler
, wxXmlResourceHandler
)
383 wxStdDialogButtonSizerXmlHandler::wxStdDialogButtonSizerXmlHandler()
384 : m_isInside(false), m_parentSizer(NULL
)
388 wxObject
*wxStdDialogButtonSizerXmlHandler::DoCreateResource()
390 if (m_class
== wxT("wxStdDialogButtonSizer"))
392 wxASSERT( !m_parentSizer
);
394 wxSizer
*s
= m_parentSizer
= new wxStdDialogButtonSizer
;
397 CreateChildren(m_parent
, true/*only this handler*/);
399 m_parentSizer
->Realize();
402 m_parentSizer
= NULL
;
406 else // m_class == "button"
408 wxASSERT( m_parentSizer
);
410 // find the item to be managed by this sizeritem
411 wxXmlNode
*n
= GetParamNode(wxT("object"));
413 n
= GetParamNode(wxT("object_ref"));
418 wxObject
*item
= CreateResFromNode(n
, m_parent
, NULL
);
419 wxButton
*button
= wxDynamicCast(item
, wxButton
);
422 m_parentSizer
->AddButton(button
);
424 wxLogError(wxT("Error in resource - expected button."));
430 wxLogError(wxT("Error in resource: no button within wxStdDialogButtonSizer."));
436 bool wxStdDialogButtonSizerXmlHandler::CanHandle(wxXmlNode
*node
)
438 return (!m_isInside
&& IsOfClass(node
, wxT("wxStdDialogButtonSizer"))) ||
439 (m_isInside
&& IsOfClass(node
, wxT("button")));