added support for drawing themed background: DoEraseBackground() and GetThemeBackgroundBrush()
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30631 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -72,6 +72,7 @@ public:
|
|||||||
const wxSize& size = wxDefaultSize,
|
const wxSize& size = wxDefaultSize,
|
||||||
long style = 0,
|
long style = 0,
|
||||||
const wxString& name = wxNOTEBOOK_NAME);
|
const wxString& name = wxNOTEBOOK_NAME);
|
||||||
|
virtual ~wxNotebook();
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
// ---------
|
// ---------
|
||||||
@@ -111,9 +112,6 @@ public:
|
|||||||
// set the padding between tabs (in pixels)
|
// set the padding between tabs (in pixels)
|
||||||
void SetPadding(const wxSize& padding);
|
void SetPadding(const wxSize& padding);
|
||||||
|
|
||||||
// Windows only: attempts to get colour for UX theme page background
|
|
||||||
wxColour GetThemeBackgroundColour();
|
|
||||||
|
|
||||||
// operations
|
// operations
|
||||||
// ----------
|
// ----------
|
||||||
// remove all pages
|
// remove all pages
|
||||||
@@ -134,9 +132,6 @@ public:
|
|||||||
// style.
|
// style.
|
||||||
void SetTabSize(const wxSize& sz);
|
void SetTabSize(const wxSize& sz);
|
||||||
|
|
||||||
// Windows only: attempts to apply the UX theme page background to this page
|
|
||||||
void ApplyThemeBackground(wxWindow* window, const wxColour& colour);
|
|
||||||
|
|
||||||
// hit test
|
// hit test
|
||||||
virtual int HitTest(const wxPoint& pt, long *flags = NULL) const;
|
virtual int HitTest(const wxPoint& pt, long *flags = NULL) const;
|
||||||
|
|
||||||
@@ -162,6 +157,19 @@ public:
|
|||||||
virtual bool DoPhase(int nPhase);
|
virtual bool DoPhase(int nPhase);
|
||||||
#endif // wxUSE_CONSTRAINTS
|
#endif // wxUSE_CONSTRAINTS
|
||||||
|
|
||||||
|
|
||||||
|
// implementation only
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
#if wxUSE_UXTHEME
|
||||||
|
// handler for child pages erase background event
|
||||||
|
void DoEraseBackground(wxEraseEvent& event);
|
||||||
|
|
||||||
|
// get the brush to be used for painting the background for the controls
|
||||||
|
// which need it in their MSWControlColor()
|
||||||
|
WXHBRUSH GetThemeBackgroundBrush() const { return m_hbrBackground; }
|
||||||
|
#endif // wxUSE_UXTHEME
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
void Init();
|
void Init();
|
||||||
@@ -175,15 +183,20 @@ protected:
|
|||||||
// set the size of the given page to fit in the notebook
|
// set the size of the given page to fit in the notebook
|
||||||
void AdjustPageSize(wxNotebookPage *page);
|
void AdjustPageSize(wxNotebookPage *page);
|
||||||
|
|
||||||
// override WndProc.
|
|
||||||
#if wxUSE_UXTHEME
|
#if wxUSE_UXTHEME
|
||||||
virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
|
// creates the brush to be used for drawing the tab control background
|
||||||
#endif
|
void UpdateBgBrush();
|
||||||
|
#endif // wxUSE_UXTHEME
|
||||||
|
|
||||||
// the current selection (-1 if none)
|
// the current selection (-1 if none)
|
||||||
int m_nSelection;
|
int m_nSelection;
|
||||||
|
|
||||||
wxNotebookPageInfoList m_pageInfos ;
|
wxNotebookPageInfoList m_pageInfos;
|
||||||
|
|
||||||
|
#if wxUSE_UXTHEME
|
||||||
|
// background brush used to paint the tab control
|
||||||
|
WXHBRUSH m_hbrBackground;
|
||||||
|
#endif // wxUSE_UXTHEME
|
||||||
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxNotebook)
|
DECLARE_DYNAMIC_CLASS_NO_COPY(wxNotebook)
|
||||||
|
@@ -54,18 +54,7 @@
|
|||||||
#include "wx/msw/winundef.h"
|
#include "wx/msw/winundef.h"
|
||||||
|
|
||||||
#if wxUSE_UXTHEME
|
#if wxUSE_UXTHEME
|
||||||
#include "wx/msw/uxtheme.h"
|
#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
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -220,6 +209,10 @@ void wxNotebook::Init()
|
|||||||
{
|
{
|
||||||
m_imageList = NULL;
|
m_imageList = NULL;
|
||||||
m_nSelection = -1;
|
m_nSelection = -1;
|
||||||
|
|
||||||
|
#if wxUSE_UXTHEME
|
||||||
|
m_hbrBackground = NULL;
|
||||||
|
#endif // wxUSE_UXTHEME
|
||||||
}
|
}
|
||||||
|
|
||||||
// default for dynamic class
|
// default for dynamic class
|
||||||
@@ -270,8 +263,6 @@ bool wxNotebook::Create(wxWindow *parent,
|
|||||||
if ( !MSWCreateControl(WC_TABCONTROL, wxEmptyString, pos, size) )
|
if ( !MSWCreateControl(WC_TABCONTROL, wxEmptyString, pos, size) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SetBackgroundColour(wxColour(::GetSysColor(COLOR_BTNFACE)));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,6 +295,14 @@ WXDWORD wxNotebook::MSWGetStyle(long style, WXDWORD *exstyle) const
|
|||||||
return tabStyle;
|
return tabStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxNotebook::~wxNotebook()
|
||||||
|
{
|
||||||
|
#if wxUSE_UXTHEME
|
||||||
|
if ( m_hbrBackground )
|
||||||
|
::DeleteObject((HBRUSH)m_hbrBackground);
|
||||||
|
#endif // wxUSE_UXTHEME
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxNotebook accessors
|
// wxNotebook accessors
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -571,27 +570,6 @@ bool wxNotebook::InsertPage(size_t nPage,
|
|||||||
wxASSERT_MSG( pPage->GetParent() == this,
|
wxASSERT_MSG( pPage->GetParent() == this,
|
||||||
_T("notebook pages must have notebook as parent") );
|
_T("notebook pages must have notebook as parent") );
|
||||||
|
|
||||||
#if wxUSE_UXTHEME && wxUSE_UXTHEME_AUTO
|
|
||||||
static bool g_TestedForTheme = false;
|
|
||||||
static bool g_UseTheme = false;
|
|
||||||
if (!g_TestedForTheme)
|
|
||||||
{
|
|
||||||
int commCtrlVersion = wxTheApp->GetComCtl32Version() ;
|
|
||||||
|
|
||||||
g_UseTheme = (commCtrlVersion >= 600);
|
|
||||||
g_TestedForTheme = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 (g_UseTheme && wxUxThemeEngine::Get() && pPage->IsKindOf(CLASSINFO(wxPanel)))
|
|
||||||
{
|
|
||||||
ApplyThemeBackground(pPage, GetThemeBackgroundColour());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// add a new tab to the control
|
// add a new tab to the control
|
||||||
// ----------------------------
|
// ----------------------------
|
||||||
|
|
||||||
@@ -743,6 +721,10 @@ void wxNotebook::OnSize(wxSizeEvent& event)
|
|||||||
pPage->SetSize(rc.left, rc.top, width, height);
|
pPage->SetSize(rc.left, rc.top, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_UXTHEME
|
||||||
|
UpdateBgBrush();
|
||||||
|
#endif // wxUSE_UXTHEME
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -877,6 +859,66 @@ void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_UXTHEME
|
||||||
|
|
||||||
|
void wxNotebook::UpdateBgBrush()
|
||||||
|
{
|
||||||
|
if ( m_hbrBackground )
|
||||||
|
::DeleteObject((HBRUSH)m_hbrBackground);
|
||||||
|
|
||||||
|
if ( wxUxThemeEngine::GetIfActive() )
|
||||||
|
{
|
||||||
|
RECT rc;
|
||||||
|
GetWindowRect(GetHwnd(), &rc);
|
||||||
|
|
||||||
|
WindowHDC hDC(GetHwnd());
|
||||||
|
MemoryHDC hDCMem(hDC);
|
||||||
|
CompatibleBitmap hBmp(hDC, rc.right - rc.left, rc.bottom - rc.top);
|
||||||
|
|
||||||
|
SelectInHDC selectBmp(hDCMem, hBmp);
|
||||||
|
|
||||||
|
SendMessage(GetHwnd(), WM_PRINTCLIENT, (WPARAM)(HDC)hDCMem,
|
||||||
|
PRF_ERASEBKGND | PRF_CLIENT | PRF_NONCLIENT);
|
||||||
|
|
||||||
|
m_hbrBackground = (WXHBRUSH)::CreatePatternBrush(hBmp);
|
||||||
|
}
|
||||||
|
else // no themes
|
||||||
|
{
|
||||||
|
m_hbrBackground = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxNotebook::DoEraseBackground(wxEraseEvent& event)
|
||||||
|
{
|
||||||
|
// we can either draw the background ourselves or let DrawThemeBackground()
|
||||||
|
// do it, but as we already have the correct brush, let's do it ourselves
|
||||||
|
// (note that we use the same code in wxControl::MSWControlColor(), so if
|
||||||
|
// it breaks, it should at least break in consistent way)
|
||||||
|
if ( m_hbrBackground )
|
||||||
|
{
|
||||||
|
// before drawing with the background brush, we need to position it
|
||||||
|
// correctly
|
||||||
|
wxWindow *win = (wxWindow *)event.GetEventObject();
|
||||||
|
|
||||||
|
RECT rc;
|
||||||
|
::GetWindowRect(GetHwndOf(win), &rc);
|
||||||
|
|
||||||
|
::MapWindowPoints(NULL, GetHwnd(), (POINT *)&rc, 1);
|
||||||
|
|
||||||
|
HDC hdc = GetHdcOf(*event.GetDC());
|
||||||
|
if ( !::SetBrushOrgEx(hdc, -rc.left, -rc.top, NULL) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("SetBrushOrgEx(notebook bg brush)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT rectClient;
|
||||||
|
::GetClientRect(GetHwndOf(win), &rectClient);
|
||||||
|
::FillRect(hdc, &rectClient, (HBRUSH)m_hbrBackground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_UXTHEME
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxNotebook base class virtuals
|
// wxNotebook base class virtuals
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -941,104 +983,4 @@ bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result)
|
|||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Windows only: attempts to get colour for UX theme page background
|
|
||||||
wxColour wxNotebook::GetThemeBackgroundColour()
|
|
||||||
{
|
|
||||||
#if wxUSE_UXTHEME
|
|
||||||
if (wxUxThemeEngine::Get())
|
|
||||||
{
|
|
||||||
wxUxThemeHandle hTheme(this, L"TAB");
|
|
||||||
if (hTheme)
|
|
||||||
{
|
|
||||||
// This is total guesswork.
|
|
||||||
// See PlatformSDK\Include\Tmschema.h for values
|
|
||||||
COLORREF themeColor;
|
|
||||||
wxUxThemeEngine::Get()->GetThemeColor(
|
|
||||||
hTheme,
|
|
||||||
10 /* TABP_BODY */,
|
|
||||||
1 /* NORMAL */,
|
|
||||||
3821 /* FILLCOLORHINT */,
|
|
||||||
&themeColor);
|
|
||||||
|
|
||||||
/*
|
|
||||||
[DS] Workaround for WindowBlinds:
|
|
||||||
Some themes return a near black theme color using FILLCOLORHINT,
|
|
||||||
this makes notebook pages have an ugly black background and makes
|
|
||||||
text (usually black) unreadable. Retry again with FILLCOLOR.
|
|
||||||
|
|
||||||
This workaround potentially breaks appearance of some themes,
|
|
||||||
but in practice it already fixes some themes.
|
|
||||||
*/
|
|
||||||
if (themeColor == 1)
|
|
||||||
{
|
|
||||||
wxUxThemeEngine::Get()->GetThemeColor(
|
|
||||||
hTheme,
|
|
||||||
10 /* TABP_BODY */,
|
|
||||||
1 /* NORMAL */,
|
|
||||||
3802 /* FILLCOLOR */,
|
|
||||||
&themeColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxColour colour(GetRValue(themeColor), GetGValue(themeColor), GetBValue(themeColor));
|
|
||||||
return colour;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // wxUSE_UXTHEME
|
|
||||||
|
|
||||||
return GetBackgroundColour();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Windows only: attempts to apply the UX theme page background to this page
|
|
||||||
#if wxUSE_UXTHEME
|
|
||||||
void wxNotebook::ApplyThemeBackground(wxWindow* window, const wxColour& colour)
|
|
||||||
#else
|
|
||||||
void wxNotebook::ApplyThemeBackground(wxWindow*, const wxColour&)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if wxUSE_UXTHEME
|
|
||||||
|
|
||||||
window->ApplyParentThemeBackground(colour);
|
|
||||||
|
|
||||||
for ( wxWindowList::compatibility_iterator node = window->GetChildren().GetFirst(); node; node = node->GetNext() )
|
|
||||||
{
|
|
||||||
wxWindow *child = node->GetData();
|
|
||||||
ApplyThemeBackground(child, colour);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if wxUSE_UXTHEME
|
|
||||||
WXLRESULT wxNotebook::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
|
||||||
{
|
|
||||||
static bool g_TestedForTheme = false;
|
|
||||||
static bool g_supportsThemes = false;
|
|
||||||
switch ( nMsg )
|
|
||||||
{
|
|
||||||
case WM_ERASEBKGND:
|
|
||||||
{
|
|
||||||
if (!g_TestedForTheme)
|
|
||||||
{
|
|
||||||
int commCtrlVersion = wxTheApp->GetComCtl32Version() ;
|
|
||||||
|
|
||||||
g_supportsThemes = (commCtrlVersion >= 600);
|
|
||||||
g_TestedForTheme = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If currently an XP theme is active, it seems we can get away
|
|
||||||
// with not drawing a background, which reduces flicker.
|
|
||||||
if (g_supportsThemes)
|
|
||||||
{
|
|
||||||
wxUxThemeEngine *p = wxUxThemeEngine::Get();
|
|
||||||
if (p && p->IsThemeActive() )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxControl::MSWWindowProc(nMsg, wParam, lParam);
|
|
||||||
}
|
|
||||||
#endif // #if wxUSE_UXTHEME
|
|
||||||
|
|
||||||
#endif // wxUSE_NOTEBOOK
|
#endif // wxUSE_NOTEBOOK
|
||||||
|
Reference in New Issue
Block a user