]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/combo.cpp
Commit FM's GTK+ native assert dialog code.
[wxWidgets.git] / src / msw / combo.cpp
index 260ef989285349cce9ee2a7d716e767406e4cd03..7c69f60c861b2c2b838f3b1d277752a62858fe1d 100644 (file)
     #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"
 #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;
@@ -450,7 +456,7 @@ void wxComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
     dc.DrawRectangle(rect);
 
     // Button background with theme?
-    bool drawButBg = true;
+    int drawButFlags = Draw_PaintBg;
     if ( hTheme && m_blankButtonBg )
     {
         RECT r;
@@ -462,11 +468,11 @@ void wxComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
                                          GetHdcOf(dc),
                                          &r);
 
-        drawButBg = false;
+        drawButFlags = 0;
     }
 
     // Standard button rendering
-    DrawButton(dc,rectb,drawButBg);
+    DrawButton(dc,rectb,drawButFlags);
 
     // paint required portion on the control
     if ( (!m_text || m_widthCustomPaint) )
@@ -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
 {