diff --git a/Software/PC_Application/CustomWidgets/tilewidget.cpp b/Software/PC_Application/CustomWidgets/tilewidget.cpp index 51e3abd..2c8e1cb 100644 --- a/Software/PC_Application/CustomWidgets/tilewidget.cpp +++ b/Software/PC_Application/CustomWidgets/tilewidget.cpp @@ -122,24 +122,24 @@ bool TileWidget::allLimitsPassing() } } -void TileWidget::splitVertically() +void TileWidget::splitVertically(bool moveContentToSecondChild) { if(isSplit) { return; } isSplit = true; splitter = new QSplitter(Qt::Vertical); - split(); + split(moveContentToSecondChild); } -void TileWidget::splitHorizontally() +void TileWidget::splitHorizontally(bool moveContentToSecondChild) { if(isSplit) { return; } isSplit = true; splitter = new QSplitter(Qt::Horizontal); - split(); + split(moveContentToSecondChild); } void TileWidget::closeTile() @@ -197,7 +197,7 @@ TileWidget::TileWidget(TraceModel &model, TileWidget &parent) ui->bClose->setVisible(true); } -void TileWidget::split() +void TileWidget::split(bool moveContentToSecondChild) { splitter->setHandleWidth(0); child1 = new TileWidget(model, *this); @@ -205,19 +205,40 @@ void TileWidget::split() splitter->addWidget(child1); splitter->addWidget(child2); ui->ContentPage->layout()->addWidget(splitter); + if(hasContent) { + if(moveContentToSecondChild) { + child2->setContent(content); + } else { + child1->setContent(content); + } + removeContent(); + } + ui->stack->setCurrentWidget(ui->ContentPage); } void TileWidget::setContent(TracePlot *plot) { content = plot; + content->setParentTile(this); hasContent = true; ui->ContentPage->layout()->addWidget(plot); ui->stack->setCurrentWidget(ui->ContentPage); - connect(content, &TracePlot::deleted, this, &TileWidget::traceDeleted); + connect(content, &TracePlot::deleted, this, &TileWidget::plotDeleted); connect(content, &TracePlot::doubleClicked, this, &TileWidget::on_plotDoubleClicked); } +void TileWidget::removeContent() +{ + if(hasContent) { + disconnect(content, &TracePlot::deleted, this, &TileWidget::plotDeleted); + disconnect(content, &TracePlot::doubleClicked, this, &TileWidget::on_plotDoubleClicked); + hasContent = false; + content = nullptr; + ui->stack->setCurrentWidget(ui->TilePage); + } +} + void TileWidget::on_plotDoubleClicked() { setFullScreen(); @@ -272,9 +293,8 @@ void TileWidget::on_bXYplot_clicked() plot->axisSetupDialog(); } -void TileWidget::traceDeleted(TracePlot *) +void TileWidget::plotDeleted() { - if (isFullScreen) { auto rootTile = findRootTile(); diff --git a/Software/PC_Application/CustomWidgets/tilewidget.h b/Software/PC_Application/CustomWidgets/tilewidget.h index 1bb9958..66e385b 100644 --- a/Software/PC_Application/CustomWidgets/tilewidget.h +++ b/Software/PC_Application/CustomWidgets/tilewidget.h @@ -20,8 +20,8 @@ public: explicit TileWidget(TraceModel &model, QWidget *parent = nullptr); ~TileWidget(); - TileWidget *Child1() { return child1; }; - TileWidget *Child2() { return child2; }; + TileWidget *Child1() { return child1; } + TileWidget *Child2() { return child2; } // closes all plots/childs, leaving only the tilewidget at the top void clear(); @@ -31,9 +31,10 @@ public: // check potential trace limits on graphs, only returns true if all traces in all graphs are within limits bool allLimitsPassing(); + public slots: - void splitVertically(); - void splitHorizontally(); + void splitVertically(bool moveContentToSecondChild = false); + void splitHorizontally(bool moveContentToSecondChild = false); void closeTile(); void setPlot(TracePlot *plot); @@ -41,14 +42,15 @@ private slots: void on_bSmithchart_clicked(); void on_bXYplot_clicked(); void on_plotDoubleClicked(); - void traceDeleted(TracePlot *t); + void plotDeleted(); void on_bWaterfall_clicked(); private: TileWidget(TraceModel &model, TileWidget &parent); - void split(); + void split(bool moveContentToSecondChild = false); void setContent(TracePlot *plot); + void removeContent(); void setChild(); TileWidget* findRootTile(); void setFullScreen(); diff --git a/Software/PC_Application/Traces/traceplot.cpp b/Software/PC_Application/Traces/traceplot.cpp index fd0a754..3ba9497 100644 --- a/Software/PC_Application/Traces/traceplot.cpp +++ b/Software/PC_Application/Traces/traceplot.cpp @@ -5,6 +5,7 @@ #include "Marker/markermodel.h" #include "preferences.h" #include "Util/util.h" +#include "CustomWidgets/tilewidget.h" #include #include @@ -25,6 +26,8 @@ TracePlot::TracePlot(TraceModel &model, QWidget *parent) marginTop(20), limitPassing(true) { + parentTile = nullptr; + contextmenu = new QMenu(); markedForDeletion = false; setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -51,6 +54,12 @@ TracePlot::~TracePlot() delete cursorLabel; } +void TracePlot::setParentTile(TileWidget *tile) +{ + parentTile = tile; + updateContextMenu(); +} + void TracePlot::enableTrace(Trace *t, bool enabled) { if(traces[t] != enabled) { @@ -246,6 +255,45 @@ void TracePlot::paintEvent(QPaintEvent *event) draw(p); } +void TracePlot::finishContextMenu() +{ + contextmenu->addSeparator(); + if(parentTile) { + auto add = new QMenu("Add graph...", contextmenu); + auto left = new QAction("to the left"); + connect(left, &QAction::triggered, [=](){ + // split, keep current graph on the right + parentTile->splitHorizontally(true); + }); + add->addAction(left); + auto right = new QAction("to the right"); + connect(right, &QAction::triggered, [=](){ + // split, keep current graph on the left + parentTile->splitHorizontally(false); + }); + add->addAction(right); + auto above = new QAction("above"); + connect(above, &QAction::triggered, [=](){ + // split, keep current graph on the bottom + parentTile->splitVertically(true); + }); + add->addAction(above); + auto below = new QAction("below"); + connect(below, &QAction::triggered, [=](){ + // split, keep current graph on the top + parentTile->splitVertically(false); + }); + add->addAction(below); + contextmenu->addMenu(add); + } + + auto close = new QAction("Close", contextmenu); + contextmenu->addAction(close); + connect(close, &QAction::triggered, [=]() { + markedForDeletion = true; + }); +} + void TracePlot::mousePressEvent(QMouseEvent *event) { diff --git a/Software/PC_Application/Traces/traceplot.h b/Software/PC_Application/Traces/traceplot.h index 32178e1..4330a48 100644 --- a/Software/PC_Application/Traces/traceplot.h +++ b/Software/PC_Application/Traces/traceplot.h @@ -10,6 +10,8 @@ #include #include +class TileWidget; + class TracePlot : public QWidget, public Savable { Q_OBJECT @@ -23,6 +25,8 @@ public: TracePlot(TraceModel &model, QWidget *parent = nullptr); ~TracePlot(); + void setParentTile(TileWidget *tile); + virtual void enableTrace(Trace *t, bool enabled); void mouseDoubleClickEvent(QMouseEvent *event) override; virtual void updateSpan(double min, double max); @@ -51,6 +55,8 @@ protected: void contextMenuEvent(QContextMenuEvent *event) override; void paintEvent(QPaintEvent *event) override; virtual void updateContextMenu(){} + // adds common entries at bottom of context menu. Should be called at the end of derived udpateContextMenu functions + void finishContextMenu(); virtual void replot(){update();} virtual void draw(QPainter& p) = 0; virtual bool supported(Trace *t) = 0; @@ -97,6 +103,7 @@ protected: double sweep_fmin, sweep_fmax; TraceModel &model; Marker *selectedMarker; + TileWidget *parentTile; // graph settings have been changed, check and possibly remove incompatible traces before next paint event bool traceRemovalPending; diff --git a/Software/PC_Application/Traces/tracesmithchart.cpp b/Software/PC_Application/Traces/tracesmithchart.cpp index 2c03c22..43545e6 100644 --- a/Software/PC_Application/Traces/tracesmithchart.cpp +++ b/Software/PC_Application/Traces/tracesmithchart.cpp @@ -525,12 +525,7 @@ void TraceSmithChart::updateContextMenu() contextmenu->addAction(action); } - contextmenu->addSeparator(); - auto close = new QAction("Close", contextmenu); - contextmenu->addAction(close); - connect(close, &QAction::triggered, [=]() { - markedForDeletion = true; - }); + finishContextMenu(); } bool TraceSmithChart::supported(Trace *t) diff --git a/Software/PC_Application/Traces/tracewaterfall.cpp b/Software/PC_Application/Traces/tracewaterfall.cpp index 0dfca68..fba3e73 100644 --- a/Software/PC_Application/Traces/tracewaterfall.cpp +++ b/Software/PC_Application/Traces/tracewaterfall.cpp @@ -211,12 +211,7 @@ void TraceWaterfall::updateContextMenu() contextmenu->addAction(action); } - contextmenu->addSeparator(); - auto close = new QAction("Close", contextmenu); - contextmenu->addAction(close); - connect(close, &QAction::triggered, [=]() { - markedForDeletion = true; - }); + finishContextMenu(); } void TraceWaterfall::draw(QPainter &p) diff --git a/Software/PC_Application/Traces/tracexyplot.cpp b/Software/PC_Application/Traces/tracexyplot.cpp index b28f77c..fc4a748 100644 --- a/Software/PC_Application/Traces/tracexyplot.cpp +++ b/Software/PC_Application/Traces/tracexyplot.cpp @@ -322,12 +322,7 @@ void TraceXYPlot::updateContextMenu() } } - contextmenu->addSeparator(); - auto close = new QAction("Close", contextmenu); - contextmenu->addAction(close); - connect(close, &QAction::triggered, [=]() { - markedForDeletion = true; - }); + finishContextMenu(); } bool TraceXYPlot::dropSupported(Trace *t)