From c765e6fb9df639bb4e65a8824ed13a42f457027b Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= <vslavik@fastmail.fm> Date: Mon, 5 Apr 2010 17:19:04 +0000 Subject: [PATCH] Fix text input and completion in wxComboCtrl and wxOwnerDrawnComboBox. Both wxEVT_KEY_DOWN and wxEVT_CHAR must be handled and only the latter used for completion (or any characters input). Don't make incorrect assumptions about wxEVT_CHAR keycodes either, it's only the Unicode character and printability that matter. Otherwise, completion in readonly controls wouldn't work correctly for e.g. numbers on numpad or non-ASCII characters. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63864 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/combo.h | 7 ++++- include/wx/odcombo.h | 6 ++-- src/common/combocmn.cpp | 28 ++++++++++++++++++ src/generic/odcombo.cpp | 65 +++++++++++++++++++++++++---------------- 4 files changed, 78 insertions(+), 28 deletions(-) diff --git a/include/wx/combo.h b/include/wx/combo.h index 2cdb81102a..0c31d0bb50 100644 --- a/include/wx/combo.h +++ b/include/wx/combo.h @@ -523,6 +523,7 @@ protected: void OnTextCtrlEvent(wxCommandEvent& event); void OnSysColourChanged(wxSysColourChangedEvent& event); void OnKeyEvent(wxKeyEvent& event); + void OnCharEvent(wxKeyEvent& event); // Set customization flags (directs how wxComboCtrlBase helpers behave) void Customize( wxUint32 flags ) { m_iFlags |= flags; } @@ -726,10 +727,14 @@ public: // Default implementation draws value as string. virtual void PaintComboControl( wxDC& dc, const wxRect& rect ); - // Receives key events from the parent wxComboCtrl. + // Receives wxEVT_KEY_DOWN key events from the parent wxComboCtrl. // Events not handled should be skipped, as usual. virtual void OnComboKeyEvent( wxKeyEvent& event ); + // Receives wxEVT_CHAR key events from the parent wxComboCtrl. + // Events not handled should be skipped, as usual. + virtual void OnComboCharEvent( wxKeyEvent& event ); + // Implement if you need to support special action when user // double-clicks on the parent wxComboCtrl. virtual void OnComboDoubleClick(); diff --git a/include/wx/odcombo.h b/include/wx/odcombo.h index 1c803aa5a2..614663e72c 100644 --- a/include/wx/odcombo.h +++ b/include/wx/odcombo.h @@ -89,6 +89,7 @@ public: virtual wxSize GetAdjustedSize( int minWidth, int prefHeight, int maxHeight ); virtual void PaintComboControl( wxDC& dc, const wxRect& rect ); virtual void OnComboKeyEvent( wxKeyEvent& event ); + virtual void OnComboCharEvent( wxKeyEvent& event ); virtual void OnComboDoubleClick(); virtual bool LazyCreate(); @@ -117,8 +118,8 @@ public: protected: - // Called by OnComboDoubleClick and OnComboKeyEvent - bool HandleKey( int keycode, bool saturate, wxChar unicode = 0 ); + // Called by OnComboDoubleClick and OnCombo{Key,Char}Event + bool HandleKey( int keycode, bool saturate, wxChar keychar = 0 ); // sends combobox select event from the parent combo control void SendComboBoxEvent( int selection ); @@ -164,6 +165,7 @@ protected: void OnMouseMove(wxMouseEvent& event); void OnMouseWheel(wxMouseEvent& event); void OnKey(wxKeyEvent& event); + void OnChar(wxKeyEvent& event); void OnLeftClick(wxMouseEvent& event); // Return the widest item width (recalculating it if necessary) diff --git a/src/common/combocmn.cpp b/src/common/combocmn.cpp index 05eeb0eb31..f037eb9dbd 100644 --- a/src/common/combocmn.cpp +++ b/src/common/combocmn.cpp @@ -465,6 +465,7 @@ private: BEGIN_EVENT_TABLE(wxComboPopupWindowEvtHandler, wxEvtHandler) EVT_KEY_DOWN(wxComboPopupWindowEvtHandler::OnKeyEvent) EVT_KEY_UP(wxComboPopupWindowEvtHandler::OnKeyEvent) + EVT_CHAR(wxComboPopupWindowEvtHandler::OnKeyEvent) #if USES_GENERICTLW EVT_ACTIVATE(wxComboPopupWindowEvtHandler::OnActivate) #endif @@ -552,6 +553,11 @@ void wxComboPopup::OnComboKeyEvent( wxKeyEvent& event ) event.Skip(); } +void wxComboPopup::OnComboCharEvent( wxKeyEvent& event ) +{ + event.Skip(); +} + void wxComboPopup::OnComboDoubleClick() { } @@ -780,6 +786,7 @@ BEGIN_EVENT_TABLE(wxComboCtrlBase, wxControl) EVT_IDLE(wxComboCtrlBase::OnIdleEvent) //EVT_BUTTON(wxID_ANY,wxComboCtrlBase::OnButtonClickEvent) EVT_KEY_DOWN(wxComboCtrlBase::OnKeyEvent) + EVT_CHAR(wxComboCtrlBase::OnCharEvent) EVT_TEXT_ENTER(wxID_ANY,wxComboCtrlBase::OnTextCtrlEvent) EVT_SYS_COLOUR_CHANGED(wxComboCtrlBase::OnSysColourChanged) END_EVENT_TABLE() @@ -1830,6 +1837,27 @@ void wxComboCtrlBase::OnKeyEvent(wxKeyEvent& event) } } +void wxComboCtrlBase::OnCharEvent(wxKeyEvent& event) +{ + if ( IsPopupShown() ) + { + // pass it to the popped up control + GetPopupControl()->GetControl()->GetEventHandler()->ProcessEvent(event); + } + else // no popup + { + wxComboPopup* popupInterface = GetPopupControl(); + if ( popupInterface ) + { + popupInterface->OnComboCharEvent(event); + } + else + { + event.Skip(); + } + } +} + void wxComboCtrlBase::OnFocusEvent( wxFocusEvent& event ) { if ( event.GetEventType() == wxEVT_SET_FOCUS ) diff --git a/src/generic/odcombo.cpp b/src/generic/odcombo.cpp index 9dec19bc50..5176871ddd 100644 --- a/src/generic/odcombo.cpp +++ b/src/generic/odcombo.cpp @@ -54,6 +54,7 @@ BEGIN_EVENT_TABLE(wxVListBoxComboPopup, wxVListBox) EVT_MOTION(wxVListBoxComboPopup::OnMouseMove) EVT_KEY_DOWN(wxVListBoxComboPopup::OnKey) + EVT_CHAR(wxVListBoxComboPopup::OnChar) EVT_LEFT_UP(wxVListBoxComboPopup::OnLeftClick) END_EVENT_TABLE() @@ -244,7 +245,7 @@ void wxVListBoxComboPopup::SendComboBoxEvent( int selection ) } // returns true if key was consumed -bool wxVListBoxComboPopup::HandleKey( int keycode, bool saturate, wxChar unicode ) +bool wxVListBoxComboPopup::HandleKey( int keycode, bool saturate, wxChar keychar ) { const int itemCount = GetCount(); @@ -256,19 +257,12 @@ bool wxVListBoxComboPopup::HandleKey( int keycode, bool saturate, wxChar unicode int value = m_value; int comboStyle = m_combo->GetWindowStyle(); - // this is the character equivalent of the code - wxChar keychar = 0; - if ( keycode < WXK_START ) + if ( keychar > 0 ) { - if ( unicode > 0 ) - { - if ( wxIsprint(unicode) ) - keychar = unicode; - } - else if ( wxIsprint(keycode) ) - { - keychar = (wxChar) keycode; - } + // we have character equivalent of the keycode; filter out these that + // are not printable characters + if ( !wxIsprint(keychar) ) + keychar = 0; } if ( keycode == WXK_DOWN || keycode == WXK_NUMPAD_DOWN || keycode == WXK_RIGHT ) @@ -395,13 +389,21 @@ void wxVListBoxComboPopup::OnComboDoubleClick() void wxVListBoxComboPopup::OnComboKeyEvent( wxKeyEvent& event ) { // Saturated key movement on - if ( !HandleKey(event.GetKeyCode(),true, + if ( !HandleKey(event.GetKeyCode(), true) ) + event.Skip(); +} + +void wxVListBoxComboPopup::OnComboCharEvent( wxKeyEvent& event ) +{ + // unlike in OnComboKeyEvent, wxEVT_CHAR contains meaningful + // printable character information, so pass it #if wxUSE_UNICODE - event.GetUnicodeKey() + const wxChar charcode = event.GetUnicodeKey(); #else - 0 + const wxChar charcode = (wxChar)event.GetKeyCode(); #endif - ) ) + + if ( !HandleKey(event.GetKeyCode(), true, charcode) ) event.Skip(); } @@ -466,18 +468,31 @@ void wxVListBoxComboPopup::OnKey(wxKeyEvent& event) } else { - int comboStyle = m_combo->GetWindowStyle(); - int keycode = event.GetKeyCode(); - // Process partial completion key codes here, but not the arrow keys as the base class will do that for us - if ((comboStyle & wxCB_READONLY) && - (keycode >= WXK_SPACE) && (keycode <=255) && (keycode != WXK_DELETE) && wxIsprint(keycode)) + // completion is handled in OnChar() below + event.Skip(); + } +} + +void wxVListBoxComboPopup::OnChar(wxKeyEvent& event) +{ + if ( m_combo->GetWindowStyle() & wxCB_READONLY ) + { + // Process partial completion key codes here, but not the arrow keys as + // the base class will do that for us +#if wxUSE_UNICODE + const wxChar charcode = event.GetUnicodeKey(); +#else + const wxChar charcode = (wxChar)event.GetKeyCode(); +#endif + if ( wxIsprint(charcode) ) { - OnComboKeyEvent(event); + OnComboCharEvent(event); SetSelection(m_value); // ensure the highlight bar moves + return; // don't skip the event } - else - event.Skip(); } + + event.Skip(); } void wxVListBoxComboPopup::Insert( const wxString& item, int pos ) -- 2.47.2