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