diff --git a/Doc/graph/mask-classes.gv b/Doc/graph/mask-classes.gv index e179be7699eef9aa4d1964d0ac65042030c1196b..75e355077ba17d45724e937cf7b5e09782df3bbb 100644 --- a/Doc/graph/mask-classes.gv +++ b/Doc/graph/mask-classes.gv @@ -10,7 +10,7 @@ node[shape=box]; # DataView->StackedDataFrames; # StackedDataFrames[label="StackedDataFrames\n< ItemStackWidget\n< QWidget" style=filled fillcolor=orchid]; -MaskEditingFrame[label="MaskEditingFrame\n< DataAccessWidget\n< QWidget" style=filled fillcolor=orchid]; +MaskEditingFrame[label="MaskEditingFrame\n< DataSource\n< QWidget" style=filled fillcolor=orchid]; MaskEditingFrame->FrameActions; MaskEditingFrame->MaskPanel; MaskEditingFrame->MaskEditorCanvas; diff --git a/Doc/graph/projn-classes.gv b/Doc/graph/projn-classes.gv index 677a23d9178e320a618675d2bf7777a0e1ad2f7e..8ec2bc06d3c4eeb01e8e9c97ac67362021ec9b36 100644 --- a/Doc/graph/projn-classes.gv +++ b/Doc/graph/projn-classes.gv @@ -5,7 +5,7 @@ digraph maskClasses { node[shape=box]; - Plot2DFrame->DataAccessWidget[arrowhead=onormal color=chocolate4]; + Plot2DFrame->DataSource[arrowhead=onormal color=chocolate4]; Plot2DFrame->ProjectionActions; Plot2DFrame->ProjectionToolbar; Plot2DFrame->ProjectionsEditorCanvas; diff --git a/GUI/Model/Device/InstrumentItems.cpp b/GUI/Model/Device/InstrumentItems.cpp index ce8774f430727c15694f9dc502c98579fc365386..1f209bba2e384678bb79b5a49beb69a6beeac018 100644 --- a/GUI/Model/Device/InstrumentItems.cpp +++ b/GUI/Model/Device/InstrumentItems.cpp @@ -114,9 +114,9 @@ InstrumentItem* InstrumentItem::createItemCopy() const return copy; } -bool InstrumentItem::alignedWith(const DatafileItem* item) const +bool InstrumentItem::alignedWith(const DatafileItem* dfileItem) const { - return axdims() == item->axdims(); + return axdims() == dfileItem->axdims(); } void InstrumentItem::writeTo(QXmlStreamWriter* w) const @@ -367,21 +367,21 @@ std::vector<int> SpecularInstrumentItem::axdims() const return {scanItem()->inclinationAxisItem()->size()}; } -void SpecularInstrumentItem::updateToRealData(const DatafileItem* item) +void SpecularInstrumentItem::updateToRealData(const DatafileItem* dfileItem) { - if (axdims().size() != item->axdims().size()) + if (axdims().size() != dfileItem->axdims().size()) throw std::runtime_error("Specular instrument type is incompatible with passed data shape"); - const auto& dataAxis = item->dataItem()->c_field()->axis(0); + const auto& dataAxis = dfileItem->dataItem()->c_field()->axis(0); scanItem()->updateToData(dataAxis); scanItem()->grazingScanItem()->updateAxIndicators(makeFrame()); } -bool SpecularInstrumentItem::alignedWith(const DatafileItem* item) const +bool SpecularInstrumentItem::alignedWith(const DatafileItem* dfileItem) const { - if (!item->holdsDimensionalData()) + if (!dfileItem->holdsDimensionalData()) return scanItem()->grazingScanItem()->uniformAlphaAxisSelected() - && axdims() == item->axdims(); + && axdims() == dfileItem->axdims(); if (!scanItem()->grazingScanItem()->pointwiseAlphaAxisSelected()) return false; @@ -394,7 +394,7 @@ bool SpecularInstrumentItem::alignedWith(const DatafileItem* item) const if (!instrumentAxis) return false; - const auto& native_axis = item->dataItem()->c_field()->axis(0); + const auto& native_axis = dfileItem->dataItem()->c_field()->axis(0); return *instrumentAxis == native_axis; } @@ -586,12 +586,12 @@ std::vector<int> OffspecInstrumentItem::axdims() const return {scanItem()->grazingScanItem()->nBins(), detectorItem()->ySize()}; } -void OffspecInstrumentItem::updateToRealData(const DatafileItem* dataItem) +void OffspecInstrumentItem::updateToRealData(const DatafileItem* dfileItem) { - if (!dataItem) + if (!dfileItem) return; - const auto data_shape = dataItem->axdims(); + const auto data_shape = dfileItem->axdims(); if (axdims().size() != data_shape.size()) throw std::runtime_error("Offspec instrument type is incompatible with passed data shape"); @@ -689,12 +689,12 @@ std::vector<int> GISASInstrumentItem::axdims() const return {(int)detectorItem()->phiAxis().nbins(), (int)detectorItem()->alphaAxis().nbins()}; } -void GISASInstrumentItem::updateToRealData(const DatafileItem* item) +void GISASInstrumentItem::updateToRealData(const DatafileItem* dfileItem) { - if (!item) + if (!dfileItem) return; - const auto data_shape = item->axdims(); + const auto data_shape = dfileItem->axdims(); if (axdims().size() != data_shape.size()) throw std::runtime_error("GISAS instrument type is incompatible with passed data shape."); ASSERT(detectorItem()); diff --git a/GUI/Model/Device/InstrumentItems.h b/GUI/Model/Device/InstrumentItems.h index 2619fcafc496bf301b192ecc77bd1cd61c9c717f..e075b06d1967cecebb458405ca030f931eec2d79 100644 --- a/GUI/Model/Device/InstrumentItems.h +++ b/GUI/Model/Device/InstrumentItems.h @@ -46,9 +46,9 @@ public: virtual std::vector<int> axdims() const = 0; - virtual void updateToRealData(const DatafileItem* item) = 0; + virtual void updateToRealData(const DatafileItem* dfileItem) = 0; - virtual bool alignedWith(const DatafileItem* item) const; + virtual bool alignedWith(const DatafileItem* dfileItem) const; virtual Frame makeFrame() const = 0; @@ -131,8 +131,8 @@ public: QString instrumentType() const override { return "Specular"; } std::vector<int> axdims() const override; - void updateToRealData(const DatafileItem* item) override; - bool alignedWith(const DatafileItem* item) const override; + void updateToRealData(const DatafileItem* dfileItem) override; + bool alignedWith(const DatafileItem* dfileItem) const override; Frame makeFrame() const override; ISimulation* createSimulation(const MultiLayer& sample) const override; @@ -147,7 +147,7 @@ public: QString instrumentType() const override { return "Depth probe"; } std::vector<int> axdims() const override; - void updateToRealData(const DatafileItem* item) override; + void updateToRealData(const DatafileItem* dfileItem) override; Frame makeFrame() const override; ISimulation* createSimulation(const MultiLayer& sample) const override; void writeTo(QXmlStreamWriter* w) const override; @@ -166,7 +166,7 @@ public: QString instrumentType() const override { return "Off specular"; } std::vector<int> axdims() const override; - void updateToRealData(const DatafileItem* item) override; + void updateToRealData(const DatafileItem* dfileItem) override; Frame makeFrame() const override; ISimulation* createSimulation(const MultiLayer& sample) const override; void writeTo(QXmlStreamWriter* w) const override; @@ -185,7 +185,7 @@ public: QString instrumentType() const override { return "GISAS"; } std::vector<int> axdims() const override; - void updateToRealData(const DatafileItem* item) override; + void updateToRealData(const DatafileItem* dfileItem) override; Frame makeFrame() const override; ISimulation* createSimulation(const MultiLayer& sample) const override; void writeTo(QXmlStreamWriter* w) const override; diff --git a/GUI/View/Access/DataAccessWidget.cpp b/GUI/Model/Job/DataSource.cpp similarity index 71% rename from GUI/View/Access/DataAccessWidget.cpp rename to GUI/Model/Job/DataSource.cpp index 493c1f70dfec341e85bf559bd2bed5cede9c871c..fcd3ff3262aba50f41ac9226658c88cde9819c4e 100644 --- a/GUI/View/Access/DataAccessWidget.cpp +++ b/GUI/Model/Job/DataSource.cpp @@ -2,8 +2,8 @@ // // BornAgain: simulate and fit reflection and scattering // -//! @file GUI/View/Access/DataAccessWidget.cpp -//! @brief Defines class DataAccessWidget. +//! @file GUI/Model/Job/DataSource.cpp +//! @brief Defines class DataSource. //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) @@ -12,35 +12,30 @@ // // ************************************************************************************************ -#include "GUI/View/Access/DataAccessWidget.h" +#include "GUI/Model/Job/DataSource.h" #include "Base/Util/Assert.h" #include "GUI/Model/Data/Data1DItem.h" #include "GUI/Model/Data/Data2DItem.h" #include "GUI/Model/Device/DatafileItem.h" #include "GUI/Model/Job/JobItem.h" -DataAccessWidget::DataAccessWidget() - : m_item(nullptr) +DataSource::DataSource(QObject* item) + : m_item(item) { -} - -void DataAccessWidget::setBaseItem(QObject* item) -{ - m_item = item; ASSERT(jobxItem() || realDataItem()); } -JobItem* DataAccessWidget::jobxItem() const +JobItem* DataSource::jobxItem() const { return dynamic_cast<JobItem*>(m_item); } -DataItem* DataAccessWidget::realDataItem() const +DataItem* DataSource::realDataItem() const { return dynamic_cast<DataItem*>(m_item); } -Data1DItem* DataAccessWidget::realData1DItem() const +Data1DItem* DataSource::realData1DItem() const { if (jobxItem()) { if (const DatafileItem* ii = jobxItem()->realItem()) @@ -52,7 +47,7 @@ Data1DItem* DataAccessWidget::realData1DItem() const return nullptr; } -Data2DItem* DataAccessWidget::realData2DItem() const +Data2DItem* DataSource::realData2DItem() const { if (jobxItem()) { if (const DatafileItem* ii = jobxItem()->realItem()) @@ -64,27 +59,27 @@ Data2DItem* DataAccessWidget::realData2DItem() const return nullptr; } -Data1DItem* DataAccessWidget::simuData1DItem() const +Data1DItem* DataSource::simuData1DItem() const { return jobxItem() ? dynamic_cast<Data1DItem*>(jobxItem()->simulatedDataItem()) : nullptr; } -Data2DItem* DataAccessWidget::simuData2DItem() const +Data2DItem* DataSource::simuData2DItem() const { return jobxItem() ? dynamic_cast<Data2DItem*>(jobxItem()->simulatedDataItem()) : nullptr; } -Data1DItem* DataAccessWidget::diffData1DItem() const +Data1DItem* DataSource::diffData1DItem() const { return jobxItem() ? dynamic_cast<Data1DItem*>(jobxItem()->diffDataItem()) : nullptr; } -Data2DItem* DataAccessWidget::diffData2DItem() const +Data2DItem* DataSource::diffData2DItem() const { return jobxItem() ? dynamic_cast<Data2DItem*>(jobxItem()->diffDataItem()) : nullptr; } -QList<Data1DItem*> DataAccessWidget::mainData1DItems() const +QList<Data1DItem*> DataSource::mainData1DItems() const { QList<Data1DItem*> result; if (auto* ii = simuData1DItem()) @@ -94,7 +89,7 @@ QList<Data1DItem*> DataAccessWidget::mainData1DItems() const return result; } -QList<Data2DItem*> DataAccessWidget::mainData2DItems() const +QList<Data2DItem*> DataSource::mainData2DItems() const { QList<Data2DItem*> result; if (auto* ii = simuData2DItem()) @@ -104,7 +99,7 @@ QList<Data2DItem*> DataAccessWidget::mainData2DItems() const return result; } -QList<Data1DItem*> DataAccessWidget::allData1DItems() const +QList<Data1DItem*> DataSource::allData1DItems() const { QList<Data1DItem*> result = mainData1DItems(); if (auto* ii = diffData1DItem()) @@ -112,7 +107,7 @@ QList<Data1DItem*> DataAccessWidget::allData1DItems() const return result; } -QList<Data2DItem*> DataAccessWidget::allData2DItems() const +QList<Data2DItem*> DataSource::allData2DItems() const { QList<Data2DItem*> result = mainData2DItems(); if (auto* ii = diffData2DItem()) @@ -120,14 +115,14 @@ QList<Data2DItem*> DataAccessWidget::allData2DItems() const return result; } -Data1DItem* DataAccessWidget::currentData1DItem() const +Data1DItem* DataSource::currentData1DItem() const { if (allData1DItems().empty()) return nullptr; return allData1DItems().first(); } -Data2DItem* DataAccessWidget::currentData2DItem() const +Data2DItem* DataSource::currentData2DItem() const { if (allData2DItems().empty()) return nullptr; diff --git a/GUI/View/Access/DataAccessWidget.h b/GUI/Model/Job/DataSource.h similarity index 71% rename from GUI/View/Access/DataAccessWidget.h rename to GUI/Model/Job/DataSource.h index 807dc4eb8e098d15f916c04c143711caaea90523..2cf3605503ca681de3ef7d72156c5c1a47112f95 100644 --- a/GUI/View/Access/DataAccessWidget.h +++ b/GUI/Model/Job/DataSource.h @@ -2,8 +2,8 @@ // // BornAgain: simulate and fit reflection and scattering // -//! @file GUI/View/Access/DataAccessWidget.h -//! @brief Defines class DataAccessWidget. +//! @file GUI/Model/Job/DataSource.h +//! @brief Defines class DataSource. //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) @@ -12,8 +12,8 @@ // // ************************************************************************************************ -#ifndef BORNAGAIN_GUI_VIEW_ACCESS_DATAACCESSWIDGET_H -#define BORNAGAIN_GUI_VIEW_ACCESS_DATAACCESSWIDGET_H +#ifndef BORNAGAIN_GUI_MODEL_JOB_DATASOURCE_H +#define BORNAGAIN_GUI_MODEL_JOB_DATASOURCE_H #include <QObject> @@ -22,19 +22,16 @@ class Data2DItem; class DataItem; class JobItem; -//! The DataAccessWidget class is a base for widgets, working data, stored in JobItem or -//! DatafileItem. DataAccessWidget provides an access to SpecularDataItems and Data2DItems +//! The DataSource class is a base for widgets, working data, stored in JobItem or +//! DatafileItem. DataSource provides an access to SpecularDataItems and Data2DItems //! separately and as a list of items that is required for simultaneous, synchronous work while //! plotting and changing their properties. -class DataAccessWidget { +class DataSource { public: - explicit DataAccessWidget(); - - void setBaseItem(QObject* item); + explicit DataSource(QObject* item); JobItem* jobxItem() const; - QObject* jobRealBase() const { return m_item; } //... Access to concrete items: @@ -64,4 +61,4 @@ private: QObject* m_item; }; -#endif // BORNAGAIN_GUI_VIEW_ACCESS_DATAACCESSWIDGET_H +#endif // BORNAGAIN_GUI_MODEL_JOB_DATASOURCE_H diff --git a/GUI/View/Access/DataPropertyWidget.cpp b/GUI/View/Access/DataPropertyWidget.cpp deleted file mode 100644 index 24273b6896174a4fdfef9cca46321618c3ff9ec4..0000000000000000000000000000000000000000 --- a/GUI/View/Access/DataPropertyWidget.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Access/DataPropertyWidget.cpp -//! @brief Defines class DataPropertyWidget. -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2022 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "GUI/View/Access/DataPropertyWidget.h" -#include "Base/Axis/Frame.h" -#include "Base/Util/Assert.h" -#include "GUI/Model/Data/DataItem.h" -#include "GUI/Model/Device/DatafileItem.h" -#include "GUI/Model/Device/InstrumentItems.h" -#include "GUI/Model/Job/JobItem.h" -#include "GUI/Model/Project/ProjectDocument.h" - -DataPropertyWidget::DataPropertyWidget() - : m_main_layout(new QFormLayout(this)) -{ - setWindowTitle("Properties"); - - m_main_layout->setContentsMargins(8, 20, 8, 8); - m_main_layout->setSpacing(5); -} - -void DataPropertyWidget::setJobOrDatafileItem(QObject* item) -{ - m_daw.setBaseItem(item); - createPanelElements(); -} - -void DataPropertyWidget::updateItemCoords(DataItem* item) -{ - if (!item) - return; - - emit item->axesUnitsReplotRequested(); - updateUIValues(); -} - -void DataPropertyWidget::updateUIValues() -{ - if (m_daw.jobRealBase()) - for (const auto& updater : m_updaters) - updater(); -} diff --git a/GUI/View/Access/DataPropertyWidget.h b/GUI/View/Access/DataPropertyWidget.h deleted file mode 100644 index 5ff80156aeb5960e8b217ab2b494a69b5d65924d..0000000000000000000000000000000000000000 --- a/GUI/View/Access/DataPropertyWidget.h +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Access/DataPropertyWidget.h -//! @brief Defines class DataPropertyWidget. -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2022 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI_VIEW_ACCESS_DATAPROPERTYWIDGET_H -#define BORNAGAIN_GUI_VIEW_ACCESS_DATAPROPERTYWIDGET_H - -#include "GUI/View/Access/DataAccessWidget.h" -#include <QFormLayout> -#include <QWidget> - -class DataItem; - -//! Base class for AxesPanel and AxisPanel. - -class DataPropertyWidget : public QWidget { - Q_OBJECT -public: - explicit DataPropertyWidget(); - - void setJobOrDatafileItem(QObject* item); - -signals: - void axesRangeResetRequested(); - -protected: - void updateItemCoords(DataItem* item); - void updateUIValues(); - virtual void createPanelElements() = 0; - - QFormLayout* m_main_layout; - QList<std::function<void()>> m_updaters; - - DataAccessWidget m_daw; -}; - -#endif // BORNAGAIN_GUI_VIEW_ACCESS_DATAPROPERTYWIDGET_H diff --git a/GUI/View/Frame/Fit1DFrame.cpp b/GUI/View/Frame/Fit1DFrame.cpp index fab2354377c1bd57f45f8ff23bf187d07aa00878..921903e3f530a9f1f6b92c0310b9f32c6611002c 100644 --- a/GUI/View/Frame/Fit1DFrame.cpp +++ b/GUI/View/Frame/Fit1DFrame.cpp @@ -19,6 +19,7 @@ #include "GUI/Model/Axis/AmplitudeAxisItem.h" #include "GUI/Model/Axis/BasicAxisItem.h" #include "GUI/Model/Data/Data1DItem.h" +#include "GUI/Model/Job/DataSource.h" #include "GUI/Model/Job/FitSuiteItem.h" #include "GUI/Model/Job/JobItem.h" #include "GUI/Model/Project/ProjectDocument.h" @@ -35,13 +36,8 @@ Fit1DFrame::Fit1DFrame(JobItem* job_item) , m_diff_canvas(new SpecularPlotCanvas) , m_progress_canvas(new ProgressCanvas) , m_status_label(new PlotStatusLabel(nullptr)) - , m_axis_panel(new AxisPanel) , m_reset_view_action(new QAction(this)) { - m_axis_panel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding); - QObject::connect(gActions->toggle_properties_panel, &QAction::triggered, m_axis_panel, - &QWidget::setVisible); - auto* vlayout = new QVBoxLayout; vlayout->setContentsMargins(0, 0, 0, 0); vlayout->setSpacing(0); @@ -64,38 +60,42 @@ Fit1DFrame::Fit1DFrame(JobItem* job_item) hlayout->setContentsMargins(0, 0, 0, 0); hlayout->setSpacing(0); hlayout->addLayout(vlayout); - hlayout->addWidget(m_axis_panel); + + auto* axis_panel = new AxisPanel(job_item); + hlayout->addWidget(axis_panel); + axis_panel->setVisible(false); + QObject::connect(gActions->toggle_properties_panel, &QAction::triggered, axis_panel, + &QWidget::setVisible); m_reset_view_action->setText("Center view"); m_reset_view_action->setIcon(QIcon(":/images/camera-metering-center.svg")); m_reset_view_action->setToolTip("Reset View"); connect(m_reset_view_action, &QAction::triggered, this, &Fit1DFrame::onResetViewAction); - m_axis_panel->setVisible(false); - connect(m_axis_panel, &DataPropertyWidget::axesRangeResetRequested, this, - &Fit1DFrame::onResetViewAction); - ASSERT(job_item); - m_daw.setBaseItem(job_item); - GUI::View::RangeUtil::setCommonRangeY(m_daw.mainData1DItems()); + m_data_source = std::make_unique<DataSource>(job_item); + GUI::View::RangeUtil::setCommonRangeY(m_data_source->mainData1DItems()); updateDiffData(); connectItems(); - m_data_canvas->setData1DItems({m_daw.simuData1DItem(), m_daw.realData1DItem()}); - m_diff_canvas->setData1DItems({m_daw.diffData1DItem()}); + m_data_canvas->setData1DItems( + {m_data_source->simuData1DItem(), m_data_source->realData1DItem()}); + m_diff_canvas->setData1DItems({m_data_source->diffData1DItem()}); m_progress_canvas->setJobItem(job_item); - m_axis_panel->setJobOrDatafileItem(job_item); } +Fit1DFrame::~Fit1DFrame() = default; + void Fit1DFrame::onResetViewAction() { - ASSERT(m_daw.simuData1DItem() && m_daw.diffData1DItem() && m_daw.realData1DItem()); - m_daw.simuData1DItem()->resetView(); - m_daw.realData1DItem()->resetView(); - m_daw.diffData1DItem()->resetView(); + ASSERT(m_data_source->simuData1DItem() && m_data_source->diffData1DItem() + && m_data_source->realData1DItem()); + m_data_source->simuData1DItem()->resetView(); + m_data_source->realData1DItem()->resetView(); + m_data_source->diffData1DItem()->resetView(); // synchronize data range between simulated and real - GUI::View::RangeUtil::setCommonRangeY(m_daw.mainData1DItems()); + GUI::View::RangeUtil::setCommonRangeY(m_data_source->mainData1DItems()); gDoc->setModified(); } @@ -103,29 +103,30 @@ void Fit1DFrame::connectItems() { // sync X axis view area between simulated and difference plots // simu --> diff - connect(m_daw.simuData1DItem(), &DataItem::updateOtherPlots, m_daw.diffData1DItem(), - &DataItem::checkXranges, Qt::UniqueConnection); + connect(m_data_source->simuData1DItem(), &DataItem::updateOtherPlots, + m_data_source->diffData1DItem(), &DataItem::checkXranges, Qt::UniqueConnection); // diff --> simu - connect(m_daw.diffData1DItem(), &DataItem::updateOtherPlots, m_daw.simuData1DItem(), - &DataItem::checkXranges, Qt::UniqueConnection); + connect(m_data_source->diffData1DItem(), &DataItem::updateOtherPlots, + m_data_source->simuData1DItem(), &DataItem::checkXranges, Qt::UniqueConnection); // update diff data if simulation data changes - connect(m_daw.simuData1DItem(), &Data1DItem::datafieldChanged, this, + connect(m_data_source->simuData1DItem(), &Data1DItem::datafieldChanged, this, &Fit1DFrame::updateDiffData, Qt::UniqueConnection); } void Fit1DFrame::updateDiffData() { - ASSERT(m_daw.simuData1DItem() && m_daw.diffData1DItem() && m_daw.realData1DItem()); - if (!m_daw.simuData1DItem()->c_field() || !m_daw.realData1DItem()->c_field()) + ASSERT(m_data_source->simuData1DItem() && m_data_source->diffData1DItem() + && m_data_source->realData1DItem()); + if (!m_data_source->simuData1DItem()->c_field() || !m_data_source->realData1DItem()->c_field()) return; - m_daw.diffData1DItem()->setDatafield(DiffUtil::relativeDifferenceField( - *m_daw.simuData1DItem()->c_field(), *m_daw.realData1DItem()->c_field())); + m_data_source->diffData1DItem()->setDatafield(DiffUtil::relativeDifferenceField( + *m_data_source->simuData1DItem()->c_field(), *m_data_source->realData1DItem()->c_field())); // keep Y axis range up with data range - double min = m_daw.diffData1DItem()->yMin(); - double max = m_daw.diffData1DItem()->yMax(); - if (!m_daw.diffData1DItem()->axItemY()->isLogScale() || min > 0) - m_daw.diffData1DItem()->setYrange(min, max); + double min = m_data_source->diffData1DItem()->yMin(); + double max = m_data_source->diffData1DItem()->yMax(); + if (!m_data_source->diffData1DItem()->axItemY()->isLogScale() || min > 0) + m_data_source->diffData1DItem()->setYrange(min, max); } diff --git a/GUI/View/Frame/Fit1DFrame.h b/GUI/View/Frame/Fit1DFrame.h index 54bb665191d59915f42f39b896e0334d01e206eb..7c3aae87d4e8df10847d4c7f5497181e7edf9c63 100644 --- a/GUI/View/Frame/Fit1DFrame.h +++ b/GUI/View/Frame/Fit1DFrame.h @@ -15,11 +15,10 @@ #ifndef BORNAGAIN_GUI_VIEW_FRAME_FIT1DFRAME_H #define BORNAGAIN_GUI_VIEW_FRAME_FIT1DFRAME_H -#include "GUI/View/Access/DataAccessWidget.h" #include <QAction> #include <QWidget> -class AxisPanel; +class DataSource; class JobItem; class JobRealBase; class PlotStatusLabel; @@ -33,6 +32,7 @@ class Fit1DFrame : public QWidget { Q_OBJECT public: explicit Fit1DFrame(JobItem* item); + ~Fit1DFrame(); private: void onResetViewAction(); @@ -43,10 +43,9 @@ private: SpecularPlotCanvas* m_diff_canvas; ProgressCanvas* m_progress_canvas; PlotStatusLabel* m_status_label; - AxisPanel* m_axis_panel; QAction* m_reset_view_action; - DataAccessWidget m_daw; + std::unique_ptr<DataSource> m_data_source; }; #endif // BORNAGAIN_GUI_VIEW_FRAME_FIT1DFRAME_H diff --git a/GUI/View/Frame/Fit2DFrame.cpp b/GUI/View/Frame/Fit2DFrame.cpp index d79d22808f948bf61d96a412bb770af23a52779c..ec303ed3c288a3088b5b9103380ba3e2b23d7e62 100644 --- a/GUI/View/Frame/Fit2DFrame.cpp +++ b/GUI/View/Frame/Fit2DFrame.cpp @@ -18,6 +18,7 @@ #include "Device/IO/DiffUtil.h" #include "GUI/Model/Data/Data1DItem.h" #include "GUI/Model/Data/Data2DItem.h" +#include "GUI/Model/Job/DataSource.h" #include "GUI/Model/Job/JobItem.h" #include "GUI/Model/Project/ProjectDocument.h" #include "GUI/View/Canvas/ColorMapCanvas.h" @@ -35,17 +36,12 @@ Fit2DFrame::Fit2DFrame(JobItem* job_item) , m_diff_canvas(new ColorMapCanvas) , m_progress_canvas(new ProgressCanvas) , m_status_label(new PlotStatusLabel(nullptr)) - , m_axes_panel(new AxesPanel) , m_reset_view_action(new QAction(this)) { auto* vlayout = new QVBoxLayout; vlayout->setContentsMargins(0, 0, 0, 0); vlayout->setSpacing(0); - m_axes_panel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); - QObject::connect(gActions->toggle_properties_panel, &QAction::triggered, m_axes_panel, - &QWidget::setVisible); - auto* gridLayout = new QGridLayout; gridLayout->setContentsMargins(0, 0, 0, 0); gridLayout->setSpacing(0); @@ -66,79 +62,83 @@ Fit2DFrame::Fit2DFrame(JobItem* job_item) hlayout->setContentsMargins(0, 0, 0, 0); hlayout->setSpacing(0); hlayout->addLayout(vlayout); - hlayout->addWidget(m_axes_panel); + + auto* axes_panel = new AxesPanel(job_item); + hlayout->addWidget(axes_panel); + axes_panel->setVisible(false); + QObject::connect(gActions->toggle_properties_panel, &QAction::triggered, axes_panel, + &QWidget::setVisible); m_reset_view_action->setText("Center view"); m_reset_view_action->setIcon(QIcon(":/images/camera-metering-center.svg")); m_reset_view_action->setToolTip("Reset View"); connect(m_reset_view_action, &QAction::triggered, this, &Fit2DFrame::onResetViewAction); - m_axes_panel->setVisible(false); - connect(m_axes_panel, &DataPropertyWidget::axesRangeResetRequested, this, - &Fit2DFrame::onResetViewAction); - ASSERT(job_item); - m_daw.setBaseItem(job_item); + m_data_source = std::make_unique<DataSource>(job_item); - GUI::View::RangeUtil::setCommonRangeZ(m_daw.mainData2DItems()); + GUI::View::RangeUtil::setCommonRangeZ(m_data_source->mainData2DItems()); updateDiffData(); connectItems(); - m_simu_canvas->itemToCanvas(m_daw.simuData2DItem()); - m_real_canvas->itemToCanvas(m_daw.realData2DItem()); - m_diff_canvas->itemToCanvas(m_daw.diffData2DItem()); + m_simu_canvas->itemToCanvas(m_data_source->simuData2DItem()); + m_real_canvas->itemToCanvas(m_data_source->realData2DItem()); + m_diff_canvas->itemToCanvas(m_data_source->diffData2DItem()); m_progress_canvas->setJobItem(job_item); - m_axes_panel->setJobOrDatafileItem(job_item); } +Fit2DFrame::~Fit2DFrame() = default; + void Fit2DFrame::onResetViewAction() { - ASSERT(m_daw.simuData2DItem() && m_daw.diffData2DItem() && m_daw.realData2DItem()); - m_daw.simuData2DItem()->resetView(); - m_daw.realData2DItem()->resetView(); - m_daw.diffData2DItem()->resetView(); + ASSERT(m_data_source->simuData2DItem() && m_data_source->diffData2DItem() + && m_data_source->realData2DItem()); + m_data_source->simuData2DItem()->resetView(); + m_data_source->realData2DItem()->resetView(); + m_data_source->diffData2DItem()->resetView(); // synchronize data range between simulated and real - GUI::View::RangeUtil::setCommonRangeZ(m_daw.mainData2DItems()); + GUI::View::RangeUtil::setCommonRangeZ(m_data_source->mainData2DItems()); gDoc->setModified(); } void Fit2DFrame::connectItems() { // sync XY view area between simulated, real and difference plots - for (auto* senderItem : m_daw.allData2DItems()) - for (auto* receiverItem : m_daw.allData2DItems()) + for (auto* senderItem : m_data_source->allData2DItems()) + for (auto* receiverItem : m_data_source->allData2DItems()) if (receiverItem != senderItem) connect(senderItem, &DataItem::updateOtherPlots, receiverItem, &DataItem::checkXYranges, Qt::UniqueConnection); // sync Z range between simulated and real - connect(m_daw.simuData2DItem(), &Data2DItem::alignRanges, - [this] { GUI::View::RangeUtil::setCommonRangeZ(m_daw.mainData2DItems()); }); + connect(m_data_source->simuData2DItem(), &Data2DItem::alignRanges, + [this] { GUI::View::RangeUtil::setCommonRangeZ(m_data_source->mainData2DItems()); }); // sync Z range: simu --> real - connect(m_daw.simuData2DItem(), &DataItem::updateOtherPlots, m_daw.realData2DItem(), - &Data2DItem::copyZRangeFromItem, Qt::UniqueConnection); + connect(m_data_source->simuData2DItem(), &DataItem::updateOtherPlots, + m_data_source->realData2DItem(), &Data2DItem::copyZRangeFromItem, Qt::UniqueConnection); // sync Z range: real --> simu - connect(m_daw.realData2DItem(), &DataItem::updateOtherPlots, m_daw.simuData2DItem(), - &Data2DItem::copyZRangeFromItem, Qt::UniqueConnection); + connect(m_data_source->realData2DItem(), &DataItem::updateOtherPlots, + m_data_source->simuData2DItem(), &Data2DItem::copyZRangeFromItem, Qt::UniqueConnection); // update diff data if simulation data changes - connect(m_daw.simuData2DItem(), &Data1DItem::datafieldChanged, this, + connect(m_data_source->simuData2DItem(), &Data1DItem::datafieldChanged, this, &Fit2DFrame::updateDiffData, Qt::UniqueConnection); } void Fit2DFrame::updateDiffData() { - ASSERT(m_daw.simuData2DItem() && m_daw.diffData2DItem() && m_daw.realData2DItem()); - if (!m_daw.simuData2DItem()->c_field() || !m_daw.realData2DItem()->c_field()) + ASSERT(m_data_source->simuData2DItem() && m_data_source->diffData2DItem() + && m_data_source->realData2DItem()); + if (!m_data_source->simuData2DItem()->c_field() || !m_data_source->realData2DItem()->c_field()) return; - m_daw.diffData2DItem()->setDatafield(DiffUtil::relativeDifferenceField( - *m_daw.simuData2DItem()->c_field(), *m_daw.realData2DItem()->c_field())); + m_data_source->diffData2DItem()->setDatafield(DiffUtil::relativeDifferenceField( + *m_data_source->simuData2DItem()->c_field(), *m_data_source->realData2DItem()->c_field())); // keep Z axis range up with data range - m_daw.diffData2DItem()->computeDataRange(); + m_data_source->diffData2DItem()->computeDataRange(); } diff --git a/GUI/View/Frame/Fit2DFrame.h b/GUI/View/Frame/Fit2DFrame.h index 7f1b4e2912ed00dc5e3559e6d87ba005ac25d40d..aa7d366623c6b5029a16c147ed772f1246ac95f8 100644 --- a/GUI/View/Frame/Fit2DFrame.h +++ b/GUI/View/Frame/Fit2DFrame.h @@ -15,12 +15,11 @@ #ifndef BORNAGAIN_GUI_VIEW_FRAME_FIT2DFRAME_H #define BORNAGAIN_GUI_VIEW_FRAME_FIT2DFRAME_H -#include "GUI/View/Access/DataAccessWidget.h" #include <QAction> #include <QWidget> -class AxesPanel; class ColorMapCanvas; +class DataSource; class JobItem; class PlotStatusLabel; class ProgressCanvas; @@ -31,6 +30,7 @@ class Fit2DFrame : public QWidget { Q_OBJECT public: explicit Fit2DFrame(JobItem* item); + ~Fit2DFrame(); private: void onResetViewAction(); @@ -42,10 +42,9 @@ private: ColorMapCanvas* m_diff_canvas; ProgressCanvas* m_progress_canvas; PlotStatusLabel* m_status_label; - AxesPanel* m_axes_panel; QAction* m_reset_view_action; - DataAccessWidget m_daw; + std::unique_ptr<DataSource> m_data_source; }; #endif // BORNAGAIN_GUI_VIEW_FRAME_FIT2DFRAME_H diff --git a/GUI/View/Frame/Plot2DFrame.cpp b/GUI/View/Frame/Plot2DFrame.cpp index b4a77ea49f5e679bb7d99a06ee78ee20c730c7c8..9ffcc3d22cbdabf23e9e7a5540b05fe036d8d230 100644 --- a/GUI/View/Frame/Plot2DFrame.cpp +++ b/GUI/View/Frame/Plot2DFrame.cpp @@ -31,10 +31,11 @@ Plot2DFrame::Plot2DFrame(Data2DItem* item) : m_canvas2D(new MaskEditorCanvas) , m_canvas1D(new ProjectedGraphsCanvas) - , m_axes_panel(new AxesPanel) , m_mask_panel(new MaskPanel) , m_data_item(item) { + ASSERT(item); + auto* layout = new QHBoxLayout; setLayout(layout); layout->setContentsMargins(0, 0, 0, 0); @@ -51,7 +52,9 @@ Plot2DFrame::Plot2DFrame(Data2DItem* item) panels->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); panels->setHidden(true); - panels->addWidget(m_axes_panel); + auto* axes_panel = new AxesPanel(item); + panels->addWidget(axes_panel); + panels->addWidget(m_mask_panel); auto* toolbars = new QStackedWidget; @@ -103,8 +106,6 @@ Plot2DFrame::Plot2DFrame(Data2DItem* item) prjc_toolbar->onChangeActivityRequest(MaskFlags::HORIZONTAL_LINE_MODE); - ASSERT(item); - m_axes_panel->setJobOrDatafileItem(item); updateFrame(); } diff --git a/GUI/View/Frame/Plot2DFrame.h b/GUI/View/Frame/Plot2DFrame.h index ed76d7030c418b4e898ef4f82c2801ed65f81ed9..9061e0571d722a2014b937d1f5de612cca9edd24 100644 --- a/GUI/View/Frame/Plot2DFrame.h +++ b/GUI/View/Frame/Plot2DFrame.h @@ -17,7 +17,6 @@ #include <QWidget> -class AxesPanel; class Data2DItem; class MaskEditorCanvas; class MaskPanel; @@ -36,7 +35,6 @@ private: MaskEditorCanvas* m_canvas2D; //!< canvas with color map at the top ProjectedGraphsCanvas* m_canvas1D; //!< bottom widget to draw projections plot - AxesPanel* m_axes_panel; //!< panel with axes properties MaskPanel* m_mask_panel; //!< panel with mask list and properties of one mask Data2DItem* m_data_item; diff --git a/GUI/View/Frame/SpecularFrame.cpp b/GUI/View/Frame/SpecularFrame.cpp index 91e7f573a73ccfa77695174c2e099a4f672ba038..c917e613789469e61d9db4789e9fb6505d15448a 100644 --- a/GUI/View/Frame/SpecularFrame.cpp +++ b/GUI/View/Frame/SpecularFrame.cpp @@ -22,37 +22,39 @@ #include <QBoxLayout> #include <QMenu> +namespace { + +void execContextMenu(const QPoint& point) +{ + QMenu menu; + menu.addAction(gActions->reset_view); + menu.addAction(gActions->save_plot); + menu.addAction(gActions->toggle_properties_panel); + menu.exec(point); +} + +} // namespace + SpecularFrame::SpecularFrame(Data1DItem* item) : m_specular_canvas(new SpecularDataCanvas) - , m_scale_editor(new AxisPanel) -// , m_data_item(item) { + ASSERT(item); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_scale_editor->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding); - QObject::connect(gActions->toggle_properties_panel, &QAction::triggered, m_scale_editor, - &QWidget::setVisible); auto* hlayout = new QHBoxLayout(this); hlayout->setContentsMargins(0, 0, 0, 0); hlayout->setSpacing(0); hlayout->addWidget(m_specular_canvas); - hlayout->addWidget(m_scale_editor); - connect(m_specular_canvas, &SpecularDataCanvas::customContextMenuRequested, this, - &SpecularFrame::onContextMenuRequest); + connect(m_specular_canvas, &SpecularDataCanvas::customContextMenuRequested, + [](const QPoint& point) { execContextMenu(point); }); - m_scale_editor->setVisible(false); + auto* axis_panel = new AxisPanel(item); + hlayout->addWidget(axis_panel); + QObject::connect(gActions->toggle_properties_panel, &QAction::triggered, axis_panel, + &QWidget::setVisible); + axis_panel->setVisible(false); - ASSERT(item); m_specular_canvas->setDataItem(item); - m_scale_editor->setJobOrDatafileItem(item); -} - -void SpecularFrame::onContextMenuRequest(const QPoint& point) -{ - QMenu menu; - menu.addAction(gActions->reset_view); - menu.addAction(gActions->save_plot); - menu.addAction(gActions->toggle_properties_panel); - menu.exec(point); } diff --git a/GUI/View/Frame/SpecularFrame.h b/GUI/View/Frame/SpecularFrame.h index fdb90bff39e19bd46da904dcf96511d7f7cb745a..16cce78f2a5a913fe8fdaed7e5300e11263600ea 100644 --- a/GUI/View/Frame/SpecularFrame.h +++ b/GUI/View/Frame/SpecularFrame.h @@ -17,7 +17,6 @@ #include <QWidget> -class AxisPanel; class Data1DItem; class SpecularDataCanvas; @@ -26,14 +25,8 @@ class SpecularFrame : public QWidget { public: SpecularFrame(Data1DItem* item); -private slots: - void onContextMenuRequest(const QPoint& point); - private: SpecularDataCanvas* m_specular_canvas; - AxisPanel* m_scale_editor; - - // const Data1DItem* m_data_item; }; #endif // BORNAGAIN_GUI_VIEW_FRAME_SPECULARFRAME_H diff --git a/GUI/View/Setup/AxesPanel.cpp b/GUI/View/Setup/AxesPanel.cpp index 5d426b94564b0d7148fc88f688f3ee92fae7b98c..5965b0143793798ec8f32aba1c3612232fd6f6a6 100644 --- a/GUI/View/Setup/AxesPanel.cpp +++ b/GUI/View/Setup/AxesPanel.cpp @@ -17,6 +17,7 @@ #include "GUI/Model/Axis/AmplitudeAxisItem.h" #include "GUI/Model/Axis/BasicAxisItem.h" #include "GUI/Model/Data/Data2DItem.h" +#include "GUI/Model/Job/DataSource.h" #include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Support/Data/ComboProperty.h" #include "GUI/View/Numeric/ComboUtil.h" @@ -27,19 +28,28 @@ #include <QFormLayout> #include <QLineEdit> -void AxesPanel::createPanelElements() +AxesPanel::AxesPanel(QObject* item) + : m_data_source(std::make_unique<DataSource>(item)) { - if (m_daw.allData2DItems().empty()) + setWindowTitle("Properties"); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding); + + auto* main_layout = new QFormLayout(this); + + main_layout->setContentsMargins(8, 20, 8, 8); + main_layout->setSpacing(5); + + if (m_data_source->allData2DItems().empty()) return; - for (auto* item : m_daw.allData2DItems()) + for (auto* item : m_data_source->allData2DItems()) disconnect(item, nullptr, this, nullptr); - GUI::Util::Layout::clearLayout(m_main_layout); + GUI::Util::Layout::clearLayout(main_layout); m_updaters.clear(); /* - m_main_layout->addRow("Axes units:", + main_layout->addRow("Axes units:", GUI::Util::createUnitsComboBox( axesUnitsList(), [this] { return currentData2DItem()->currentAxesUnits(); }, @@ -52,20 +62,20 @@ void AxesPanel::createPanelElements() &m_updaters)); */ - m_main_layout->addRow( - "Color scheme:", - GUI::Util::createComboBox([this] { return m_daw.currentData2DItem()->gradientCombo(); }, - [this](const QString& newVal) { - for (auto* item : m_daw.allData2DItems()) - item->setCurrentGradient(newVal); - gDoc->setModified(); - }, - false, &m_updaters)); - - m_main_layout->addRow(GUI::Util::createCheckBox( - "Interpolate", [this] { return m_daw.currentData2DItem()->isInterpolated(); }, + main_layout->addRow("Color scheme:", + GUI::Util::createComboBox( + [this] { return m_data_source->currentData2DItem()->gradientCombo(); }, + [this](const QString& newVal) { + for (auto* item : m_data_source->allData2DItems()) + item->setCurrentGradient(newVal); + gDoc->setModified(); + }, + false, &m_updaters)); + + main_layout->addRow(GUI::Util::createCheckBox( + "Interpolate", [this] { return m_data_source->currentData2DItem()->isInterpolated(); }, [this](bool b) { - for (auto* item : m_daw.allData2DItems()) + for (auto* item : m_data_source->allData2DItems()) item->setInterpolated(b); gDoc->setModified(); }, @@ -77,25 +87,27 @@ void AxesPanel::createPanelElements() xFormLayout->setContentsMargins(0, 0, 0, 0); xFormLayout->setSpacing(5); - xFormLayout->addRow("Min:", GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData2DItem()->axItemX()->min(); }, - [this](double newValue) { - for (auto* item : m_daw.allData2DItems()) - item->axItemX()->setMin(newValue); - gDoc->setModified(); - }, - &m_updaters)); - - xFormLayout->addRow("Max:", GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData2DItem()->axItemX()->max(); }, - [this](double newValue) { - for (auto* item : m_daw.allData2DItems()) - item->axItemX()->setMax(newValue); - gDoc->setModified(); - }, - &m_updaters)); - - m_main_layout->addRow(xGroup); + xFormLayout->addRow("Min:", + GUI::Util::createDoubleSpinBox( + [this] { return m_data_source->currentData2DItem()->axItemX()->min(); }, + [this](double newValue) { + for (auto* item : m_data_source->allData2DItems()) + item->axItemX()->setMin(newValue); + gDoc->setModified(); + }, + &m_updaters)); + + xFormLayout->addRow("Max:", + GUI::Util::createDoubleSpinBox( + [this] { return m_data_source->currentData2DItem()->axItemX()->max(); }, + [this](double newValue) { + for (auto* item : m_data_source->allData2DItems()) + item->axItemX()->setMax(newValue); + gDoc->setModified(); + }, + &m_updaters)); + + main_layout->addRow(xGroup); // -- y-axis auto* yGroup = new StaticGroupBox("Y axis", this); @@ -103,25 +115,27 @@ void AxesPanel::createPanelElements() yFormLayout->setContentsMargins(0, 0, 0, 0); yFormLayout->setSpacing(5); - yFormLayout->addRow("Min:", GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData2DItem()->axItemY()->min(); }, - [this](double newValue) { - for (auto* item : m_daw.allData2DItems()) - item->axItemY()->setMin(newValue); - gDoc->setModified(); - }, - &m_updaters)); - - yFormLayout->addRow("Max:", GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData2DItem()->axItemY()->max(); }, - [this](double newValue) { - for (auto* item : m_daw.allData2DItems()) - item->axItemY()->setMax(newValue); - gDoc->setModified(); - }, - &m_updaters)); - - m_main_layout->addRow(yGroup); + yFormLayout->addRow("Min:", + GUI::Util::createDoubleSpinBox( + [this] { return m_data_source->currentData2DItem()->axItemY()->min(); }, + [this](double newValue) { + for (auto* item : m_data_source->allData2DItems()) + item->axItemY()->setMin(newValue); + gDoc->setModified(); + }, + &m_updaters)); + + yFormLayout->addRow("Max:", + GUI::Util::createDoubleSpinBox( + [this] { return m_data_source->currentData2DItem()->axItemY()->max(); }, + [this](double newValue) { + for (auto* item : m_data_source->allData2DItems()) + item->axItemY()->setMax(newValue); + gDoc->setModified(); + }, + &m_updaters)); + + main_layout->addRow(yGroup); // -- color-axis auto* zGroup = new StaticGroupBox("Color legend", this); @@ -130,9 +144,9 @@ void AxesPanel::createPanelElements() zFormLayout->setSpacing(5); auto* logRangeSpinBox = GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData2DItem()->zAxisItem()->logRangeOrders(); }, + [this] { return m_data_source->currentData2DItem()->zAxisItem()->logRangeOrders(); }, [this](double newValue) { - for (auto* item : m_daw.mainData2DItems()) { + for (auto* item : m_data_source->mainData2DItems()) { item->zAxisItem()->setLogRangeOrders(newValue); updateUIValues(); } @@ -140,37 +154,37 @@ void AxesPanel::createPanelElements() }, &m_updaters, "Dynamic range to display values", RealLimits::positive()); - zFormLayout->addRow("Min:", - GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData2DItem()->zAxisItem()->min(); }, - [this](double newValue) { - for (auto* item : m_daw.allData2DItems()) { - item->zAxisItem()->setMin(newValue); - item->zAxisItem()->adjustLogRangeOrders(); - updateUIValues(); - } - gDoc->setModified(); - }, - &m_updaters)); - - zFormLayout->addRow("Max:", - GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData2DItem()->zAxisItem()->max(); }, - [this](double newValue) { - for (auto* item : m_daw.mainData2DItems()) { - item->zAxisItem()->setMax(newValue); - item->zAxisItem()->adjustLogRangeOrders(); - updateUIValues(); - } - gDoc->setModified(); - }, - &m_updaters)); + zFormLayout->addRow( + "Min:", GUI::Util::createDoubleSpinBox( + [this] { return m_data_source->currentData2DItem()->zAxisItem()->min(); }, + [this](double newValue) { + for (auto* item : m_data_source->allData2DItems()) { + item->zAxisItem()->setMin(newValue); + item->zAxisItem()->adjustLogRangeOrders(); + updateUIValues(); + } + gDoc->setModified(); + }, + &m_updaters)); + + zFormLayout->addRow( + "Max:", GUI::Util::createDoubleSpinBox( + [this] { return m_data_source->currentData2DItem()->zAxisItem()->max(); }, + [this](double newValue) { + for (auto* item : m_data_source->mainData2DItems()) { + item->zAxisItem()->setMax(newValue); + item->zAxisItem()->adjustLogRangeOrders(); + updateUIValues(); + } + gDoc->setModified(); + }, + &m_updaters)); zFormLayout->addRow(GUI::Util::createCheckBox( - "log10", [this] { return m_daw.currentData2DItem()->zAxisItem()->isLogScale(); }, + "log10", [this] { return m_data_source->currentData2DItem()->zAxisItem()->isLogScale(); }, [this, logRangeSpinBox](bool b) { logRangeSpinBox->setEnabled(b); - for (auto* item : m_daw.allData2DItems()) + for (auto* item : m_data_source->allData2DItems()) item->zAxisItem()->setLogScale(b); gDoc->setModified(); }, @@ -179,20 +193,20 @@ void AxesPanel::createPanelElements() zFormLayout->addRow("Log range:", logRangeSpinBox); zFormLayout->addRow(GUI::Util::createCheckBox( - "Visible", [this] { return m_daw.currentData2DItem()->zAxisItem()->isVisible(); }, + "Visible", [this] { return m_data_source->currentData2DItem()->zAxisItem()->isVisible(); }, [this](bool b) { - for (auto* item : m_daw.allData2DItems()) + for (auto* item : m_data_source->allData2DItems()) item->zAxisItem()->setVisible(b); gDoc->setModified(); }, &m_updaters)); - m_main_layout->addRow(zGroup); + main_layout->addRow(zGroup); updateUIValues(); // react on external changes (e.g. zooming in customplot shall update the axis values) - connect(m_daw.currentData2DItem(), &DataItem::itemAxesRangeChanged, this, + connect(m_data_source->currentData2DItem(), &DataItem::itemAxesRangeChanged, this, &AxesPanel::updateUIValues, Qt::UniqueConnection); // update coordinates on axes units change @@ -202,3 +216,20 @@ void AxesPanel::createPanelElements() &AxesPanel::updateItemCoords, Qt::UniqueConnection); */ } + +AxesPanel::~AxesPanel() = default; + +void AxesPanel::updateItemCoords(DataItem* item) +{ + if (!item) + return; + + emit item->axesUnitsReplotRequested(); + updateUIValues(); +} + +void AxesPanel::updateUIValues() +{ + for (const auto& updater : m_updaters) + updater(); +} diff --git a/GUI/View/Setup/AxesPanel.h b/GUI/View/Setup/AxesPanel.h index 5fc2b589ee1de01b0311d735fba34eb196dcc513..a8035edc16a6c033a27043b471a0e6bb60954b1d 100644 --- a/GUI/View/Setup/AxesPanel.h +++ b/GUI/View/Setup/AxesPanel.h @@ -15,13 +15,25 @@ #ifndef BORNAGAIN_GUI_VIEW_SETUP_AXESPANEL_H #define BORNAGAIN_GUI_VIEW_SETUP_AXESPANEL_H -#include "GUI/View/Access/DataPropertyWidget.h" +#include <QWidget> -//! Widget to edit properties of an Data2DItem. +class DataItem; +class DataSource; + +//! Widget to edit properties of a Data2DItem. + +class AxesPanel : public QWidget { +public: + AxesPanel(QObject* item); + ~AxesPanel(); -class AxesPanel : public DataPropertyWidget { private: - void createPanelElements() override; + void updateItemCoords(DataItem* item); + void updateUIValues(); + + QList<std::function<void()>> m_updaters; + + std::unique_ptr<DataSource> m_data_source; }; #endif // BORNAGAIN_GUI_VIEW_SETUP_AXESPANEL_H diff --git a/GUI/View/Setup/AxisPanel.cpp b/GUI/View/Setup/AxisPanel.cpp index 4d8e44cc83d64c133f44ca3d9e0a08a931a96ac5..be69a5f6b9ebe35300fde5d190356cffa8727875 100644 --- a/GUI/View/Setup/AxisPanel.cpp +++ b/GUI/View/Setup/AxisPanel.cpp @@ -13,9 +13,16 @@ // ************************************************************************************************ #include "GUI/View/Setup/AxisPanel.h" +#include "Base/Axis/Frame.h" +#include "Base/Util/Assert.h" #include "GUI/Model/Axis/AmplitudeAxisItem.h" #include "GUI/Model/Axis/BasicAxisItem.h" #include "GUI/Model/Data/Data1DItem.h" +#include "GUI/Model/Data/DataItem.h" +#include "GUI/Model/Device/DatafileItem.h" +#include "GUI/Model/Device/InstrumentItems.h" +#include "GUI/Model/Job/DataSource.h" +#include "GUI/Model/Job/JobItem.h" #include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Support/Data/ComboProperty.h" #include "GUI/View/Numeric/DoubleSpinBox.h" @@ -27,56 +34,52 @@ #include <QFormLayout> #include <QLineEdit> -void AxisPanel::createPanelElements() +AxisPanel::AxisPanel(QObject* item) + : m_data_source(std::make_unique<DataSource>(item)) { - if (m_daw.allData1DItems().empty()) + setWindowTitle("Properties"); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding); + + auto* main_layout = new QFormLayout(this); + main_layout->setContentsMargins(8, 20, 8, 8); + main_layout->setSpacing(5); + + if (m_data_source->allData1DItems().empty()) return; - for (auto* item : m_daw.allData1DItems()) + for (auto* item : m_data_source->allData1DItems()) disconnect(item, nullptr, this, nullptr); - GUI::Util::Layout::clearLayout(m_main_layout); + GUI::Util::Layout::clearLayout(main_layout); m_updaters.clear(); - /* - m_main_layout->addRow("Axes units:", - GUI::Util::createUnitsComboBox( - axesUnitsList(), - [this] { return currentData1DItem()->currentAxesUnits(); }, - [this](const QString& newVal) { - for (auto item : allData1DItems()) - item->setCurrentAxesUnits(newVal); - emit axesRangeResetRequested(); - gDoc->setModified(); - }, - &m_updaters)); - */ - // -- x-axis auto* xGroup = new StaticGroupBox("X axis", this); auto* xFormLayout = new QFormLayout(xGroup->body()); xFormLayout->setContentsMargins(0, 0, 0, 0); xFormLayout->setSpacing(5); - xFormLayout->addRow("Min:", GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData1DItem()->axItemX()->min(); }, - [this](double newValue) { - for (auto* item : m_daw.allData1DItems()) - item->axItemX()->setMin(newValue); - gDoc->setModified(); - }, - &m_updaters)); - - xFormLayout->addRow("Max:", GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData1DItem()->axItemX()->max(); }, - [this](double newValue) { - for (auto* item : m_daw.allData1DItems()) - item->axItemX()->setMax(newValue); - gDoc->setModified(); - }, - &m_updaters)); - - m_main_layout->addRow(xGroup); + xFormLayout->addRow("Min:", + GUI::Util::createDoubleSpinBox( + [this] { return m_data_source->currentData1DItem()->axItemX()->min(); }, + [this](double newValue) { + for (auto* item : m_data_source->allData1DItems()) + item->axItemX()->setMin(newValue); + gDoc->setModified(); + }, + &m_updaters)); + + xFormLayout->addRow("Max:", + GUI::Util::createDoubleSpinBox( + [this] { return m_data_source->currentData1DItem()->axItemX()->max(); }, + [this](double newValue) { + for (auto* item : m_data_source->allData1DItems()) + item->axItemX()->setMax(newValue); + gDoc->setModified(); + }, + &m_updaters)); + + main_layout->addRow(xGroup); // -- y-axis auto* yGroup = new StaticGroupBox("Y axis", this); @@ -85,9 +88,9 @@ void AxisPanel::createPanelElements() yFormLayout->setSpacing(5); auto* logRangeSpinBox = GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData1DItem()->axItemY()->logRangeOrders(); }, + [this] { return m_data_source->currentData1DItem()->axItemY()->logRangeOrders(); }, [this](double newValue) { - for (auto* item : m_daw.mainData1DItems()) { + for (auto* item : m_data_source->mainData1DItems()) { item->axItemY()->setLogRangeOrders(newValue); updateUIValues(); } @@ -95,35 +98,37 @@ void AxisPanel::createPanelElements() }, &m_updaters, "Dynamic range to display values", RealLimits::positive()); - yFormLayout->addRow("Min:", GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData1DItem()->axItemY()->min(); }, - [this](double newValue) { - for (auto* item : m_daw.mainData1DItems()) { - item->axItemY()->setMin(newValue); - item->axItemY()->adjustLogRangeOrders(); - updateUIValues(); - } - gDoc->setModified(); - }, - &m_updaters)); - - yFormLayout->addRow("Max:", GUI::Util::createDoubleSpinBox( - [this] { return m_daw.currentData1DItem()->axItemY()->max(); }, - [this](double newValue) { - for (auto* item : m_daw.mainData1DItems()) { - item->axItemY()->setMax(newValue); - item->axItemY()->adjustLogRangeOrders(); - updateUIValues(); - } - gDoc->setModified(); - }, - &m_updaters)); + yFormLayout->addRow("Min:", + GUI::Util::createDoubleSpinBox( + [this] { return m_data_source->currentData1DItem()->axItemY()->min(); }, + [this](double newValue) { + for (auto* item : m_data_source->mainData1DItems()) { + item->axItemY()->setMin(newValue); + item->axItemY()->adjustLogRangeOrders(); + updateUIValues(); + } + gDoc->setModified(); + }, + &m_updaters)); + + yFormLayout->addRow("Max:", + GUI::Util::createDoubleSpinBox( + [this] { return m_data_source->currentData1DItem()->axItemY()->max(); }, + [this](double newValue) { + for (auto* item : m_data_source->mainData1DItems()) { + item->axItemY()->setMax(newValue); + item->axItemY()->adjustLogRangeOrders(); + updateUIValues(); + } + gDoc->setModified(); + }, + &m_updaters)); yFormLayout->addRow(GUI::Util::createCheckBox( - "log10", [this] { return m_daw.currentData1DItem()->axItemY()->isLogScale(); }, + "log10", [this] { return m_data_source->currentData1DItem()->axItemY()->isLogScale(); }, [this, logRangeSpinBox](bool b) { logRangeSpinBox->setEnabled(b); - for (auto* item : m_daw.allData1DItems()) + for (auto* item : m_data_source->allData1DItems()) item->axItemY()->setLogScale(b); gDoc->setModified(); }, @@ -131,16 +136,33 @@ void AxisPanel::createPanelElements() yFormLayout->addRow("Log range:", logRangeSpinBox); - m_main_layout->addRow(yGroup); + main_layout->addRow(yGroup); updateUIValues(); // react on external changes (e.g. zooming in customplot shall update the axis values) - connect(m_daw.currentData1DItem(), &DataItem::itemAxesRangeChanged, this, + connect(m_data_source->currentData1DItem(), &DataItem::itemAxesRangeChanged, this, &AxisPanel::updateUIValues, Qt::UniqueConnection); // update coordinates on axes units change - for (auto* item : m_daw.allData1DItems()) + for (auto* item : m_data_source->allData1DItems()) connect(item, &DataItem::axesUnitsChanged, this, &AxisPanel::updateItemCoords, Qt::UniqueConnection); } + +AxisPanel::~AxisPanel() = default; + +void AxisPanel::updateItemCoords(DataItem* item) +{ + if (!item) + return; + + emit item->axesUnitsReplotRequested(); + updateUIValues(); +} + +void AxisPanel::updateUIValues() +{ + for (const auto& updater : m_updaters) + updater(); +} diff --git a/GUI/View/Setup/AxisPanel.h b/GUI/View/Setup/AxisPanel.h index 14107cbac13f1c04e5c0afee47bb8c587d9c2486..0e6440bbc12ebd47698f201ac78dd3e593f38e41 100644 --- a/GUI/View/Setup/AxisPanel.h +++ b/GUI/View/Setup/AxisPanel.h @@ -15,13 +15,25 @@ #ifndef BORNAGAIN_GUI_VIEW_SETUP_AXISPANEL_H #define BORNAGAIN_GUI_VIEW_SETUP_AXISPANEL_H -#include "GUI/View/Access/DataPropertyWidget.h" +#include <QWidget> + +class DataItem; +class DataSource; //! Widget to edit properties of a Data1DItem. -class AxisPanel : public DataPropertyWidget { +class AxisPanel : public QWidget { +public: + AxisPanel(QObject* item); + ~AxisPanel(); + private: - void createPanelElements() override; + void updateItemCoords(DataItem* item); + void updateUIValues(); + + QList<std::function<void()>> m_updaters; + + std::unique_ptr<DataSource> m_data_source; }; #endif // BORNAGAIN_GUI_VIEW_SETUP_AXISPANEL_H