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