Add some additional renderer functions for Mac and MSW (so far) but do it as standalone functions in order to not disrupt the ABI. These are primarily needed for wxWebKit which is why they are going in to 2.8 instead of straight into 2.9 the proper way (as new methods of the wxRenderer* classes.)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@53524 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2008-05-10 00:05:20 +00:00
parent aae5ec8bbe
commit 95704802eb
4 changed files with 397 additions and 13 deletions

View File

@@ -406,4 +406,31 @@ wxRendererNative& wxRendererNative::GetDefault()
#endif // !wxHAS_NATIVE_RENDERER
// ----------------------------------------------------------------------------
// Other renderer functions to be merged in to wxRenderer class in 2.9, but
// they are standalone functions here to protect the ABI.
// ----------------------------------------------------------------------------
#if defined(__WXMSW__) || defined(__WXMAC__)
#if wxABI_VERSION >= 20804
// Draw a native wxChoice
void WXDLLEXPORT wxRenderer_DrawChoice(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags=0);
// Draw a native wxComboBox
void WXDLLEXPORT wxRenderer_DrawComboBox(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags=0);
// Draw a native wxTextCtrl frame
void WXDLLEXPORT wxRenderer_DrawTextCtrl(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags=0);
// Draw a native wxRadioButton (just the graphical portion)
void WXDLLEXPORT wxRenderer_DrawRadioButton(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags=0);
#endif // wxABI_VERSION
#endif // (platforms)
#endif // _WX_RENDERER_H_

View File

@@ -30,6 +30,18 @@
#include "wx/mac/uma.h"
// check if we're currently in a paint event
inline bool wxInPaintEvent(wxWindow* win, wxDC& dc)
{
#if wxMAC_USE_CORE_GRAPHICS
return ( win->MacGetCGContextRef() != NULL );
#else
return dc.IsKindOf( CLASSINFO(wxPaintDC) );
#endif
}
class WXDLLEXPORT wxRendererMac : public wxDelegateRendererNative
{
public:
@@ -88,6 +100,13 @@ private:
// the tree buttons
wxBitmap m_bmpTreeExpanded;
wxBitmap m_bmpTreeCollapsed;
friend void wxRenderer_DrawRadioButton(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags);
friend void wxRenderer_DrawChoice(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags);
friend void wxRenderer_DrawComboBox(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags);
};
// ============================================================================
@@ -125,7 +144,7 @@ int wxRendererMac::DrawHeaderButton( wxWindow *win,
dc.SetBrush( *wxTRANSPARENT_BRUSH );
HIRect headerRect = CGRectMake( x, y, w, h );
if ( !dc.IsKindOf( CLASSINFO( wxPaintDC ) ) )
if ( !wxInPaintEvent(win, dc) )
{
Rect r =
{
@@ -248,7 +267,7 @@ void wxRendererMac::DrawTreeItemButton( wxWindow *win,
dc.SetBrush( *wxTRANSPARENT_BRUSH );
HIRect headerRect = CGRectMake( x, y, w, h );
if ( !dc.IsKindOf( CLASSINFO( wxPaintDC ) ) )
if ( !wxInPaintEvent(win, dc) )
{
Rect r =
{
@@ -332,7 +351,7 @@ void wxRendererMac::DrawSplitterSash( wxWindow *win,
// under compositing we should only draw when called by the OS, otherwise just issue a redraw command
// strange redraw errors occur if we don't do this
if ( !dc.IsKindOf( CLASSINFO( wxPaintDC ) ) )
if ( !wxInPaintEvent(win, dc) )
{
Rect r =
{
@@ -421,7 +440,7 @@ wxRendererMac::DrawMacThemeButton(wxWindow *win,
dc.SetBrush( *wxTRANSPARENT_BRUSH );
HIRect headerRect = CGRectMake( x, y, w, h );
if ( !dc.IsKindOf( CLASSINFO( wxPaintDC ) ) )
if ( !wxInPaintEvent(win, dc) )
{
Rect r =
{
@@ -467,6 +486,8 @@ wxRendererMac::DrawMacThemeButton(wxWindow *win,
if (flags & wxCONTROL_UNDETERMINED)
drawInfo.value = kThemeButtonMixed;
drawInfo.adornment = adornment;
if (flags & wxCONTROL_FOCUSED)
drawInfo.adornment |= kThemeAdornmentFocus;
HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect );
}
@@ -484,11 +505,22 @@ wxRendererMac::DrawCheckBox(wxWindow *win,
const wxRect& rect,
int flags)
{
int kind;
if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL ||
(win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL))
kind = kThemeCheckBoxSmall;
else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI ||
(win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI))
kind = kThemeCheckBoxMini;
else
kind = kThemeCheckBox;
if (flags & wxCONTROL_CHECKED)
flags |= wxCONTROL_SELECTED;
DrawMacThemeButton(win, dc, rect, flags,
kThemeCheckBox, kThemeAdornmentNone);
kind, kThemeAdornmentNone);
}
void
@@ -530,3 +562,145 @@ wxRendererMac::DrawPushButton(wxWindow *win,
kind, kThemeAdornmentNone);
}
void wxRenderer_DrawChoice(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags)
{
wxRendererMac& r = (wxRendererMac&)wxRendererNative::Get();
int kind;
if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL ||
(win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL))
kind = kThemePopupButtonSmall;
else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI ||
(win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI))
kind = kThemePopupButtonMini;
else
kind = kThemePopupButton;
r.DrawMacThemeButton(win, dc, rect, flags, kind, kThemeAdornmentNone);
}
void wxRenderer_DrawComboBox(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags)
{
wxRendererMac& r = (wxRendererMac&)wxRendererNative::Get();
int kind;
if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL ||
(win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL))
kind = kThemeComboBoxSmall;
else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI ||
(win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI))
kind = kThemeComboBoxMini;
else
kind = kThemeComboBox;
r.DrawMacThemeButton(win, dc, rect, flags, kind, kThemeAdornmentNone);
}
void wxRenderer_DrawRadioButton(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags)
{
wxRendererMac& r = (wxRendererMac&)wxRendererNative::Get();
int kind;
if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL ||
(win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL))
kind = kThemeRadioButtonSmall;
else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI ||
(win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI))
kind = kThemeRadioButtonMini;
else
kind = kThemeRadioButton;
if (flags & wxCONTROL_CHECKED)
flags |= wxCONTROL_SELECTED;
r.DrawMacThemeButton(win, dc, rect, flags,
kind, kThemeAdornmentNone);
}
void wxRenderer_DrawTextCtrl(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags)
{
#if !wxMAC_USE_CORE_GRAPHICS
const wxCoord x = dc.LogicalToDeviceX(rect.x);
const wxCoord y = dc.LogicalToDeviceY(rect.y);
const wxCoord w = dc.LogicalToDeviceXRel(rect.width);
const wxCoord h = dc.LogicalToDeviceYRel(rect.height);
#else
// now the wxGCDC is using native transformations
const wxCoord x = rect.x;
const wxCoord y = rect.y;
const wxCoord w = rect.width;
const wxCoord h = rect.height;
#endif
dc.SetBrush( *wxWHITE_BRUSH );
dc.SetPen( *wxTRANSPARENT_PEN );
dc.DrawRectangle(rect);
dc.SetBrush( *wxTRANSPARENT_BRUSH );
HIRect hiRect = CGRectMake( x, y, w, h );
if ( !wxInPaintEvent(win, dc) )
{
Rect r =
{
(short) hiRect.origin.y, (short) hiRect.origin.x,
(short) (hiRect.origin.y + hiRect.size.height),
(short) (hiRect.origin.x + hiRect.size.width)
};
RgnHandle updateRgn = NewRgn();
RectRgn( updateRgn, &r );
HIViewSetNeedsDisplayInRegion( (HIViewRef) win->GetHandle(), updateRgn, true );
DisposeRgn( updateRgn );
}
else
{
CGContextRef cgContext;
#if wxMAC_USE_CORE_GRAPHICS
cgContext = (CGContextRef) dc.GetGraphicsContext()->GetNativeContext();
#else
Rect bounds;
GetPortBounds( (CGrafPtr) dc.m_macPort, &bounds );
QDBeginCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top );
CGContextScaleCTM( cgContext, 1, -1 );
HIShapeReplacePathInCGContext( HIShapeCreateWithQDRgn( (RgnHandle) dc.m_macCurrentClipRgn ), cgContext );
CGContextClip( cgContext );
HIViewConvertRect( &hiRect, (HIViewRef) win->GetHandle(), (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() );
#endif
{
HIThemeFrameDrawInfo drawInfo;
memset( &drawInfo, 0, sizeof(drawInfo) );
drawInfo.version = 0;
drawInfo.kind = kHIThemeFrameTextFieldSquare;
drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive;
if (flags & wxCONTROL_FOCUSED)
drawInfo.isFocused = true;
HIThemeDrawFrame( &hiRect, &drawInfo, cgContext, kHIThemeOrientationNormal);
}
#if wxMAC_USE_CORE_GRAPHICS
#else
QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
#endif
}
}

View File

@@ -36,11 +36,29 @@
#include "wx/msw/private.h"
#include "wx/msw/uxtheme.h"
#if wxUSE_GRAPHICS_CONTEXT
// TODO remove this dependency (gdiplus needs the macros)
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#include "gdiplus.h"
using namespace Gdiplus;
#endif
// tmschema.h is in Win32 Platform SDK and might not be available with earlier
// compilers
#ifndef CP_DROPDOWNBUTTON
#define BP_PUSHBUTTON 1
#define BP_RADIOBUTTON 2
#define BP_CHECKBOX 3
#define RBS_UNCHECKEDNORMAL 1
#define RBS_CHECKEDNORMAL (RBS_UNCHECKEDNORMAL + 4)
#define RBS_MIXEDNORMAL (RBS_CHECKEDNORMAL + 4)
#define CBS_UNCHECKEDNORMAL 1
#define CBS_CHECKEDNORMAL (CBS_UNCHECKEDNORMAL + 4)
#define CBS_MIXEDNORMAL (CBS_CHECKEDNORMAL + 4)
@@ -74,12 +92,64 @@
#define HP_HEADERSORTARROW 4
#define HSAS_SORTEDUP 1
#define HSAS_SORTEDDOWN 2
#define EP_EDITTEXT 1
#define ETS_NORMAL 1
#define ETS_HOT 2
#define ETS_SELECTED 3
#define ETS_DISABLED 4
#define ETS_FOCUSED 5
#define ETS_READONLY 6
#define ETS_ASSIST 7
#define TMT_FILLCOLOR 3802
#define TMT_TEXTCOLOR 3803
#define TMT_BORDERCOLOR 3801
#define TMT_EDGEFILLCOLOR 3808
#endif
#if defined(__WXWINCE__) && !defined(DFCS_FLAT)
#define DFCS_FLAT 0
#endif
// ----------------------------------------------------------------------------
// If the DC is a wxGCDC then pull out the HDC from the GraphicsContext when
// it is needed, and handle the Release when done.
class GraphicsHDC
{
public:
GraphicsHDC(wxDC* dc)
{
#if wxUSE_GRAPHICS_CONTEXT
m_graphics = NULL;
wxGCDC* gcdc = wxDynamicCast(dc, wxGCDC);
if (gcdc) {
m_graphics = (Graphics*)gcdc->GetGraphicsContext()->GetNativeContext();
m_hdc = m_graphics->GetHDC();
}
else
#endif
m_hdc = GetHdcOf(*dc);
}
~GraphicsHDC()
{
#if wxUSE_GRAPHICS_CONTEXT
if (m_graphics)
m_graphics->ReleaseHDC(m_hdc);
#endif
}
operator HDC() const { return m_hdc; }
private:
HDC m_hdc;
#if wxUSE_GRAPHICS_CONTEXT
Graphics* m_graphics;
#endif
};
// ----------------------------------------------------------------------------
// wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
// ----------------------------------------------------------------------------
@@ -203,7 +273,7 @@ wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
if ( flags & wxCONTROL_PRESSED )
style |= DFCS_PUSHED | DFCS_FLAT;
::DrawFrameControl(GetHdcOf(dc), &r, DFC_SCROLL, style);
::DrawFrameControl(GraphicsHDC(&dc), &r, DFC_SCROLL, style);
}
void
@@ -232,7 +302,7 @@ wxRendererMSW::DrawPushButton(wxWindow * WXUNUSED(win),
RECT rc;
wxCopyRectToRECT(rect, rc);
::DrawFrameControl(GetHdcOf(dc), &rc, DFC_BUTTON, style);
::DrawFrameControl(GraphicsHDC(&dc), &rc, DFC_BUTTON, style);
}
// ============================================================================
@@ -281,7 +351,7 @@ wxRendererXP::DrawComboBoxDropButton(wxWindow * win,
wxUxThemeEngine::Get()->DrawThemeBackground
(
hTheme,
GetHdcOf(dc),
GraphicsHDC(&dc),
CP_DROPDOWNBUTTON,
state,
&r,
@@ -317,7 +387,7 @@ wxRendererXP::DrawHeaderButton(wxWindow *win,
wxUxThemeEngine::Get()->DrawThemeBackground
(
hTheme,
GetHdcOf(dc),
GraphicsHDC(&dc),
HP_HEADERITEM,
state,
&r,
@@ -378,7 +448,7 @@ wxRendererXP::DrawTreeItemButton(wxWindow *win,
wxUxThemeEngine::Get()->DrawThemeBackground
(
hTheme,
GetHdcOf(dc),
GraphicsHDC(&dc),
TVP_GLYPH,
state,
&r,
@@ -421,7 +491,7 @@ wxRendererXP::DrawCheckBox(wxWindow *win,
wxUxThemeEngine::Get()->DrawThemeBackground
(
hTheme,
GetHdcOf(dc),
GraphicsHDC(&dc),
BP_CHECKBOX,
state,
&r,
@@ -429,6 +499,8 @@ wxRendererXP::DrawCheckBox(wxWindow *win,
);
}
void
wxRendererXP::DrawPushButton(wxWindow * win,
wxDC& dc,
@@ -460,13 +532,12 @@ wxRendererXP::DrawPushButton(wxWindow * win,
wxUxThemeEngine::Get()->DrawThemeBackground
(
hTheme,
GetHdcOf(dc),
GraphicsHDC(&dc),
BP_PUSHBUTTON,
state,
&r,
NULL
);
}
// ----------------------------------------------------------------------------
@@ -524,4 +595,115 @@ wxRendererXP::DrawSplitterSash(wxWindow *win,
m_rendererNative.DrawSplitterSash(win, dc, size, position, orient, flags);
}
// ----------------------------------------------------------------------------
// Other renderer functions to be merged in to wxRenderer class in 2.9, but
// they are standalone functions here to protect the ABI.
// ----------------------------------------------------------------------------
// Uses the theme to draw the border and fill for something like a wxTextCtrl
void wxRenderer_DrawTextCtrl(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
{
wxColour fill;
wxColour bdr;
COLORREF cref;
#if wxUSE_UXTHEME
wxUxThemeHandle hTheme(win, L"EDIT");
if (hTheme)
{
wxUxThemeEngine::Get()->GetThemeColor(hTheme, EP_EDITTEXT,
ETS_NORMAL, TMT_FILLCOLOR, &cref);
fill = wxRGBToColour(cref);
int etsState;
if ( flags & wxCONTROL_DISABLED )
etsState = ETS_DISABLED;
else
etsState = ETS_NORMAL;
wxUxThemeEngine::Get()->GetThemeColor(hTheme, EP_EDITTEXT,
etsState, TMT_BORDERCOLOR, &cref);
bdr = wxRGBToColour(cref);
}
else
#endif
{
fill = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
bdr = *wxBLACK;
}
dc.SetPen( bdr );
dc.SetBrush( fill );
dc.DrawRectangle(rect);
}
// Draw the equivallent of a wxComboBox
void wxRenderer_DrawComboBox(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
{
// Draw the main part of the control same as TextCtrl
wxRenderer_DrawTextCtrl(win, dc, rect, flags);
// Draw the button inside the border, on the right side
wxRect br(rect);
br.height -= 2;
br.x += br.width - br.height - 1;
br.width = br.height;
br.y += 1;
wxRendererNative::Get().DrawComboBoxDropButton(win, dc, br, flags);
}
void wxRenderer_DrawChoice(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags)
{
wxRenderer_DrawComboBox(win, dc, rect, flags);
}
// Draw a themed radio button
void wxRenderer_DrawRadioButton(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
{
#if wxUSE_UXTHEME
wxUxThemeHandle hTheme(win, L"BUTTON");
if ( !hTheme )
#endif
{
// ??? m_rendererNative.DrawRadioButton(win, dc, rect, flags);
return;
}
#if wxUSE_UXTHEME
RECT r;
wxCopyRectToRECT(rect, r);
int state;
if ( flags & wxCONTROL_CHECKED )
state = RBS_CHECKEDNORMAL;
else if ( flags & wxCONTROL_UNDETERMINED )
state = RBS_MIXEDNORMAL;
else
state = RBS_UNCHECKEDNORMAL;
// RBS_XXX is followed by RBX_XXXGOT, then RBS_XXXPRESSED and DISABLED
if ( flags & wxCONTROL_CURRENT )
state += 1;
else if ( flags & wxCONTROL_PRESSED )
state += 2;
else if ( flags & wxCONTROL_DISABLED )
state += 3;
wxUxThemeEngine::Get()->DrawThemeBackground
(
hTheme,
GraphicsHDC(&dc),
BP_RADIOBUTTON,
state,
&r,
NULL
);
#endif
}
#endif // wxUSE_UXTHEME

View File

@@ -33,6 +33,7 @@
*wxGridBagSizer*AdjustForOverflow*;
*wxRemotelyScrolledTreeCtrl*DoCalcScrolledPosition*;
*wxRemotelyScrolledTreeCtrl*SetScrollbar*;
*wxRenderer_Draw*;
*wxRichTextAction*CalculateRefreshOptimizations*;
*wxRichTextCtrl*GetTextCursor*;
*wxRichTextCtrl*GetURLCursor*;