From dc8a1aa53d9c71820d683aefe7ea04d7e480f63b Mon Sep 17 00:00:00 2001 From: Alex Bligh Date: Thu, 13 Jul 2006 22:06:32 +0000 Subject: [PATCH] Apply patch 1520776, partial completion on wxOwnerDrawnComboBox git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40085 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/odcombo.h | 11 ++++- src/generic/odcombo.cpp | 91 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 4 deletions(-) diff --git a/include/wx/odcombo.h b/include/wx/odcombo.h index 451ab90e73..5dd14a08aa 100644 --- a/include/wx/odcombo.h +++ b/include/wx/odcombo.h @@ -110,7 +110,7 @@ public: protected: // Called by OnComboDoubleClick and OnComboKeyEvent - bool HandleKey( int keycode, bool saturate ); + bool HandleKey( int keycode, bool saturate, wxChar unicode = 0 ); // sends combobox select event from the parent combo control void SendComboBoxEvent( int selection ); @@ -163,6 +163,9 @@ protected: // Return the index of the widest item (recalculating it if necessary) int GetWidestItem() { CalcWidths(); return m_widestItem; } + // Stop partial completion (when some other event occurs) + void StopPartialCompletion(); + wxArrayString m_strings; wxArrayPtrVoid m_clientDatas; @@ -198,6 +201,12 @@ private: // Recalculate widths if they are dirty void CalcWidths(); + // Partial completion string + wxString m_partialCompletionString; + + // Partial completion timer + wxTimer m_partialCompletionTimer; + DECLARE_EVENT_TABLE() }; diff --git a/src/generic/odcombo.cpp b/src/generic/odcombo.cpp index f824fa3670..cfa07e2ed1 100644 --- a/src/generic/odcombo.cpp +++ b/src/generic/odcombo.cpp @@ -41,6 +41,8 @@ // implementation // ============================================================================ +// time in milliseconds before partial completion buffer drops +#define wxODCB_PARTIAL_COMPLETION_TIME 1000 // ---------------------------------------------------------------------------- // wxVListBoxComboPopup is a wxVListBox customized to act as a popup control @@ -65,6 +67,7 @@ void wxVListBoxComboPopup::Init() m_value = -1; m_itemHover = -1; m_clientDataItemsType = wxClientData_None; + m_partialCompletionString = wxEmptyString; } bool wxVListBoxComboPopup::Create(wxWindow* parent) @@ -183,6 +186,8 @@ void wxVListBoxComboPopup::OnDrawItem( wxDC& dc, const wxRect& rect, int item, i void wxVListBoxComboPopup::DismissWithEvent() { + StopPartialCompletion(); + int selection = wxVListBox::GetSelection(); Dismiss(); @@ -223,26 +228,78 @@ void wxVListBoxComboPopup::SendComboBoxEvent( int selection ) } // returns true if key was consumed -bool wxVListBoxComboPopup::HandleKey( int keycode, bool saturate ) +bool wxVListBoxComboPopup::HandleKey( int keycode, bool saturate, wxChar unicode ) { int value = m_value; int itemCount = GetCount(); + int comboStyle = m_combo->GetWindowStyle(); + + // this is the character equivalent of the code + wxChar keychar=0; + if ((keycode >= WXK_SPACE) && (keycode <=255) && (keycode != WXK_DELETE) && wxIsprint(keycode)) + { + keychar = keycode; + } + else if (unicode>0) + { + keychar = unicode; + } if ( keycode == WXK_DOWN || keycode == WXK_RIGHT ) { value++; + StopPartialCompletion(); } else if ( keycode == WXK_UP || keycode == WXK_LEFT ) { value--; + StopPartialCompletion(); } else if ( keycode == WXK_PAGEDOWN ) { value+=10; + StopPartialCompletion(); } else if ( keycode == WXK_PAGEUP ) { value-=10; + StopPartialCompletion(); + } + else if ( comboStyle && wxCB_READONLY ) + { + // Try partial completion + + // find the new partial completion string + if (m_partialCompletionTimer.IsRunning()) + m_partialCompletionString+=wxString(keychar); + else + m_partialCompletionString=wxString(keychar); + + // now search through the values to see if this is found + int found = -1; + unsigned int length=m_partialCompletionString.Length(); + int i; + for (i=0; i=length) && (! m_partialCompletionString.CmpNoCase(item.Left(length)))) + { + found=i; + break; + } + } + + if (found<0) + { + StopPartialCompletion(); + ::wxBell(); + return true; // to stop the first value being set + } + else + { + value=i; + m_partialCompletionTimer.Start(wxODCB_PARTIAL_COMPLETION_TIME, true); + } } else return false; @@ -277,6 +334,13 @@ bool wxVListBoxComboPopup::HandleKey( int keycode, bool saturate ) return true; } +// stop partial completion +void wxVListBoxComboPopup::StopPartialCompletion() +{ + m_partialCompletionString = wxEmptyString; + m_partialCompletionTimer.Stop(); +} + void wxVListBoxComboPopup::OnComboDoubleClick() { // Cycle on dclick (disable saturation to allow true cycling). @@ -289,7 +353,13 @@ void wxVListBoxComboPopup::OnComboDoubleClick() void wxVListBoxComboPopup::OnComboKeyEvent( wxKeyEvent& event ) { // Saturated key movement on - if ( !HandleKey(event.GetKeyCode(),true) ) + if ( !HandleKey(event.GetKeyCode(),true, +#if wxUSE_UNICODE + event.GetUnicodeKey() +#else + 0 +#endif + ) ) event.Skip(); } @@ -341,9 +411,24 @@ void wxVListBoxComboPopup::OnKey(wxKeyEvent& event) } // Hide popup if ESC is pressed else if ( event.GetKeyCode() == WXK_ESCAPE ) + { + StopPartialCompletion(); Dismiss(); + } else - event.Skip(); + { + 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)) + { + OnComboKeyEvent(event); + SetSelection(m_value); // ensure the highlight bar moves + } + else + event.Skip(); + } } void wxVListBoxComboPopup::Insert( const wxString& item, int pos ) -- 2.45.2