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