X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b445b6a76eddacd5bab45c71f640dad672d83393..91885f468ae257fd295ae46750e91719646fa381:/src/common/combocmn.cpp diff --git a/src/common/combocmn.cpp b/src/common/combocmn.cpp index b5cd42e424..deeff9218a 100644 --- a/src/common/combocmn.cpp +++ b/src/common/combocmn.cpp @@ -53,7 +53,7 @@ #define BMP_BUTTON_MARGIN 4 -#define DEFAULT_POPUP_HEIGHT 200 +#define DEFAULT_POPUP_HEIGHT 400 #define DEFAULT_TEXT_INDENT 3 @@ -140,7 +140,7 @@ class wxComboFrameEventHandler : public wxEvtHandler { public: wxComboFrameEventHandler( wxComboCtrlBase* pCb ); - ~wxComboFrameEventHandler(); + virtual ~wxComboFrameEventHandler(); void OnPopup(); @@ -191,7 +191,7 @@ void wxComboFrameEventHandler::OnIdle( wxIdleEvent& event ) { wxWindow* winFocused = ::wxWindow::FindFocus(); - wxWindow* popup = m_combo->GetPopupControl(); + wxWindow* popup = m_combo->GetPopupControl()->GetControl(); wxWindow* winpopup = m_combo->GetPopupWindow(); if ( @@ -386,7 +386,7 @@ void wxComboPopup::DefaultPaintComboControl( wxComboCtrlBase* combo, { if ( combo->GetWindowStyle() & wxCB_READONLY ) // ie. no textctrl { - combo->DrawFocusBackground(dc,rect,0); + combo->PrepareBackground(dc,rect,0); dc.DrawText( combo->GetValue(), rect.x + combo->GetTextIndent(), @@ -438,7 +438,7 @@ public: { m_combo = combo; } - ~wxComboBoxExtraInputHandler() { } + virtual ~wxComboBoxExtraInputHandler() { } void OnKey(wxKeyEvent& event); void OnFocus(wxFocusEvent& event); @@ -510,7 +510,7 @@ public: m_combo = combo; m_beenInside = false; } - ~wxComboPopupExtraEventHandler() { } + virtual ~wxComboPopupExtraEventHandler() { } void OnMouseEvent( wxMouseEvent& event ); @@ -638,6 +638,7 @@ void wxComboCtrlBase::Init() m_btnState = 0; m_btnWidDefault = 0; m_blankButtonBg = false; + m_ignoreEvtText = 0; m_btnWid = m_btnHei = -1; m_btnSide = wxRIGHT; m_btnSpacingX = 0; @@ -646,7 +647,6 @@ void wxComboCtrlBase::Init() m_extRight = 0; m_absIndent = -1; m_iFlags = 0; - m_downReceived = false; m_timeCanAcceptClick = 0; } @@ -710,6 +710,14 @@ wxComboCtrlBase::CreateTextCtrl(int style, const wxValidator& validator) if ( HasFlag(wxTE_PROCESS_ENTER) ) style |= wxTE_PROCESS_ENTER; + // Ignore EVT_TEXT generated by the constructor (but only + // if the event redirector already exists) + // NB: This must be " = 1" instead of "++"; + if ( m_textEvtHandler ) + m_ignoreEvtText = 1; + else + m_ignoreEvtText = 0; + m_text = new wxTextCtrl(this, wxID_ANY, m_valueString, wxDefaultPosition, wxDefaultSize, style, validator); @@ -1036,8 +1044,9 @@ void wxComboCtrlBase::DoSetToolTip(wxToolTip *tooltip) // painting // ---------------------------------------------------------------------------- -// draw focus background on area in a way typical on platform -void wxComboCtrlBase::DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags ) const +#if (!defined(__WXMSW__)) || defined(__WXUNIVERSAL__) +// prepare combo box background on area in a way typical on platform +void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const { wxSize sz = GetClientSize(); bool isEnabled; @@ -1106,7 +1115,19 @@ void wxComboCtrlBase::DrawFocusBackground( wxDC& dc, const wxRect& rect, int fla dc.SetBrush( bgCol ); dc.SetPen( bgCol ); dc.DrawRectangle( selRect ); + + // Don't clip exactly to the selection rectangle so we can draw + // to the non-selected area in front of it. + wxRect clipRect(rect.x,rect.y, + (selRect.x+selRect.width)-rect.x,rect.height); + dc.SetClippingRegion(clipRect); +} +#else +// Save the library size a bit for platforms that re-implement this. +void wxComboCtrlBase::PrepareBackground( wxDC&, const wxRect&, int ) const +{ } +#endif void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, bool paintBg ) { @@ -1236,6 +1257,15 @@ wxBitmap& wxComboCtrlBase::GetBufferBitmap( const wxSize& sz ) const void wxComboCtrlBase::OnTextCtrlEvent(wxCommandEvent& event) { + if ( event.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED ) + { + if ( m_ignoreEvtText > 0 ) + { + m_ignoreEvtText--; + return; + } + } + // Change event id, object and string before relaying it forward event.SetId(GetId()); wxString s = event.GetString(); @@ -1333,56 +1363,21 @@ bool wxComboCtrlBase::HandleButtonMouseEvent( wxMouseEvent& event, return true; } -// Conversion to double-clicks and some basic filtering // returns true if event was consumed or filtered -//bool wxComboCtrlBase::PreprocessMouseEvent( wxMouseEvent& event, bool isOnButtonArea ) bool wxComboCtrlBase::PreprocessMouseEvent( wxMouseEvent& event, - int flags ) + int WXUNUSED(flags) ) { wxLongLong t = ::wxGetLocalTimeMillis(); int evtType = event.GetEventType(); - // - // Generate our own double-clicks - // (to allow on-focus dc-event on double-clicks instead of triple-clicks) - if ( (m_windowStyle & wxCC_SPECIAL_DCLICK) && - !m_isPopupShown && - //!(handlerFlags & wxCC_MF_ON_BUTTON) ) - !(flags & wxCC_MF_ON_BUTTON) ) +#if !USE_TRANSIENT_POPUP + if ( m_isPopupShown && + ( evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_RIGHT_DOWN ) ) { - if ( evtType == wxEVT_LEFT_DOWN ) - { - // Set value to avoid up-events without corresponding downs - m_downReceived = true; - } - else if ( evtType == wxEVT_LEFT_DCLICK ) - { - // We'll make our own double-clicks - //evtType = 0; - event.SetEventType(0); - return true; - } - else if ( evtType == wxEVT_LEFT_UP ) - { - if ( m_downReceived || m_timeLastMouseUp == 1 ) - { - wxLongLong timeFromLastUp = (t-m_timeLastMouseUp); - - if ( timeFromLastUp < DOUBLE_CLICK_CONVERSION_TRESHOLD ) - { - //type = wxEVT_LEFT_DCLICK; - event.SetEventType(wxEVT_LEFT_DCLICK); - m_timeLastMouseUp = 1; - } - else - { - m_timeLastMouseUp = t; - } - - //m_downReceived = false; - } - } + HidePopup(); + return true; } +#endif // Filter out clicks on button immediately after popup dismiss (Windows like behaviour) if ( evtType == wxEVT_LEFT_DOWN && t < m_timeCanAcceptClick ) @@ -1489,12 +1484,6 @@ void wxComboCtrlBase::OnFocusEvent( wxFocusEvent& event ) { if ( event.GetEventType() == wxEVT_SET_FOCUS ) { - // First click is the first part of double-click - // Some platforms don't generate down-less mouse up-event - // (Windows does, GTK+2 doesn't), so that's why we have - // to do this. - m_timeLastMouseUp = ::wxGetLocalTimeMillis(); - if ( m_text && m_text != ::wxWindow::FindFocus() ) m_text->SetFocus(); } @@ -1541,13 +1530,13 @@ void wxComboCtrlBase::CreatePopup() // Destroy popup window and the child control void wxComboCtrlBase::DestroyPopup() { + HidePopup(); + if ( m_popup ) m_popup->RemoveEventHandler(m_popupExtraHandler); delete m_popupExtraHandler; - HidePopup(); - delete m_popupInterface; if ( m_winPopup ) @@ -1803,7 +1792,7 @@ void wxComboCtrlBase::OnPopupDismiss() // If cursor not on dropdown button, then clear its state // (technically not required by all ports, but do it for all just in case) - if ( !m_btnArea.Inside(ScreenToClient(::wxGetMousePosition())) ) + if ( !m_btnArea.Contains(ScreenToClient(::wxGetMousePosition())) ) m_btnState = 0; // Return parent's tab traversal flag. @@ -1953,10 +1942,13 @@ wxString wxComboCtrlBase::GetValue() const return m_valueString; } -void wxComboCtrlBase::SetValue(const wxString& value) +void wxComboCtrlBase::SetValueWithEvent(const wxString& value, bool withEvent) { if ( m_text ) { + if ( !withEvent ) + m_ignoreEvtText++; + m_text->SetValue(value); if ( !(m_iFlags & wxCC_NO_TEXT_AUTO_SELECT) ) m_text->SelectAll(); @@ -1974,6 +1966,11 @@ void wxComboCtrlBase::SetValue(const wxString& value) } } +void wxComboCtrlBase::SetValue(const wxString& value) +{ + SetValueWithEvent(value, false); +} + // In this SetValue variant wxComboPopup::SetStringValue is not called void wxComboCtrlBase::SetText(const wxString& value) { @@ -1983,6 +1980,12 @@ void wxComboCtrlBase::SetText(const wxString& value) m_valueString = value; + if ( m_text ) + { + m_ignoreEvtText++; + m_text->SetValue( value ); + } + Refresh(); }