fix initial layout of the widgets pages: avoid calling Fit() on them
[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 "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
98 virtual wxControl *GetWidget() const { return m_combobox; }
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
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
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
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
379 void BitmapComboBoxWidgetsPage::Reset()
380 {
381 m_chkSort->SetValue(false);
382 m_chkReadonly->SetValue(true);
383 }
384
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 bitmaps.Add(new wxBitmap(m_combobox->GetItemBitmap(n)));
403 }
404
405 m_sizerCombo->Detach( m_combobox );
406 delete m_combobox;
407 }
408
409 m_combobox = new wxBitmapComboBox();
410 m_combobox->Create(this, BitmapComboBoxPage_Combo, wxEmptyString,
411 wxDefaultPosition, wxDefaultSize,
412 0, NULL,
413 flags);
414
415 #if defined(wxGENERIC_BITMAPCOMBOBOX)
416 // This will sure make the list look nicer when larger images are used.
417 m_combobox->SetPopupMaxHeight(600);
418 #endif
419
420 unsigned int count = items.GetCount();
421 for ( unsigned int n = 0; n < count; n++ )
422 {
423 wxBitmap* bmp = (wxBitmap*) bitmaps[n];
424 m_combobox->Append(items[n], *bmp);
425 delete bmp;
426 }
427
428 m_sizerCombo->Add(m_combobox, 0, wxGROW | wxALL, 5);
429 m_sizerCombo->Layout();
430
431 // Allow changing height inorder to demonstrate flexible
432 // size of image "thumbnail" painted in the control itself.
433 long h = 0;
434 m_textChangeHeight->GetValue().ToLong(&h);
435 if ( h >= 5 )
436 m_combobox->SetSize(wxDefaultCoord, h);
437 }
438
439 // ----------------------------------------------------------------------------
440 // event handlers
441 // ----------------------------------------------------------------------------
442
443 void BitmapComboBoxWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
444 {
445 Reset();
446
447 CreateCombo();
448 }
449
450 void BitmapComboBoxWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event))
451 {
452 int sel = m_combobox->GetSelection();
453 if ( sel != wxNOT_FOUND )
454 {
455 #ifndef __WXGTK__
456 m_combobox->SetString(sel, m_textChange->GetValue());
457 #else
458 wxLogMessage(_T("Not implemented in wxGTK"));
459 #endif
460 }
461 }
462
463 void BitmapComboBoxWidgetsPage::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
464 {
465 unsigned long n;
466 if ( !m_textDelete->GetValue().ToULong(&n) ||
467 (n >= m_combobox->GetCount()) )
468 {
469 return;
470 }
471
472 m_combobox->Delete(n);
473 }
474
475 void BitmapComboBoxWidgetsPage::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
476 {
477 int sel = m_combobox->GetSelection();
478 if ( sel != wxNOT_FOUND )
479 {
480 m_combobox->Delete(sel);
481 }
482 }
483
484 void BitmapComboBoxWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
485 {
486 m_combobox->Clear();
487 }
488
489 void BitmapComboBoxWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
490 {
491 static unsigned int s_item = 0;
492
493 wxString s = m_textInsert->GetValue();
494 if ( !m_textInsert->IsModified() )
495 {
496 // update the default string
497 m_textInsert->SetValue(wxString::Format(_T("test item %u"), ++s_item));
498 }
499
500 int sel = m_combobox->GetSelection();
501 if ( sel == wxNOT_FOUND )
502 sel = m_combobox->GetCount();
503
504 m_combobox->Insert(s, wxNullBitmap, m_combobox->GetSelection());
505 }
506
507 void BitmapComboBoxWidgetsPage::OnTextChangeHeight(wxCommandEvent& WXUNUSED(event))
508 {
509 long h = 0;
510 m_textChangeHeight->GetValue().ToLong(&h);
511 if ( h < 5 )
512 return;
513 m_combobox->SetSize(wxDefaultCoord, h);
514 }
515
516 void BitmapComboBoxWidgetsPage::OnButtonLoadFromFile(wxCommandEvent& WXUNUSED(event))
517 {
518 wxString s;
519 int sel = m_combobox->GetSelection();
520 if ( sel == wxNOT_FOUND )
521 sel = m_combobox->GetCount();
522
523 m_combobox->Insert(s, QueryBitmap(&s), sel);
524 }
525
526 void BitmapComboBoxWidgetsPage::OnButtonSetFromFile(wxCommandEvent& WXUNUSED(event))
527 {
528 m_combobox->SetItemBitmap(m_combobox->GetSelection(), QueryBitmap(NULL));
529 }
530
531 void BitmapComboBoxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
532 {
533 // "many" means 1000 here
534 for ( unsigned int n = 0; n < 1000; n++ )
535 {
536 m_combobox->Append(wxString::Format(_T("item #%u"), n));
537 }
538 }
539
540 void BitmapComboBoxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
541 {
542 m_combobox->Append(_T("First"));
543 m_combobox->Append(_T("another one"));
544 m_combobox->Append(_T("and the last (very very very very very very very very very very long) one"));
545 }
546
547 void BitmapComboBoxWidgetsPage::OnButtonAddSeveralWithImages(wxCommandEvent& WXUNUSED(event))
548 {
549 int i;
550
551 for ( i=0; i<4; i++ )
552 {
553 wxString s;
554 wxBitmap bmp = CreateRandomBitmap(&s);
555 m_combobox->Append(s, bmp);
556 }
557 }
558
559 #if wxUSE_IMAGE
560 void BitmapComboBoxWidgetsPage::RescaleImage(wxImage& image, int w, int h)
561 {
562 if ( image.GetWidth() == w && image.GetHeight() == h )
563 return;
564
565 if ( w <= 0 || h <= 0 )
566 return;
567
568 static bool isFirstScale = true;
569
570 if ( isFirstScale && m_combobox->GetCount() > 0 )
571 {
572 wxMessageBox( wxT("wxBitmapComboBox normally only supports images of one size. ")
573 wxT("However, for demonstration purposes, loaded bitmaps are scaled to fit ")
574 wxT("using wxImage::Rescale."),
575 wxT("Notice"),
576 wxOK,
577 this );
578
579 isFirstScale = false;
580 }
581
582 image.Rescale(w, h);
583 }
584 #endif
585
586 void BitmapComboBoxWidgetsPage::LoadWidgetImages( wxArrayString* strings, wxImageList* images )
587 {
588 wxFileName fn;
589 fn.AssignCwd();
590 fn.AppendDir(wxT("icons"));
591
592 wxSetCursor(*wxHOURGLASS_CURSOR);
593
594 if ( !wxDir::Exists(fn.GetFullPath()) ||
595 !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
596 {
597 fn.RemoveLastDir();
598 fn.RemoveLastDir();
599 fn.AppendDir(wxT("icons"));
600 if ( !wxDir::Exists(fn.GetFullPath()) ||
601 !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
602 {
603 // Try ../../../samples/widgets/icons
604 fn.AssignCwd();
605 fn.RemoveLastDir();
606 fn.RemoveLastDir();
607 fn.RemoveLastDir();
608 fn.AppendDir(wxT("samples"));
609 fn.AppendDir(wxT("widgets"));
610 fn.AppendDir(wxT("icons"));
611 if ( !wxDir::Exists(fn.GetFullPath()) ||
612 !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
613 {
614 wxLogWarning(wxT("Could not load widget icons."));
615 wxSetCursor(*wxSTANDARD_CURSOR);
616 return;
617 }
618 }
619 }
620
621 unsigned int i;
622
623 // Get size of existing images in list
624 wxSize foundSize = m_combobox->GetBitmapSize();
625
626 for ( i=0; i<strings->size(); i++ )
627 {
628 fn.SetFullName((*strings)[i]);
629 wxString name =fn.GetName();
630
631 // Handle few exceptions
632 if ( name == wxT("bmpbtn") )
633 {
634 strings->RemoveAt(i);
635 i--;
636 }
637 else
638 {
639 #if wxUSE_IMAGE
640 wxASSERT(fn.FileExists());
641 wxImage image(fn.GetFullPath());
642 wxASSERT(image.Ok());
643 RescaleImage(image, foundSize.x, foundSize.y);
644 wxBitmap bmp(image);
645 wxASSERT( bmp.Ok() );
646 #else
647 wxBitmap bmp(wxNullBitmap);
648 #endif
649 images->Add(bmp);
650 (*strings)[i] = name;
651 }
652 }
653
654 wxSetCursor(*wxSTANDARD_CURSOR);
655 }
656
657 void BitmapComboBoxWidgetsPage::OnButtonAddWidgetIcons(wxCommandEvent& WXUNUSED(event))
658 {
659 wxArrayString strings;
660
661 wxSize sz = m_combobox->GetBitmapSize();
662 if ( sz.x <= 0 )
663 {
664 sz.x = 32;
665 sz.y = 32;
666 }
667
668 wxImageList images(sz.x, sz.y);
669
670 LoadWidgetImages(&strings, &images);
671
672 unsigned int i;
673
674 for ( i=0; i<strings.size(); i++ )
675 {
676 m_combobox->Append(strings[i], images.GetBitmap(i));
677 }
678 }
679
680 void BitmapComboBoxWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
681 {
682 if (m_combobox)
683 event.Enable( m_chkSort->GetValue() || m_chkReadonly->GetValue() );
684 }
685
686 void BitmapComboBoxWidgetsPage::OnUpdateUIInsert(wxUpdateUIEvent& event)
687 {
688 if (m_combobox)
689 {
690 bool enable = !(m_combobox->GetWindowStyle() & wxCB_SORT);
691
692 event.Enable(enable);
693 }
694 }
695
696 void BitmapComboBoxWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
697 {
698 if (m_combobox)
699 {
700 unsigned long n;
701 event.Enable(m_textDelete->GetValue().ToULong(&n) &&
702 (n < (unsigned)m_combobox->GetCount()));
703 }
704 }
705
706 void BitmapComboBoxWidgetsPage::OnUpdateUIItemManipulator(wxUpdateUIEvent& event)
707 {
708 if (m_combobox)
709 event.Enable(m_combobox->GetSelection() != wxNOT_FOUND);
710 }
711
712 void BitmapComboBoxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
713 {
714 if (m_combobox)
715 event.Enable(m_combobox->GetCount() != 0);
716 }
717
718 void BitmapComboBoxWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
719 {
720 if (m_combobox)
721 event.Enable(!(m_combobox->GetWindowStyle() & wxCB_SORT));
722 }
723
724 void BitmapComboBoxWidgetsPage::OnUpdateUIAddSeveralWithImages(wxUpdateUIEvent& event)
725 {
726 if (m_combobox)
727 event.Enable(!(m_combobox->GetWindowStyle() & wxCB_SORT));
728 }
729
730 void BitmapComboBoxWidgetsPage::OnComboText(wxCommandEvent& event)
731 {
732 if (!m_combobox)
733 return;
734
735 wxString s = event.GetString();
736
737 wxASSERT_MSG( s == m_combobox->GetValue(),
738 _T("event and combobox values should be the same") );
739
740 if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER)
741 wxLogMessage(_T("BitmapCombobox enter pressed (now '%s')"), s.c_str());
742 else
743 wxLogMessage(_T("BitmapCombobox text changed (now '%s')"), s.c_str());
744 }
745
746 void BitmapComboBoxWidgetsPage::OnComboBox(wxCommandEvent& event)
747 {
748 long sel = event.GetInt();
749 m_textDelete->SetValue(wxString::Format(_T("%ld"), sel));
750
751 wxLogMessage(_T("BitmapCombobox item %ld selected"), sel);
752
753 wxLogMessage(_T("BitmapCombobox GetValue(): %s"), m_combobox->GetValue().c_str() );
754 }
755
756 void BitmapComboBoxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
757 {
758 CreateCombo();
759 }
760
761 #if wxUSE_IMAGE
762 wxBitmap BitmapComboBoxWidgetsPage::LoadBitmap(const wxString& filepath)
763 {
764 // Get size of existing images in list
765 wxSize foundSize = m_combobox->GetBitmapSize();
766
767 // Have some reasonable maximum size
768 if ( foundSize.x <= 0 )
769 {
770 foundSize.x = IMG_SIZE_TRUNC;
771 foundSize.y = IMG_SIZE_TRUNC;
772 }
773
774 wxImage image(filepath);
775 if ( image.Ok() )
776 {
777 // Rescale very large images
778 int ow = image.GetWidth();
779 int oh = image.GetHeight();
780
781 if ( foundSize.x > 0 &&
782 (ow != foundSize.x || oh != foundSize.y) )
783 {
784 int w = ow;
785 if ( w > foundSize.x )
786 w = foundSize.x;
787 int h = oh;
788 if ( h > foundSize.y )
789 h = foundSize.y;
790
791 RescaleImage(image, w, h);
792 }
793
794 return wxBitmap(image);
795 }
796
797 return wxNullBitmap;
798 }
799 #else
800 wxBitmap BitmapComboBoxWidgetsPage::LoadBitmap(const wxString& WXUNUSED(filepath))
801 {
802 return wxNullBitmap;
803 }
804 #endif
805
806 wxBitmap BitmapComboBoxWidgetsPage::QueryBitmap(wxString* pStr)
807 {
808 wxString filepath = wxFileSelector(wxT("Choose image file"),
809 wxEmptyString,
810 wxEmptyString,
811 wxEmptyString,
812 wxT("*.*"),
813 wxFD_OPEN | wxFD_FILE_MUST_EXIST,
814 this);
815
816 wxBitmap bitmap;
817
818 ::wxSetCursor( *wxHOURGLASS_CURSOR );
819
820 if ( filepath.length() )
821 {
822 if ( pStr )
823 {
824 *pStr = wxFileName(filepath).GetName();
825 }
826
827 bitmap = LoadBitmap(filepath);
828 }
829
830 wxLogDebug(wxT("%i, %i"),bitmap.GetWidth(), bitmap.GetHeight());
831
832 ::wxSetCursor( *wxSTANDARD_CURSOR );
833
834 return bitmap;
835 }
836
837 wxBitmap BitmapComboBoxWidgetsPage::CreateBitmap(const wxColour& colour)
838 {
839 int ch = m_combobox->GetBitmapSize().y;
840 int h0 = ch - 5;
841
842 long w = ch;
843 long h = ch;
844
845 if ( w <= 0 )
846 w = h0 - 1;
847 if ( h <= 0 )
848 h = h0;
849 if ( h > ch )
850 h = ch;
851
852 wxMemoryDC dc;
853 wxBitmap bmp(w,h);
854 dc.SelectObject(bmp);
855
856 // Draw transparent background
857 wxColour magic(255,0,255);
858 wxBrush magicBrush(magic);
859 dc.SetBrush(magicBrush);
860 dc.SetPen(*wxTRANSPARENT_PEN);
861 dc.DrawRectangle(0,0,bmp.GetWidth(),bmp.GetHeight());
862
863 // Draw image content
864 dc.SetBrush(wxBrush(colour));
865 dc.DrawCircle(h/2,h/2+1,(h/2));
866
867 dc.SelectObject(wxNullBitmap);
868
869 // Finalize transparency with a mask
870 wxMask *mask = new wxMask(bmp, magic);
871 bmp.SetMask(mask);
872
873 return bmp;
874 }
875
876 wxBitmap BitmapComboBoxWidgetsPage::CreateRandomBitmap( wxString* pStr )
877 {
878 int i = rand() % 6;
879 const wxChar* str = wxT("");
880 wxBitmap bmp;
881
882 if ( i == 0 )
883 {
884 str = wxT("Red Circle");
885 bmp = CreateBitmap( *wxRED );
886 }
887 else if ( i == 1 )
888 {
889 str = wxT("Green Circle");
890 bmp = CreateBitmap( *wxGREEN );
891 }
892 else if ( i == 2 )
893 {
894 str = wxT("Blue Circle");
895 bmp = CreateBitmap( *wxBLUE );
896 }
897 else if ( i == 3 )
898 {
899 str = wxT("Black Circle");
900 bmp = CreateBitmap( *wxBLACK );
901 }
902 else if ( i == 4 )
903 {
904 str = wxT("Cyan Circle");
905 bmp = CreateBitmap( *wxCYAN );
906 }
907 else if ( i == 5 )
908 {
909 str = wxT("Light Grey Circle");
910 bmp = CreateBitmap( *wxLIGHT_GREY );
911 }
912
913 if ( pStr )
914 *pStr = str;
915
916 return bmp;
917 }
918
919 #endif //wxUSE_BITMAPCOMBOBOX