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