Help/litehtml: Support scaling

Scale the paint area for the HTML document

Change-Id: I75aa5f2bf057df7b2b160b2a005172ff88dbb2b7
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Eike Ziller
2019-09-17 12:33:01 +02:00
parent 93ed44bfea
commit 12ea33446d
4 changed files with 93 additions and 24 deletions

View File

@@ -65,6 +65,7 @@ LiteHtmlHelpViewer::LiteHtmlHelpViewer(QWidget *parent)
, m_viewer(new QLiteHtmlWidget)
{
m_viewer->setResourceHandler([](const QUrl &url) { return getData(url); });
m_viewer->viewport()->installEventFilter(this);
connect(m_viewer, &QLiteHtmlWidget::linkClicked, this, &LiteHtmlHelpViewer::setSource);
connect(m_viewer,
&QLiteHtmlWidget::contextMenuRequested,
@@ -99,28 +100,28 @@ void LiteHtmlHelpViewer::setViewerFont(const QFont &newFont)
void LiteHtmlHelpViewer::scaleUp()
{
// TODO
setScale(scale() * 1.1);
}
void LiteHtmlHelpViewer::scaleDown()
{
// TODO
setScale(scale() * .9);
}
void LiteHtmlHelpViewer::resetScale()
{
// TODO
m_viewer->setZoomFactor(1);
}
qreal LiteHtmlHelpViewer::scale() const
{
// TODO
return 1;
return m_viewer->zoomFactor();
}
void LiteHtmlHelpViewer::setScale(qreal scale)
{
// TODO
// interpret 0 as "default"
m_viewer->setZoomFactor(scale == 0 ? qreal(1) : scale);
}
QString LiteHtmlHelpViewer::title() const
@@ -253,6 +254,16 @@ void LiteHtmlHelpViewer::print(QPrinter *printer)
// TODO
}
bool LiteHtmlHelpViewer::eventFilter(QObject *src, QEvent *e)
{
if (isScrollWheelZoomingEnabled() && e->type() == QEvent::Wheel) {
auto we = static_cast<QWheelEvent *>(e);
if (we->modifiers() == Qt::ControlModifier)
return true;
}
return HelpViewer::eventFilter(src, e);
}
void LiteHtmlHelpViewer::setSourceInternal(const QUrl &url, Utils::optional<int> vscroll)
{
slotLoadStarted();

View File

@@ -77,6 +77,8 @@ public:
void backward() override;
void print(QPrinter *printer) override;
bool eventFilter(QObject *src, QEvent *e) override;
private:
void goForward(int count);
void goBackward(int count);

View File

@@ -373,6 +373,7 @@ public:
litehtml::context context;
QUrl url;
DocumentContainer documentContainer;
qreal zoomFactor = 1;
};
QLiteHtmlWidget::QLiteHtmlWidget(QWidget *parent)
@@ -434,6 +435,18 @@ QString QLiteHtmlWidget::title() const
return d->documentContainer.caption();
}
void QLiteHtmlWidget::setZoomFactor(qreal scale)
{
Q_ASSERT(scale != 0);
d->zoomFactor = scale;
render();
}
qreal QLiteHtmlWidget::zoomFactor() const
{
return d->zoomFactor;
}
bool QLiteHtmlWidget::findText(const QString &text,
QTextDocument::FindFlags flags,
bool incremental,
@@ -451,13 +464,14 @@ bool QLiteHtmlWidget::findText(const QString &text,
if (success && verticalScrollBar()->value() > newSelectionCombined.top()) {
verticalScrollBar()->setValue(newSelectionCombined.top());
} else if (success
&& verticalScrollBar()->value() + viewport()->height()
&& verticalScrollBar()->value() + toVirtual(viewport()->size()).height()
< newSelectionCombined.bottom()) {
verticalScrollBar()->setValue(newSelectionCombined.bottom() - viewport()->height());
verticalScrollBar()->setValue(newSelectionCombined.bottom()
- toVirtual(viewport()->size()).height());
} else {
viewport()->update(newSelectionCombined.translated(-scrollPosition()));
viewport()->update(fromVirtual(newSelectionCombined.translated(-scrollPosition())));
for (const QRect &r : oldSelection)
viewport()->update(r.translated(-scrollPosition()));
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
}
return success;
}
@@ -510,9 +524,10 @@ void QLiteHtmlWidget::paintEvent(QPaintEvent *event)
return;
d->documentContainer.setScrollPosition(scrollPosition());
const QPoint pos = -scrollPosition();
const QRect r = event->rect();
const QRect r = toVirtual(event->rect());
const litehtml::position clip = {r.x(), r.y(), r.width(), r.height()};
QPainter p(viewport());
p.setWorldTransform(QTransform().scale(d->zoomFactor, d->zoomFactor));
d->documentContainer.document()->draw(reinterpret_cast<litehtml::uint_ptr>(&p),
pos.x(),
pos.y(),
@@ -531,7 +546,7 @@ void QLiteHtmlWidget::mouseMoveEvent(QMouseEvent *event)
QPoint pos;
htmlPos(event->pos(), &viewportPos, &pos);
for (const QRect &r : d->documentContainer.mouseMoveEvent(pos, viewportPos))
viewport()->update(r.translated(-scrollPosition()));
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
}
void QLiteHtmlWidget::mousePressEvent(QMouseEvent *event)
@@ -540,7 +555,7 @@ void QLiteHtmlWidget::mousePressEvent(QMouseEvent *event)
QPoint pos;
htmlPos(event->pos(), &viewportPos, &pos);
for (const QRect &r : d->documentContainer.mousePressEvent(pos, viewportPos, event->button()))
viewport()->update(r.translated(-scrollPosition()));
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
}
void QLiteHtmlWidget::mouseReleaseEvent(QMouseEvent *event)
@@ -549,7 +564,7 @@ void QLiteHtmlWidget::mouseReleaseEvent(QMouseEvent *event)
QPoint pos;
htmlPos(event->pos(), &viewportPos, &pos);
for (const QRect &r : d->documentContainer.mouseReleaseEvent(pos, viewportPos, event->button()))
viewport()->update(r.translated(-scrollPosition()));
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
}
void QLiteHtmlWidget::mouseDoubleClickEvent(QMouseEvent *event)
@@ -559,7 +574,7 @@ void QLiteHtmlWidget::mouseDoubleClickEvent(QMouseEvent *event)
htmlPos(event->pos(), &viewportPos, &pos);
for (const QRect &r :
d->documentContainer.mouseDoubleClickEvent(pos, viewportPos, event->button())) {
viewport()->update(r.translated(-scrollPosition()));
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
}
}
@@ -567,7 +582,7 @@ void QLiteHtmlWidget::leaveEvent(QEvent *event)
{
Q_UNUSED(event)
for (const QRect &r : d->documentContainer.leaveEvent())
viewport()->update(r.translated(-scrollPosition()));
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
}
void QLiteHtmlWidget::contextMenuEvent(QContextMenuEvent *event)
@@ -582,17 +597,19 @@ void QLiteHtmlWidget::render()
{
if (!d->documentContainer.document())
return;
const int fullWidth = width() / d->zoomFactor;
const QSize vViewportSize = toVirtual(viewport()->size());
const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent, nullptr, this);
const int w = width() - scrollbarWidth - 2;
d->documentContainer.render(w, viewport()->height());
horizontalScrollBar()->setPageStep(viewport()->width());
horizontalScrollBar()
->setRange(0, std::max(0, d->documentContainer.document()->width() - viewport()->width()));
verticalScrollBar()->setPageStep(viewport()->height());
const int w = fullWidth - scrollbarWidth - 2;
d->documentContainer.render(w, vViewportSize.height());
// scroll bars reflect virtual/scaled size of html document
horizontalScrollBar()->setPageStep(vViewportSize.width());
horizontalScrollBar()->setRange(0, std::max(0, d->documentContainer.document()->width() - w));
verticalScrollBar()->setPageStep(vViewportSize.height());
verticalScrollBar()->setRange(0,
std::max(0,
d->documentContainer.document()->height()
- viewport()->height()));
- vViewportSize.height()));
viewport()->update();
}
@@ -603,6 +620,36 @@ QPoint QLiteHtmlWidget::scrollPosition() const
void QLiteHtmlWidget::htmlPos(const QPoint &pos, QPoint *viewportPos, QPoint *htmlPos) const
{
*viewportPos = viewport()->mapFromParent(pos);
*viewportPos = toVirtual(viewport()->mapFromParent(pos));
*htmlPos = *viewportPos + scrollPosition();
}
QPoint QLiteHtmlWidget::toVirtual(const QPoint &p) const
{
return {int(p.x() / d->zoomFactor), int(p.y() / d->zoomFactor)};
}
QPoint QLiteHtmlWidget::fromVirtual(const QPoint &p) const
{
return {int(p.x() * d->zoomFactor), int(p.y() * d->zoomFactor)};
}
QSize QLiteHtmlWidget::toVirtual(const QSize &s) const
{
return {int(s.width() / d->zoomFactor), int(s.height() / d->zoomFactor)};
}
QSize QLiteHtmlWidget::fromVirtual(const QSize &s) const
{
return {int(s.width() * d->zoomFactor + 0.5), int(s.height() * d->zoomFactor + 0.5)};
}
QRect QLiteHtmlWidget::toVirtual(const QRect &r) const
{
return {toVirtual(r.topLeft()), toVirtual(r.size())};
}
QRect QLiteHtmlWidget::fromVirtual(const QRect &r) const
{
return {fromVirtual(r.topLeft()), fromVirtual(r.size())};
}

View File

@@ -44,6 +44,9 @@ public:
void setHtml(const QString &content);
QString title() const;
void setZoomFactor(qreal scale);
qreal zoomFactor() const;
bool findText(const QString &text,
QTextDocument::FindFlags flags,
bool incremental,
@@ -77,6 +80,12 @@ private:
void render();
QPoint scrollPosition() const;
void htmlPos(const QPoint &pos, QPoint *viewportPos, QPoint *htmlPos) const;
QPoint toVirtual(const QPoint &p) const;
QPoint fromVirtual(const QPoint &p) const;
QSize toVirtual(const QSize &s) const;
QSize fromVirtual(const QSize &s) const;
QRect toVirtual(const QRect &r) const;
QRect fromVirtual(const QRect &r) const;
QLiteHtmlWidgetPrivate *d;
};