added wxWindow::IsDoubleBuffered() and improve wxBufferedDC (patch 1565330)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41810 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-10-09 16:39:34 +00:00
parent af86380553
commit 2e992e06a7
29 changed files with 827 additions and 142 deletions

View File

@@ -569,6 +569,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/common/ctrlsub.cpp src/common/ctrlsub.cpp
src/common/datacmn.cpp src/common/datacmn.cpp
src/common/dcbase.cpp src/common/dcbase.cpp
src/common/dcbufcmn.cpp
src/common/dlgcmn.cpp src/common/dlgcmn.cpp
src/common/dndcmn.cpp src/common/dndcmn.cpp
src/common/dobjcmn.cpp src/common/dobjcmn.cpp

View File

@@ -76,6 +76,7 @@ All (GUI):
consistency with wxRichTextCtrl. consistency with wxRichTextCtrl.
- wxRichTextCtrl: fixed range out-by-one bug to be consistent with wxTextCtrl API, - wxRichTextCtrl: fixed range out-by-one bug to be consistent with wxTextCtrl API,
fixed some attribute bugs and added wxRichTextStyleComboCtrl. fixed some attribute bugs and added wxRichTextStyleComboCtrl.
- Added wxWindow::IsDoubleBuffered()
wxMSW: wxMSW:

View File

@@ -1495,6 +1495,19 @@ to the dialog via validators.
Resets the cached best size value so it will be recalculated the next time it is needed. Resets the cached best size value so it will be recalculated the next time it is needed.
\membersection{wxWindow::IsDoubleBuffered}\label{wxwindowisdoublebuffered}
\constfunc{virtual bool}{IsDoubleBuffered}{\void}
Returns \true if the window contents is double-buffered by the system, i.e. if
any drawing done on the window is really done on a temporary backing surface
and transferred to the screen all at once later.
\wxheading{See also}
\helpref{wxBufferedDC}{wxbuffereddc}
\membersection{wxWindow::IsEnabled}\label{wxwindowisenabled} \membersection{wxWindow::IsEnabled}\label{wxwindowisenabled}
\constfunc{virtual bool}{IsEnabled}{\void} \constfunc{virtual bool}{IsEnabled}{\void}

View File

@@ -199,6 +199,8 @@ public:
virtual bool Close( bool force = false ); virtual bool Close( bool force = false );
virtual bool Show( bool show = true ); virtual bool Show( bool show = true );
virtual bool Enable( bool enable = true ); virtual bool Enable( bool enable = true );
virtual bool IsDoubleBuffered() const { return true; }
}; };
#endif // __WX_COCOA_WINDOW_H__ #endif // __WX_COCOA_WINDOW_H__

View File

@@ -434,9 +434,6 @@ protected:
virtual void DoSetToolTip( wxToolTip *tip ); virtual void DoSetToolTip( wxToolTip *tip );
#endif #endif
// Used by OnPaints of derived classes
wxBitmap& GetBufferBitmap(const wxSize& sz) const;
// This is used when m_text is hidden (readonly). // This is used when m_text is hidden (readonly).
wxString m_valueString; wxString m_valueString;

View File

@@ -134,11 +134,6 @@ public:
virtual ~wxDCBase() { } virtual ~wxDCBase() { }
#if WXWIN_COMPATIBILITY_2_6
wxDEPRECATED( virtual void BeginDrawing() );
wxDEPRECATED( virtual void EndDrawing() );
#endif // WXWIN_COMPATIBILITY_2_6
// graphic primitives // graphic primitives
// ------------------ // ------------------
@@ -387,6 +382,12 @@ public:
virtual void StartPage() { } virtual void StartPage() { }
virtual void EndPage() { } virtual void EndPage() { }
#if WXWIN_COMPATIBILITY_2_6
wxDEPRECATED( void BeginDrawing() );
wxDEPRECATED( void EndDrawing() );
#endif // WXWIN_COMPATIBILITY_2_6
// set objects to use for drawing // set objects to use for drawing
// ------------------------------ // ------------------------------
@@ -503,20 +504,20 @@ public:
// accessors and setters // accessors and setters
// --------------------- // ---------------------
int GetBackgroundMode() const { return m_backgroundMode; } virtual int GetBackgroundMode() const { return m_backgroundMode; }
const wxBrush& GetBackground() const { return m_backgroundBrush; } virtual const wxBrush& GetBackground() const { return m_backgroundBrush; }
const wxBrush& GetBrush() const { return m_brush; } virtual const wxBrush& GetBrush() const { return m_brush; }
const wxFont& GetFont() const { return m_font; } virtual const wxFont& GetFont() const { return m_font; }
const wxPen& GetPen() const { return m_pen; } virtual const wxPen& GetPen() const { return m_pen; }
const wxColour& GetTextForeground() const { return m_textForegroundColour; } virtual const wxColour& GetTextForeground() const { return m_textForegroundColour; }
const wxColour& GetTextBackground() const { return m_textBackgroundColour; } virtual const wxColour& GetTextBackground() const { return m_textBackgroundColour; }
virtual void SetTextForeground(const wxColour& colour) virtual void SetTextForeground(const wxColour& colour)
{ m_textForegroundColour = colour; } { m_textForegroundColour = colour; }
virtual void SetTextBackground(const wxColour& colour) virtual void SetTextBackground(const wxColour& colour)
{ m_textBackgroundColour = colour; } { m_textBackgroundColour = colour; }
int GetMapMode() const { return m_mappingMode; } virtual int GetMapMode() const { return m_mappingMode; }
virtual void SetMapMode(int mode) = 0; virtual void SetMapMode(int mode) = 0;
virtual void GetUserScale(double *x, double *y) const virtual void GetUserScale(double *x, double *y) const
@@ -553,7 +554,7 @@ public:
virtual void SetAxisOrientation(bool xLeftRight, bool yBottomUp) = 0; virtual void SetAxisOrientation(bool xLeftRight, bool yBottomUp) = 0;
int GetLogicalFunction() const { return m_logicalFunction; } virtual int GetLogicalFunction() const { return m_logicalFunction; }
virtual void SetLogicalFunction(int function) = 0; virtual void SetLogicalFunction(int function) = 0;
#if WXWIN_COMPATIBILITY_2_4 #if WXWIN_COMPATIBILITY_2_4

View File

@@ -16,6 +16,29 @@
#include "wx/dcclient.h" #include "wx/dcclient.h"
#include "wx/window.h" #include "wx/window.h"
// I think this patch should be test on wxMac with
// wxTEST_PAINTDCDELEGATION as 1, and then with
// with wxTEST_MEMORYDCDELEGATION as 1.
#define wxTEST_PAINTDCDELEGATION 0
#define wxTEST_MEMORYDCDELEGATION 0
// Split platforms into two groups - those which have well-working
// double-buffering by default, and those which do not.
#if defined(__WXMAC__) || defined(__WXGTK20__)
#define wxALWAYS_NATIVE_DOUBLE_BUFFER 1
#else
#define wxALWAYS_NATIVE_DOUBLE_BUFFER 0
#endif
#if wxTEST_PAINTDCDELEGATION || wxTEST_MEMORYDCDELEGATION
#undef wxALWAYS_NATIVE_DOUBLE_BUFFER
#define wxALWAYS_NATIVE_DOUBLE_BUFFER 0
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Double buffering helper. // Double buffering helper.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -28,11 +51,12 @@
// does not prepare the window DC // does not prepare the window DC
#define wxBUFFER_CLIENT_AREA 0x02 #define wxBUFFER_CLIENT_AREA 0x02
class wxBufferedDC : public wxMemoryDC class WXDLLEXPORT wxBufferedDC : public wxDC
{ {
public: public:
// Default ctor, must subsequently call Init for two stage construction. // Default ctor, must subsequently call Init for two stage construction.
wxBufferedDC() : m_dc( 0 ), m_style(0) wxBufferedDC() : wxDC(), m_targetDc(NULL), m_mainDc(NULL),
m_buffer(NULL), m_style(0)
{ {
} }
@@ -40,23 +64,38 @@ public:
wxBufferedDC(wxDC *dc, wxBufferedDC(wxDC *dc,
const wxBitmap &buffer = wxNullBitmap, const wxBitmap &buffer = wxNullBitmap,
int style = wxBUFFER_CLIENT_AREA) int style = wxBUFFER_CLIENT_AREA)
: m_dc( dc ), : wxDC(),
m_buffer( buffer ), m_targetDc(NULL),
m_style(style) m_mainDc(NULL)
{ {
UseBuffer(); // All other members except dcs are initialized in Init
Init(dc, buffer, style);
} }
// Construct a wxBufferedDC with an internal buffer of 'area' // Construct a wxBufferedDC with an internal buffer of 'area'
// (where area is usually something like the size of the window // (where area is usually something like the size of the window
// being buffered) // being buffered)
wxBufferedDC(wxDC *dc, const wxSize &area, int style = wxBUFFER_CLIENT_AREA) wxBufferedDC(wxDC *dc, const wxSize &area, int style = wxBUFFER_CLIENT_AREA)
: m_dc( dc ), : wxDC(),
m_buffer( area.GetWidth(), area.GetHeight() ), m_targetDc(NULL),
m_style(style) m_mainDc(NULL)
{ {
UseBuffer(); // All other members except dcs are initialized in Init
Init(NULL, dc, area, style);
}
// Same, but also receives window to detect whether it is
// natively double-buffered.
wxBufferedDC(wxWindow* win,
wxDC *dc,
const wxSize &area,
int style = wxBUFFER_CLIENT_AREA)
: wxDC(),
m_targetDc(NULL),
m_mainDc(NULL)
{
// All other members except dcs are initialized in Init
Init(win, dc, area, style);
} }
// default copy ctor ok. // default copy ctor ok.
@@ -64,26 +103,55 @@ public:
// The usually desired action in the dtor is to blit the buffer. // The usually desired action in the dtor is to blit the buffer.
virtual ~wxBufferedDC() virtual ~wxBufferedDC()
{ {
if ( m_dc ) UnMask(); UnMask();
} }
// These reimplement the actions of the ctors for two stage creation, but
// are not used by the ctors themselves to save a few cpu cycles.
void Init(wxDC *dc, void Init(wxDC *dc,
const wxBitmap &buffer=wxNullBitmap, const wxBitmap &buffer,
int style = wxBUFFER_CLIENT_AREA) int style = wxBUFFER_CLIENT_AREA)
{ {
wxASSERT_MSG( m_dc == 0 && m_buffer == wxNullBitmap, wxASSERT_MSG( m_mainDc == NULL,
_T("wxBufferedDC already initialised") ); wxT("wxBufferedDC already initialised") );
m_dc = dc; wxASSERT_MSG( buffer.Ok(),
m_buffer = buffer; wxT("invalid bitmap") );
m_mainDc = dc;
m_buffer = &buffer;
m_style = style; m_style = style;
UseBuffer(); UseBuffer();
} }
void Init(wxDC *dc, const wxSize &area, int style = wxBUFFER_CLIENT_AREA) void Init(wxWindow* win,
wxDC *dc,
const wxSize &area = wxDefaultSize,
int style = wxBUFFER_CLIENT_AREA)
{ {
Init(dc, wxBitmap(area.GetWidth(), area.GetHeight()), style); wxASSERT_MSG( m_mainDc == NULL,
wxT("wxBufferedDC already initialised") );
m_mainDc = dc;
m_style = style;
#if wxTEST_MEMORYDCDELEGATION
if ( 0 )
#elif wxTEST_PAINTDCDELEGATION
if ( 1 )
#else
if ( win && win->IsDoubleBuffered() )
#endif
{
AttachDC(dc);
m_buffer = NULL;
}
else
{
PrepareBuffer(win, area);
UseBuffer();
}
}
void Init(wxDC *dc, const wxSize &area = wxDefaultSize, int style = wxBUFFER_CLIENT_AREA)
{
Init(NULL, dc, area, style);
} }
// Blits the buffer to the dc, and detaches the dc from the buffer (so it // Blits the buffer to the dc, and detaches the dc from the buffer (so it
@@ -92,54 +160,439 @@ public:
// Usually called in the dtor or by the dtor of derived classes if the // Usually called in the dtor or by the dtor of derived classes if the
// BufferedDC must blit before the derived class (which may own the dc it's // BufferedDC must blit before the derived class (which may own the dc it's
// blitting to) is destroyed. // blitting to) is destroyed.
void UnMask() void UnMask();
{
wxASSERT_MSG( m_dc != 0,
_T("No underlying DC associated with wxBufferedDC (anymore)") );
wxCoord x=0, y=0;
if (m_style & wxBUFFER_CLIENT_AREA)
GetDeviceOrigin(& x, & y);
m_dc->Blit( 0, 0,
m_buffer.GetWidth(), m_buffer.GetHeight(), this,
-x, -y );
m_dc = NULL;
}
// Set and get the style // Set and get the style
void SetStyle(int style) { m_style = style; } void SetStyle(int style) { m_style = style; }
int GetStyle() const { return m_style; } int GetStyle() const { return m_style; }
private: private:
// check that the bitmap is valid and use it // Prepares wxMemoryDC.
void UseBuffer() void UseBuffer();
{
if (!m_buffer.Ok())
{
wxCoord w, h;
m_dc->GetSize(&w, &h);
m_buffer = wxBitmap(w, h);
}
SelectObject(m_buffer); // Allocate m_buffer, if necessary.
} void PrepareBuffer(wxWindow* win, const wxSize& area);
// the underlying DC to which we copy everything drawn on this one in // DC to which calls are delegated.
// UnMask() wxDC* m_targetDc;
// This the underlying DC to which we copy everything drawn on
// this one in UnMask().
// //
// NB: Without the existence of a wxNullDC, this must be a pointer, else it // NB: Without the existence of a wxNullDC, this must be a pointer, else it
// could probably be a reference. // could probably be a reference.
wxDC *m_dc; wxDC* m_mainDc;
// the buffer (selected in this DC) // the buffer (selected in this DC)
wxBitmap m_buffer; const wxBitmap* m_buffer;
// the buffering style // the buffering style
int m_style; int m_style;
DECLARE_NO_COPY_CLASS(wxBufferedDC) DECLARE_NO_COPY_CLASS(wxBufferedDC)
public:
//
// BEGIN DC-DELEGATION IMPLEMENTATION
//
wxDC& GetAttachedDC()
{
return *m_targetDc;
}
// Use this to set the DC which receives delegated calls.
void AttachDC(wxDC* dc)
{
m_targetDc = dc;
#ifdef __WXMSW__
SetHDC( dc ? dc->GetHDC() : NULL );
#endif
}
// Sets DC to NULL
wxDC* DetachDC()
{
wxDC* retDc = m_targetDc;
AttachDC(NULL);
return retDc;
}
#ifdef __WXGTK__
virtual GdkWindow* GetGDKWindow() const
{
return m_targetDc->GetGDKWindow();
}
#endif
bool Blit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
wxDC *source, wxCoord xsrc, wxCoord ysrc,
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord)
{ return m_targetDc->Blit(xdest, ydest, width, height,
source, xsrc, ysrc, rop,
useMask, xsrcMask, ysrcMask); }
bool Blit(const wxPoint& destPt, const wxSize& sz,
wxDC *source, const wxPoint& srcPt,
int rop = wxCOPY, bool useMask = false, const wxPoint& srcPtMask = wxDefaultPosition)
{ return m_targetDc->Blit(destPt, sz, source, srcPt,
rop, useMask, srcPtMask); }
virtual void CalcBoundingBox(wxCoord x, wxCoord y) { m_targetDc->CalcBoundingBox(x, y); }
#if defined(__WXWINCE__)
void CalculateEllipticPoints( wxList* points,
wxCoord xStart, wxCoord yStart,
wxCoord w, wxCoord h,
double sa, double ea )
{ m_targetDc->CalculateEllipticPoints(points, xStart, yStart, w,
h, sa, ea); }
#endif // defined(__WXWINCE__)
virtual bool CanDrawBitmap() const { return m_targetDc->CanDrawBitmap(); }
virtual bool CanGetTextExtent() const { return m_targetDc->CanGetTextExtent(); }
virtual void Clear() { m_targetDc->Clear(); }
virtual void ComputeScaleAndOrigin() { m_targetDc->ComputeScaleAndOrigin(); }
void CrossHair(wxCoord x, wxCoord y) { m_targetDc->CrossHair(x, y); }
void CrossHair(const wxPoint& pt) { m_targetDc->CrossHair(pt); }
virtual void DestroyClippingRegion() { m_targetDc->DestroyClippingRegion(); }
wxCoord DeviceToLogicalX(wxCoord x) const { return m_targetDc->DeviceToLogicalX(x); }
wxCoord DeviceToLogicalXRel(wxCoord x) const { return m_targetDc->DeviceToLogicalXRel(x); }
wxCoord DeviceToLogicalY(wxCoord y) const { return m_targetDc->DeviceToLogicalY(y); }
wxCoord DeviceToLogicalYRel(wxCoord y) const { return m_targetDc->DeviceToLogicalYRel(y); }
#if defined(__WXWINCE__)
virtual void DoDrawEllipticArcRot( wxCoord x, wxCoord y,
wxCoord w, wxCoord h,
double sa = 0, double ea = 0, double angle = 0 )
{ m_targetDc->DoDrawEllipticArcRot(x, y, w, h,
sa, ea, angle); }
#endif // defined(__WXWINCE__)
void DrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
wxCoord xc, wxCoord yc)
{ m_targetDc->DrawArc(x1, y1, x2, y2,
xc, yc); }
void DrawArc(const wxPoint& pt1, const wxPoint& pt2, const wxPoint& centre)
{ m_targetDc->DrawArc(pt1, pt2, centre); }
void DrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
bool useMask = false)
{ m_targetDc->DrawBitmap(bmp, x, y, useMask); }
void DrawBitmap(const wxBitmap &bmp, const wxPoint& pt,
bool useMask = false)
{ m_targetDc->DrawBitmap(bmp, pt, useMask); }
void DrawCheckMark(wxCoord x, wxCoord y,
wxCoord width, wxCoord height)
{ m_targetDc->DrawCheckMark(x, y, width, height); }
void DrawCheckMark(const wxRect& rect) { m_targetDc->DrawCheckMark(rect); }
void DrawCircle(wxCoord x, wxCoord y, wxCoord radius) { m_targetDc->DrawCircle(x, y, radius); }
void DrawCircle(const wxPoint& pt, wxCoord radius) { m_targetDc->DrawCircle(pt, radius); }
void DrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{ m_targetDc->DrawEllipse(x, y, width, height); }
void DrawEllipse(const wxPoint& pt, const wxSize& sz) { m_targetDc->DrawEllipse(pt, sz); }
void DrawEllipse(const wxRect& rect) { m_targetDc->DrawEllipse(rect); }
void DrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
double sa, double ea)
{ m_targetDc->DrawEllipticArc(x, y, w, h,
sa, ea); }
void DrawEllipticArc(const wxPoint& pt, const wxSize& sz,
double sa, double ea)
{ m_targetDc->DrawEllipticArc(pt, sz, sa, ea); }
#if defined(__WXWINCE__)
void DrawEllipticArcRot( wxCoord x, wxCoord y,
wxCoord width, wxCoord height,
double sa = 0, double ea = 0, double angle = 0 )
{ m_targetDc->DrawEllipticArcRot(x, y, width, height,
sa, ea, angle); }
void DrawEllipticArcRot( const wxPoint& pt,
const wxSize& sz,
double sa = 0, double ea = 0, double angle = 0 )
{ m_targetDc->DrawEllipticArcRot(pt, sz, sa, ea,
angle); }
void DrawEllipticArcRot( const wxRect& rect,
double sa = 0, double ea = 0, double angle = 0 )
{ m_targetDc->DrawEllipticArcRot(rect, sa, ea, angle); }
#endif // defined(__WXWINCE__)
void DrawIcon(const wxIcon& icon, wxCoord x, wxCoord y) { m_targetDc->DrawIcon(icon, x, y); }
void DrawIcon(const wxIcon& icon, const wxPoint& pt) { m_targetDc->DrawIcon(icon, pt); }
virtual void DrawLabel(const wxString& text,
const wxBitmap& image,
const wxRect& rect,
int alignment = wxALIGN_LEFT | wxALIGN_TOP,
int indexAccel = -1,
wxRect *rectBounding = NULL)
{ m_targetDc->DrawLabel(text, image, rect, alignment,
indexAccel, rectBounding); }
void DrawLabel(const wxString& text, const wxRect& rect,
int alignment = wxALIGN_LEFT | wxALIGN_TOP,
int indexAccel = -1)
{ m_targetDc->DrawLabel(text, rect, alignment, indexAccel); }
void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
{ m_targetDc->DrawLine(x1, y1, x2, y2); }
void DrawLine(const wxPoint& pt1, const wxPoint& pt2) { m_targetDc->DrawLine(pt1, pt2); }
void DrawLines(int n, wxPoint points[],
wxCoord xoffset = 0, wxCoord yoffset = 0)
{ m_targetDc->DrawLines(n, points, xoffset, yoffset); }
void DrawLines(const wxList *list,
wxCoord xoffset = 0, wxCoord yoffset = 0)
{ m_targetDc->DrawLines(list, xoffset, yoffset); }
virtual void DrawObject(wxDrawObject* drawobject) { m_targetDc->DrawObject(drawobject); }
void DrawPoint(wxCoord x, wxCoord y) { m_targetDc->DrawPoint(x, y); }
void DrawPoint(const wxPoint& pt) { m_targetDc->DrawPoint(pt); }
void DrawPolyPolygon(int n, int count[], wxPoint points[],
wxCoord xoffset = 0, wxCoord yoffset = 0,
int fillStyle = wxODDEVEN_RULE)
{ m_targetDc->DrawPolyPolygon(n, count, points, xoffset,
yoffset, fillStyle); }
void DrawPolygon(int n, wxPoint points[],
wxCoord xoffset = 0, wxCoord yoffset = 0,
int fillStyle = wxODDEVEN_RULE)
{ m_targetDc->DrawPolygon(n, points, xoffset, yoffset,
fillStyle); }
void DrawPolygon(const wxList *list,
wxCoord xoffset = 0, wxCoord yoffset = 0,
int fillStyle = wxODDEVEN_RULE)
{ m_targetDc->DrawPolygon(list, xoffset, yoffset, fillStyle); }
void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{ m_targetDc->DrawRectangle(x, y, width, height); }
void DrawRectangle(const wxPoint& pt, const wxSize& sz) { m_targetDc->DrawRectangle(pt, sz); }
void DrawRectangle(const wxRect& rect) { m_targetDc->DrawRectangle(rect); }
void DrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
{ m_targetDc->DrawRotatedText(text, x, y, angle); }
void DrawRotatedText(const wxString& text, const wxPoint& pt, double angle)
{ m_targetDc->DrawRotatedText(text, pt, angle); }
void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height,
double radius)
{ m_targetDc->DrawRoundedRectangle(x, y, width, height,
radius); }
void DrawRoundedRectangle(const wxPoint& pt, const wxSize& sz,
double radius)
{ m_targetDc->DrawRoundedRectangle(pt, sz, radius); }
void DrawRoundedRectangle(const wxRect& r, double radius)
{ m_targetDc->DrawRoundedRectangle(r, radius); }
#if wxUSE_SPLINES
void DrawSpline(wxCoord x1, wxCoord y1,
wxCoord x2, wxCoord y2,
wxCoord x3, wxCoord y3)
{ m_targetDc->DrawSpline(x1, y1, x2, y2,
x3, y3); }
void DrawSpline(int n, wxPoint points[]) { m_targetDc->DrawSpline(n, points); }
void DrawSpline(wxList *points) { m_targetDc->DrawSpline(points); }
#endif // wxUSE_SPLINES
void DrawText(const wxString& text, wxCoord x, wxCoord y)
{ m_targetDc->DrawText(text, x, y); }
void DrawText(const wxString& text, const wxPoint& pt) { m_targetDc->DrawText(text, pt); }
virtual void EndDoc() { m_targetDc->EndDoc(); }
virtual void EndPage() { m_targetDc->EndPage(); }
bool FloodFill(wxCoord x, wxCoord y, const wxColour& col,
int style = wxFLOOD_SURFACE)
{ return m_targetDc->FloodFill(x, y, col, style); }
bool FloodFill(const wxPoint& pt, const wxColour& col,
int style = wxFLOOD_SURFACE)
{ return m_targetDc->FloodFill(pt, col, style); }
virtual const wxBrush& GetBackground() const { return m_targetDc->GetBackground(); }
virtual int GetBackgroundMode() const { return m_targetDc->GetBackgroundMode(); }
virtual const wxBrush& GetBrush() const { return m_targetDc->GetBrush(); }
virtual wxCoord GetCharHeight() const { return m_targetDc->GetCharHeight(); }
virtual wxCoord GetCharWidth() const { return m_targetDc->GetCharWidth(); }
void GetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const
{ m_targetDc->GetClippingBox(x, y, w, h); }
void GetClippingBox(wxRect& rect) const { m_targetDc->GetClippingBox(rect); }
void GetClippingBox(long *x, long *y, long *w, long *h) const
{ m_targetDc->GetClippingBox(x, y, w, h); }
virtual int GetDepth() const { return m_targetDc->GetDepth(); }
void GetDeviceOrigin(wxCoord *x, wxCoord *y) const { m_targetDc->GetDeviceOrigin(x, y); }
wxPoint GetDeviceOrigin() const { return m_targetDc->GetDeviceOrigin(); }
void GetDeviceOrigin(long *x, long *y) const { m_targetDc->GetDeviceOrigin(x, y); }
virtual const wxFont& GetFont() const { return m_targetDc->GetFont(); }
virtual int GetLogicalFunction() const { return m_targetDc->GetLogicalFunction(); }
void GetLogicalOrigin(wxCoord *x, wxCoord *y) const { m_targetDc->GetLogicalOrigin(x, y); }
wxPoint GetLogicalOrigin() const { return m_targetDc->GetLogicalOrigin(); }
void GetLogicalOrigin(long *x, long *y) const { m_targetDc->GetLogicalOrigin(x, y); }
virtual void GetLogicalScale(double *x, double *y) { m_targetDc->GetLogicalScale(x, y); }
virtual int GetMapMode() const { return m_targetDc->GetMapMode(); }
virtual void GetMultiLineTextExtent(const wxString& text,
wxCoord *width,
wxCoord *height,
wxCoord *heightLine = NULL,
wxFont *font = NULL)
{ m_targetDc->GetMultiLineTextExtent(text, width, height, heightLine,
font); }
#if WXWIN_COMPATIBILITY_2_4
virtual bool GetOptimization() { return m_targetDc->GetOptimization(); }
#endif // WXWIN_COMPATIBILITY_2_4
virtual wxSize GetPPI() const { return m_targetDc->GetPPI(); }
bool GetPartialTextExtents(const wxString& text, wxArrayInt& widths) const
{ return m_targetDc->GetPartialTextExtents(text, widths); }
virtual const wxPen& GetPen() const { return m_targetDc->GetPen(); }
bool GetPixel(wxCoord x, wxCoord y, wxColour *col) const
{ return m_targetDc->GetPixel(x, y, col); }
bool GetPixel(const wxPoint& pt, wxColour *col) const { return m_targetDc->GetPixel(pt, col); }
void GetSize(int *width, int *height) const { m_targetDc->GetSize(width, height); }
wxSize GetSize() const { return m_targetDc->GetSize(); }
void GetSizeMM(int* width, int* height) const { m_targetDc->GetSizeMM(width, height); }
wxSize GetSizeMM() const { return m_targetDc->GetSizeMM(); }
virtual const wxColour& GetTextBackground() const { return m_targetDc->GetTextBackground(); }
void GetTextExtent(const wxString& string,
wxCoord *x, wxCoord *y,
wxCoord *descent = NULL,
wxCoord *externalLeading = NULL,
wxFont *theFont = NULL) const
{ m_targetDc->GetTextExtent(string, x, y, descent,
externalLeading, theFont); }
void GetTextExtent(const wxString& string,
long *x, long *y,
long *descent = NULL,
long *externalLeading = NULL,
wxFont *theFont = NULL) const
{ m_targetDc->GetTextExtent(string, x, y, descent,
externalLeading, theFont); }
virtual const wxColour& GetTextForeground() const { return m_targetDc->GetTextForeground(); }
virtual void GetUserScale(double *x, double *y) const { m_targetDc->GetUserScale(x, y); }
void GradientFillConcentric(const wxRect& rect,
const wxColour& initialColour,
const wxColour& destColour)
{ m_targetDc->GradientFillConcentric(rect, initialColour, destColour); }
void GradientFillConcentric(const wxRect& rect,
const wxColour& initialColour,
const wxColour& destColour,
const wxPoint& circleCenter)
{ m_targetDc->GradientFillConcentric(rect, initialColour, destColour, circleCenter); }
void GradientFillLinear(const wxRect& rect,
const wxColour& initialColour,
const wxColour& destColour,
wxDirection nDirection = wxEAST)
{ m_targetDc->GradientFillLinear(rect, initialColour, destColour, nDirection); }
wxCoord LogicalToDeviceX(wxCoord x) const { return m_targetDc->LogicalToDeviceX(x); }
wxCoord LogicalToDeviceXRel(wxCoord x) const { return m_targetDc->LogicalToDeviceXRel(x); }
wxCoord LogicalToDeviceY(wxCoord y) const { return m_targetDc->LogicalToDeviceY(y); }
wxCoord LogicalToDeviceYRel(wxCoord y) const { return m_targetDc->LogicalToDeviceYRel(y); }
wxCoord MaxX() const { return m_targetDc->MaxX(); }
wxCoord MaxY() const { return m_targetDc->MaxY(); }
wxCoord MinX() const { return m_targetDc->MinX(); }
wxCoord MinY() const { return m_targetDc->MinY(); }
virtual bool Ok() const { return m_targetDc->Ok(); }
void ResetBoundingBox()
{ m_targetDc->ResetBoundingBox(); }
#if defined(__WXWINCE__)
void Rotate( wxList* points, double angle, wxPoint center = wxPoint(0,0) )
{ m_targetDc->Rotate(points, angle, center, 0)); }
#endif // defined(__WXWINCE__)
virtual void SetAxisOrientation(bool xLeftRight, bool yBottomUp)
{ m_targetDc->SetAxisOrientation(xLeftRight, yBottomUp); }
virtual void SetBackground(const wxBrush& brush) { m_targetDc->SetBackground(brush); }
virtual void SetBackgroundMode(int mode) { m_targetDc->SetBackgroundMode(mode); }
virtual void SetBrush(const wxBrush& brush) { m_targetDc->SetBrush(brush); }
void SetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{ m_targetDc->SetClippingRegion(x, y, width, height); }
void SetClippingRegion(const wxPoint& pt, const wxSize& sz)
{ m_targetDc->SetClippingRegion(pt, sz); }
void SetClippingRegion(const wxRect& rect) { m_targetDc->SetClippingRegion(rect); }
void SetClippingRegion(const wxRegion& region) { m_targetDc->SetClippingRegion(region); }
virtual void SetDeviceOrigin(wxCoord x, wxCoord y) { m_targetDc->SetDeviceOrigin(x, y); }
virtual void SetFont(const wxFont& font) { m_targetDc->SetFont(font); }
virtual void SetLogicalFunction(int function) { m_targetDc->SetLogicalFunction(function); }
virtual void SetLogicalOrigin(wxCoord x, wxCoord y) { m_targetDc->SetLogicalOrigin(x, y); }
virtual void SetLogicalScale(double x, double y) { m_targetDc->SetLogicalScale(x, y); }
virtual void SetMapMode(int mode) { m_targetDc->SetMapMode(mode); }
#if WXWIN_COMPATIBILITY_2_4
virtual void SetOptimization(bool opt) { m_targetDc->SetOptimization(opt); }
#endif // WXWIN_COMPATIBILITY_2_4
#if wxUSE_PALETTE
virtual void SetPalette(const wxPalette& palette) { m_targetDc->SetPalette(palette); }
#endif // wxUSE_PALETTE
virtual void SetPen(const wxPen& pen) { m_targetDc->SetPen(pen); }
virtual void SetTextBackground(const wxColour& colour) { m_targetDc->SetTextBackground(colour); }
virtual void SetTextForeground(const wxColour& colour) { m_targetDc->SetTextForeground(colour); }
virtual void SetUserScale(double x, double y) { m_targetDc->SetUserScale(x, y); }
virtual bool StartDoc(const wxString& message) { return m_targetDc->StartDoc(message); }
virtual void StartPage() { m_targetDc->StartPage(); }
protected:
virtual bool DoBlit(wxCoord xdest, wxCoord ydest,
wxCoord width, wxCoord height,
wxDC *source, wxCoord xsrc, wxCoord ysrc,
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord)
{ return m_targetDc->Blit(xdest, ydest, width, height,
source, xsrc, ysrc, rop,
useMask, xsrcMask, ysrcMask); }
virtual void DoCrossHair(wxCoord x, wxCoord y) { m_targetDc->CrossHair(x, y); }
virtual void DoDrawArc(wxCoord x1, wxCoord y1,
wxCoord x2, wxCoord y2,
wxCoord xc, wxCoord yc)
{ m_targetDc->DrawArc(x1, y1, x2, y2,
xc, yc); }
virtual void DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
bool useMask = false)
{ m_targetDc->DrawBitmap(bmp, x, y, useMask); }
virtual void DoDrawCheckMark(wxCoord x, wxCoord y,
wxCoord width, wxCoord height)
{ m_targetDc->DrawCheckMark(x, y, width, height); }
virtual void DoDrawEllipse(wxCoord x, wxCoord y,
wxCoord width, wxCoord height)
{ m_targetDc->DrawEllipse(x, y, width, height); }
virtual void DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
double sa, double ea)
{ m_targetDc->DrawEllipticArc(x, y, w, h,
sa, ea); }
virtual void DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
{ m_targetDc->DrawIcon(icon, x, y); }
virtual void DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
{ m_targetDc->DrawLine(x1, y1, x2, y2); }
virtual void DoDrawLines(int n, wxPoint points[],
wxCoord xoffset, wxCoord yoffset)
{ m_targetDc->DrawLines(n, points, xoffset, yoffset); }
virtual void DoDrawPoint(wxCoord x, wxCoord y) { m_targetDc->DrawPoint(x, y); }
virtual void DoDrawPolyPolygon(int n, int count[], wxPoint points[],
wxCoord xoffset, wxCoord yoffset,
int fillStyle)
{ m_targetDc->DrawPolyPolygon(n, count, points, xoffset,
yoffset, fillStyle); }
virtual void DoDrawPolygon(int n, wxPoint points[],
wxCoord xoffset, wxCoord yoffset,
int fillStyle = wxODDEVEN_RULE)
{ m_targetDc->DrawPolygon(n, points, xoffset, yoffset,
fillStyle); }
virtual void DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{ m_targetDc->DrawRectangle(x, y, width, height); }
virtual void DoDrawRotatedText(const wxString& text,
wxCoord x, wxCoord y, double angle)
{ m_targetDc->DrawRotatedText(text, x, y, angle); }
virtual void DoDrawRoundedRectangle(wxCoord x, wxCoord y,
wxCoord width, wxCoord height,
double radius)
{ m_targetDc->DrawRoundedRectangle(x, y, width, height,
radius); }
#if wxUSE_SPLINES
virtual void DoDrawSpline(wxList *points) { m_targetDc->DrawSpline(points); }
#endif // wxUSE_SPLINES
virtual void DoDrawText(const wxString& text, wxCoord x, wxCoord y)
{ m_targetDc->DrawText(text, x, y); }
virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col,
int style = wxFLOOD_SURFACE)
{ return m_targetDc->FloodFill(x, y, col, style); }
virtual void DoGetClippingBox(wxCoord *x, wxCoord *y,
wxCoord *w, wxCoord *h) const
{ m_targetDc->GetClippingBox(x, y, w, h); }
virtual void DoGetDeviceOrigin(wxCoord *x, wxCoord *y) const
{ m_targetDc->GetDeviceOrigin(x, y); }
virtual void DoGetLogicalOrigin(wxCoord *x, wxCoord *y) const
{ m_targetDc->GetLogicalOrigin(x, y); }
virtual bool DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const
{ return m_targetDc->GetPartialTextExtents(text, widths); }
virtual bool DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
{ return m_targetDc->GetPixel(x, y, col); }
virtual void DoGetSize(int *width, int *height) const { m_targetDc->GetSize(width, height); }
virtual void DoGetSizeMM(int* width, int* height) const { m_targetDc->GetSizeMM(width, height); }
virtual void DoGetTextExtent(const wxString& string,
wxCoord *x, wxCoord *y,
wxCoord *descent = NULL,
wxCoord *externalLeading = NULL,
wxFont *theFont = NULL) const
{ m_targetDc->GetTextExtent(string, x, y, descent,
externalLeading, theFont); }
virtual void DoGradientFillLinear(const wxRect& rect,
const wxColour& initialColour,
const wxColour& destColour,
wxDirection nDirection = wxEAST)
{ m_targetDc->GradientFillLinear(rect, initialColour, destColour, nDirection); }
virtual void DoSetClippingRegion(wxCoord x, wxCoord y,
wxCoord width, wxCoord height)
{ m_targetDc->SetClippingRegion(x, y, width, height); }
virtual void DoSetClippingRegionAsRegion(const wxRegion& region)
{ m_targetDc->SetClippingRegion(region); }
}; };
@@ -163,7 +616,7 @@ public:
if( buffer != wxNullBitmap ) if( buffer != wxNullBitmap )
Init(&m_paintdc, buffer, style); Init(&m_paintdc, buffer, style);
else else
Init(&m_paintdc, window->GetClientSize(), style); Init(window, &m_paintdc, window->GetClientSize(), style);
} }
// If no bitmap is supplied by the user, a temporary one will be created. // If no bitmap is supplied by the user, a temporary one will be created.
@@ -174,7 +627,7 @@ public:
if (style & wxBUFFER_VIRTUAL_AREA) if (style & wxBUFFER_VIRTUAL_AREA)
window->PrepareDC( m_paintdc ); window->PrepareDC( m_paintdc );
Init(&m_paintdc, window->GetClientSize(), style); Init(window, &m_paintdc, window->GetClientSize(), style);
} }
// default copy ctor ok. // default copy ctor ok.
@@ -192,5 +645,54 @@ private:
DECLARE_NO_COPY_CLASS(wxBufferedPaintDC) DECLARE_NO_COPY_CLASS(wxBufferedPaintDC)
}; };
#endif // _WX_DCBUFFER_H_
//
// wxAutoBufferedPaintDC is a wxPaintDC in toolkits which have double-
// buffering by default. Otherwise it is a wxBufferedPaintDC. Thus,
// you can only expect it work with a simple constructor that
// accepts single wxWindow* argument.
//
#if wxALWAYS_NATIVE_DOUBLE_BUFFER
#define wxAutoBufferedPaintDCBase wxPaintDC
#else
#define wxAutoBufferedPaintDCBase wxBufferedPaintDC
#endif
#ifdef __WXDEBUG__
class wxAutoBufferedPaintDC : public wxAutoBufferedPaintDCBase
{
public:
wxAutoBufferedPaintDC(wxWindow* win)
: wxAutoBufferedPaintDCBase(win)
{
TestWinStyle(win);
}
virtual ~wxAutoBufferedPaintDC() { }
private:
void TestWinStyle(wxWindow* win)
{
// Help the user to get the double-buffering working properly.
wxASSERT_MSG( win->GetBackgroundStyle() == wxBG_STYLE_CUSTOM,
wxT("In constructor, you need to call GetBackgroundStyle(wxBG_STYLE_CUSTOM), ")
wxT("and also, if needed, paint the background manually in the paint event handler."));
}
DECLARE_NO_COPY_CLASS(wxAutoBufferedPaintDC)
};
#else // !__WXDEBUG__
// In release builds, just use typedef
typedef wxAutoBufferedPaintDCBase wxAutoBufferedPaintDC;
#endif
#endif // _WX_DCBUFFER_H_

View File

@@ -109,6 +109,8 @@ public:
void OnInternalIdle(); void OnInternalIdle();
virtual bool IsDoubleBuffered() const { return true; }
protected: protected:
// implement the base class pure virtuals // implement the base class pure virtuals
virtual void DoClientToScreen(int *x, int *y) const; virtual void DoClientToScreen(int *x, int *y) const;

View File

@@ -94,6 +94,8 @@ public:
virtual void ComputeScaleAndOrigin(); virtual void ComputeScaleAndOrigin();
virtual GdkWindow* GetGDKWindow() const { return NULL; }
protected: protected:
// implementation // implementation
// -------------- // --------------

View File

@@ -99,6 +99,8 @@ public:
virtual void SetDeviceOrigin( wxCoord x, wxCoord y ); virtual void SetDeviceOrigin( wxCoord x, wxCoord y );
virtual void SetAxisOrientation( bool xLeftRight, bool yBottomUp ); virtual void SetAxisOrientation( bool xLeftRight, bool yBottomUp );
virtual GdkWindow* GetGDKWindow() const { return m_window; }
// protected: // protected:
// implementation // implementation
// -------------- // --------------

View File

@@ -124,6 +124,7 @@ public:
// currently wxGTK2-only // currently wxGTK2-only
void SetDoubleBuffered(bool on); void SetDoubleBuffered(bool on);
virtual bool IsDoubleBuffered() const;
// implementation // implementation
// -------------- // --------------

View File

@@ -66,6 +66,8 @@ public:
virtual void ComputeScaleAndOrigin(); virtual void ComputeScaleAndOrigin();
virtual GdkWindow* GetGDKWindow() const { return NULL; }
wxCoord XDEV2LOG(wxCoord x) const wxCoord XDEV2LOG(wxCoord x) const
{ {
wxCoord new_x = x - m_deviceOriginX; wxCoord new_x = x - m_deviceOriginX;

View File

@@ -100,6 +100,8 @@ public:
virtual wxSize GetPPI() const; virtual wxSize GetPPI() const;
virtual int GetDepth() const; virtual int GetDepth() const;
virtual GdkWindow* GetGDKWindow() const { return m_window; }
// implementation // implementation
// -------------- // --------------

View File

@@ -108,6 +108,8 @@ public:
virtual void SetDropTarget( wxDropTarget *dropTarget ); virtual void SetDropTarget( wxDropTarget *dropTarget );
#endif // wxUSE_DRAG_AND_DROP #endif // wxUSE_DRAG_AND_DROP
virtual bool IsDoubleBuffered() const { return false; }
// implementation // implementation
// -------------- // --------------

View File

@@ -142,6 +142,8 @@ public:
bool AcceptsFocus() const; bool AcceptsFocus() const;
virtual bool IsDoubleBuffered() const { return true; }
public: public:
static long MacRemoveBordersFromStyle( long style ) ; static long MacRemoveBordersFromStyle( long style ) ;

View File

@@ -126,6 +126,10 @@
#define WS_EX_LAYOUTRTL 0x00400000 #define WS_EX_LAYOUTRTL 0x00400000
#endif #endif
#ifndef WS_EX_COMPOSITED
#define WS_EX_COMPOSITED 0x02000000L
#endif
#ifndef WS_EX_LAYERED #ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x00080000 #define WS_EX_LAYERED 0x00080000
#endif #endif

View File

@@ -420,6 +420,9 @@ public:
// check if mouse is in the window // check if mouse is in the window
bool IsMouseInWindow() const; bool IsMouseInWindow() const;
// check if a native double-buffering applies for this window
virtual bool IsDoubleBuffered() const;
// synthesize a wxEVT_LEAVE_WINDOW event and set m_mouseInWindow to false // synthesize a wxEVT_LEAVE_WINDOW event and set m_mouseInWindow to false
void GenerateMouseLeave(); void GenerateMouseLeave();

View File

@@ -287,9 +287,6 @@ private:
// the selection bg colour // the selection bg colour
wxColour m_colBgSel; wxColour m_colBgSel;
// double buffer
wxBitmap* m_doubleBuffer;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxVListBox) DECLARE_NO_COPY_CLASS(wxVListBox)
DECLARE_ABSTRACT_CLASS(wxVListBox) DECLARE_ABSTRACT_CLASS(wxVListBox)

View File

@@ -725,6 +725,9 @@ public:
// adjust DC for drawing on this window // adjust DC for drawing on this window
virtual void PrepareDC( wxDC & WXUNUSED(dc) ) { } virtual void PrepareDC( wxDC & WXUNUSED(dc) ) { }
// return true if the window contents is double buffered by the system
virtual bool IsDoubleBuffered() const { return false; }
// the update region of the window contains the areas which must be // the update region of the window contains the areas which must be
// repainted by the program // repainted by the program
const wxRegion& GetUpdateRegion() const { return m_updateRegion; } const wxRegion& GetUpdateRegion() const { return m_updateRegion; }

View File

@@ -35,7 +35,6 @@
#include "wx/timer.h" #include "wx/timer.h"
#endif #endif
#include "wx/dcbuffer.h"
#include "wx/tooltip.h" #include "wx/tooltip.h"
#include "wx/combo.h" #include "wx/combo.h"
@@ -610,9 +609,6 @@ END_EVENT_TABLE()
IMPLEMENT_ABSTRACT_CLASS(wxComboCtrlBase, wxControl) IMPLEMENT_ABSTRACT_CLASS(wxComboCtrlBase, wxControl)
// Have global double buffer - should be enough for multiple combos
static wxBitmap* gs_doubleBuffer = (wxBitmap*) NULL;
void wxComboCtrlBase::Init() void wxComboCtrlBase::Init()
{ {
m_winPopup = (wxWindow *)NULL; m_winPopup = (wxWindow *)NULL;
@@ -737,9 +733,6 @@ wxComboCtrlBase::~wxComboCtrlBase()
if ( HasCapture() ) if ( HasCapture() )
ReleaseMouse(); ReleaseMouse();
delete gs_doubleBuffer;
gs_doubleBuffer = (wxBitmap*) NULL;
#if INSTALL_TOPLEV_HANDLER #if INSTALL_TOPLEV_HANDLER
delete ((wxComboFrameEventHandler*)m_toplevEvtHandler); delete ((wxComboFrameEventHandler*)m_toplevEvtHandler);
m_toplevEvtHandler = (wxEvtHandler*) NULL; m_toplevEvtHandler = (wxEvtHandler*) NULL;
@@ -1238,19 +1231,6 @@ void wxComboCtrlBase::RecalcAndRefresh()
} }
} }
wxBitmap& wxComboCtrlBase::GetBufferBitmap( const wxSize& sz ) const
{
// If size is larger, recalculate double buffer bitmap
if ( !gs_doubleBuffer ||
sz.x > gs_doubleBuffer->GetWidth() ||
sz.y > gs_doubleBuffer->GetHeight() )
{
delete gs_doubleBuffer;
gs_doubleBuffer = new wxBitmap(sz.x+25,sz.y);
}
return *gs_doubleBuffer;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// miscellaneous event handlers // miscellaneous event handlers
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

136
src/common/dcbufcmn.cpp Normal file
View File

@@ -0,0 +1,136 @@
/////////////////////////////////////////////////////////////////////////////
// Name: src/common/dcbufcmn.cpp
// Purpose: Buffered DC implementation
// Author: Ron Lee, Jaakko Salli
// Modified by:
// Created: Sep-20-2006
// RCS-ID: $Id$
// Copyright: (c) wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#endif
#include "wx/dcbuffer.h"
// ============================================================================
// implementation
// ============================================================================
// ============================================================================
// wxSharedDCBufferManager
// Helper class to free shared buffer when the app exists.
// ============================================================================
class wxSharedDCBufferManager
{
friend class wxBufferedDC;
public:
wxSharedDCBufferManager()
{
m_buffer = NULL;
}
~wxSharedDCBufferManager()
{
delete m_buffer;
}
wxBitmap* GetBuffer(wxWindow* win, const wxSize& area)
{
int width = area.x;
int height = area.y;
if ( width <= 0 )
win->GetClientSize(&width, &height);
if ( !m_buffer ||
width > m_buffer->GetWidth() ||
height > m_buffer->GetHeight() )
{
delete m_buffer;
// Create slightly larger bitmap so we don't need to
// be reallocating constantly when the user enlarges
// the frame for the first time.
m_buffer = new wxBitmap(width+20, height+20);
}
return m_buffer;
}
private:
wxBitmap* m_buffer;
};
static wxSharedDCBufferManager gs_sharedDCBufferManager;
// ============================================================================
// wxBufferedDC
// ============================================================================
// Blits the buffer to the dc, and detaches the dc from the buffer (so it
// can be effectively used once only).
//
// Usually called in the dtor or by the dtor of derived classes if the
// BufferedDC must blit before the derived class (which may own the dc it's
// blitting to) is destroyed.
void wxBufferedDC::UnMask()
{
if ( m_buffer )
{
wxASSERT_MSG( m_mainDc != NULL,
_T("No underlying DC associated with wxBufferedDC (anymore)") );
wxDC* bufferDc = DetachDC();
wxASSERT( bufferDc->IsKindOf(CLASSINFO(wxMemoryDC)) );
wxCoord x=0, y=0;
if (m_style & wxBUFFER_CLIENT_AREA)
bufferDc->GetDeviceOrigin(& x, & y);
m_mainDc->Blit( 0, 0,
m_buffer->GetWidth(), m_buffer->GetHeight(), bufferDc,
-x, -y );
m_mainDc = NULL;
m_buffer = NULL;
delete bufferDc;
}
}
void wxBufferedDC::PrepareBuffer(wxWindow* win, const wxSize& area)
{
m_buffer = gs_sharedDCBufferManager.GetBuffer(win, area);
}
void wxBufferedDC::UseBuffer()
{
wxASSERT(m_buffer);
wxMemoryDC* memoryDc = new wxMemoryDC(m_mainDc);
memoryDc->SelectObject(*m_buffer);
AttachDC(memoryDc);
}

View File

@@ -201,7 +201,7 @@ void wxGenericComboCtrl::OnResize()
void wxGenericComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) ) void wxGenericComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
{ {
wxSize sz = GetClientSize(); wxSize sz = GetClientSize();
wxBufferedPaintDC dc(this,GetBufferBitmap(sz)); wxAutoBufferedPaintDC dc(this);
const wxRect& rectb = m_btnArea; const wxRect& rectb = m_btnArea;
wxRect rect = m_tcArea; wxRect rect = m_tcArea;

View File

@@ -35,6 +35,7 @@
#include "wx/calctrl.h" #include "wx/calctrl.h"
#include "wx/popupwin.h" #include "wx/popupwin.h"
#include "wx/renderer.h" #include "wx/renderer.h"
#include "wx/dcbuffer.h"
#include "wx/icon.h" #include "wx/icon.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -682,6 +683,7 @@ wxDataViewHeaderWindow::wxDataViewHeaderWindow( wxDataViewCtrl *parent, wxWindow
m_resizeCursor = new wxCursor( wxCURSOR_SIZEWE ); m_resizeCursor = new wxCursor( wxCURSOR_SIZEWE );
wxVisualAttributes attr = wxPanel::GetClassDefaultAttributes(); wxVisualAttributes attr = wxPanel::GetClassDefaultAttributes();
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
SetOwnForegroundColour( attr.colFg ); SetOwnForegroundColour( attr.colFg );
SetOwnBackgroundColour( attr.colBg ); SetOwnBackgroundColour( attr.colBg );
if (!m_hasFont) if (!m_hasFont)
@@ -698,7 +700,10 @@ void wxDataViewHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
int w, h; int w, h;
GetClientSize( &w, &h ); GetClientSize( &w, &h );
wxPaintDC dc( this ); wxAutoBufferedPaintDC dc( this );
dc.SetBackground(GetBackgroundColour());
dc.Clear();
int xpix; int xpix;
m_owner->GetScrollPixelsPerUnit( &xpix, NULL ); m_owner->GetScrollPixelsPerUnit( &xpix, NULL );
@@ -953,6 +958,7 @@ wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID i
m_hasFocus = false; m_hasFocus = false;
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
SetBackgroundColour( *wxWHITE ); SetBackgroundColour( *wxWHITE );
UpdateDisplay(); UpdateDisplay();
@@ -1094,7 +1100,10 @@ void wxDataViewMainWindow::ScrollWindow( int dx, int dy, const wxRect *rect )
void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{ {
wxPaintDC dc( this ); wxAutoBufferedPaintDC dc( this );
dc.SetBackground(GetBackgroundColour());
dc.Clear();
GetOwner()->PrepareDC( dc ); GetOwner()->PrepareDC( dc );

View File

@@ -64,7 +64,6 @@ void wxVListBox::Init()
m_current = m_current =
m_anchor = wxNOT_FOUND; m_anchor = wxNOT_FOUND;
m_selStore = NULL; m_selStore = NULL;
m_doubleBuffer = NULL;
} }
bool wxVListBox::Create(wxWindow *parent, bool wxVListBox::Create(wxWindow *parent,
@@ -94,7 +93,6 @@ bool wxVListBox::Create(wxWindow *parent,
wxVListBox::~wxVListBox() wxVListBox::~wxVListBox()
{ {
delete m_doubleBuffer;
delete m_selStore; delete m_selStore;
} }
@@ -360,18 +358,9 @@ void wxVListBox::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const
void wxVListBox::OnPaint(wxPaintEvent& WXUNUSED(event)) void wxVListBox::OnPaint(wxPaintEvent& WXUNUSED(event))
{ {
// If size is larger, recalculate double buffer bitmap
wxSize clientSize = GetClientSize(); wxSize clientSize = GetClientSize();
if ( !m_doubleBuffer || wxAutoBufferedPaintDC dc(this);
clientSize.x > m_doubleBuffer->GetWidth() ||
clientSize.y > m_doubleBuffer->GetHeight() )
{
delete m_doubleBuffer;
m_doubleBuffer = new wxBitmap(clientSize.x+25,clientSize.y+25);
}
wxBufferedPaintDC dc(this,*m_doubleBuffer);
// the update rectangle // the update rectangle
wxRect rectUpdate = GetUpdateClientRect(); wxRect rectUpdate = GetUpdateClientRect();

View File

@@ -192,6 +192,10 @@ wxRendererGTK::DrawHeaderButton(wxWindow *win,
GtkWidget *button = GetButtonWidget(); GtkWidget *button = GetButtonWidget();
GdkWindow* gdk_window = dc.GetGDKWindow();
wxASSERT_MSG( gdk_window,
wxT("cannot use wxRendererNative on wxDC of this type") );
int x_diff = 0; int x_diff = 0;
if (win->GetLayoutDirection() == wxLayout_RightToLeft) if (win->GetLayoutDirection() == wxLayout_RightToLeft)
x_diff = rect.width; x_diff = rect.width;
@@ -199,9 +203,7 @@ wxRendererGTK::DrawHeaderButton(wxWindow *win,
gtk_paint_box gtk_paint_box
( (
button->style, button->style,
// FIXME: I suppose GTK_PIZZA(win->m_wxwindow)->bin_window doesn't work with wxMemoryDC. gdk_window,
// Maybe use code similar as in DrawPushButton below?
GTK_PIZZA(win->m_wxwindow)->bin_window,
flags & wxCONTROL_DISABLED ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL, flags & wxCONTROL_DISABLED ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL,
GTK_SHADOW_OUT, GTK_SHADOW_OUT,
NULL, NULL,
@@ -220,6 +222,10 @@ wxRendererGTK::DrawTreeItemButton(wxWindow* win,
{ {
GtkWidget *tree = GetTreeWidget(); GtkWidget *tree = GetTreeWidget();
GdkWindow* gdk_window = dc.GetGDKWindow();
wxASSERT_MSG( gdk_window,
wxT("cannot use wxRendererNative on wxDC of this type") );
GtkStateType state; GtkStateType state;
if ( flags & wxCONTROL_CURRENT ) if ( flags & wxCONTROL_CURRENT )
state = GTK_STATE_PRELIGHT; state = GTK_STATE_PRELIGHT;
@@ -229,13 +235,13 @@ wxRendererGTK::DrawTreeItemButton(wxWindow* win,
int x_diff = 0; int x_diff = 0;
if (win->GetLayoutDirection() == wxLayout_RightToLeft) if (win->GetLayoutDirection() == wxLayout_RightToLeft)
x_diff = rect.width; x_diff = rect.width;
// VZ: I don't know how to get the size of the expander so as to centre it // VZ: I don't know how to get the size of the expander so as to centre it
// in the given rectangle, +2/3 below is just what looks good here... // in the given rectangle, +2/3 below is just what looks good here...
gtk_paint_expander gtk_paint_expander
( (
tree->style, tree->style,
GTK_PIZZA(win->m_wxwindow)->bin_window, gdk_window,
state, state,
NULL, NULL,
tree, tree,
@@ -299,6 +305,10 @@ wxRendererGTK::DrawSplitterSash(wxWindow *win,
return; return;
} }
GdkWindow* gdk_window = dc.GetGDKWindow();
wxASSERT_MSG( gdk_window,
wxT("cannot use wxRendererNative on wxDC of this type") );
wxCoord full_size = GetGtkSplitterFullSize(); wxCoord full_size = GetGtkSplitterFullSize();
// are we drawing vertical or horizontal splitter? // are we drawing vertical or horizontal splitter?
@@ -332,7 +342,7 @@ wxRendererGTK::DrawSplitterSash(wxWindow *win,
gtk_paint_handle gtk_paint_handle
( (
win->m_wxwindow->style, win->m_wxwindow->style,
GTK_PIZZA(win->m_wxwindow)->bin_window, gdk_window,
flags & wxCONTROL_CURRENT ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL, flags & wxCONTROL_CURRENT ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
GTK_SHADOW_NONE, GTK_SHADOW_NONE,
NULL /* no clipping */, NULL /* no clipping */,
@@ -347,7 +357,7 @@ wxRendererGTK::DrawSplitterSash(wxWindow *win,
} }
void void
wxRendererGTK::DrawDropArrow(wxWindow *win, wxRendererGTK::DrawDropArrow(wxWindow *WXUNUSED(win),
wxDC& dc, wxDC& dc,
const wxRect& rect, const wxRect& rect,
int flags) int flags)
@@ -359,11 +369,9 @@ wxRendererGTK::DrawDropArrow(wxWindow *win,
// work for wxMemoryDC. So that is why we assume wxDC // work for wxMemoryDC. So that is why we assume wxDC
// is wxWindowDC (wxClientDC, wxMemoryDC and wxPaintDC // is wxWindowDC (wxClientDC, wxMemoryDC and wxPaintDC
// are derived from it) and use its m_window. // are derived from it) and use its m_window.
wxWindowDC& wdc = (wxWindowDC&)dc; GdkWindow* gdk_window = dc.GetGDKWindow();
wxASSERT_MSG( gdk_window,
// only doing debug-time checking here (it should wxT("cannot use wxRendererNative on wxDC of this type") );
// probably be enough)
wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) );
// draw arrow so that there is even space horizontally // draw arrow so that there is even space horizontally
// on both sides // on both sides
@@ -390,7 +398,7 @@ wxRendererGTK::DrawDropArrow(wxWindow *win,
gtk_paint_arrow gtk_paint_arrow
( (
button->style, button->style,
wdc.m_window, gdk_window,
state, state,
flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT, flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
NULL, NULL,
@@ -416,7 +424,7 @@ wxRendererGTK::DrawComboBoxDropButton(wxWindow *win,
} }
void void
wxRendererGTK::DrawCheckBox(wxWindow *win, wxRendererGTK::DrawCheckBox(wxWindow *WXUNUSED(win),
wxDC& dc, wxDC& dc,
const wxRect& rect, const wxRect& rect,
int flags ) int flags )
@@ -424,8 +432,9 @@ wxRendererGTK::DrawCheckBox(wxWindow *win,
GtkWidget *button = GetCheckButtonWidget(); GtkWidget *button = GetCheckButtonWidget();
// for reason why we do this, see DrawDropArrow // for reason why we do this, see DrawDropArrow
wxWindowDC& wdc = (wxWindowDC&)dc; GdkWindow* gdk_window = dc.GetGDKWindow();
wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) ); wxASSERT_MSG( gdk_window,
wxT("cannot use wxRendererNative on wxDC of this type") );
GtkStateType state; GtkStateType state;
@@ -441,7 +450,7 @@ wxRendererGTK::DrawCheckBox(wxWindow *win,
gtk_paint_check gtk_paint_check
( (
button->style, button->style,
wdc.m_window, gdk_window,
state, state,
flags & wxCONTROL_CHECKED ? GTK_SHADOW_IN : GTK_SHADOW_OUT, flags & wxCONTROL_CHECKED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
NULL, NULL,
@@ -454,7 +463,7 @@ wxRendererGTK::DrawCheckBox(wxWindow *win,
} }
void void
wxRendererGTK::DrawPushButton(wxWindow *win, wxRendererGTK::DrawPushButton(wxWindow *WXUNUSED(win),
wxDC& dc, wxDC& dc,
const wxRect& rect, const wxRect& rect,
int flags) int flags)
@@ -462,8 +471,9 @@ wxRendererGTK::DrawPushButton(wxWindow *win,
GtkWidget *button = GetButtonWidget(); GtkWidget *button = GetButtonWidget();
// for reason why we do this, see DrawDropArrow // for reason why we do this, see DrawDropArrow
wxWindowDC& wdc = (wxWindowDC&)dc; GdkWindow* gdk_window = dc.GetGDKWindow();
wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) ); wxASSERT_MSG( gdk_window,
wxT("cannot use wxRendererNative on wxDC of this type") );
// draw button // draw button
GtkStateType state; GtkStateType state;
@@ -480,7 +490,7 @@ wxRendererGTK::DrawPushButton(wxWindow *win,
gtk_paint_box gtk_paint_box
( (
button->style, button->style,
wdc.m_window, gdk_window,
state, state,
flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT, flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
NULL, NULL,
@@ -496,6 +506,10 @@ wxRendererGTK::DrawItemSelectionRect(wxWindow *win,
const wxRect& rect, const wxRect& rect,
int flags ) int flags )
{ {
GdkWindow* gdk_window = dc.GetGDKWindow();
wxASSERT_MSG( gdk_window,
wxT("cannot use wxRendererNative on wxDC of this type") );
GtkStateType state; GtkStateType state;
if (flags & wxCONTROL_SELECTED) if (flags & wxCONTROL_SELECTED)
{ {
@@ -505,7 +519,7 @@ wxRendererGTK::DrawItemSelectionRect(wxWindow *win,
state = GTK_STATE_INSENSITIVE; state = GTK_STATE_INSENSITIVE;
gtk_paint_flat_box( win->m_wxwindow->style, gtk_paint_flat_box( win->m_wxwindow->style,
GTK_PIZZA(win->m_wxwindow)->bin_window, gdk_window,
state, state,
GTK_SHADOW_NONE, GTK_SHADOW_NONE,
NULL, NULL,

View File

@@ -3935,6 +3935,11 @@ void wxWindowGTK::SetDoubleBuffered( bool on )
gtk_widget_set_double_buffered( m_wxwindow, on ); gtk_widget_set_double_buffered( m_wxwindow, on );
} }
bool wxWindowGTK::IsDoubleBuffered() const
{
return GTK_WIDGET_DOUBLE_BUFFERED( m_wxwindow );
}
void wxWindowGTK::ClearBackground() void wxWindowGTK::ClearBackground()
{ {
wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); wxCHECK_RET( m_widget != NULL, wxT("invalid window") );

View File

@@ -309,11 +309,9 @@ wxRendererGTK::DrawDropArrow(wxWindow *win,
// work for wxMemoryDC. So that is why we assume wxDC // work for wxMemoryDC. So that is why we assume wxDC
// is wxWindowDC (wxClientDC, wxMemoryDC and wxPaintDC // is wxWindowDC (wxClientDC, wxMemoryDC and wxPaintDC
// are derived from it) and use its m_window. // are derived from it) and use its m_window.
wxWindowDC& wdc = (wxWindowDC&)dc; GdkWindow* gdk_window = dc.GetGDKWindow();
wxASSERT_MSG( gdk_window,
// only doing debug-time checking here (it should wxT("cannot use wxRendererNative on wxDC of this type") );
// probably be enough)
wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) );
// draw arrow so that there is even space horizontally // draw arrow so that there is even space horizontally
// on both sides // on both sides
@@ -340,7 +338,7 @@ wxRendererGTK::DrawDropArrow(wxWindow *win,
gtk_paint_arrow gtk_paint_arrow
( (
button->style, button->style,
wdc.m_window, gdk_window,
state, state,
flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT, flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
NULL, NULL,
@@ -364,8 +362,9 @@ wxRendererGTK::DrawComboBoxDropButton(wxWindow *win,
GtkWidget *button = GetButtonWidget(); GtkWidget *button = GetButtonWidget();
// for reason why we do this, see DrawDropArrow // for reason why we do this, see DrawDropArrow
wxWindowDC& wdc = (wxWindowDC&)dc; GdkWindow* gdk_window = dc.GetGDKWindow();
wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) ); wxASSERT_MSG( gdk_window,
wxT("cannot use wxRendererNative on wxDC of this type") );
// draw button // draw button
GtkStateType state; GtkStateType state;
@@ -382,7 +381,7 @@ wxRendererGTK::DrawComboBoxDropButton(wxWindow *win,
gtk_paint_box gtk_paint_box
( (
button->style, button->style,
wdc.m_window, gdk_window,
state, state,
flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT, flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
NULL, NULL,

View File

@@ -388,7 +388,7 @@ void wxComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
// TODO: Convert drawing in this function to Windows API Code // TODO: Convert drawing in this function to Windows API Code
wxSize sz = GetClientSize(); wxSize sz = GetClientSize();
wxBufferedPaintDC dc(this,GetBufferBitmap(sz)); wxAutoBufferedPaintDC dc(this);
const wxRect& rectb = m_btnArea; const wxRect& rectb = m_btnArea;
wxRect rect = m_tcArea; wxRect rect = m_tcArea;

View File

@@ -3950,6 +3950,20 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
#endif #endif
} }
bool wxWindowMSW::IsDoubleBuffered() const
{
const wxWindow* wnd = this;
while ( wnd )
{
if ( ::GetWindowLong((HWND)wnd->GetHWND(), GWL_EXSTYLE) & WS_EX_COMPOSITED )
return true;
wnd = wnd->GetParent();
}
return false;
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// owner drawn stuff // owner drawn stuff
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------