From 2e40aef45245bcc14bef59c4b93998d7ae2b0195 Mon Sep 17 00:00:00 2001 From: Gleb Kasachou Date: Fri, 27 Jun 2025 10:47:21 +0300 Subject: Combine the zoom menu entries into one Line Replaced a KActionMenu that contained separate Zoom In, Zoom Out and Reset Zoom actions with a single QWidgetAction that provides the same functionality using three buttons arranged in a single line. Keyboard shortcuts for the three actions are preserved, and the actions still appear separately in the View submenu in the menubar. --- src/views/zoomwidgetaction.cpp | 171 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 src/views/zoomwidgetaction.cpp (limited to 'src/views/zoomwidgetaction.cpp') diff --git a/src/views/zoomwidgetaction.cpp b/src/views/zoomwidgetaction.cpp new file mode 100644 index 000000000..7bd66e300 --- /dev/null +++ b/src/views/zoomwidgetaction.cpp @@ -0,0 +1,171 @@ +/* + * SPDX-FileCopyrightText: 2025 Gleb Kasachou + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "zoomwidgetaction.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ZoomWidget : public QWidget +{ +public: + ZoomWidget(QWidget *parent) + : QWidget(parent) + { + } + +protected: + void paintEvent(QPaintEvent *event) override + { + Q_UNUSED(event); + + QStylePainter painter(this); + QStyleOptionMenuItem option; + option.initFrom(this); + option.menuHasCheckableItems = true; + option.checkType = QStyleOptionMenuItem::NotCheckable; + option.text = i18nc("@action:inmenu", "Zoom"); + option.icon = QIcon::fromTheme(QStringLiteral("zoom")); + option.reservedShortcutWidth = 0; + option.menuItemType = QStyleOptionMenuItem::Normal; + + option.maxIconWidth = 0; + for (QAction *action : qobject_cast(parent())->actions()) { + if (!action->icon().isNull()) { + option.maxIconWidth = style()->pixelMetric(QStyle::PM_SmallIconSize) + 4; + break; + } + } + + painter.drawControl(QStyle::CE_MenuItem, option); + } +}; + +ZoomWidgetAction::ZoomWidgetAction(QAction *zoomInAction, QAction *zoomResetAction, QAction *zoomOutAction, QObject *parent) + : KToolBarPopupAction(QIcon::fromTheme(QStringLiteral("zoom")), i18nc("@action:intoolbar", "Zoom"), parent) + , m_zoomInAction(zoomInAction) + , m_zoomResetAction(zoomResetAction) + , m_zoomOutAction(zoomOutAction) +{ + // This is a property that KXMLGui reads to determine whether this action + // should be included in the shortcut configuration UI + setProperty("isShortcutConfigurable", false); + setPopupMode(InstantPopup); + popupMenu()->addActions({zoomInAction, zoomResetAction, zoomOutAction}); +} + +bool ZoomWidgetAction::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() != QEvent::KeyPress) { + return false; + } + + QKeyEvent *keyEvent = static_cast(event); + QWidget *widget = qobject_cast(object); + + if (keyEvent->keyCombination() == QKeyCombination(Qt::Modifier::SHIFT, Qt::Key_Backtab) || keyEvent->key() == Qt::Key_Left + || keyEvent->key() == Qt::Key_Up) { + QWidget *previous = widget->previousInFocusChain(); + if (previous == widget->parentWidget() || !qobject_cast(previous)->isEnabled()) { + return false; + } + + previous->setFocus(Qt::BacktabFocusReason); + event->accept(); + return true; + } + + if (keyEvent->keyCombination() == QKeyCombination(Qt::Key_Tab) || keyEvent->key() == Qt::Key_Right || keyEvent->key() == Qt::Key_Down) { + QWidget *next = widget->nextInFocusChain(); + if (next->parentWidget() != widget->parentWidget() || !qobject_cast(next)->isEnabled()) { + return false; + } + + next->setFocus(Qt::TabFocusReason); + event->accept(); + return true; + } + + return false; +} + +QWidget *ZoomWidgetAction::createWidget(QWidget *parent) +{ + if (qobject_cast(parent)) { + return KToolBarPopupAction::createWidget(parent); + } + + ZoomWidget *zoomWidget = new ZoomWidget(parent); + QHBoxLayout *zoomWidgetLayout = new QHBoxLayout; + zoomWidgetLayout->setContentsMargins(0, 0, 0, 0); + zoomWidget->setLayout(zoomWidgetLayout); + zoomWidget->setFocusPolicy(Qt::StrongFocus); + + QSpacerItem *zoomSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); + zoomWidgetLayout->addSpacerItem(zoomSpacer); + + int maxButtonSize = parent->style()->pixelMetric(QStyle::PM_ButtonIconSize) + 10; + + QToolButton *zoomOutButton = new QToolButton(zoomWidget); + zoomOutButton->setMaximumSize(maxButtonSize, maxButtonSize); + zoomOutButton->setDefaultAction(m_zoomOutAction); + zoomOutButton->installEventFilter(this); + zoomWidgetLayout->addWidget(zoomOutButton); + zoomWidget->setFocusProxy(zoomOutButton); + + QIcon zoomOutIcon; + QPixmap zoomOutPixmapNormal = m_zoomOutAction->icon().pixmap(zoomOutButton->iconSize(), QIcon::Normal); + QPixmap zoomOutPixmapDisabled = m_zoomOutAction->icon().pixmap(zoomOutButton->iconSize(), QIcon::Disabled); + QPixmap zoomOutPixmapActive = m_zoomOutAction->icon().pixmap(zoomOutButton->iconSize(), QIcon::Active); + zoomOutIcon.addPixmap(zoomOutPixmapNormal, QIcon::Normal); + zoomOutIcon.addPixmap(zoomOutPixmapDisabled, QIcon::Disabled); + zoomOutIcon.addPixmap(zoomOutPixmapActive, QIcon::Active); + zoomOutIcon.addPixmap(zoomOutPixmapNormal, QIcon::Selected); + m_zoomOutAction->setIcon(zoomOutIcon); + + QToolButton *zoomResetButton = new QToolButton(zoomWidget); + zoomResetButton->setMaximumSize(maxButtonSize, maxButtonSize); + zoomResetButton->setDefaultAction(m_zoomResetAction); + zoomResetButton->installEventFilter(this); + zoomWidgetLayout->addWidget(zoomResetButton); + + QIcon zoomResetIcon; + QPixmap zoomResetPixmapNormal = m_zoomResetAction->icon().pixmap(zoomResetButton->iconSize(), QIcon::Normal); + QPixmap zoomResetPixmapDisabled = m_zoomResetAction->icon().pixmap(zoomResetButton->iconSize(), QIcon::Disabled); + QPixmap zoomResetPixmapActive = m_zoomResetAction->icon().pixmap(zoomResetButton->iconSize(), QIcon::Active); + zoomResetIcon.addPixmap(zoomResetPixmapNormal, QIcon::Normal); + zoomResetIcon.addPixmap(zoomResetPixmapDisabled, QIcon::Disabled); + zoomResetIcon.addPixmap(zoomResetPixmapActive, QIcon::Active); + zoomResetIcon.addPixmap(zoomResetPixmapNormal, QIcon::Selected); + m_zoomResetAction->setIcon(zoomResetIcon); + + QToolButton *zoomInButton = new QToolButton(zoomWidget); + zoomInButton->setMaximumSize(maxButtonSize, maxButtonSize); + zoomInButton->setDefaultAction(m_zoomInAction); + zoomInButton->installEventFilter(this); + zoomWidgetLayout->addWidget(zoomInButton); + + QIcon zoomInIcon; + QPixmap zoomInPixmapNormal = m_zoomInAction->icon().pixmap(zoomInButton->iconSize(), QIcon::Normal); + QPixmap zoomInPixmapDisabled = m_zoomInAction->icon().pixmap(zoomInButton->iconSize(), QIcon::Disabled); + QPixmap zoomInPixmapActive = m_zoomInAction->icon().pixmap(zoomInButton->iconSize(), QIcon::Active); + zoomInIcon.addPixmap(zoomInPixmapNormal, QIcon::Normal); + zoomInIcon.addPixmap(zoomInPixmapDisabled, QIcon::Disabled); + zoomInIcon.addPixmap(zoomInPixmapActive, QIcon::Active); + zoomInIcon.addPixmap(zoomInPixmapNormal, QIcon::Selected); + m_zoomInAction->setIcon(zoomInIcon); + + return zoomWidget; +} -- cgit v1.3