]> git.saurik.com Git - wxWidgets.git/blob - src/univ/combobox.cpp
Smooth Aqua buttons in wxTreeCtrl.
[wxWidgets.git] / src / univ / combobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: univ/combobox.cpp
3 // Purpose: wxComboControl and wxComboBox implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 15.12.00
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 /*
13 TODO:
14
15 +1. typing in the text should select the string in listbox
16 +2. scrollbars in listbox are unusable
17 +3. the initially selected item is not selected
18 ?4. kbd interface (what does GTK do?)
19 5. there is still autoscrolling without scrollbars - but is it bad?
20 */
21
22 // ============================================================================
23 // declarations
24 // ============================================================================
25
26 // ----------------------------------------------------------------------------
27 // headers
28 // ----------------------------------------------------------------------------
29
30 #ifdef __GNUG__
31 #pragma implementation "univcombobox.h"
32 #endif
33
34 #include "wx/wxprec.h"
35
36 #ifdef __BORLANDC__
37 #pragma hdrstop
38 #endif
39
40 #if wxUSE_COMBOBOX
41
42 #ifndef WX_PRECOMP
43 #include "wx/log.h"
44
45 #include "wx/button.h"
46 #include "wx/combobox.h"
47 #include "wx/listbox.h"
48 #include "wx/textctrl.h"
49 #include "wx/bmpbuttn.h"
50
51 #include "wx/validate.h"
52 #endif
53
54 #include "wx/popupwin.h"
55
56 #include "wx/univ/renderer.h"
57 #include "wx/univ/inphand.h"
58 #include "wx/univ/theme.h"
59
60 /*
61 The keyboard event flow:
62
63 1. they always come to the text ctrl
64 2. it forwards the ones it doesn't process to the wxComboControl
65 3. which passes them to the popup window if it is popped up
66 */
67
68 // ----------------------------------------------------------------------------
69 // wxComboButton is just a normal button except that it sends commands to the
70 // combobox and not its parent
71 // ----------------------------------------------------------------------------
72
73 class wxComboButton : public wxBitmapButton
74 {
75 public:
76 wxComboButton(wxComboControl *combo)
77 : wxBitmapButton(combo->GetParent(), -1, wxNullBitmap,
78 wxDefaultPosition, wxDefaultSize,
79 wxBORDER_NONE | wxBU_EXACTFIT)
80 {
81 m_combo = combo;
82
83 wxBitmap bmpNormal, bmpFocus, bmpPressed, bmpDisabled;
84
85 GetRenderer()->GetComboBitmaps(&bmpNormal,
86 &bmpFocus,
87 &bmpPressed,
88 &bmpDisabled);
89
90 SetBitmapLabel(bmpNormal);
91 SetBitmapFocus(bmpFocus.Ok() ? bmpFocus : bmpNormal);
92 SetBitmapSelected(bmpPressed.Ok() ? bmpPressed : bmpNormal);
93 SetBitmapDisabled(bmpDisabled.Ok() ? bmpDisabled : bmpNormal);
94
95 SetBestSize(wxDefaultSize);
96 }
97
98 protected:
99 void OnButton(wxCommandEvent& event) { m_combo->ShowPopup(); }
100
101 virtual wxSize DoGetBestClientSize() const
102 {
103 const wxBitmap& bmp = GetBitmapLabel();
104
105 return wxSize(bmp.GetWidth(), bmp.GetHeight());
106
107 }
108
109 private:
110 wxComboControl *m_combo;
111
112 DECLARE_EVENT_TABLE()
113 };
114
115 // ----------------------------------------------------------------------------
116 // wxComboListBox is a listbox modified to be used as a popup window in a
117 // combobox
118 // ----------------------------------------------------------------------------
119
120 class wxComboListBox : public wxListBox, public wxComboPopup
121 {
122 public:
123 // ctor and dtor
124 wxComboListBox(wxComboControl *combo, int style = 0);
125 virtual ~wxComboListBox();
126
127 // implement wxComboPopup methods
128 virtual bool SetSelection(const wxString& value);
129 virtual wxControl *GetControl() { return this; }
130 virtual void OnShow();
131
132 protected:
133 // we shouldn't return height too big from here
134 virtual wxSize DoGetBestClientSize() const;
135
136 // filter mouse move events happening outside the list box
137 void OnMouseMove(wxMouseEvent& event);
138
139 // called whenever the user selects or activates a listbox item
140 void OnSelect(wxCommandEvent& event);
141
142 // used to process wxUniv actions
143 bool PerformAction(const wxControlAction& action,
144 long numArg,
145 const wxString& strArg);
146
147 private:
148 DECLARE_EVENT_TABLE()
149 };
150
151 // ----------------------------------------------------------------------------
152 // wxComboTextCtrl is a simple text ctrl which forwards
153 // wxEVT_COMMAND_TEXT_UPDATED events and all key events to the combobox
154 // ----------------------------------------------------------------------------
155
156 class wxComboTextCtrl : public wxTextCtrl
157 {
158 public:
159 wxComboTextCtrl(wxComboControl *combo,
160 const wxString& value,
161 long style,
162 const wxValidator& validator);
163
164 protected:
165 void OnKey(wxKeyEvent& event);
166 void OnText(wxCommandEvent& event);
167
168 private:
169 wxComboControl *m_combo;
170
171 DECLARE_EVENT_TABLE()
172 };
173
174 // ----------------------------------------------------------------------------
175 // event tables and such
176 // ----------------------------------------------------------------------------
177
178 BEGIN_EVENT_TABLE(wxComboButton, wxButton)
179 EVT_BUTTON(-1, wxComboButton::OnButton)
180 END_EVENT_TABLE()
181
182 BEGIN_EVENT_TABLE(wxComboListBox, wxListBox)
183 EVT_LISTBOX(-1, wxComboListBox::OnSelect)
184 EVT_LISTBOX_DCLICK(-1, wxComboListBox::OnSelect)
185 EVT_MOTION(wxComboListBox::OnMouseMove)
186 END_EVENT_TABLE()
187
188 BEGIN_EVENT_TABLE(wxComboControl, wxControl)
189 EVT_KEY_DOWN(wxComboControl::OnKey)
190 EVT_KEY_UP(wxComboControl::OnKey)
191 END_EVENT_TABLE()
192
193 BEGIN_EVENT_TABLE(wxComboTextCtrl, wxTextCtrl)
194 EVT_KEY_DOWN(wxComboTextCtrl::OnKey)
195 EVT_KEY_UP(wxComboTextCtrl::OnKey)
196 EVT_TEXT(-1, wxComboTextCtrl::OnText)
197 END_EVENT_TABLE()
198
199 IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl);
200
201 // ============================================================================
202 // implementation
203 // ============================================================================
204
205 // ----------------------------------------------------------------------------
206 // wxComboControl creation
207 // ----------------------------------------------------------------------------
208
209 void wxComboControl::Init()
210 {
211 m_popup = (wxComboPopup *)NULL;
212 m_winPopup = (wxPopupComboWindow *)NULL;
213 m_isPopupShown = FALSE;
214 m_btn = NULL;
215 m_text = NULL;
216 }
217
218 bool wxComboControl::Create(wxWindow *parent,
219 wxWindowID id,
220 const wxString& value,
221 const wxPoint& pos,
222 const wxSize& size,
223 long style,
224 const wxValidator& validator,
225 const wxString& name)
226 {
227 // first create our own window, i.e. the one which will contain all
228 // subcontrols
229 style &= ~wxBORDER_NONE;
230 style |= wxBORDER_SUNKEN;
231 if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
232 return FALSE;
233
234 // create the text control and the button as our siblings (*not* children),
235 // don't care about size/position here - they will be set in DoMoveWindow()
236 m_btn = new wxComboButton(this);
237 m_text = new wxComboTextCtrl(this,
238 value,
239 style & wxCB_READONLY ? wxTE_READONLY : 0,
240 validator);
241
242 // for compatibility with the other ports, the height specified is the
243 // combined height of the combobox itself and the popup
244 if ( size.y == -1 )
245 {
246 // ok, use default height for popup too
247 m_heightPopup = -1;
248 }
249 else
250 {
251 m_heightPopup = size.y - DoGetBestSize().y;
252 }
253
254 SetBestSize(size);
255 Move(pos);
256
257 // create the popup window immediately here to allow creating the controls
258 // with parent == GetPopupWindow() from the derived class ctor
259 m_winPopup = new wxPopupComboWindow(this);
260
261 // have to disable this window to avoid interfering it with message
262 // processing to the text and the button... but pretend it is enabled to
263 // make IsEnabled() return TRUE
264 wxControl::Enable(FALSE); // don't use non virtual Disable() here!
265 m_isEnabled = TRUE;
266
267 CreateInputHandler(wxINP_HANDLER_COMBOBOX);
268
269 return TRUE;
270 }
271
272 wxComboControl::~wxComboControl()
273 {
274 // as the button and the text control are the parent's children and not
275 // ours, we have to delete them manually - they are not deleted
276 // automatically by wxWindows when we're deleted
277 delete m_btn;
278 delete m_text;
279
280 delete m_winPopup;
281 }
282
283 // ----------------------------------------------------------------------------
284 // geometry stuff
285 // ----------------------------------------------------------------------------
286
287 void wxComboControl::DoSetSize(int x, int y,
288 int width, int height,
289 int sizeFlags)
290 {
291 // combo height is always fixed
292 wxControl::DoSetSize(x, y, width, DoGetBestSize().y, sizeFlags);
293 }
294
295 wxSize wxComboControl::DoGetBestClientSize() const
296 {
297 wxSize sizeBtn = m_btn->GetBestSize(),
298 sizeText = m_text->GetBestSize();
299
300 return wxSize(sizeBtn.x + sizeText.x, wxMax(sizeBtn.y, sizeText.y));
301 }
302
303 void wxComboControl::DoMoveWindow(int x, int y, int width, int height)
304 {
305 wxControl::DoMoveWindow(x, y, width, height);
306
307 // position the subcontrols inside the client area
308 wxRect rectBorders = GetRenderer()->GetBorderDimensions(GetBorder());
309 x += rectBorders.x;
310 y += rectBorders.y;
311 width -= rectBorders.x + rectBorders.width;
312 height -= rectBorders.y + rectBorders.height;
313
314 wxSize sizeBtn = m_btn->GetBestSize();
315
316 wxCoord wText = width - sizeBtn.x;
317 m_text->SetSize(x, y, wText, height);
318 m_btn->SetSize(x + wText, y, sizeBtn.x, height);
319 }
320
321 // ----------------------------------------------------------------------------
322 // operations
323 // ----------------------------------------------------------------------------
324
325 bool wxComboControl::Enable(bool enable)
326 {
327 if ( !wxControl::Enable(enable) )
328 return FALSE;
329
330 m_btn->Enable(enable);
331 m_text->Enable(enable);
332
333 return TRUE;
334 }
335
336 bool wxComboControl::Show(bool show)
337 {
338 if ( !wxControl::Show(show) )
339 return FALSE;
340
341 if (m_btn)
342 m_btn->Show(show);
343
344 if (m_text)
345 m_text->Show(show);
346
347 return TRUE;
348 }
349
350 // ----------------------------------------------------------------------------
351 // popup window handling
352 // ----------------------------------------------------------------------------
353
354 void wxComboControl::SetPopupControl(wxComboPopup *popup)
355 {
356 m_popup = popup;
357 }
358
359 void wxComboControl::ShowPopup()
360 {
361 wxCHECK_RET( m_popup, _T("no popup to show in wxComboControl") );
362 wxCHECK_RET( !IsPopupShown(), _T("popup window already shown") );
363
364 wxControl *control = m_popup->GetControl();
365
366 // size and position the popup window correctly
367 m_winPopup->SetSize(GetSize().x,
368 m_heightPopup == -1 ? control->GetBestSize().y
369 : m_heightPopup);
370 wxSize sizePopup = m_winPopup->GetClientSize();
371 control->SetSize(0, 0, sizePopup.x, sizePopup.y);
372
373 // some controls don't accept the size we give then: e.g. a listbox may
374 // require more space to show its last row
375 wxSize sizeReal = control->GetSize();
376 if ( sizeReal != sizePopup )
377 {
378 m_winPopup->SetClientSize(sizeReal);
379 }
380
381 m_winPopup->PositionNearCombo();
382
383 // show it
384 m_winPopup->Popup(m_text);
385 m_text->SelectAll();
386 m_popup->SetSelection(m_text->GetValue());
387
388 m_isPopupShown = TRUE;
389 }
390
391 void wxComboControl::HidePopup()
392 {
393 wxCHECK_RET( m_popup, _T("no popup to hide in wxComboControl") );
394 wxCHECK_RET( IsPopupShown(), _T("popup window not shown") );
395
396 m_winPopup->Dismiss();
397
398 m_isPopupShown = FALSE;
399 }
400
401 void wxComboControl::OnSelect(const wxString& value)
402 {
403 m_text->SetValue(value);
404 m_text->SelectAll();
405
406 OnDismiss();
407 }
408
409 void wxComboControl::OnDismiss()
410 {
411 HidePopup();
412 m_text->SetFocus();
413 }
414
415 // ----------------------------------------------------------------------------
416 // wxComboTextCtrl
417 // ----------------------------------------------------------------------------
418
419 wxComboTextCtrl::wxComboTextCtrl(wxComboControl *combo,
420 const wxString& value,
421 long style,
422 const wxValidator& validator)
423 : wxTextCtrl(combo->GetParent(), -1, value,
424 wxDefaultPosition, wxDefaultSize,
425 wxBORDER_NONE | style,
426 validator)
427 {
428 m_combo = combo;
429 }
430
431 void wxComboTextCtrl::OnText(wxCommandEvent& event)
432 {
433 if ( m_combo->IsPopupShown() )
434 {
435 m_combo->GetPopupControl()->SetSelection(GetValue());
436 }
437
438 // we need to make a copy of the event to have the correct originating
439 // object and id
440 wxCommandEvent event2 = event;
441 event2.SetEventObject(m_combo);
442 event2.SetId(m_combo->GetId());
443
444 // there is a small incompatibility with wxMSW here: the combobox gets the
445 // event before the text control in our case which corresponds to SMW
446 // CBN_EDITUPDATE notification and not CBN_EDITCHANGE one wxMSW currently
447 // uses
448 //
449 // if this is really a problem, we can play games with the event handlers
450 // to circumvent this
451 (void)m_combo->ProcessEvent(event2);
452
453 event.Skip();
454 }
455
456 // pass the keys we don't process to the combo first
457 void wxComboTextCtrl::OnKey(wxKeyEvent& event)
458 {
459 switch ( event.GetKeyCode() )
460 {
461 case WXK_RETURN:
462 // the popup control gets it first but only if it is shown
463 if ( !m_combo->IsPopupShown() )
464 break;
465 //else: fall through
466
467 case WXK_UP:
468 case WXK_DOWN:
469 case WXK_ESCAPE:
470 case WXK_PAGEDOWN:
471 case WXK_PAGEUP:
472 case WXK_PRIOR:
473 case WXK_NEXT:
474 (void)m_combo->ProcessEvent(event);
475 return;
476 }
477
478 event.Skip();
479 }
480
481 // ----------------------------------------------------------------------------
482 // wxComboListBox
483 // ----------------------------------------------------------------------------
484
485 wxComboListBox::wxComboListBox(wxComboControl *combo, int style)
486 : wxListBox(combo->GetPopupWindow(), -1,
487 wxDefaultPosition, wxDefaultSize,
488 0, NULL,
489 wxBORDER_SIMPLE | wxLB_INT_HEIGHT | style),
490 wxComboPopup(combo)
491 {
492 // we don't react to the mouse events outside the window at all
493 StopAutoScrolling();
494 }
495
496 wxComboListBox::~wxComboListBox()
497 {
498 }
499
500 bool wxComboListBox::SetSelection(const wxString& value)
501 {
502 // FindItem() would just find the current item for an empty string (it
503 // always matches), but we want to show the first one in such case
504 if ( value.empty() )
505 {
506 if ( GetCount() )
507 {
508 wxListBox::SetSelection(0);
509 }
510 //else: empty listbox - nothing to do
511 }
512 else if ( !FindItem(value) )
513 {
514 // no match att all
515 return FALSE;
516 }
517
518 return TRUE;
519 }
520
521 void wxComboListBox::OnSelect(wxCommandEvent& event)
522 {
523 // first update the combo and close the listbox
524 m_combo->OnSelect(event.GetString());
525
526 // next let the user code have the event
527
528 // all fields are already filled by the listbox, just change the event
529 // type and send it to the combo
530 wxCommandEvent event2 = event;
531 event2.SetEventType(wxEVT_COMMAND_COMBOBOX_SELECTED);
532 event2.SetEventObject(m_combo);
533 event2.SetId(m_combo->GetId());
534 m_combo->ProcessEvent(event2);
535 }
536
537 void wxComboListBox::OnShow()
538 {
539 }
540
541 bool wxComboListBox::PerformAction(const wxControlAction& action,
542 long numArg,
543 const wxString& strArg)
544
545 {
546 if ( action == wxACTION_LISTBOX_FIND )
547 {
548 // we don't let the listbox handle this as instead of just using the
549 // single key presses, as usual, we use the text ctrl value as prefix
550 // and this is done by wxComboControl itself
551 return TRUE;
552 }
553
554 return wxListBox::PerformAction(action, numArg, strArg);
555 }
556
557 void wxComboListBox::OnMouseMove(wxMouseEvent& event)
558 {
559 // while a wxComboListBox is shown, it always has capture, so if it doesn't
560 // we're about to go away anyhow (normally this shouldn't happen at all,
561 // but I don't put assert here as it just might do on other platforms and
562 // it doesn't break anythign anyhow)
563 if ( this == wxWindow::GetCapture() )
564 {
565 if ( HitTest(event.GetPosition()) == wxHT_WINDOW_INSIDE )
566 {
567 event.Skip();
568 }
569 //else: popup shouldn't react to the mouse motions outside it, it only
570 // captures the mouse to be able to detect when it must be
571 // dismissed, so don't call Skip()
572 }
573 }
574
575 wxSize wxComboListBox::DoGetBestClientSize() const
576 {
577 // don't return size too big or we risk to not fit on the screen
578 wxSize size = wxListBox::DoGetBestClientSize();
579 wxCoord hChar = GetCharHeight();
580
581 int nLines = size.y / hChar;
582
583 // 10 is the same limit as used by wxMSW
584 if ( nLines > 10 )
585 {
586 size.y = 10*hChar;
587 }
588
589 return size;
590 }
591
592 // ----------------------------------------------------------------------------
593 // wxComboBox
594 // ----------------------------------------------------------------------------
595
596 void wxComboBox::Init()
597 {
598 m_lbox = (wxListBox *)NULL;
599 }
600
601 bool wxComboBox::Create(wxWindow *parent,
602 wxWindowID id,
603 const wxString& value,
604 const wxPoint& pos,
605 const wxSize& size,
606 int n,
607 const wxString *choices,
608 long style,
609 const wxValidator& validator,
610 const wxString& name)
611 {
612 if ( !wxComboControl::Create(parent, id, value, pos, size, style,
613 validator, name) )
614 {
615 return FALSE;
616 }
617
618 wxComboListBox *combolbox =
619 new wxComboListBox(this, style & wxCB_SORT ? wxLB_SORT : 0);
620 m_lbox = combolbox;
621 m_lbox->Set(n, choices);
622
623 SetPopupControl(combolbox);
624
625 return TRUE;
626 }
627
628 wxComboBox::~wxComboBox()
629 {
630 }
631
632 // ----------------------------------------------------------------------------
633 // wxComboBox methods forwarded to wxTextCtrl
634 // ----------------------------------------------------------------------------
635
636 wxString wxComboBox::GetValue() const
637 {
638 return GetText()->GetValue();
639 }
640
641 void wxComboBox::SetValue(const wxString& value)
642 {
643 GetText()->SetValue(value);
644 }
645
646 void wxComboBox::Copy()
647 {
648 GetText()->Copy();
649 }
650
651 void wxComboBox::Cut()
652 {
653 GetText()->Cut();
654 }
655
656 void wxComboBox::Paste()
657 {
658 GetText()->Paste();
659 }
660
661 void wxComboBox::SetInsertionPoint(long pos)
662 {
663 GetText()->SetInsertionPoint(pos);
664 }
665
666 void wxComboBox::SetInsertionPointEnd()
667 {
668 GetText()->SetInsertionPointEnd();
669 }
670
671 long wxComboBox::GetInsertionPoint() const
672 {
673 return GetText()->GetInsertionPoint();
674 }
675
676 long wxComboBox::GetLastPosition() const
677 {
678 return GetText()->GetLastPosition();
679 }
680
681 void wxComboBox::Replace(long from, long to, const wxString& value)
682 {
683 GetText()->Replace(from, to, value);
684 }
685
686 void wxComboBox::Remove(long from, long to)
687 {
688 GetText()->Remove(from, to);
689 }
690
691 void wxComboBox::SetSelection(long from, long to)
692 {
693 GetText()->SetSelection(from, to);
694 }
695
696 void wxComboBox::SetEditable(bool editable)
697 {
698 GetText()->SetEditable(editable);
699 }
700
701 // ----------------------------------------------------------------------------
702 // wxComboBox methods forwarded to wxListBox
703 // ----------------------------------------------------------------------------
704
705 void wxComboBox::Clear()
706 {
707 GetLBox()->Clear();
708 }
709
710 void wxComboBox::Delete(int n)
711 {
712 GetLBox()->Delete(n);
713 }
714
715 int wxComboBox::GetCount() const
716 {
717 return GetLBox()->GetCount();
718 }
719
720 wxString wxComboBox::GetString(int n) const
721 {
722 return GetLBox()->GetString(n);
723 }
724
725 void wxComboBox::SetString(int n, const wxString& s)
726 {
727 GetLBox()->SetString(n, s);
728 }
729
730 int wxComboBox::FindString(const wxString& s) const
731 {
732 return GetLBox()->FindString(s);
733 }
734
735 void wxComboBox::Select(int n)
736 {
737 wxCHECK_RET( (n >= 0) && (n < GetCount()), _T("invalid combobox index") );
738
739 GetLBox()->SetSelection(n);
740 GetText()->SetValue(GetLBox()->GetString(n));
741 }
742
743 int wxComboBox::GetSelection() const
744 {
745 // if the current value isn't one of the listbox strings, return -1
746 return FindString(GetText()->GetValue());
747 }
748
749 int wxComboBox::DoAppend(const wxString& item)
750 {
751 return GetLBox()->Append(item);
752 }
753
754 void wxComboBox::DoSetItemClientData(int n, void* clientData)
755 {
756 GetLBox()->SetClientData(n, clientData);
757 }
758
759 void *wxComboBox::DoGetItemClientData(int n) const
760 {
761 return GetLBox()->GetClientData(n);
762 }
763
764 void wxComboBox::DoSetItemClientObject(int n, wxClientData* clientData)
765 {
766 GetLBox()->SetClientObject(n, clientData);
767 }
768
769 wxClientData* wxComboBox::DoGetItemClientObject(int n) const
770 {
771 return GetLBox()->GetClientObject(n);
772 }
773
774 // ----------------------------------------------------------------------------
775 // input handling
776 // ----------------------------------------------------------------------------
777
778 void wxComboControl::OnKey(wxKeyEvent& event)
779 {
780 if ( m_isPopupShown )
781 {
782 // pass it to the popped up control
783 (void)m_popup->GetControl()->ProcessEvent(event);
784 }
785 else // no popup
786 {
787 event.Skip();
788 }
789 }
790
791 bool wxComboControl::PerformAction(const wxControlAction& action,
792 long numArg,
793 const wxString& strArg)
794 {
795 bool processed = FALSE;
796 if ( action == wxACTION_COMBOBOX_POPUP )
797 {
798 if ( !m_isPopupShown )
799 {
800 ShowPopup();
801
802 processed = TRUE;
803 }
804 }
805 else if ( action == wxACTION_COMBOBOX_DISMISS )
806 {
807 if ( m_isPopupShown )
808 {
809 HidePopup();
810
811 processed = TRUE;
812 }
813 }
814
815 if ( !processed )
816 {
817 // pass along
818 return wxControl::PerformAction(action, numArg, strArg);
819 }
820
821 return TRUE;
822 }
823
824 // ----------------------------------------------------------------------------
825 // wxStdComboBoxInputHandler
826 // ----------------------------------------------------------------------------
827
828 wxStdComboBoxInputHandler::wxStdComboBoxInputHandler(wxInputHandler *inphand)
829 : wxStdInputHandler(inphand)
830 {
831 }
832
833 bool wxStdComboBoxInputHandler::HandleKey(wxInputConsumer *consumer,
834 const wxKeyEvent& event,
835 bool pressed)
836 {
837 if ( pressed )
838 {
839 wxControlAction action;
840 switch ( event.GetKeyCode() )
841 {
842 case WXK_DOWN:
843 action = wxACTION_COMBOBOX_POPUP;
844 break;
845
846 case WXK_ESCAPE:
847 action = wxACTION_COMBOBOX_DISMISS;
848 break;
849 }
850
851 if ( !!action )
852 {
853 consumer->PerformAction(action);
854
855 return TRUE;
856 }
857 }
858
859 return wxStdInputHandler::HandleKey(consumer, event, pressed);
860 }
861
862 #endif // wxUSE_COMBOBOX