The original drawing mechanism was generating lots of QWarning messages when running samples (e.g. htlbox, caret, etc.) and in some cases was not actually completely drawing every element of the sample. The issue was that the QPicture was being shared incorrectly between wxWindow and wxClientDC and attempts to start painting, update, etc. were generating console warnings. Closes https://github.com/wxWidgets/wxWidgets/pull/1152
176 lines
4.1 KiB
C++
176 lines
4.1 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/qt/dcclient.cpp
|
|
// Author: Peter Most, Javier Torres, Mariano Reingart
|
|
// Copyright: (c) 2010 wxWidgets dev team
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#include <QtGui/QPicture>
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/log.h"
|
|
#include "wx/window.h"
|
|
#endif // WX_PRECOMP
|
|
|
|
#include "wx/dcclient.h"
|
|
#include "wx/qt/dcclient.h"
|
|
|
|
#include <QtWidgets/QScrollArea>
|
|
#include <QtGui/QPainter>
|
|
|
|
//##############################################################################
|
|
|
|
namespace
|
|
{
|
|
class QtPictureSetter
|
|
{
|
|
public:
|
|
QtPictureSetter(wxWindow *window, QPicture *pict)
|
|
: m_window( window )
|
|
{
|
|
m_window->QtSetPicture( pict );
|
|
}
|
|
|
|
~QtPictureSetter()
|
|
{
|
|
m_window->QtSetPicture( NULL );
|
|
}
|
|
|
|
private:
|
|
wxWindow* const m_window;
|
|
|
|
wxDECLARE_NO_COPY_CLASS(QtPictureSetter);
|
|
};
|
|
}
|
|
|
|
|
|
wxIMPLEMENT_CLASS(wxWindowDCImpl,wxQtDCImpl);
|
|
|
|
wxWindowDCImpl::wxWindowDCImpl( wxDC *owner )
|
|
: wxQtDCImpl( owner )
|
|
{
|
|
m_window = NULL;
|
|
m_ok = false;
|
|
m_qtPainter = new QPainter();
|
|
}
|
|
|
|
wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *win )
|
|
: wxQtDCImpl( owner )
|
|
{
|
|
m_window = win;
|
|
m_qtPainter = m_window->QtGetPainter();
|
|
// if we're not inside a Paint event, painter will invalid
|
|
m_ok = m_qtPainter != NULL;
|
|
}
|
|
|
|
wxWindowDCImpl::~wxWindowDCImpl()
|
|
{
|
|
if ( m_ok )
|
|
{
|
|
m_ok = false;
|
|
}
|
|
if ( m_window )
|
|
{
|
|
// do not destroy in base class as it is owned by the window
|
|
m_qtPainter = NULL;
|
|
}
|
|
}
|
|
|
|
//##############################################################################
|
|
|
|
wxIMPLEMENT_CLASS(wxClientDCImpl,wxWindowDCImpl);
|
|
|
|
wxClientDCImpl::wxClientDCImpl( wxDC *owner )
|
|
: wxWindowDCImpl( owner )
|
|
{
|
|
m_window = NULL;
|
|
m_qtPainter = NULL;
|
|
}
|
|
|
|
wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *win )
|
|
: wxWindowDCImpl( owner )
|
|
{
|
|
m_window = win;
|
|
|
|
m_qtPainter = new QPainter();
|
|
|
|
m_pict.reset(new QPicture());
|
|
m_ok = m_qtPainter->begin( m_pict.get() );
|
|
|
|
QtPreparePainter();
|
|
}
|
|
|
|
wxClientDCImpl::~wxClientDCImpl()
|
|
{
|
|
/* Paint to a QPicture that will then be painted in the next
|
|
* paint event of that window (a paint event will be generated
|
|
* when this wxClientDC is done). */
|
|
if ( m_ok )
|
|
{
|
|
m_qtPainter->end();
|
|
m_ok = false;
|
|
|
|
if ( m_window != NULL )
|
|
{
|
|
QtPictureSetter pictureSetter(m_window, m_pict.get());
|
|
|
|
// get the inner widget in scroll areas:
|
|
QWidget *widget;
|
|
if ( m_window->QtGetScrollBarsContainer() )
|
|
{
|
|
widget = m_window->QtGetScrollBarsContainer()->viewport();
|
|
} else {
|
|
widget = m_window->GetHandle();
|
|
}
|
|
// force paint event if there is something to replay and
|
|
// if not currently inside a paint event (to avoid recursion)
|
|
QRect rect = m_pict->boundingRect();
|
|
if ( !m_pict->isNull() && !widget->paintingActive() && !rect.isEmpty() )
|
|
{
|
|
// only force the update of the rect affected by the DC
|
|
widget->update( rect );
|
|
}
|
|
else
|
|
{
|
|
// Not drawing anything, reset picture to avoid issues in handler
|
|
m_pict->setData( NULL, 0 );
|
|
}
|
|
|
|
// let destroy the m_qtPainter (see inherited classes destructors)
|
|
m_window = NULL;
|
|
}
|
|
}
|
|
|
|
// Painter will be deleted by base class
|
|
}
|
|
|
|
//##############################################################################
|
|
|
|
wxIMPLEMENT_CLASS(wxPaintDCImpl,wxClientDCImpl);
|
|
|
|
wxPaintDCImpl::wxPaintDCImpl( wxDC *owner )
|
|
: wxWindowDCImpl( owner )
|
|
{
|
|
if ( m_ok )
|
|
{
|
|
QtPreparePainter();
|
|
}
|
|
}
|
|
|
|
wxPaintDCImpl::wxPaintDCImpl( wxDC *owner, wxWindow *win )
|
|
: wxWindowDCImpl( owner, win )
|
|
{
|
|
if ( m_ok )
|
|
{
|
|
QtPreparePainter();
|
|
}
|
|
}
|
|
|