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"
30 #include "wx/scrolwin.h"
33 #include "wx/gbsizer.h"
34 #include "wx/wrapsizer.h"
35 #include "wx/notebook.h"
36 #include "wx/tokenzr.h"
39 //-----------------------------------------------------------------------------
41 //-----------------------------------------------------------------------------
43 IMPLEMENT_DYNAMIC_CLASS(wxSizerXmlHandler
, wxXmlResourceHandler
)
45 wxSizerXmlHandler::wxSizerXmlHandler()
46 :wxXmlResourceHandler(),
51 XRC_ADD_STYLE(wxHORIZONTAL
);
52 XRC_ADD_STYLE(wxVERTICAL
);
55 XRC_ADD_STYLE(wxLEFT
);
56 XRC_ADD_STYLE(wxRIGHT
);
58 XRC_ADD_STYLE(wxBOTTOM
);
59 XRC_ADD_STYLE(wxNORTH
);
60 XRC_ADD_STYLE(wxSOUTH
);
61 XRC_ADD_STYLE(wxEAST
);
62 XRC_ADD_STYLE(wxWEST
);
65 XRC_ADD_STYLE(wxGROW
);
66 XRC_ADD_STYLE(wxEXPAND
);
67 XRC_ADD_STYLE(wxSHAPED
);
68 XRC_ADD_STYLE(wxSTRETCH_NOT
);
70 XRC_ADD_STYLE(wxALIGN_CENTER
);
71 XRC_ADD_STYLE(wxALIGN_CENTRE
);
72 XRC_ADD_STYLE(wxALIGN_LEFT
);
73 XRC_ADD_STYLE(wxALIGN_TOP
);
74 XRC_ADD_STYLE(wxALIGN_RIGHT
);
75 XRC_ADD_STYLE(wxALIGN_BOTTOM
);
76 XRC_ADD_STYLE(wxALIGN_CENTER_HORIZONTAL
);
77 XRC_ADD_STYLE(wxALIGN_CENTRE_HORIZONTAL
);
78 XRC_ADD_STYLE(wxALIGN_CENTER_VERTICAL
);
79 XRC_ADD_STYLE(wxALIGN_CENTRE_VERTICAL
);
81 XRC_ADD_STYLE(wxFIXED_MINSIZE
);
82 XRC_ADD_STYLE(wxRESERVE_SPACE_EVEN_IF_HIDDEN
);
84 // wxWrapSizer-specific flags
85 XRC_ADD_STYLE(wxEXTEND_LAST_ON_EACH_LINE
);
86 XRC_ADD_STYLE(wxREMOVE_LEADING_SPACES
);
91 bool wxSizerXmlHandler::CanHandle(wxXmlNode
*node
)
93 return ( (!m_isInside
&& IsSizerNode(node
)) ||
94 (m_isInside
&& IsOfClass(node
, wxT("sizeritem"))) ||
95 (m_isInside
&& IsOfClass(node
, wxT("spacer")))
100 wxObject
* wxSizerXmlHandler::DoCreateResource()
102 if (m_class
== wxT("sizeritem"))
103 return Handle_sizeritem();
105 else if (m_class
== wxT("spacer"))
106 return Handle_spacer();
109 return Handle_sizer();
115 bool wxSizerXmlHandler::IsSizerNode(wxXmlNode
*node
)
117 return (IsOfClass(node
, wxT("wxBoxSizer"))) ||
118 (IsOfClass(node
, wxT("wxStaticBoxSizer"))) ||
119 (IsOfClass(node
, wxT("wxGridSizer"))) ||
120 (IsOfClass(node
, wxT("wxFlexGridSizer"))) ||
121 (IsOfClass(node
, wxT("wxGridBagSizer"))) ||
122 (IsOfClass(node
, wxT("wxWrapSizer")));
126 wxObject
* wxSizerXmlHandler::Handle_sizeritem()
128 // find the item to be managed by this sizeritem
129 wxXmlNode
*n
= GetParamNode(wxT("object"));
131 n
= GetParamNode(wxT("object_ref"));
136 // create a sizer item for it
137 wxSizerItem
* sitem
= MakeSizerItem();
139 // now fetch the item to be managed
140 bool old_gbs
= m_isGBS
;
141 bool old_ins
= m_isInside
;
142 wxSizer
*old_par
= m_parentSizer
;
144 if (!IsSizerNode(n
)) m_parentSizer
= NULL
;
145 wxObject
*item
= CreateResFromNode(n
, m_parent
, NULL
);
146 m_isInside
= old_ins
;
147 m_parentSizer
= old_par
;
150 // and figure out what type it is
151 wxSizer
*sizer
= wxDynamicCast(item
, wxSizer
);
152 wxWindow
*wnd
= wxDynamicCast(item
, wxWindow
);
155 sitem
->AssignSizer(sizer
);
157 sitem
->AssignWindow(wnd
);
159 wxLogError(wxT("Error in resource."));
161 // finally, set other wxSizerItem attributes
162 SetSizerItemAttributes(sitem
);
169 wxLogError(wxT("Error in resource: no window/sizer/spacer within sizeritem object."));
175 wxObject
* wxSizerXmlHandler::Handle_spacer()
177 wxCHECK_MSG(m_parentSizer
, NULL
, wxT("Incorrect syntax of XRC resource: spacer not within sizer!"));
179 wxSizerItem
* sitem
= MakeSizerItem();
180 SetSizerItemAttributes(sitem
);
181 sitem
->AssignSpacer(GetSize());
187 wxObject
* wxSizerXmlHandler::Handle_sizer()
189 wxSizer
*sizer
= NULL
;
191 wxXmlNode
*parentNode
= m_node
->GetParent();
193 wxCHECK_MSG(m_parentSizer
!= NULL
||
194 (parentNode
&& parentNode
->GetType() == wxXML_ELEMENT_NODE
&&
195 m_parentAsWindow
), NULL
,
196 wxT("Sizer must have a window parent node"));
198 if (m_class
== wxT("wxBoxSizer"))
199 sizer
= Handle_wxBoxSizer();
202 else if (m_class
== wxT("wxStaticBoxSizer"))
203 sizer
= Handle_wxStaticBoxSizer();
206 else if (m_class
== wxT("wxGridSizer"))
207 sizer
= Handle_wxGridSizer();
209 else if (m_class
== wxT("wxFlexGridSizer"))
210 sizer
= Handle_wxFlexGridSizer();
212 else if (m_class
== wxT("wxGridBagSizer"))
213 sizer
= Handle_wxGridBagSizer();
215 else if (m_class
== wxT("wxWrapSizer"))
216 sizer
= Handle_wxWrapSizer();
220 wxLogError(_T("Failed to create size of class \"%s\""), m_class
.c_str());
224 wxSize minsize
= GetSize(wxT("minsize"));
225 if (!(minsize
== wxDefaultSize
))
226 sizer
->SetMinSize(minsize
);
229 wxSizer
*old_par
= m_parentSizer
;
230 bool old_ins
= m_isInside
;
233 m_parentSizer
= sizer
;
235 m_isGBS
= (m_class
== wxT("wxGridBagSizer"));
237 CreateChildren(m_parent
, true/*only this handler*/);
240 m_isInside
= old_ins
;
241 m_parentSizer
= old_par
;
243 if (m_parentSizer
== NULL
) // setup window:
245 m_parentAsWindow
->SetSizer(sizer
);
247 wxXmlNode
*nd
= m_node
;
249 if (GetSize() == wxDefaultSize
)
251 if ( wxDynamicCast(m_parentAsWindow
, wxScrolledWindow
) != NULL
)
253 sizer
->FitInside(m_parentAsWindow
);
257 sizer
->Fit(m_parentAsWindow
);
262 if (m_parentAsWindow
->IsTopLevel())
264 sizer
->SetSizeHints(m_parentAsWindow
);
272 wxSizer
* wxSizerXmlHandler::Handle_wxBoxSizer()
274 return new wxBoxSizer(GetStyle(wxT("orient"), wxHORIZONTAL
));
278 wxSizer
* wxSizerXmlHandler::Handle_wxStaticBoxSizer()
280 return new wxStaticBoxSizer(
281 new wxStaticBox(m_parentAsWindow
,
283 GetText(wxT("label")),
284 wxDefaultPosition
, wxDefaultSize
,
287 GetStyle(wxT("orient"), wxHORIZONTAL
));
289 #endif // wxUSE_STATBOX
291 wxSizer
* wxSizerXmlHandler::Handle_wxGridSizer()
293 return new wxGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
294 GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
298 wxSizer
* wxSizerXmlHandler::Handle_wxFlexGridSizer()
300 wxFlexGridSizer
*sizer
=
301 new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
302 GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
303 SetGrowables(sizer
, wxT("growablerows"), true);
304 SetGrowables(sizer
, wxT("growablecols"), false);
309 wxSizer
* wxSizerXmlHandler::Handle_wxGridBagSizer()
311 wxGridBagSizer
*sizer
=
312 new wxGridBagSizer(GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
313 SetGrowables(sizer
, wxT("growablerows"), true);
314 SetGrowables(sizer
, wxT("growablecols"), false);
318 wxSizer
* wxSizerXmlHandler::Handle_wxWrapSizer()
320 wxWrapSizer
*sizer
= new wxWrapSizer(GetStyle("orient"), GetStyle("flag"));
326 void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer
* sizer
,
330 wxStringTokenizer tkn
;
332 tkn
.SetString(GetParamValue(param
), wxT(","));
333 while (tkn
.HasMoreTokens())
335 if (!tkn
.GetNextToken().ToULong(&l
))
336 wxLogError(wxT("growable[rows|cols] must be comma-separated list of row numbers"));
339 sizer
->AddGrowableRow(l
);
341 sizer
->AddGrowableCol(l
);
347 wxGBPosition
wxSizerXmlHandler::GetGBPos(const wxString
& param
)
349 wxSize sz
= GetSize(param
);
350 if (sz
.x
< 0) sz
.x
= 0;
351 if (sz
.y
< 0) sz
.y
= 0;
352 return wxGBPosition(sz
.x
, sz
.y
);
355 wxGBSpan
wxSizerXmlHandler::GetGBSpan(const wxString
& param
)
357 wxSize sz
= GetSize(param
);
358 if (sz
.x
< 1) sz
.x
= 1;
359 if (sz
.y
< 1) sz
.y
= 1;
360 return wxGBSpan(sz
.x
, sz
.y
);
365 wxSizerItem
* wxSizerXmlHandler::MakeSizerItem()
368 return new wxGBSizerItem();
370 return new wxSizerItem();
373 void wxSizerXmlHandler::SetSizerItemAttributes(wxSizerItem
* sitem
)
375 sitem
->SetProportion(GetLong(wxT("option"))); // Should this check for "proportion" too?
376 sitem
->SetFlag(GetStyle(wxT("flag")));
377 sitem
->SetBorder(GetDimension(wxT("border")));
378 wxSize sz
= GetSize(wxT("minsize"));
379 if (!(sz
== wxDefaultSize
))
380 sitem
->SetMinSize(sz
);
381 sz
= GetSize(wxT("ratio"));
382 if (!(sz
== wxDefaultSize
))
387 wxGBSizerItem
* gbsitem
= (wxGBSizerItem
*)sitem
;
388 gbsitem
->SetPos(GetGBPos(wxT("cellpos")));
389 gbsitem
->SetSpan(GetGBSpan(wxT("cellspan")));
392 // record the id of the item, if any, for use by XRCSIZERITEM()
393 sitem
->SetId(GetID());
396 void wxSizerXmlHandler::AddSizerItem(wxSizerItem
* sitem
)
399 ((wxGridBagSizer
*)m_parentSizer
)->Add((wxGBSizerItem
*)sitem
);
401 m_parentSizer
->Add(sitem
);
406 //-----------------------------------------------------------------------------
407 // wxStdDialogButtonSizerXmlHandler
408 //-----------------------------------------------------------------------------
411 IMPLEMENT_DYNAMIC_CLASS(wxStdDialogButtonSizerXmlHandler
, wxXmlResourceHandler
)
413 wxStdDialogButtonSizerXmlHandler::wxStdDialogButtonSizerXmlHandler()
414 : m_isInside(false), m_parentSizer(NULL
)
418 wxObject
*wxStdDialogButtonSizerXmlHandler::DoCreateResource()
420 if (m_class
== wxT("wxStdDialogButtonSizer"))
422 wxASSERT( !m_parentSizer
);
424 wxSizer
*s
= m_parentSizer
= new wxStdDialogButtonSizer
;
427 CreateChildren(m_parent
, true/*only this handler*/);
429 m_parentSizer
->Realize();
432 m_parentSizer
= NULL
;
436 else // m_class == "button"
438 wxASSERT( m_parentSizer
);
440 // find the item to be managed by this sizeritem
441 wxXmlNode
*n
= GetParamNode(wxT("object"));
443 n
= GetParamNode(wxT("object_ref"));
448 wxObject
*item
= CreateResFromNode(n
, m_parent
, NULL
);
449 wxButton
*button
= wxDynamicCast(item
, wxButton
);
452 m_parentSizer
->AddButton(button
);
454 wxLogError(wxT("Error in resource - expected button."));
460 wxLogError(wxT("Error in resource: no button within wxStdDialogButtonSizer."));
466 bool wxStdDialogButtonSizerXmlHandler::CanHandle(wxXmlNode
*node
)
468 return (!m_isInside
&& IsOfClass(node
, wxT("wxStdDialogButtonSizer"))) ||
469 (m_isInside
&& IsOfClass(node
, wxT("button")));
471 #endif // wxUSE_BUTTON