]> git.saurik.com Git - wxWidgets.git/blame - samples/widgets/radiobox.cpp
Support using GetTextExtent() with empty string to get descent in wxOSX.
[wxWidgets.git] / samples / widgets / radiobox.cpp
CommitLineData
32b8ec41 1/////////////////////////////////////////////////////////////////////////////
be5a51fb 2// Program: wxWidgets Widgets Sample
32b8ec41
VZ
3// Name: radiobox.cpp
4// Purpose: Part of the widgets sample showing wxRadioBox
5// Author: Vadim Zeitlin
6// Created: 15.04.01
7// Id: $Id$
8// Copyright: (c) 2001 Vadim Zeitlin
526954c5 9// Licence: wxWindows licence
32b8ec41
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// for compilers that support precompilation, includes "wx/wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
61c083e7
WS
27#if wxUSE_RADIOBOX
28
32b8ec41
VZ
29// for all others, include the necessary headers
30#ifndef WX_PRECOMP
31 #include "wx/log.h"
32
3bb70c40 33 #include "wx/bitmap.h"
32b8ec41
VZ
34 #include "wx/button.h"
35 #include "wx/checkbox.h"
36 #include "wx/radiobox.h"
37 #include "wx/statbox.h"
38 #include "wx/textctrl.h"
39#endif
40
41#include "wx/sizer.h"
42
43#include "widgets.h"
61c083e7 44
32b8ec41
VZ
45#include "icons/radiobox.xpm"
46
47// ----------------------------------------------------------------------------
48// constants
49// ----------------------------------------------------------------------------
50
51// control ids
52enum
53{
f0fa4312 54 RadioPage_Reset = wxID_HIGHEST,
32b8ec41
VZ
55 RadioPage_Update,
56 RadioPage_Selection,
57 RadioPage_Label,
58 RadioPage_LabelBtn,
3bfa7be9
VZ
59 RadioPage_EnableItem,
60 RadioPage_ShowItem,
32b8ec41
VZ
61 RadioPage_Radio
62};
63
64// layout direction radiobox selections
65enum
66{
67 RadioDir_Default,
68 RadioDir_LtoR,
69 RadioDir_TtoB
70};
71
72// default values for the number of radiobox items
0c61716c
VZ
73static const unsigned int DEFAULT_NUM_ENTRIES = 12;
74static const unsigned int DEFAULT_MAJOR_DIM = 3;
32b8ec41 75
3bfa7be9
VZ
76// this item is enabled/disabled shown/hidden by the test checkboxes
77static const int TEST_BUTTON = 1;
78
32b8ec41
VZ
79// ----------------------------------------------------------------------------
80// RadioWidgetsPage
81// ----------------------------------------------------------------------------
82
83class RadioWidgetsPage : public WidgetsPage
84{
85public:
f2fdc4d5 86 RadioWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
8f6eaec9 87 virtual ~RadioWidgetsPage(){};
32b8ec41 88
195df7a7 89 virtual wxControl *GetWidget() const { return m_radio; }
1301e228 90 virtual void RecreateWidget() { CreateRadio(); }
195df7a7 91
453535a7
WS
92 // lazy creation of the content
93 virtual void CreateContent();
94
32b8ec41
VZ
95protected:
96 // event handlers
97 void OnCheckOrRadioBox(wxCommandEvent& event);
98 void OnRadioBox(wxCommandEvent& event);
99
100 void OnButtonReset(wxCommandEvent& event);
101 void OnButtonRecreate(wxCommandEvent& event);
102
103 void OnButtonSelection(wxCommandEvent& event);
104 void OnButtonSetLabel(wxCommandEvent& event);
105
3bfa7be9
VZ
106 void OnEnableItem(wxCommandEvent& event);
107 void OnShowItem(wxCommandEvent& event);
108
32b8ec41
VZ
109 void OnUpdateUIReset(wxUpdateUIEvent& event);
110 void OnUpdateUIUpdate(wxUpdateUIEvent& event);
111 void OnUpdateUISelection(wxUpdateUIEvent& event);
3bfa7be9
VZ
112 void OnUpdateUIEnableItem(wxUpdateUIEvent& event);
113 void OnUpdateUIShowItem(wxUpdateUIEvent& event);
32b8ec41
VZ
114
115 // reset the wxRadioBox parameters
116 void Reset();
117
118 // (re)create the wxRadioBox
119 void CreateRadio();
120
121 // the controls
122 // ------------
123
124 // the check/radio boxes for styles
3998c74b 125 wxCheckBox *m_chkSpecifyRows;
3bfa7be9
VZ
126 wxCheckBox *m_chkEnableItem;
127 wxCheckBox *m_chkShowItem;
32b8ec41
VZ
128 wxRadioBox *m_radioDir;
129
130 // the gauge itself and the sizer it is in
131 wxRadioBox *m_radio;
132 wxSizer *m_sizerRadio;
133
134 // the text entries for command parameters
135 wxTextCtrl *m_textNumBtns,
136 *m_textMajorDim,
137 *m_textCurSel,
138 *m_textSel,
139 *m_textLabel,
140 *m_textLabelBtns;
141
142private:
5e173f35
GD
143 DECLARE_EVENT_TABLE()
144 DECLARE_WIDGETS_PAGE(RadioWidgetsPage)
32b8ec41
VZ
145};
146
147// ----------------------------------------------------------------------------
148// event tables
149// ----------------------------------------------------------------------------
150
151BEGIN_EVENT_TABLE(RadioWidgetsPage, WidgetsPage)
152 EVT_BUTTON(RadioPage_Reset, RadioWidgetsPage::OnButtonReset)
153
154 EVT_BUTTON(RadioPage_Update, RadioWidgetsPage::OnButtonRecreate)
155 EVT_BUTTON(RadioPage_LabelBtn, RadioWidgetsPage::OnButtonRecreate)
156
157 EVT_BUTTON(RadioPage_Selection, RadioWidgetsPage::OnButtonSelection)
158 EVT_BUTTON(RadioPage_Label, RadioWidgetsPage::OnButtonSetLabel)
159
160 EVT_UPDATE_UI(RadioPage_Update, RadioWidgetsPage::OnUpdateUIUpdate)
161 EVT_UPDATE_UI(RadioPage_Selection, RadioWidgetsPage::OnUpdateUISelection)
162
163 EVT_RADIOBOX(RadioPage_Radio, RadioWidgetsPage::OnRadioBox)
164
3bfa7be9
VZ
165 EVT_CHECKBOX(RadioPage_EnableItem, RadioWidgetsPage::OnEnableItem)
166 EVT_CHECKBOX(RadioPage_ShowItem, RadioWidgetsPage::OnShowItem)
167
168 EVT_UPDATE_UI(RadioPage_EnableItem, RadioWidgetsPage::OnUpdateUIEnableItem)
169 EVT_UPDATE_UI(RadioPage_ShowItem, RadioWidgetsPage::OnUpdateUIShowItem)
170
206d3a16
JS
171 EVT_CHECKBOX(wxID_ANY, RadioWidgetsPage::OnCheckOrRadioBox)
172 EVT_RADIOBOX(wxID_ANY, RadioWidgetsPage::OnCheckOrRadioBox)
32b8ec41
VZ
173END_EVENT_TABLE()
174
175// ============================================================================
176// implementation
177// ============================================================================
178
f0fa4312
WS
179#if defined(__WXUNIVERSAL__)
180 #define FAMILY_CTRLS UNIVERSAL_CTRLS
181#else
182 #define FAMILY_CTRLS NATIVE_CTRLS
183#endif
184
9a83f860 185IMPLEMENT_WIDGETS_PAGE(RadioWidgetsPage, wxT("Radio"),
f0fa4312 186 FAMILY_CTRLS | WITH_ITEMS_CTRLS
f2fdc4d5 187 );
32b8ec41 188
f2fdc4d5 189RadioWidgetsPage::RadioWidgetsPage(WidgetsBookCtrl *book,
61c083e7 190 wxImageList *imaglist)
261357eb 191 : WidgetsPage(book, imaglist, radio_xpm)
32b8ec41 192{
32b8ec41 193 // init everything
3998c74b 194 m_chkSpecifyRows = (wxCheckBox *)NULL;
3bfa7be9
VZ
195 m_chkEnableItem = (wxCheckBox *)NULL;
196 m_chkShowItem = (wxCheckBox *)NULL;
32b8ec41
VZ
197
198 m_textNumBtns =
199 m_textLabelBtns =
200 m_textLabel = (wxTextCtrl *)NULL;
201
202 m_radio =
203 m_radioDir = (wxRadioBox *)NULL;
204 m_sizerRadio = (wxSizer *)NULL;
453535a7 205}
32b8ec41 206
453535a7
WS
207void RadioWidgetsPage::CreateContent()
208{
32b8ec41
VZ
209 wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
210
211 // left pane
9a83f860 212 wxStaticBox *box = new wxStaticBox(this, wxID_ANY, wxT("&Set style"));
32b8ec41
VZ
213
214 wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
215
3998c74b
VZ
216 m_chkSpecifyRows = CreateCheckBoxAndAddToSizer
217 (
218 sizerLeft,
219 "Major specifies &rows count"
220 );
32b8ec41
VZ
221
222 static const wxString layoutDir[] =
223 {
9a83f860
VZ
224 wxT("default"),
225 wxT("left to right"),
226 wxT("top to bottom")
32b8ec41
VZ
227 };
228
9a83f860 229 m_radioDir = new wxRadioBox(this, wxID_ANY, wxT("Numbering:"),
32b8ec41 230 wxDefaultPosition, wxDefaultSize,
7b127900
JS
231 WXSIZEOF(layoutDir), layoutDir,
232 1, wxRA_SPECIFY_COLS);
32b8ec41
VZ
233 sizerLeft->Add(m_radioDir, 0, wxGROW | wxALL, 5);
234
235 // if it's not defined, we can't change the radiobox direction
236#ifndef wxRA_LEFTTORIGHT
237 m_radioDir->Disable();
238#endif // wxRA_LEFTTORIGHT
239
240 wxSizer *sizerRow;
9a83f860 241 sizerRow = CreateSizerWithTextAndLabel(wxT("&Major dimension:"),
206d3a16 242 wxID_ANY,
32b8ec41
VZ
243 &m_textMajorDim);
244 sizerLeft->Add(sizerRow, 0, wxGROW | wxALL, 5);
245
9a83f860 246 sizerRow = CreateSizerWithTextAndLabel(wxT("&Number of buttons:"),
206d3a16 247 wxID_ANY,
32b8ec41
VZ
248 &m_textNumBtns);
249 sizerLeft->Add(sizerRow, 0, wxGROW | wxALL, 5);
250
251 wxButton *btn;
9a83f860 252 btn = new wxButton(this, RadioPage_Update, wxT("&Update"));
32b8ec41
VZ
253 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 5);
254
255 sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
256
9a83f860 257 btn = new wxButton(this, RadioPage_Reset, wxT("&Reset"));
32b8ec41
VZ
258 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
259
260 // middle pane
9a83f860 261 wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, wxT("&Change parameters"));
32b8ec41
VZ
262 wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
263
9a83f860 264 sizerRow = CreateSizerWithTextAndLabel(wxT("Current selection:"),
206d3a16 265 wxID_ANY,
32b8ec41
VZ
266 &m_textCurSel);
267 sizerMiddle->Add(sizerRow, 0, wxGROW | wxALL, 5);
268
269 sizerRow = CreateSizerWithTextAndButton(RadioPage_Selection,
9a83f860 270 wxT("&Change selection:"),
206d3a16 271 wxID_ANY,
32b8ec41
VZ
272 &m_textSel);
273 sizerMiddle->Add(sizerRow, 0, wxGROW | wxALL, 5);
274
275 sizerRow = CreateSizerWithTextAndButton(RadioPage_Label,
9a83f860 276 wxT("&Label for box:"),
206d3a16 277 wxID_ANY,
32b8ec41
VZ
278 &m_textLabel);
279 sizerMiddle->Add(sizerRow, 0, wxGROW | wxALL, 5);
280
281 sizerRow = CreateSizerWithTextAndButton(RadioPage_LabelBtn,
9a83f860 282 wxT("&Label for buttons:"),
206d3a16 283 wxID_ANY,
32b8ec41
VZ
284 &m_textLabelBtns);
285 sizerMiddle->Add(sizerRow, 0, wxGROW | wxALL, 5);
286
3bfa7be9 287 m_chkEnableItem = CreateCheckBoxAndAddToSizer(sizerMiddle,
9a83f860 288 wxT("Disable &2nd item"),
3bfa7be9
VZ
289 RadioPage_EnableItem);
290 m_chkShowItem = CreateCheckBoxAndAddToSizer(sizerMiddle,
9a83f860 291 wxT("Hide 2nd &item"),
3bfa7be9 292 RadioPage_ShowItem);
8b6d589d 293
32b8ec41
VZ
294 // right pane
295 wxSizer *sizerRight = new wxBoxSizer(wxHORIZONTAL);
7b127900 296 sizerRight->SetMinSize(150, 0);
32b8ec41
VZ
297 m_sizerRadio = sizerRight; // save it to modify it later
298
299 Reset();
300 CreateRadio();
301
302 // the 3 panes panes compose the window
303 sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
304 sizerTop->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
7b127900 305 sizerTop->Add(sizerRight, 0, wxGROW | (wxALL & ~wxRIGHT), 10);
32b8ec41
VZ
306
307 // final initializations
32b8ec41 308 SetSizer(sizerTop);
32b8ec41
VZ
309}
310
32b8ec41
VZ
311// ----------------------------------------------------------------------------
312// operations
313// ----------------------------------------------------------------------------
314
315void RadioWidgetsPage::Reset()
316{
9a83f860
VZ
317 m_textMajorDim->SetValue(wxString::Format(wxT("%u"), DEFAULT_MAJOR_DIM));
318 m_textNumBtns->SetValue(wxString::Format(wxT("%u"), DEFAULT_NUM_ENTRIES));
319 m_textLabel->SetValue(wxT("I'm a radiobox"));
320 m_textLabelBtns->SetValue(wxT("item"));
32b8ec41 321
3998c74b 322 m_chkSpecifyRows->SetValue(false);
3bfa7be9
VZ
323 m_chkEnableItem->SetValue(true);
324 m_chkShowItem->SetValue(true);
32b8ec41
VZ
325 m_radioDir->SetSelection(RadioDir_Default);
326}
327
328void RadioWidgetsPage::CreateRadio()
329{
330 int sel;
331 if ( m_radio )
332 {
333 sel = m_radio->GetSelection();
334
12a3f227 335 m_sizerRadio->Detach( m_radio );
32b8ec41
VZ
336
337 delete m_radio;
338 }
339 else // first time creation, no old selection to preserve
340 {
341 sel = -1;
342 }
343
344 unsigned long count;
345 if ( !m_textNumBtns->GetValue().ToULong(&count) )
346 {
9a83f860 347 wxLogWarning(wxT("Should have a valid number for number of items."));
32b8ec41
VZ
348
349 // fall back to default
350 count = DEFAULT_NUM_ENTRIES;
351 }
352
353 unsigned long majorDim;
354 if ( !m_textMajorDim->GetValue().ToULong(&majorDim) )
355 {
9a83f860 356 wxLogWarning(wxT("Should have a valid major dimension number."));
32b8ec41
VZ
357
358 // fall back to default
359 majorDim = DEFAULT_MAJOR_DIM;
360 }
361
362 wxString *items = new wxString[count];
363
364 wxString labelBtn = m_textLabelBtns->GetValue();
365 for ( size_t n = 0; n < count; n++ )
366 {
9a83f860 367 items[n] = wxString::Format(wxT("%s %lu"),
0c61716c 368 labelBtn.c_str(), (unsigned long)n + 1);
32b8ec41
VZ
369 }
370
3998c74b
VZ
371 int flags = m_chkSpecifyRows->GetValue() ? wxRA_SPECIFY_ROWS
372 : wxRA_SPECIFY_COLS;
32b8ec41 373
1301e228
VZ
374 flags |= ms_defaultFlags;
375
32b8ec41
VZ
376#ifdef wxRA_LEFTTORIGHT
377 switch ( m_radioDir->GetSelection() )
378 {
379 default:
9a83f860 380 wxFAIL_MSG( wxT("unexpected wxRadioBox layout direction") );
32b8ec41
VZ
381 // fall through
382
383 case RadioDir_Default:
384 break;
385
386 case RadioDir_LtoR:
387 flags |= wxRA_LEFTTORIGHT;
388 break;
389
390 case RadioDir_TtoB:
391 flags |= wxRA_TOPTOBOTTOM;
392 break;
393 }
394#endif // wxRA_LEFTTORIGHT
395
396 m_radio = new wxRadioBox(this, RadioPage_Radio,
397 m_textLabel->GetValue(),
398 wxDefaultPosition, wxDefaultSize,
399 count, items,
400 majorDim,
401 flags);
402
403 delete [] items;
404
405 if ( sel >= 0 && (size_t)sel < count )
406 {
407 m_radio->SetSelection(sel);
408 }
409
410 m_sizerRadio->Add(m_radio, 1, wxGROW);
411 m_sizerRadio->Layout();
8b6d589d 412
3bfa7be9
VZ
413 m_chkEnableItem->SetValue(true);
414 m_chkEnableItem->SetValue(true);
32b8ec41
VZ
415}
416
417// ----------------------------------------------------------------------------
418// event handlers
419// ----------------------------------------------------------------------------
420
421void RadioWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
422{
423 Reset();
424
425 CreateRadio();
426}
427
c02e5a31 428void RadioWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
32b8ec41
VZ
429{
430 CreateRadio();
431}
432
433void RadioWidgetsPage::OnRadioBox(wxCommandEvent& event)
434{
435 int sel = m_radio->GetSelection();
dacaa6f1
JS
436 int event_sel = event.GetSelection();
437 wxUnusedVar(event_sel);
32b8ec41 438
9a83f860 439 wxLogMessage(wxT("Radiobox selection changed, now %d"), sel);
32b8ec41 440
dacaa6f1 441 wxASSERT_MSG( sel == event_sel,
9a83f860 442 wxT("selection should be the same in event and radiobox") );
32b8ec41 443
9a83f860 444 m_textCurSel->SetValue(wxString::Format(wxT("%d"), sel));
32b8ec41
VZ
445}
446
447void RadioWidgetsPage::OnButtonRecreate(wxCommandEvent& WXUNUSED(event))
448{
449 CreateRadio();
450}
451
452void RadioWidgetsPage::OnButtonSetLabel(wxCommandEvent& WXUNUSED(event))
453{
454 m_radio->wxControl::SetLabel(m_textLabel->GetValue());
455}
456
457void RadioWidgetsPage::OnButtonSelection(wxCommandEvent& WXUNUSED(event))
458{
459 unsigned long sel;
460 if ( !m_textSel->GetValue().ToULong(&sel) ||
461 (sel >= (size_t)m_radio->GetCount()) )
462 {
9a83f860 463 wxLogWarning(wxT("Invalid number specified as new selection."));
32b8ec41
VZ
464 }
465 else
466 {
467 m_radio->SetSelection(sel);
468 }
469}
470
3bfa7be9
VZ
471void RadioWidgetsPage::OnEnableItem(wxCommandEvent& event)
472{
473 m_radio->Enable(TEST_BUTTON, event.IsChecked());
474}
475
476void RadioWidgetsPage::OnShowItem(wxCommandEvent& event)
477{
478 m_radio->Show(TEST_BUTTON, event.IsChecked());
479}
480
32b8ec41
VZ
481void RadioWidgetsPage::OnUpdateUIUpdate(wxUpdateUIEvent& event)
482{
483 unsigned long n;
484 event.Enable( m_textNumBtns->GetValue().ToULong(&n) &&
485 m_textMajorDim->GetValue().ToULong(&n) );
486}
487
488void RadioWidgetsPage::OnUpdateUISelection(wxUpdateUIEvent& event)
489{
490 unsigned long n;
491 event.Enable( m_textSel->GetValue().ToULong(&n) &&
492 (n < (size_t)m_radio->GetCount()) );
493}
494
495void RadioWidgetsPage::OnUpdateUIReset(wxUpdateUIEvent& event)
496{
497 // only enable it if something is not set to default
3998c74b 498 bool enable = m_chkSpecifyRows->GetValue();
32b8ec41
VZ
499
500 if ( !enable )
501 {
502 unsigned long numEntries;
503
504 enable = !m_textNumBtns->GetValue().ToULong(&numEntries) ||
505 numEntries != DEFAULT_NUM_ENTRIES;
506
507 if ( !enable )
508 {
509 unsigned long majorDim;
510
511 enable = !m_textMajorDim->GetValue().ToULong(&majorDim) ||
512 majorDim != DEFAULT_MAJOR_DIM;
513 }
514 }
515
516 event.Enable(enable);
517}
518
3bfa7be9
VZ
519void RadioWidgetsPage::OnUpdateUIEnableItem(wxUpdateUIEvent& event)
520{
9a83f860
VZ
521 event.SetText(m_radio->IsItemEnabled(TEST_BUTTON) ? wxT("Disable &2nd item")
522 : wxT("Enable &2nd item"));
3bfa7be9
VZ
523}
524
525void RadioWidgetsPage::OnUpdateUIShowItem(wxUpdateUIEvent& event)
526{
9a83f860
VZ
527 event.SetText(m_radio->IsItemShown(TEST_BUTTON) ? wxT("Hide 2nd &item")
528 : wxT("Show 2nd &item"));
3bfa7be9
VZ
529}
530
61c083e7 531#endif // wxUSE_RADIOBOX