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" 
  29 #include "wx/gbsizer.h" 
  30 #include "wx/notebook.h" 
  31 #include "wx/tokenzr.h" 
  34 //----------------------------------------------------------------------------- 
  36 //----------------------------------------------------------------------------- 
  38 IMPLEMENT_DYNAMIC_CLASS(wxSizerXmlHandler
, wxXmlResourceHandler
) 
  40 wxSizerXmlHandler::wxSizerXmlHandler() 
  41     : wxXmlResourceHandler(), 
  46     XRC_ADD_STYLE(wxHORIZONTAL
); 
  47     XRC_ADD_STYLE(wxVERTICAL
); 
  50     XRC_ADD_STYLE(wxLEFT
); 
  51     XRC_ADD_STYLE(wxRIGHT
); 
  53     XRC_ADD_STYLE(wxBOTTOM
); 
  54     XRC_ADD_STYLE(wxNORTH
); 
  55     XRC_ADD_STYLE(wxSOUTH
); 
  56     XRC_ADD_STYLE(wxEAST
); 
  57     XRC_ADD_STYLE(wxWEST
); 
  60     XRC_ADD_STYLE(wxGROW
); 
  61     XRC_ADD_STYLE(wxEXPAND
); 
  62     XRC_ADD_STYLE(wxSHAPED
); 
  63     XRC_ADD_STYLE(wxSTRETCH_NOT
); 
  65     XRC_ADD_STYLE(wxALIGN_CENTER
); 
  66     XRC_ADD_STYLE(wxALIGN_CENTRE
); 
  67     XRC_ADD_STYLE(wxALIGN_LEFT
); 
  68     XRC_ADD_STYLE(wxALIGN_TOP
); 
  69     XRC_ADD_STYLE(wxALIGN_RIGHT
); 
  70     XRC_ADD_STYLE(wxALIGN_BOTTOM
); 
  71     XRC_ADD_STYLE(wxALIGN_CENTER_HORIZONTAL
); 
  72     XRC_ADD_STYLE(wxALIGN_CENTRE_HORIZONTAL
); 
  73     XRC_ADD_STYLE(wxALIGN_CENTER_VERTICAL
); 
  74     XRC_ADD_STYLE(wxALIGN_CENTRE_VERTICAL
); 
  76     XRC_ADD_STYLE(wxADJUST_MINSIZE
); 
  77     XRC_ADD_STYLE(wxFIXED_MINSIZE
); 
  82 bool wxSizerXmlHandler::CanHandle(wxXmlNode 
*node
) 
  84     return ( (!m_isInside 
&& IsSizerNode(node
)) || 
  85              (m_isInside 
&& IsOfClass(node
, wxT("sizeritem"))) || 
  86              (m_isInside 
&& IsOfClass(node
, wxT("spacer"))) 
  91 wxObject
* wxSizerXmlHandler::DoCreateResource() 
  93     if (m_class 
== wxT("sizeritem")) 
  94         return Handle_sizeritem(); 
  96     else if (m_class 
== wxT("spacer")) 
  97         return Handle_spacer(); 
 100         return Handle_sizer(); 
 106 bool wxSizerXmlHandler::IsSizerNode(wxXmlNode 
*node
) 
 108     return (IsOfClass(node
, wxT("wxBoxSizer"))) || 
 109            (IsOfClass(node
, wxT("wxStaticBoxSizer"))) || 
 110            (IsOfClass(node
, wxT("wxGridSizer"))) || 
 111            (IsOfClass(node
, wxT("wxFlexGridSizer"))) || 
 112            (IsOfClass(node
, wxT("wxGridBagSizer"))); 
 116 wxObject
* wxSizerXmlHandler::Handle_sizeritem() 
 118     // find the item to be managed by this sizeritem 
 119     wxXmlNode 
*n 
= GetParamNode(wxT("object")); 
 121         n 
= GetParamNode(wxT("object_ref")); 
 126         // create a sizer item for it 
 127         wxSizerItem
* sitem 
= MakeSizerItem(); 
 129         // now fetch the item to be managed 
 130         bool old_gbs 
= m_isGBS
; 
 131         bool old_ins 
= m_isInside
; 
 132         wxSizer 
*old_par 
= m_parentSizer
; 
 134         if (!IsSizerNode(n
)) m_parentSizer 
= NULL
; 
 135         wxObject 
*item 
= CreateResFromNode(n
, m_parent
, NULL
); 
 136         m_isInside 
= old_ins
; 
 137         m_parentSizer 
= old_par
; 
 140         // and figure out what type it is 
 141         wxSizer 
*sizer 
= wxDynamicCast(item
, wxSizer
); 
 142         wxWindow 
*wnd 
= wxDynamicCast(item
, wxWindow
); 
 145             sitem
->SetSizer(sizer
); 
 147             sitem
->SetWindow(wnd
); 
 149             wxLogError(wxT("Error in resource.")); 
 151         // finally, set other wxSizerItem attributes 
 152         SetSizerItemAttributes(sitem
); 
 159         wxLogError(wxT("Error in resource: no window/sizer/spacer within sizeritem object.")); 
 165 wxObject
* wxSizerXmlHandler::Handle_spacer() 
 167     wxCHECK_MSG(m_parentSizer
, NULL
, wxT("Incorrect syntax of XRC resource: spacer not within sizer!")); 
 169     wxSizerItem
* sitem 
= MakeSizerItem(); 
 170     SetSizerItemAttributes(sitem
); 
 171     sitem
->SetSpacer(GetSize()); 
 177 wxObject
* wxSizerXmlHandler::Handle_sizer() 
 179     wxSizer 
*sizer 
= NULL
; 
 181     wxXmlNode 
*parentNode 
= m_node
->GetParent(); 
 183     wxCHECK_MSG(m_parentSizer 
!= NULL 
|| 
 184                 (parentNode 
&& parentNode
->GetType() == wxXML_ELEMENT_NODE 
&& 
 185                  m_parentAsWindow 
!= NULL 
&& 
 186                  (m_parentAsWindow
->IsKindOf(CLASSINFO(wxPanel
)) || 
 187                   m_parentAsWindow
->IsKindOf(CLASSINFO(wxFrame
)) || 
 188                   m_parentAsWindow
->IsKindOf(CLASSINFO(wxDialog
))) 
 190                 wxT("Incorrect use of sizer: parent is not 'wxDialog', 'wxFrame' or 'wxPanel'.")); 
 192     if (m_class 
== wxT("wxBoxSizer")) 
 193         sizer 
= Handle_wxBoxSizer(); 
 195     else if (m_class 
== wxT("wxStaticBoxSizer")) 
 196         sizer 
= Handle_wxStaticBoxSizer(); 
 198     else if (m_class 
== wxT("wxGridSizer")) 
 199         sizer 
= Handle_wxGridSizer(); 
 201     else if (m_class 
== wxT("wxFlexGridSizer")) 
 202         sizer 
= Handle_wxFlexGridSizer(); 
 204     else if (m_class 
== wxT("wxGridBagSizer")) 
 205         sizer 
= Handle_wxGridBagSizer(); 
 209         wxLogError(_T("Failed to create size of class \"%s\""), m_class
.c_str()); 
 213     wxSize minsize 
= GetSize(wxT("minsize")); 
 214     if (!(minsize 
== wxDefaultSize
)) 
 215         sizer
->SetMinSize(minsize
); 
 218     wxSizer 
*old_par 
= m_parentSizer
; 
 219     bool old_ins 
= m_isInside
; 
 222     m_parentSizer 
= sizer
; 
 224     m_isGBS 
= (m_class 
== wxT("wxGridBagSizer")); 
 226     CreateChildren(m_parent
, true/*only this handler*/); 
 229     m_isInside 
= old_ins
; 
 230     m_parentSizer 
= old_par
; 
 232     if (m_parentSizer 
== NULL
) // setup window: 
 234         m_parentAsWindow
->SetSizer(sizer
); 
 236         wxXmlNode 
*nd 
= m_node
; 
 238         if (GetSize() == wxDefaultSize
) 
 239             sizer
->Fit(m_parentAsWindow
); 
 242         if (m_parentAsWindow
->GetWindowStyle() & (wxMAXIMIZE_BOX 
| wxRESIZE_BORDER
)) 
 243             sizer
->SetSizeHints(m_parentAsWindow
); 
 250 wxSizer
*  wxSizerXmlHandler::Handle_wxBoxSizer() 
 252     return new wxBoxSizer(GetStyle(wxT("orient"), wxHORIZONTAL
)); 
 255 wxSizer
*  wxSizerXmlHandler::Handle_wxStaticBoxSizer() 
 257     return new wxStaticBoxSizer( 
 258             new wxStaticBox(m_parentAsWindow
, 
 260                             GetText(wxT("label")), 
 261                             wxDefaultPosition
, wxDefaultSize
, 
 264             GetStyle(wxT("orient"), wxHORIZONTAL
)); 
 267 wxSizer
*  wxSizerXmlHandler::Handle_wxGridSizer() 
 269     return new wxGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")), 
 270                            GetDimension(wxT("vgap")), GetDimension(wxT("hgap"))); 
 274 wxSizer
*  wxSizerXmlHandler::Handle_wxFlexGridSizer() 
 276     wxFlexGridSizer 
*sizer 
= 
 277         new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")), 
 278                             GetDimension(wxT("vgap")), GetDimension(wxT("hgap"))); 
 279     SetGrowables(sizer
, wxT("growablerows"), true); 
 280     SetGrowables(sizer
, wxT("growablecols"), false); 
 285 wxSizer
*  wxSizerXmlHandler::Handle_wxGridBagSizer() 
 287     wxGridBagSizer 
*sizer 
= 
 288         new wxGridBagSizer(GetDimension(wxT("vgap")), GetDimension(wxT("hgap"))); 
 289     SetGrowables(sizer
, wxT("growablerows"), true); 
 290     SetGrowables(sizer
, wxT("growablecols"), false); 
 297 void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer
* sizer
, 
 301     wxStringTokenizer tkn
; 
 303     tkn
.SetString(GetParamValue(param
), wxT(",")); 
 304     while (tkn
.HasMoreTokens()) 
 306         if (!tkn
.GetNextToken().ToULong(&l
)) 
 307             wxLogError(wxT("growable[rows|cols] must be comma-separated list of row numbers")); 
 310                 sizer
->AddGrowableRow(l
); 
 312                 sizer
->AddGrowableCol(l
); 
 318 wxGBPosition 
wxSizerXmlHandler::GetGBPos(const wxString
& param
) 
 320     wxSize sz 
= GetSize(param
); 
 321     if (sz
.x 
< 0) sz
.x 
= 0; 
 322     if (sz
.y 
< 0) sz
.y 
= 0; 
 323     return wxGBPosition(sz
.x
, sz
.y
); 
 326 wxGBSpan 
wxSizerXmlHandler::GetGBSpan(const wxString
& param
) 
 328     wxSize sz 
= GetSize(param
); 
 329     if (sz
.x 
< 1) sz
.x 
= 1; 
 330     if (sz
.y 
< 1) sz
.y 
= 1; 
 331     return wxGBSpan(sz
.x
, sz
.y
); 
 336 wxSizerItem
* wxSizerXmlHandler::MakeSizerItem() 
 339         return new wxGBSizerItem(); 
 341         return new wxSizerItem(); 
 344 void wxSizerXmlHandler::SetSizerItemAttributes(wxSizerItem
* sitem
) 
 346     sitem
->SetProportion(GetLong(wxT("option")));  // Should this check for "proportion" too? 
 347     sitem
->SetFlag(GetStyle(wxT("flag"))); 
 348     sitem
->SetBorder(GetDimension(wxT("border"))); 
 349     wxSize sz 
= GetSize(wxT("minsize")); 
 350     if (!(sz 
== wxDefaultSize
)) 
 351         sitem
->SetMinSize(sz
); 
 352     sz 
= GetSize(wxT("ratio")); 
 353     if (!(sz 
== wxDefaultSize
)) 
 358         wxGBSizerItem
* gbsitem 
= (wxGBSizerItem
*)sitem
; 
 359         gbsitem
->SetPos(GetGBPos(wxT("cellpos"))); 
 360         gbsitem
->SetSpan(GetGBSpan(wxT("cellspan"))); 
 364 void wxSizerXmlHandler::AddSizerItem(wxSizerItem
* sitem
) 
 367         ((wxGridBagSizer
*)m_parentSizer
)->Add((wxGBSizerItem
*)sitem
); 
 369         m_parentSizer
->Add(sitem
); 
 374 //----------------------------------------------------------------------------- 
 375 // wxStdDialogButtonSizerXmlHandler 
 376 //----------------------------------------------------------------------------- 
 378 IMPLEMENT_DYNAMIC_CLASS(wxStdDialogButtonSizerXmlHandler
, wxXmlResourceHandler
) 
 380 wxStdDialogButtonSizerXmlHandler::wxStdDialogButtonSizerXmlHandler() 
 381     : m_isInside(false), m_parentSizer(NULL
) 
 385 wxObject 
*wxStdDialogButtonSizerXmlHandler::DoCreateResource() 
 387     if (m_class 
== wxT("wxStdDialogButtonSizer")) 
 389         wxASSERT( !m_parentSizer 
); 
 391         wxSizer 
*s 
= m_parentSizer 
= new wxStdDialogButtonSizer
; 
 394         CreateChildren(m_parent
, true/*only this handler*/); 
 396         m_parentSizer
->Realize(); 
 399         m_parentSizer 
= NULL
; 
 403     else // m_class == "button" 
 405         wxASSERT( m_parentSizer 
); 
 407         // find the item to be managed by this sizeritem 
 408         wxXmlNode 
*n 
= GetParamNode(wxT("object")); 
 410             n 
= GetParamNode(wxT("object_ref")); 
 415             wxObject 
*item 
= CreateResFromNode(n
, m_parent
, NULL
); 
 416             wxButton 
*button 
= wxDynamicCast(item
, wxButton
); 
 419                 m_parentSizer
->AddButton(button
); 
 421                 wxLogError(wxT("Error in resource - expected button.")); 
 427             wxLogError(wxT("Error in resource: no button within wxStdDialogButtonSizer.")); 
 433 bool wxStdDialogButtonSizerXmlHandler::CanHandle(wxXmlNode 
*node
) 
 435     return (!m_isInside 
&& IsOfClass(node
, wxT("wxStdDialogButtonSizer"))) || 
 436            (m_isInside 
&& IsOfClass(node
, wxT("button")));