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