From b6aeec4cc1b16924cffca650f5bcf32d44d9c390 Mon Sep 17 00:00:00 2001 From: Serge45 Date: Mon, 7 Sep 2020 17:40:47 +0800 Subject: [PATCH] feat(ui): use QWidgetAction to implement zoom actions A custom QStyleSheet must be applied to BrowserZoomWidget since QMenu does not handle item highlighting of QWidget in QWidgetAction. --- src/libs/browser/webcontrol.cpp | 5 ++ src/libs/browser/webcontrol.h | 1 + src/libs/ui/browsertab.cpp | 54 ++++++++-------- src/libs/ui/browsertab.h | 1 - src/libs/ui/mainwindow.ui | 12 +++- src/libs/ui/widgets/CMakeLists.txt | 1 + src/libs/ui/widgets/browserzoomwidget.cpp | 75 +++++++++++++++++++++++ src/libs/ui/widgets/browserzoomwidget.h | 26 ++++++++ 8 files changed, 141 insertions(+), 34 deletions(-) create mode 100644 src/libs/ui/widgets/browserzoomwidget.cpp create mode 100644 src/libs/ui/widgets/browserzoomwidget.h diff --git a/src/libs/browser/webcontrol.cpp b/src/libs/browser/webcontrol.cpp index 2b1b6e7be..86db53dad 100644 --- a/src/libs/browser/webcontrol.cpp +++ b/src/libs/browser/webcontrol.cpp @@ -73,6 +73,11 @@ int WebControl::zoomLevel() const return m_webView->zoomLevel(); } +int WebControl::zoomLevelPercentage() const +{ + return m_webView->availableZoomLevels().at(zoomLevel()); +} + void WebControl::setZoomLevel(int level) { m_webView->setZoomLevel(level); diff --git a/src/libs/browser/webcontrol.h b/src/libs/browser/webcontrol.h index 87a211a05..309e6ef08 100644 --- a/src/libs/browser/webcontrol.h +++ b/src/libs/browser/webcontrol.h @@ -54,6 +54,7 @@ class WebControl final : public QWidget QByteArray saveHistory() const; int zoomLevel() const; + int zoomLevelPercentage() const; void setZoomLevel(int level); void setJavaScriptEnabled(bool enabled); diff --git a/src/libs/ui/browsertab.cpp b/src/libs/ui/browsertab.cpp index 4d6a4013f..e6e72523d 100644 --- a/src/libs/ui/browsertab.cpp +++ b/src/libs/ui/browsertab.cpp @@ -25,6 +25,7 @@ #include "searchsidebar.h" #include "widgets/layouthelper.h" #include "widgets/toolbarframe.h" +#include "widgets/browserzoomwidget.h" #include #include @@ -37,10 +38,12 @@ #include #include #include +#include #include #include #include #include +#include using namespace Zeal; using namespace Zeal::WidgetUi; @@ -131,22 +134,38 @@ BrowserTab::BrowserTab(QWidget *parent) m_browserActionButton->setArrowType(Qt::NoArrow); m_browserActionButton->setPopupMode(QToolButton::InstantPopup); - auto browserActionsMenu = new QMenu(m_browserActionButton); + auto zoomActionWidget = new BrowserZoomWidget(); - m_browserZoomInAction = browserActionsMenu->addAction(tr("Zoom In"), [this] () { + connect(zoomActionWidget->zoomInButton(), &QPushButton::clicked, [this, zoomActionWidget]() { m_webControl->zoomIn(); + const auto zoomLevel = QString("%1%").arg(m_webControl->zoomLevelPercentage()); + zoomActionWidget->zoomLevelLabel()->setText(zoomLevel); }); - m_browserZoomOutAction = browserActionsMenu->addAction(tr("Zoom Out"), [this] () { + connect(zoomActionWidget->zoomOutButton(), &QPushButton::clicked, [this, zoomActionWidget]() { m_webControl->zoomOut(); + const auto zoomLevel = QString("%1%").arg(m_webControl->zoomLevelPercentage()); + zoomActionWidget->zoomLevelLabel()->setText(zoomLevel); }); - m_browserResetZoomAction = browserActionsMenu->addAction(tr("Reset Zoom"), [this] () { + connect(zoomActionWidget->resetZoomButton(), &QPushButton::clicked, [this, zoomActionWidget]() { m_webControl->resetZoom(); + const auto zoomLevel = QString("%1%").arg(m_webControl->zoomLevelPercentage()); + zoomActionWidget->zoomLevelLabel()->setText(zoomLevel); + }); + + auto zoomWidgetAction = new QWidgetAction(this); + zoomWidgetAction->setDefaultWidget(zoomActionWidget); + + auto browserActionsMenu = new QMenu(m_browserActionButton); + browserActionsMenu->addAction(zoomWidgetAction); + + connect(browserActionsMenu, &QMenu::aboutToShow, [this, zoomActionWidget] () { + const auto zoomLevel = QString("%1%").arg(m_webControl->zoomLevelPercentage()); + zoomActionWidget->zoomLevelLabel()->setText(zoomLevel); }); m_browserActionButton->setMenu(browserActionsMenu); - browserActionsMenu->installEventFilter(this); auto toolBarLayout = new QHBoxLayout(); toolBarLayout->setContentsMargins(4, 0, 4, 0); @@ -246,28 +265,3 @@ QIcon BrowserTab::docsetIcon(const QUrl &url) const Registry::Docset *docset = Core::Application::instance()->docsetRegistry()->docsetForUrl(url); return docset ? docset->icon() : QIcon(QStringLiteral(":/icons/logo/icon.png")); } - -bool BrowserTab::eventFilter(QObject *watched, QEvent *event) -{ - if (watched == m_browserActionButton->menu()) { - QAction *triggeredAction = nullptr; - - if (event->type() == QEvent::MouseButtonRelease) { - triggeredAction = m_browserActionButton->menu()->activeAction(); - } else if (event->type() == QEvent::KeyPress) { - const auto *keyEvent = static_cast(event); - - if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) { - triggeredAction = m_browserActionButton->menu()->activeAction(); - } - } - - if (triggeredAction - && (triggeredAction == m_browserZoomInAction || triggeredAction == m_browserZoomOutAction)) { - triggeredAction->trigger(); - return true; - } - } - - return false; -} diff --git a/src/libs/ui/browsertab.h b/src/libs/ui/browsertab.h index 824079e6a..140b129fa 100644 --- a/src/libs/ui/browsertab.h +++ b/src/libs/ui/browsertab.h @@ -66,7 +66,6 @@ public slots: private: Q_DISABLE_COPY(BrowserTab) QIcon docsetIcon(const QUrl &url) const; - bool eventFilter(QObject *watched, QEvent *event) override; // Widgets. SearchSidebar *m_searchSidebar = nullptr; diff --git a/src/libs/ui/mainwindow.ui b/src/libs/ui/mainwindow.ui index e8265a2cd..961443572 100644 --- a/src/libs/ui/mainwindow.ui +++ b/src/libs/ui/mainwindow.ui @@ -90,10 +90,16 @@ &Edit + + + &Zoom + + + + + - - - + diff --git a/src/libs/ui/widgets/CMakeLists.txt b/src/libs/ui/widgets/CMakeLists.txt index 09d12dd0b..0a4865087 100644 --- a/src/libs/ui/widgets/CMakeLists.txt +++ b/src/libs/ui/widgets/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(Widgets STATIC searchedit.cpp shortcutedit.cpp toolbarframe.cpp + browserzoomwidget.cpp ) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED) diff --git a/src/libs/ui/widgets/browserzoomwidget.cpp b/src/libs/ui/widgets/browserzoomwidget.cpp new file mode 100644 index 000000000..e227e2f4a --- /dev/null +++ b/src/libs/ui/widgets/browserzoomwidget.cpp @@ -0,0 +1,75 @@ +#include "browserzoomwidget.h" +#include +#include +#include +#include +#include +#include + +BrowserZoomWidget::BrowserZoomWidget(QWidget *parent) +: QWidget(parent) +{ + const auto highlightedBackgroundColor = palette().highlight().color().name(); + const auto highlightedTextColor = palette().highlightedText().color().name(); + const auto styleSheet + = QString("QPushButton:hover { background-color: %1; color: %2; border: none; }").arg(highlightedBackgroundColor) + .arg(highlightedTextColor); + setStyleSheet(styleSheet); + setMouseTracking(true); + auto zoomLabel = new QLabel(tr("Zoom")); + zoomLabel->setMouseTracking(true); + zoomLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + + constexpr int maxButtonWidth = 32; + + m_zoomOutButton = new QPushButton(QStringLiteral("-")); + m_zoomOutButton->setMouseTracking(true); + m_zoomOutButton->setMaximumWidth(maxButtonWidth); + m_zoomOutButton->setToolTip(tr("Zoom out")); + + m_zoomOutButton->setFlat(true); + m_zoomLevelLabel = new QLabel("100%"); + m_zoomLevelLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + m_zoomLevelLabel->setMouseTracking(true); + m_zoomLevelLabel->setToolTip(tr("Current zoom level")); + + m_zoomInButton = new QPushButton(QStringLiteral("+")); + m_zoomInButton->setFlat(true); + m_zoomInButton->setMouseTracking(true); + m_zoomInButton->setMaximumWidth(maxButtonWidth); + m_zoomInButton->setToolTip(tr("Zoom in")); + + m_resetZoomButton = new QPushButton(QStringLiteral("↻")); + m_resetZoomButton->setFlat(true); + m_resetZoomButton->setMouseTracking(true); + m_resetZoomButton->setMaximumWidth(maxButtonWidth); + m_resetZoomButton->setToolTip(tr("Reset zoom level")); + + auto layout = new QHBoxLayout(this); + layout->setSpacing(2); + layout->addWidget(zoomLabel); + layout->addWidget(m_zoomOutButton); + layout->addWidget(m_zoomLevelLabel); + layout->addWidget(m_zoomInButton); + layout->addWidget(m_resetZoomButton); +} + +QPushButton *BrowserZoomWidget::zoomOutButton() +{ + return m_zoomOutButton; +} + +QPushButton *BrowserZoomWidget::zoomInButton() +{ + return m_zoomInButton; +} + +QPushButton *BrowserZoomWidget::resetZoomButton() +{ + return m_resetZoomButton; +} + +QLabel *BrowserZoomWidget::zoomLevelLabel() +{ + return m_zoomLevelLabel; +} diff --git a/src/libs/ui/widgets/browserzoomwidget.h b/src/libs/ui/widgets/browserzoomwidget.h new file mode 100644 index 000000000..6d65a8352 --- /dev/null +++ b/src/libs/ui/widgets/browserzoomwidget.h @@ -0,0 +1,26 @@ +#ifndef BROWSERZOOMWIDGET_H +#define BROWSERZOOMWIDGET_H + +#include + +class QPushButton; +class QLabel; + +class BrowserZoomWidget : public QWidget +{ + Q_OBJECT +public: + explicit BrowserZoomWidget(QWidget *parent = nullptr); + QPushButton *zoomOutButton(); + QPushButton *zoomInButton(); + QPushButton *resetZoomButton(); + QLabel *zoomLevelLabel(); + +private: + QPushButton *m_zoomOutButton{nullptr}; + QPushButton *m_zoomInButton{nullptr}; + QPushButton *m_resetZoomButton{nullptr}; + QLabel *m_zoomLevelLabel{nullptr}; +}; + +#endif // BROWSERZOOMWIDGETACTION_H