Fix for assert in setting image from file 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,-1), 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, -1);
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(-1, 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 if (m_combobox->GetSelection() >= 0)
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(-1, h);
514 }
515
516 void BitmapComboBoxWidgetsPage::OnButtonLoadFromFile(wxCommandEvent& WXUNUSED(event))
517 {
518 wxString s;
519 m_combobox->Insert(s, QueryBitmap(&s), m_combobox->GetSelection());
520 }
521
522 void BitmapComboBoxWidgetsPage::OnButtonSetFromFile(wxCommandEvent& WXUNUSED(event))
523 {
524 m_combobox->SetItemBitmap(m_combobox->GetSelection(), QueryBitmap(NULL));
525 }
526
527 void BitmapComboBoxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
528 {
529 // "many" means 1000 here
530 for ( unsigned int n = 0; n < 1000; n++ )
531 {
532 m_combobox->Append(wxString::Format(_T("item #%u"), n));
533 }
534 }
535
536 void BitmapComboBoxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
537 {
538 m_combobox->Append(_T("First"));
539 m_combobox->Append(_T("another one"));
540 m_combobox->Append(_T("and the last (very very very very very very very very very very long) one"));
541 }
542
543 void BitmapComboBoxWidgetsPage::OnButtonAddSeveralWithImages(wxCommandEvent& WXUNUSED(event))
544 {
545 int i;
546
547 for ( i=0; i<4; i++ )
548 {
549 wxString s;
550 wxBitmap bmp = CreateRandomBitmap(&s);
551 m_combobox->Append(s, bmp);
552 }
553 }
554
555 void BitmapComboBoxWidgetsPage::LoadWidgetImages( wxArrayString* strings, wxImageList* images )
556 {
557 wxFileName fn;
558 fn.AssignCwd();
559 fn.AppendDir(wxT("icons"));
560
561 wxSetCursor(*wxHOURGLASS_CURSOR);
562
563 if ( !wxDir::Exists(fn.GetFullPath()) ||
564 !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
565 {
566 fn.RemoveLastDir();
567 fn.RemoveLastDir();
568 fn.AppendDir(wxT("icons"));
569 if ( !wxDir::Exists(fn.GetFullPath()) ||
570 !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
571 {
572 // Try ../../../samples/widgets/icons
573 fn.AssignCwd();
574 fn.RemoveLastDir();
575 fn.RemoveLastDir();
576 fn.RemoveLastDir();
577 fn.AppendDir(wxT("samples"));
578 fn.AppendDir(wxT("widgets"));
579 fn.AppendDir(wxT("icons"));
580 if ( !wxDir::Exists(fn.GetFullPath()) ||
581 !wxDir::GetAllFiles(fn.GetFullPath(),strings,wxT("*.xpm")) )
582 {
583 wxLogWarning(wxT("Could not load widget icons."));
584 wxSetCursor(*wxSTANDARD_CURSOR);
585 return;
586 }
587 }
588 }
589
590 unsigned int i;
591
592 // Get size of existing images in list
593 wxSize foundSize = m_combobox->GetBitmapSize();
594
595 for ( i=0; i<strings->size(); i++ )
596 {
597 fn.SetFullName((*strings)[i]);
598 wxString name =fn.GetName();
599
600 // Handle few exceptions
601 if ( name == wxT("bmpbtn") )
602 {
603 strings->RemoveAt(i);
604 i--;
605 }
606 else
607 {
608 #if wxUSE_IMAGE
609 wxASSERT(fn.FileExists());
610 wxImage image(fn.GetFullPath());
611 wxASSERT(image.Ok());
612 if ( m_chkScaleimages->GetValue() && foundSize.x > 0 )
613 image.Rescale(foundSize.x, foundSize.y);
614 wxBitmap bmp(image);
615 wxASSERT( bmp.Ok() );
616 #else
617 wxBitmap bmp(wxNullBitmap);
618 #endif
619 images->Add(bmp);
620 (*strings)[i] = name;
621 }
622 }
623
624 wxSetCursor(*wxSTANDARD_CURSOR);
625 }
626
627 void BitmapComboBoxWidgetsPage::OnButtonAddWidgetIcons(wxCommandEvent& WXUNUSED(event))
628 {
629 wxArrayString strings;
630
631 int sz = 32;
632 //if ( m_chkScaleimages->GetValue() )
633 // sz = 16;
634
635 wxImageList images(sz, sz);
636
637 LoadWidgetImages(&strings, &images);
638
639 unsigned int i;
640
641 for ( i=0; i<strings.size(); i++ )
642 {
643 m_combobox->Append(strings[i], images.GetBitmap(i));
644 }
645 }
646
647 void BitmapComboBoxWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
648 {
649 if (m_combobox)
650 event.Enable( m_chkSort->GetValue() || m_chkReadonly->GetValue() );
651 }
652
653 void BitmapComboBoxWidgetsPage::OnUpdateUIInsert(wxUpdateUIEvent& event)
654 {
655 if (m_combobox)
656 {
657 bool enable = !(m_combobox->GetWindowStyle() & wxCB_SORT);
658
659 event.Enable(enable);
660 }
661 }
662
663 void BitmapComboBoxWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
664 {
665 if (m_combobox)
666 {
667 unsigned long n;
668 event.Enable(m_textDelete->GetValue().ToULong(&n) &&
669 (n < (unsigned)m_combobox->GetCount()));
670 }
671 }
672
673 void BitmapComboBoxWidgetsPage::OnUpdateUIItemManipulator(wxUpdateUIEvent& event)
674 {
675 if (m_combobox)
676 event.Enable(m_combobox->GetSelection() != wxNOT_FOUND);
677 }
678
679 void BitmapComboBoxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
680 {
681 if (m_combobox)
682 event.Enable(m_combobox->GetCount() != 0);
683 }
684
685 void BitmapComboBoxWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
686 {
687 if (m_combobox)
688 event.Enable(!(m_combobox->GetWindowStyle() & wxCB_SORT));
689 }
690
691 void BitmapComboBoxWidgetsPage::OnUpdateUIAddSeveralWithImages(wxUpdateUIEvent& event)
692 {
693 if (m_combobox)
694 event.Enable(!(m_combobox->GetWindowStyle() & wxCB_SORT));
695 }
696
697 void BitmapComboBoxWidgetsPage::OnComboText(wxCommandEvent& event)
698 {
699 if (!m_combobox)
700 return;
701
702 wxString s = event.GetString();
703
704 wxASSERT_MSG( s == m_combobox->GetValue(),
705 _T("event and combobox values should be the same") );
706
707 if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER)
708 wxLogMessage(_T("BitmapCombobox enter pressed (now '%s')"), s.c_str());
709 else
710 wxLogMessage(_T("BitmapCombobox text changed (now '%s')"), s.c_str());
711 }
712
713 void BitmapComboBoxWidgetsPage::OnComboBox(wxCommandEvent& event)
714 {
715 long sel = event.GetInt();
716 m_textDelete->SetValue(wxString::Format(_T("%ld"), sel));
717
718 wxLogMessage(_T("BitmapCombobox item %ld selected"), sel);
719
720 wxLogMessage(_T("BitmapCombobox GetValue(): %s"), m_combobox->GetValue().c_str() );
721 }
722
723 void BitmapComboBoxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
724 {
725 CreateCombo();
726 }
727
728 #if wxUSE_IMAGE
729 wxBitmap BitmapComboBoxWidgetsPage::LoadBitmap(const wxString& filepath)
730 {
731 // Get size of existing images in list
732 wxSize foundSize = m_combobox->GetBitmapSize();
733
734 wxImage image(filepath);
735 if ( image.Ok() )
736 {
737 // Rescale very large images
738 int ow = image.GetWidth();
739 int oh = image.GetHeight();
740
741 if ( foundSize.x > 0 &&
742 (ow != foundSize.x || oh != foundSize.y) )
743 {
744 int w = ow;
745 if ( w > foundSize.x )
746 w = foundSize.x;
747 int h = oh;
748 if ( h > foundSize.y )
749 h = foundSize.y;
750
751 image.Rescale(w, h);
752 }
753
754 return wxBitmap(image);
755 }
756
757 return wxNullBitmap;
758 }
759 #else
760 wxBitmap BitmapComboBoxWidgetsPage::LoadBitmap(const wxString& WXUNUSED(filepath))
761 {
762 return wxNullBitmap;
763 }
764 #endif
765
766 wxBitmap BitmapComboBoxWidgetsPage::QueryBitmap(wxString* pStr)
767 {
768 wxString filepath = wxFileSelector(wxT("Choose image file"),
769 wxT(""),
770 wxT(""),
771 wxT(""),
772 wxT("*.*"),
773 wxFD_OPEN | wxFD_FILE_MUST_EXIST,
774 this);
775
776 wxBitmap bitmap;
777
778 ::wxSetCursor( *wxHOURGLASS_CURSOR );
779
780 if ( filepath.length() )
781 {
782 if ( pStr )
783 {
784 *pStr = wxFileName(filepath).GetName();
785 }
786
787 bitmap = LoadBitmap(filepath);
788 }
789
790 ::wxSetCursor( *wxSTANDARD_CURSOR );
791
792 return bitmap;
793 }
794
795 wxBitmap BitmapComboBoxWidgetsPage::CreateBitmap(const wxColour& colour)
796 {
797 int ch = m_combobox->GetBitmapSize().y;
798 int h0 = ch - 5;
799
800 long w = ch;
801 long h = ch;
802
803 if ( w <= 0 )
804 w = h0 - 1;
805 if ( h <= 0 )
806 h = h0;
807 if ( h > ch )
808 h = ch;
809
810 wxMemoryDC dc;
811 wxBitmap bmp(w,h);
812 dc.SelectObject(bmp);
813
814 // Draw transparent background
815 wxColour magic(255,0,255);
816 wxBrush magicBrush(magic);
817 dc.SetBrush(magicBrush);
818 dc.SetPen(*wxTRANSPARENT_PEN);
819 dc.DrawRectangle(0,0,bmp.GetWidth(),bmp.GetHeight());
820
821 // Draw image content
822 dc.SetBrush(wxBrush(colour));
823 dc.DrawCircle(h/2,h/2+1,(h/2));
824
825 dc.SelectObject(wxNullBitmap);
826
827 // Finalize transparency with a mask
828 wxMask *mask = new wxMask(bmp, magic);
829 bmp.SetMask(mask);
830
831 return bmp;
832 }
833
834 wxBitmap BitmapComboBoxWidgetsPage::CreateRandomBitmap( wxString* pStr )
835 {
836 int i = rand() % 6;
837 const wxChar* str = wxT("");
838 wxBitmap bmp;
839
840 if ( i == 0 )
841 {
842 str = wxT("Red Circle");
843 bmp = CreateBitmap( *wxRED );
844 }
845 else if ( i == 1 )
846 {
847 str = wxT("Green Circle");
848 bmp = CreateBitmap( *wxGREEN );
849 }
850 else if ( i == 2 )
851 {
852 str = wxT("Blue Circle");
853 bmp = CreateBitmap( *wxBLUE );
854 }
855 else if ( i == 3 )
856 {
857 str = wxT("Black Circle");
858 bmp = CreateBitmap( *wxBLACK );
859 }
860 else if ( i == 4 )
861 {
862 str = wxT("Cyan Circle");
863 bmp = CreateBitmap( *wxCYAN );
864 }
865 else if ( i == 5 )
866 {
867 str = wxT("Light Grey Circle");
868 bmp = CreateBitmap( *wxLIGHT_GREY );
869 }
870
871 if ( pStr )
872 *pStr = str;
873
874 return bmp;
875 }
876
877 #endif //wxUSE_BITMAPCOMBOBOX