BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
elementview.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file gui2/sldeditor/elementview.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 Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
18 
19 #include <QCursor>
20 #include <QPainter>
21 #include <QPainterPath>
22 
23 namespace gui2 {
24 
25 //! The constructor
26 ElementView::ElementView() : QGraphicsObject()
27 {
28  setAcceptHoverEvents(true);
29 }
30 
31 ElementView::~ElementView() = default;
32 
33 //! Get the conversion axes
35 {
36  GraphicsScene* scene_item = static_cast<GraphicsScene*>(scene());
37  if (!scene_item)
38  return nullptr;
39 
40  return scene_item->sceneAdapter();
41 }
42 
43 //! Advance method used by the scene adapter
44 void ElementView::advance(int phase)
45 {
46  if (!phase)
47  return;
48  prepareGeometryChange();
49  update();
50 }
51 
52 //! paint override
53 void ElementView::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/,
54  QWidget* /*widget*/)
55 {
56  painter->setClipRect(sceneAdapter()->viewportRectangle());
57 }
58 
59 //! modify the rectangle for display according to the scene adapter
60 QRectF ElementView::displayRect(const QRectF& real_rect) const
61 {
62  auto adapter = sceneAdapter();
63  if (!adapter)
64  return real_rect;
65 
66  auto output = QRectF(real_rect);
67 
68  if (m_center_based) {
69  output = displayRectCenterBased(real_rect);
70  } else {
71  output = displayRectEdgeBased(real_rect);
72  }
73 
74  if (m_stretch_left) {
75  output = stretchRectLeft(output);
76  } else if (m_stretch_right) {
77  output = stretchRectRight(output);
78  }
79 
80  return output;
81 }
82 
83 //! Helper function for displayRect based on the center of real_rect
84 QRectF ElementView::displayRectCenterBased(const QRectF& real_rect) const
85 {
86  auto adapter = sceneAdapter();
87  double x = real_rect.x();
88  double y = real_rect.y();
89  double w = real_rect.width();
90  double h = real_rect.height();
91 
92  double center_x = x + w / 2.;
93  double center_y = y + h / 2.;
94 
95  if (m_adapt_x) {
96  center_x = adapter->toSceneX(-center_x);
97  }
98  if (m_adapt_y) {
99  center_y = adapter->toSceneY(center_y);
100  }
101  if (m_adapt_width) {
102  w = adapter->toSceneX(w) - adapter->toSceneX(0);
103  }
104  if (m_adapt_height) {
105  h = adapter->toSceneY(h) - adapter->toSceneY(0);
106  }
107 
108  x = center_x - w / 2;
109  y = center_y - h / 2;
110 
111  return QRectF(x, y, w, h);
112 }
113 
114 //! Helper function for displayRect based on the edge of real_rect
115 QRectF ElementView::displayRectEdgeBased(const QRectF& real_rect) const
116 {
117  auto adapter = sceneAdapter();
118  double x = real_rect.x();
119  double y = real_rect.y();
120  double w = real_rect.width();
121  double h = real_rect.height();
122 
123  if (m_adapt_x) {
124  x = adapter->toSceneX(-x);
125  }
126  if (m_adapt_y) {
127  y = adapter->toSceneY(y);
128  }
129  if (m_adapt_width) {
130  w = adapter->toSceneX(w) - adapter->toSceneX(0);
131  }
132  if (m_adapt_height) {
133  h = adapter->toSceneY(h) - adapter->toSceneY(0);
134  }
135 
136  return QRectF(x, y, w, h);
137 }
138 
139 //! Stretch the rectangle to the left limit of the viewport
140 QRectF ElementView::stretchRectLeft(const QRectF& real_rect) const
141 {
142  double x_i = real_rect.x();
143  double y_i = real_rect.y();
144  double x_f = real_rect.x() + real_rect.width();
145  double y_f = real_rect.y() + real_rect.height();
146 
147  auto viewport_rect = sceneAdapter()->viewportRectangle();
148  x_i = viewport_rect.x();
149 
150  return QRectF(x_i, y_i, x_f - x_i, y_f - y_i);
151 }
152 
153 //! Stretch the rectangle to the right limit of the viewport
154 QRectF ElementView::stretchRectRight(const QRectF& real_rect) const
155 {
156  double x_i = real_rect.x();
157  double y_i = real_rect.y();
158  double x_f = real_rect.x() + real_rect.width();
159  double y_f = real_rect.y() + real_rect.height();
160 
161  auto viewport_rect = sceneAdapter()->viewportRectangle();
162  x_f = viewport_rect.x() + viewport_rect.width();
163 
164  return QRectF(x_i, y_i, x_f - x_i, y_f - y_i);
165 }
166 
167 //! modify the path for display according to the scene adapter
168 QPainterPath ElementView::displayPath(QPainterPath real_path) const
169 {
170  auto adapter = sceneAdapter();
171  if (!adapter)
172  return real_path;
173 
174  auto display_path = QPainterPath(real_path);
175  for (int i = 0; i < display_path.elementCount(); i++) {
176  QPointF pt = display_path.elementAt(i);
177  display_path.setElementPositionAt(i, adapter->toSceneX(-pt.x()), adapter->toSceneY(pt.y()));
178  }
179  return display_path;
180 }
181 
182 //! modify the rectangle for display according to the scene adapter
183 QPointF ElementView::scenePos(QPointF pixel_pos) const
184 {
185  auto adapter = sceneAdapter();
186  if (!adapter)
187  return pixel_pos;
188 
189  return QPointF(-adapter->fromSceneX(pixel_pos.x()), adapter->fromSceneY(pixel_pos.y()));
190 }
191 
192 //! Adapt the dimensions according to the center
194 {
195  m_center_based = choice;
196 }
197 
198 //! Adapt the x position
199 void ElementView::adaptX(bool choice)
200 {
201  m_adapt_x = choice;
202 }
203 
204 //! Adapt the y position
205 void ElementView::adaptY(bool choice)
206 {
207  m_adapt_y = choice;
208 }
209 
210 //! Adapt the width
211 void ElementView::adaptW(bool choice)
212 {
213  m_adapt_width = choice;
214 }
215 
216 //! Adapt the height
217 void ElementView::adaptH(bool choice)
218 {
219  m_adapt_height = choice;
220 }
221 
222 //! Stretch the rectangle to the left limit of the viewport
223 void ElementView::stretchLeft(bool choice)
224 {
225  m_stretch_left = choice;
226 }
227 
228 //! Stretch the rectangle to the right limit of the viewport
229 void ElementView::stretchRight(bool choice)
230 {
231  m_stretch_right = choice;
232 }
233 
234 //! The hoover enter event
235 void ElementView::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
236 {
237  if (flags() & QGraphicsItem::ItemIsMovable)
238  setCursor(QCursor(Qt::OpenHandCursor));
239  QGraphicsItem::hoverEnterEvent(event);
240 }
241 
242 //! The hoover exit event
243 void ElementView::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
244 {
245  unsetCursor();
246  QGraphicsItem::hoverLeaveEvent(event);
247 }
248 
249 //! The mouse press event
250 void ElementView::mousePressEvent(QGraphicsSceneMouseEvent* event)
251 {
252  if (flags() & QGraphicsItem::ItemIsMovable)
253  setCursor(QCursor(Qt::ClosedHandCursor));
254  QGraphicsItem::mousePressEvent(event);
255 }
256 
257 //! The mouse release event
258 void ElementView::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
259 {
260  if (flags() & QGraphicsItem::ItemIsMovable)
261  setCursor(QCursor(Qt::OpenHandCursor));
262  QGraphicsItem::mouseReleaseEvent(event);
263 }
264 
265 } // namespace gui2
Interface to convert coordinates of "scene" to coordinates of "widget".
virtual QRectF viewportRectangle() const =0
returns viewport rectangle in scene coordinates
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
paint override
Definition: elementview.cpp:53
void setCenterBased(bool choice)
Adapt the dimensions according to the center.
QPointF scenePos(QPointF pixel_pos) const
modify the rectangle for display according to the scene adapter
QRectF stretchRectLeft(const QRectF &real_rect) const
Stretch the rectangle to the left limit of the viewport.
QPainterPath displayPath(QPainterPath real_path) const
modify the path for display according to the scene adapter
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
The mouse press event.
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
The mouse release event.
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override
The hoover exit event.
void advance(int phase) override
Advance method used by the scene adapter.
Definition: elementview.cpp:44
ModelView::SceneAdapterInterface * sceneAdapter() const
Get the conversion axes.
Definition: elementview.cpp:34
void stretchRight(bool choice)
Stretch the rectangle to the right limit of the viewport.
void stretchLeft(bool choice)
Stretch the rectangle to the left limit of the viewport.
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override
The hoover enter event.
QRectF displayRectEdgeBased(const QRectF &real_rect) const
Helper function for displayRect based on the edge of real_rect.
QRectF displayRect(const QRectF &real_rect) const
modify the rectangle for display according to the scene adapter
Definition: elementview.cpp:60
void adaptY(bool choice)
Adapt the y position.
void adaptX(bool choice)
Adapt the x position.
QRectF displayRectCenterBased(const QRectF &real_rect) const
Helper function for displayRect based on the center of real_rect.
Definition: elementview.cpp:84
void adaptW(bool choice)
Adapt the width.
QRectF stretchRectRight(const QRectF &real_rect) const
Stretch the rectangle to the right limit of the viewport.
void adaptH(bool choice)
Adapt the height.
ElementView()
The constructor.
Definition: elementview.cpp:26
Custom graphics scene to show QCustomPlot with additional elements on top.
Definition: graphicsscene.h:34
ModelView::SceneAdapterInterface * sceneAdapter() const
Return the pointer of the scene adapter on request.
Defines class CLASS?
Defines class CLASS?
Based on Qt example "codeeditor" Copyright (C) 2016 The Qt Company Ltd.
Definition: app_constants.h:20
Defines class CLASS?