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