Added wxRendererNative::DrawTitleBarBitmap().

This is currently only implemented for wxMSW as there is no advantage to use a
generic implementation compared to using wxArtProvider directly under the
other ports. But for MSW this allows to have perfectly natively looking
titlebar-like buttons.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62295 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2009-10-05 22:57:04 +00:00
parent 942d5e2d72
commit b50d93d1da
4 changed files with 232 additions and 31 deletions

View File

@ -41,6 +41,11 @@ class WXDLLIMPEXP_FWD_CORE wxWindow;
#undef wxHAS_NATIVE_RENDERER
#endif
// only MSW currently provides DrawTitleBarBitmap() method
#if defined(__WXMSW__)
#define wxHAS_DRAW_TITLE_BAR_BITMAP
#endif
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
@ -70,6 +75,19 @@ enum
wxCONTROL_DIRTY = 0x80000000
};
// title bar buttons supported by DrawTitleBarBitmap()
//
// NB: they have the same values as wxTOPLEVEL_BUTTON_XXX constants in
// wx/univ/toplevel.h as they really represent the same things
enum wxTitleBarButton
{
wxTITLEBAR_BUTTON_CLOSE = 0x01000000,
wxTITLEBAR_BUTTON_MAXIMIZE = 0x02000000,
wxTITLEBAR_BUTTON_ICONIZE = 0x04000000,
wxTITLEBAR_BUTTON_RESTORE = 0x08000000,
wxTITLEBAR_BUTTON_HELP = 0x10000000
};
// ----------------------------------------------------------------------------
// helper structs
// ----------------------------------------------------------------------------
@ -283,6 +301,21 @@ public:
const wxRect& rect,
int flags = 0) = 0;
#ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
// Draw one of the standard title bar buttons
//
// This is currently implemented only for MSW because there is no way to
// render standard title bar buttons under the other platforms, the best
// can be done is to use normal (only) images which wxArtProvider provides
// for wxART_HELP and wxART_CLOSE (but not any other title bar buttons)
virtual void DrawTitleBarBitmap(wxWindow *win,
wxDC& dc,
const wxRect& rect,
wxTitleBarButton button,
int flags = 0) = 0;
#endif // wxHAS_DRAW_TITLE_BAR_BITMAP
// geometry functions
// ------------------
@ -449,6 +482,15 @@ public:
int flags = 0)
{ m_rendererNative.DrawRadioBitmap(win, dc, rect, flags); }
#ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
virtual void DrawTitleBarBitmap(wxWindow *win,
wxDC& dc,
const wxRect& rect,
wxTitleBarButton button,
int flags = 0)
{ m_rendererNative.DrawTitleBarBitmap(win, dc, rect, button, flags); }
#endif // wxHAS_DRAW_TITLE_BAR_BITMAP
virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win)
{ return m_rendererNative.GetSplitterParams(win); }

View File

@ -193,6 +193,27 @@ private:
renderer.DrawTreeItemButton(this, dc,
wxRect(x2, y, 20, 20), m_flags);
y += lineHeight + 20;
#ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
dc.DrawText("DrawTitleBarBitmap()", x1, y);
wxRect rBtn(x2, y, 21, 21);
renderer.DrawTitleBarBitmap(this, dc, rBtn,
wxTITLEBAR_BUTTON_HELP, m_flags);
rBtn.x += 2*rBtn.width;
renderer.DrawTitleBarBitmap(this, dc, rBtn,
wxTITLEBAR_BUTTON_ICONIZE, m_flags);
rBtn.x += 2*rBtn.width;
renderer.DrawTitleBarBitmap(this, dc, rBtn,
wxTITLEBAR_BUTTON_RESTORE, m_flags);
rBtn.x += 2*rBtn.width;
renderer.DrawTitleBarBitmap(this, dc, rBtn,
wxTITLEBAR_BUTTON_MAXIMIZE, m_flags);
rBtn.x += 2*rBtn.width;
renderer.DrawTitleBarBitmap(this, dc, rBtn,
wxTITLEBAR_BUTTON_CLOSE, m_flags);
y += lineHeight + rBtn.height;
#endif // wxHAS_DRAW_TITLE_BAR_BITMAP
}
int m_flags;

View File

@ -120,6 +120,14 @@ public:
virtual void DrawRadioBitmap(wxWindow* win, wxDC& dc, const wxRect& rect, int flags=0);
#ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
virtual void DrawTitleBarBitmap(wxWindow *win,
wxDC& dc,
const wxRect& rect,
wxTitleBarButton button,
int flags = 0);
#endif // wxHAS_DRAW_TITLE_BAR_BITMAP
virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
virtual wxRendererVersion GetVersion() const
@ -751,7 +759,22 @@ void wxRendererGeneric::DrawTextCtrl(wxWindow* WXUNUSED(win), wxDC& WXUNUSED(dc)
wxFAIL_MSG("UNIMPLEMENTED: wxRendererGeneric::DrawTextCtrl");
}
#ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
void wxRendererGeneric::DrawTitleBarBitmap(wxWindow * WXUNUSED(win),
wxDC& WXUNUSED(dc),
const wxRect& WXUNUSED(rect),
wxTitleBarButton WXUNUSED(button),
int WXUNUSED(flags))
{
// no need to fail here, if wxHAS_DRAW_TITLE_BAR_BITMAP is defined this
// will be implemented in the native renderer and this version is never
// going to be used -- but we still need to define it to allow
// instantiation of this class (which would have been pure virtual
// otherwise)
}
#endif // wxHAS_DRAW_TITLE_BAR_BITMAP
// ----------------------------------------------------------------------------

View File

@ -92,6 +92,12 @@
#define TMT_TEXTCOLOR 3803
#define TMT_BORDERCOLOR 3801
#define TMT_EDGEFILLCOLOR 3808
#define WP_MINBUTTON 15
#define WP_MAXBUTTON 17
#define WP_CLOSEBUTTON 18
#define WP_RESTOREBUTTON 21
#define WP_HELPBUTTON 23
#endif
#if defined(__WXWINCE__)
@ -181,18 +187,35 @@ public:
DoDrawButton(DFCS_BUTTONRADIO, win, dc, rect, flags);
}
virtual void DrawTitleBarBitmap(wxWindow *win,
wxDC& dc,
const wxRect& rect,
wxTitleBarButton button,
int flags = 0);
virtual wxSize GetCheckBoxSize(wxWindow *win);
virtual int GetHeaderButtonHeight(wxWindow *win);
private:
// wrapper of DrawFrameControl()
void DoDrawFrameControl(UINT type,
UINT kind,
wxWindow *win,
wxDC& dc,
const wxRect& rect,
int flags);
// common part of Draw{PushButton,CheckBox,RadioBitmap}(): wraps
// DrawFrameControl(DFC_BUTTON)
void DoDrawButton(UINT kind,
wxWindow *win,
wxDC& dc,
const wxRect& rect,
int flags);
int flags)
{
DoDrawFrameControl(DFC_BUTTON, kind, win, dc, rect, flags);
}
wxDECLARE_NO_COPY_CLASS(wxRendererMSW);
};
@ -262,9 +285,24 @@ public:
m_rendererNative.DrawRadioBitmap(win, dc, rect, flags);
}
virtual void DrawTitleBarBitmap(wxWindow *win,
wxDC& dc,
const wxRect& rect,
wxTitleBarButton button,
int flags = 0);
virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
private:
// wrapper around DrawThemeBackground() translating flags to NORMAL/HOT/
// PUSHED/DISABLED states (and so suitable for drawing anything
// button-like)
void DoDrawButtonLike(HTHEME htheme,
int part,
wxDC& dc,
const wxRect& rect,
int flags);
// common part of DrawCheckBox(), DrawPushButton() and DrawRadioBitmap()
bool DoDrawXPButton(int kind,
wxWindow *win,
@ -367,11 +405,12 @@ wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
}
void
wxRendererMSW::DoDrawButton(UINT kind,
wxWindow * WXUNUSED(win),
wxDC& dc,
const wxRect& rect,
int flags)
wxRendererMSW::DoDrawFrameControl(UINT type,
UINT kind,
wxWindow * WXUNUSED(win),
wxDC& dc,
const wxRect& rect,
int flags)
{
RECT r;
wxCopyRectToRECT(rect, r);
@ -388,7 +427,7 @@ wxRendererMSW::DoDrawButton(UINT kind,
if ( flags & wxCONTROL_CURRENT )
style |= DFCS_HOT;
::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, DFC_BUTTON, style);
::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, type, style);
}
void
@ -411,6 +450,44 @@ wxRendererMSW::DrawPushButton(wxWindow *win,
DoDrawButton(DFCS_BUTTONPUSH, win, dc, rect, flags);
}
void
wxRendererMSW::DrawTitleBarBitmap(wxWindow *win,
wxDC& dc,
const wxRect& rect,
wxTitleBarButton button,
int flags)
{
UINT kind;
switch ( button )
{
case wxTITLEBAR_BUTTON_CLOSE:
kind = DFCS_CAPTIONCLOSE;
break;
case wxTITLEBAR_BUTTON_MAXIMIZE:
kind = DFCS_CAPTIONMAX;
break;
case wxTITLEBAR_BUTTON_ICONIZE:
kind = DFCS_CAPTIONMIN;
break;
case wxTITLEBAR_BUTTON_RESTORE:
kind = DFCS_CAPTIONRESTORE;
break;
case wxTITLEBAR_BUTTON_HELP:
kind = DFCS_CAPTIONHELP;
break;
default:
wxFAIL_MSG( "unsupported title bar button" );
return;
}
DoDrawFrameControl(DFC_CAPTION, kind, win, dc, rect, flags);
}
wxSize wxRendererMSW::GetCheckBoxSize(wxWindow * WXUNUSED(win))
{
return wxSize(::GetSystemMetrics(SM_CXMENUCHECK),
@ -638,29 +715,24 @@ wxRendererXP::DoDrawXPButton(int kind,
if ( !hTheme )
return false;
DoDrawButtonLike(hTheme, kind, dc, rect, flags);
return true;
}
void
wxRendererXP::DoDrawButtonLike(HTHEME htheme,
int part,
wxDC& dc,
const wxRect& rect,
int flags)
{
RECT r;
wxCopyRectToRECT(rect, r);
// determine the base state depending on the button kind
int state;
switch ( kind )
{
case BP_PUSHBUTTON:
state = PBS_NORMAL;
break;
case BP_RADIOBUTTON:
state = RBS_UNCHECKEDNORMAL;
break;
case BP_CHECKBOX:
state = CBS_UNCHECKEDNORMAL;
break;
default:
wxFAIL_MSG( "unknown button kind" );
return false;
}
// the base state is always 1, whether it is PBS_NORMAL,
// {CBS,RBS}_UNCHECKEDNORMAL or CBS_NORMAL
int state = 1;
// XBS_XXX is followed by XBX_XXXHOT, then XBS_XXXPRESSED and DISABLED
enum
@ -687,20 +759,63 @@ wxRendererXP::DoDrawXPButton(int kind,
else if ( flags & wxCONTROL_CURRENT )
state += HOT_OFFSET;
// wxCONTROL_ISDEFAULT flag is only valid for push buttons
else if ( kind == BP_PUSHBUTTON && (flags & wxCONTROL_ISDEFAULT) )
else if ( part == BP_PUSHBUTTON && (flags & wxCONTROL_ISDEFAULT) )
state = PBS_DEFAULTED;
wxUxThemeEngine::Get()->DrawThemeBackground
(
hTheme,
htheme,
GetHdcOf(dc.GetTempHDC()),
kind,
part,
state,
&r,
NULL
);
}
return true;
void
wxRendererXP::DrawTitleBarBitmap(wxWindow *win,
wxDC& dc,
const wxRect& rect,
wxTitleBarButton button,
int flags)
{
wxUxThemeHandle hTheme(win, L"WINDOW");
if ( !hTheme )
{
m_rendererNative.DrawTitleBarBitmap(win, dc, rect, button, flags);
return;
}
int part;
switch ( button )
{
case wxTITLEBAR_BUTTON_CLOSE:
part = WP_CLOSEBUTTON;
break;
case wxTITLEBAR_BUTTON_MAXIMIZE:
part = WP_MAXBUTTON;
break;
case wxTITLEBAR_BUTTON_ICONIZE:
part = WP_MINBUTTON;
break;
case wxTITLEBAR_BUTTON_RESTORE:
part = WP_RESTOREBUTTON;
break;
case wxTITLEBAR_BUTTON_HELP:
part = WP_HELPBUTTON;
break;
default:
wxFAIL_MSG( "unsupported title bar button" );
return;
}
DoDrawButtonLike(hTheme, part, dc, rect, flags);
}
// ----------------------------------------------------------------------------