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