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