]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/notebook.cpp
Add room for the scrollbar
[wxWidgets.git] / src / msw / notebook.cpp
index e73853067695a35904562411e68d26c33f9ae508..cb09470b78e15213b8bef66631b46a597ea10a90 100644 (file)
@@ -94,9 +94,7 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
 
 BEGIN_EVENT_TABLE(wxNotebook, wxControl)
     EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
-
     EVT_SIZE(wxNotebook::OnSize)
-
     EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
 END_EVENT_TABLE()
 
@@ -135,6 +133,8 @@ wxBEGIN_FLAGS( wxNotebookStyle )
     wxFLAGS_MEMBER(wxNB_LEFT)
     wxFLAGS_MEMBER(wxNB_RIGHT)
     wxFLAGS_MEMBER(wxNB_BOTTOM)
+    wxFLAGS_MEMBER(wxNB_NOPAGETHEME)
+    wxFLAGS_MEMBER(wxNB_FLAT)
 
 wxEND_FLAGS( wxNotebookStyle )
 
@@ -239,6 +239,13 @@ bool wxNotebook::Create(wxWindow *parent,
                         long style,
                         const wxString& name)
 {
+#ifdef __WXWINCE__
+    // Not sure why, but without this style, there is no border
+    // around the notebook tabs.
+    if (style & wxNB_FLAT)
+        style |= wxBORDER_SUNKEN;
+#endif
+
     // comctl32.dll 6.0 doesn't support non-top tabs with visual styles (the
     // control is simply not rendered correctly), so disable them in this case
     const int verComCtl32 = wxApp::GetComCtl32Version();
@@ -296,15 +303,26 @@ bool wxNotebook::Create(wxWindow *parent,
     if ( !MSWCreateControl(className, wxEmptyString, pos, size) )
         return false;
 
-    if (HasFlag(wxNB_NOPAGETHEME) || (wxSystemOptions::HasOption(wxT("msw.notebook.themed-background")) &&
-                                      wxSystemOptions::GetOptionInt(wxT("msw.notebook.themed-background")) == 0))
+#if wxUSE_UXTHEME
+    if ( HasFlag(wxNB_NOPAGETHEME) ||
+            wxSystemOptions::IsFalse(wxT("msw.notebook.themed-background")) )
     {
-        wxColour col = GetThemeBackgroundColour();
-        if (col.Ok())
-        {
-            SetBackgroundColour(col);
-        }
+        SetBackgroundColour(GetThemeBackgroundColour());
+    }
+#endif // wxUSE_UXTHEME
+
+    // Undocumented hack to get flat notebook style
+    // In fact, we should probably only do this in some
+    // curcumstances, i.e. if we know we will have a border
+    // at the bottom (the tab control doesn't draw it itself)
+#if defined(__POCKETPC__) || defined(__SMARTPHONE__)
+    if (HasFlag(wxNB_FLAT))
+    {
+        SendMessage(m_hwnd, CCM_SETVERSION, COMCTL32_VERSION, 0);
+        if (!m_hasBgCol)
+            SetBackgroundColour(*wxWHITE);
     }
+#endif
     return true;
 }
 
@@ -448,6 +466,29 @@ void wxNotebook::SetImageList(wxImageList* imageList)
 // wxNotebook size settings
 // ----------------------------------------------------------------------------
 
+wxRect wxNotebook::GetPageSize() const
+{
+    wxRect r;
+
+    RECT rc;
+    ::GetClientRect(GetHwnd(), &rc);
+
+    // This check is to work around a bug in TabCtrl_AdjustRect which will
+    // cause a crash on win2k, or on XP with themes disabled, if the
+    // wxNB_MULTILINE style is used and the rectangle is very small, (such as
+    // when the notebook is first created.)  The value of 20 is just
+    // arbitrarily chosen, if there is a better way to determine this value
+    // then please do so.  --RD
+    if ( !HasFlag(wxNB_MULTILINE) || (rc.right > 20 && rc.bottom > 20) )
+    {
+        TabCtrl_AdjustRect(m_hwnd, false, &rc);
+
+        wxCopyRECTToRect(rc, r);
+    }
+
+    return r;
+}
+
 void wxNotebook::SetPageSize(const wxSize& size)
 {
     // transform the page size into the notebook size
@@ -506,23 +547,10 @@ void wxNotebook::AdjustPageSize(wxNotebookPage *page)
 {
     wxCHECK_RET( page, _T("NULL page in wxNotebook::AdjustPageSize") );
 
-    RECT rc;
-    rc.left =
-    rc.top = 0;
-
-    // get the page size from the notebook size
-    GetSize((int *)&rc.right, (int *)&rc.bottom);
-
-    // This check is to work around a bug in TabCtrl_AdjustRect which will
-    // cause a crash on win2k, or on XP with themes disabled, if the
-    // wxNB_MULTILINE style is used and the rectangle is very small, (such as
-    // when the notebook is first created.)  The value of 20 is just
-    // arbitrarily chosen, if there is a better way to determine this value
-    // then please do so.  --RD
-    if (rc.right > 20 && rc.bottom > 20)
+    const wxRect r = GetPageSize();
+    if ( !r.IsEmpty() )
     {
-        TabCtrl_AdjustRect(m_hwnd, false, &rc);
-        page->SetSize(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
+        page->SetSize(r);
     }
 }
 
@@ -726,11 +754,20 @@ int wxNotebook::HitTest(const wxPoint& pt, long *flags) const
 
 void wxNotebook::OnSize(wxSizeEvent& event)
 {
-    // update the background brush
 #if wxUSE_UXTHEME
+    // background bitmap size has changed, update the brush using it too
     UpdateBgBrush();
 #endif // wxUSE_UXTHEME
 
+    if ( GetPageCount() == 0 )
+    {
+        // Prevents droppings on resize, but does cause some flicker
+        // when there are no pages.
+        Refresh();
+        event.Skip();
+        return;
+    }
+
     // fit all the notebook pages to the tab control's display area
 
     RECT rc;
@@ -923,33 +960,65 @@ void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
 
 #if wxUSE_UXTHEME
 
-WXHANDLE wxNotebook::QueryBgBitmap(wxWindow *win)
+bool wxNotebook::DoDrawBackground(WXHDC hDC, wxWindow *child)
 {
+    wxUxThemeHandle theme(child ? child : this, L"TAB");
+    if ( !theme )
+        return false;
+
+    // get the notebook client rect (we're not interested in drawing tabs
+    // themselves)
+    wxRect r = GetPageSize();
+    if ( r.IsEmpty() )
+        return false;
+
     RECT rc;
-    GetWindowRect(GetHwnd(), &rc);
+    wxCopyRectToRECT(r, rc);
 
-    WindowHDC hDC(GetHwnd());
-    MemoryHDC hDCMem(hDC);
-    CompatibleBitmap hBmp(hDC, rc.right - rc.left, rc.bottom - rc.top);
+    // map rect to the coords of the window we're drawing in
+    if ( child )
+        ::MapWindowPoints(GetHwnd(), GetHwndOf(child), (POINT *)&rc, 2);
 
-    SelectInHDC selectBmp(hDCMem, hBmp);
 
-    ::SendMessage(GetHwnd(), WM_PRINTCLIENT,
-                  (WPARAM)(HDC)hDCMem,
-                  PRF_ERASEBKGND | PRF_CLIENT | PRF_NONCLIENT);
+    // apparently DrawThemeBackground() modifies the rect passed to it and if we
+    // don't do these adjustments, there are some drawing artifacts which are
+    // only visible with some non default themes; so modify the rect here using
+    // the magic numbers below so that it still paints the correct area
+    rc.left   -= 2;
+    rc.top    -= 2;
+    rc.right  += 4;
+    rc.bottom += 5;
 
-    if ( win )
-    {
-        RECT rc2;
-        ::GetWindowRect(GetHwndOf(win), &rc2);
 
-        COLORREF c = ::GetPixel(hDCMem, rc2.left - rc.left, rc2.top - rc.top);
+    wxUxThemeEngine::Get()->DrawThemeBackground
+                            (
+                                theme,
+                                hDC,
+                                9 /* TABP_PANE */,
+                                0,
+                                &rc,
+                                NULL
+                            );
 
-        return (WXHANDLE)c;
-    }
-    //else: we are asked to create the brush
+    return true;
+}
+
+WXHBRUSH wxNotebook::QueryBgBitmap()
+{
+    wxRect r = GetPageSize();
+    if ( r.IsEmpty() )
+        return 0;
 
-    return (WXHANDLE)::CreatePatternBrush(hBmp);
+    WindowHDC hDC(GetHwnd());
+    MemoryHDC hDCMem(hDC);
+    CompatibleBitmap hBmp(hDC, r.x + r.width, r.y + r.height);
+
+    SelectInHDC selectBmp(hDCMem, hBmp);
+
+    if ( !DoDrawBackground((WXHDC)(HDC)hDCMem) )
+        return 0;
+
+    return (WXHBRUSH)::CreatePatternBrush(hBmp);
 }
 
 void wxNotebook::UpdateBgBrush()
@@ -959,22 +1028,22 @@ void wxNotebook::UpdateBgBrush()
 
     if ( !m_hasBgCol && wxUxThemeEngine::GetIfActive() )
     {
-        m_hbrBackground = (WXHBRUSH)QueryBgBitmap();
+        m_hbrBackground = QueryBgBitmap();
     }
-    else // no themes
+    else // no themes or we've got user-defined solid colour
     {
         m_hbrBackground = NULL;
     }
 }
 
-WXHBRUSH wxNotebook::MSWGetBgBrushForChild(WXHDC hDC, wxWindow *win)
+WXHBRUSH wxNotebook::MSWGetBgBrushForChild(WXHDC hDC, WXHWND hWnd)
 {
     if ( m_hbrBackground )
     {
         // before drawing with the background brush, we need to position it
         // correctly
         RECT rc;
-        ::GetWindowRect(GetHwndOf(win), &rc);
+        ::GetWindowRect((HWND)hWnd, &rc);
 
         ::MapWindowPoints(NULL, GetHwnd(), (POINT *)&rc, 1);
 
@@ -986,47 +1055,16 @@ WXHBRUSH wxNotebook::MSWGetBgBrushForChild(WXHDC hDC, wxWindow *win)
         return m_hbrBackground;
     }
 
-    return wxNotebookBase::MSWGetBgBrushForChild(hDC, win);
+    return wxNotebookBase::MSWGetBgBrushForChild(hDC, hWnd);
 }
 
-wxColour wxNotebook::MSWGetBgColourForChild(wxWindow *win)
+bool wxNotebook::MSWPrintChild(WXHDC hDC, wxWindow *child)
 {
-    if ( m_hasBgCol )
-        return GetBackgroundColour();
-
-    if ( !wxUxThemeEngine::GetIfActive() )
-        return wxNullColour;
-
-    COLORREF c = (COLORREF)QueryBgBitmap(win);
-
-    return c == CLR_INVALID ? wxNullColour : wxRGBToColour(c);
-}
+    // solid background colour overrides themed background drawing
+    if ( !UseBgCol() && DoDrawBackground(hDC, child) )
+        return true;
 
-bool
-wxNotebook::MSWPrintChild(wxWindow *win,
-                          WXWPARAM wParam,
-                          WXLPARAM WXUNUSED(lParam))
-{
-    RECT rc;
-    ::GetClientRect(GetHwnd(), &rc);
-    TabCtrl_AdjustRect(GetHwnd(), true, &rc);
-    ::MapWindowPoints(GetHwnd(), GetHwndOf(win), (POINT *)&rc, 2);
-
-    wxUxThemeHandle theme(win, L"TAB");
-    if ( theme )
-    {
-        wxUxThemeEngine::Get()->DrawThemeBackground
-        (
-            theme,
-            (WXHDC)wParam,
-            9 /* TABP_PANE */,
-            0,
-            &rc,
-            NULL
-        );
-    }
-
-    return true;
+    return wxNotebookBase::MSWPrintChild(hDC, child);
 }
 
 #endif // wxUSE_UXTHEME
@@ -1069,8 +1107,7 @@ wxColour wxNotebook::GetThemeBackgroundColour() const
                                             &themeColor);
             }
 
-            wxColour colour(GetRValue(themeColor), GetGValue(themeColor), GetBValue(themeColor));
-            return colour;
+            return wxRGBToColour(themeColor);
         }
     }
 #endif // wxUSE_UXTHEME