No changes, just add a couple of #if wxUSE_COMMANDLINKBUTTON tests.
[wxWidgets.git] / samples / widgets / button.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Program: wxWidgets Widgets Sample
3 // Name: button.cpp
4 // Purpose: Part of the widgets sample showing wxButton
5 // Author: Vadim Zeitlin
6 // Created: 10.04.01
7 // Id: $Id$
8 // Copyright: (c) 2001 Vadim Zeitlin
9 // Licence: wxWindows licence
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
27 // for all others, include the necessary headers
28 #ifndef WX_PRECOMP
29 #include "wx/app.h"
30 #include "wx/log.h"
31
32 #include "wx/bmpbuttn.h"
33 #include "wx/button.h"
34 #include "wx/checkbox.h"
35 #include "wx/radiobox.h"
36 #include "wx/statbox.h"
37 #include "wx/textctrl.h"
38 #endif
39
40 #include "wx/artprov.h"
41 #include "wx/sizer.h"
42 #include "wx/dcmemory.h"
43 #include "wx/commandlinkbutton.h"
44
45 #include "widgets.h"
46
47 #include "icons/button.xpm"
48
49 // ----------------------------------------------------------------------------
50 // constants
51 // ----------------------------------------------------------------------------
52
53 // control ids
54 enum
55 {
56 ButtonPage_Reset = wxID_HIGHEST,
57 ButtonPage_ChangeLabel,
58 ButtonPage_ChangeNote,
59 ButtonPage_Button
60 };
61
62 // radio boxes
63 enum
64 {
65 ButtonImagePos_Left,
66 ButtonImagePos_Right,
67 ButtonImagePos_Top,
68 ButtonImagePos_Bottom
69 };
70
71 enum
72 {
73 ButtonHAlign_Left,
74 ButtonHAlign_Centre,
75 ButtonHAlign_Right
76 };
77
78 enum
79 {
80 ButtonVAlign_Top,
81 ButtonVAlign_Centre,
82 ButtonVAlign_Bottom
83 };
84
85 // ----------------------------------------------------------------------------
86 // ButtonWidgetsPage
87 // ----------------------------------------------------------------------------
88
89 class ButtonWidgetsPage : public WidgetsPage
90 {
91 public:
92 ButtonWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
93 virtual ~ButtonWidgetsPage(){};
94
95 virtual wxControl *GetWidget() const { return m_button; }
96 virtual void RecreateWidget() { CreateButton(); }
97
98 // lazy creation of the content
99 virtual void CreateContent();
100
101 protected:
102 // event handlers
103 void OnCheckOrRadioBox(wxCommandEvent& event);
104
105 void OnButton(wxCommandEvent& event);
106 void OnButtonReset(wxCommandEvent& event);
107 void OnButtonChangeLabel(wxCommandEvent& event);
108 void OnButtonChangeNote(wxCommandEvent& event);
109
110 // reset the wxButton parameters
111 void Reset();
112
113 // (re)create the wxButton
114 void CreateButton();
115
116 // add m_button to m_sizerButton using current value of m_chkFit
117 void AddButtonToSizer();
118
119 // helper function: create a bitmap for wxBitmapButton
120 wxBitmap CreateBitmap(const wxString& label);
121
122
123 // the controls
124 // ------------
125
126 // the check/radio boxes for styles
127 wxCheckBox *m_chkBitmapOnly,
128 *m_chkTextAndBitmap,
129 *m_chkFit,
130 *m_chkAuthNeeded,
131 #if wxUSE_COMMANDLINKBUTTON
132 *m_chkCommandLink,
133 #endif // wxUSE_COMMANDLINKBUTTON
134 *m_chkDefault;
135
136 // more checkboxes for wxBitmapButton only
137 wxCheckBox *m_chkUsePressed,
138 *m_chkUseFocused,
139 *m_chkUseCurrent,
140 *m_chkUseDisabled;
141
142 // and an image position choice used if m_chkTextAndBitmap is on
143 wxRadioBox *m_radioImagePos;
144
145 wxRadioBox *m_radioHAlign,
146 *m_radioVAlign;
147
148 // the button itself and the sizer it is in
149 wxButton *m_button;
150
151 #if wxUSE_COMMANDLINKBUTTON
152 // same as m_button or NULL if not showing a command link button currently
153 wxCommandLinkButton *m_cmdLnkButton;
154 #endif // wxUSE_COMMANDLINKBUTTON
155
156 wxSizer *m_sizerButton;
157
158 // the text entries for command parameters
159 wxTextCtrl *m_textLabel;
160
161 #if wxUSE_COMMANDLINKBUTTON
162 wxTextCtrl *m_textNote;
163
164 // used to hide or show button for changing note
165 wxSizer *m_sizerNote;
166 #endif // wxUSE_COMMANDLINKBUTTON
167
168 private:
169 DECLARE_EVENT_TABLE()
170 DECLARE_WIDGETS_PAGE(ButtonWidgetsPage)
171 };
172
173 // ----------------------------------------------------------------------------
174 // event tables
175 // ----------------------------------------------------------------------------
176
177 BEGIN_EVENT_TABLE(ButtonWidgetsPage, WidgetsPage)
178 EVT_BUTTON(ButtonPage_Button, ButtonWidgetsPage::OnButton)
179
180 EVT_BUTTON(ButtonPage_Reset, ButtonWidgetsPage::OnButtonReset)
181 EVT_BUTTON(ButtonPage_ChangeLabel, ButtonWidgetsPage::OnButtonChangeLabel)
182 EVT_BUTTON(ButtonPage_ChangeNote, ButtonWidgetsPage::OnButtonChangeNote)
183
184 EVT_CHECKBOX(wxID_ANY, ButtonWidgetsPage::OnCheckOrRadioBox)
185 EVT_RADIOBOX(wxID_ANY, ButtonWidgetsPage::OnCheckOrRadioBox)
186 END_EVENT_TABLE()
187
188 // ============================================================================
189 // implementation
190 // ============================================================================
191
192 #if defined(__WXUNIVERSAL__)
193 #define FAMILY_CTRLS UNIVERSAL_CTRLS
194 #else
195 #define FAMILY_CTRLS NATIVE_CTRLS
196 #endif
197
198 IMPLEMENT_WIDGETS_PAGE(ButtonWidgetsPage, wxT("Button"), FAMILY_CTRLS );
199
200 ButtonWidgetsPage::ButtonWidgetsPage(WidgetsBookCtrl *book,
201 wxImageList *imaglist)
202 : WidgetsPage(book, imaglist, button_xpm)
203 {
204 // init everything
205 m_chkBitmapOnly =
206 m_chkTextAndBitmap =
207 m_chkFit =
208 m_chkAuthNeeded =
209 #if wxUSE_COMMANDLINKBUTTON
210 m_chkCommandLink =
211 #endif // wxUSE_COMMANDLINKBUTTON
212 m_chkDefault =
213 m_chkUsePressed =
214 m_chkUseFocused =
215 m_chkUseCurrent =
216 m_chkUseDisabled = (wxCheckBox *)NULL;
217
218 m_radioImagePos =
219 m_radioHAlign =
220 m_radioVAlign = (wxRadioBox *)NULL;
221
222 m_textLabel = (wxTextCtrl *)NULL;
223
224 m_button = (wxButton *)NULL;
225 m_sizerButton = (wxSizer *)NULL;
226 }
227
228 void ButtonWidgetsPage::CreateContent()
229 {
230 wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
231
232 // left pane
233 wxStaticBox *box = new wxStaticBox(this, wxID_ANY, wxT("&Set style"));
234
235 wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
236
237 m_chkBitmapOnly = CreateCheckBoxAndAddToSizer(sizerLeft, "&Bitmap only");
238 m_chkTextAndBitmap = CreateCheckBoxAndAddToSizer(sizerLeft, "Text &and bitmap");
239 m_chkFit = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("&Fit exactly"));
240 m_chkAuthNeeded = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("Require a&uth"));
241 #if wxUSE_COMMANDLINKBUTTON
242 m_chkCommandLink = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("Use command &link button"));
243 #endif
244 m_chkDefault = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("&Default"));
245
246 sizerLeft->AddSpacer(5);
247
248 wxSizer *sizerUseLabels =
249 new wxStaticBoxSizer(wxVERTICAL, this,
250 "&Use the following bitmaps in addition to the normal one?");
251 m_chkUsePressed = CreateCheckBoxAndAddToSizer(sizerUseLabels,
252 "&Pressed (small help icon)");
253 m_chkUseFocused = CreateCheckBoxAndAddToSizer(sizerUseLabels,
254 "&Focused (small error icon)");
255 m_chkUseCurrent = CreateCheckBoxAndAddToSizer(sizerUseLabels,
256 "&Current (small warning icon)");
257 m_chkUseDisabled = CreateCheckBoxAndAddToSizer(sizerUseLabels,
258 "&Disabled (broken image icon)");
259 sizerLeft->Add(sizerUseLabels, wxSizerFlags().Expand().Border());
260
261 sizerLeft->AddSpacer(10);
262
263 static const wxString dirs[] =
264 {
265 "left", "right", "top", "bottom",
266 };
267 m_radioImagePos = new wxRadioBox(this, wxID_ANY, "Image &position",
268 wxDefaultPosition, wxDefaultSize,
269 WXSIZEOF(dirs), dirs);
270 sizerLeft->Add(m_radioImagePos, 0, wxGROW | wxALL, 5);
271 sizerLeft->AddSpacer(15);
272
273 // should be in sync with enums Button[HV]Align!
274 static const wxString halign[] =
275 {
276 wxT("left"),
277 wxT("centre"),
278 wxT("right"),
279 };
280
281 static const wxString valign[] =
282 {
283 wxT("top"),
284 wxT("centre"),
285 wxT("bottom"),
286 };
287
288 m_radioHAlign = new wxRadioBox(this, wxID_ANY, wxT("&Horz alignment"),
289 wxDefaultPosition, wxDefaultSize,
290 WXSIZEOF(halign), halign);
291 m_radioVAlign = new wxRadioBox(this, wxID_ANY, wxT("&Vert alignment"),
292 wxDefaultPosition, wxDefaultSize,
293 WXSIZEOF(valign), valign);
294
295 sizerLeft->Add(m_radioHAlign, 0, wxGROW | wxALL, 5);
296 sizerLeft->Add(m_radioVAlign, 0, wxGROW | wxALL, 5);
297
298 sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
299
300 wxButton *btn = new wxButton(this, ButtonPage_Reset, wxT("&Reset"));
301 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
302
303 // middle pane
304 wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, wxT("&Operations"));
305 wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
306
307 wxSizer *sizerRow = CreateSizerWithTextAndButton(ButtonPage_ChangeLabel,
308 wxT("Change label"),
309 wxID_ANY,
310 &m_textLabel);
311 m_textLabel->SetValue(wxT("&Press me!"));
312 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
313
314 #if wxUSE_COMMANDLINKBUTTON
315 m_sizerNote = CreateSizerWithTextAndButton(ButtonPage_ChangeNote,
316 wxT("Change note"),
317 wxID_ANY,
318 &m_textNote);
319 m_textNote->SetValue(wxT("Writes down button clicks in the log."));
320
321 sizerMiddle->Add(m_sizerNote, 0, wxALL | wxGROW, 5);
322 #endif
323
324 // right pane
325 m_sizerButton = new wxBoxSizer(wxHORIZONTAL);
326 m_sizerButton->SetMinSize(150, 0);
327
328 // the 3 panes panes compose the window
329 sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
330 sizerTop->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
331 sizerTop->Add(m_sizerButton, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
332
333 // do create the main control
334 Reset();
335 CreateButton();
336
337 SetSizer(sizerTop);
338 }
339
340 // ----------------------------------------------------------------------------
341 // operations
342 // ----------------------------------------------------------------------------
343
344 void ButtonWidgetsPage::Reset()
345 {
346 m_chkBitmapOnly->SetValue(false);
347 m_chkFit->SetValue(true);
348 m_chkAuthNeeded->SetValue(false);
349 m_chkTextAndBitmap->SetValue(false);
350 m_chkDefault->SetValue(false);
351 #if wxUSE_COMMANDLINKBUTTON
352 m_chkCommandLink->SetValue(false);
353 #endif
354
355 m_chkUsePressed->SetValue(true);
356 m_chkUseFocused->SetValue(true);
357 m_chkUseCurrent->SetValue(true);
358 m_chkUseDisabled->SetValue(true);
359
360 m_radioImagePos->SetSelection(ButtonImagePos_Left);
361 m_radioHAlign->SetSelection(ButtonHAlign_Centre);
362 m_radioVAlign->SetSelection(ButtonVAlign_Centre);
363 }
364
365 void ButtonWidgetsPage::CreateButton()
366 {
367 wxString label;
368 if ( m_button )
369 {
370 #if wxUSE_COMMANDLINKBUTTON
371 if ( m_cmdLnkButton )
372 label = m_cmdLnkButton->GetMainLabel();
373 else
374 #endif
375 label = m_button->GetLabel();
376
377 size_t count = m_sizerButton->GetChildren().GetCount();
378 for ( size_t n = 0; n < count; n++ )
379 {
380 m_sizerButton->Remove( 0 );
381 }
382
383 delete m_button;
384 }
385
386 if ( label.empty() )
387 {
388 // creating for the first time or recreating a button after bitmap
389 // button
390 label = m_textLabel->GetValue();
391 }
392
393 int flags = ms_defaultFlags;
394 switch ( m_radioHAlign->GetSelection() )
395 {
396 case ButtonHAlign_Left:
397 flags |= wxBU_LEFT;
398 break;
399
400 default:
401 wxFAIL_MSG(wxT("unexpected radiobox selection"));
402 // fall through
403
404 case ButtonHAlign_Centre:
405 break;
406
407 case ButtonHAlign_Right:
408 flags |= wxBU_RIGHT;
409 break;
410 }
411
412 switch ( m_radioVAlign->GetSelection() )
413 {
414 case ButtonVAlign_Top:
415 flags |= wxBU_TOP;
416 break;
417
418 default:
419 wxFAIL_MSG(wxT("unexpected radiobox selection"));
420 // fall through
421
422 case ButtonVAlign_Centre:
423 // centre vertical alignment is the default (no style)
424 break;
425
426 case ButtonVAlign_Bottom:
427 flags |= wxBU_BOTTOM;
428 break;
429 }
430
431 #if wxUSE_COMMANDLINKBUTTON
432 m_sizerNote->Show(m_chkCommandLink->GetValue());
433 #endif
434
435 bool showsBitmap = false;
436 if ( m_chkBitmapOnly->GetValue() )
437 {
438 showsBitmap = true;
439
440 wxBitmapButton *bbtn = new wxBitmapButton(this, ButtonPage_Button,
441 CreateBitmap(wxT("normal")));
442 if ( m_chkUsePressed->GetValue() )
443 bbtn->SetBitmapPressed(CreateBitmap(wxT("pushed")));
444 if ( m_chkUseFocused->GetValue() )
445 bbtn->SetBitmapFocus(CreateBitmap(wxT("focused")));
446 if ( m_chkUseCurrent->GetValue() )
447 bbtn->SetBitmapCurrent(CreateBitmap(wxT("hover")));
448 if ( m_chkUseDisabled->GetValue() )
449 bbtn->SetBitmapDisabled(CreateBitmap(wxT("disabled")));
450 m_button = bbtn;
451 #if wxUSE_COMMANDLINKBUTTON
452 m_cmdLnkButton = NULL;
453 #endif
454 }
455 else // normal button
456 {
457 #if wxUSE_COMMANDLINKBUTTON
458 m_cmdLnkButton = NULL;
459
460 if ( m_chkCommandLink->GetValue() )
461 {
462 m_cmdLnkButton = new wxCommandLinkButton(this, ButtonPage_Button,
463 label,
464 m_textNote->GetValue(),
465 wxDefaultPosition,
466 wxDefaultSize,
467 flags);
468 m_button = m_cmdLnkButton;
469 }
470 else
471 #endif // wxUSE_COMMANDLINKBUTTON
472 {
473 m_button = new wxButton(this, ButtonPage_Button, label,
474 wxDefaultPosition, wxDefaultSize,
475 flags);
476 }
477 }
478
479 if ( !showsBitmap && m_chkTextAndBitmap->GetValue() )
480 {
481 showsBitmap = true;
482
483 static const wxDirection positions[] =
484 {
485 wxLEFT, wxRIGHT, wxTOP, wxBOTTOM
486 };
487
488 m_button->SetBitmap(wxArtProvider::GetIcon(wxART_INFORMATION),
489 positions[m_radioImagePos->GetSelection()]);
490
491 if ( m_chkUsePressed->GetValue() )
492 m_button->SetBitmapPressed(wxArtProvider::GetIcon(wxART_HELP));
493 if ( m_chkUseFocused->GetValue() )
494 m_button->SetBitmapFocus(wxArtProvider::GetIcon(wxART_ERROR));
495 if ( m_chkUseCurrent->GetValue() )
496 m_button->SetBitmapCurrent(wxArtProvider::GetIcon(wxART_WARNING));
497 if ( m_chkUseDisabled->GetValue() )
498 m_button->SetBitmapDisabled(wxArtProvider::GetIcon(wxART_MISSING_IMAGE));
499 }
500
501 m_chkUsePressed->Enable(showsBitmap);
502 m_chkUseFocused->Enable(showsBitmap);
503 m_chkUseCurrent->Enable(showsBitmap);
504 m_chkUseDisabled->Enable(showsBitmap);
505
506 if ( m_chkAuthNeeded->GetValue() )
507 m_button->SetAuthNeeded();
508
509 if ( m_chkDefault->GetValue() )
510 m_button->SetDefault();
511
512 AddButtonToSizer();
513
514 m_sizerButton->Layout();
515 }
516
517 void ButtonWidgetsPage::AddButtonToSizer()
518 {
519 if ( m_chkFit->GetValue() )
520 {
521 m_sizerButton->AddStretchSpacer(1);
522 m_sizerButton->Add(m_button, wxSizerFlags(0).Centre().Border());
523 m_sizerButton->AddStretchSpacer(1);
524 }
525 else // take up the entire space
526 {
527 m_sizerButton->Add(m_button, wxSizerFlags(1).Expand().Border());
528 }
529 }
530
531 // ----------------------------------------------------------------------------
532 // event handlers
533 // ----------------------------------------------------------------------------
534
535 void ButtonWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
536 {
537 Reset();
538
539 CreateButton();
540 }
541
542 void ButtonWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
543 {
544 CreateButton();
545 Layout(); // make sure the text field for changing note displays correctly.
546 }
547
548 void ButtonWidgetsPage::OnButtonChangeLabel(wxCommandEvent& WXUNUSED(event))
549 {
550 #if wxUSE_COMMANDLINKBUTTON
551 if ( m_cmdLnkButton )
552 m_cmdLnkButton->SetMainLabel(m_textLabel->GetValue());
553 else
554 #endif // wxUSE_COMMANDLINKBUTTON
555 m_button->SetLabel(m_textLabel->GetValue());
556
557 m_sizerButton->Layout();
558 }
559
560 void ButtonWidgetsPage::OnButtonChangeNote(wxCommandEvent& WXUNUSED(event))
561 {
562 #if wxUSE_COMMANDLINKBUTTON
563 m_cmdLnkButton->SetNote(m_textNote->GetValue());
564
565 m_sizerButton->Layout();
566 #endif // wxUSE_COMMANDLINKBUTTON
567 }
568
569 void ButtonWidgetsPage::OnButton(wxCommandEvent& WXUNUSED(event))
570 {
571 wxLogMessage(wxT("Test button clicked."));
572 }
573
574 // ----------------------------------------------------------------------------
575 // bitmap button stuff
576 // ----------------------------------------------------------------------------
577
578 wxBitmap ButtonWidgetsPage::CreateBitmap(const wxString& label)
579 {
580 wxBitmap bmp(180, 70); // shouldn't hardcode but it's simpler like this
581 wxMemoryDC dc;
582 dc.SelectObject(bmp);
583 dc.SetBackground(wxBrush(*wxCYAN));
584 dc.Clear();
585 dc.SetTextForeground(*wxBLACK);
586 dc.DrawLabel(wxStripMenuCodes(m_textLabel->GetValue()) + wxT("\n")
587 wxT("(") + label + wxT(" state)"),
588 wxArtProvider::GetBitmap(wxART_INFORMATION),
589 wxRect(10, 10, bmp.GetWidth() - 20, bmp.GetHeight() - 20),
590 wxALIGN_CENTRE);
591
592 return bmp;
593 }
594