BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
graphcanvas.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // qt-mvvm: Model-view-view-model framework for large GUI applications
4 //
5 //! @file mvvm/view/mvvm/plotting/graphcanvas.cpp
6 //! @brief Implements class CLASS?
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2020
11 //! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
22 #include "qcustomplot.h"
23 #include <QBoxLayout>
24 
25 namespace {
26 
27 //! Returns policy to which side of the axes box margins can be applied.
28 //! If number is negative, this side will be callulated automatically.
29 
30 // FIXME move to utils, provide unit tests
31 QCP::MarginSides autoMarginPolicy(int left, int top, int right, int bottom)
32 {
33  QCP::MarginSides result{QCP::msAll};
34  if (left >= 0)
35  result &= ~QCP::msLeft;
36  if (top >= 0)
37  result &= ~QCP::msTop;
38  if (right >= 0)
39  result &= ~QCP::msRight;
40  if (bottom >= 0)
41  result &= ~QCP::msBottom;
42  return result;
43 }
44 } // namespace
45 
46 using namespace ModelView;
47 
49  QCustomPlot* custom_plot{nullptr};
50  std::unique_ptr<GraphViewportPlotController> viewport_controller;
51  std::unique_ptr<StatusStringReporter> reporter;
53 
55  {
56  viewport_controller = std::make_unique<GraphViewportPlotController>(custom_plot);
57 
58  auto on_mouse_move = [this](const std::string& str) {
59  status_label->setText(QString::fromStdString(str));
60  };
61  reporter = CreateGraphReporter(custom_plot, on_mouse_move);
62  }
63 
64  //! Updates viewport.
66  {
67  if (!viewport_controller->currentItem())
68  return;
69  viewport_controller->currentItem()->setViewportToContent();
70  }
71 
72  //! Updates viewport.
73  void setViewportToContent(double left, double top, double right, double bottom)
74  {
75  if (!viewport_controller->currentItem())
76  return;
77  viewport_controller->currentItem()->setViewportToContent(left, top, right, bottom);
78  }
79 
80  QCustomPlot* customPlot() { return custom_plot; }
81 };
82 
83 GraphCanvas::GraphCanvas(QWidget* parent)
84  : QWidget(parent), p_impl(std::make_unique<GraphCanvasImpl>())
85 {
86  auto layout = new QVBoxLayout(this);
87  layout->setMargin(0);
88  layout->setSpacing(0);
89  layout->addWidget(p_impl->custom_plot);
90  layout->addWidget(p_impl->status_label);
91  setLayout(layout);
92 
93  setMouseTracking(true);
94  p_impl->customPlot()->setMouseTracking(true);
95  p_impl->customPlot()->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
96  p_impl->customPlot()->axisRect()->setupFullAxesBox(true);
97 
98  auto on_replot = [this]() {
99  QMargins margins = p_impl->customPlot()->axisRect()->margins();
100  axisMarginsChanged(margins.left(), margins.top(), margins.right(), margins.bottom());
101  };
102  connect(p_impl->customPlot(), &QCustomPlot::afterReplot, this, on_replot);
103 }
104 
105 GraphCanvas::~GraphCanvas() = default;
106 
108 {
109  p_impl->viewport_controller->setItem(viewport_item);
110 }
111 
112 std::unique_ptr<SceneAdapterInterface> GraphCanvas::createSceneAdapter() const
113 {
114  return std::make_unique<CustomPlotSceneAdapter>(p_impl->customPlot());
115 }
116 
117 void GraphCanvas::setViewportToContent(double left, double top, double right, double bottom)
118 {
119  p_impl->setViewportToContent(left, top, right, bottom);
120 }
121 
123 {
124  p_impl->setViewportToContent();
125 }
126 
127 //! Set margins between axes rectangle and widget borders.
128 //! If the value is negative, leave old margin intact and allow automatic margin adjustment.
129 
130 void GraphCanvas::setAxisMargins(int left, int top, int right, int bottom)
131 {
132  auto customPlot = p_impl->customPlot();
133  customPlot->axisRect()->setAutoMargins(autoMarginPolicy(left, top, right, bottom));
134 
135  QMargins orig = customPlot->axisRect()->margins();
136  int new_left = left >= 0 ? left : orig.left();
137  int new_top = top >= 0 ? top : orig.top();
138  int new_right = right >= 0 ? right : orig.right();
139  int new_bottom = bottom >= 0 ? bottom : orig.bottom();
140  customPlot->axisRect()->setMargins(QMargins(new_left, new_top, new_right, new_bottom));
141 
142  customPlot->replot();
143 }
void setAxisMargins(int left, int top, int right, int bottom)
Set margins between axes rectangle and widget borders.
std::unique_ptr< GraphCanvasImpl > p_impl
Definition: graphcanvas.h:51
void axisMarginsChanged(int left, int top, int right, int bottom)
void setItem(GraphViewportItem *viewport_item)
GraphCanvas(QWidget *parent=nullptr)
Definition: graphcanvas.cpp:83
std::unique_ptr< SceneAdapterInterface > createSceneAdapter() const
2D viewport specialized for showing multiple GraphItem's.
Shows a single line of text on a white background.
Definition: statuslabel.h:29
void setText(const QString &text)
Definition: statuslabel.cpp:31
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
materialitems.h Collection of materials to populate MaterialModel.
std::unique_ptr< StatusStringReporter > CreateGraphReporter(QCustomPlot *custom_plot, std::function< void(const std::string &)> callback)
Creates reporter for status string in QCustomPlot containing graphs.
Definition: filesystem.h:81
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
void setViewportToContent(double left, double top, double right, double bottom)
Updates viewport.
Definition: graphcanvas.cpp:73
std::unique_ptr< StatusStringReporter > reporter
Definition: graphcanvas.cpp:51
std::unique_ptr< GraphViewportPlotController > viewport_controller
Definition: graphcanvas.cpp:50
void setViewportToContent()
Updates viewport.
Definition: graphcanvas.cpp:65