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