[LyX/master] HiDPI support for search indicators (#12162)
Juergen Spitzmueller
spitz at lyx.org
Sun Feb 28 11:31:40 UTC 2021
commit 557382520246c80bff226e6f7e6fcbd45941c14c
Author: Juergen Spitzmueller <spitz at lyx.org>
Date: Sun Feb 28 12:35:29 2021 +0100
HiDPI support for search indicators (#12162)
Requires Qt5
---
src/frontends/qt/FancyLineEdit.cpp | 25 ++++++--
src/frontends/qt/GuiSearch.cpp | 124 ++++++++++++++++++++++++++++++------
2 files changed, 125 insertions(+), 24 deletions(-)
diff --git a/src/frontends/qt/FancyLineEdit.cpp b/src/frontends/qt/FancyLineEdit.cpp
index c3b597c..b9874d2 100644
--- a/src/frontends/qt/FancyLineEdit.cpp
+++ b/src/frontends/qt/FancyLineEdit.cpp
@@ -33,6 +33,9 @@
#include <QPainter>
#include <QStyle>
#include <QPaintEvent>
+#if QT_VERSION >= 0x050000
+#include <QWindow>
+#endif
enum { margin = 6 };
@@ -194,8 +197,13 @@ void FancyLineEdit::updateMargins()
Side realLeft = (leftToRight ? Left : Right);
Side realRight = (leftToRight ? Right : Left);
- int leftMargin = m_d->m_iconbutton[realLeft]->pixmap().width() + 8;
- int rightMargin = m_d->m_iconbutton[realRight]->pixmap().width() + 8;
+ qreal dpr = 1.0;
+#if QT_VERSION >= 0x050000
+ // Consider device/pixel ratio (HiDPI)
+ dpr = devicePixelRatio();
+#endif
+ int leftMargin = (m_d->m_iconbutton[realLeft]->pixmap().width() / dpr ) + 8;
+ int rightMargin = (m_d->m_iconbutton[realRight]->pixmap().width() / dpr) + 8;
// Note KDE does not reserve space for the highlight color
if (style()->inherits("OxygenStyle")) {
leftMargin = qMax(24, leftMargin);
@@ -334,14 +342,21 @@ IconButton::IconButton(QWidget *parent)
void IconButton::paintEvent(QPaintEvent *)
{
- QPainter painter(this);
- QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height());
+ qreal dpr = 1.0;
+#if QT_VERSION >= 0x050000
+ // Consider device/pixel ratio (HiDPI)
+ QWindow * window = this->window()->windowHandle();
+ dpr = window->devicePixelRatio();
+#endif
+ QRect pixmapRect(QPoint(), m_pixmap.size() / dpr);
pixmapRect.moveCenter(rect().center());
+ QPixmap pm = m_pixmap;
+ QPainter painter(this);
if (m_autoHide)
painter.setOpacity(m_iconOpacity);
- painter.drawPixmap(pixmapRect, m_pixmap);
+ painter.drawPixmap(pixmapRect, pm);
}
diff --git a/src/frontends/qt/GuiSearch.cpp b/src/frontends/qt/GuiSearch.cpp
index e938d0c..169c7aa 100644
--- a/src/frontends/qt/GuiSearch.cpp
+++ b/src/frontends/qt/GuiSearch.cpp
@@ -27,8 +27,11 @@
#include "GuiKeySymbol.h"
#include "GuiView.h"
+#include "qt_helpers.h"
+#include "support/filetools.h"
#include "support/debug.h"
#include "support/gettext.h"
+#include "support/FileName.h"
#include "frontends/alert.h"
#include "frontends/Clipboard.h"
@@ -38,8 +41,12 @@
#include <QSettings>
#include <QShowEvent>
#include "QSizePolicy"
+#if QT_VERSION >= 0x050000
+#include <QSvgRenderer>
+#endif
using namespace std;
+using namespace lyx::support;
using lyx::KeySymbol;
@@ -221,13 +228,24 @@ void GuiSearchWidget::handleIndicators()
if (wrapCB->isChecked())
++pms;
+ bool const dark_mode = guiApp && guiApp->isInDarkMode();
+ qreal dpr = 1.0;
+#if QT_VERSION >= 0x050000
+ // Consider device/pixel ratio (HiDPI)
+ if (guiApp && guiApp->currentView())
+ dpr = guiApp->currentView()->devicePixelRatio();
+#endif
+ QString imagedir = "images/";
QPixmap bpixmap = getPixmap("images/", "search-options", "svgz,png");
+ QPixmap pm = bpixmap;
if (pms > 0) {
int const gap = 3;
- QPixmap tpixmap(pms * (bpixmap.width() + gap), bpixmap.height());
- tpixmap.fill(Qt::transparent);
- QPainter painter(&tpixmap);
+ QPixmap scaled_pm = QPixmap(bpixmap.size() * dpr);
+ pm = QPixmap(pms * scaled_pm.width() + ((pms - 1) * gap),
+ scaled_pm.height());
+ pm.fill(Qt::transparent);
+ QPainter painter(&pm);
int x = 0;
tip = qt_("Active options:");
@@ -235,50 +253,118 @@ void GuiSearchWidget::handleIndicators()
if (caseCB->isChecked()) {
tip += "<li>" + qt_("Case sensitive search");
QPixmap spixmap = getPixmap("images/", "search-case-sensitive", "svgz,png");
+#if QT_VERSION < 0x050000
painter.drawPixmap(x, 0, spixmap);
- x += spixmap.width() + gap;
+#else
+ // With Qt5, we render SVG directly for HiDPI scalability
+ FileName fname = imageLibFileSearch(imagedir, "search-case-sensitive", "svgz,png");
+ QString fpath = toqstr(fname.absFileName());
+ if (!fpath.isEmpty()) {
+ QSvgRenderer svgRenderer(fpath);
+ if (svgRenderer.isValid())
+ svgRenderer.render(&painter, QRectF(0, 0, spixmap.width() * dpr,
+ spixmap.height() * dpr));
+ }
+#endif
+ x += (spixmap.width() * dpr) + gap;
}
if (wordsCB->isChecked()) {
tip += "<li>" + qt_("Whole words only");
QPixmap spixmap = getPixmap("images/", "search-whole-words", "svgz,png");
+#if QT_VERSION < 0x050000
painter.drawPixmap(x, 0, spixmap);
- x += spixmap.width() + gap;
+#else
+ FileName fname = imageLibFileSearch(imagedir, "search-whole-words", "svgz,png");
+ QString fpath = toqstr(fname.absFileName());
+ if (!fpath.isEmpty()) {
+ QSvgRenderer svgRenderer(fpath);
+ if (svgRenderer.isValid())
+ svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
+ spixmap.height() * dpr));
+ }
+#endif
+ x += (spixmap.width() * dpr) + gap;
}
if (selectionCB->isChecked()) {
tip += "<li>" + qt_("Search only in selection");
QPixmap spixmap = getPixmap("images/", "search-selection", "svgz,png");
+#if QT_VERSION < 0x050000
painter.drawPixmap(x, 0, spixmap);
- x += spixmap.width() + gap;
+#else
+ FileName fname = imageLibFileSearch(imagedir, "search-selection", "svgz,png");
+ QString fpath = toqstr(fname.absFileName());
+ if (!fpath.isEmpty()) {
+ QSvgRenderer svgRenderer(fpath);
+ if (svgRenderer.isValid())
+ svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
+ spixmap.height() * dpr));
+ }
+#endif
+ x += (spixmap.width() * dpr) + gap;
}
if (instantSearchCB->isChecked()) {
tip += "<li>" + qt_("Search as you type");
QPixmap spixmap = getPixmap("images/", "search-instant", "svgz,png");
+#if QT_VERSION < 0x050000
painter.drawPixmap(x, 0, spixmap);
- x += spixmap.width() + gap;
+#else
+ FileName fname = imageLibFileSearch(imagedir, "search-instant", "svgz,png");
+ QString fpath = toqstr(fname.absFileName());
+ if (!fpath.isEmpty()) {
+ QSvgRenderer svgRenderer(fpath);
+ if (svgRenderer.isValid())
+ svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
+ spixmap.height() * dpr));
+ }
+#endif
+ x += (spixmap.width() * dpr) + gap;
}
if (wrapCB->isChecked()) {
tip += "<li>" + qt_("Wrap search");
QPixmap spixmap = getPixmap("images/", "search-wrap", "svgz,png");
+#if QT_VERSION < 0x050000
painter.drawPixmap(x, 0, spixmap);
- x += spixmap.width() + gap;
+#else
+ FileName fname = imageLibFileSearch(imagedir, "search-wrap", "svgz,png");
+ QString fpath = toqstr(fname.absFileName());
+ if (!fpath.isEmpty()) {
+ QSvgRenderer svgRenderer(fpath);
+ if (svgRenderer.isValid())
+ svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
+ spixmap.height() * dpr));
+ }
+#endif
+ x += (spixmap.width() * dpr) + gap;
}
tip += "</ul>";
+#if QT_VERSION >= 0x050000
+ pm.setDevicePixelRatio(dpr);
+#endif
painter.end();
- if (guiApp && guiApp->isInDarkMode()) {
- QImage img = tpixmap.toImage();
- img.invertPixels();
- tpixmap.convertFromImage(img);
- }
- findLE_->setButtonPixmap(FancyLineEdit::Right, tpixmap);
} else {
tip = qt_("Click here to change search options");
- if (guiApp && guiApp->isInDarkMode()) {
- QImage img = bpixmap.toImage();
- img.invertPixels();
- bpixmap.convertFromImage(img);
+#if QT_VERSION >= 0x050000
+ // With Qt5, we render SVG directly for HiDPI scalability
+ FileName fname = imageLibFileSearch(imagedir, "search-options", "svgz,png");
+ QString fpath = toqstr(fname.absFileName());
+ if (!fpath.isEmpty()) {
+ QSvgRenderer svgRenderer(fpath);
+ if (svgRenderer.isValid()) {
+ pm = QPixmap(bpixmap.size() * dpr);
+ pm.fill(Qt::transparent);
+ QPainter painter(&pm);
+ svgRenderer.render(&painter);
+ pm.setDevicePixelRatio(dpr);
+ }
}
- findLE_->setButtonPixmap(FancyLineEdit::Right, bpixmap);
+#endif
+ }
+ if (dark_mode) {
+ QImage img = pm.toImage();
+ img.invertPixels();
+ pm.convertFromImage(img);
}
+ findLE_->setButtonPixmap(FancyLineEdit::Right, pm);
}
findLE_->setButtonToolTip(FancyLineEdit::Right, tip);
}
More information about the lyx-cvs
mailing list