toggle.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Program: wxWidgets Widgets Sample
  3. // Name: toggle.cpp
  4. // Purpose: Part of the widgets sample showing toggle control
  5. // Author: Dimitri Schoolwerth, Vadim Zeitlin
  6. // Created: 27 Sep 2003
  7. // Copyright: (c) 2006 Wlodzmierz Skiba
  8. // Licence: wxWindows licence
  9. /////////////////////////////////////////////////////////////////////////////
  10. // ============================================================================
  11. // declarations
  12. // ============================================================================
  13. // ----------------------------------------------------------------------------
  14. // headers
  15. // ----------------------------------------------------------------------------
  16. // for compilers that support precompilation, includes "wx/wx.h".
  17. #include "wx/wxprec.h"
  18. #ifdef __BORLANDC__
  19. #pragma hdrstop
  20. #endif
  21. #if wxUSE_TOGGLEBTN
  22. #include "wx/tglbtn.h"
  23. #include "widgets.h"
  24. // for all others, include the necessary headers
  25. #ifndef WX_PRECOMP
  26. #include "wx/button.h"
  27. #include "wx/checkbox.h"
  28. #include "wx/radiobox.h"
  29. #include "wx/statbox.h"
  30. #include "wx/textctrl.h"
  31. #endif
  32. #include "wx/artprov.h"
  33. #include "wx/sizer.h"
  34. #include "wx/dcmemory.h"
  35. #include "icons/toggle.xpm"
  36. // ----------------------------------------------------------------------------
  37. // constants
  38. // ----------------------------------------------------------------------------
  39. // control ids
  40. enum
  41. {
  42. TogglePage_Reset = wxID_HIGHEST,
  43. TogglePage_ChangeLabel,
  44. TogglePage_Picker
  45. };
  46. // radio boxes
  47. enum
  48. {
  49. ToggleImagePos_Left,
  50. ToggleImagePos_Right,
  51. ToggleImagePos_Top,
  52. ToggleImagePos_Bottom
  53. };
  54. enum
  55. {
  56. ToggleHAlign_Left,
  57. ToggleHAlign_Centre,
  58. ToggleHAlign_Right
  59. };
  60. enum
  61. {
  62. ToggleVAlign_Top,
  63. ToggleVAlign_Centre,
  64. ToggleVAlign_Bottom
  65. };
  66. // ----------------------------------------------------------------------------
  67. // CheckBoxWidgetsPage
  68. // ----------------------------------------------------------------------------
  69. class ToggleWidgetsPage : public WidgetsPage
  70. {
  71. public:
  72. ToggleWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
  73. virtual ~ToggleWidgetsPage(){};
  74. virtual wxControl *GetWidget() const { return m_toggle; }
  75. virtual void RecreateWidget() { CreateToggle(); }
  76. // lazy creation of the content
  77. virtual void CreateContent();
  78. protected:
  79. // event handlers
  80. void OnCheckOrRadioBox(wxCommandEvent& event);
  81. // event handlers
  82. void OnButtonReset(wxCommandEvent& event);
  83. void OnButtonChangeLabel(wxCommandEvent& event);
  84. // reset the toggle parameters
  85. void Reset();
  86. // (re)create the toggle
  87. void CreateToggle();
  88. // helper function: create a bitmap for wxBitmapToggleButton
  89. wxBitmap CreateBitmap(const wxString& label);
  90. // the controls
  91. // ------------
  92. #if wxUSE_MARKUP
  93. wxCheckBox *m_chkUseMarkup;
  94. #endif // wxUSE_MARKUP
  95. #ifdef wxHAS_BITMAPTOGGLEBUTTON
  96. // the check/radio boxes for styles
  97. wxCheckBox *m_chkBitmapOnly,
  98. *m_chkTextAndBitmap,
  99. *m_chkFit,
  100. *m_chkUseBitmapClass;
  101. // more checkboxes for wxBitmapToggleButton only
  102. wxCheckBox *m_chkUsePressed,
  103. *m_chkUseFocused,
  104. *m_chkUseCurrent,
  105. *m_chkUseDisabled;
  106. // and an image position choice used if m_chkTextAndBitmap is on
  107. wxRadioBox *m_radioImagePos;
  108. wxRadioBox *m_radioHAlign,
  109. *m_radioVAlign;
  110. #endif // wxHAS_BITMAPTOGGLEBUTTON
  111. // the checkbox itself and the sizer it is in
  112. #ifdef wxHAS_ANY_BUTTON
  113. wxToggleButton *m_toggle;
  114. #else
  115. wxToggleButtonBase *m_toggle;
  116. #endif // wxHAS_ANY_BUTTON
  117. wxSizer *m_sizerToggle;
  118. // the text entries for command parameters
  119. wxTextCtrl *m_textLabel;
  120. private:
  121. wxDECLARE_EVENT_TABLE();
  122. DECLARE_WIDGETS_PAGE(ToggleWidgetsPage)
  123. };
  124. // ----------------------------------------------------------------------------
  125. // event tables
  126. // ----------------------------------------------------------------------------
  127. wxBEGIN_EVENT_TABLE(ToggleWidgetsPage, WidgetsPage)
  128. EVT_BUTTON(TogglePage_Reset, ToggleWidgetsPage::OnButtonReset)
  129. EVT_BUTTON(TogglePage_ChangeLabel, ToggleWidgetsPage::OnButtonChangeLabel)
  130. EVT_CHECKBOX(wxID_ANY, ToggleWidgetsPage::OnCheckOrRadioBox)
  131. EVT_RADIOBOX(wxID_ANY, ToggleWidgetsPage::OnCheckOrRadioBox)
  132. wxEND_EVENT_TABLE()
  133. // ============================================================================
  134. // implementation
  135. // ============================================================================
  136. #if defined(__WXUNIVERSAL__)
  137. #define FAMILY_CTRLS UNIVERSAL_CTRLS
  138. #else
  139. #define FAMILY_CTRLS NATIVE_CTRLS
  140. #endif
  141. IMPLEMENT_WIDGETS_PAGE(ToggleWidgetsPage, wxT("ToggleButton"),
  142. FAMILY_CTRLS
  143. );
  144. ToggleWidgetsPage::ToggleWidgetsPage(WidgetsBookCtrl *book,
  145. wxImageList *imaglist)
  146. :WidgetsPage(book, imaglist, toggle_xpm)
  147. {
  148. #if wxUSE_MARKUP
  149. m_chkUseMarkup = (wxCheckBox *)NULL;
  150. #endif // wxUSE_MARKUP
  151. #ifdef wxHAS_BITMAPTOGGLEBUTTON
  152. // init everything
  153. m_chkBitmapOnly =
  154. m_chkTextAndBitmap =
  155. m_chkFit =
  156. m_chkUseBitmapClass =
  157. m_chkUsePressed =
  158. m_chkUseFocused =
  159. m_chkUseCurrent =
  160. m_chkUseDisabled = (wxCheckBox *)NULL;
  161. m_radioImagePos =
  162. m_radioHAlign =
  163. m_radioVAlign = (wxRadioBox *)NULL;
  164. #endif // wxHAS_BITMAPTOGGLEBUTTON
  165. m_textLabel = (wxTextCtrl *)NULL;
  166. m_toggle = (wxToggleButton *)NULL;
  167. m_sizerToggle = (wxSizer *)NULL;
  168. }
  169. void ToggleWidgetsPage::CreateContent()
  170. {
  171. wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
  172. // left pane
  173. wxStaticBox *box = new wxStaticBox(this, wxID_ANY, wxT("Styles"));
  174. wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
  175. #ifdef wxHAS_BITMAPTOGGLEBUTTON
  176. m_chkBitmapOnly = CreateCheckBoxAndAddToSizer(sizerLeft, "&Bitmap only");
  177. m_chkTextAndBitmap = CreateCheckBoxAndAddToSizer(sizerLeft, "Text &and bitmap");
  178. m_chkFit = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("&Fit exactly"));
  179. #endif // wxHAS_BITMAPTOGGLEBUTTON
  180. #if wxUSE_MARKUP
  181. m_chkUseMarkup = CreateCheckBoxAndAddToSizer(sizerLeft, "Interpret &markup");
  182. #endif // wxUSE_MARKUP
  183. #ifdef wxHAS_BITMAPTOGGLEBUTTON
  184. m_chkUseBitmapClass = CreateCheckBoxAndAddToSizer(sizerLeft,
  185. "Use wxBitmapToggleButton");
  186. m_chkUseBitmapClass->SetValue(true);
  187. sizerLeft->AddSpacer(5);
  188. wxSizer *sizerUseLabels =
  189. new wxStaticBoxSizer(wxVERTICAL, this,
  190. "&Use the following bitmaps in addition to the normal one?");
  191. m_chkUsePressed = CreateCheckBoxAndAddToSizer(sizerUseLabels,
  192. "&Pressed (small help icon)");
  193. m_chkUseFocused = CreateCheckBoxAndAddToSizer(sizerUseLabels,
  194. "&Focused (small error icon)");
  195. m_chkUseCurrent = CreateCheckBoxAndAddToSizer(sizerUseLabels,
  196. "&Current (small warning icon)");
  197. m_chkUseDisabled = CreateCheckBoxAndAddToSizer(sizerUseLabels,
  198. "&Disabled (broken image icon)");
  199. sizerLeft->Add(sizerUseLabels, wxSizerFlags().Expand().Border());
  200. sizerLeft->AddSpacer(10);
  201. static const wxString dirs[] =
  202. {
  203. "left", "right", "top", "bottom",
  204. };
  205. m_radioImagePos = new wxRadioBox(this, wxID_ANY, "Image &position",
  206. wxDefaultPosition, wxDefaultSize,
  207. WXSIZEOF(dirs), dirs);
  208. sizerLeft->Add(m_radioImagePos, 0, wxGROW | wxALL, 5);
  209. sizerLeft->AddSpacer(15);
  210. // should be in sync with enums Toggle[HV]Align!
  211. static const wxString halign[] =
  212. {
  213. wxT("left"),
  214. wxT("centre"),
  215. wxT("right"),
  216. };
  217. static const wxString valign[] =
  218. {
  219. wxT("top"),
  220. wxT("centre"),
  221. wxT("bottom"),
  222. };
  223. m_radioHAlign = new wxRadioBox(this, wxID_ANY, wxT("&Horz alignment"),
  224. wxDefaultPosition, wxDefaultSize,
  225. WXSIZEOF(halign), halign);
  226. m_radioVAlign = new wxRadioBox(this, wxID_ANY, wxT("&Vert alignment"),
  227. wxDefaultPosition, wxDefaultSize,
  228. WXSIZEOF(valign), valign);
  229. sizerLeft->Add(m_radioHAlign, 0, wxGROW | wxALL, 5);
  230. sizerLeft->Add(m_radioVAlign, 0, wxGROW | wxALL, 5);
  231. #endif // wxHAS_BITMAPTOGGLEBUTTON
  232. sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
  233. wxButton *btn = new wxButton(this, TogglePage_Reset, wxT("&Reset"));
  234. sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
  235. // middle pane
  236. wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, wxT("&Operations"));
  237. wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
  238. wxSizer *sizerRow = CreateSizerWithTextAndButton(TogglePage_ChangeLabel,
  239. wxT("Change label"),
  240. wxID_ANY,
  241. &m_textLabel);
  242. m_textLabel->SetValue(wxT("&Toggle me!"));
  243. sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
  244. // right pane
  245. m_sizerToggle = new wxBoxSizer(wxHORIZONTAL);
  246. m_sizerToggle->SetMinSize(150, 0);
  247. // the 3 panes panes compose the window
  248. sizerTop->Add(sizerLeft, 0, (wxALL & ~wxLEFT), 10);
  249. sizerTop->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
  250. sizerTop->Add(m_sizerToggle, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
  251. // do create the main control
  252. Reset();
  253. CreateToggle();
  254. SetSizer(sizerTop);
  255. }
  256. void ToggleWidgetsPage::Reset()
  257. {
  258. #ifdef wxHAS_BITMAPTOGGLEBUTTON
  259. m_chkBitmapOnly->SetValue(false);
  260. m_chkFit->SetValue(true);
  261. m_chkTextAndBitmap->SetValue(false);
  262. #if wxUSE_MARKUP
  263. m_chkUseMarkup->SetValue(false);
  264. #endif // wxUSE_MARKUP
  265. m_chkUseBitmapClass->SetValue(true);
  266. m_chkUsePressed->SetValue(true);
  267. m_chkUseFocused->SetValue(true);
  268. m_chkUseCurrent->SetValue(true);
  269. m_chkUseDisabled->SetValue(true);
  270. m_radioImagePos->SetSelection(ToggleImagePos_Left);
  271. m_radioHAlign->SetSelection(ToggleHAlign_Centre);
  272. m_radioVAlign->SetSelection(ToggleVAlign_Centre);
  273. #endif // wxHAS_BITMAPTOGGLEBUTTON
  274. if ( m_toggle )
  275. {
  276. m_toggle->SetValue(false);
  277. }
  278. }
  279. void ToggleWidgetsPage::CreateToggle()
  280. {
  281. wxString label;
  282. bool value = false;
  283. if ( m_toggle )
  284. {
  285. label = m_toggle->GetLabel();
  286. value = m_toggle->GetValue();
  287. size_t count = m_sizerToggle->GetChildren().GetCount();
  288. for ( size_t n = 0; n < count; n++ )
  289. {
  290. m_sizerToggle->Remove(0);
  291. }
  292. delete m_toggle;
  293. }
  294. if ( label.empty() )
  295. {
  296. // creating for the first time or recreating a toggle button after bitmap
  297. // button
  298. label = m_textLabel->GetValue();
  299. }
  300. int flags = ms_defaultFlags;
  301. #ifdef wxHAS_BITMAPTOGGLEBUTTON
  302. switch ( m_radioHAlign->GetSelection() )
  303. {
  304. case ToggleHAlign_Left:
  305. flags |= wxBU_LEFT;
  306. break;
  307. default:
  308. wxFAIL_MSG(wxT("unexpected radiobox selection"));
  309. // fall through
  310. case ToggleHAlign_Centre:
  311. break;
  312. case ToggleHAlign_Right:
  313. flags |= wxBU_RIGHT;
  314. break;
  315. }
  316. switch ( m_radioVAlign->GetSelection() )
  317. {
  318. case ToggleVAlign_Top:
  319. flags |= wxBU_TOP;
  320. break;
  321. default:
  322. wxFAIL_MSG(wxT("unexpected radiobox selection"));
  323. // fall through
  324. case ToggleVAlign_Centre:
  325. // centre vertical alignment is the default (no style)
  326. break;
  327. case ToggleVAlign_Bottom:
  328. flags |= wxBU_BOTTOM;
  329. break;
  330. }
  331. #endif // wxHAS_BITMAPTOGGLEBUTTON
  332. #ifdef wxHAS_BITMAPTOGGLEBUTTON
  333. bool showsBitmap = false;
  334. if ( m_chkBitmapOnly->GetValue() )
  335. {
  336. showsBitmap = true;
  337. wxToggleButton *btgl;
  338. if ( m_chkUseBitmapClass->GetValue() )
  339. {
  340. btgl = new wxBitmapToggleButton(this, TogglePage_Picker,
  341. CreateBitmap(wxT("normal")));
  342. }
  343. else
  344. {
  345. btgl = new wxToggleButton(this, TogglePage_Picker, wxT(""));
  346. btgl->SetBitmapLabel(CreateBitmap(wxT("normal")));
  347. }
  348. #ifdef wxHAS_ANY_BUTTON
  349. if ( m_chkUsePressed->GetValue() )
  350. btgl->SetBitmapPressed(CreateBitmap(wxT("pushed")));
  351. if ( m_chkUseFocused->GetValue() )
  352. btgl->SetBitmapFocus(CreateBitmap(wxT("focused")));
  353. if ( m_chkUseCurrent->GetValue() )
  354. btgl->SetBitmapCurrent(CreateBitmap(wxT("hover")));
  355. if ( m_chkUseDisabled->GetValue() )
  356. btgl->SetBitmapDisabled(CreateBitmap(wxT("disabled")));
  357. #endif // wxHAS_ANY_BUTTON
  358. m_toggle = btgl;
  359. }
  360. else // normal button
  361. #endif // wxHAS_BITMAPTOGGLEBUTTON
  362. {
  363. m_toggle = new wxToggleButton(this, TogglePage_Picker, label,
  364. wxDefaultPosition, wxDefaultSize,
  365. flags);
  366. }
  367. m_toggle->SetValue(value);
  368. #ifdef wxHAS_BITMAPTOGGLEBUTTON
  369. #ifdef wxHAS_ANY_BUTTON
  370. if ( !showsBitmap && m_chkTextAndBitmap->GetValue() )
  371. {
  372. showsBitmap = true;
  373. static const wxDirection positions[] =
  374. {
  375. wxLEFT, wxRIGHT, wxTOP, wxBOTTOM
  376. };
  377. m_toggle->SetBitmap(wxArtProvider::GetIcon(wxART_INFORMATION, wxART_BUTTON),
  378. positions[m_radioImagePos->GetSelection()]);
  379. if ( m_chkUsePressed->GetValue() )
  380. m_toggle->SetBitmapPressed(wxArtProvider::GetIcon(wxART_HELP, wxART_BUTTON));
  381. if ( m_chkUseFocused->GetValue() )
  382. m_toggle->SetBitmapFocus(wxArtProvider::GetIcon(wxART_ERROR, wxART_BUTTON));
  383. if ( m_chkUseCurrent->GetValue() )
  384. m_toggle->SetBitmapCurrent(wxArtProvider::GetIcon(wxART_WARNING, wxART_BUTTON));
  385. if ( m_chkUseDisabled->GetValue() )
  386. m_toggle->SetBitmapDisabled(wxArtProvider::GetIcon(wxART_MISSING_IMAGE, wxART_BUTTON));
  387. }
  388. #endif // wxHAS_ANY_BUTTON
  389. m_chkUseBitmapClass->Enable(showsBitmap);
  390. m_chkUsePressed->Enable(showsBitmap);
  391. m_chkUseFocused->Enable(showsBitmap);
  392. m_chkUseCurrent->Enable(showsBitmap);
  393. m_chkUseDisabled->Enable(showsBitmap);
  394. #endif // wxHAS_BITMAPTOGGLEBUTTON
  395. m_sizerToggle->Add(0, 0, 1, wxCENTRE);
  396. m_sizerToggle->Add(m_toggle, 1, wxCENTRE);
  397. m_sizerToggle->Add(0, 0, 1, wxCENTRE);
  398. m_sizerToggle->Layout();
  399. }
  400. // ----------------------------------------------------------------------------
  401. // event handlers
  402. // ----------------------------------------------------------------------------
  403. void ToggleWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
  404. {
  405. Reset();
  406. CreateToggle();
  407. }
  408. void ToggleWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
  409. {
  410. CreateToggle();
  411. }
  412. void ToggleWidgetsPage::OnButtonChangeLabel(wxCommandEvent& WXUNUSED(event))
  413. {
  414. const wxString labelText = m_textLabel->GetValue();
  415. #if wxUSE_MARKUP
  416. if ( m_chkUseMarkup->GetValue() )
  417. m_toggle->SetLabelMarkup(labelText);
  418. else
  419. #endif // wxUSE_MARKUP
  420. m_toggle->SetLabel(labelText);
  421. }
  422. #ifdef wxHAS_BITMAPTOGGLEBUTTON
  423. // ----------------------------------------------------------------------------
  424. // bitmap toggle button stuff
  425. // ----------------------------------------------------------------------------
  426. wxBitmap ToggleWidgetsPage::CreateBitmap(const wxString& label)
  427. {
  428. wxBitmap bmp(180, 70); // shouldn't hardcode but it's simpler like this
  429. wxMemoryDC dc;
  430. dc.SelectObject(bmp);
  431. dc.SetBackground(*wxCYAN_BRUSH);
  432. dc.Clear();
  433. dc.SetTextForeground(*wxBLACK);
  434. dc.DrawLabel(wxStripMenuCodes(m_textLabel->GetValue()) + wxT("\n")
  435. wxT("(") + label + wxT(" state)"),
  436. wxArtProvider::GetBitmap(wxART_INFORMATION),
  437. wxRect(10, 10, bmp.GetWidth() - 20, bmp.GetHeight() - 20),
  438. wxALIGN_CENTRE);
  439. return bmp;
  440. }
  441. #endif // wxHAS_BITMAPTOGGLEBUTTON
  442. #endif // wxUSE_TOGGLEBTN