From 5b094d751d8d91d0c1ea1f5aa8fe743a29a60a1e Mon Sep 17 00:00:00 2001
From: Dmitry Yurov <d.yurov@fz-juelich.de>
Date: Mon, 9 Jul 2018 13:22:40 +0200
Subject: [PATCH] FitComparison1DViewController prototype

Redmine: #2106
---
 .../FitComparisonViewController.cpp           | 130 ++++++++++++++++++
 .../FitWidgets/FitComparisonViewController.h  |  51 +++++++
 2 files changed, 181 insertions(+)
 create mode 100644 GUI/coregui/Views/FitWidgets/FitComparisonViewController.cpp
 create mode 100644 GUI/coregui/Views/FitWidgets/FitComparisonViewController.h

diff --git a/GUI/coregui/Views/FitWidgets/FitComparisonViewController.cpp b/GUI/coregui/Views/FitWidgets/FitComparisonViewController.cpp
new file mode 100644
index 00000000000..3c63f1dfa96
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/FitComparisonViewController.cpp
@@ -0,0 +1,130 @@
+#include "FitComparisonViewController.h"
+#include "AxesItems.h"
+#include "DataItem.h"
+#include "DataItem1DView.h"
+#include "IntensityDataFunctions.h"
+#include "JobItem.h"
+#include "PropertyRepeater.h"
+#include "RealDataItem.h"
+#include "SessionModel.h"
+
+namespace
+{
+const double relative_diff_min_1d = 1e-05;
+const double relative_diff_max_1d = 4.0;
+}
+
+FitComparison1DViewController::FitComparison1DViewController(QObject* parent)
+    : QObject(parent),
+      m_diff_item_controller(new DiffItemController(Constants::SpecularDataType, this)),
+      m_diff_view_item(dynamic_cast<DataItem1DView*>(
+          m_diff_item_controller->model()->insertNewItem(Constants::DataItem1DViewType))),
+      m_appearanceRepeater(new PropertyRepeater(this)), m_xAxisRepeater(new PropertyRepeater(this))
+{
+    m_diff_view_item->addItem(m_diff_item_controller->diffItem());
+}
+
+DataItem1DView* FitComparison1DViewController::diffItemView()
+{
+    return m_diff_view_item;
+}
+
+void FitComparison1DViewController::setItem(JobItem* job_item)
+{
+    assert(job_item);
+
+    clear();
+    m_diff_item_controller->setJobItem(job_item);
+    diffItemView()->setJobItem(job_item);
+
+    auto job_data_view = job_item->dataItemView();
+
+    m_appearanceRepeater->addItem(job_data_view);
+    m_appearanceRepeater->addItem(diffItemView());
+
+    m_xAxisRepeater->addItem(job_data_view->xAxisItem());
+    m_xAxisRepeater->addItem(diffItemView()->xAxisItem());
+
+    diffItemView()->setXaxisTitle(job_data_view->getXaxisTitle());
+    diffItemView()->setYaxisTitle("Relative difference");
+    diffItemView()->setLowerY(relative_diff_min_1d);
+    diffItemView()->setUpperY(relative_diff_max_1d);
+}
+
+void FitComparison1DViewController::updateDiffData()
+{
+    m_diff_item_controller->updateDiffData();
+}
+
+void FitComparison1DViewController::resetDiffView()
+{
+    diffItemView()->resetView();
+    diffItemView()->setLowerY(relative_diff_min_1d);
+    diffItemView()->setUpperY(relative_diff_max_1d);
+}
+
+void FitComparison1DViewController::clear()
+{
+    m_diff_item_controller->unsubscribe();
+    m_appearanceRepeater->clear();
+    m_xAxisRepeater->clear();
+}
+
+DiffItemController::DiffItemController(const QString& data_type, QObject* parent)
+    : QObject(parent), m_current_item(nullptr),
+      m_private_model(new SessionModel("TempIntensityDataModel", this)),
+      m_diff_item(dynamic_cast<DataItem*>(m_private_model->insertNewItem(data_type)))
+{
+    assert(m_diff_item);
+}
+
+DiffItemController::~DiffItemController()
+{
+    unsubscribe();
+}
+
+void DiffItemController::setJobItem(JobItem* job_item)
+{
+    assert(job_item);
+    if (m_current_item)
+        unsubscribe();
+    m_current_item = job_item;
+    subscribe();
+    updateDiffData();
+}
+
+void DiffItemController::updateDiffData()
+{
+    assert(m_current_item);
+
+    auto sim_data = m_current_item->dataItem();
+    auto real_data = m_current_item->realDataItem()->dataItem();
+    assert(sim_data && real_data);
+
+    if (!sim_data->getOutputData()) // job failed
+        return;
+
+    m_diff_item->setOutputData(IntensityDataFunctions::createRelativeDifferenceData(
+                                   *sim_data->getOutputData(), *real_data->getOutputData())
+                                   .release());
+}
+
+void DiffItemController::subscribe()
+{
+    if (!m_current_item) {
+        assert(false);
+        return;
+    }
+
+    // on simulation data change
+    m_current_item->dataItem()->mapper()->setOnValueChange([this]() { updateDiffData(); }, this);
+}
+
+void DiffItemController::unsubscribe()
+{
+    if (!m_current_item)
+        return;
+    m_current_item->dataItem()->mapper()->unsubscribe(this);
+    m_diff_item->mapper()->unsubscribe(this);
+    m_current_item = nullptr;
+}
diff --git a/GUI/coregui/Views/FitWidgets/FitComparisonViewController.h b/GUI/coregui/Views/FitWidgets/FitComparisonViewController.h
new file mode 100644
index 00000000000..c50c8db382c
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/FitComparisonViewController.h
@@ -0,0 +1,51 @@
+#ifndef FITCOMPARISONVIEWCONTROLLER_H
+#define FITCOMPARISONVIEWCONTROLLER_H
+
+#include "WinDllMacros.h"
+#include <QObject>
+
+class DataItem;
+class DataItem1DView;
+class JobItem;
+class PropertyRepeater;
+class SessionModel;
+
+class BA_CORE_API_ DiffItemController : public QObject
+{
+public:
+    DiffItemController(const QString& data_type, QObject* parent);
+    ~DiffItemController() override;
+    SessionModel* model() {return m_private_model;}
+    void setJobItem(JobItem* job_item);
+    JobItem* jobItem() {return m_current_item;}
+    void updateDiffData();
+    DataItem* diffItem() {return m_diff_item;}
+    void subscribe();
+    void unsubscribe();
+private:
+    JobItem* m_current_item;
+    SessionModel* m_private_model;
+    DataItem* m_diff_item;
+};
+
+class BA_CORE_API_ FitComparison1DViewController : public QObject
+{
+public:
+    explicit FitComparison1DViewController(QObject* parent);
+
+    DataItem1DView* diffItemView();
+
+    void setItem(JobItem* job_item);
+    void updateDiffData();
+    void resetDiffView();
+
+    void clear();
+
+private:
+    DiffItemController* m_diff_item_controller;
+    DataItem1DView* m_diff_view_item;
+    PropertyRepeater* m_appearanceRepeater;
+    PropertyRepeater* m_xAxisRepeater;
+};
+
+#endif // FITCOMPARISONVIEWCONTROLLER_H
-- 
GitLab