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