]> git.saurik.com Git - wxWidgets.git/blob - samples/widgets/bmpcombobox.cpp
Use template class instead of template function in wxVectorSort().
[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 OnDropDown(wxCommandEvent& event);
132 void OnCloseUp(wxCommandEvent& event);
133 void OnComboText(wxCommandEvent& event);
134
135 void OnCheckOrRadioBox(wxCommandEvent& event);
136
137 void OnTextPopupWidth(wxCommandEvent& event);
138 void OnTextPopupHeight(wxCommandEvent& event);
139 void OnTextButtonAll(wxCommandEvent& event);
140
141 void OnUpdateUIInsert(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_Clear, BitmapComboBoxWidgetsPage::OnUpdateUIClearButton)
220 EVT_UPDATE_UI(BitmapComboBoxPage_DeleteText, BitmapComboBoxWidgetsPage::OnUpdateUIClearButton)
221 EVT_UPDATE_UI(BitmapComboBoxPage_Delete, BitmapComboBoxWidgetsPage::OnUpdateUIDeleteButton)
222 EVT_UPDATE_UI(BitmapComboBoxPage_Change, BitmapComboBoxWidgetsPage::OnUpdateUIItemManipulator)
223 EVT_UPDATE_UI(BitmapComboBoxPage_SetFromFile, BitmapComboBoxWidgetsPage::OnUpdateUIItemManipulator)
224 EVT_UPDATE_UI(BitmapComboBoxPage_DeleteSel, BitmapComboBoxWidgetsPage::OnUpdateUIItemManipulator)
225
226 EVT_COMBOBOX_DROPDOWN(BitmapComboBoxPage_Combo, BitmapComboBoxWidgetsPage::OnDropDown)
227 EVT_COMBOBOX_CLOSEUP(BitmapComboBoxPage_Combo, BitmapComboBoxWidgetsPage::OnCloseUp)
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, wxT("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, wxT("&Set style"));
303
304
305 // should be in sync with ComboKind_XXX values
306 static const wxString kinds[] =
307 {
308 wxT("default"),
309 wxT("simple"),
310 wxT("drop down"),
311 };
312
313 m_radioKind = new wxRadioBox(this, wxID_ANY, wxT("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, wxT("&Sort items"));
321 m_chkReadonly = CreateCheckBoxAndAddToSizer(sizerStyle, wxT("&Read only"));
322
323 wxButton *btn = new wxButton(this, BitmapComboBoxPage_Reset, wxT("&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, wxT("Demo options"));
331
332 wxSizer *sizerOptions = new wxStaticBoxSizer(box, wxVERTICAL);
333
334 sizerRow = CreateSizerWithSmallTextAndLabel(wxT("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 wxT("&Change wxBitmapComboBox contents"));
345 wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
346
347 btn = new wxButton(this, BitmapComboBoxPage_ContainerTests, wxT("Run &tests"));
348 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
349
350 #if wxUSE_IMAGE
351 btn = new wxButton(this, BitmapComboBoxPage_AddWidgetIcons, wxT("Add &widget icons"));
352 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
353
354 btn = new wxButton(this, BitmapComboBoxPage_LoadFromFile, wxT("Insert image from &file"));
355 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
356
357 btn = new wxButton(this, BitmapComboBoxPage_SetFromFile, wxT("&Set image from file"));
358 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
359 #endif
360
361 btn = new wxButton(this, BitmapComboBoxPage_AddSeveralWithImages, wxT("A&ppend a few strings with images"));
362 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
363
364 btn = new wxButton(this, BitmapComboBoxPage_AddSeveral, wxT("Append a &few strings"));
365 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
366
367 btn = new wxButton(this, BitmapComboBoxPage_AddMany, wxT("Append &many strings"));
368 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
369
370 sizerRow = CreateSizerWithTextAndButton(BitmapComboBoxPage_Delete,
371 wxT("&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, wxT("Delete &selection"));
377 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
378
379 btn = new wxButton(this, BitmapComboBoxPage_Clear, wxT("&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( wxT("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 wxBitmap bmp = m_combobox->GetItemBitmap(n);
460 bitmaps.Add(new wxBitmap(bmp));
461 }
462
463 m_sizerCombo->Detach( m_combobox );
464 delete m_combobox;
465 }
466
467 m_combobox = new wxBitmapComboBox();
468 m_combobox->Create(this, BitmapComboBoxPage_Combo, wxEmptyString,
469 wxDefaultPosition, wxDefaultSize,
470 0, NULL,
471 flags);
472
473 #if defined(wxGENERIC_BITMAPCOMBOBOX)
474 // This will sure make the list look nicer when larger images are used.
475 m_combobox->SetPopupMaxHeight(600);
476 #endif
477
478 unsigned int count = items.GetCount();
479 for ( unsigned int n = 0; n < count; n++ )
480 {
481 wxBitmap* bmp = (wxBitmap*) bitmaps[n];
482 m_combobox->Append(items[n], *bmp);
483 delete bmp;
484 }
485
486 m_sizerCombo->Add(m_combobox, 0, wxGROW | wxALL, 5);
487 m_sizerCombo->Layout();
488
489 // Allow changing height inorder to demonstrate flexible
490 // size of image "thumbnail" painted in the control itself.
491 long h = 0;
492 m_textChangeHeight->GetValue().ToLong(&h);
493 if ( h >= 5 )
494 m_combobox->SetSize(wxDefaultCoord, h);
495 }
496
497 // ----------------------------------------------------------------------------
498 // event handlers
499 // ----------------------------------------------------------------------------
500
501 void BitmapComboBoxWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
502 {
503 Reset();
504
505 CreateCombo();
506 }
507
508 void BitmapComboBoxWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event))
509 {
510 int sel = m_combobox->GetSelection();
511 if ( sel != wxNOT_FOUND )
512 {
513 #ifndef __WXGTK__
514 m_combobox->SetString(sel, m_textChange->GetValue());
515 #else
516 wxLogMessage(wxT("Not implemented in wxGTK"));
517 #endif
518 }
519 }
520
521 void BitmapComboBoxWidgetsPage::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
522 {
523 unsigned long n;
524 if ( !m_textDelete->GetValue().ToULong(&n) ||
525 (n >= m_combobox->GetCount()) )
526 {
527 return;
528 }
529
530 m_combobox->Delete(n);
531 }
532
533 void BitmapComboBoxWidgetsPage::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
534 {
535 int sel = m_combobox->GetSelection();
536 if ( sel != wxNOT_FOUND )
537 {
538 m_combobox->Delete(sel);
539 }
540 }
541
542 void BitmapComboBoxWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
543 {
544 m_combobox->Clear();
545 }
546
547 void BitmapComboBoxWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
548 {
549 static unsigned int s_item = 0;
550
551 wxString s = m_textInsert->GetValue();
552 if ( !m_textInsert->IsModified() )
553 {
554 // update the default string
555 m_textInsert->SetValue(wxString::Format(wxT("test item %u"), ++s_item));
556 }
557
558 int sel = m_combobox->GetSelection();
559 if ( sel == wxNOT_FOUND )
560 sel = m_combobox->GetCount();
561
562 m_combobox->Insert(s, wxNullBitmap, m_combobox->GetSelection());
563 }
564
565 void BitmapComboBoxWidgetsPage::OnTextChangeHeight(wxCommandEvent& WXUNUSED(event))
566 {
567 long h = 0;
568 if ( m_textChangeHeight )
569 m_textChangeHeight->GetValue().ToLong(&h);
570 if ( h < 5 )
571 return;
572 m_combobox->SetSize(wxDefaultCoord, h);
573 }
574
575 void BitmapComboBoxWidgetsPage::OnButtonLoadFromFile(wxCommandEvent& WXUNUSED(event))
576 {
577 wxString s;
578 int sel = m_combobox->GetSelection();
579 if ( sel == wxNOT_FOUND )
580 sel = m_combobox->GetCount();
581
582 wxBitmap bmp = QueryBitmap(&s);
583 if (bmp.IsOk())
584 m_combobox->Insert(s, bmp, sel);
585 }
586
587 void BitmapComboBoxWidgetsPage::OnButtonSetFromFile(wxCommandEvent& WXUNUSED(event))
588 {
589 wxBitmap bmp = QueryBitmap(NULL);
590 if (bmp.IsOk())
591 m_combobox->SetItemBitmap(m_combobox->GetSelection(), bmp);
592 }
593
594 void BitmapComboBoxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
595 {
596 // "many" means 1000 here
597 for ( unsigned int n = 0; n < 1000; n++ )
598 {
599 m_combobox->Append(wxString::Format(wxT("item #%u"), n));
600 }
601 }
602
603 void BitmapComboBoxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
604 {
605 m_combobox->Append(wxT("First"));
606 m_combobox->Append(wxT("another one"));
607 m_combobox->Append(wxT("and the last (very very very very very very very very very very long) one"));
608 }
609
610 void BitmapComboBoxWidgetsPage::OnButtonAddSeveralWithImages(wxCommandEvent& WXUNUSED(event))
611 {
612 static const struct TestEntry
613 {
614 const char *text;
615 unsigned long rgb;
616 } s_entries[] =
617 {
618 { "Red circle", 0x0000ff },
619 { "Blue circle", 0xff0000 },
620 { "Green circle", 0x00ff00 },
621 { "Black circle", 0x000000 },
622 };
623
624 for ( unsigned i = 0; i < WXSIZEOF(s_entries); i++ )
625 {
626 const TestEntry& e = s_entries[i];
627 m_combobox->Append(e.text, CreateBitmap(wxColour(e.rgb)));
628 }
629 }
630
631 #if wxUSE_IMAGE
632 void BitmapComboBoxWidgetsPage::RescaleImage(wxImage& image, int w, int h)
633 {
634 if ( image.GetWidth() == w && image.GetHeight() == h )
635 return;
636
637 if ( w <= 0 || h <= 0 )
638 return;
639
640 static bool isFirstScale = true;
641
642 if ( isFirstScale && m_combobox->GetCount() > 0 )
643 {
644 wxMessageBox( wxT("wxBitmapComboBox normally only supports images of one size. ")
645 wxT("However, for demonstration purposes, loaded bitmaps are scaled to fit ")
646 wxT("using wxImage::Rescale."),
647 wxT("Notice"),
648 wxOK,
649 this );
650
651 isFirstScale = false;
652 }
653
654 image.Rescale(w, h);
655 }
656 #endif
657
658 void BitmapComboBoxWidgetsPage::LoadWidgetImages( wxArrayString* strings, wxImageList* images )
659 {
660 wxFileName fn;
661 fn.AssignCwd();
662 fn.AppendDir(wxT("icons"));
663
664 wxSetCursor(*wxHOURGLASS_CURSOR);
665
666 if ( !wxDir::Exists(fn.GetFullPath()) ||
667 !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
668 {
669 // Try ../../samples/widgets/icons
670 fn.RemoveLastDir();
671 fn.RemoveLastDir();
672 fn.AppendDir(wxT("icons"));
673 if ( !wxDir::Exists(fn.GetFullPath()) ||
674 !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
675 {
676 // Try ../../../samples/widgets/icons
677 fn.AssignCwd();
678 fn.RemoveLastDir();
679 fn.RemoveLastDir();
680 fn.RemoveLastDir();
681 fn.AppendDir(wxT("samples"));
682 fn.AppendDir(wxT("widgets"));
683 fn.AppendDir(wxT("icons"));
684 if ( !wxDir::Exists(fn.GetFullPath()) ||
685 !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
686 {
687 wxLogWarning(wxT("Could not load widget icons."));
688 wxSetCursor(*wxSTANDARD_CURSOR);
689 return;
690 }
691 }
692 }
693
694 unsigned int i;
695
696 // Get size of existing images in list
697 wxSize foundSize = m_combobox->GetBitmapSize();
698
699 for ( i=0; i<strings->size(); i++ )
700 {
701 fn.SetFullName((*strings)[i]);
702 wxString name = fn.GetName();
703
704 // Handle few exceptions
705 if ( name == wxT("bmpbtn") )
706 {
707 strings->RemoveAt(i);
708 i--;
709 }
710 else
711 {
712 #if wxUSE_IMAGE
713 wxASSERT(fn.FileExists());
714 wxImage image(fn.GetFullPath());
715 wxASSERT(image.Ok());
716 RescaleImage(image, foundSize.x, foundSize.y);
717 wxBitmap bmp(image);
718 wxASSERT( bmp.Ok() );
719 #else
720 wxBitmap bmp(wxNullBitmap);
721 #endif
722 images->Add(bmp);
723 (*strings)[i] = name;
724
725 // if the combobox is empty, use as bitmap size of the image list
726 // the size of the first valid image loaded
727 if (foundSize == wxDefaultSize)
728 foundSize = bmp.GetSize();
729 }
730 }
731
732 wxSetCursor(*wxSTANDARD_CURSOR);
733 }
734
735 void BitmapComboBoxWidgetsPage::OnButtonAddWidgetIcons(wxCommandEvent& WXUNUSED(event))
736 {
737 wxArrayString strings;
738
739 wxSize sz = m_combobox->GetBitmapSize();
740 if ( sz.x <= 0 )
741 {
742 sz.x = 32;
743 sz.y = 32;
744 }
745
746 wxImageList images(sz.x, sz.y);
747
748 LoadWidgetImages(&strings, &images);
749
750 unsigned int i;
751
752 for ( i=0; i<strings.size(); i++ )
753 {
754 m_combobox->Append(strings[i], images.GetBitmap(i));
755 }
756 }
757
758 void BitmapComboBoxWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
759 {
760 if (m_combobox)
761 event.Enable( m_chkSort->GetValue() || m_chkReadonly->GetValue() );
762 }
763
764 void BitmapComboBoxWidgetsPage::OnUpdateUIInsert(wxUpdateUIEvent& event)
765 {
766 if (m_combobox)
767 {
768 bool enable = !(m_combobox->GetWindowStyle() & wxCB_SORT);
769
770 event.Enable(enable);
771 }
772 }
773
774 void BitmapComboBoxWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
775 {
776 if (m_combobox)
777 {
778 unsigned long n;
779 event.Enable(m_textDelete->GetValue().ToULong(&n) &&
780 (n < (unsigned)m_combobox->GetCount()));
781 }
782 }
783
784 void BitmapComboBoxWidgetsPage::OnUpdateUIItemManipulator(wxUpdateUIEvent& event)
785 {
786 if (m_combobox)
787 event.Enable(m_combobox->GetSelection() != wxNOT_FOUND);
788 }
789
790 void BitmapComboBoxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
791 {
792 if (m_combobox)
793 event.Enable(m_combobox->GetCount() != 0);
794 }
795
796 void BitmapComboBoxWidgetsPage::OnComboText(wxCommandEvent& event)
797 {
798 if (!m_combobox)
799 return;
800
801 wxString s = event.GetString();
802
803 wxASSERT_MSG( s == m_combobox->GetValue(),
804 wxT("event and combobox values should be the same") );
805
806 if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER)
807 {
808 wxLogMessage(wxT("BitmapCombobox enter pressed (now '%s')"), s.c_str());
809 }
810 else
811 {
812 wxLogMessage(wxT("BitmapCombobox text changed (now '%s')"), s.c_str());
813 }
814 }
815
816 void BitmapComboBoxWidgetsPage::OnComboBox(wxCommandEvent& event)
817 {
818 long sel = event.GetInt();
819 m_textDelete->SetValue(wxString::Format(wxT("%ld"), sel));
820
821 wxLogMessage(wxT("BitmapCombobox item %ld selected"), sel);
822
823 wxLogMessage(wxT("BitmapCombobox GetValue(): %s"), m_combobox->GetValue().c_str() );
824 }
825
826 void BitmapComboBoxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
827 {
828 CreateCombo();
829 }
830
831 #if wxUSE_IMAGE
832 wxBitmap BitmapComboBoxWidgetsPage::LoadBitmap(const wxString& filepath)
833 {
834 // Get size of existing images in list
835 wxSize foundSize = m_combobox->GetBitmapSize();
836
837 // Have some reasonable maximum size
838 if ( foundSize.x <= 0 )
839 {
840 foundSize.x = IMG_SIZE_TRUNC;
841 foundSize.y = IMG_SIZE_TRUNC;
842 }
843
844 wxImage image(filepath);
845 if ( image.Ok() )
846 {
847 // Rescale very large images
848 int ow = image.GetWidth();
849 int oh = image.GetHeight();
850
851 if ( foundSize.x > 0 &&
852 (ow != foundSize.x || oh != foundSize.y) )
853 {
854 int w = ow;
855 if ( w > foundSize.x )
856 w = foundSize.x;
857 int h = oh;
858 if ( h > foundSize.y )
859 h = foundSize.y;
860
861 RescaleImage(image, w, h);
862 }
863
864 return wxBitmap(image);
865 }
866
867 return wxNullBitmap;
868 }
869 #else
870 wxBitmap BitmapComboBoxWidgetsPage::LoadBitmap(const wxString& WXUNUSED(filepath))
871 {
872 return wxNullBitmap;
873 }
874 #endif
875
876 wxBitmap BitmapComboBoxWidgetsPage::QueryBitmap(wxString* pStr)
877 {
878 wxString filepath = wxLoadFileSelector(wxT("image"),
879 wxEmptyString,
880 wxEmptyString,
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 if (bitmap.IsOk())
898 {
899 wxLogDebug(wxT("%i, %i"),bitmap.GetWidth(), bitmap.GetHeight());
900 }
901
902 ::wxSetCursor( *wxSTANDARD_CURSOR );
903
904 return bitmap;
905 }
906
907 wxBitmap BitmapComboBoxWidgetsPage::CreateBitmap(const wxColour& colour)
908 {
909 const int w = 10,
910 h = 10;
911
912 wxMemoryDC dc;
913 wxBitmap bmp(w, h);
914 dc.SelectObject(bmp);
915
916 // Draw transparent background
917 wxColour magic(255, 0, 255);
918 wxBrush magicBrush(magic);
919 dc.SetBrush(magicBrush);
920 dc.SetPen(*wxTRANSPARENT_PEN);
921 dc.DrawRectangle(0, 0, w, h);
922
923 // Draw image content
924 dc.SetBrush(wxBrush(colour));
925 dc.DrawCircle(h/2, h/2+1, h/2);
926
927 dc.SelectObject(wxNullBitmap);
928
929 // Finalize transparency with a mask
930 wxMask *mask = new wxMask(bmp, magic);
931 bmp.SetMask(mask);
932
933 return bmp;
934 }
935
936 void BitmapComboBoxWidgetsPage::OnDropDown(wxCommandEvent& WXUNUSED(event))
937 {
938 wxLogMessage(wxT("Combobox dropped down"));
939 }
940
941 void BitmapComboBoxWidgetsPage::OnCloseUp(wxCommandEvent& WXUNUSED(event))
942 {
943 wxLogMessage(wxT("Combobox closed up"));
944 }
945
946 #endif // wxUSE_BITMAPCOMBOBOX