X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/974a12f86a2882b0999a441ce4ad07e0e2c4377c..88e183d7693c5272673d109b21e40e1bb525a386:/src/msw/combo.cpp diff --git a/src/msw/combo.cpp b/src/msw/combo.cpp index 260ef98928..367f609c50 100644 --- a/src/msw/combo.cpp +++ b/src/msw/combo.cpp @@ -31,10 +31,10 @@ #include "wx/dcclient.h" #include "wx/settings.h" #include "wx/dialog.h" + #include "wx/stopwatch.h" #endif #include "wx/dcbuffer.h" - #include "wx/combo.h" #include "wx/msw/registry.h" @@ -70,8 +70,13 @@ #define TEXTCTRLXADJUST_CLASSIC 1 #define TEXTCTRLYADJUST_CLASSIC 2 +#define COMBOBOX_ANIMATION_RESOLUTION 10 + #define COMBOBOX_ANIMATION_DURATION 200 // In milliseconds +#define wxMSW_DESKTOP_USERPREFERENCESMASK_COMBOBOXANIM (1<<2) + + // ============================================================================ // implementation // ============================================================================ @@ -80,6 +85,9 @@ BEGIN_EVENT_TABLE(wxComboCtrl, wxComboCtrlBase) EVT_PAINT(wxComboCtrl::OnPaintEvent) EVT_MOUSE_EVENTS(wxComboCtrl::OnMouseEvent) +#if wxUSE_COMBOCTRL_POPUP_ANIMATION + EVT_TIMER(wxID_ANY, wxComboCtrl::OnTimerEvent) +#endif END_EVENT_TABLE() @@ -141,8 +149,8 @@ bool wxComboCtrl::Create(wxWindow *parent, // Prepare background for double-buffering SetBackgroundStyle( wxBG_STYLE_CUSTOM ); - // SetBestSize should be called last - SetBestSize(size); + // SetInitialSize should be called last + SetInitialSize(size); return true; } @@ -240,12 +248,9 @@ static void wxMSWDrawFocusRect( wxDC& dc, const wxRect& rect ) } // draw focus background on area in a way typical on platform -void wxComboCtrl::PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const +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; @@ -308,8 +313,9 @@ void wxComboCtrl::PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) c selRect.x += wcp + focusSpacingX; selRect.width -= wcp + (focusSpacingX*2); - if ( hTheme ) - theme = wxUxThemeEngine::GetIfActive(); + //wxUxThemeEngine* theme = (wxUxThemeEngine*) NULL; + //if ( hTheme ) + // theme = wxUxThemeEngine::GetIfActive(); wxColour bgCol; bool drawDottedEdge = false; @@ -530,7 +536,7 @@ void wxComboCtrl::OnMouseEvent( wxMouseEvent& event ) } -#if !defined(__WXWINCE__) +#if wxUSE_COMBOCTRL_POPUP_ANIMATION static wxUint32 GetUserPreferencesMask() { static wxUint32 userPreferencesMask = 0; @@ -539,16 +545,28 @@ static wxUint32 GetUserPreferencesMask() if ( valueSet ) return userPreferencesMask; - wxRegKey key(wxRegKey::HKCU, wxT("Control Panel\\Desktop")); - if( key.Open(wxRegKey::Read) ) + wxRegKey* pKey = NULL; + wxRegKey key1(wxRegKey::HKCU, wxT("Software\\Policies\\Microsoft\\Control Panel")); + wxRegKey key2(wxRegKey::HKCU, wxT("Software\\Policies\\Microsoft\\Windows\\Control Panel")); + wxRegKey key3(wxRegKey::HKCU, wxT("Control Panel\\Desktop")); + + if ( key1.Exists() ) + pKey = &key1; + else if ( key2.Exists() ) + pKey = &key2; + else if ( key3.Exists() ) + pKey = &key3; + + if ( pKey && pKey->Open(wxRegKey::Read) ) { wxMemoryBuffer buf; - if ( key.QueryValue(wxT("UserPreferencesMask"), buf) ) + if ( pKey->HasValue(wxT("UserPreferencesMask")) && + pKey->QueryValue(wxT("UserPreferencesMask"), buf) ) { if ( buf.GetDataLen() >= 4 ) { - wxByte* p = (wxByte*) buf.GetData(); - userPreferencesMask = p[3] + (p[2]<<8) + (p[1]<<16) + (p[0]<<24); + wxUint32* p = (wxUint32*) buf.GetData(); + userPreferencesMask = *p; } } } @@ -559,64 +577,83 @@ static wxUint32 GetUserPreferencesMask() } #endif -bool wxComboCtrl::AnimateShow( const wxRect& rect, int flags ) +#if wxUSE_COMBOCTRL_POPUP_ANIMATION +void wxComboCtrl::OnTimerEvent( wxTimerEvent& WXUNUSED(event) ) { -#if !defined(__WXWINCE__) - if ( GetUserPreferencesMask() & (1<<26) ) - { - wxLongLong tStart = ::wxGetLocalTimeMillis(); + bool stopTimer = false; - int height = rect.height; + wxWindow* popup = GetPopupControl()->GetControl(); + // Popup was hidden before it was fully shown? + if ( IsPopupWindowState(Hidden) ) + { + stopTimer = true; + } + else + { + wxLongLong t = ::wxGetLocalTimeMillis(); + const wxRect& rect = m_animRect; wxWindow* win = GetPopupWindow(); - wxWindow* popup = GetPopupControl()->GetControl(); - const int delay = COMBOBOX_ANIMATION_DURATION; - const int resolution = 10; - int h0 = popup->GetSize().y; - - win->SetSize( rect.x, rect.y, rect.width, 0 ); - win->Show(); - - for (;;) + int pos = (int) (t-m_animStart).GetLo(); + if ( pos < COMBOBOX_ANIMATION_DURATION ) { - wxLongLong t = ::wxGetLocalTimeMillis(); - int pos = (int) (t-tStart).GetLo(); - if ( pos > delay ) - break; - - int h = (((pos*256)/delay)*height)/256; - int y = (h0 - h); + int height = rect.height; + //int h0 = rect.height; + int h = (((pos*256)/COMBOBOX_ANIMATION_DURATION)*height)/256; + int y = (height - h); if ( y < 0 ) y = 0; - if ( flags & ShowAbove ) + if ( m_animFlags & ShowAbove ) { - win->SetSize( rect.x, rect.y + h0 - h, rect.width, h ); + win->SetSize( rect.x, rect.y + height - h, rect.width, h ); } else { popup->Move( 0, -y ); win->SetSize( rect.x, rect.y, rect.width, h ); } - - wxMilliSleep( resolution ); - wxYield(); - - // Popup was hidden before it was fully shown? - if ( IsPopupWindowState(Hidden) ) - return true; } + else + { + stopTimer = true; + } + } + if ( stopTimer ) + { popup->Move( 0, 0 ); + m_animTimer.Stop(); + DoShowPopup( m_animRect, m_animFlags ); } -#else - wxUnusedVar(rect); - wxUnusedVar(flags); +} #endif +#if wxUSE_COMBOCTRL_POPUP_ANIMATION +bool wxComboCtrl::AnimateShow( const wxRect& rect, int flags ) +{ + if ( GetUserPreferencesMask() & wxMSW_DESKTOP_USERPREFERENCESMASK_COMBOBOXANIM ) + { + m_animStart = ::wxGetLocalTimeMillis(); + m_animRect = rect; + m_animFlags = flags; + + wxWindow* win = GetPopupWindow(); + win->SetSize( rect.x, rect.y, rect.width, 0 ); + win->Show(); + + m_animTimer.SetOwner( this, wxID_ANY ); + m_animTimer.Start( COMBOBOX_ANIMATION_RESOLUTION, wxTIMER_CONTINUOUS ); + + OnTimerEvent(*((wxTimerEvent*)NULL)); // Event is never used, so we can give NULL + + return false; + } + return true; } +#endif wxCoord wxComboCtrl::GetNativeTextIndent() const {