Files
yacreader/YACReader/continuous_page_widget.cpp

148 lines
4.0 KiB
C++

#include "continuous_page_widget.h"
#include "continuous_view_model.h"
#include "render.h"
#include <QPainter>
#include <QPaintEvent>
ContinuousPageWidget::ContinuousPageWidget(QWidget *parent)
: QWidget(parent)
{
QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred);
sp.setHeightForWidth(true);
setSizePolicy(sp);
setMouseTracking(true);
initTheme(this);
}
void ContinuousPageWidget::applyTheme(const Theme &)
{
update();
}
void ContinuousPageWidget::setRender(Render *r)
{
render = r;
}
void ContinuousPageWidget::setViewModel(ContinuousViewModel *viewModel)
{
if (continuousViewModel == viewModel) {
return;
}
if (continuousViewModel) {
disconnect(continuousViewModel, &ContinuousViewModel::stateChanged, this, QOverload<>::of(&ContinuousPageWidget::update));
}
continuousViewModel = viewModel;
if (continuousViewModel) {
connect(continuousViewModel, &ContinuousViewModel::stateChanged, this, QOverload<>::of(&ContinuousPageWidget::update));
}
updateGeometry();
update();
}
void ContinuousPageWidget::reset()
{
setMinimumHeight(0);
setMaximumHeight(QWIDGETSIZE_MAX);
updateGeometry();
update();
}
bool ContinuousPageWidget::hasHeightForWidth() const
{
return true;
}
int ContinuousPageWidget::heightForWidth(int w) const
{
if (!continuousViewModel || w <= 0) {
return 0;
}
Q_UNUSED(w)
return continuousViewModel->totalHeight();
}
QSize ContinuousPageWidget::sizeHint() const
{
if (!continuousViewModel) {
return QSize(800, 0);
}
return QSize(width(), continuousViewModel->totalHeight());
}
void ContinuousPageWidget::onPageAvailable(int absolutePageIndex)
{
if (!render || !continuousViewModel || absolutePageIndex < 0 || absolutePageIndex >= continuousViewModel->numPages()) {
return;
}
const QImage *img = render->bufferedImage(absolutePageIndex);
if (!img || img->isNull()) {
return;
}
// repaint the region where this page lives
if (absolutePageIndex < continuousViewModel->numPages()) {
QSize scaled = continuousViewModel->scaledPageSize(absolutePageIndex);
const int y = continuousViewModel->yPositionForPage(absolutePageIndex);
int x = (width() - scaled.width()) / 2;
if (x < 0) {
x = 0;
}
QRect pageRect(x, y, scaled.width(), scaled.height());
update(pageRect);
}
}
void ContinuousPageWidget::paintEvent(QPaintEvent *event)
{
if (!continuousViewModel || continuousViewModel->numPages() == 0 || !render) {
return;
}
QPainter painter(this);
QRect visibleRect = event->rect();
int firstPage = continuousViewModel->pageAtY(visibleRect.top());
int lastPage = continuousViewModel->pageAtY(visibleRect.bottom());
int w = width();
for (int i = firstPage; i <= lastPage && i < continuousViewModel->numPages(); ++i) {
int y = continuousViewModel->yPositionForPage(i);
QSize scaled = continuousViewModel->scaledPageSize(i);
// center horizontally if page is narrower than widget
int x = (w - scaled.width()) / 2;
if (x < 0) {
x = 0;
}
QRect pageRect(x, y, scaled.width(), scaled.height());
const QImage *img = render->bufferedImage(i);
if (img && !img->isNull()) {
if (img->size() != scaled) {
painter.drawImage(pageRect, img->scaled(scaled, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
} else {
painter.drawImage(pageRect, *img);
}
} else {
// placeholder
painter.fillRect(pageRect, QColor(45, 45, 45));
painter.setPen(theme.viewer.defaultTextColor);
painter.drawText(pageRect, Qt::AlignCenter, tr("Loading page %1").arg(i + 1));
}
}
}
void ContinuousPageWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
if (continuousViewModel) {
continuousViewModel->setViewportSize(width(), continuousViewModel->viewportHeight());
}
}