X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7dc234d633e255de95f17d62d513d0525efad1af..4c75209fc3cd4b7f9e2698949e73b64341b56aef:/src/common/combocmn.cpp?ds=sidebyside diff --git a/src/common/combocmn.cpp b/src/common/combocmn.cpp index 07ab83c061..fbad327842 100644 --- a/src/common/combocmn.cpp +++ b/src/common/combocmn.cpp @@ -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 ( @@ -427,8 +427,7 @@ void wxComboPopup::Dismiss() // ---------------------------------------------------------------------------- // -// This is pushed to the event handler queue of either combo box -// or its textctrl (latter if not readonly combo). +// This is pushed to the event handler queue of the child textctrl. // class wxComboBoxExtraInputHandler : public wxEvtHandler { @@ -459,56 +458,16 @@ END_EVENT_TABLE() void wxComboBoxExtraInputHandler::OnKey(wxKeyEvent& event) { - int keycode = event.GetKeyCode(); + // Let the wxComboCtrl event handler have a go first. + wxComboCtrlBase* combo = m_combo; + wxObject* prevObj = event.GetEventObject(); - if ( keycode == WXK_TAB && !m_combo->IsPopupShown() ) - { - wxNavigationKeyEvent evt; - evt.SetFlags(wxNavigationKeyEvent::FromTab| - (!event.ShiftDown()?wxNavigationKeyEvent::IsForward: - wxNavigationKeyEvent::IsBackward)); - evt.SetEventObject(m_combo); - m_combo->GetParent()->GetEventHandler()->AddPendingEvent(evt); - return; - } - - if ( m_combo->IsPopupShown() ) - { - // pass it to the popped up control - m_combo->GetPopupControl()->GetControl()->AddPendingEvent(event); - } - else // no popup - { - int comboStyle = m_combo->GetWindowStyle(); - wxComboPopup* popupInterface = m_combo->GetPopupControl(); - - if ( !popupInterface ) - { - event.Skip(); - return; - } + event.SetId(combo->GetId()); + event.SetEventObject(combo); + combo->GetEventHandler()->ProcessEvent(event); - if ( (comboStyle & wxCB_READONLY) || - ( keycode != WXK_RIGHT && keycode != WXK_LEFT ) - ) - { - // Alternate keys: UP and DOWN show the popup instead of cycling - if ( (comboStyle & wxCC_ALT_KEYS) ) - { - if ( keycode == WXK_UP || keycode == WXK_DOWN ) - { - m_combo->OnButtonClick(); - return; - } - else - event.Skip(); - } - else - popupInterface->OnComboKeyEvent(event); - } - else - event.Skip(); - } + event.SetId(((wxWindow*)prevObj)->GetId()); + event.SetEventObject(prevObj); } void wxComboBoxExtraInputHandler::OnFocus(wxFocusEvent& event) @@ -523,17 +482,15 @@ void wxComboBoxExtraInputHandler::OnFocus(wxFocusEvent& event) m_combo->SetSelection(-1,-1); } - if ( event.GetId() != m_combo->GetId() ) - { - // Add textctrl set focus events as combo set focus events - // NOTE: Simply changing the event and skipping didn't seem - // to do the trick. - wxFocusEvent evt2(wxEVT_SET_FOCUS,m_combo->GetId()); - evt2.SetEventObject(m_combo); - m_combo->GetEventHandler()->ProcessEvent(evt2); - } - else - event.Skip(); + // Send focus indication to parent. + // NB: This is needed for cases where the textctrl gets focus + // instead of its parent. While this may trigger multiple + // wxEVT_SET_FOCUSes (since m_text->SetFocus is called + // from combo's focus event handler), they should be quite + // harmless. + wxFocusEvent evt2(wxEVT_SET_FOCUS,m_combo->GetId()); + evt2.SetEventObject(m_combo); + m_combo->GetEventHandler()->ProcessEvent(evt2); event.Skip(); } @@ -645,6 +602,7 @@ BEGIN_EVENT_TABLE(wxComboCtrlBase, wxControl) EVT_SET_FOCUS(wxComboCtrlBase::OnFocusEvent) EVT_KILL_FOCUS(wxComboCtrlBase::OnFocusEvent) //EVT_BUTTON(wxID_ANY,wxComboCtrlBase::OnButtonClickEvent) + EVT_KEY_DOWN(wxComboCtrlBase::OnKeyEvent) EVT_TEXT_ENTER(wxID_ANY,wxComboCtrlBase::OnTextCtrlEvent) EVT_SYS_COLOUR_CHANGED(wxComboCtrlBase::OnSysColourChanged) END_EVENT_TABLE() @@ -664,7 +622,6 @@ void wxComboCtrlBase::Init() m_text = (wxTextCtrl*) NULL; m_popupInterface = (wxComboPopup*) NULL; - m_extraEvtHandler = (wxEvtHandler*) NULL; m_popupExtraHandler = (wxEvtHandler*) NULL; m_textEvtHandler = (wxEvtHandler*) NULL; @@ -730,17 +687,13 @@ bool wxComboCtrlBase::Create(wxWindow *parent, return true; } -void wxComboCtrlBase::InstallInputHandlers( bool alsoTextCtrl ) +void wxComboCtrlBase::InstallInputHandlers() { - if ( m_text && alsoTextCtrl ) + if ( m_text ) { m_textEvtHandler = new wxComboBoxExtraInputHandler(this); m_text->PushEventHandler(m_textEvtHandler); } - - wxComboBoxExtraInputHandler* inputHandler = new wxComboBoxExtraInputHandler(this); - PushEventHandler(inputHandler); - m_extraEvtHandler = inputHandler; } void @@ -786,13 +739,10 @@ wxComboCtrlBase::~wxComboCtrlBase() DestroyPopup(); - RemoveEventHandler(m_extraEvtHandler); - if ( m_text ) m_text->RemoveEventHandler(m_textEvtHandler); delete m_textEvtHandler; - delete m_extraEvtHandler; } @@ -1392,6 +1342,15 @@ bool wxComboCtrlBase::PreprocessMouseEvent( wxMouseEvent& event, wxLongLong t = ::wxGetLocalTimeMillis(); int evtType = event.GetEventType(); +#if !USE_TRANSIENT_POPUP + if ( m_isPopupShown && + ( evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_RIGHT_DOWN ) ) + { + HidePopup(); + return true; + } +#endif + // // Generate our own double-clicks // (to allow on-focus dc-event on double-clicks instead of triple-clicks) @@ -1488,23 +1447,68 @@ void wxComboCtrlBase::HandleNormalMouseEvent( wxMouseEvent& event ) event.Skip(); } -void wxComboCtrlBase::OnFocusEvent( wxFocusEvent& ) +void wxComboCtrlBase::OnKeyEvent(wxKeyEvent& event) { - // 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 ( IsPopupShown() ) + { + // pass it to the popped up control + GetPopupControl()->GetControl()->AddPendingEvent(event); + } + else // no popup + { + int keycode = event.GetKeyCode(); - if ( m_text ) + if ( keycode == WXK_TAB ) + { + wxNavigationKeyEvent evt; + evt.SetFlags(wxNavigationKeyEvent::FromTab| + (!event.ShiftDown() ? wxNavigationKeyEvent::IsForward + : wxNavigationKeyEvent::IsBackward)); + evt.SetEventObject(this); + GetParent()->GetEventHandler()->AddPendingEvent(evt); + return; + } + + if ( IsKeyPopupToggle(event) ) + { + OnButtonClick(); + return; + } + + int comboStyle = GetWindowStyle(); + wxComboPopup* popupInterface = GetPopupControl(); + + if ( !popupInterface ) + { + event.Skip(); + return; + } + + if ( (comboStyle & wxCB_READONLY) || + (keycode != WXK_RIGHT && keycode != WXK_LEFT) ) + { + popupInterface->OnComboKeyEvent(event); + } + else + event.Skip(); + } +} + +void wxComboCtrlBase::OnFocusEvent( wxFocusEvent& event ) +{ + if ( event.GetEventType() == wxEVT_SET_FOCUS ) { - m_text->SetFocus(); + // 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(); } - else - // no need to check for m_widthCustomPaint - that - // area never gets special handling when selected - // (in writable mode, that is) - Refresh(); + + Refresh(); } void wxComboCtrlBase::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) @@ -1546,13 +1550,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 )