]> git.saurik.com Git - wxWidgets.git/commitdiff
Don't draw over dummy separators in MSW toolbar, just don't draw them at all.
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 18 Dec 2009 22:31:48 +0000 (22:31 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 18 Dec 2009 22:31:48 +0000 (22:31 +0000)
Prevent the native toolbar from drawing the separators which we use simply as
placeholders by excluding them from the update region when handling WM_PAINT.

This reduces flicker by not redrawing the areas occupied by these separators
twice and also prevents them from ever being shown (you could see them briefly
appear before being erased before).

The other toolbar tools still flicker though, there doesn't seem to be any
simple way to prevent the control from entirely invalidating itself whenever
it is resized.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62934 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/toolbar.h
src/msw/toolbar.cpp

index eadf5217c4f4d2adbc60f31237e48bd2ba35dc3b..2161bc49c493122541c632c4c0ba4fdb5479ae9d 100644 (file)
@@ -156,12 +156,6 @@ private:
     // have
     void UpdateStretchableSpacersSize();
 
-#ifndef __WXWINCE__
-    // redraw the background of the given part of the window to erase separator
-    // drawn in it
-    void MSWEraseRect(wxDC& dc, const wxRect& rectItem);
-#endif // !__WXWINCE__
-
     DECLARE_EVENT_TABLE()
     DECLARE_DYNAMIC_CLASS(wxToolBar)
     wxDECLARE_NO_COPY_CLASS(wxToolBar);
index 1a9e9efe866e06e663958cc04adf811bbd92b3f2..71aec08351b82a5c904c6c1c8be083493d6f7f5b 100644 (file)
@@ -940,6 +940,10 @@ bool wxToolBar::Realize()
                     // so we need a valid id for it and not wxID_SEPARATOR
                     // which is used by spacers by default
                     tool->AllocSpacerId();
+
+                    // also set the number of separators so that the logic in
+                    // HandlePaint() works correctly
+                    tool->SetSeparatorsCount(1);
                 }
 
                 button.idCommand = tool->GetId();
@@ -1196,7 +1200,11 @@ bool wxToolBar::Realize()
 
 void wxToolBar::UpdateStretchableSpacersSize()
 {
-    // we can't resize the spacers if TB_SETBUTTONINFO is not supported
+#ifdef TB_SETBUTTONINFO
+    // we can't resize the spacers if TB_SETBUTTONINFO is not supported (we
+    // could try to do it with multiple separators as for the controls but this
+    // is too painful and it just doesn't seem to be worth doing for the
+    // ancient systems)
     if ( wxApp::GetComCtl32Version() < 471 )
         return;
 
@@ -1263,6 +1271,7 @@ void wxToolBar::UpdateStretchableSpacersSize()
             offset += tbbi.cx - (rcOld.right - rcOld.left);
         }
     }
+#endif // TB_SETBUTTONINFO
 }
 
 // ----------------------------------------------------------------------------
@@ -1700,127 +1709,41 @@ bool wxToolBar::HandleSize(WXWPARAM WXUNUSED(wParam), WXLPARAM lParam)
 
 #ifndef __WXWINCE__
 
-void wxToolBar::MSWEraseRect(wxDC& dc, const wxRect& rectItem)
-{
-    dc.DrawRectangle(rectItem);
-}
-
-bool wxToolBar::HandlePaint(WXWPARAM wParam, WXLPARAM lParam)
+bool wxToolBar::HandlePaint(WXWPARAM WXUNUSED(wParam), WXLPARAM WXUNUSED(lParam))
 {
-    // erase any dummy separators which were used only for reserving space in
-    // the toolbar (either for a control or just for a stretchable space)
-
-    // first of all, are there any controls at all?
-    wxToolBarToolsList::compatibility_iterator node;
-    for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
-    {
-        wxToolBarToolBase * const tool = node->GetData();
-        if ( tool->IsControl() || tool->IsStretchableSpace() )
-            break;
-    }
-
-    if ( !node )
-    {
-        // no controls, nothing to erase
-        return false;
-    }
-
-    // prepare the DC on which we'll be drawing
-    wxClientDC dc(this);
-    dc.SetBrush(GetBackgroundColour());
-    dc.SetPen(*wxTRANSPARENT_PEN);
-
-    RECT rcUpdate;
-    if ( !::GetUpdateRect(GetHwnd(), &rcUpdate, FALSE) )
-    {
-        // nothing to redraw anyhow
-        return false;
-    }
-
-    const wxRect rectUpdate = wxRectFromRECT(rcUpdate);
-    dc.SetClippingRegion(rectUpdate);
-
-    // draw the toolbar tools, separators &c normally
-    wxControl::MSWWindowProc(WM_PAINT, wParam, lParam);
-
-    // for each control in the toolbar find all the separators intersecting it
-    // and erase them
-    //
-    // NB: this is really the only way to do it as we don't know if a separator
-    //     corresponds to a control (i.e. is a dummy one) or a real one
-    //     otherwise
+    // exclude the area occupied by the controls and stretchable spaces from
+    // the update region to prevent the toolbar from drawing separators in it
     int toolIndex = 0;
-    for ( node = m_tools.GetFirst(); node; node = node->GetNext(), toolIndex++ )
+    for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+          node;
+          node = node->GetNext() )
     {
-        wxToolBarTool *tool = (wxToolBarTool*)node->GetData();
-        if ( tool->IsControl() )
-        {
-            // get the control rect in our client coords
-            wxControl *control = tool->GetControl();
-            wxStaticText *staticText = tool->GetStaticText();
-            wxRect rectCtrl = control->GetRect();
-            wxRect rectStaticText;
-            if ( staticText )
-                rectStaticText = staticText->GetRect();
-
-            if ( !rectCtrl.Intersects(rectUpdate) &&
-                    (!staticText || !rectStaticText.Intersects(rectUpdate)) )
-                continue;
+        wxToolBarTool * const
+            tool = static_cast<wxToolBarTool *>(node->GetData());
 
-            // iterate over all buttons to find all separators intersecting
-            // this control
-            TBBUTTON tbb;
-            int count = ::SendMessage(GetHwnd(), TB_BUTTONCOUNT, 0, 0);
-            for ( int n = 0; n < count; n++ )
+        if ( tool->IsControl() || tool->IsStretchableSpace() )
+        {
+            const size_t numSeps = tool->GetSeparatorsCount();
+            for ( size_t n = 0; n < numSeps; n++, toolIndex++ )
             {
-                // is it a separator?
-                if ( !::SendMessage(GetHwnd(), TB_GETBUTTON,
-                                    n, (LPARAM)&tbb) )
-                {
-                    wxLogDebug(wxT("TB_GETBUTTON failed?"));
+                const RECT rcItem = wxGetTBItemRect(GetHwnd(), toolIndex);
 
-                    continue;
+                const wxRegion rgnItem(wxRectFromRECT(rcItem));
+                if ( !ValidateRgn(GetHwnd(), GetHrgnOf(rgnItem)) )
+                {
+                    wxLogLastError(wxT("ValidateRgn()"));
                 }
-
-                if ( tbb.fsStyle != TBSTYLE_SEP )
-                    continue;
-
-                // get the bounding rect of the separator
-                RECT r = wxGetTBItemRect(GetHwnd(), n);
-                if ( !r.right )
-                    continue;
-
-                const wxRect rectItem = wxRectFromRECT(r);
-
-                // does it intersect the update region at all?
-                if ( !rectUpdate.Intersects(rectItem) )
-                    continue;
-
-                // does it intersect the control itself or its label?
-                //
-                // if it does, refresh it so it's redrawn on top of the
-                // background
-                if ( rectCtrl.Intersects(rectItem) )
-                    control->Refresh(false);
-                else if ( staticText && rectStaticText.Intersects(rectItem) )
-                    staticText->Refresh(false);
-                else
-                    continue;
-
-                MSWEraseRect(dc, rectItem);
             }
         }
-        else if ( tool->IsStretchableSpace() )
+        else
         {
-            const wxRect
-                rectItem = wxRectFromRECT(wxGetTBItemRect(GetHwnd(), toolIndex));
-
-            if ( rectUpdate.Intersects(rectItem) )
-                MSWEraseRect(dc, rectItem);
+            // normal tools never correspond to more than one native button
+            toolIndex++;
         }
     }
 
-    return true;
+    // still let the native control draw everything else normally
+    return false;
 }
 #endif // __WXWINCE__