]> git.saurik.com Git - wxWidgets.git/blame - src/xrc/xh_sizer.cpp
added back 2 extra pixels for the best size under XP
[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"
e4db172a
WS
27#endif
28
0d077b41 29#include "wx/gbsizer.h"
78d14f80
VS
30#include "wx/notebook.h"
31#include "wx/tokenzr.h"
32
78d14f80 33
172541f6
VS
34//-----------------------------------------------------------------------------
35// wxSizerXmlHandler
36//-----------------------------------------------------------------------------
78d14f80 37
0d077b41 38IMPLEMENT_DYNAMIC_CLASS(wxSizerXmlHandler, wxXmlResourceHandler)
78d14f80 39
f80ea77b 40wxSizerXmlHandler::wxSizerXmlHandler()
ed2fbeb8
WS
41 :wxXmlResourceHandler(),
42 m_isInside(false),
43 m_isGBS(false),
44 m_parentSizer(NULL)
78d14f80 45{
544fee32
VS
46 XRC_ADD_STYLE(wxHORIZONTAL);
47 XRC_ADD_STYLE(wxVERTICAL);
78d14f80
VS
48
49 // and flags
544fee32
VS
50 XRC_ADD_STYLE(wxLEFT);
51 XRC_ADD_STYLE(wxRIGHT);
52 XRC_ADD_STYLE(wxTOP);
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);
58 XRC_ADD_STYLE(wxALL);
78d14f80 59
544fee32
VS
60 XRC_ADD_STYLE(wxGROW);
61 XRC_ADD_STYLE(wxEXPAND);
62 XRC_ADD_STYLE(wxSHAPED);
63 XRC_ADD_STYLE(wxSTRETCH_NOT);
78d14f80 64
544fee32
VS
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);
f80ea77b 75
a02376c8 76 XRC_ADD_STYLE(wxADJUST_MINSIZE);
c66b63e5 77 XRC_ADD_STYLE(wxFIXED_MINSIZE);
78d14f80
VS
78}
79
80
81
0d077b41
RD
82bool wxSizerXmlHandler::CanHandle(wxXmlNode *node)
83{
84 return ( (!m_isInside && IsSizerNode(node)) ||
85 (m_isInside && IsOfClass(node, wxT("sizeritem"))) ||
f80ea77b 86 (m_isInside && IsOfClass(node, wxT("spacer")))
0d077b41
RD
87 );
88}
89
f80ea77b 90
0d077b41 91wxObject* wxSizerXmlHandler::DoCreateResource()
f80ea77b 92{
78d14f80 93 if (m_class == wxT("sizeritem"))
0d077b41 94 return Handle_sizeritem();
f80ea77b 95
78d14f80 96 else if (m_class == wxT("spacer"))
0d077b41
RD
97 return Handle_spacer();
98
99 else
100 return Handle_sizer();
101}
102
103
104
105
106bool wxSizerXmlHandler::IsSizerNode(wxXmlNode *node)
107{
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")));
113}
114
115
116wxObject* wxSizerXmlHandler::Handle_sizeritem()
117{
118 // find the item to be managed by this sizeritem
119 wxXmlNode *n = GetParamNode(wxT("object"));
120 if ( !n )
121 n = GetParamNode(wxT("object_ref"));
122
123 // did we find one?
124 if (n)
125 {
126 // create a sizer item for it
127 wxSizerItem* sitem = MakeSizerItem();
f80ea77b 128
0d077b41
RD
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;
f80ea77b
WS
133 m_isInside = false;
134 if (!IsSizerNode(n)) m_parentSizer = NULL;
0d077b41
RD
135 wxObject *item = CreateResFromNode(n, m_parent, NULL);
136 m_isInside = old_ins;
137 m_parentSizer = old_par;
138 m_isGBS = old_gbs;
139
140 // and figure out what type it is
141 wxSizer *sizer = wxDynamicCast(item, wxSizer);
142 wxWindow *wnd = wxDynamicCast(item, wxWindow);
f80ea77b 143
0d077b41
RD
144 if (sizer)
145 sitem->SetSizer(sizer);
146 else if (wnd)
147 sitem->SetWindow(wnd);
f80ea77b 148 else
0d077b41
RD
149 wxLogError(wxT("Error in resource."));
150
1eba2193
RD
151 // finally, set other wxSizerItem attributes
152 SetSizerItemAttributes(sitem);
153
0d077b41
RD
154 AddSizerItem(sitem);
155 return item;
156 }
157 else /*n == NULL*/
78d14f80 158 {
0d077b41 159 wxLogError(wxT("Error in resource: no window/sizer/spacer within sizeritem object."));
78d14f80
VS
160 return NULL;
161 }
0d077b41
RD
162}
163
164
165wxObject* wxSizerXmlHandler::Handle_spacer()
166{
167 wxCHECK_MSG(m_parentSizer, NULL, wxT("Incorrect syntax of XRC resource: spacer not within sizer!"));
168
169 wxSizerItem* sitem = MakeSizerItem();
170 SetSizerItemAttributes(sitem);
171 sitem->SetSpacer(GetSize());
f80ea77b 172 AddSizerItem(sitem);
0d077b41
RD
173 return NULL;
174}
175
78d14f80 176
0d077b41
RD
177wxObject* wxSizerXmlHandler::Handle_sizer()
178{
179 wxSizer *sizer = NULL;
f80ea77b 180
0d077b41 181 wxXmlNode *parentNode = m_node->GetParent();
78d14f80 182
0d077b41 183 wxCHECK_MSG(m_parentSizer != NULL ||
0a904ad4 184 (parentNode && parentNode->GetType() == wxXML_ELEMENT_NODE &&
0d077b41
RD
185 m_parentAsWindow != NULL &&
186 (m_parentAsWindow->IsKindOf(CLASSINFO(wxPanel)) ||
187 m_parentAsWindow->IsKindOf(CLASSINFO(wxFrame)) ||
188 m_parentAsWindow->IsKindOf(CLASSINFO(wxDialog)))
189 ), NULL,
5dff4e24 190 wxT("Incorrect use of sizer: parent is not 'wxDialog', 'wxFrame' or 'wxPanel'."));
78d14f80 191
0d077b41
RD
192 if (m_class == wxT("wxBoxSizer"))
193 sizer = Handle_wxBoxSizer();
194
195 else if (m_class == wxT("wxStaticBoxSizer"))
196 sizer = Handle_wxStaticBoxSizer();
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
0d077b41
RD
255wxSizer* wxSizerXmlHandler::Handle_wxStaticBoxSizer()
256{
257 return new wxStaticBoxSizer(
258 new wxStaticBox(m_parentAsWindow,
259 GetID(),
260 GetText(wxT("label")),
261 wxDefaultPosition, wxDefaultSize,
262 0/*style*/,
263 GetName()),
264 GetStyle(wxT("orient"), wxHORIZONTAL));
265}
f80ea77b 266
0d077b41
RD
267wxSizer* wxSizerXmlHandler::Handle_wxGridSizer()
268{
269 return new wxGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
270 GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
271}
272
273
274wxSizer* wxSizerXmlHandler::Handle_wxFlexGridSizer()
275{
f80ea77b 276 wxFlexGridSizer *sizer =
0d077b41
RD
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);
281 return sizer;
282}
283
284
285wxSizer* wxSizerXmlHandler::Handle_wxGridBagSizer()
286{
f80ea77b 287 wxGridBagSizer *sizer =
0d077b41
RD
288 new wxGridBagSizer(GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
289 SetGrowables(sizer, wxT("growablerows"), true);
290 SetGrowables(sizer, wxT("growablecols"), false);
291 return sizer;
292}
293
294
295
296
297void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer* sizer,
298 const wxChar* param,
299 bool rows)
300{
301 wxStringTokenizer tkn;
302 unsigned long l;
303 tkn.SetString(GetParamValue(param), wxT(","));
304 while (tkn.HasMoreTokens())
305 {
306 if (!tkn.GetNextToken().ToULong(&l))
307 wxLogError(wxT("growable[rows|cols] must be comma-separated list of row numbers"));
308 else {
309 if (rows)
310 sizer->AddGrowableRow(l);
311 else
312 sizer->AddGrowableCol(l);
78d14f80 313 }
78d14f80
VS
314 }
315}
316
317
0d077b41
RD
318wxGBPosition wxSizerXmlHandler::GetGBPos(const wxString& param)
319{
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);
324}
78d14f80 325
0d077b41
RD
326wxGBSpan wxSizerXmlHandler::GetGBSpan(const wxString& param)
327{
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);
332}
333
334
335
336wxSizerItem* wxSizerXmlHandler::MakeSizerItem()
337{
338 if (m_isGBS)
339 return new wxGBSizerItem();
340 else
341 return new wxSizerItem();
342}
343
344void wxSizerXmlHandler::SetSizerItemAttributes(wxSizerItem* sitem)
345{
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))
1eba2193 351 sitem->SetMinSize(sz);
0d077b41
RD
352 sz = GetSize(wxT("ratio"));
353 if (!(sz == wxDefaultSize))
354 sitem->SetRatio(sz);
f80ea77b 355
0d077b41
RD
356 if (m_isGBS)
357 {
358 wxGBSizerItem* gbsitem = (wxGBSizerItem*)sitem;
ea0d8ca6
RD
359 gbsitem->SetPos(GetGBPos(wxT("cellpos")));
360 gbsitem->SetSpan(GetGBSpan(wxT("cellspan")));
f80ea77b 361 }
0d077b41
RD
362}
363
364void wxSizerXmlHandler::AddSizerItem(wxSizerItem* sitem)
78d14f80 365{
0d077b41
RD
366 if (m_isGBS)
367 ((wxGridBagSizer*)m_parentSizer)->Add((wxGBSizerItem*)sitem);
368 else
369 m_parentSizer->Add(sitem);
78d14f80 370}
f80ea77b 371
172541f6
VS
372
373
374//-----------------------------------------------------------------------------
375// wxStdDialogButtonSizerXmlHandler
376//-----------------------------------------------------------------------------
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}
438
621be1ec 439#endif // wxUSE_XRC