X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a340b80d8a692f5308d26c1c1b95fd689a1d7eb3..f5766910b6731eb03e82371416e9778203396ce7:/src/msw/combo.cpp diff --git a/src/msw/combo.cpp b/src/msw/combo.cpp index b006217757..762b82eadc 100644 --- a/src/msw/combo.cpp +++ b/src/msw/combo.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: combo.cpp -// Purpose: wxMSW wxComboControl +// Name: src/msw/combo.cpp +// Purpose: wxMSW wxComboCtrl // Author: Jaakko Salli // Modified by: // Created: Apr-30-2006 @@ -23,7 +23,7 @@ #pragma hdrstop #endif -#if wxUSE_COMBOCONTROL +#if wxUSE_COMBOCTRL #ifndef WX_PRECOMP #include "wx/log.h" @@ -76,19 +76,19 @@ // ============================================================================ -BEGIN_EVENT_TABLE(wxComboControl, wxComboControlBase) - EVT_PAINT(wxComboControl::OnPaintEvent) - EVT_MOUSE_EVENTS(wxComboControl::OnMouseEvent) +BEGIN_EVENT_TABLE(wxComboCtrl, wxComboCtrlBase) + EVT_PAINT(wxComboCtrl::OnPaintEvent) + EVT_MOUSE_EVENTS(wxComboCtrl::OnMouseEvent) END_EVENT_TABLE() -IMPLEMENT_DYNAMIC_CLASS(wxComboControl, wxComboControlBase) +IMPLEMENT_DYNAMIC_CLASS(wxComboCtrl, wxComboCtrlBase) -void wxComboControl::Init() +void wxComboCtrl::Init() { } -bool wxComboControl::Create(wxWindow *parent, +bool wxComboCtrl::Create(wxWindow *parent, wxWindowID id, const wxString& value, const wxPoint& pos, @@ -118,14 +118,14 @@ bool wxComboControl::Create(wxWindow *parent, } // create main window - if ( !wxComboControlBase::Create(parent, - id, - value, - wxDefaultPosition, - wxDefaultSize, - style | wxFULL_REPAINT_ON_RESIZE, - wxDefaultValidator, - name) ) + if ( !wxComboCtrlBase::Create(parent, + id, + value, + pos, + size, + style | wxFULL_REPAINT_ON_RESIZE, + wxDefaultValidator, + name) ) return false; if ( style & wxCC_STD_BUTTON ) @@ -135,22 +135,22 @@ bool wxComboControl::Create(wxWindow *parent, CreateTextCtrl( wxNO_BORDER, validator ); // Add keyboard input handlers for main control and textctrl - InstallInputHandlers( true ); + InstallInputHandlers(); // Prepare background for double-buffering SetBackgroundStyle( wxBG_STYLE_CUSTOM ); - // SetSize should be called last - SetSize(pos.x,pos.y,size.x,size.y); + // SetBestSize should be called last + SetBestSize(size); return true; } -wxComboControl::~wxComboControl() +wxComboCtrl::~wxComboCtrl() { } -void wxComboControl::OnThemeChange() +void wxComboCtrl::OnThemeChange() { wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive(); if ( theme ) @@ -170,7 +170,7 @@ void wxComboControl::OnThemeChange() } } -void wxComboControl::OnResize() +void wxComboCtrl::OnResize() { // // Recalculates button and textctrl areas @@ -239,9 +239,12 @@ static void wxMSWDrawFocusRect( wxDC& dc, const wxRect& rect ) } // draw focus background on area in a way typical on platform -void wxComboControl::DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags ) +void wxComboCtrl::PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const { wxUxThemeEngine* theme = (wxUxThemeEngine*) NULL; + + // Constructor only calls GetHWND() const, so it should be safe + // to cast "this" to const. wxUxThemeHandle hTheme(this, L"COMBOBOX"); //COLORREF cref; @@ -295,8 +298,14 @@ void wxComboControl::DrawFocusBackground( wxDC& dc, const wxRect& rect, int flag wxRect selRect(rect); selRect.y += focusSpacingY; selRect.height -= (focusSpacingY*2); - selRect.x += m_widthCustomPaint + focusSpacingX; - selRect.width -= m_widthCustomPaint + (focusSpacingX*2); + + int wcp = 0; + + if ( !(flags & wxCONTROL_ISSUBMENU) ) + wcp += m_widthCustomPaint; + + selRect.x += wcp + focusSpacingX; + selRect.width -= wcp + (focusSpacingX*2); if ( hTheme ) theme = wxUxThemeEngine::GetIfActive(); @@ -367,14 +376,19 @@ void wxComboControl::DrawFocusBackground( wxDC& dc, const wxRect& rect, int flag if ( drawDottedEdge ) wxMSWDrawFocusRect(dc,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-1,rect.height); + dc.SetClippingRegion(clipRect); } -void wxComboControl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) ) +void wxComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) ) { // TODO: Convert drawing in this function to Windows API Code wxSize sz = GetClientSize(); - wxBufferedPaintDC dc(this,GetBufferBitmap(sz)); + wxAutoBufferedPaintDC dc(this); const wxRect& rectb = m_btnArea; wxRect rect = m_tcArea; @@ -448,13 +462,13 @@ void wxComboControl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) ) &r); drawButBg = false; - } + } // Standard button rendering DrawButton(dc,rectb,drawButBg); // paint required portion on the control - if ( !m_text || m_widthCustomPaint ) + if ( (!m_text || m_widthCustomPaint) ) { wxASSERT( m_widthCustomPaint >= 0 ); @@ -466,17 +480,19 @@ void wxComboControl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) ) dc.SetFont( GetFont() ); dc.SetClippingRegion(rect); - m_popupInterface->PaintComboControl(dc,rect); + if ( m_popupInterface ) + m_popupInterface->PaintComboControl(dc,rect); + else + wxComboPopup::DefaultPaintComboControl(this,dc,rect); } } -void wxComboControl::OnMouseEvent( wxMouseEvent& event ) +void wxComboCtrl::OnMouseEvent( wxMouseEvent& event ) { - bool isOnButtonArea = m_btnArea.Inside(event.m_x,event.m_y); + int mx = event.m_x; + bool isOnButtonArea = m_btnArea.Contains(mx,event.m_y); int handlerFlags = isOnButtonArea ? wxCC_MF_ON_BUTTON : 0; - // Preprocessing fabricates double-clicks and prevents - // (it may also do other common things in future) if ( PreprocessMouseEvent(event,isOnButtonArea) ) return; @@ -490,8 +506,11 @@ void wxComboControl::OnMouseEvent( wxMouseEvent& event ) } else { - if ( isOnButtonArea || HasCapture() ) + if ( isOnButtonArea || HasCapture() || + (m_widthCustomPaint && mx < (m_tcArea.x+m_widthCustomPaint)) ) { + handlerFlags |= wxCC_MF_ON_CLICK_AREA; + if ( HandleButtonMouseEvent(event,handlerFlags) ) return; } @@ -510,12 +529,46 @@ void wxComboControl::OnMouseEvent( wxMouseEvent& event ) } -wxCoord wxComboControl::GetNativeTextIndent() const +wxCoord wxComboCtrl::GetNativeTextIndent() const { if ( wxUxThemeEngine::GetIfActive() ) return NATIVE_TEXT_INDENT_XP; return NATIVE_TEXT_INDENT_CLASSIC; } +bool wxComboCtrl::IsKeyPopupToggle(const wxKeyEvent& event) const +{ + const bool isPopupShown = IsPopupShown(); + + switch ( event.GetKeyCode() ) + { + case WXK_F4: + // F4 toggles the popup in the native comboboxes, so emulate them + if ( !event.AltDown() ) + return true; + break; + + case WXK_ESCAPE: + if ( isPopupShown ) + return true; + break; + + case WXK_DOWN: + case WXK_UP: + // On XP or with writable combo in Classic, arrows don't open the + // popup but Alt-arrow does + if ( event.AltDown() || + ( !isPopupShown && + HasFlag(wxCB_READONLY) && + !wxUxThemeEngine::GetIfActive() + ) ) + { + return true; + } + break; + } + + return false; +} -#endif // wxUSE_COMBOCONTROL +#endif // wxUSE_COMBOCTRL