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