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