BornAgain  1.19.0
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/coregui/Views/MaskWidgets/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 const double bbox_margins = 5; // additional margins around points to form bounding box
23 }
24 
25 PolygonView::PolygonView() : m_block_on_point_update(false), m_close_polygon_request(false)
26 {
27  setFlag(QGraphicsItem::ItemIsSelectable);
28  setFlag(QGraphicsItem::ItemIsMovable);
29  setFlag(QGraphicsItem::ItemSendsGeometryChanges);
30 }
31 
32 void PolygonView::addView(IShape2DView* childView, int row)
33 {
34  Q_UNUSED(row);
35 
36  if (childItems().contains(childView))
37  return;
38 
39  PolygonPointView* pointView = dynamic_cast<PolygonPointView*>(childView);
40  ASSERT(pointView);
41  pointView->setParentItem(this);
42 
43  // polygon consisting from more than 2 points can be closed via hover event by clicking
44  // on first polygon point
45  if (!isClosedPolygon() && childItems().size() > 2)
46  childItems()[0]->setAcceptHoverEvents(true);
47 
48  pointView->setVisible(true);
50 
52  connect(pointView, &PolygonPointView::closePolygonRequest, this,
54 }
55 
56 //! returns last added poligon point in scene coordinates
58 {
59  return childItems().size() ? childItems().back()->scenePos() : QPointF();
60 }
61 
62 //! Returns true if there was a request to close polygon (emitted by its start point),
63 //! and then closes a polygon. Returns true if polygon was closed.
65 {
67  for (QGraphicsItem* childItem : childItems()) {
68  childItem->setFlag(QGraphicsItem::ItemIsMovable);
69  childItem->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
70  childItem->setAcceptHoverEvents(false);
71  childItem->setCursor(Qt::SizeAllCursor);
72  }
74  update();
75  }
76  return isClosedPolygon();
77 }
78 
80 {
82 }
83 
85 {
87 }
88 
89 void PolygonView::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
90 {
91  ASSERT(m_item);
92  painter->setRenderHints(QPainter::Antialiasing);
93 
94  bool mask_value = m_item->getItemValue(MaskItem::P_MASK_VALUE).toBool();
95  painter->setBrush(MaskEditorHelper::getMaskBrush(mask_value));
96  painter->setPen(MaskEditorHelper::getMaskPen(mask_value));
97 
98  // painter->drawRect(m_bounding_rect);
99 
100  painter->drawPolyline(m_polygon.toPolygon());
101 
102  if (isClosedPolygon())
103  painter->drawPolygon(m_polygon.toPolygon());
104 }
105 
106 QVariant PolygonView::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
107 {
108  if (change == QGraphicsItem::ItemSelectedHasChanged)
109  setChildrenVisible(this->isSelected());
110 
111  return value;
112 }
113 
114 void PolygonView::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
115 {
116  IShape2DView::mouseMoveEvent(event);
117  update_points();
118 }
119 
121 {
122  update_polygon();
123  update();
124 }
125 
126 //! Runs through all PolygonPointItem and calculate bounding rectangle.
127 //! Determines position of the rectangle in scene.
128 //! Calculates position of PolygonPointView in local polygon coordinates
130 {
132  return;
133 
135 
136  if (m_item->numberOfChildren()) {
137 
138  m_polygon.clear();
139 
140  for (SessionItem* item : m_item->getChildrenOfType("PolygonPoint")) {
141  qreal px = toSceneX(item->getItemValue(PolygonPointItem::P_POSX).toReal());
142  qreal py = toSceneY(item->getItemValue(PolygonPointItem::P_POSY).toReal());
143  m_polygon << QPointF(px, py);
144  }
145  QRectF scene_rect = m_polygon.boundingRect().marginsAdded(
146  QMarginsF(bbox_margins, bbox_margins, bbox_margins, bbox_margins));
147 
148  m_bounding_rect = QRectF(0.0, 0.0, scene_rect.width(), scene_rect.height());
149 
150  setPos(scene_rect.x(), scene_rect.y());
151  update(); // to propagate changes to scene
152 
153  m_polygon = mapFromScene(m_polygon);
154 
155  // for (int i = 0; i < childItems().size(); ++i) {
156  // QGraphicsItem* childView = childItems()[i];
157  // childView->setPos(m_polygon[i]);
158  // }
159  int index(0);
160  for (auto childView : childItems())
161  childView->setPos(m_polygon[index++]);
162 
163  setPos(scene_rect.x(), scene_rect.y());
164  }
165  m_block_on_point_update = false;
166 }
167 
168 //! When polygon moves as a whole thing across the scene, given method updates coordinates
169 //! of PolygonPointItem's
171 {
173  return;
174 
175  for (QGraphicsItem* childItem : childItems()) {
176  PolygonPointView* view = dynamic_cast<PolygonPointView*>(childItem);
177  QPointF pos = view->scenePos();
179  view->updateParameterizedItem(pos);
181  }
182 }
183 
185 {
186  for (QGraphicsItem* childItem : childItems())
187  childItem->setVisible(value);
188 }
#define ASSERT(condition)
Definition: Assert.h:31
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(const QString &property_name) const
qreal toSceneY(const QString &property_name) const
SessionItem * m_item
Definition: IShape2DView.h:65
QRectF m_bounding_rect
Definition: IShape2DView.h:67
static QBrush getMaskBrush(bool mask_value)
static QPen getMaskPen(bool mask_value)
static const QString P_MASK_VALUE
Definition: MaskItems.h:33
static const QString P_ISCLOSED
Definition: MaskItems.h:65
static const QString P_POSX
Definition: MaskItems.h:57
static const QString P_POSY
Definition: MaskItems.h:58
This is a View of polygon point for PolygonMaskItem.
void closePolygonRequest(bool)
void updateParameterizedItem(const QPointF &pos)
void propertyChanged()
void update_view()
void onClosePolygonRequest(bool value)
Definition: PolygonView.cpp:79
bool closePolygonIfNecessary()
Returns true if there was a request to close polygon (emitted by its start point),...
Definition: PolygonView.cpp:64
void addView(IShape2DView *childView, int row)
Definition: PolygonView.cpp:32
bool m_close_polygon_request
Definition: PolygonView.h:55
QPointF lastAddedPoint() const
returns last added poligon point in scene coordinates
Definition: PolygonView.cpp:57
void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
QPolygonF m_polygon
Definition: PolygonView.h:53
void update_polygon()
Runs through all PolygonPointItem and calculate bounding rectangle.
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
bool isClosedPolygon()
Definition: PolygonView.cpp:84
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
Definition: PolygonView.cpp:89
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:54
void setChildrenVisible(bool value)
int numberOfChildren() const
Returns total number of children.
Definition: SessionItem.cpp:94
QVariant getItemValue(const QString &tag) const
Directly access value of item under given tag.
void setItemValue(const QString &tag, const QVariant &variant)
Directly set value of item under given tag.
QVector< SessionItem * > getChildrenOfType(const QString &model_type) const
Returns a vector of all children of the given type.