diff --git a/gui/include/Visualization/IVisualizationWidget.h b/gui/include/Visualization/IVisualizationWidget.h index 4bbafbb..5713a2a 100644 --- a/gui/include/Visualization/IVisualizationWidget.h +++ b/gui/include/Visualization/IVisualizationWidget.h @@ -18,7 +18,6 @@ public: /// Initializes the plugin virtual void accept(IVisualizationWidgetVisitor *visitor) = 0; - virtual void close() = 0; virtual QString name() const = 0; }; diff --git a/gui/include/Visualization/VisualizationGraphWidget.h b/gui/include/Visualization/VisualizationGraphWidget.h index d23cbc5..15b93e9 100644 --- a/gui/include/Visualization/VisualizationGraphWidget.h +++ b/gui/include/Visualization/VisualizationGraphWidget.h @@ -27,11 +27,12 @@ public: virtual ~VisualizationGraphWidget(); void addVariable(std::shared_ptr variable); + /// Removes a variable from the graph + void removeVariable(std::shared_ptr variable) noexcept; // IVisualizationWidget interface void accept(IVisualizationWidgetVisitor *visitor) override; bool canDrop(const Variable &variable) const override; - void close() override; QString name() const override; void updateDisplay(std::shared_ptr variable); @@ -44,6 +45,8 @@ private: spimpl::unique_impl_ptr impl; private slots: + /// Slot called when right clicking on the graph (displays a menu) + void onGraphMenuRequested(const QPoint &pos) noexcept; void onRangeChanged(const QCPRange &t1, const QCPRange &t2); diff --git a/gui/include/Visualization/VisualizationTabWidget.h b/gui/include/Visualization/VisualizationTabWidget.h index 2adcb91..6c25cc8 100644 --- a/gui/include/Visualization/VisualizationTabWidget.h +++ b/gui/include/Visualization/VisualizationTabWidget.h @@ -35,13 +35,9 @@ public: */ VisualizationZoneWidget *createZone(std::shared_ptr variable); - /// Remove a zone - void removeZone(VisualizationZoneWidget *zone); - // IVisualizationWidget interface void accept(IVisualizationWidgetVisitor *visitor) override; bool canDrop(const Variable &variable) const override; - void close() override; QString name() const override; private: diff --git a/gui/include/Visualization/VisualizationWidget.h b/gui/include/Visualization/VisualizationWidget.h index ca74bdf..2321bbd 100644 --- a/gui/include/Visualization/VisualizationWidget.h +++ b/gui/include/Visualization/VisualizationWidget.h @@ -23,19 +23,9 @@ public: explicit VisualizationWidget(QWidget *parent = 0); virtual ~VisualizationWidget(); - /// Add a zone widget - virtual void addTab(VisualizationTabWidget *tabWidget); - - /// Create a tab using a Variable - VisualizationTabWidget *createTab(); - - /// Remove a tab - void removeTab(VisualizationTabWidget *tab); - // IVisualizationWidget interface void accept(IVisualizationWidgetVisitor *visitor) override; bool canDrop(const Variable &variable) const override; - void close() override; QString name() const override; public slots: diff --git a/gui/include/Visualization/VisualizationZoneWidget.h b/gui/include/Visualization/VisualizationZoneWidget.h index 9aa4a78..7732a9f 100644 --- a/gui/include/Visualization/VisualizationZoneWidget.h +++ b/gui/include/Visualization/VisualizationZoneWidget.h @@ -32,13 +32,9 @@ public: */ VisualizationGraphWidget *createGraph(std::shared_ptr variable); - /// Remove a graph - void removeGraph(VisualizationGraphWidget *graph); - // IVisualizationWidget interface void accept(IVisualizationWidgetVisitor *visitor) override; bool canDrop(const Variable &variable) const override; - void close() override; QString name() const override; private: diff --git a/gui/src/Visualization/VisualizationGraphWidget.cpp b/gui/src/Visualization/VisualizationGraphWidget.cpp index edd5cd3..444ea46 100644 --- a/gui/src/Visualization/VisualizationGraphWidget.cpp +++ b/gui/src/Visualization/VisualizationGraphWidget.cpp @@ -26,8 +26,7 @@ const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier; struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { // 1 variable -> n qcpplot - std::unordered_multimap, QCPAbstractPlottable *> - m_VariableToPlotMultiMap; + std::multimap, QCPAbstractPlottable *> m_VariableToPlotMultiMap; }; VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent) @@ -37,9 +36,12 @@ VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget { ui->setupUi(this); - // qcpplot title - ui->widget->plotLayout()->insertRow(0); - ui->widget->plotLayout()->addElement(0, 0, new QCPTextElement{ui->widget, name}); + ui->graphNameLabel->setText(name); + + // 'Close' options : widget is deleted when closed + setAttribute(Qt::WA_DeleteOnClose); + connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close); + ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton)); // Set qcpplot properties : // - Drag (on x-axis) and zoom are enabled @@ -50,6 +52,11 @@ VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget connect(ui->widget->xAxis, static_cast( &QCPAxis::rangeChanged), this, &VisualizationGraphWidget::onRangeChanged); + + // Activates menu when right clicking on the graph + ui->widget->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->widget, &QCustomPlot::customContextMenuRequested, this, + &VisualizationGraphWidget::onGraphMenuRequested); } @@ -70,6 +77,21 @@ void VisualizationGraphWidget::addVariable(std::shared_ptr variable) connect(variable.get(), SIGNAL(dataCacheUpdated()), this, SLOT(onDataCacheVariableUpdated())); } +void VisualizationGraphWidget::removeVariable(std::shared_ptr variable) noexcept +{ + // Each component associated to the variable : + // - is removed from qcpplot (which deletes it) + // - is no longer referenced in the map + auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable); + for (auto it = componentsIt.first; it != componentsIt.second;) { + ui->widget->removePlottable(it->second); + it = impl->m_VariableToPlotMultiMap.erase(it); + } + + // Updates graph + ui->widget->replot(); +} + void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor) { if (visitor) { @@ -88,19 +110,26 @@ bool VisualizationGraphWidget::canDrop(const Variable &variable) const return true; } -void VisualizationGraphWidget::close() +QString VisualizationGraphWidget::name() const { - // The main view cannot be directly closed. - return; + return ui->graphNameLabel->text(); } -QString VisualizationGraphWidget::name() const +void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept { - if (auto title = dynamic_cast(ui->widget->plotLayout()->elementAt(0))) { - return title->text(); + QMenu graphMenu{}; + + // Iterates on variables (unique keys) + for (auto it = impl->m_VariableToPlotMultiMap.cbegin(), + end = impl->m_VariableToPlotMultiMap.cend(); + it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) { + // 'Remove variable' action + graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()), + [ this, var = it->first ]() { removeVariable(var); }); } - else { - return QString{}; + + if (!graphMenu.isEmpty()) { + graphMenu.exec(mapToGlobal(pos)); } } diff --git a/gui/src/Visualization/VisualizationTabWidget.cpp b/gui/src/Visualization/VisualizationTabWidget.cpp index 7d68276..8b404dd 100644 --- a/gui/src/Visualization/VisualizationTabWidget.cpp +++ b/gui/src/Visualization/VisualizationTabWidget.cpp @@ -36,6 +36,9 @@ VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par impl{spimpl::make_unique_impl(name)} { ui->setupUi(this); + + // Widget is deleted when closed + setAttribute(Qt::WA_DeleteOnClose); } VisualizationTabWidget::~VisualizationTabWidget() @@ -59,10 +62,6 @@ VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptrm_Name; diff --git a/gui/src/Visualization/VisualizationWidget.cpp b/gui/src/Visualization/VisualizationWidget.cpp index cccc592..8f04c44 100644 --- a/gui/src/Visualization/VisualizationWidget.cpp +++ b/gui/src/Visualization/VisualizationWidget.cpp @@ -48,7 +48,13 @@ VisualizationWidget::VisualizationWidget(QWidget *parent) enableMinimumCornerWidgetSize(true); } + // Removes widget from tab and closes it + auto widget = ui->tabWidget->widget(index); ui->tabWidget->removeTab(index); + if (widget) { + widget->close(); + } + qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index); }; @@ -67,22 +73,6 @@ VisualizationWidget::~VisualizationWidget() delete ui; } -void VisualizationWidget::addTab(VisualizationTabWidget *tabWidget) -{ - // NOTE: check is this method has to be deleted because of its dupplicated version visible as - // lambda function (in the constructor) -} - -VisualizationTabWidget *VisualizationWidget::createTab() -{ -} - -void VisualizationWidget::removeTab(VisualizationTabWidget *tab) -{ - // NOTE: check is this method has to be deleted because of its dupplicated version visible as - // lambda function (in the constructor) -} - void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor) { if (visitor) { @@ -111,12 +101,6 @@ bool VisualizationWidget::canDrop(const Variable &variable) const return false; } -void VisualizationWidget::close() -{ - // The main view cannot be directly closed. - return; -} - QString VisualizationWidget::name() const { return QStringLiteral("MainView"); diff --git a/gui/src/Visualization/VisualizationZoneWidget.cpp b/gui/src/Visualization/VisualizationZoneWidget.cpp index 0d60830..2a4eb95 100644 --- a/gui/src/Visualization/VisualizationZoneWidget.cpp +++ b/gui/src/Visualization/VisualizationZoneWidget.cpp @@ -4,6 +4,8 @@ #include "Visualization/VisualizationGraphWidget.h" +#include + Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget") namespace { @@ -30,6 +32,11 @@ VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p ui->setupUi(this); ui->zoneNameLabel->setText(name); + + // 'Close' options : widget is deleted when closed + setAttribute(Qt::WA_DeleteOnClose); + connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close); + ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton)); } VisualizationZoneWidget::~VisualizationZoneWidget() @@ -53,10 +60,6 @@ VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptrzoneNameLabel->text(); diff --git a/gui/ui/Visualization/VisualizationGraphWidget.ui b/gui/ui/Visualization/VisualizationGraphWidget.ui index bcecbc4..69df1b0 100644 --- a/gui/ui/Visualization/VisualizationGraphWidget.ui +++ b/gui/ui/Visualization/VisualizationGraphWidget.ui @@ -15,7 +15,58 @@ - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + font: 75 9pt "MS Shell Dlg 2"; + + + TextLabel + + + Qt::AutoText + + + Qt::AlignCenter + + + + + + + background-color: transparent; + + + Close + + + + + + + + + + + 0 + 0 + + + diff --git a/gui/ui/Visualization/VisualizationZoneWidget.ui b/gui/ui/Visualization/VisualizationZoneWidget.ui index 1c2920e..fe266c5 100644 --- a/gui/ui/Visualization/VisualizationZoneWidget.ui +++ b/gui/ui/Visualization/VisualizationZoneWidget.ui @@ -46,6 +46,16 @@ + + + + background-color: transparent; + + + Close + + +