BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
PolygonView.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/View/Mask/PolygonView.cpp
6 //! @brief Implements PolygonView 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 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
18 #include <QCursor>
19 #include <QPainter>
20 
21 namespace {
22 
23 const double bbox_margins = 5; // additional margins around points to form bounding box
24 }
25 
27  : IShape2DView(item)
28  , m_item(item)
29  , m_block_on_point_update(false)
30  , m_close_polygon_request(false)
31 {
32  setFlag(QGraphicsItem::ItemIsSelectable);
33  setFlag(QGraphicsItem::ItemIsMovable);
34  setFlag(QGraphicsItem::ItemSendsGeometryChanges);
35 }
36 
38 {
40 }
41 
43 {
44  return m_item;
45 }
46 
47 void PolygonView::addView(IShape2DView* childView, int row)
48 {
49  Q_UNUSED(row);
50 
51  if (childItems().contains(childView))
52  return;
53 
54  auto* pointView = dynamic_cast<PolygonPointView*>(childView);
55  ASSERT(pointView);
56  pointView->setParentItem(this);
57 
58  // polygon consisting from more than 2 points can be closed via hover event by clicking
59  // on first polygon point
60  if (!isClosedPolygon() && childItems().size() > 2)
61  childItems()[0]->setAcceptHoverEvents(true);
62 
63  pointView->setVisible(true);
65 
67  connect(pointView, &PolygonPointView::closePolygonRequest, this,
69 }
70 
71 //! Returns last added poligon point in scene coordinates
73 {
74  return !childItems().empty() ? childItems().back()->scenePos() : QPointF();
75 }
76 
77 QPainterPath PolygonView::shape() const
78 {
79  QPainterPath path;
80  path.addPolygon(m_polygon);
81  path.closeSubpath();
82  return path;
83 }
84 
85 //! Returns true if there was a request to close polygon (emitted by its start point),
86 //! and then closes a polygon. Returns true if polygon was closed.
88 {
90  for (QGraphicsItem* childItem : childItems()) {
91  childItem->setFlag(QGraphicsItem::ItemIsMovable);
92  childItem->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
93  childItem->setAcceptHoverEvents(false);
94  childItem->setCursor(Qt::SizeAllCursor);
95  }
96  m_item->setIsClosed(true);
97  update();
98  }
99  return isClosedPolygon();
100 }
101 
103 {
104  m_close_polygon_request = value;
105 }
106 
108 {
109  return m_item->isClosed();
110 }
111 
112 void PolygonView::paint(QPainter* painter, const QStyleOptionGraphicsItem* o, QWidget* w)
113 {
114  if (isClosedPolygon())
115  IShape2DView::paint(painter, o, w);
116  else {
117  ASSERT(m_item);
118  const bool mask_value = static_cast<PolygonItem*>(m_item)->maskValue();
119  painter->setRenderHints(QPainter::Antialiasing);
120  painter->setPen(MaskEditorHelper::getMaskPen(mask_value));
121  painter->drawPolyline(m_polygon.toPolygon());
122  }
123 }
124 
125 QVariant PolygonView::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
126 {
127  if (change == QGraphicsItem::ItemSelectedHasChanged)
128  setChildrenVisible(this->isSelected());
129 
130  return value;
131 }
132 
133 void PolygonView::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
134 {
135  IShape2DView::mouseMoveEvent(event);
136  update_points();
137 }
138 
140 {
141  update_polygon();
142  update();
143 }
144 
145 //! Runs through all PolygonPointItem and calculate bounding rectangle.
146 //! Determines position of the rectangle in scene.
147 //! Calculates position of PolygonPointView in local polygon coordinates
149 {
151  return;
152 
154 
155  if (!m_item->points().isEmpty()) {
156  m_polygon.clear();
157 
158  for (auto* point : m_item->points())
159  m_polygon << QPointF(toSceneX(point->posX()), toSceneY(point->posY()));
160 
161  const QRectF scene_rect = m_polygon.boundingRect().marginsAdded(
162  QMarginsF(bbox_margins, bbox_margins, bbox_margins, bbox_margins));
163 
164  m_bounding_rect = QRectF(0.0, 0.0, scene_rect.width(), scene_rect.height());
165 
166  setPos(scene_rect.x(), scene_rect.y());
167  update(); // to propagate changes to scene
168 
169  m_polygon = mapFromScene(m_polygon);
170 
171  int index(0);
172  for (auto* childView : childItems())
173  childView->setPos(m_polygon[index++]);
174 
175  setPos(scene_rect.x(), scene_rect.y());
176  }
177  m_block_on_point_update = false;
178 }
179 
180 //! When polygon moves as a whole thing across the scene, given method updates coordinates
181 //! of PolygonPointItem's
183 {
185  return;
186 
187  for (QGraphicsItem* childItem : childItems()) {
188  auto* view = dynamic_cast<PolygonPointView*>(childItem);
189  QPointF pos = view->scenePos();
191  view->updateParameterizedItem(pos);
193  }
194 }
195 
197 {
198  for (QGraphicsItem* childItem : childItems())
199  childItem->setVisible(value);
200 }
201 
203 {
204  m_item = nullptr;
205 }
Defines MaskItems classes.
Defines PolygonPointView class.
Defines PolygonView class.
Main interface class for views representing MaskItems, Projections on graphics scene.
Definition: IShape2DView.h:27
qreal toSceneX(qreal value) const
void disconnectFromItem(SessionItem *item)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override
qreal toSceneY(qreal value) const
QRectF m_bounding_rect
Definition: IShape2DView.h:68
static QPen getMaskPen(bool mask_value)
void setIsClosed(bool closed)
Definition: MaskItems.cpp:278
QVector< PolygonPointItem * > points() const
Definition: MaskItems.cpp:284
bool isClosed() const
Definition: MaskItems.cpp:273
This is a View of polygon point for PolygonMaskItem.
void closePolygonRequest(bool)
void propertyChanged()
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
void onClosePolygonRequest(bool value)
bool closePolygonIfNecessary()
Returns true if there was a request to close polygon (emitted by its start point),...
Definition: PolygonView.cpp:87
void onItemDestroyed() override
~PolygonView() override
Definition: PolygonView.cpp:37
PolygonView(PolygonItem *item)
Definition: PolygonView.cpp:26
bool m_close_polygon_request
Definition: PolygonView.h:65
QPointF lastAddedPoint() const
Returns last added poligon point in scene coordinates.
Definition: PolygonView.cpp:72
PolygonItem * m_item
Definition: PolygonView.h:62
QPolygonF m_polygon
Definition: PolygonView.h:63
void addView(IShape2DView *childView, int row) override
Definition: PolygonView.cpp:47
void update_view() override
void update_polygon()
Runs through all PolygonPointItem and calculate bounding rectangle. Determines position of the rectan...
bool isClosedPolygon()
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override
QPainterPath shape() const override
Definition: PolygonView.cpp:77
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override
SessionItem * parameterizedItem() const override
Definition: PolygonView.cpp:42
void update_points()
When polygon moves as a whole thing across the scene, given method updates coordinates of PolygonPoin...
bool m_block_on_point_update
Definition: PolygonView.h:64
void setChildrenVisible(bool value)
Base class for a GUI data item.
Definition: SessionItem.h:204