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