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