]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/xrc/xh_sizer.cpp
add ms78 projects
[wxWidgets.git] / src / xrc / xh_sizer.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/xrc/xh_sizer.cpp
3// Purpose: XRC resource for wxBoxSizer
4// Author: Vaclav Slavik
5// Created: 2000/03/21
6// RCS-ID: $Id$
7// Copyright: (c) 2000 Vaclav Slavik
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
18#if wxUSE_XRC
19
20#include "wx/xrc/xh_sizer.h"
21
22#ifndef WX_PRECOMP
23 #include "wx/log.h"
24 #include "wx/panel.h"
25 #include "wx/statbox.h"
26 #include "wx/sizer.h"
27 #include "wx/frame.h"
28 #include "wx/dialog.h"
29 #include "wx/button.h"
30 #include "wx/scrolwin.h"
31#endif
32
33#include "wx/gbsizer.h"
34#include "wx/notebook.h"
35#include "wx/tokenzr.h"
36
37
38//-----------------------------------------------------------------------------
39// wxSizerXmlHandler
40//-----------------------------------------------------------------------------
41
42IMPLEMENT_DYNAMIC_CLASS(wxSizerXmlHandler, wxXmlResourceHandler)
43
44wxSizerXmlHandler::wxSizerXmlHandler()
45 :wxXmlResourceHandler(),
46 m_isInside(false),
47 m_isGBS(false),
48 m_parentSizer(NULL)
49{
50 XRC_ADD_STYLE(wxHORIZONTAL);
51 XRC_ADD_STYLE(wxVERTICAL);
52
53 // and flags
54 XRC_ADD_STYLE(wxLEFT);
55 XRC_ADD_STYLE(wxRIGHT);
56 XRC_ADD_STYLE(wxTOP);
57 XRC_ADD_STYLE(wxBOTTOM);
58 XRC_ADD_STYLE(wxNORTH);
59 XRC_ADD_STYLE(wxSOUTH);
60 XRC_ADD_STYLE(wxEAST);
61 XRC_ADD_STYLE(wxWEST);
62 XRC_ADD_STYLE(wxALL);
63
64 XRC_ADD_STYLE(wxGROW);
65 XRC_ADD_STYLE(wxEXPAND);
66 XRC_ADD_STYLE(wxSHAPED);
67 XRC_ADD_STYLE(wxSTRETCH_NOT);
68
69 XRC_ADD_STYLE(wxALIGN_CENTER);
70 XRC_ADD_STYLE(wxALIGN_CENTRE);
71 XRC_ADD_STYLE(wxALIGN_LEFT);
72 XRC_ADD_STYLE(wxALIGN_TOP);
73 XRC_ADD_STYLE(wxALIGN_RIGHT);
74 XRC_ADD_STYLE(wxALIGN_BOTTOM);
75 XRC_ADD_STYLE(wxALIGN_CENTER_HORIZONTAL);
76 XRC_ADD_STYLE(wxALIGN_CENTRE_HORIZONTAL);
77 XRC_ADD_STYLE(wxALIGN_CENTER_VERTICAL);
78 XRC_ADD_STYLE(wxALIGN_CENTRE_VERTICAL);
79
80 XRC_ADD_STYLE(wxFIXED_MINSIZE);
81}
82
83
84
85bool wxSizerXmlHandler::CanHandle(wxXmlNode *node)
86{
87 return ( (!m_isInside && IsSizerNode(node)) ||
88 (m_isInside && IsOfClass(node, wxT("sizeritem"))) ||
89 (m_isInside && IsOfClass(node, wxT("spacer")))
90 );
91}
92
93
94wxObject* wxSizerXmlHandler::DoCreateResource()
95{
96 if (m_class == wxT("sizeritem"))
97 return Handle_sizeritem();
98
99 else if (m_class == wxT("spacer"))
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();
131
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;
136 m_isInside = false;
137 if (!IsSizerNode(n)) m_parentSizer = NULL;
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);
146
147 if (sizer)
148 sitem->AssignSizer(sizer);
149 else if (wnd)
150 sitem->AssignWindow(wnd);
151 else
152 wxLogError(wxT("Error in resource."));
153
154 // finally, set other wxSizerItem attributes
155 SetSizerItemAttributes(sitem);
156
157 AddSizerItem(sitem);
158 return item;
159 }
160 else /*n == NULL*/
161 {
162 wxLogError(wxT("Error in resource: no window/sizer/spacer within sizeritem object."));
163 return NULL;
164 }
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->AssignSpacer(GetSize());
175 AddSizerItem(sitem);
176 return NULL;
177}
178
179
180wxObject* wxSizerXmlHandler::Handle_sizer()
181{
182 wxSizer *sizer = NULL;
183
184 wxXmlNode *parentNode = m_node->GetParent();
185
186 wxCHECK_MSG(m_parentSizer != NULL ||
187 (parentNode && parentNode->GetType() == wxXML_ELEMENT_NODE &&
188 m_parentAsWindow), NULL,
189 wxT("Sizer must have a window parent node"));
190
191 if (m_class == wxT("wxBoxSizer"))
192 sizer = Handle_wxBoxSizer();
193
194#if wxUSE_STATBOX
195 else if (m_class == wxT("wxStaticBoxSizer"))
196 sizer = Handle_wxStaticBoxSizer();
197#endif
198
199 else if (m_class == wxT("wxGridSizer"))
200 sizer = Handle_wxGridSizer();
201
202 else if (m_class == wxT("wxFlexGridSizer"))
203 sizer = Handle_wxFlexGridSizer();
204
205 else if (m_class == wxT("wxGridBagSizer"))
206 sizer = Handle_wxGridBagSizer();
207
208 if ( !sizer )
209 {
210 wxLogError(_T("Failed to create size of class \"%s\""), m_class.c_str());
211 return NULL;
212 }
213
214 wxSize minsize = GetSize(wxT("minsize"));
215 if (!(minsize == wxDefaultSize))
216 sizer->SetMinSize(minsize);
217
218 // save state
219 wxSizer *old_par = m_parentSizer;
220 bool old_ins = m_isInside;
221
222 // set new state
223 m_parentSizer = sizer;
224 m_isInside = true;
225 m_isGBS = (m_class == wxT("wxGridBagSizer"));
226
227 CreateChildren(m_parent, true/*only this handler*/);
228
229 // restore state
230 m_isInside = old_ins;
231 m_parentSizer = old_par;
232
233 if (m_parentSizer == NULL) // setup window:
234 {
235 m_parentAsWindow->SetSizer(sizer);
236
237 wxXmlNode *nd = m_node;
238 m_node = parentNode;
239 if (GetSize() == wxDefaultSize)
240 {
241 if ( wxDynamicCast(m_parentAsWindow, wxScrolledWindow) != NULL )
242 {
243 sizer->FitInside(m_parentAsWindow);
244 }
245 else
246 {
247 sizer->Fit(m_parentAsWindow);
248 }
249 }
250 m_node = nd;
251
252 if (m_parentAsWindow->IsTopLevel())
253 {
254 sizer->SetSizeHints(m_parentAsWindow);
255 }
256 }
257
258 return sizer;
259}
260
261
262wxSizer* wxSizerXmlHandler::Handle_wxBoxSizer()
263{
264 return new wxBoxSizer(GetStyle(wxT("orient"), wxHORIZONTAL));
265}
266
267#if wxUSE_STATBOX
268wxSizer* wxSizerXmlHandler::Handle_wxStaticBoxSizer()
269{
270 return new wxStaticBoxSizer(
271 new wxStaticBox(m_parentAsWindow,
272 GetID(),
273 GetText(wxT("label")),
274 wxDefaultPosition, wxDefaultSize,
275 0/*style*/,
276 GetName()),
277 GetStyle(wxT("orient"), wxHORIZONTAL));
278}
279#endif // wxUSE_STATBOX
280
281wxSizer* wxSizerXmlHandler::Handle_wxGridSizer()
282{
283 return new wxGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
284 GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
285}
286
287
288wxSizer* wxSizerXmlHandler::Handle_wxFlexGridSizer()
289{
290 wxFlexGridSizer *sizer =
291 new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
292 GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
293 SetGrowables(sizer, wxT("growablerows"), true);
294 SetGrowables(sizer, wxT("growablecols"), false);
295 return sizer;
296}
297
298
299wxSizer* wxSizerXmlHandler::Handle_wxGridBagSizer()
300{
301 wxGridBagSizer *sizer =
302 new wxGridBagSizer(GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
303 SetGrowables(sizer, wxT("growablerows"), true);
304 SetGrowables(sizer, wxT("growablecols"), false);
305 return sizer;
306}
307
308
309
310
311void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer* sizer,
312 const wxChar* param,
313 bool rows)
314{
315 wxStringTokenizer tkn;
316 unsigned long l;
317 tkn.SetString(GetParamValue(param), wxT(","));
318 while (tkn.HasMoreTokens())
319 {
320 if (!tkn.GetNextToken().ToULong(&l))
321 wxLogError(wxT("growable[rows|cols] must be comma-separated list of row numbers"));
322 else {
323 if (rows)
324 sizer->AddGrowableRow(l);
325 else
326 sizer->AddGrowableCol(l);
327 }
328 }
329}
330
331
332wxGBPosition wxSizerXmlHandler::GetGBPos(const wxString& param)
333{
334 wxSize sz = GetSize(param);
335 if (sz.x < 0) sz.x = 0;
336 if (sz.y < 0) sz.y = 0;
337 return wxGBPosition(sz.x, sz.y);
338}
339
340wxGBSpan wxSizerXmlHandler::GetGBSpan(const wxString& param)
341{
342 wxSize sz = GetSize(param);
343 if (sz.x < 1) sz.x = 1;
344 if (sz.y < 1) sz.y = 1;
345 return wxGBSpan(sz.x, sz.y);
346}
347
348
349
350wxSizerItem* wxSizerXmlHandler::MakeSizerItem()
351{
352 if (m_isGBS)
353 return new wxGBSizerItem();
354 else
355 return new wxSizerItem();
356}
357
358void wxSizerXmlHandler::SetSizerItemAttributes(wxSizerItem* sitem)
359{
360 sitem->SetProportion(GetLong(wxT("option"))); // Should this check for "proportion" too?
361 sitem->SetFlag(GetStyle(wxT("flag")));
362 sitem->SetBorder(GetDimension(wxT("border")));
363 wxSize sz = GetSize(wxT("minsize"));
364 if (!(sz == wxDefaultSize))
365 sitem->SetMinSize(sz);
366 sz = GetSize(wxT("ratio"));
367 if (!(sz == wxDefaultSize))
368 sitem->SetRatio(sz);
369
370 if (m_isGBS)
371 {
372 wxGBSizerItem* gbsitem = (wxGBSizerItem*)sitem;
373 gbsitem->SetPos(GetGBPos(wxT("cellpos")));
374 gbsitem->SetSpan(GetGBSpan(wxT("cellspan")));
375 }
376
377 // record the id of the item, if any, for use by XRCSIZERITEM()
378 sitem->SetId(GetID());
379}
380
381void wxSizerXmlHandler::AddSizerItem(wxSizerItem* sitem)
382{
383 if (m_isGBS)
384 ((wxGridBagSizer*)m_parentSizer)->Add((wxGBSizerItem*)sitem);
385 else
386 m_parentSizer->Add(sitem);
387}
388
389
390
391//-----------------------------------------------------------------------------
392// wxStdDialogButtonSizerXmlHandler
393//-----------------------------------------------------------------------------
394#if wxUSE_BUTTON
395
396IMPLEMENT_DYNAMIC_CLASS(wxStdDialogButtonSizerXmlHandler, wxXmlResourceHandler)
397
398wxStdDialogButtonSizerXmlHandler::wxStdDialogButtonSizerXmlHandler()
399 : m_isInside(false), m_parentSizer(NULL)
400{
401}
402
403wxObject *wxStdDialogButtonSizerXmlHandler::DoCreateResource()
404{
405 if (m_class == wxT("wxStdDialogButtonSizer"))
406 {
407 wxASSERT( !m_parentSizer );
408
409 wxSizer *s = m_parentSizer = new wxStdDialogButtonSizer;
410 m_isInside = true;
411
412 CreateChildren(m_parent, true/*only this handler*/);
413
414 m_parentSizer->Realize();
415
416 m_isInside = false;
417 m_parentSizer = NULL;
418
419 return s;
420 }
421 else // m_class == "button"
422 {
423 wxASSERT( m_parentSizer );
424
425 // find the item to be managed by this sizeritem
426 wxXmlNode *n = GetParamNode(wxT("object"));
427 if ( !n )
428 n = GetParamNode(wxT("object_ref"));
429
430 // did we find one?
431 if (n)
432 {
433 wxObject *item = CreateResFromNode(n, m_parent, NULL);
434 wxButton *button = wxDynamicCast(item, wxButton);
435
436 if (button)
437 m_parentSizer->AddButton(button);
438 else
439 wxLogError(wxT("Error in resource - expected button."));
440
441 return item;
442 }
443 else /*n == NULL*/
444 {
445 wxLogError(wxT("Error in resource: no button within wxStdDialogButtonSizer."));
446 return NULL;
447 }
448 }
449}
450
451bool wxStdDialogButtonSizerXmlHandler::CanHandle(wxXmlNode *node)
452{
453 return (!m_isInside && IsOfClass(node, wxT("wxStdDialogButtonSizer"))) ||
454 (m_isInside && IsOfClass(node, wxT("button")));
455}
456#endif // wxUSE_BUTTON
457
458#endif // wxUSE_XRC