Enable OpenGL drawing

This commit is contained in:
Jakub Melka
2019-09-01 18:26:52 +02:00
parent 69ba66ae04
commit 135fa6fc86
4 changed files with 166 additions and 64 deletions

View File

@ -373,7 +373,7 @@ void PDFDrawWidgetProxy::init(PDFWidget* widget)
connect(m_horizontalScrollbar, &QScrollBar::valueChanged, this, &PDFDrawWidgetProxy::onHorizontalScrollbarValueChanged);
connect(m_verticalScrollbar, &QScrollBar::valueChanged, this, &PDFDrawWidgetProxy::onVerticalScrollbarValueChanged);
connect(this, &PDFDrawWidgetProxy::drawSpaceChanged, m_widget, QOverload<void>::of(&PDFDrawWidget::update));
connect(this, &PDFDrawWidgetProxy::drawSpaceChanged, m_widget->getWidget(), QOverload<void>::of(&PDFDrawWidget::update));
// We must update the draw space - widget has been set
update();
@ -391,9 +391,11 @@ void PDFDrawWidgetProxy::update()
Q_ASSERT(m_horizontalScrollbar);
Q_ASSERT(m_verticalScrollbar);
QWidget* widget = m_widget->getWidget();
// First, we must calculate pixel per mm ratio to obtain DPMM (device pixel per mm),
// we also assume, that zoom is correctly set.
m_pixelPerMM = static_cast<PDFReal>(m_widget->width()) / static_cast<PDFReal>(m_widget->widthMM());
m_pixelPerMM = static_cast<PDFReal>(widget->width()) / static_cast<PDFReal>(widget->widthMM());
Q_ASSERT(m_zoom > 0.0);
Q_ASSERT(m_pixelPerMM > 0.0);
@ -438,7 +440,7 @@ void PDFDrawWidgetProxy::update()
}
QSize blockSize = m_layout.blockRect.size();
QSize widgetSize = m_widget->size();
QSize widgetSize = widget->size();
// Horizontal scrollbar
const int horizontalDifference = blockSize.width() - widgetSize.width();

View File

@ -33,7 +33,7 @@ class QScrollBar;
namespace pdf
{
class PDFWidget;
class PDFDrawWidget;
class IDrawWidget;
/// This class controls draw space - page layout. Pages are divided into blocks
/// each block can contain one or multiple pages. Units are in milimeters.
@ -319,7 +319,7 @@ private:
PDFDrawSpaceController* m_controller;
/// Controlled draw widget (proxy is for this widget)
PDFDrawWidget* m_widget;
IDrawWidget* m_widget;
/// Vertical scrollbar
QScrollBar* m_verticalScrollbar;

View File

@ -33,24 +33,24 @@ PDFWidget::PDFWidget(QWidget* parent) :
m_verticalScrollBar(nullptr),
m_proxy(nullptr)
{
m_drawWidget = new PDFDrawWidget(this, this);
m_drawWidget = new PDFOpenGLDrawWidget(this, this);
m_horizontalScrollBar = new QScrollBar(Qt::Horizontal, this);
m_verticalScrollBar = new QScrollBar(Qt::Vertical, this);
QGridLayout* layout = new QGridLayout(this);
layout->setSpacing(0);
layout->addWidget(m_drawWidget, 0, 0);
layout->addWidget(m_drawWidget->getWidget(), 0, 0);
layout->addWidget(m_horizontalScrollBar, 1, 0);
layout->addWidget(m_verticalScrollBar, 0, 1);
layout->setMargin(0);
setLayout(layout);
setFocusProxy(m_drawWidget);
setFocusProxy(m_drawWidget->getWidget());
m_proxy = new PDFDrawWidgetProxy(this);
m_proxy->init(this);
connect(m_proxy, &PDFDrawWidgetProxy::renderingError, this, &PDFWidget::onRenderingError);
connect(m_proxy, &PDFDrawWidgetProxy::repaintNeeded, m_drawWidget, QOverload<>::of(&PDFDrawWidget::update));
connect(m_proxy, &PDFDrawWidgetProxy::repaintNeeded, m_drawWidget->getWidget(), QOverload<>::of(&QWidget::update));
}
PDFWidget::~PDFWidget()
@ -82,45 +82,51 @@ void PDFWidget::onRenderingError(PDFInteger pageIndex, const QList<PDFRenderErro
emit pageRenderingErrorsChanged(pageIndex, errors.size());
}
PDFDrawWidget::PDFDrawWidget(PDFWidget* widget, QWidget* parent) :
QWidget(parent),
template<typename BaseWidget>
PDFDrawWidgetBase<BaseWidget>::PDFDrawWidgetBase(PDFWidget* widget, QWidget* parent) :
BaseWidget(parent),
m_widget(widget),
m_mouseOperation(MouseOperation::None)
{
setFocusPolicy(Qt::StrongFocus);
this->setFocusPolicy(Qt::StrongFocus);
}
PDFDrawWidget::~PDFDrawWidget()
template<typename BaseWidget>
std::vector<PDFInteger> PDFDrawWidgetBase<BaseWidget>::getCurrentPages() const
{
return this->m_widget->getDrawWidgetProxy()->getPagesIntersectingRect(this->rect());
}
std::vector<PDFInteger> PDFDrawWidget::getCurrentPages() const
{
return m_widget->getDrawWidgetProxy()->getPagesIntersectingRect(this->rect());
}
QSize PDFDrawWidget::minimumSizeHint() const
template<typename BaseWidget>
QSize PDFDrawWidgetBase<BaseWidget>::minimumSizeHint() const
{
return QSize(200, 200);
}
void PDFDrawWidget::paintEvent(QPaintEvent* event)
template<typename BaseWidget>
void PDFDrawWidgetBase<BaseWidget>::performMouseOperation(QPoint currentMousePosition)
{
Q_UNUSED(event);
switch (m_mouseOperation)
{
case MouseOperation::None:
// No operation performed
break;
QPainter painter(this);
m_widget->getDrawWidgetProxy()->draw(&painter, this->rect());
case MouseOperation::Translate:
{
QPoint difference = currentMousePosition - m_lastMousePosition;
m_widget->getDrawWidgetProxy()->scrollByPixels(difference);
m_lastMousePosition = currentMousePosition;
break;
}
default:
Q_ASSERT(false);
}
}
void PDFDrawWidget::resizeEvent(QResizeEvent* event)
{
QWidget::resizeEvent(event);
m_widget->getDrawWidgetProxy()->update();
}
void PDFDrawWidget::keyPressEvent(QKeyEvent* event)
template<typename BaseWidget>
void PDFDrawWidgetBase<BaseWidget>::keyPressEvent(QKeyEvent* event)
{
QScrollBar* verticalScrollbar = m_widget->getVerticalScrollbar();
@ -149,7 +155,8 @@ void PDFDrawWidget::keyPressEvent(QKeyEvent* event)
event->accept();
}
void PDFDrawWidget::mousePressEvent(QMouseEvent* event)
template<typename BaseWidget>
void PDFDrawWidgetBase<BaseWidget>::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton)
{
@ -161,7 +168,8 @@ void PDFDrawWidget::mousePressEvent(QMouseEvent* event)
event->accept();
}
void PDFDrawWidget::mouseReleaseEvent(QMouseEvent* event)
template<typename BaseWidget>
void PDFDrawWidgetBase<BaseWidget>::mouseReleaseEvent(QMouseEvent* event)
{
performMouseOperation(event->pos());
@ -184,13 +192,15 @@ void PDFDrawWidget::mouseReleaseEvent(QMouseEvent* event)
event->accept();
}
void PDFDrawWidget::mouseMoveEvent(QMouseEvent* event)
template<typename BaseWidget>
void PDFDrawWidgetBase<BaseWidget>::mouseMoveEvent(QMouseEvent* event)
{
performMouseOperation(event->pos());
event->accept();
}
void PDFDrawWidget::wheelEvent(QWheelEvent* event)
template<typename BaseWidget>
void PDFDrawWidgetBase<BaseWidget>::wheelEvent(QWheelEvent* event)
{
Qt::KeyboardModifiers keyboardModifiers = QApplication::keyboardModifiers();
@ -256,25 +266,67 @@ void PDFDrawWidget::wheelEvent(QWheelEvent* event)
event->accept();
}
void PDFDrawWidget::performMouseOperation(QPoint currentMousePosition)
PDFOpenGLDrawWidget::PDFOpenGLDrawWidget(PDFWidget* widget, QWidget* parent) :
BaseClass(widget, parent)
{
switch (m_mouseOperation)
{
case MouseOperation::None:
// No operation performed
break;
case MouseOperation::Translate:
{
QPoint difference = currentMousePosition - m_lastMousePosition;
m_widget->getDrawWidgetProxy()->scrollByPixels(difference);
m_lastMousePosition = currentMousePosition;
break;
}
default:
Q_ASSERT(false);
}
QSurfaceFormat format = this->format();
format.setProfile(QSurfaceFormat::CoreProfile);
format.setSamples(16);
format.setColorSpace(QSurfaceFormat::sRGBColorSpace);
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
setFormat(format);
}
PDFOpenGLDrawWidget::~PDFOpenGLDrawWidget()
{
}
void PDFOpenGLDrawWidget::resizeGL(int w, int h)
{
QOpenGLWidget::resizeGL(w, h);
getPDFWidget()->getDrawWidgetProxy()->update();
}
void PDFOpenGLDrawWidget::initializeGL()
{
QOpenGLWidget::initializeGL();
}
void PDFOpenGLDrawWidget::paintGL()
{
QPainter painter(this);
getPDFWidget()->getDrawWidgetProxy()->draw(&painter, this->rect());
}
PDFDrawWidget::PDFDrawWidget(PDFWidget* widget, QWidget* parent) :
BaseClass(widget, parent)
{
}
PDFDrawWidget::~PDFDrawWidget()
{
}
void PDFDrawWidget::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event);
QPainter painter(this);
getPDFWidget()->getDrawWidgetProxy()->draw(&painter, this->rect());
}
void PDFDrawWidget::resizeEvent(QResizeEvent* event)
{
BaseClass::resizeEvent(event);
getPDFWidget()->getDrawWidgetProxy()->update();
}
template class PDFDrawWidgetBase<QOpenGLWidget>;
template class PDFDrawWidgetBase<QWidget>;
} // namespace pdf

View File

@ -24,6 +24,7 @@
#include <QWidget>
#include <QScrollBar>
#include <QOpenGLWidget>
namespace pdf
{
@ -31,6 +32,17 @@ class PDFDocument;
class PDFDrawWidget;
class PDFDrawWidgetProxy;
class IDrawWidget
{
public:
virtual ~IDrawWidget() = default;
virtual QWidget* getWidget() = 0;
/// Returns page indices, which are currently displayed in the widget
virtual std::vector<PDFInteger> getCurrentPages() const = 0;
};
class PDFFORQTLIBSHARED_EXPORT PDFWidget : public QWidget
{
Q_OBJECT
@ -48,7 +60,7 @@ public:
/// \param optionalContentActivity Optional content activity
void setDocument(const PDFDocument* document, const PDFOptionalContentActivity* optionalContentActivity);
PDFDrawWidget* getDrawWidget() const { return m_drawWidget; }
IDrawWidget* getDrawWidget() const { return m_drawWidget; }
QScrollBar* getHorizontalScrollbar() const { return m_horizontalScrollBar; }
QScrollBar* getVerticalScrollbar() const { return m_verticalScrollBar; }
PDFDrawWidgetProxy* getDrawWidgetProxy() const { return m_proxy; }
@ -61,35 +73,35 @@ signals:
private:
void onRenderingError(PDFInteger pageIndex, const QList<PDFRenderError>& errors);
PDFDrawWidget* m_drawWidget;
IDrawWidget* m_drawWidget;
QScrollBar* m_horizontalScrollBar;
QScrollBar* m_verticalScrollBar;
PDFDrawWidgetProxy* m_proxy;
PageRenderingErrors m_pageRenderingErrors;
};
class PDFFORQTLIBSHARED_EXPORT PDFDrawWidget : public QWidget
template<typename BaseWidget>
class PDFDrawWidgetBase : public BaseWidget, public IDrawWidget
{
Q_OBJECT
public:
explicit PDFDrawWidget(PDFWidget* widget, QWidget* parent);
virtual ~PDFDrawWidget() override;
explicit PDFDrawWidgetBase(PDFWidget* widget, QWidget* parent);
virtual ~PDFDrawWidgetBase() override = default;
/// Returns page indices, which are currently displayed in the widget
std::vector<PDFInteger> getCurrentPages() const;
virtual std::vector<PDFInteger> getCurrentPages() const override;
virtual QSize minimumSizeHint() const override;
virtual QWidget* getWidget() override { return this; }
protected:
virtual void paintEvent(QPaintEvent* event) override;
virtual void resizeEvent(QResizeEvent* event) override;
virtual void keyPressEvent(QKeyEvent* event) override;
virtual void mousePressEvent(QMouseEvent* event) override;
virtual void mouseReleaseEvent(QMouseEvent* event) override;
virtual void mouseMoveEvent(QMouseEvent* event) override;
virtual void wheelEvent(QWheelEvent* event) override;
PDFWidget* getPDFWidget() const { return m_widget; }
private:
enum class MouseOperation
{
@ -106,6 +118,42 @@ private:
MouseOperation m_mouseOperation;
};
class PDFOpenGLDrawWidget : public PDFDrawWidgetBase<QOpenGLWidget>
{
Q_OBJECT
private:
using BaseClass = PDFDrawWidgetBase<QOpenGLWidget>;
public:
explicit PDFOpenGLDrawWidget(PDFWidget* widget, QWidget* parent);
virtual ~PDFOpenGLDrawWidget() override;
protected:
virtual void resizeGL(int w, int h) override;
virtual void initializeGL() override;
virtual void paintGL() override;
};
class PDFDrawWidget : public PDFDrawWidgetBase<QWidget>
{
Q_OBJECT
private:
using BaseClass = PDFDrawWidgetBase<QWidget>;
public:
explicit PDFDrawWidget(PDFWidget* widget, QWidget* parent);
virtual ~PDFDrawWidget() override;
protected:
virtual void paintEvent(QPaintEvent* event) override;
virtual void resizeEvent(QResizeEvent* event) override;
};
extern template class PDFDrawWidgetBase<QOpenGLWidget>;
extern template class PDFDrawWidgetBase<QWidget>;
} // namespace pdf
#endif // PDFDRAWWIDGET_H