Warning fixes found under hardest mode of OpenWatcom. Seems clean in Borland, MinGW...
[wxWidgets.git] / samples / layout / layout.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: layout.cpp
3 // Purpose: Layout sample
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ----------------------------------------------------------------------------
13 // headers
14 // ----------------------------------------------------------------------------
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 #include "wx/sizer.h"
28 #include "wx/gbsizer.h"
29 #include "wx/statline.h"
30 #include "wx/notebook.h"
31
32 #include "layout.h"
33
34 // ----------------------------------------------------------------------------
35 // MyApp
36 // ----------------------------------------------------------------------------
37
38 IMPLEMENT_APP(MyApp)
39
40 bool MyApp::OnInit()
41 {
42 // Create the main frame window
43 MyFrame *frame = new MyFrame;
44
45 frame->Show(true);
46
47 return true;
48 }
49
50 // ----------------------------------------------------------------------------
51 // MyFrame
52 // ----------------------------------------------------------------------------
53
54 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
55 EVT_MENU(LAYOUT_ABOUT, MyFrame::OnAbout)
56 EVT_MENU(LAYOUT_QUIT, MyFrame::OnQuit)
57
58 EVT_MENU(LAYOUT_TEST_SIZER, MyFrame::TestFlexSizers)
59 EVT_MENU(LAYOUT_TEST_NB_SIZER, MyFrame::TestNotebookSizers)
60 EVT_MENU(LAYOUT_TEST_GB_SIZER, MyFrame::TestGridBagSizer)
61 END_EVENT_TABLE()
62
63 // Define my frame constructor
64 MyFrame::MyFrame()
65 : wxFrame(NULL, wxID_ANY, _T("wxWidgets Layout Demo"),
66 wxDefaultPosition, wxDefaultSize,
67 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
68 {
69 // Make a menubar
70 wxMenu *file_menu = new wxMenu;
71
72 file_menu->Append(LAYOUT_TEST_SIZER, _T("Test wx&FlexSizer"));
73 file_menu->Append(LAYOUT_TEST_NB_SIZER, _T("&Test notebook sizers"));
74 file_menu->Append(LAYOUT_TEST_GB_SIZER, _T("Test &gridbag sizer"));
75
76 file_menu->AppendSeparator();
77 file_menu->Append(LAYOUT_QUIT, _T("E&xit"), _T("Quit program"));
78
79 wxMenu *help_menu = new wxMenu;
80 help_menu->Append(LAYOUT_ABOUT, _T("&About"), _T("About layout demo"));
81
82 wxMenuBar *menu_bar = new wxMenuBar;
83
84 menu_bar->Append(file_menu, _T("&File"));
85 menu_bar->Append(help_menu, _T("&Help"));
86
87 // Associate the menu bar with the frame
88 SetMenuBar(menu_bar);
89
90 #if wxUSE_STATUSBAR
91 CreateStatusBar(2);
92 SetStatusText(_T("wxWidgets layout demo"));
93 #endif // wxUSE_STATUSBAR
94
95 // we want to get a dialog that is stretchable because it
96 // has a text ctrl in the middle. at the bottom, we have
97 // two buttons which.
98
99 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
100
101 // 1) top: create wxStaticText with minimum size equal to its default size
102 topsizer->Add(
103 new wxStaticText( this, wxID_ANY, _T("An explanation (wxALIGN_RIGHT).") ),
104 wxSizerFlags().Align(wxALIGN_RIGHT).Border(wxALL & ~wxBOTTOM, 5));
105
106 // 2) top: create wxTextCtrl with minimum size (100x60)
107 topsizer->Add(
108 new wxTextCtrl( this, wxID_ANY, _T("My text (wxEXPAND)."), wxDefaultPosition, wxSize(100,60), wxTE_MULTILINE),
109 wxSizerFlags(1).Expand().Border(wxALL, 5));
110
111 // 2.5) Gratuitous test of wxStaticBoxSizers
112 wxBoxSizer *statsizer = new wxStaticBoxSizer(
113 new wxStaticBox(this, wxID_ANY, _T("A wxStaticBoxSizer")), wxVERTICAL );
114 statsizer->Add(
115 new wxStaticText(this, wxID_ANY, _T("And some TEXT inside it")),
116 wxSizerFlags().Center().Border(wxALL, 30));
117 topsizer->Add(
118 statsizer,
119 wxSizerFlags(1).Expand().Border(wxALL, 10));
120
121 // 2.7) And a test of wxGridSizer
122 wxGridSizer *gridsizer = new wxGridSizer(2, 5, 5);
123 gridsizer->Add(new wxStaticText(this, wxID_ANY, _T("Label")),
124 wxSizerFlags().Align(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL));
125 gridsizer->Add(new wxTextCtrl(this, wxID_ANY, _T("Grid sizer demo")),
126 wxSizerFlags(1).Align(wxGROW | wxALIGN_CENTER_VERTICAL));
127 gridsizer->Add(new wxStaticText(this, wxID_ANY, _T("Another label")),
128 wxSizerFlags().Align(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL));
129 gridsizer->Add(new wxTextCtrl(this, wxID_ANY, _T("More text")),
130 wxSizerFlags(1).Align(wxGROW | wxALIGN_CENTER_VERTICAL));
131 gridsizer->Add(new wxStaticText(this, wxID_ANY, _T("Final label")),
132 wxSizerFlags().Align(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL));
133 gridsizer->Add(new wxTextCtrl(this, wxID_ANY, _T("And yet more text")),
134 wxSizerFlags().Align(wxGROW | wxALIGN_CENTER_VERTICAL));
135 topsizer->Add(
136 gridsizer,
137 wxSizerFlags().Proportion(1).Expand().Border(wxALL, 10));
138
139
140 #if wxUSE_STATLINE
141 // 3) middle: create wxStaticLine with minimum size (3x3)
142 topsizer->Add(
143 new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL),
144 wxSizerFlags().Expand());
145 #endif // wxUSE_STATLINE
146
147
148 // 4) bottom: create two centred wxButtons
149 wxBoxSizer *button_box = new wxBoxSizer( wxHORIZONTAL );
150 button_box->Add(
151 new wxButton( this, wxID_ANY, _T("Two buttons in a box") ),
152 wxSizerFlags().Border(wxALL, 7));
153 button_box->Add(
154 new wxButton( this, wxID_ANY, _T("(wxCENTER)") ),
155 wxSizerFlags().Border(wxALL, 7));
156
157 topsizer->Add(button_box, wxSizerFlags().Center());
158
159 // don't allow frame to get smaller than what the sizers tell it and also set
160 // the initial size as calculated by the sizers
161 topsizer->SetSizeHints( this );
162
163 SetSizer( topsizer );
164 }
165
166 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
167 {
168 Close(true);
169 }
170
171 void MyFrame::TestFlexSizers(wxCommandEvent& WXUNUSED(event) )
172 {
173 MyFlexSizerFrame *newFrame = new MyFlexSizerFrame(_T("Flex Sizer Test Frame"), 50, 50);
174 newFrame->Show(true);
175 }
176
177 void MyFrame::TestNotebookSizers(wxCommandEvent& WXUNUSED(event) )
178 {
179 MySizerDialog dialog( this, _T("Notebook Sizer Test Dialog") );
180
181 dialog.ShowModal();
182 }
183
184
185 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
186 {
187 (void)wxMessageBox(_T("wxWidgets GUI library layout demo\n"),
188 _T("About Layout Demo"), wxOK|wxICON_INFORMATION);
189 }
190
191 void MyFrame::TestGridBagSizer(wxCommandEvent& WXUNUSED(event) )
192 {
193 MyGridBagSizerFrame *newFrame = new
194 MyGridBagSizerFrame(_T("wxGridBagSizer Test Frame"), 50, 50);
195 newFrame->Show(true);
196 }
197
198
199 // ----------------------------------------------------------------------------
200 // MyFlexSizerFrame
201 // ----------------------------------------------------------------------------
202
203 void MyFlexSizerFrame::InitFlexSizer(wxFlexGridSizer *sizer)
204 {
205 for ( int i = 0; i < 3; i++ )
206 {
207 for ( int j = 0; j < 3; j++ )
208 {
209 sizer->Add(new wxStaticText
210 (
211 this,
212 wxID_ANY,
213 wxString::Format(_T("(%d, %d)"), i + 1, j + 1),
214 wxDefaultPosition,
215 wxDefaultSize,
216 wxALIGN_CENTER
217 ),
218 0, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 3);
219 }
220 }
221 }
222
223 MyFlexSizerFrame::MyFlexSizerFrame(const wxChar *title, int x, int y )
224 : wxFrame(NULL, wxID_ANY, title, wxPoint(x, y) )
225 {
226 wxFlexGridSizer *sizerFlex;
227
228 // consttuct the first column
229 wxSizer *sizerCol1 = new wxBoxSizer(wxVERTICAL);
230 sizerCol1->Add(new wxStaticText(this, wxID_ANY, _T("Ungrowable:")), 0, wxCENTER | wxTOP, 20);
231 sizerFlex = new wxFlexGridSizer(3, 3);
232 InitFlexSizer(sizerFlex);
233 sizerCol1->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
234
235 sizerCol1->Add(new wxStaticText(this, wxID_ANY, _T("Growable middle column:")), 0, wxCENTER | wxTOP, 20);
236 sizerFlex = new wxFlexGridSizer(3, 3);
237 InitFlexSizer(sizerFlex);
238 sizerFlex->AddGrowableCol(1);
239 sizerCol1->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
240
241 sizerCol1->Add(new wxStaticText(this, wxID_ANY, _T("Growable middle row:")), 0, wxCENTER | wxTOP, 20);
242 sizerFlex = new wxFlexGridSizer(3, 3);
243 InitFlexSizer(sizerFlex);
244 sizerFlex->AddGrowableRow(1);
245 sizerCol1->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
246
247 sizerCol1->Add(new wxStaticText(this, wxID_ANY, _T("All growable columns:")), 0, wxCENTER | wxTOP, 20);
248 sizerFlex = new wxFlexGridSizer(3, 3);
249 InitFlexSizer(sizerFlex);
250 sizerFlex->AddGrowableCol(0, 1);
251 sizerFlex->AddGrowableCol(1, 2);
252 sizerFlex->AddGrowableCol(2, 3);
253 sizerCol1->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
254
255 // the second one
256 wxSizer *sizerCol2 = new wxBoxSizer(wxVERTICAL);
257 sizerCol2->Add(new wxStaticText(this, wxID_ANY, _T("Growable middle row and column:")), 0, wxCENTER | wxTOP, 20);
258 sizerFlex = new wxFlexGridSizer(3, 3);
259 InitFlexSizer(sizerFlex);
260 sizerFlex->AddGrowableCol(1);
261 sizerFlex->AddGrowableRow(1);
262 sizerCol2->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
263
264 sizerCol2->Add(new wxStaticText(this, wxID_ANY, _T("Same with horz flex direction")), 0, wxCENTER | wxTOP, 20);
265 sizerFlex = new wxFlexGridSizer(3, 3);
266 InitFlexSizer(sizerFlex);
267 sizerFlex->AddGrowableCol(1);
268 sizerFlex->AddGrowableRow(1);
269 sizerFlex->SetFlexibleDirection(wxHORIZONTAL);
270 sizerCol2->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
271
272 sizerCol2->Add(new wxStaticText(this, wxID_ANY, _T("Same with grow mode == \"none\"")), 0, wxCENTER | wxTOP, 20);
273 sizerFlex = new wxFlexGridSizer(3, 3);
274 InitFlexSizer(sizerFlex);
275 sizerFlex->AddGrowableCol(1);
276 sizerFlex->AddGrowableRow(1);
277 sizerFlex->SetFlexibleDirection(wxHORIZONTAL);
278 sizerFlex->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_NONE);
279 sizerCol2->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
280
281 sizerCol2->Add(new wxStaticText(this, wxID_ANY, _T("Same with grow mode == \"all\"")), 0, wxCENTER | wxTOP, 20);
282 sizerFlex = new wxFlexGridSizer(3, 3);
283 InitFlexSizer(sizerFlex);
284 sizerFlex->AddGrowableCol(1);
285 sizerFlex->AddGrowableRow(1);
286 sizerFlex->SetFlexibleDirection(wxHORIZONTAL);
287 sizerFlex->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_ALL);
288 sizerCol2->Add(sizerFlex, 1, wxALL | wxEXPAND, 10);
289
290 // add both columns to grid sizer
291 wxGridSizer *sizerTop = new wxGridSizer(2, 0, 20);
292 sizerTop->Add(sizerCol1, 1, wxEXPAND);
293 sizerTop->Add(sizerCol2, 1, wxEXPAND);
294
295 SetSizer(sizerTop);
296 sizerTop->SetSizeHints(this);
297 }
298
299 // ----------------------------------------------------------------------------
300 // MySizerDialog
301 // ----------------------------------------------------------------------------
302
303 MySizerDialog::MySizerDialog(wxWindow *parent, const wxChar *title)
304 : wxDialog(parent, wxID_ANY, wxString(title))
305 {
306 // Begin with first hierarchy: a notebook at the top and
307 // and OK button at the bottom.
308
309 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
310
311 wxNotebook *notebook = new wxNotebook( this, wxID_ANY );
312 topsizer->Add( notebook, 1, wxGROW );
313
314 wxButton *button = new wxButton( this, wxID_OK, _T("OK") );
315 topsizer->Add( button, 0, wxALIGN_RIGHT | wxALL, 10 );
316
317 // First page: one big text ctrl
318 wxTextCtrl *multi = new wxTextCtrl( notebook, wxID_ANY, _T("TextCtrl."), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
319 notebook->AddPage( multi, _T("Page One") );
320
321 // Second page: a text ctrl and a button
322 wxPanel *panel = new wxPanel( notebook, wxID_ANY );
323 notebook->AddPage( panel, _T("Page Two") );
324
325 wxSizer *panelsizer = new wxBoxSizer( wxVERTICAL );
326
327 wxTextCtrl *text = new wxTextCtrl( panel, wxID_ANY, _T("TextLine 1."), wxDefaultPosition, wxSize(250,-1) );
328 panelsizer->Add( text, 0, wxGROW|wxALL, 30 );
329 text = new wxTextCtrl( panel, wxID_ANY, _T("TextLine 2."), wxDefaultPosition, wxSize(250,-1) );
330 panelsizer->Add( text, 0, wxGROW|wxALL, 30 );
331 wxButton *button2 = new wxButton( panel, wxID_ANY, _T("Hallo") );
332 panelsizer->Add( button2, 0, wxALIGN_RIGHT | wxLEFT|wxRIGHT|wxBOTTOM, 30 );
333
334 panel->SetAutoLayout( true );
335 panel->SetSizer( panelsizer );
336
337 // Tell dialog to use sizer
338 SetSizer( topsizer );
339 topsizer->SetSizeHints( this );
340 }
341
342 // ----------------------------------------------------------------------------
343 // MyGridBagSizerFrame
344 // ----------------------------------------------------------------------------
345
346 // some simple macros to help make the sample code below more clear
347 #define TEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text))
348 #define MLTEXTCTRL(text) new wxTextCtrl(p, wxID_ANY, _T(text), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE)
349 #define POS(r, c) wxGBPosition(r,c)
350 #define SPAN(r, c) wxGBSpan(r,c)
351
352 wxChar* gbsDescription =_T("\
353 The wxGridBagSizer is similar to the wxFlexGridSizer except the items are explicitly positioned\n\
354 in a virtual cell of the layout grid, and column or row spanning is allowed. For example, this\n\
355 static text is positioned at (0,0) and it spans 7 columns.");
356
357
358 // Some IDs
359 enum {
360 GBS_HIDE_BTN = 1212,
361 GBS_SHOW_BTN,
362 GBS_MOVE_BTN1,
363 GBS_MOVE_BTN2,
364
365 GBS_MAX,
366 };
367
368
369 BEGIN_EVENT_TABLE(MyGridBagSizerFrame, wxFrame)
370 EVT_BUTTON( GBS_HIDE_BTN, MyGridBagSizerFrame::OnHideBtn)
371 EVT_BUTTON( GBS_SHOW_BTN, MyGridBagSizerFrame::OnShowBtn)
372 EVT_BUTTON( GBS_MOVE_BTN1, MyGridBagSizerFrame::OnMoveBtn)
373 EVT_BUTTON( GBS_MOVE_BTN2, MyGridBagSizerFrame::OnMoveBtn)
374 END_EVENT_TABLE()
375
376
377 MyGridBagSizerFrame::MyGridBagSizerFrame(const wxChar *title, int x, int y )
378 : wxFrame( NULL, wxID_ANY, title, wxPoint(x, y) )
379 {
380 wxPanel* p = new wxPanel(this, wxID_ANY);
381 m_panel = p;
382 m_gbs = new wxGridBagSizer();
383
384
385 m_gbs->Add( new wxStaticText(p, wxID_ANY, gbsDescription),
386 POS(0,0), SPAN(1, 7),
387 wxALIGN_CENTER | wxALL, 5);
388
389 m_gbs->Add( TEXTCTRL("pos(1,0)"), POS(1,0) );
390 m_gbs->Add( TEXTCTRL("pos(1,1)"), POS(1,1) );
391 m_gbs->Add( TEXTCTRL("pos(2,0)"), POS(2,0) );
392 m_gbs->Add( TEXTCTRL("pos(2,1)"), POS(2,1) );
393 m_gbs->Add( MLTEXTCTRL("pos(3,2), span(1,2)\nthis row and col are growable"),
394 POS(3,2), SPAN(1,2), wxEXPAND );
395 m_gbs->Add( MLTEXTCTRL("pos(4,3)\nspan(3,1)"),
396 POS(4,3), SPAN(3,1), wxEXPAND );
397 m_gbs->Add( TEXTCTRL("pos(5,4)"), POS(5,4), wxDefaultSpan, wxEXPAND );
398 m_gbs->Add( TEXTCTRL("pos(6,5)"), POS(6,5), wxDefaultSpan, wxEXPAND );
399 m_gbs->Add( TEXTCTRL("pos(7,6)"), POS(7,6) );
400
401 //m_gbs->Add( TEXTCTRL("bad position"), POS(4,3) ); // Test for assert
402 //m_gbs->Add( TEXTCTRL("bad position"), POS(5,3) ); // Test for assert
403
404
405 m_moveBtn1 = new wxButton(p, GBS_MOVE_BTN1, _T("Move this to (3,6)"));
406 m_moveBtn2 = new wxButton(p, GBS_MOVE_BTN2, _T("Move this to (3,6)"));
407 m_gbs->Add( m_moveBtn1, POS(10,2) );
408 m_gbs->Add( m_moveBtn2, POS(10,3) );
409
410 m_hideBtn = new wxButton(p, GBS_HIDE_BTN, _T("Hide this item -->"));
411 m_gbs->Add(m_hideBtn, POS(12, 3));
412
413 m_hideTxt = new wxTextCtrl(p, wxID_ANY, _T("pos(12,4), size(150, -1)"),
414 wxDefaultPosition, wxSize(150,-1));
415 m_gbs->Add( m_hideTxt, POS(12,4) );
416
417 m_showBtn = new wxButton(p, GBS_SHOW_BTN, _T("<-- Show it again"));
418 m_gbs->Add(m_showBtn, POS(12, 5));
419 m_showBtn->Disable();
420
421 m_gbs->Add(10,10, POS(14,0));
422
423 m_gbs->AddGrowableRow(3);
424 m_gbs->AddGrowableCol(2);
425
426 p->SetSizerAndFit(m_gbs);
427 SetClientSize(p->GetSize());
428 }
429
430
431 void MyGridBagSizerFrame::OnHideBtn(wxCommandEvent&)
432 {
433 m_gbs->Hide(m_hideTxt);
434 m_hideBtn->Disable();
435 m_showBtn->Enable();
436 m_gbs->Layout();
437 }
438
439 void MyGridBagSizerFrame::OnShowBtn(wxCommandEvent&)
440 {
441 m_gbs->Show(m_hideTxt);
442 m_hideBtn->Enable();
443 m_showBtn->Disable();
444 m_gbs->Layout();
445 }
446
447
448 void MyGridBagSizerFrame::OnMoveBtn(wxCommandEvent& event)
449 {
450 wxButton* btn = (wxButton*)event.GetEventObject();
451 wxGBPosition curPos = m_gbs->GetItemPosition(btn);
452
453 // if it's already at the "other" spot then move it back
454 if (curPos == wxGBPosition(3,6))
455 {
456 m_gbs->SetItemPosition(btn, m_lastPos);
457 btn->SetLabel(_T("Move this to (3,6)"));
458 }
459 else
460 {
461 if ( m_gbs->CheckForIntersection(wxGBPosition(3,6), wxGBSpan(1,1)) )
462 wxMessageBox(
463 _T("wxGridBagSizer will not allow items to be in the same cell as\n\
464 another item, so this operation will fail. You will also get an assert\n\
465 when compiled in debug mode."), _T("Warning"), wxOK | wxICON_INFORMATION);
466
467 if ( m_gbs->SetItemPosition(btn, wxGBPosition(3,6)) )
468 {
469 m_lastPos = curPos;
470 btn->SetLabel(_T("Move it back"));
471 }
472 }
473 m_gbs->Layout();
474 }