X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/30be036c6d4990f8aa21af5b86abdc0852e686a0..a4cc2d0919408f8248516f768032944a55824a12:/src/common/combocmn.cpp diff --git a/src/common/combocmn.cpp b/src/common/combocmn.cpp index bcfbb96bfd..77c67f137e 100644 --- a/src/common/combocmn.cpp +++ b/src/common/combocmn.cpp @@ -62,6 +62,7 @@ // native controls work on it like normal. #define POPUPWIN_IS_PERFECT 0 // Same, but for non-transient popup window. #define TEXTCTRL_TEXT_CENTERED 0 // 1 if text in textctrl is vertically centered +#define FOCUS_RING 0 // No focus ring on wxMSW //#undef wxUSE_POPUPWIN //#define wxUSE_POPUPWIN 0 @@ -79,6 +80,7 @@ // native controls work on it like normal. #define POPUPWIN_IS_PERFECT 1 // Same, but for non-transient popup window. #define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered +#define FOCUS_RING 0 // No focus ring on wxGTK #elif defined(__WXMAC__) @@ -87,6 +89,12 @@ // native controls work on it like normal. #define POPUPWIN_IS_PERFECT 0 // Same, but for non-transient popup window. #define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered +#define FOCUS_RING 3 // Reserve room for the textctrl's focus ring to display + +#undef DEFAULT_DROPBUTTON_WIDTH +#define DEFAULT_DROPBUTTON_WIDTH 22 +#undef COMBO_MARGIN +#define COMBO_MARGIN FOCUS_RING #else @@ -95,6 +103,7 @@ // native controls work on it like normal. #define POPUPWIN_IS_PERFECT 0 // Same, but for non-transient popup window. #define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered +#define FOCUS_RING 0 #endif @@ -707,6 +716,7 @@ BEGIN_EVENT_TABLE(wxComboCtrlBase, wxControl) EVT_SIZE(wxComboCtrlBase::OnSizeEvent) EVT_SET_FOCUS(wxComboCtrlBase::OnFocusEvent) EVT_KILL_FOCUS(wxComboCtrlBase::OnFocusEvent) + EVT_IDLE(wxComboCtrlBase::OnIdleEvent) //EVT_BUTTON(wxID_ANY,wxComboCtrlBase::OnButtonClickEvent) EVT_KEY_DOWN(wxComboCtrlBase::OnKeyEvent) EVT_TEXT_ENTER(wxID_ANY,wxComboCtrlBase::OnTextCtrlEvent) @@ -732,6 +742,8 @@ void wxComboCtrlBase::Init() m_toplevEvtHandler = (wxEvtHandler*) NULL; #endif + m_mainCtrlWnd = this; + m_heightPopup = -1; m_widthMinPopup = -1; m_anchorSide = 0; @@ -752,6 +764,8 @@ void wxComboCtrlBase::Init() m_absIndent = -1; m_iFlags = 0; m_timeCanAcceptClick = 0; + + m_resetFocus = false; } bool wxComboCtrlBase::Create(wxWindow *parent, @@ -826,17 +840,19 @@ wxComboCtrlBase::CreateTextCtrl(int style, const wxValidator& validator) m_ignoreEvtText = 0; m_text = new wxTextCtrl(this, wxID_ANY, m_valueString, - wxDefaultPosition, wxDefaultSize, + wxDefaultPosition, wxSize(10,-1), style, validator); - - // This is required for some platforms (GTK+ atleast) - m_text->SetSizeHints(2,4); } } void wxComboCtrlBase::OnThemeChange() { - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + // Leave the default bg on the Mac so the area used by the focus ring will + // be the correct colour and themed brush. Instead we'll use + // wxSYS_COLOUR_WINDOW in the EVT_PAINT handler as needed. +#ifndef __WXMAC__ + SetOwnBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#endif } wxComboCtrlBase::~wxComboCtrlBase() @@ -964,14 +980,14 @@ void wxComboCtrlBase::CalculateAreas( int btnWidth ) m_btnSize.y = butHeight; m_btnArea.x = ( m_btnSide==wxRIGHT ? sz.x - butAreaWid - btnBorder : btnBorder ); - m_btnArea.y = btnBorder; + m_btnArea.y = btnBorder + FOCUS_RING; m_btnArea.width = butAreaWid; - m_btnArea.height = sz.y - (btnBorder*2); + m_btnArea.height = sz.y - ((btnBorder+FOCUS_RING)*2); - m_tcArea.x = ( m_btnSide==wxRIGHT ? 0 : butAreaWid ) + customBorder; - m_tcArea.y = customBorder; - m_tcArea.width = sz.x - butAreaWid - (customBorder*2); - m_tcArea.height = sz.y - (customBorder*2); + m_tcArea.x = ( m_btnSide==wxRIGHT ? 0 : butAreaWid ) + customBorder + FOCUS_RING; + m_tcArea.y = customBorder + FOCUS_RING; + m_tcArea.width = sz.x - butAreaWid - (customBorder*2) - (FOCUS_RING*2); + m_tcArea.height = sz.y - ((customBorder+FOCUS_RING)*2); /* if ( m_text ) @@ -988,9 +1004,9 @@ void wxComboCtrlBase::PositionTextCtrl( int textCtrlXAdjust, int textCtrlYAdjust return; wxSize sz = GetClientSize(); - int customBorder = m_widthCustomBorder; #if !TEXTCTRL_TEXT_CENTERED + int customBorder = m_widthCustomBorder; if ( (m_text->GetWindowStyleFlag() & wxBORDER_MASK) == wxNO_BORDER ) { // Centre textctrl @@ -1017,16 +1033,16 @@ void wxComboCtrlBase::PositionTextCtrl( int textCtrlXAdjust, int textCtrlYAdjust } } else -#else +#else // TEXTCTRL_TEXT_CENTERED wxUnusedVar(textCtrlXAdjust); wxUnusedVar(textCtrlYAdjust); -#endif +#endif // !TEXTCTRL_TEXT_CENTERED/TEXTCTRL_TEXT_CENTERED { // If it has border, have textctrl will the entire text field. m_text->SetSize( m_tcArea.x + m_widthCustomPaint, - customBorder, - sz.x - m_btnArea.width - m_widthCustomPaint - customBorder, - sz.y-(customBorder*2) ); + m_tcArea.y, + m_tcArea.width - m_widthCustomPaint, + m_tcArea.height ); } } @@ -1070,9 +1086,27 @@ wxSize wxComboCtrlBase::DoGetBestSize() const fhei += 1; #endif - wxSize ret(sizeText.x + COMBO_MARGIN + DEFAULT_DROPBUTTON_WIDTH, - fhei); +#ifdef __WXMAC__ + // these are the numbers from the HIG: + switch ( m_windowVariant ) + { + case wxWINDOW_VARIANT_NORMAL: + default : + fhei = 22; + break; + case wxWINDOW_VARIANT_SMALL: + fhei = 19; + break; + case wxWINDOW_VARIANT_MINI: + fhei = 15; + break; + } +#endif + + fhei += 2 * FOCUS_RING; + int width = sizeText.x + FOCUS_RING + COMBO_MARGIN + DEFAULT_DROPBUTTON_WIDTH; + wxSize ret(width, fhei); CacheBestSize(ret); return ret; } @@ -1150,6 +1184,26 @@ void wxComboCtrlBase::DoSetToolTip(wxToolTip *tooltip) } #endif // wxUSE_TOOLTIPS +#if wxUSE_VALIDATORS +void wxComboCtrlBase::SetValidator(const wxValidator& validator) +{ + wxTextCtrl* textCtrl = GetTextCtrl(); + + if ( textCtrl ) + textCtrl->SetValidator( validator ); +} + +wxValidator* wxComboCtrlBase::GetValidator() +{ + wxTextCtrl* textCtrl = GetTextCtrl(); + + if ( textCtrl ) + return textCtrl->GetValidator(); + + return wxControl::GetValidator(); +} +#endif // wxUSE_VALIDATORS + // ---------------------------------------------------------------------------- // painting // ---------------------------------------------------------------------------- @@ -1213,13 +1267,21 @@ void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags else { dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) ); +#ifndef __WXMAC__ // see note in OnThemeChange bgCol = GetBackgroundColour(); +#else + bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); +#endif } } else { dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT) ); +#ifndef __WXMAC__ // see note in OnThemeChange bgCol = GetBackgroundColour(); +#else + bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); +#endif } dc.SetBrush( bgCol ); @@ -1239,7 +1301,7 @@ void wxComboCtrlBase::PrepareBackground( wxDC&, const wxRect&, int ) const } #endif -void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, bool paintBg ) +void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, int paintBg ) { int drawState = m_btnState; @@ -1537,11 +1599,15 @@ void wxComboCtrlBase::OnKeyEvent(wxKeyEvent& event) if ( keycode == WXK_TAB ) { wxNavigationKeyEvent evt; + + wxWindow* mainCtrl = GetMainWindowOfCompositeControl(); + evt.SetFlags(wxNavigationKeyEvent::FromTab| (!event.ShiftDown() ? wxNavigationKeyEvent::IsForward : wxNavigationKeyEvent::IsBackward)); - evt.SetEventObject(this); - GetParent()->GetEventHandler()->AddPendingEvent(evt); + evt.SetEventObject(mainCtrl); + evt.SetCurrentFocus(mainCtrl); + mainCtrl->GetParent()->GetEventHandler()->AddPendingEvent(evt); return; } @@ -1574,13 +1640,29 @@ void wxComboCtrlBase::OnFocusEvent( wxFocusEvent& event ) { if ( event.GetEventType() == wxEVT_SET_FOCUS ) { - if ( m_text && m_text != ::wxWindow::FindFocus() ) - m_text->SetFocus(); + wxWindow* tc = GetTextCtrl(); + if ( tc && tc != DoFindFocus() ) +#ifdef __WXMAC__ + m_resetFocus = true; +#else + tc->SetFocus(); +#endif } Refresh(); } +void wxComboCtrlBase::OnIdleEvent( wxIdleEvent& WXUNUSED(event) ) +{ + if ( m_resetFocus ) + { + m_resetFocus = false; + wxWindow* tc = GetTextCtrl(); + if ( tc ) + tc->SetFocus(); + } +} + void wxComboCtrlBase::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) { OnThemeChange(); @@ -1769,6 +1851,8 @@ void wxComboCtrlBase::ShowPopup() popup = m_popup; } + winPopup->Enable(); + wxASSERT( !m_popup || m_popup == popup ); // Consistency check. wxSize adjustedSize = m_popupInterface->GetAdjustedSize(widthPopup, @@ -1915,20 +1999,13 @@ void wxComboCtrlBase::OnPopupDismiss() if ( IsPopupWindowState(Hidden) ) return; - // NB: Focus setting is really funny, atleast on wxMSW. First of all, - // we need to have SetFocus at the end. Otherwise wxTextCtrl may - // freeze until focus goes somewhere else. Second, wxTreeCtrl as - // popup, when dismissing, "steals" focus back to itself unless - // SetFocus is called also here, exactly before m_popupWinState - // is set to false. Which is truly weird since SetFocus is just - // wxWindowMSW method and does not call event handler or anything like - // that (ie. does not care about m_popupWinState). - - SetFocus(); - - // This should preferably be set before focus. + // This must be set before focus - otherwise there will be recursive + // OnPopupDismisses. m_popupWinState = Hidden; + //SetFocus(); + m_winPopup->Disable(); + // Inform popup control itself m_popupInterface->OnDismiss();