From b1f93bc51e60fec0a5337400aa02d1ecf8ae1d16 Mon Sep 17 00:00:00 2001 From: xtemp09 Date: Fri, 13 Dec 2024 23:52:51 +0700 Subject: [PATCH] [Spreadsheet] Enable zoom in Spreadsheet (#16130) * [Spreadsheet] Enable zoom in Spreadsheet Closes #6094. This commit also fixes page tab order of Spreadsheet settings in Preferences. * Spreadsheet: apply clang-format --------- Co-authored-by: Chris Hennes --- src/Mod/Spreadsheet/Gui/CMakeLists.txt | 2 + src/Mod/Spreadsheet/Gui/DlgSettings.ui | 116 +++++++--- src/Mod/Spreadsheet/Gui/DlgSettingsImp.cpp | 2 + src/Mod/Spreadsheet/Gui/Sheet.ui | 149 ++++++++++++- src/Mod/Spreadsheet/Gui/SheetTableView.cpp | 47 ++-- src/Mod/Spreadsheet/Gui/SheetTableView.h | 4 +- src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp | 4 +- src/Mod/Spreadsheet/Gui/ZoomableView.cpp | 231 ++++++++++++++++++++ src/Mod/Spreadsheet/Gui/ZoomableView.h | 83 +++++++ 9 files changed, 576 insertions(+), 62 deletions(-) create mode 100644 src/Mod/Spreadsheet/Gui/ZoomableView.cpp create mode 100644 src/Mod/Spreadsheet/Gui/ZoomableView.h diff --git a/src/Mod/Spreadsheet/Gui/CMakeLists.txt b/src/Mod/Spreadsheet/Gui/CMakeLists.txt index 35e130667f..f6a6a2f3af 100644 --- a/src/Mod/Spreadsheet/Gui/CMakeLists.txt +++ b/src/Mod/Spreadsheet/Gui/CMakeLists.txt @@ -86,6 +86,8 @@ SET(SpreadsheetGui_SRCS DlgBindSheet.cpp DlgSheetConf.h DlgSheetConf.cpp + ZoomableView.h + ZoomableView.cpp ${SpreadsheetGui_UIC_HDRS} ) diff --git a/src/Mod/Spreadsheet/Gui/DlgSettings.ui b/src/Mod/Spreadsheet/Gui/DlgSettings.ui index 947d5e2961..e6f19c4313 100644 --- a/src/Mod/Spreadsheet/Gui/DlgSettings.ui +++ b/src/Mod/Spreadsheet/Gui/DlgSettings.ui @@ -6,8 +6,8 @@ 0 0 - 322 - 149 + 392 + 282 @@ -25,8 +25,8 @@ Display Settings - - + + If checked, use the custom presentation to display cell string. @@ -42,7 +42,62 @@ - + + + + Set a zoom level for table view from 60% to 160%. + + + % + + + 60 + + + 160 + + + 10 + + + 100 + + + DefaultZoomLevel + + + Mod/Spreadsheet + + + + + + + Default zoom level: + + + + + + + The format of the custom cell string presentation. +Defaults to: %V = %A + +%A - alias name +%V - cell value + + + %V = %A + + + DisplayAliasFormatString + + + Mod/Spreadsheet + + + + Qt::Horizontal @@ -55,26 +110,6 @@ - - - - %V = %A - - - The format of the custom cell string presentation. -Defaults to: %V = %A - -%A - alias name -%V - cell value - - - DisplayAliasFormatString - - - Mod/Spreadsheet - - - @@ -110,10 +145,10 @@ Defaults to: %V = %A - + - <html><head/><body><p>Character to use as field delimiter. Default is tab, but also commonly used are commas (,) and semicolons (;). Select from the list or enter your own in the field. Must be a single character or the words <span style=" font-style:italic;">tab</span>, <span style=" font-style:italic;">comma</span>, or <span style=" font-style:italic;">semicolon</span>.</p></body></html> + <html><head/><body><p>Character to use as field delimiter. Default is tab, but also commonly used are commas (,) and semicolons (;). Select from the list or enter your own in the field. Must be a single character or the words <span style=" font-style:italic;">tab</span>, <span style=" font-style:italic;">comma</span>, or <span style=" font-style:italic;">semicolon</span>.</p></body></html> true @@ -166,7 +201,7 @@ Defaults to: %V = %A - " + " ImportExportQuoteCharacter @@ -205,7 +240,7 @@ Defaults to: %V = %A - + @@ -225,22 +260,35 @@ Defaults to: %V = %A + + Gui::PrefCheckBox + QCheckBox +
Gui/PrefWidgets.h
+
Gui::PrefComboBox QComboBox
Gui/PrefWidgets.h
+ + Gui::PrefSpinBox + QSpinBox +
Gui/PrefWidgets.h
+
Gui::PrefLineEdit QLineEdit
Gui/PrefWidgets.h
- - Gui::PrefCheckBox - QCheckBox -
Gui/PrefWidgets.h
-
+ + delimiterComboBox + quoteCharLineEdit + escapeCharLineEdit + dZLSpinBox + checkBoxShowAlias + formatString + diff --git a/src/Mod/Spreadsheet/Gui/DlgSettingsImp.cpp b/src/Mod/Spreadsheet/Gui/DlgSettingsImp.cpp index d90e4fc54b..f301917e46 100644 --- a/src/Mod/Spreadsheet/Gui/DlgSettingsImp.cpp +++ b/src/Mod/Spreadsheet/Gui/DlgSettingsImp.cpp @@ -57,6 +57,7 @@ void DlgSettingsImp::saveSettings() ui->quoteCharLineEdit->onSave(); ui->escapeCharLineEdit->onSave(); ui->formatString->onSave(); + ui->dZLSpinBox->onSave(); ui->checkBoxShowAlias->onSave(); } @@ -94,6 +95,7 @@ void DlgSettingsImp::loadSettings() ui->quoteCharLineEdit->onRestore(); ui->escapeCharLineEdit->onRestore(); ui->formatString->onRestore(); + ui->dZLSpinBox->onRestore(); ui->checkBoxShowAlias->onRestore(); } diff --git a/src/Mod/Spreadsheet/Gui/Sheet.ui b/src/Mod/Spreadsheet/Gui/Sheet.ui index 0a0c47596e..9d1f78bfe0 100644 --- a/src/Mod/Spreadsheet/Gui/Sheet.ui +++ b/src/Mod/Spreadsheet/Gui/Sheet.ui @@ -57,7 +57,154 @@ Spreadsheet.my_alias_name instead of Spreadsheet.B1
- + + + + + + + + + 0 + 0 + + + + 5 + + + 20 + + + Qt::Vertical + + + + + + + + + + + + 0 + 0 + + + + 5 + + + 20 + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + Zoom + + + Qt::ToolButtonTextOnly + + + true + + + + + + + Qt::ClickFocus + + + - + + + Qt::ToolButtonTextOnly + + + true + + + + + + + + 0 + 0 + + + + Qt::ClickFocus + + + 60 + + + 160 + + + 10 + + + 20 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 10 + + + + + + + Qt::ClickFocus + + + + + + + Qt::ToolButtonTextOnly + + + true + + + + diff --git a/src/Mod/Spreadsheet/Gui/SheetTableView.cpp b/src/Mod/Spreadsheet/Gui/SheetTableView.cpp index 3a9f33585c..e956370843 100644 --- a/src/Mod/Spreadsheet/Gui/SheetTableView.cpp +++ b/src/Mod/Spreadsheet/Gui/SheetTableView.cpp @@ -119,7 +119,7 @@ SheetTableView::SheetTableView(QWidget* parent) setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); connect(verticalHeader(), &QWidget::customContextMenuRequested, [this](const QPoint& point) { - QMenu menu(this); + QMenu menu {nullptr}; const auto selection = selectionModel()->selectedRows(); const auto& [min, max] = selectedMinMaxRows(selection); if (bool isContiguous = max - min == selection.size() - 1) { @@ -141,11 +141,11 @@ SheetTableView::SheetTableView(QWidget* parent) } auto remove = menu.addAction(tr("Remove row(s)", "", selection.size())); connect(remove, &QAction::triggered, this, &SheetTableView::removeRows); - menu.exec(verticalHeader()->mapToGlobal(point)); + menu.exec(QCursor::pos()); }); connect(horizontalHeader(), &QWidget::customContextMenuRequested, [this](const QPoint& point) { - QMenu menu(this); + QMenu menu {nullptr}; const auto selection = selectionModel()->selectedColumns(); const auto& [min, max] = selectedMinMaxColumns(selection); if (bool isContiguous = max - min == selection.size() - 1) { @@ -171,7 +171,7 @@ SheetTableView::SheetTableView(QWidget* parent) } auto remove = menu.addAction(tr("Remove column(s)", "", selection.size())); connect(remove, &QAction::triggered, this, &SheetTableView::removeColumns); - menu.exec(horizontalHeader()->mapToGlobal(point)); + menu.exec(QCursor::pos()); }); actionProperties = new QAction(tr("Properties..."), this); @@ -180,41 +180,40 @@ SheetTableView::SheetTableView(QWidget* parent) horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); verticalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); - contextMenu = new QMenu(this); - contextMenu->addAction(actionProperties); + contextMenu.addAction(actionProperties); connect(actionProperties, &QAction::triggered, this, &SheetTableView::cellProperties); - contextMenu->addSeparator(); + contextMenu.addSeparator(); actionRecompute = new QAction(tr("Recompute"), this); connect(actionRecompute, &QAction::triggered, this, &SheetTableView::onRecompute); - contextMenu->addAction(actionRecompute); + contextMenu.addAction(actionRecompute); actionBind = new QAction(tr("Bind..."), this); connect(actionBind, &QAction::triggered, this, &SheetTableView::onBind); - contextMenu->addAction(actionBind); + contextMenu.addAction(actionBind); actionConf = new QAction(tr("Configuration table..."), this); connect(actionConf, &QAction::triggered, this, &SheetTableView::onConfSetup); - contextMenu->addAction(actionConf); + contextMenu.addAction(actionConf); horizontalHeader()->addAction(actionBind); verticalHeader()->addAction(actionBind); - contextMenu->addSeparator(); - actionMerge = contextMenu->addAction(tr("Merge cells")); + contextMenu.addSeparator(); + actionMerge = contextMenu.addAction(tr("Merge cells")); connect(actionMerge, &QAction::triggered, this, &SheetTableView::mergeCells); - actionSplit = contextMenu->addAction(tr("Split cells")); + actionSplit = contextMenu.addAction(tr("Split cells")); connect(actionSplit, &QAction::triggered, this, &SheetTableView::splitCell); - contextMenu->addSeparator(); - actionCut = contextMenu->addAction(tr("Cut")); + contextMenu.addSeparator(); + actionCut = contextMenu.addAction(tr("Cut")); connect(actionCut, &QAction::triggered, this, &SheetTableView::cutSelection); - actionCopy = contextMenu->addAction(tr("Copy")); + actionCopy = contextMenu.addAction(tr("Copy")); connect(actionCopy, &QAction::triggered, this, &SheetTableView::copySelection); - actionPaste = contextMenu->addAction(tr("Paste")); + actionPaste = contextMenu.addAction(tr("Paste")); connect(actionPaste, &QAction::triggered, this, &SheetTableView::pasteClipboard); - actionDel = contextMenu->addAction(tr("Delete")); + actionDel = contextMenu.addAction(tr("Delete")); connect(actionDel, &QAction::triggered, this, &SheetTableView::deleteSelection); setTabKeyNavigation(false); @@ -241,7 +240,7 @@ void SheetTableView::onBind() { auto ranges = selectedRanges(); if (!ranges.empty() && ranges.size() <= 2) { - DlgBindSheet dlg(sheet, ranges, this); + DlgBindSheet dlg {sheet, ranges}; dlg.exec(); } } @@ -252,16 +251,16 @@ void SheetTableView::onConfSetup() if (ranges.empty()) { return; } - DlgSheetConf dlg(sheet, ranges.back(), this); + DlgSheetConf dlg {sheet, ranges.back()}; dlg.exec(); } void SheetTableView::cellProperties() { - std::unique_ptr dialog(new PropertiesDialog(sheet, selectedRanges(), this)); + PropertiesDialog dialog {sheet, selectedRanges()}; - if (dialog->exec() == QDialog::Accepted) { - dialog->apply(); + if (dialog.exec() == QDialog::Accepted) { + dialog.apply(); } } @@ -1125,7 +1124,7 @@ void SheetTableView::contextMenuEvent(QContextMenuEvent*) auto ranges = selectedRanges(); actionBind->setEnabled(!ranges.empty() && ranges.size() <= 2); - contextMenu->exec(QCursor::pos()); + contextMenu.exec(QCursor::pos()); } QString SheetTableView::toHtml() const diff --git a/src/Mod/Spreadsheet/Gui/SheetTableView.h b/src/Mod/Spreadsheet/Gui/SheetTableView.h index 4c41900974..e63af97da9 100644 --- a/src/Mod/Spreadsheet/Gui/SheetTableView.h +++ b/src/Mod/Spreadsheet/Gui/SheetTableView.h @@ -26,7 +26,7 @@ #include #include #include - +#include #include @@ -109,7 +109,7 @@ protected: Spreadsheet::Sheet* sheet; int tabCounter; - QMenu* contextMenu; + QMenu contextMenu; QAction* actionProperties; QAction* actionRecompute; diff --git a/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp b/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp index 3a7a009943..fb276b562a 100644 --- a/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp +++ b/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #endif #include @@ -47,6 +46,7 @@ #include "LineEdit.h" #include "SpreadsheetDelegate.h" #include "SpreadsheetView.h" +#include "ZoomableView.h" #include "qtcolorpicker.h" #include "ui_Sheet.h" @@ -74,6 +74,8 @@ SheetView::SheetView(Gui::Document* pcDocument, App::DocumentObject* docObj, QWi ui->setupUi(w); setCentralWidget(w); + new ZoomableView(ui); + delegate = new SpreadsheetDelegate(sheet); ui->cells->setModel(model); ui->cells->setItemDelegate(delegate); diff --git a/src/Mod/Spreadsheet/Gui/ZoomableView.cpp b/src/Mod/Spreadsheet/Gui/ZoomableView.cpp new file mode 100644 index 0000000000..3efcd32a29 --- /dev/null +++ b/src/Mod/Spreadsheet/Gui/ZoomableView.cpp @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/**************************************************************************** + * * + * Copyright (c) 2024 xtemp09 * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +#include +#include + +#include "ZoomableView.h" +#include "ui_Sheet.h" + + +ZoomableView::ZoomableView(Ui::Sheet* ui) + : QGraphicsView {} + , stv {ui->cells} +{ + if (!stv) { + Base::Console().DeveloperWarning("ZoomableView", "Failed to find a SheetTableView object"); + deleteLater(); + return; + } + else { + QLayoutItem* li_stv = stv->parentWidget()->layout()->replaceWidget(stv, this); + if (li_stv == nullptr) { + Base::Console().DeveloperWarning("ZoomableView", + "Failed to replace the SheetTableView object"); + deleteLater(); + return; + } + delete li_stv; + } + + stv->setParent(nullptr); + qpw = m_scene.addWidget(stv); + setScene(&m_scene); + + setBackgroundBrush(Qt::transparent); + setFrameStyle(QFrame::NoFrame); + + setSizePolicy(QSizePolicy {QSizePolicy::Expanding, QSizePolicy::Expanding}); + + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + stv->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + stv->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + QPointer dummySB_h {stv->horizontalScrollBar()}, + dummySB_v {stv->verticalScrollBar()}, realSB_h {ui->realSB_h}, realSB_v {ui->realSB_v}; + + if (!dummySB_h || !dummySB_v || !realSB_h || !realSB_v) { + Base::Console().DeveloperWarning("ZoomableView", "Failed to identify the scrollbars"); + deleteLater(); + return; + } + + realSB_h->setRange(dummySB_h->minimum(), dummySB_h->maximum()); + realSB_v->setRange(dummySB_v->minimum(), dummySB_v->maximum()); + + realSB_h->setPageStep(dummySB_h->pageStep()); + realSB_v->setPageStep(dummySB_v->pageStep()); + + + connect(realSB_h, &QAbstractSlider::valueChanged, dummySB_h, &QAbstractSlider::setValue); + connect(realSB_v, &QAbstractSlider::valueChanged, dummySB_v, &QAbstractSlider::setValue); + + connect(dummySB_h, &QAbstractSlider::rangeChanged, realSB_h, &QAbstractSlider::setRange); + connect(dummySB_v, &QAbstractSlider::rangeChanged, realSB_v, &QAbstractSlider::setRange); + + connect(dummySB_h, &QAbstractSlider::valueChanged, this, &ZoomableView::updateView); + connect(dummySB_v, &QAbstractSlider::valueChanged, this, &ZoomableView::updateView); + + connect(this, + &ZoomableView::zoomLevelChanged, + ui->zoomTB, + [zoomTB = ui->zoomTB](int new_zoomLevel) { + zoomTB->setText(QStringLiteral("%1%").arg(new_zoomLevel)); + }); + + connect(this, + &ZoomableView::zoomLevelChanged, + ui->zoomSlider, + [zoomSlider = ui->zoomSlider](int new_zoomLevel) { + zoomSlider->blockSignals(true); + zoomSlider->setValue(new_zoomLevel); + zoomSlider->blockSignals(false); + }); + + connect(ui->zoomPlus, &QToolButton::clicked, this, &ZoomableView::zoomIn); + connect(ui->zoomSlider, &QSlider::valueChanged, this, &ZoomableView::setZoomLevel); + connect(ui->zoomMinus, &QToolButton::clicked, this, &ZoomableView::zoomOut); + + connect(ui->zoomTB, &QToolButton::clicked, ui->zoomSlider, [zoomSlider = ui->zoomSlider]() { + const QString title = tr("Zoom level"), label = tr("New zoom level:"); + constexpr int min = ZoomableView::min, max = ZoomableView::max, step = 10; + const int val = zoomSlider->value(); + bool ok; + const int new_val = + QInputDialog::getInt(zoomSlider, title, label, val, min, max, step, &ok); + + if (ok) { + zoomSlider->setValue(new_val); + } + }); + + resetZoom(); +} + +int ZoomableView::zoomLevel() const +{ + return m_zoomLevel; +} + +void ZoomableView::setZoomLevel(int new_zoomLevel) +{ + checkLimits(new_zoomLevel); + + if (m_zoomLevel == new_zoomLevel) { + return; + } + + m_zoomLevel = new_zoomLevel; + updateView(); + Q_EMIT zoomLevelChanged(m_zoomLevel); +} + +inline void ZoomableView::checkLimits(int& zoom_level) +{ + zoom_level = qBound(ZoomableView::min, zoom_level, ZoomableView::max); +} + +void ZoomableView::zoomIn(void) +{ + setZoomLevel(m_zoomLevel + zoom_step_kb); +} + +void ZoomableView::zoomOut(void) +{ + setZoomLevel(m_zoomLevel - zoom_step_kb); +} + +void ZoomableView::resetZoom(void) +{ + constexpr const char* path = "User parameter:BaseApp/Preferences/Mod/Spreadsheet"; + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(path); + const int defaultZoomLevel = static_cast(hGrp->GetInt("DefaultZoomLevel", 100)); + + setZoomLevel(defaultZoomLevel); +} + +void ZoomableView::updateView(void) +{ + /* QGraphicsView has hardcoded margins therefore we have to avoid fitInView + * Find more information at https://bugreports.qt.io/browse/QTBUG-42331 */ + + const qreal scale_factor = static_cast(m_zoomLevel) / 100.0, + new_w = static_cast(viewport()->rect().width()) / scale_factor, + new_h = static_cast(viewport()->rect().height()) / scale_factor; + + const QRectF new_geometry {0.0, 0.0, new_w, new_h}; + + const QRect old_geometry {stv->geometry()}; + stv->setGeometry(1, 1, old_geometry.width() - 1, old_geometry.height() - 1); + + resetTransform(); + qpw->setGeometry(new_geometry); + setSceneRect(new_geometry); + scale(scale_factor, scale_factor); + centerOn(new_geometry.center()); +} + +void ZoomableView::keyPressEvent(QKeyEvent* event) +{ + if (event->modifiers() & Qt::ControlModifier) { + switch (event->key()) { + case Qt::Key_Plus: + zoomIn(); + event->accept(); + break; + case Qt::Key_Minus: + zoomOut(); + event->accept(); + break; + case Qt::Key_0: + resetZoom(); + event->accept(); + break; + default: + QGraphicsView::keyPressEvent(event); + } + } + else { + QGraphicsView::keyPressEvent(event); + } +} + +void ZoomableView::resizeEvent(QResizeEvent* event) +{ + QGraphicsView::resizeEvent(event); + updateView(); +} + +void ZoomableView::wheelEvent(QWheelEvent* event) +{ + if (event->modifiers() & Qt::ControlModifier) { + const int y = event->angleDelta().y(); + setZoomLevel(m_zoomLevel + (y > 0 ? zoom_step_mwheel : -zoom_step_mwheel)); + event->accept(); + } + else { + QGraphicsView::wheelEvent(event); + } +} diff --git a/src/Mod/Spreadsheet/Gui/ZoomableView.h b/src/Mod/Spreadsheet/Gui/ZoomableView.h new file mode 100644 index 0000000000..7f14abb7ff --- /dev/null +++ b/src/Mod/Spreadsheet/Gui/ZoomableView.h @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/**************************************************************************** + * * + * Copyright (c) 2024 xtemp09 * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +#ifndef ZOOMABLEVIEW_H +#define ZOOMABLEVIEW_H + +#include + +#include "SpreadsheetView.h" + +namespace SpreadsheetGui +{ +class SheetTableView; +} + +class ZoomableView: public QGraphicsView +{ + Q_OBJECT + Q_PROPERTY(int zoomLevel READ zoomLevel() WRITE setZoomLevel NOTIFY zoomLevelChanged) +public: + /*! + * \brief A descendant of QGraphicsView to show a SheetTableView object in its viewport, + * allowing magnification. \param ui \details The object replaces SheetTableView in layout, + * handling mouse and keyboard events. + */ + explicit ZoomableView(Ui::Sheet* ui); + ~ZoomableView() override = default; + + int zoomLevel() const; + void setZoomLevel(int new_scale); + + + static constexpr int min {60}, max {160}; + static void checkLimits(int& zoom_level); + +Q_SIGNALS: + void zoomLevelChanged(int); /// This signal is emitted whenever zoom level is changed. It is + /// used to show the zoom level in the zoom button. + +public Q_SLOTS: + void zoomIn(void); /// This function is the slot for the zoomIn button and a keyboard shortcut + void + zoomOut(void); /// This function is the slot for the zoomOut button and a keyboard shortcut + void resetZoom(void); /// This function is the slot for a keyboard shortcut + +private: + void updateView(void); + + QPointer stv; + QGraphicsScene m_scene; + QGraphicsProxyWidget* qpw; + + int m_zoomLevel; + +protected: + void keyPressEvent(QKeyEvent* event) override; + void resizeEvent(QResizeEvent* event) override; + void wheelEvent(QWheelEvent* event) override; + + static constexpr int zoom_step_mwheel {5}, zoom_step_kb {10}; +}; + +#endif // ZOOMABLEVIEW_H