X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/efa14cf20a6fb94b2d3099cb1b884a2c3d8c2b8f..4676948b6814c97b93c431a8cbcd8c0352c87ba9:/src/msw/notebook.cpp diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index 05b4f2c0b5..c09e5fc085 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -32,6 +32,7 @@ #include "wx/event.h" #include "wx/control.h" #include "wx/notebook.h" +#include "wx/app.h" #include "wx/msw/private.h" @@ -42,16 +43,31 @@ #include // for SetWindowFont -#ifndef __TWIN32__ - #ifdef __GNUWIN32_OLD__ - #include "wx/msw/gnuwin32/extra.h" - #endif +#ifdef __GNUWIN32_OLD__ + #include "wx/msw/gnuwin32/extra.h" #endif -#if defined(__WIN95__) && !((defined(__GNUWIN32_OLD__) || defined(__TWIN32__)) && !defined(__CYGWIN10__)) +#if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__)) #include #endif +#include "wx/msw/winundef.h" + +#if wxUSE_UXTHEME +#include "wx/msw/uxtheme.h" + +#include "wx/radiobut.h" +#include "wx/radiobox.h" +#include "wx/checkbox.h" +#include "wx/bmpbuttn.h" +#include "wx/statline.h" +#include "wx/statbox.h" +#include "wx/stattext.h" +#include "wx/slider.h" +#include "wx/scrolwin.h" +#include "wx/panel.h" +#endif + // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -141,12 +157,25 @@ bool wxNotebook::Create(wxWindow *parent, long style, const wxString& name) { - // base init + // Does ComCtl32 support non-top tabs? + int verComCtl32 = wxApp::GetComCtl32Version(); + if ( verComCtl32 < 470 || verComCtl32 >= 600 ) + { + if (style & wxNB_BOTTOM) + style &= ~wxNB_BOTTOM; + + if (style & wxNB_LEFT) + style &= ~wxNB_LEFT; + + if (style & wxNB_RIGHT) + style &= ~wxNB_RIGHT; + } + if ( !CreateControl(parent, id, pos, size, style | wxTAB_TRAVERSAL, wxDefaultValidator, name) ) return FALSE; - if ( !MSWCreateControl(WC_TABCONTROL, _T(""), pos, size) ) + if ( !MSWCreateControl(WC_TABCONTROL, wxEmptyString, pos, size) ) return FALSE; SetBackgroundColour(wxColour(::GetSysColor(COLOR_BTNFACE))); @@ -236,7 +265,7 @@ bool wxNotebook::SetPageText(int nPage, const wxString& strText) wxString wxNotebook::GetPageText(int nPage) const { - wxCHECK_MSG( IS_VALID_PAGE(nPage), wxT(""), wxT("notebook page out of range") ); + wxCHECK_MSG( IS_VALID_PAGE(nPage), wxEmptyString, wxT("notebook page out of range") ); wxChar buf[256]; TC_ITEM tcItem; @@ -313,6 +342,48 @@ void wxNotebook::SetTabSize(const wxSize& sz) ::SendMessage(GetHwnd(), TCM_SETITEMSIZE, 0, MAKELPARAM(sz.x, sz.y)); } +wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage) const +{ + wxSize sizeTotal = sizePage; + + // We need to make getting tab size part of the wxWindows API. + wxSize tabSize(0, 0); + if (GetPageCount() > 0) + { + RECT rect; + TabCtrl_GetItemRect((HWND) GetHWND(), 0, & rect); + tabSize.x = rect.right - rect.left; + tabSize.y = rect.bottom - rect.top; + } + if ( HasFlag(wxNB_LEFT) || HasFlag(wxNB_RIGHT) ) + { + sizeTotal.x += tabSize.x + 7; + sizeTotal.y += 7; + } + else + { + sizeTotal.x += 7; + sizeTotal.y += tabSize.y + 7; + } + + return sizeTotal; +} + +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); + TabCtrl_AdjustRect(m_hwnd, FALSE, &rc); + + page->SetSize(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); +} + // ---------------------------------------------------------------------------- // wxNotebook operations // ---------------------------------------------------------------------------- @@ -399,6 +470,17 @@ bool wxNotebook::InsertPage(int nPage, wxASSERT_MSG( pPage->GetParent() == this, _T("notebook pages must have notebook as parent") ); +#if wxUSE_UXTHEME && wxUSE_UXTHEME_AUTO + // Automatically apply the theme background, + // changing the colour of the panel to match the + // tab page colour. This won't work well with all + // themes but it's a start. + if (wxUxThemeEngine::Get() && pPage->IsKindOf(CLASSINFO(wxPanel))) + { + ApplyThemeBackground(pPage, GetThemeBackgroundColour()); + } +#endif + // add a new tab to the control // ---------------------------- @@ -423,15 +505,11 @@ bool wxNotebook::InsertPage(int nPage, // fit the notebook page to the tab control's display area: this should be // done before adding it to the notebook or TabCtrl_InsertItem() will // change the notebooks size itself! - RECT rc; - rc.left = rc.top = 0; - GetSize((int *)&rc.right, (int *)&rc.bottom); - TabCtrl_AdjustRect(m_hwnd, FALSE, &rc); - pPage->SetSize(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); - + AdjustPageSize(pPage); // finally do insert it - if ( TabCtrl_InsertItem(m_hwnd, nPage, &tcItem) == -1 ) { + if ( TabCtrl_InsertItem(m_hwnd, nPage, &tcItem) == -1 ) + { wxLogError(wxT("Can't create the notebook page '%s'."), strText.c_str()); return FALSE; @@ -440,6 +518,14 @@ bool wxNotebook::InsertPage(int nPage, // succeeded: save the pointer to the page m_pages.Insert(pPage, nPage); + // for the first page (only) we need to adjust the size again because the + // notebook size changed: the tabs which hadn't been there before are now + // shown + if ( m_pages.GetCount() == 1 ) + { + AdjustPageSize(pPage); + } + // hide the page: unless it is selected, it shouldn't be shown (and if it // is selected it will be shown later) HWND hwnd = GetWinHwnd(pPage); @@ -475,6 +561,31 @@ bool wxNotebook::InsertPage(int nPage, return TRUE; } +int wxNotebook::HitTest(const wxPoint& pt, long *flags) const +{ + TC_HITTESTINFO hitTestInfo; + hitTestInfo.pt.x = pt.x; + hitTestInfo.pt.y = pt.y; + int item = TabCtrl_HitTest(GetHwnd(), &hitTestInfo); + + if ( flags ) + { + *flags = 0; + + if ((hitTestInfo.flags & TCHT_NOWHERE) == TCHT_NOWHERE) + *flags |= wxNB_HITTEST_NOWHERE; + if ((hitTestInfo.flags & TCHT_ONITEM) == TCHT_ONITEM) + *flags |= wxNB_HITTEST_ONITEM; + if ((hitTestInfo.flags & TCHT_ONITEMICON) == TCHT_ONITEMICON) + *flags |= wxNB_HITTEST_ONICON; + if ((hitTestInfo.flags & TCHT_ONITEMLABEL) == TCHT_ONITEMLABEL) + *flags |= wxNB_HITTEST_ONLABEL; + } + + return item; +} + + // ---------------------------------------------------------------------------- // wxNotebook callbacks // ---------------------------------------------------------------------------- @@ -557,9 +668,9 @@ void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event) // OnSetFocus() because we don't know which direction the focus came // from in this case and so can't choose between setting the focus to // first or last panel child - wxWindow *parent = GetParent(); - if ( event.GetEventObject() == parent ) + // the cast is here to fic a GCC ICE + if ( ((wxWindow*)event.GetEventObject()) == parent ) { // no, it doesn't come from child, case (b): forward to a page if ( m_nSelection != -1 ) @@ -656,4 +767,67 @@ bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result) return processed; } +// Windows only: attempts to get colour for UX theme page background +wxColour wxNotebook::GetThemeBackgroundColour() +{ +#if wxUSE_UXTHEME + if (wxUxThemeEngine::Get()) + { + WXHTHEME hTheme = wxUxThemeEngine::Get()->m_pfnOpenThemeData(GetHWND(), L"TAB"); + if (hTheme) + { + // This is total guesswork. + // See PlatformSDK\Include\Tmschema.h for values + COLORREF themeColor; + wxUxThemeEngine::Get()-> + m_pfnGetThemeColor(hTheme, + 10 /* TABP_BODY */, + 1 /* NORMAL */, + 3821, /* FILLCOLORHINT */ + & themeColor); + + wxUxThemeEngine::Get()->m_pfnCloseThemeData(hTheme); + + wxColour colour(GetRValue(themeColor), GetGValue(themeColor), GetBValue(themeColor)); + return colour; + } + } +#endif + return GetBackgroundColour(); +} + +// Windows only: attempts to apply the UX theme page background to this page +void wxNotebook::ApplyThemeBackground(wxWindow* window, const wxColour& colour) +{ +#if wxUSE_UXTHEME + // Don't set the background for buttons since this will + // switch it into ownerdraw mode + if (window->IsKindOf(CLASSINFO(wxButton)) && !window->IsKindOf(CLASSINFO(wxBitmapButton))) + // This is essential, otherwise you'll see dark grey + // corners in the buttons. + ((wxButton*)window)->wxControl::SetBackgroundColour(colour); + else if (window->IsKindOf(CLASSINFO(wxStaticText)) || + window->IsKindOf(CLASSINFO(wxStaticBox)) || + window->IsKindOf(CLASSINFO(wxStaticLine)) || + window->IsKindOf(CLASSINFO(wxRadioButton)) || + window->IsKindOf(CLASSINFO(wxRadioBox)) || + window->IsKindOf(CLASSINFO(wxCheckBox)) || + window->IsKindOf(CLASSINFO(wxBitmapButton)) || + window->IsKindOf(CLASSINFO(wxSlider)) || + window->IsKindOf(CLASSINFO(wxPanel)) || + (window->IsKindOf(CLASSINFO(wxNotebook)) && (window != this)) || + window->IsKindOf(CLASSINFO(wxScrolledWindow)) + ) + { + window->SetBackgroundColour(colour); + } + + for ( wxWindowList::compatibility_iterator node = window->GetChildren().GetFirst(); node; node = node->GetNext() ) + { + wxWindow *child = node->GetData(); + ApplyThemeBackground(child, colour); + } +#endif +} + #endif // wxUSE_NOTEBOOK