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