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