bmpcombobox.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Program: wxWidgets Widgets Sample
  3. // Name: bmpcombobox.cpp
  4. // Purpose: Part of the widgets sample showing wxBitmapComboBox
  5. // Author: Jaakko Salli
  6. // Created: Sep-01-2006
  7. // Copyright: (c) 2006 Jaakko Salli
  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_BITMAPCOMBOBOX
  22. // for all others, include the necessary headers
  23. #ifndef WX_PRECOMP
  24. #include "wx/log.h"
  25. #include "wx/bitmap.h"
  26. #include "wx/button.h"
  27. #include "wx/checkbox.h"
  28. #include "wx/combobox.h"
  29. #include "wx/radiobox.h"
  30. #include "wx/statbox.h"
  31. #include "wx/textctrl.h"
  32. #include "wx/filedlg.h"
  33. #endif
  34. #include "wx/stattext.h"
  35. #include "wx/dc.h"
  36. #include "wx/dcmemory.h"
  37. #include "wx/sizer.h"
  38. #include "wx/icon.h"
  39. #include "wx/dir.h"
  40. #include "wx/msgdlg.h"
  41. #include "wx/filename.h"
  42. #include "wx/image.h"
  43. #include "wx/imaglist.h"
  44. #include "wx/bmpcbox.h"
  45. #include "itemcontainer.h"
  46. #include "widgets.h"
  47. #include "icons/bmpcombobox.xpm"
  48. // Images loaded from file are reduced this width and height, if larger
  49. #define IMG_SIZE_TRUNC 256
  50. // ----------------------------------------------------------------------------
  51. // constants
  52. // ----------------------------------------------------------------------------
  53. // control ids
  54. enum
  55. {
  56. BitmapComboBoxPage_Reset = wxID_HIGHEST,
  57. BitmapComboBoxPage_Insert,
  58. BitmapComboBoxPage_InsertText,
  59. BitmapComboBoxPage_ChangeHeight,
  60. BitmapComboBoxPage_LoadFromFile,
  61. BitmapComboBoxPage_SetFromFile,
  62. BitmapComboBoxPage_AddWidgetIcons,
  63. BitmapComboBoxPage_AddSeveralWithImages,
  64. BitmapComboBoxPage_AddSeveral,
  65. BitmapComboBoxPage_AddMany,
  66. BitmapComboBoxPage_Clear,
  67. BitmapComboBoxPage_Change,
  68. BitmapComboBoxPage_Delete,
  69. BitmapComboBoxPage_DeleteText,
  70. BitmapComboBoxPage_DeleteSel,
  71. BitmapComboBoxPage_Combo,
  72. BitmapComboBoxPage_ContainerTests
  73. };
  74. // kinds of comboboxes
  75. enum
  76. {
  77. ComboKind_Default,
  78. ComboKind_Simple,
  79. ComboKind_DropDown
  80. };
  81. // ----------------------------------------------------------------------------
  82. // BitmapComboBoxWidgetsPage
  83. // ----------------------------------------------------------------------------
  84. class BitmapComboBoxWidgetsPage : public ItemContainerWidgetsPage
  85. {
  86. public:
  87. BitmapComboBoxWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
  88. virtual wxControl *GetWidget() const { return m_combobox; }
  89. virtual wxItemContainer* GetContainer() const { return m_combobox; }
  90. virtual void RecreateWidget() { CreateCombo(); }
  91. // lazy creation of the content
  92. virtual void CreateContent();
  93. protected:
  94. // event handlers
  95. void OnButtonReset(wxCommandEvent& event);
  96. void OnButtonChange(wxCommandEvent& event);
  97. void OnButtonDelete(wxCommandEvent& event);
  98. void OnButtonDeleteSel(wxCommandEvent& event);
  99. void OnButtonClear(wxCommandEvent& event);
  100. void OnButtonInsert(wxCommandEvent &event);
  101. void OnTextChangeHeight(wxCommandEvent& event);
  102. void OnButtonLoadFromFile(wxCommandEvent& event);
  103. void OnButtonSetFromFile(wxCommandEvent& event);
  104. void OnButtonAddSeveral(wxCommandEvent& event);
  105. void OnButtonAddSeveralWithImages(wxCommandEvent& event);
  106. void OnButtonAddWidgetIcons(wxCommandEvent& event);
  107. void OnButtonAddMany(wxCommandEvent& event);
  108. void OnComboBox(wxCommandEvent& event);
  109. void OnDropDown(wxCommandEvent& event);
  110. void OnCloseUp(wxCommandEvent& event);
  111. void OnComboText(wxCommandEvent& event);
  112. void OnCheckOrRadioBox(wxCommandEvent& event);
  113. void OnTextPopupWidth(wxCommandEvent& event);
  114. void OnTextPopupHeight(wxCommandEvent& event);
  115. void OnTextButtonAll(wxCommandEvent& event);
  116. void OnUpdateUIInsert(wxUpdateUIEvent& event);
  117. void OnUpdateUIClearButton(wxUpdateUIEvent& event);
  118. void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
  119. void OnUpdateUIItemManipulator(wxUpdateUIEvent& event);
  120. void OnUpdateUIResetButton(wxUpdateUIEvent& event);
  121. // reset the bmpcombobox parameters
  122. void Reset();
  123. // (re)create the bmpcombobox
  124. void CreateCombo();
  125. // helpers for creating bitmaps
  126. wxBitmap CreateBitmap(const wxColour& colour);
  127. wxBitmap LoadBitmap(const wxString& filepath);
  128. wxBitmap QueryBitmap(wxString* pStr);
  129. void LoadWidgetImages( wxArrayString* strings, wxImageList* images );
  130. wxSizer *CreateSizerWithSmallTextAndLabel(const wxString& label,
  131. wxWindowID id,
  132. wxTextCtrl **ppText);
  133. #if wxUSE_IMAGE
  134. void RescaleImage(wxImage& image, int w, int h);
  135. #endif
  136. // the controls
  137. // ------------
  138. // the sel mode radiobox
  139. wxRadioBox *m_radioKind;
  140. // the checkboxes for styles
  141. wxCheckBox *m_chkSort,
  142. *m_chkReadonly;
  143. // the combobox itself and the sizer it is in
  144. wxBitmapComboBox *m_combobox;
  145. wxSizer *m_sizerCombo;
  146. // the text entries for "Add/change string" and "Delete" buttons
  147. wxTextCtrl *m_textInsert,
  148. *m_textChangeHeight,
  149. *m_textChange,
  150. *m_textDelete;
  151. private:
  152. wxDECLARE_EVENT_TABLE();
  153. DECLARE_WIDGETS_PAGE(BitmapComboBoxWidgetsPage)
  154. };
  155. // ----------------------------------------------------------------------------
  156. // event tables
  157. // ----------------------------------------------------------------------------
  158. wxBEGIN_EVENT_TABLE(BitmapComboBoxWidgetsPage, WidgetsPage)
  159. EVT_BUTTON(BitmapComboBoxPage_Reset, BitmapComboBoxWidgetsPage::OnButtonReset)
  160. EVT_BUTTON(BitmapComboBoxPage_Change, BitmapComboBoxWidgetsPage::OnButtonChange)
  161. EVT_BUTTON(BitmapComboBoxPage_Delete, BitmapComboBoxWidgetsPage::OnButtonDelete)
  162. EVT_BUTTON(BitmapComboBoxPage_DeleteSel, BitmapComboBoxWidgetsPage::OnButtonDeleteSel)
  163. EVT_BUTTON(BitmapComboBoxPage_Clear, BitmapComboBoxWidgetsPage::OnButtonClear)
  164. EVT_BUTTON(BitmapComboBoxPage_Insert, BitmapComboBoxWidgetsPage::OnButtonInsert)
  165. EVT_BUTTON(BitmapComboBoxPage_AddSeveral, BitmapComboBoxWidgetsPage::OnButtonAddSeveral)
  166. EVT_BUTTON(BitmapComboBoxPage_AddSeveralWithImages, BitmapComboBoxWidgetsPage::OnButtonAddSeveralWithImages)
  167. EVT_BUTTON(BitmapComboBoxPage_AddWidgetIcons, BitmapComboBoxWidgetsPage::OnButtonAddWidgetIcons)
  168. EVT_BUTTON(BitmapComboBoxPage_AddMany, BitmapComboBoxWidgetsPage::OnButtonAddMany)
  169. EVT_BUTTON(BitmapComboBoxPage_LoadFromFile, BitmapComboBoxWidgetsPage::OnButtonLoadFromFile)
  170. EVT_BUTTON(BitmapComboBoxPage_SetFromFile, BitmapComboBoxWidgetsPage::OnButtonSetFromFile)
  171. EVT_BUTTON(BitmapComboBoxPage_ContainerTests, ItemContainerWidgetsPage::OnButtonTestItemContainer)
  172. EVT_TEXT_ENTER(BitmapComboBoxPage_InsertText, BitmapComboBoxWidgetsPage::OnButtonInsert)
  173. EVT_TEXT(BitmapComboBoxPage_ChangeHeight, BitmapComboBoxWidgetsPage::OnTextChangeHeight)
  174. EVT_TEXT_ENTER(BitmapComboBoxPage_DeleteText, BitmapComboBoxWidgetsPage::OnButtonDelete)
  175. EVT_UPDATE_UI(BitmapComboBoxPage_Reset, BitmapComboBoxWidgetsPage::OnUpdateUIResetButton)
  176. EVT_UPDATE_UI(BitmapComboBoxPage_Insert, BitmapComboBoxWidgetsPage::OnUpdateUIInsert)
  177. EVT_UPDATE_UI(BitmapComboBoxPage_LoadFromFile, BitmapComboBoxWidgetsPage::OnUpdateUIInsert)
  178. EVT_UPDATE_UI(BitmapComboBoxPage_Clear, BitmapComboBoxWidgetsPage::OnUpdateUIClearButton)
  179. EVT_UPDATE_UI(BitmapComboBoxPage_DeleteText, BitmapComboBoxWidgetsPage::OnUpdateUIClearButton)
  180. EVT_UPDATE_UI(BitmapComboBoxPage_Delete, BitmapComboBoxWidgetsPage::OnUpdateUIDeleteButton)
  181. EVT_UPDATE_UI(BitmapComboBoxPage_Change, BitmapComboBoxWidgetsPage::OnUpdateUIItemManipulator)
  182. EVT_UPDATE_UI(BitmapComboBoxPage_SetFromFile, BitmapComboBoxWidgetsPage::OnUpdateUIItemManipulator)
  183. EVT_UPDATE_UI(BitmapComboBoxPage_DeleteSel, BitmapComboBoxWidgetsPage::OnUpdateUIItemManipulator)
  184. EVT_COMBOBOX_DROPDOWN(BitmapComboBoxPage_Combo, BitmapComboBoxWidgetsPage::OnDropDown)
  185. EVT_COMBOBOX_CLOSEUP(BitmapComboBoxPage_Combo, BitmapComboBoxWidgetsPage::OnCloseUp)
  186. EVT_COMBOBOX(BitmapComboBoxPage_Combo, BitmapComboBoxWidgetsPage::OnComboBox)
  187. EVT_TEXT(BitmapComboBoxPage_Combo, BitmapComboBoxWidgetsPage::OnComboText)
  188. EVT_TEXT_ENTER(BitmapComboBoxPage_Combo, BitmapComboBoxWidgetsPage::OnComboText)
  189. EVT_CHECKBOX(wxID_ANY, BitmapComboBoxWidgetsPage::OnCheckOrRadioBox)
  190. EVT_RADIOBOX(wxID_ANY, BitmapComboBoxWidgetsPage::OnCheckOrRadioBox)
  191. wxEND_EVENT_TABLE()
  192. // ============================================================================
  193. // implementation
  194. // ============================================================================
  195. #if defined(__WXMSW__) || defined(__WXGTK__)
  196. #define NATIVE_OR_GENERIC_CTRLS NATIVE_CTRLS
  197. #else
  198. #define NATIVE_OR_GENERIC_CTRLS GENERIC_CTRLS
  199. #endif
  200. IMPLEMENT_WIDGETS_PAGE(BitmapComboBoxWidgetsPage, wxT("BitmapCombobox"),
  201. NATIVE_OR_GENERIC_CTRLS | WITH_ITEMS_CTRLS | COMBO_CTRLS
  202. );
  203. BitmapComboBoxWidgetsPage::BitmapComboBoxWidgetsPage(WidgetsBookCtrl *book,
  204. wxImageList *imaglist)
  205. : ItemContainerWidgetsPage(book, imaglist, bmpcombobox_xpm)
  206. {
  207. // init everything
  208. m_chkSort =
  209. m_chkReadonly = NULL;
  210. m_combobox = NULL;
  211. m_sizerCombo = NULL;
  212. m_textInsert =
  213. m_textChangeHeight =
  214. m_textChange =
  215. m_textDelete = NULL;
  216. }
  217. // create a sizer containing a label and a small text ctrl
  218. wxSizer *BitmapComboBoxWidgetsPage::CreateSizerWithSmallTextAndLabel(const wxString& label,
  219. wxWindowID id,
  220. wxTextCtrl **ppText)
  221. {
  222. wxControl* control = new wxStaticText(this, wxID_ANY, label);
  223. wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
  224. wxTextCtrl *text = new wxTextCtrl(this, id, wxEmptyString,
  225. wxDefaultPosition, wxSize(50,wxDefaultCoord), wxTE_PROCESS_ENTER);
  226. sizerRow->Add(control, 0, wxRIGHT | wxALIGN_CENTRE_VERTICAL, 5);
  227. sizerRow->Add(text, 1, wxFIXED_MINSIZE | wxLEFT | wxALIGN_CENTRE_VERTICAL, 5);
  228. if ( ppText )
  229. *ppText = text;
  230. return sizerRow;
  231. }
  232. void BitmapComboBoxWidgetsPage::CreateContent()
  233. {
  234. /*
  235. What we create here is a frame having 3 panes: style pane is the
  236. leftmost one, in the middle the pane with buttons allowing to perform
  237. miscellaneous combobox operations and the pane containing the combobox
  238. itself to the right
  239. */
  240. wxSizer *sizerRow;
  241. wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
  242. wxSizer *sizerLeft = new wxBoxSizer(wxVERTICAL);
  243. // left pane - style box
  244. wxStaticBox *box = new wxStaticBox(this, wxID_ANY, wxT("&Set style"));
  245. // should be in sync with ComboKind_XXX values
  246. static const wxString kinds[] =
  247. {
  248. wxT("default"),
  249. wxT("simple"),
  250. wxT("drop down"),
  251. };
  252. m_radioKind = new wxRadioBox(this, wxID_ANY, wxT("Combobox &kind:"),
  253. wxDefaultPosition, wxDefaultSize,
  254. WXSIZEOF(kinds), kinds,
  255. 1, wxRA_SPECIFY_COLS);
  256. wxSizer *sizerStyle = new wxStaticBoxSizer(box, wxVERTICAL);
  257. m_chkSort = CreateCheckBoxAndAddToSizer(sizerStyle, wxT("&Sort items"));
  258. m_chkReadonly = CreateCheckBoxAndAddToSizer(sizerStyle, wxT("&Read only"));
  259. wxButton *btn = new wxButton(this, BitmapComboBoxPage_Reset, wxT("&Reset"));
  260. sizerStyle->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 3);
  261. sizerLeft->Add(sizerStyle, 0, wxGROW | wxALIGN_CENTRE_HORIZONTAL);
  262. sizerLeft->Add(m_radioKind, 0, wxGROW | wxALL, 5);
  263. // left pane - other options box
  264. box = new wxStaticBox(this, wxID_ANY, wxT("Demo options"));
  265. wxSizer *sizerOptions = new wxStaticBoxSizer(box, wxVERTICAL);
  266. sizerRow = CreateSizerWithSmallTextAndLabel(wxT("Control &height:"),
  267. BitmapComboBoxPage_ChangeHeight,
  268. &m_textChangeHeight);
  269. m_textChangeHeight->SetSize(20, wxDefaultCoord);
  270. sizerOptions->Add(sizerRow, 0, wxALL | wxFIXED_MINSIZE /*| wxGROW*/, 5);
  271. sizerLeft->Add(sizerOptions, 0, wxGROW | wxALIGN_CENTRE_HORIZONTAL | wxTOP, 2);
  272. // middle pane
  273. wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY,
  274. wxT("&Change wxBitmapComboBox contents"));
  275. wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
  276. btn = new wxButton(this, BitmapComboBoxPage_ContainerTests, wxT("Run &tests"));
  277. sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  278. #if wxUSE_IMAGE
  279. btn = new wxButton(this, BitmapComboBoxPage_AddWidgetIcons, wxT("Add &widget icons"));
  280. sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  281. btn = new wxButton(this, BitmapComboBoxPage_LoadFromFile, wxT("Insert image from &file"));
  282. sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  283. btn = new wxButton(this, BitmapComboBoxPage_SetFromFile, wxT("&Set image from file"));
  284. sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  285. #endif
  286. btn = new wxButton(this, BitmapComboBoxPage_AddSeveralWithImages, wxT("A&ppend a few strings with images"));
  287. sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  288. btn = new wxButton(this, BitmapComboBoxPage_AddSeveral, wxT("Append a &few strings"));
  289. sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  290. btn = new wxButton(this, BitmapComboBoxPage_AddMany, wxT("Append &many strings"));
  291. sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  292. sizerRow = CreateSizerWithTextAndButton(BitmapComboBoxPage_Delete,
  293. wxT("&Delete this item"),
  294. BitmapComboBoxPage_DeleteText,
  295. &m_textDelete);
  296. sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
  297. btn = new wxButton(this, BitmapComboBoxPage_DeleteSel, wxT("Delete &selection"));
  298. sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  299. btn = new wxButton(this, BitmapComboBoxPage_Clear, wxT("&Clear"));
  300. sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  301. #if wxUSE_IMAGE
  302. wxInitAllImageHandlers();
  303. #endif
  304. // right pane
  305. wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL);
  306. m_combobox = new wxBitmapComboBox();
  307. m_combobox->Create(this, BitmapComboBoxPage_Combo, wxEmptyString,
  308. wxDefaultPosition, wxDefaultSize,
  309. 0, NULL,
  310. wxCB_READONLY);
  311. #if defined(wxGENERIC_BITMAPCOMBOBOX)
  312. // This will sure make the list look nicer when larger images are used.
  313. m_combobox->SetPopupMaxHeight(600);
  314. #endif
  315. sizerRight->Add(m_combobox, 0, wxGROW | wxALL, 5);
  316. sizerRight->SetMinSize(150, 0);
  317. m_sizerCombo = sizerRight; // save it to modify it later
  318. // the 3 panes panes compose the window
  319. sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
  320. sizerTop->Add(sizerMiddle, 5, wxGROW | wxALL, 10);
  321. sizerTop->Add(sizerRight, 4, wxGROW | (wxALL & ~wxRIGHT), 10);
  322. // final initializations
  323. Reset();
  324. SetSizer(sizerTop);
  325. }
  326. // ----------------------------------------------------------------------------
  327. // operations
  328. // ----------------------------------------------------------------------------
  329. void BitmapComboBoxWidgetsPage::Reset()
  330. {
  331. m_chkSort->SetValue(false);
  332. m_chkReadonly->SetValue(true);
  333. }
  334. void BitmapComboBoxWidgetsPage::CreateCombo()
  335. {
  336. int flags = ms_defaultFlags;
  337. if ( m_chkSort->GetValue() )
  338. flags |= wxCB_SORT;
  339. if ( m_chkReadonly->GetValue() )
  340. flags |= wxCB_READONLY;
  341. switch ( m_radioKind->GetSelection() )
  342. {
  343. default:
  344. wxFAIL_MSG( wxT("unknown combo kind") );
  345. // fall through
  346. case ComboKind_Default:
  347. break;
  348. case ComboKind_Simple:
  349. flags |= wxCB_SIMPLE;
  350. break;
  351. case ComboKind_DropDown:
  352. flags = wxCB_DROPDOWN;
  353. break;
  354. }
  355. wxArrayString items;
  356. wxArrayPtrVoid bitmaps;
  357. if ( m_combobox )
  358. {
  359. unsigned int count = m_combobox->GetCount();
  360. for ( unsigned int n = 0; n < count; n++ )
  361. {
  362. items.Add(m_combobox->GetString(n));
  363. wxBitmap bmp = m_combobox->GetItemBitmap(n);
  364. bitmaps.Add(new wxBitmap(bmp));
  365. }
  366. m_sizerCombo->Detach( m_combobox );
  367. delete m_combobox;
  368. }
  369. m_combobox = new wxBitmapComboBox();
  370. m_combobox->Create(this, BitmapComboBoxPage_Combo, wxEmptyString,
  371. wxDefaultPosition, wxDefaultSize,
  372. 0, NULL,
  373. flags);
  374. #if defined(wxGENERIC_BITMAPCOMBOBOX)
  375. // This will sure make the list look nicer when larger images are used.
  376. m_combobox->SetPopupMaxHeight(600);
  377. #endif
  378. unsigned int count = items.GetCount();
  379. for ( unsigned int n = 0; n < count; n++ )
  380. {
  381. wxBitmap* bmp = (wxBitmap*) bitmaps[n];
  382. m_combobox->Append(items[n], *bmp);
  383. delete bmp;
  384. }
  385. m_sizerCombo->Add(m_combobox, 0, wxGROW | wxALL, 5);
  386. m_sizerCombo->Layout();
  387. // Allow changing height in order to demonstrate flexible
  388. // size of image "thumbnail" painted in the control itself.
  389. long h = 0;
  390. m_textChangeHeight->GetValue().ToLong(&h);
  391. if ( h >= 5 )
  392. m_combobox->SetSize(wxDefaultCoord, h);
  393. }
  394. // ----------------------------------------------------------------------------
  395. // event handlers
  396. // ----------------------------------------------------------------------------
  397. void BitmapComboBoxWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
  398. {
  399. Reset();
  400. CreateCombo();
  401. }
  402. void BitmapComboBoxWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event))
  403. {
  404. int sel = m_combobox->GetSelection();
  405. if ( sel != wxNOT_FOUND )
  406. {
  407. #ifndef __WXGTK__
  408. m_combobox->SetString(sel, m_textChange->GetValue());
  409. #else
  410. wxLogMessage(wxT("Not implemented in wxGTK"));
  411. #endif
  412. }
  413. }
  414. void BitmapComboBoxWidgetsPage::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
  415. {
  416. unsigned long n;
  417. if ( !m_textDelete->GetValue().ToULong(&n) ||
  418. (n >= m_combobox->GetCount()) )
  419. {
  420. return;
  421. }
  422. m_combobox->Delete(n);
  423. }
  424. void BitmapComboBoxWidgetsPage::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
  425. {
  426. int sel = m_combobox->GetSelection();
  427. if ( sel != wxNOT_FOUND )
  428. {
  429. m_combobox->Delete(sel);
  430. }
  431. }
  432. void BitmapComboBoxWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
  433. {
  434. m_combobox->Clear();
  435. }
  436. void BitmapComboBoxWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
  437. {
  438. static unsigned int s_item = 0;
  439. wxString s = m_textInsert->GetValue();
  440. if ( !m_textInsert->IsModified() )
  441. {
  442. // update the default string
  443. m_textInsert->SetValue(wxString::Format(wxT("test item %u"), ++s_item));
  444. }
  445. int sel = m_combobox->GetSelection();
  446. if ( sel == wxNOT_FOUND )
  447. sel = m_combobox->GetCount();
  448. m_combobox->Insert(s, wxNullBitmap, m_combobox->GetSelection());
  449. }
  450. void BitmapComboBoxWidgetsPage::OnTextChangeHeight(wxCommandEvent& WXUNUSED(event))
  451. {
  452. long h = 0;
  453. if ( m_textChangeHeight )
  454. m_textChangeHeight->GetValue().ToLong(&h);
  455. if ( h < 5 )
  456. return;
  457. m_combobox->SetSize(wxDefaultCoord, h);
  458. }
  459. void BitmapComboBoxWidgetsPage::OnButtonLoadFromFile(wxCommandEvent& WXUNUSED(event))
  460. {
  461. wxString s;
  462. int sel = m_combobox->GetSelection();
  463. if ( sel == wxNOT_FOUND )
  464. sel = m_combobox->GetCount();
  465. wxBitmap bmp = QueryBitmap(&s);
  466. if (bmp.IsOk())
  467. m_combobox->Insert(s, bmp, sel);
  468. }
  469. void BitmapComboBoxWidgetsPage::OnButtonSetFromFile(wxCommandEvent& WXUNUSED(event))
  470. {
  471. wxBitmap bmp = QueryBitmap(NULL);
  472. if (bmp.IsOk())
  473. m_combobox->SetItemBitmap(m_combobox->GetSelection(), bmp);
  474. }
  475. void BitmapComboBoxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
  476. {
  477. // "many" means 1000 here
  478. for ( unsigned int n = 0; n < 1000; n++ )
  479. {
  480. m_combobox->Append(wxString::Format(wxT("item #%u"), n));
  481. }
  482. }
  483. void BitmapComboBoxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
  484. {
  485. m_combobox->Append(wxT("First"));
  486. m_combobox->Append(wxT("another one"));
  487. m_combobox->Append(wxT("and the last (very very very very very very very very very very long) one"));
  488. }
  489. void BitmapComboBoxWidgetsPage::OnButtonAddSeveralWithImages(wxCommandEvent& WXUNUSED(event))
  490. {
  491. static const struct TestEntry
  492. {
  493. const char *text;
  494. unsigned long rgb;
  495. } s_entries[] =
  496. {
  497. { "Red circle", 0x0000ff },
  498. { "Blue circle", 0xff0000 },
  499. { "Green circle", 0x00ff00 },
  500. { "Black circle", 0x000000 },
  501. };
  502. for ( unsigned i = 0; i < WXSIZEOF(s_entries); i++ )
  503. {
  504. const TestEntry& e = s_entries[i];
  505. m_combobox->Append(e.text, CreateBitmap(wxColour(e.rgb)));
  506. }
  507. }
  508. #if wxUSE_IMAGE
  509. void BitmapComboBoxWidgetsPage::RescaleImage(wxImage& image, int w, int h)
  510. {
  511. if ( image.GetWidth() == w && image.GetHeight() == h )
  512. return;
  513. if ( w <= 0 || h <= 0 )
  514. return;
  515. static bool isFirstScale = true;
  516. if ( isFirstScale && m_combobox->GetCount() > 0 )
  517. {
  518. wxMessageBox( wxT("wxBitmapComboBox normally only supports images of one size. ")
  519. wxT("However, for demonstration purposes, loaded bitmaps are scaled to fit ")
  520. wxT("using wxImage::Rescale."),
  521. wxT("Notice"),
  522. wxOK,
  523. this );
  524. isFirstScale = false;
  525. }
  526. image.Rescale(w, h);
  527. }
  528. #endif
  529. void BitmapComboBoxWidgetsPage::LoadWidgetImages( wxArrayString* strings, wxImageList* images )
  530. {
  531. wxFileName fn;
  532. fn.AssignCwd();
  533. fn.AppendDir(wxT("icons"));
  534. wxSetCursor(*wxHOURGLASS_CURSOR);
  535. if ( !wxDir::Exists(fn.GetFullPath()) ||
  536. !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
  537. {
  538. // Try ../../samples/widgets/icons
  539. fn.RemoveLastDir();
  540. fn.RemoveLastDir();
  541. fn.AppendDir(wxT("icons"));
  542. if ( !wxDir::Exists(fn.GetFullPath()) ||
  543. !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
  544. {
  545. // Try ../../../samples/widgets/icons
  546. fn.AssignCwd();
  547. fn.RemoveLastDir();
  548. fn.RemoveLastDir();
  549. fn.RemoveLastDir();
  550. fn.AppendDir(wxT("samples"));
  551. fn.AppendDir(wxT("widgets"));
  552. fn.AppendDir(wxT("icons"));
  553. if ( !wxDir::Exists(fn.GetFullPath()) ||
  554. !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
  555. {
  556. wxLogWarning(wxT("Could not load widget icons."));
  557. wxSetCursor(*wxSTANDARD_CURSOR);
  558. return;
  559. }
  560. }
  561. }
  562. unsigned int i;
  563. // Get size of existing images in list
  564. wxSize foundSize = m_combobox->GetBitmapSize();
  565. for ( i=0; i<strings->size(); i++ )
  566. {
  567. fn.SetFullName((*strings)[i]);
  568. wxString name = fn.GetName();
  569. // Handle few exceptions
  570. if ( name == wxT("bmpbtn") )
  571. {
  572. strings->RemoveAt(i);
  573. i--;
  574. }
  575. else
  576. {
  577. #if wxUSE_IMAGE
  578. wxASSERT(fn.FileExists());
  579. wxImage image(fn.GetFullPath());
  580. wxASSERT(image.IsOk());
  581. RescaleImage(image, foundSize.x, foundSize.y);
  582. wxBitmap bmp(image);
  583. wxASSERT( bmp.IsOk() );
  584. #else
  585. wxBitmap bmp(wxNullBitmap);
  586. #endif
  587. images->Add(bmp);
  588. (*strings)[i] = name;
  589. // if the combobox is empty, use as bitmap size of the image list
  590. // the size of the first valid image loaded
  591. if (foundSize == wxDefaultSize)
  592. foundSize = bmp.GetSize();
  593. }
  594. }
  595. wxSetCursor(*wxSTANDARD_CURSOR);
  596. }
  597. void BitmapComboBoxWidgetsPage::OnButtonAddWidgetIcons(wxCommandEvent& WXUNUSED(event))
  598. {
  599. wxArrayString strings;
  600. wxSize sz = m_combobox->GetBitmapSize();
  601. if ( sz.x <= 0 )
  602. {
  603. sz.x = 32;
  604. sz.y = 32;
  605. }
  606. wxImageList images(sz.x, sz.y);
  607. LoadWidgetImages(&strings, &images);
  608. unsigned int i;
  609. for ( i=0; i<strings.size(); i++ )
  610. {
  611. m_combobox->Append(strings[i], images.GetBitmap(i));
  612. }
  613. }
  614. void BitmapComboBoxWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
  615. {
  616. if (m_combobox)
  617. event.Enable( m_chkSort->GetValue() || m_chkReadonly->GetValue() );
  618. }
  619. void BitmapComboBoxWidgetsPage::OnUpdateUIInsert(wxUpdateUIEvent& event)
  620. {
  621. if (m_combobox)
  622. {
  623. bool enable = !(m_combobox->GetWindowStyle() & wxCB_SORT);
  624. event.Enable(enable);
  625. }
  626. }
  627. void BitmapComboBoxWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
  628. {
  629. if (m_combobox)
  630. {
  631. unsigned long n;
  632. event.Enable(m_textDelete->GetValue().ToULong(&n) &&
  633. (n < (unsigned)m_combobox->GetCount()));
  634. }
  635. }
  636. void BitmapComboBoxWidgetsPage::OnUpdateUIItemManipulator(wxUpdateUIEvent& event)
  637. {
  638. if (m_combobox)
  639. event.Enable(m_combobox->GetSelection() != wxNOT_FOUND);
  640. }
  641. void BitmapComboBoxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
  642. {
  643. if (m_combobox)
  644. event.Enable(m_combobox->GetCount() != 0);
  645. }
  646. void BitmapComboBoxWidgetsPage::OnComboText(wxCommandEvent& event)
  647. {
  648. if (!m_combobox)
  649. return;
  650. wxString s = event.GetString();
  651. wxASSERT_MSG( s == m_combobox->GetValue(),
  652. wxT("event and combobox values should be the same") );
  653. if (event.GetEventType() == wxEVT_TEXT_ENTER)
  654. {
  655. wxLogMessage(wxT("BitmapCombobox enter pressed (now '%s')"), s.c_str());
  656. }
  657. else
  658. {
  659. wxLogMessage(wxT("BitmapCombobox text changed (now '%s')"), s.c_str());
  660. }
  661. }
  662. void BitmapComboBoxWidgetsPage::OnComboBox(wxCommandEvent& event)
  663. {
  664. long sel = event.GetInt();
  665. m_textDelete->SetValue(wxString::Format(wxT("%ld"), sel));
  666. wxLogMessage(wxT("BitmapCombobox item %ld selected"), sel);
  667. wxLogMessage(wxT("BitmapCombobox GetValue(): %s"), m_combobox->GetValue().c_str() );
  668. }
  669. void BitmapComboBoxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
  670. {
  671. CreateCombo();
  672. }
  673. #if wxUSE_IMAGE
  674. wxBitmap BitmapComboBoxWidgetsPage::LoadBitmap(const wxString& filepath)
  675. {
  676. // Get size of existing images in list
  677. wxSize foundSize = m_combobox->GetBitmapSize();
  678. // Have some reasonable maximum size
  679. if ( foundSize.x <= 0 )
  680. {
  681. foundSize.x = IMG_SIZE_TRUNC;
  682. foundSize.y = IMG_SIZE_TRUNC;
  683. }
  684. wxImage image(filepath);
  685. if ( image.IsOk() )
  686. {
  687. // Rescale very large images
  688. int ow = image.GetWidth();
  689. int oh = image.GetHeight();
  690. if ( foundSize.x > 0 &&
  691. (ow != foundSize.x || oh != foundSize.y) )
  692. {
  693. int w = ow;
  694. if ( w > foundSize.x )
  695. w = foundSize.x;
  696. int h = oh;
  697. if ( h > foundSize.y )
  698. h = foundSize.y;
  699. RescaleImage(image, w, h);
  700. }
  701. return wxBitmap(image);
  702. }
  703. return wxNullBitmap;
  704. }
  705. #else
  706. wxBitmap BitmapComboBoxWidgetsPage::LoadBitmap(const wxString& WXUNUSED(filepath))
  707. {
  708. return wxNullBitmap;
  709. }
  710. #endif
  711. wxBitmap BitmapComboBoxWidgetsPage::QueryBitmap(wxString* pStr)
  712. {
  713. wxString filepath = wxLoadFileSelector(wxT("image"),
  714. wxEmptyString,
  715. wxEmptyString,
  716. this);
  717. wxBitmap bitmap;
  718. ::wxSetCursor( *wxHOURGLASS_CURSOR );
  719. if ( !filepath.empty() )
  720. {
  721. if ( pStr )
  722. {
  723. *pStr = wxFileName(filepath).GetName();
  724. }
  725. bitmap = LoadBitmap(filepath);
  726. }
  727. if (bitmap.IsOk())
  728. {
  729. wxLogDebug(wxT("%i, %i"),bitmap.GetWidth(), bitmap.GetHeight());
  730. }
  731. ::wxSetCursor( *wxSTANDARD_CURSOR );
  732. return bitmap;
  733. }
  734. wxBitmap BitmapComboBoxWidgetsPage::CreateBitmap(const wxColour& colour)
  735. {
  736. const int w = 10,
  737. h = 10;
  738. wxMemoryDC dc;
  739. wxBitmap bmp(w, h);
  740. dc.SelectObject(bmp);
  741. // Draw transparent background
  742. wxColour magic(255, 0, 255);
  743. wxBrush magicBrush(magic);
  744. dc.SetBrush(magicBrush);
  745. dc.SetPen(*wxTRANSPARENT_PEN);
  746. dc.DrawRectangle(0, 0, w, h);
  747. // Draw image content
  748. dc.SetBrush(wxBrush(colour));
  749. dc.DrawCircle(h/2, h/2+1, h/2);
  750. dc.SelectObject(wxNullBitmap);
  751. // Finalize transparency with a mask
  752. wxMask *mask = new wxMask(bmp, magic);
  753. bmp.SetMask(mask);
  754. return bmp;
  755. }
  756. void BitmapComboBoxWidgetsPage::OnDropDown(wxCommandEvent& WXUNUSED(event))
  757. {
  758. wxLogMessage(wxT("Combobox dropped down"));
  759. }
  760. void BitmapComboBoxWidgetsPage::OnCloseUp(wxCommandEvent& WXUNUSED(event))
  761. {
  762. wxLogMessage(wxT("Combobox closed up"));
  763. }
  764. #endif // wxUSE_BITMAPCOMBOBOX