1 /////////////////////////////////////////////////////////////////////////////
2 // Program:     wxWidgets Widgets Sample
3 // Name:        odcombobox.cpp
4 // Purpose:     Part of the widgets sample showing wxOwnerDrawnComboBox
5 // Author:      Jaakko Salli (based on combobox page by Vadim Zeitlin)
6 // Created:     Jul-28-2006
7 // Id:          $Id: odcombobox.cpp 43755 2006-12-03 13:43:44Z VZ $
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_ODCOMBOBOX
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 #endif
41 
42 #include "wx/dc.h"
43 #include "wx/dcmemory.h"
44 #include "wx/sizer.h"
45 #include "wx/odcombo.h"
46 
47 
48 #include "widgets.h"
49 
50 #include "icons/odcombobox.xpm"
51 
52 // ----------------------------------------------------------------------------
53 // constants
54 // ----------------------------------------------------------------------------
55 
56 // control ids
57 enum
58 {
59     ODComboPage_Reset = wxID_HIGHEST,
60     ODComboPage_PopupMinWidth,
61     ODComboPage_PopupHeight,
62     ODComboPage_ButtonWidth,
63     ODComboPage_ButtonHeight,
64     ODComboPage_ButtonSpacing,
65     ODComboPage_CurText,
66     ODComboPage_InsertionPointText,
67     ODComboPage_Insert,
68     ODComboPage_InsertText,
69     ODComboPage_Add,
70     ODComboPage_AddText,
71     ODComboPage_AddSeveral,
72     ODComboPage_AddMany,
73     ODComboPage_Clear,
74     ODComboPage_Change,
75     ODComboPage_ChangeText,
76     ODComboPage_Delete,
77     ODComboPage_DeleteText,
78     ODComboPage_DeleteSel,
79     ODComboPage_Combo
80 };
81 
82 
83 // ----------------------------------------------------------------------------
84 // ODComboboxWidgetsPage
85 // ----------------------------------------------------------------------------
86 
87 class ODComboboxWidgetsPage : public WidgetsPage
88 {
89 public:
90     ODComboboxWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
91 
GetWidget() const92     virtual wxControl *GetWidget() const { return m_combobox; }
RecreateWidget()93     virtual void RecreateWidget() { CreateCombo(); }
94 
95     // lazy creation of the content
96     virtual void CreateContent();
97 
98 protected:
99     // event handlers
100     void OnButtonReset(wxCommandEvent& event);
101     void OnButtonChange(wxCommandEvent& event);
102     void OnButtonDelete(wxCommandEvent& event);
103     void OnButtonDeleteSel(wxCommandEvent& event);
104     void OnButtonClear(wxCommandEvent& event);
105     void OnButtonInsert(wxCommandEvent &event);
106     void OnButtonAdd(wxCommandEvent& event);
107     void OnButtonAddSeveral(wxCommandEvent& event);
108     void OnButtonAddMany(wxCommandEvent& event);
109 
110     void OnComboBox(wxCommandEvent& event);
111     void OnComboText(wxCommandEvent& event);
112 
113     void OnCheckOrRadioBox(wxCommandEvent& event);
114 
115     void OnTextPopupWidth(wxCommandEvent& event);
116     void OnTextPopupHeight(wxCommandEvent& event);
117     void OnTextButtonAll(wxCommandEvent& event);
118 
119     void OnUpdateUICurText(wxUpdateUIEvent& event);
120     void OnUpdateUIInsertionPointText(wxUpdateUIEvent& event);
121 
122     void OnUpdateUIInsert(wxUpdateUIEvent& event);
123     void OnUpdateUIAddSeveral(wxUpdateUIEvent& event);
124     void OnUpdateUIClearButton(wxUpdateUIEvent& event);
125     void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
126     void OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event);
127     void OnUpdateUIResetButton(wxUpdateUIEvent& event);
128 
129     // reset the odcombobox parameters
130     void Reset();
131 
132     // (re)create the odcombobox
133     void CreateCombo();
134 
135     // helper that gets all button values from controls and calls SetButtonPosition
136     void GetButtonPosition();
137 
138     // helper to create the button bitmap
139     wxBitmap CreateBitmap(const wxColour& colour);
140 
141     // the controls
142     // ------------
143 
144     // the checkboxes for styles
145     wxCheckBox *m_chkSort,
146                *m_chkReadonly,
147                *m_chkDclickcycles,
148                *m_chkBitmapbutton,
149                *m_chkStdbutton;
150 
151     // the text entries for popup and button adjustment
152     wxTextCtrl *m_textPopupMinWidth,
153                *m_textPopupHeight,
154                *m_textButtonWidth,
155                *m_textButtonHeight,
156                *m_textButtonSpacing;
157 
158     // the checkboxes for same
159     wxCheckBox *m_chkAlignpopupright,
160                *m_chkAlignbutleft;
161 
162     // the combobox itself and the sizer it is in
163     wxOwnerDrawnComboBox *m_combobox;
164     wxSizer *m_sizerCombo;
165 
166     // the text entries for "Add/change string" and "Delete" buttons
167     wxTextCtrl *m_textInsert,
168                *m_textAdd,
169                *m_textChange,
170                *m_textDelete;
171 
172 private:
173     DECLARE_EVENT_TABLE()
174     DECLARE_WIDGETS_PAGE(ODComboboxWidgetsPage)
175 };
176 
177 // ----------------------------------------------------------------------------
178 // event tables
179 // ----------------------------------------------------------------------------
180 
181 BEGIN_EVENT_TABLE(ODComboboxWidgetsPage, WidgetsPage)
182     EVT_BUTTON(ODComboPage_Reset, ODComboboxWidgetsPage::OnButtonReset)
183     EVT_BUTTON(ODComboPage_Change, ODComboboxWidgetsPage::OnButtonChange)
184     EVT_BUTTON(ODComboPage_Delete, ODComboboxWidgetsPage::OnButtonDelete)
185     EVT_BUTTON(ODComboPage_DeleteSel, ODComboboxWidgetsPage::OnButtonDeleteSel)
186     EVT_BUTTON(ODComboPage_Clear, ODComboboxWidgetsPage::OnButtonClear)
187     EVT_BUTTON(ODComboPage_Insert, ODComboboxWidgetsPage::OnButtonInsert)
188     EVT_BUTTON(ODComboPage_Add, ODComboboxWidgetsPage::OnButtonAdd)
189     EVT_BUTTON(ODComboPage_AddSeveral, ODComboboxWidgetsPage::OnButtonAddSeveral)
190     EVT_BUTTON(ODComboPage_AddMany, ODComboboxWidgetsPage::OnButtonAddMany)
191 
192     EVT_TEXT_ENTER(ODComboPage_InsertText, ODComboboxWidgetsPage::OnButtonInsert)
193     EVT_TEXT_ENTER(ODComboPage_AddText, ODComboboxWidgetsPage::OnButtonAdd)
194     EVT_TEXT_ENTER(ODComboPage_DeleteText, ODComboboxWidgetsPage::OnButtonDelete)
195 
196     EVT_TEXT(ODComboPage_PopupMinWidth, ODComboboxWidgetsPage::OnTextPopupWidth)
197     EVT_TEXT(ODComboPage_PopupHeight, ODComboboxWidgetsPage::OnTextPopupHeight)
198     EVT_TEXT(ODComboPage_ButtonWidth, ODComboboxWidgetsPage::OnTextButtonAll)
199     EVT_TEXT(ODComboPage_ButtonHeight, ODComboboxWidgetsPage::OnTextButtonAll)
200     EVT_TEXT(ODComboPage_ButtonSpacing, ODComboboxWidgetsPage::OnTextButtonAll)
201 
202     EVT_UPDATE_UI(ODComboPage_CurText, ODComboboxWidgetsPage::OnUpdateUICurText)
203     EVT_UPDATE_UI(ODComboPage_InsertionPointText, ODComboboxWidgetsPage::OnUpdateUIInsertionPointText)
204 
205     EVT_UPDATE_UI(ODComboPage_Reset, ODComboboxWidgetsPage::OnUpdateUIResetButton)
206     EVT_UPDATE_UI(ODComboPage_Insert, ODComboboxWidgetsPage::OnUpdateUIInsert)
207     EVT_UPDATE_UI(ODComboPage_AddSeveral, ODComboboxWidgetsPage::OnUpdateUIAddSeveral)
208     EVT_UPDATE_UI(ODComboPage_Clear, ODComboboxWidgetsPage::OnUpdateUIClearButton)
209     EVT_UPDATE_UI(ODComboPage_DeleteText, ODComboboxWidgetsPage::OnUpdateUIClearButton)
210     EVT_UPDATE_UI(ODComboPage_Delete, ODComboboxWidgetsPage::OnUpdateUIDeleteButton)
211     EVT_UPDATE_UI(ODComboPage_Change, ODComboboxWidgetsPage::OnUpdateUIDeleteSelButton)
212     EVT_UPDATE_UI(ODComboPage_ChangeText, ODComboboxWidgetsPage::OnUpdateUIDeleteSelButton)
213     EVT_UPDATE_UI(ODComboPage_DeleteSel, ODComboboxWidgetsPage::OnUpdateUIDeleteSelButton)
214 
215     EVT_COMBOBOX(ODComboPage_Combo, ODComboboxWidgetsPage::OnComboBox)
216     EVT_TEXT(ODComboPage_Combo, ODComboboxWidgetsPage::OnComboText)
217     EVT_TEXT_ENTER(ODComboPage_Combo, ODComboboxWidgetsPage::OnComboText)
218 
219     EVT_CHECKBOX(wxID_ANY, ODComboboxWidgetsPage::OnCheckOrRadioBox)
220     EVT_RADIOBOX(wxID_ANY, ODComboboxWidgetsPage::OnCheckOrRadioBox)
221 END_EVENT_TABLE()
222 
223 // ============================================================================
224 // implementation
225 // ============================================================================
226 
227 //
228 // wxOwnerDrawnComboBox needs to subclassed so that owner-drawing
229 // callbacks can be implemented.
230 class DemoODComboBox : public wxOwnerDrawnComboBox
231 {
232 public:
OnDrawItem(wxDC & dc,const wxRect & rect,int item,int WXUNUSED (flags)) const233     virtual void OnDrawItem(wxDC& dc,
234                             const wxRect& rect,
235                             int item,
236                             int WXUNUSED(flags)) const
237     {
238         if ( item == wxNOT_FOUND )
239             return;
240 
241         wxColour txtCol;
242         int mod = item % 4;
243 
244         if ( mod == 0 )
245             txtCol = *wxBLACK;
246         else if ( mod == 1 )
247             txtCol = *wxRED;
248         else if ( mod == 2 )
249             txtCol = *wxGREEN;
250         else
251             txtCol = *wxBLUE;
252 
253         dc.SetTextForeground(txtCol);
254 
255         dc.DrawText(GetString(item),
256                     rect.x + 3,
257                     rect.y + ((rect.height - dc.GetCharHeight())/2)
258                    );
259     }
260 
OnDrawBackground(wxDC & dc,const wxRect & rect,int item,int flags) const261     virtual void OnDrawBackground(wxDC& dc, const wxRect& rect,
262                                   int item, int flags ) const
263     {
264 
265         // If item is selected or even, or we are painting the
266         // combo control itself, use the default rendering.
267         if ( (flags & (wxODCB_PAINTING_CONTROL|wxODCB_PAINTING_SELECTED)) ||
268              (item & 1) == 0 )
269         {
270             wxOwnerDrawnComboBox::OnDrawBackground(dc,rect,item,flags);
271             return;
272         }
273 
274         // Otherwise, draw every other background with different colour.
275         wxColour bgCol(240,240,250);
276         dc.SetBrush(wxBrush(bgCol));
277         dc.SetPen(wxPen(bgCol));
278         dc.DrawRectangle(rect);
279     }
280 
OnMeasureItem(size_t WXUNUSED (item)) const281     virtual wxCoord OnMeasureItem(size_t WXUNUSED(item)) const
282     {
283         return 48;
284     }
285 
OnMeasureItemWidth(size_t WXUNUSED (item)) const286     virtual wxCoord OnMeasureItemWidth(size_t WXUNUSED(item)) const
287     {
288         return -1; // default - will be measured from text width
289     }
290 };
291 
292 
293 IMPLEMENT_WIDGETS_PAGE(ODComboboxWidgetsPage, _T("OwnerDrawnCombobox"),
294                        GENERIC_CTRLS | WITH_ITEMS_CTRLS | COMBO_CTRLS
295                        );
296 
ODComboboxWidgetsPage(WidgetsBookCtrl * book,wxImageList * imaglist)297 ODComboboxWidgetsPage::ODComboboxWidgetsPage(WidgetsBookCtrl *book,
298                                              wxImageList *imaglist)
299                   : WidgetsPage(book, imaglist, odcombobox_xpm)
300 {
301     // init everything
302     m_chkSort =
303     m_chkReadonly =
304     m_chkDclickcycles = (wxCheckBox *)NULL;
305 
306     m_combobox = (wxOwnerDrawnComboBox *)NULL;
307     m_sizerCombo = (wxSizer *)NULL;
308 }
309 
CreateContent()310 void ODComboboxWidgetsPage::CreateContent()
311 {
312     /*
313        What we create here is a frame having 3 panes: style pane is the
314        leftmost one, in the middle the pane with buttons allowing to perform
315        miscellaneous combobox operations and the pane containing the combobox
316        itself to the right
317     */
318     wxTextCtrl *text;
319     wxSizer *sizerRow;
320 
321     wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
322 
323     wxSizer *sizerLeft = new wxBoxSizer(wxVERTICAL);
324 
325     // left pane - style box
326     wxStaticBox *box = new wxStaticBox(this, wxID_ANY, _T("&Set style"));
327 
328     wxSizer *sizerStyle = new wxStaticBoxSizer(box, wxVERTICAL);
329 
330     m_chkSort = CreateCheckBoxAndAddToSizer(sizerStyle, _T("&Sort items"));
331     m_chkReadonly = CreateCheckBoxAndAddToSizer(sizerStyle, _T("&Read only"));
332     m_chkDclickcycles = CreateCheckBoxAndAddToSizer(sizerStyle, _T("&Double-click Cycles"));
333 
334     sizerStyle->AddSpacer(4);
335 
336     m_chkBitmapbutton = CreateCheckBoxAndAddToSizer(sizerStyle, _T("&Bitmap button"));
337     m_chkStdbutton = CreateCheckBoxAndAddToSizer(sizerStyle, _T("B&lank button background"));
338 
339     wxButton *btn = new wxButton(this, ODComboPage_Reset, _T("&Reset"));
340     sizerStyle->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 3);
341 
342     sizerLeft->Add(sizerStyle, 0, wxGROW | wxALIGN_CENTRE_HORIZONTAL);
343 
344     // left pane - popup adjustment box
345     box = new wxStaticBox(this, wxID_ANY, _T("Adjust &popup"));
346 
347     wxSizer *sizerPopupPos = new wxStaticBoxSizer(box, wxVERTICAL);
348 
349     sizerRow = CreateSizerWithTextAndLabel(_T("Min. Width:"),
350                                            ODComboPage_PopupMinWidth,
351                                            &m_textPopupMinWidth);
352     m_textPopupMinWidth->SetValue(wxT("-1"));
353     sizerPopupPos->Add(sizerRow, 0, wxALL | wxGROW, 5);
354 
355     sizerRow = CreateSizerWithTextAndLabel(_T("Max. Height:"),
356                                            ODComboPage_PopupHeight,
357                                            &m_textPopupHeight);
358     m_textPopupHeight->SetValue(wxT("-1"));
359     sizerPopupPos->Add(sizerRow, 0, wxALL | wxGROW, 5);
360 
361     m_chkAlignpopupright = CreateCheckBoxAndAddToSizer(sizerPopupPos, _T("Align Right"));
362 
363     sizerLeft->Add(sizerPopupPos, 0, wxGROW | wxALIGN_CENTRE_HORIZONTAL | wxTOP, 2);
364 
365     // left pane - button adjustment box
366     box = new wxStaticBox(this, wxID_ANY, _T("Adjust &button"));
367 
368     wxSizer *sizerButtonPos = new wxStaticBoxSizer(box, wxVERTICAL);
369 
370     sizerRow = CreateSizerWithTextAndLabel(_T("Width:"),
371                                            ODComboPage_ButtonWidth,
372                                            &m_textButtonWidth);
373     m_textButtonWidth->SetValue(wxT("-1"));
374     sizerButtonPos->Add(sizerRow, 0, wxALL | wxGROW, 5);
375 
376     sizerRow = CreateSizerWithTextAndLabel(_T("VSpacing:"),
377                                            ODComboPage_ButtonSpacing,
378                                            &m_textButtonSpacing);
379     m_textButtonSpacing->SetValue(wxT("0"));
380     sizerButtonPos->Add(sizerRow, 0, wxALL | wxGROW, 5);
381 
382     sizerRow = CreateSizerWithTextAndLabel(_T("Height:"),
383                                            ODComboPage_ButtonHeight,
384                                            &m_textButtonHeight);
385     m_textButtonHeight->SetValue(wxT("-1"));
386     sizerButtonPos->Add(sizerRow, 0, wxALL | wxGROW, 5);
387 
388     m_chkAlignbutleft = CreateCheckBoxAndAddToSizer(sizerButtonPos, _T("Align Left"));
389 
390     sizerLeft->Add(sizerButtonPos, 0, wxGROW | wxALIGN_CENTRE_HORIZONTAL | wxTOP, 2);
391 
392     // middle pane
393     wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY,
394         _T("&Change combobox contents"));
395     wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
396 
397     sizerRow = CreateSizerWithTextAndLabel(_T("Current selection"),
398                                            ODComboPage_CurText,
399                                            &text);
400     text->SetEditable(false);
401 
402     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
403 
404     sizerRow = CreateSizerWithTextAndLabel(_T("Insertion Point"),
405                                            ODComboPage_InsertionPointText,
406                                            &text);
407     text->SetEditable(false);
408 
409     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
410 
411     sizerRow = CreateSizerWithTextAndButton(ODComboPage_Insert,
412                                             _T("&Insert this string"),
413                                             ODComboPage_InsertText,
414                                             &m_textInsert);
415     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
416 
417     sizerRow = CreateSizerWithTextAndButton(ODComboPage_Add,
418                                             _T("&Add this string"),
419                                             ODComboPage_AddText,
420                                             &m_textAdd);
421     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
422 
423     btn = new wxButton(this, ODComboPage_AddSeveral, _T("&Append a few strings"));
424     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
425 
426     btn = new wxButton(this, ODComboPage_AddMany, _T("Append &many strings"));
427     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
428 
429     sizerRow = CreateSizerWithTextAndButton(ODComboPage_Change,
430                                             _T("C&hange current"),
431                                             ODComboPage_ChangeText,
432                                             &m_textChange);
433     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
434 
435     sizerRow = CreateSizerWithTextAndButton(ODComboPage_Delete,
436                                             _T("&Delete this item"),
437                                             ODComboPage_DeleteText,
438                                             &m_textDelete);
439     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
440 
441     btn = new wxButton(this, ODComboPage_DeleteSel, _T("Delete &selection"));
442     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
443 
444     btn = new wxButton(this, ODComboPage_Clear, _T("&Clear"));
445     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
446 
447     // right pane
448     wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL);
449     m_combobox = new DemoODComboBox();
450     m_combobox->Create(this, ODComboPage_Combo, wxEmptyString,
451                        wxDefaultPosition, wxDefaultSize,
452                        0, NULL,
453                        0);
454     sizerRight->Add(m_combobox, 0, wxGROW | wxALL, 5);
455     sizerRight->SetMinSize(150, 0);
456     m_sizerCombo = sizerRight; // save it to modify it later
457 
458     // the 3 panes panes compose the window
459     sizerTop->Add(sizerLeft, 4, wxGROW | (wxALL & ~wxLEFT), 10);
460     sizerTop->Add(sizerMiddle, 5, wxGROW | wxALL, 10);
461     sizerTop->Add(sizerRight, 4, wxGROW | (wxALL & ~wxRIGHT), 10);
462 
463     // final initializations
464     Reset();
465 
466     SetSizer(sizerTop);
467 }
468 
469 // ----------------------------------------------------------------------------
470 // operations
471 // ----------------------------------------------------------------------------
472 
Reset()473 void ODComboboxWidgetsPage::Reset()
474 {
475     m_chkSort->SetValue(false);
476     m_chkReadonly->SetValue(false);
477     m_chkDclickcycles->SetValue(false);
478     m_chkDclickcycles->Enable(false);
479     m_chkBitmapbutton->SetValue(false);
480     m_chkStdbutton->SetValue(false);
481     m_chkStdbutton->Enable(false);
482 }
483 
CreateCombo()484 void ODComboboxWidgetsPage::CreateCombo()
485 {
486     int flags = ms_defaultFlags;
487 
488     if ( m_chkSort->GetValue() )
489         flags |= wxCB_SORT;
490     if ( m_chkReadonly->GetValue() )
491         flags |= wxCB_READONLY;
492     if ( m_chkDclickcycles->GetValue() )
493         flags |= wxODCB_DCLICK_CYCLES;
494 
495     wxArrayString items;
496     if ( m_combobox )
497     {
498         unsigned int count = m_combobox->GetCount();
499         for ( unsigned int n = 0; n < count; n++ )
500         {
501             items.Add(m_combobox->GetString(n));
502         }
503 
504         m_sizerCombo->Detach( m_combobox );
505         delete m_combobox;
506     }
507 
508     m_combobox = new DemoODComboBox();
509     m_combobox->Create(this, ODComboPage_Combo, wxEmptyString,
510                        wxDefaultPosition, wxDefaultSize,
511                        0, NULL,
512                        flags);
513 
514     unsigned int count = items.GetCount();
515     for ( unsigned int n = 0; n < count; n++ )
516     {
517         m_combobox->Append(items[n]);
518     }
519 
520     // Update from controls that edit popup position etc.
521 
522     wxUpdateUIEvent tempEvt;
523     OnTextPopupWidth(tempEvt);
524     OnTextPopupHeight(tempEvt);
525     GetButtonPosition();
526 
527     m_combobox->SetPopupAnchor( m_chkAlignpopupright->GetValue() ? wxRIGHT : wxLEFT );
528 
529     if ( m_chkBitmapbutton->GetValue() )
530     {
531         wxBitmap bmpNormal = CreateBitmap(wxColour(0,0,255));
532         wxBitmap bmpPressed = CreateBitmap(wxColour(0,0,128));
533         wxBitmap bmpHover = CreateBitmap(wxColour(128,128,255));
534         m_combobox->SetButtonBitmaps(bmpNormal,m_chkStdbutton->GetValue(),bmpPressed,bmpHover);
535     }
536 
537     m_sizerCombo->Add(m_combobox, 0, wxGROW | wxALL, 5);
538     m_sizerCombo->Layout();
539 }
540 
541 // ----------------------------------------------------------------------------
542 // event handlers
543 // ----------------------------------------------------------------------------
544 
OnButtonReset(wxCommandEvent & WXUNUSED (event))545 void ODComboboxWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
546 {
547     Reset();
548 
549     CreateCombo();
550 }
551 
OnButtonChange(wxCommandEvent & WXUNUSED (event))552 void ODComboboxWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event))
553 {
554     int sel = m_combobox->GetSelection();
555     if ( sel != wxNOT_FOUND )
556     {
557 #ifndef __WXGTK__
558         m_combobox->SetString(sel, m_textChange->GetValue());
559 #else
560         wxLogMessage(_T("Not implemented in wxGTK"));
561 #endif
562     }
563 }
564 
OnButtonDelete(wxCommandEvent & WXUNUSED (event))565 void ODComboboxWidgetsPage::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
566 {
567     unsigned long n;
568     if ( !m_textDelete->GetValue().ToULong(&n) ||
569             (n >= m_combobox->GetCount()) )
570     {
571         return;
572     }
573 
574     m_combobox->Delete(n);
575 }
576 
OnButtonDeleteSel(wxCommandEvent & WXUNUSED (event))577 void ODComboboxWidgetsPage::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
578 {
579     int sel = m_combobox->GetSelection();
580     if ( sel != wxNOT_FOUND )
581     {
582         m_combobox->Delete(sel);
583     }
584 }
585 
OnButtonClear(wxCommandEvent & WXUNUSED (event))586 void ODComboboxWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
587 {
588     m_combobox->Clear();
589 }
590 
OnButtonInsert(wxCommandEvent & WXUNUSED (event))591 void ODComboboxWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
592 {
593     static unsigned int s_item = 0;
594 
595     wxString s = m_textInsert->GetValue();
596     if ( !m_textInsert->IsModified() )
597     {
598         // update the default string
599         m_textInsert->SetValue(wxString::Format(_T("test item %u"), ++s_item));
600     }
601 
602     if (m_combobox->GetSelection() >= 0)
603         m_combobox->Insert(s, m_combobox->GetSelection());
604 }
605 
OnButtonAdd(wxCommandEvent & WXUNUSED (event))606 void ODComboboxWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
607 {
608     static unsigned int s_item = 0;
609 
610     wxString s = m_textAdd->GetValue();
611     if ( !m_textAdd->IsModified() )
612     {
613         // update the default string
614         m_textAdd->SetValue(wxString::Format(_T("test item %u"), ++s_item));
615     }
616 
617     m_combobox->Append(s);
618 }
619 
OnButtonAddMany(wxCommandEvent & WXUNUSED (event))620 void ODComboboxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
621 {
622     // "many" means 1000 here
623     for ( unsigned int n = 0; n < 1000; n++ )
624     {
625         m_combobox->Append(wxString::Format(_T("item #%u"), n));
626     }
627 }
628 
OnButtonAddSeveral(wxCommandEvent & WXUNUSED (event))629 void ODComboboxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
630 {
631     m_combobox->Append(_T("First"));
632     m_combobox->Append(_T("another one"));
633     m_combobox->Append(_T("and the last (very very very very very very very very very very long) one"));
634 }
635 
OnTextPopupWidth(wxCommandEvent & WXUNUSED (event))636 void ODComboboxWidgetsPage::OnTextPopupWidth(wxCommandEvent& WXUNUSED(event))
637 {
638     long l = 0;
639 
640     m_textPopupMinWidth->GetValue().ToLong(&l);
641 
642     if (m_combobox && l > 0)
643     {
644         m_combobox->SetPopupMinWidth(l);
645     }
646 }
647 
OnTextPopupHeight(wxCommandEvent & WXUNUSED (event))648 void ODComboboxWidgetsPage::OnTextPopupHeight(wxCommandEvent& WXUNUSED(event))
649 {
650     long l = 0;
651 
652     m_textPopupHeight->GetValue().ToLong(&l);
653 
654     if (m_combobox && l > 0)
655     {
656         m_combobox->SetPopupMaxHeight(l);
657     }
658 }
659 
GetButtonPosition()660 void ODComboboxWidgetsPage::GetButtonPosition()
661 {
662     long w = -1;
663     long h = -1;
664     long spacing = 0;
665 
666     m_textButtonWidth->GetValue().ToLong(&w);
667     m_textButtonSpacing->GetValue().ToLong(&spacing);
668     m_textButtonHeight->GetValue().ToLong(&h);
669     int align = m_chkAlignbutleft->GetValue() ?
670                 wxLEFT : wxRIGHT;
671 
672     m_combobox->SetButtonPosition(w,h,align,spacing);
673 }
674 
OnTextButtonAll(wxCommandEvent & WXUNUSED (event))675 void ODComboboxWidgetsPage::OnTextButtonAll(wxCommandEvent& WXUNUSED(event))
676 {
677     if (m_combobox)
678     {
679         if ( m_chkBitmapbutton->GetValue() )
680             CreateCombo();
681         else
682             GetButtonPosition();
683     }
684 }
685 
OnUpdateUICurText(wxUpdateUIEvent & event)686 void ODComboboxWidgetsPage::OnUpdateUICurText(wxUpdateUIEvent& event)
687 {
688     if (m_combobox)
689         event.SetText( wxString::Format(_T("%d"), m_combobox->GetSelection()) );
690 }
691 
OnUpdateUIInsertionPointText(wxUpdateUIEvent & event)692 void ODComboboxWidgetsPage::OnUpdateUIInsertionPointText(wxUpdateUIEvent& event)
693 {
694     if (m_combobox)
695         event.SetText( wxString::Format(_T("%ld"), m_combobox->GetInsertionPoint()) );
696 }
697 
OnUpdateUIResetButton(wxUpdateUIEvent & event)698 void ODComboboxWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
699 {
700     if (m_combobox)
701         event.Enable( m_chkSort->GetValue() || m_chkReadonly->GetValue() ||
702                       m_chkBitmapbutton->GetValue() );
703 }
704 
OnUpdateUIInsert(wxUpdateUIEvent & event)705 void ODComboboxWidgetsPage::OnUpdateUIInsert(wxUpdateUIEvent& event)
706 {
707     if (m_combobox)
708     {
709         bool enable = !(m_combobox->GetWindowStyle() & wxCB_SORT) &&
710                        (m_combobox->GetSelection() >= 0);
711 
712         event.Enable(enable);
713     }
714 }
715 
OnUpdateUIDeleteButton(wxUpdateUIEvent & event)716 void ODComboboxWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
717 {
718     if (m_combobox)
719     {
720       unsigned long n;
721       event.Enable(m_textDelete->GetValue().ToULong(&n) &&
722         (n < (unsigned)m_combobox->GetCount()));
723     }
724 }
725 
OnUpdateUIDeleteSelButton(wxUpdateUIEvent & event)726 void ODComboboxWidgetsPage::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event)
727 {
728     if (m_combobox)
729         event.Enable(m_combobox->GetSelection() != wxNOT_FOUND);
730 }
731 
OnUpdateUIClearButton(wxUpdateUIEvent & event)732 void ODComboboxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
733 {
734     if (m_combobox)
735         event.Enable(m_combobox->GetCount() != 0);
736 }
737 
OnUpdateUIAddSeveral(wxUpdateUIEvent & event)738 void ODComboboxWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
739 {
740     if (m_combobox)
741         event.Enable(!(m_combobox->GetWindowStyle() & wxCB_SORT));
742 }
743 
OnComboText(wxCommandEvent & event)744 void ODComboboxWidgetsPage::OnComboText(wxCommandEvent& event)
745 {
746     if (!m_combobox)
747         return;
748 
749     wxString s = event.GetString();
750 
751     wxASSERT_MSG( s == m_combobox->GetValue(),
752                   _T("event and combobox values should be the same") );
753 
754     if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER)
755         wxLogMessage(_T("OwnerDrawnCombobox enter pressed (now '%s')"), s.c_str());
756     else
757         wxLogMessage(_T("OwnerDrawnCombobox text changed (now '%s')"), s.c_str());
758 }
759 
OnComboBox(wxCommandEvent & event)760 void ODComboboxWidgetsPage::OnComboBox(wxCommandEvent& event)
761 {
762     long sel = event.GetInt();
763     m_textDelete->SetValue(wxString::Format(_T("%ld"), sel));
764 
765     wxLogMessage(_T("OwnerDrawnCombobox item %ld selected"), sel);
766 
767     wxLogMessage(_T("OwnerDrawnCombobox GetValue(): %s"), m_combobox->GetValue().c_str() );
768 }
769 
OnCheckOrRadioBox(wxCommandEvent & event)770 void ODComboboxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event)
771 {
772     wxObject* ctrl = event.GetEventObject();
773 
774     // Double-click cycles only applies to read-only combobox
775     if ( ctrl == (wxObject*) m_chkReadonly )
776     {
777         m_chkDclickcycles->Enable( m_chkReadonly->GetValue() );
778     }
779     else if ( ctrl == (wxObject*) m_chkBitmapbutton )
780     {
781         m_chkStdbutton->Enable( m_chkBitmapbutton->GetValue() );
782     }
783     else if ( ctrl == (wxObject*) m_chkAlignbutleft )
784     {
785         wxUpdateUIEvent tempEvt;
786         OnTextButtonAll(tempEvt);
787     }
788 
789     CreateCombo();
790 }
791 
CreateBitmap(const wxColour & colour)792 wxBitmap ODComboboxWidgetsPage::CreateBitmap(const wxColour& colour)
793 {
794     int ch = m_combobox->GetClientSize().y - 1;
795     int h0 = ch - 5;
796 
797     long w = -1;
798     long h = -1;
799 
800     m_textButtonWidth->GetValue().ToLong(&w);
801     m_textButtonHeight->GetValue().ToLong(&h);
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 #endif //wxUSE_ODCOMBOBOX
835