]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Combine the zoom menu entries into one Line
authorGleb Kasachou <gkosachov99@gmail.com>
Fri, 27 Jun 2025 07:47:21 +0000 (10:47 +0300)
committerMéven Car <meven@kde.org>
Fri, 27 Jun 2025 07:47:21 +0000 (07:47 +0000)
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/CMakeLists.txt
src/views/dolphinviewactionhandler.cpp
src/views/zoomwidgetaction.cpp [new file with mode: 0644]
src/views/zoomwidgetaction.h [new file with mode: 0644]

index 5b02a0f76ebf925253788f632668bafdbdf8546f..bf1ed0101e1e18734caf4182b0a5cc20278993d4 100644 (file)
@@ -117,6 +117,7 @@ target_sources(dolphinprivate PRIVATE
     views/viewmodecontroller.cpp
     views/viewproperties.cpp
     views/zoomlevelinfo.cpp
+    views/zoomwidgetaction.cpp
     dolphinremoveaction.cpp
     middleclickactioneventfilter.cpp
     dolphinnewfilemenu.cpp
@@ -170,6 +171,7 @@ target_sources(dolphinprivate PRIVATE
     views/viewmodecontroller.h
     views/viewproperties.h
     views/zoomlevelinfo.h
+    views/zoomwidgetaction.h
     dolphinremoveaction.h
     middleclickactioneventfilter.h
     dolphinnewfilemenu.h
index ce698a1785259953aab5a3ad429658e8f9731971..e504fd831ab5effbf81c392be6fad2b825213f48 100644 (file)
@@ -12,6 +12,7 @@
 #include "selectionmode/actiontexthelper.h"
 #include "settings/viewpropertiesdialog.h"
 #include "views/zoomlevelinfo.h"
+#include "views/zoomwidgetaction.h"
 
 #if HAVE_BALOO
 #include <Baloo/IndexerConfig>
@@ -251,13 +252,8 @@ void DolphinViewActionHandler::createActions(SelectionMode::ActionTextHelper *ac
     QAction *zoomOutAction = KStandardAction::zoomOut(this, &DolphinViewActionHandler::zoomOut, m_actionCollection);
     zoomOutAction->setWhatsThis(i18nc("@info:whatsthis zoom out", "This reduces the icon size."));
 
-    KActionMenu *zoomMenu = m_actionCollection->add<KActionMenu>(QStringLiteral("zoom"));
-    zoomMenu->setText(i18nc("@action:inmenu menu of zoom actions", "Zoom"));
-    zoomMenu->setIcon(QIcon::fromTheme(QStringLiteral("zoom")));
-    zoomMenu->setPopupMode(QToolButton::InstantPopup);
-    zoomMenu->addAction(zoomInAction);
-    zoomMenu->addAction(zoomResetAction);
-    zoomMenu->addAction(zoomOutAction);
+    ZoomWidgetAction *zoomWidgetAction = new ZoomWidgetAction(zoomInAction, zoomResetAction, zoomOutAction, m_actionCollection);
+    m_actionCollection->addAction(QStringLiteral("zoom"), zoomWidgetAction);
 
     KToggleAction *showPreview = m_actionCollection->add<KToggleAction>(QStringLiteral("show_preview"));
     showPreview->setText(i18nc("@action:intoolbar", "Show Previews"));
@@ -369,7 +365,7 @@ void DolphinViewActionHandler::createActions(SelectionMode::ActionTextHelper *ac
         viewSettings->addAction(action);
     }
     viewSettings->addSeparator();
-    viewSettings->addAction(zoomMenu);
+    viewSettings->addAction(zoomWidgetAction);
     viewSettings->addAction(sortByActionMenu);
     viewSettings->addAction(visibleRolesMenu);
     viewSettings->addAction(showPreview);
diff --git a/src/views/zoomwidgetaction.cpp b/src/views/zoomwidgetaction.cpp
new file mode 100644 (file)
index 0000000..7bd66e3
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Gleb Kasachou <gkosachov99@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "zoomwidgetaction.h"
+
+#include <KLocalizedString>
+
+#include <QEvent>
+#include <QHBoxLayout>
+#include <QKeyEvent>
+#include <QMenu>
+#include <QPaintEvent>
+#include <QStyleOptionMenuItem>
+#include <QStylePainter>
+#include <QToolBar>
+#include <QToolButton>
+
+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<QMenu *>(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<QKeyEvent *>(event);
+    QWidget *widget = qobject_cast<QWidget *>(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<QToolButton *>(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<QToolButton *>(next)->isEnabled()) {
+            return false;
+        }
+
+        next->setFocus(Qt::TabFocusReason);
+        event->accept();
+        return true;
+    }
+
+    return false;
+}
+
+QWidget *ZoomWidgetAction::createWidget(QWidget *parent)
+{
+    if (qobject_cast<QToolBar *>(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;
+}
diff --git a/src/views/zoomwidgetaction.h b/src/views/zoomwidgetaction.h
new file mode 100644 (file)
index 0000000..b55f5e2
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Gleb Kasachou <gkosachov99@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ZOOM_WIDGET_ACTION_H
+#define ZOOM_WIDGET_ACTION_H
+
+#include <KToolBarPopupAction>
+
+/**
+ * This WidgetAction combines the three zoom actions into one line.
+ *
+ * This requires less space, logically groups these actions, and keeps the menu open when the user uses the buttons.
+ */
+
+class ZoomWidgetAction : public KToolBarPopupAction
+{
+public:
+    ZoomWidgetAction(QAction *zoomInAction, QAction *zoomResetAction, QAction *zoomOutAction, QObject *parent);
+
+protected:
+    QWidget *createWidget(QWidget *parent) override;
+    bool eventFilter(QObject *object, QEvent *event) override;
+
+private:
+    QAction *m_zoomInAction;
+    QAction *m_zoomResetAction;
+    QAction *m_zoomOutAction;
+};
+
+#endif