BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
IShape2DView.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/View/Mask/IShape2DView.cpp
6 //! @brief Implements interface IShape2DView.
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 <QAction>
19 #include <QGraphicsScene>
20 #include <QGraphicsSceneContextMenuEvent>
21 #include <QMenu>
22 #include <QPainter>
23 
24 namespace {
25 
26 bool itemMaskValue(const SessionItem* item)
27 {
28  if (const auto* maskItem = dynamic_cast<const MaskItem*>(item))
29  return maskItem->maskValue();
30  return false;
31 }
32 
33 } // namespace
34 
36  : m_adaptor(nullptr)
37  , m_block_on_property_change(false)
38 {
39  connect(this, &IShape2DView::xChanged, this, &IShape2DView::onChangedX);
40  connect(this, &IShape2DView::yChanged, this, &IShape2DView::onChangedY);
41 
42  if (item) {
43  item->mapper()->setOnPropertyChange(
44  [this](const QString& name) { onItemPropertyChange(name); }, this);
45 
46  item->mapper()->setOnItemDestroy([this](SessionItem*) { onItemDestroyed(); }, this);
47  }
48 }
49 
51 {
52  return m_bounding_rect;
53 }
54 
56 {
57  ASSERT(adaptor);
58 
59  if (m_adaptor != adaptor) {
60  if (m_adaptor)
62 
63  m_adaptor = adaptor;
65  Qt::UniqueConnection);
66  update_view();
67  }
68 }
69 
70 void IShape2DView::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
71 {
72  const bool isMasked = itemMaskValue(parameterizedItem());
73  painter->setBrush(MaskEditorHelper::getMaskBrush(isMasked));
74  painter->setPen(MaskEditorHelper::getMaskPen(isMasked));
75  painter->setRenderHints(QPainter::Antialiasing);
76  painter->drawPath(maskedShape());
77 }
78 
79 QPainterPath IShape2DView::maskedShape() const
80 {
81  static const QSet<MaskEditorHelper::EViewTypes> relevantMaskTypes = {
84 
85  QPainterPath resultingShape = mapToScene(shape());
86  for (auto* item : scene()->items()) {
87  auto* const maskItem = dynamic_cast<IShape2DView*>(item);
88  if (!maskItem
89  || !relevantMaskTypes.contains((MaskEditorHelper::EViewTypes)maskItem->type()))
90  continue;
91 
92  const bool isMaskingItem = itemMaskValue(maskItem->parameterizedItem());
93  const bool isOnTop = maskItem->zValue() > zValue();
94  if (isMaskingItem || !isOnTop)
95  continue;
96 
97  const auto maskItemShape = maskItem->mapToScene(maskItem->shape());
98  if (!maskItemShape.intersects(resultingShape))
99  continue;
100 
101  // Item lays on top and is non-masking -> subtract the
102  // path of the item
103  resultingShape = resultingShape.subtracted(maskItemShape);
104  }
105 
106  return mapFromScene(resultingShape);
107 }
108 
109 qreal IShape2DView::toSceneX(qreal value) const
110 {
111  return m_adaptor ? m_adaptor->toSceneX(value) : value;
112 }
113 
114 qreal IShape2DView::toSceneY(qreal value) const
115 {
116  return m_adaptor ? m_adaptor->toSceneY(value) : value;
117 }
118 
119 qreal IShape2DView::fromSceneX(qreal value) const
120 {
121  return m_adaptor ? m_adaptor->fromSceneX(value) : value;
122 }
123 
124 qreal IShape2DView::fromSceneY(qreal value) const
125 {
126  return m_adaptor ? m_adaptor->fromSceneY(value) : value;
127 }
128 
129 void IShape2DView::addView(IShape2DView* childView, int /* row */)
130 {
131  if (!childItems().contains(childView))
132  childView->setParentItem(this);
133 }
134 
136 {
138 }
139 
141 {
143 }
144 
146 {
147  if (item)
148  item->mapper()->unsubscribe(this);
149 }
150 
151 void IShape2DView::onItemPropertyChange(const QString& propertyName)
152 {
154  return;
155 
157 
158  bool schedule_update = false;
159  if (MaskItem::isMaskValuePropertyName(propertyName))
160  schedule_update = true;
161  else if (MaskItem::isIsVisiblePropertyName(propertyName)) {
162  bool visible = false;
163  if (auto* maskItem = dynamic_cast<MaskItem*>(parameterizedItem()))
164  visible = maskItem->isVisibleValue();
165  this->setVisible(visible);
166  schedule_update = true;
167  }
168 
170 
171  if (schedule_update)
172  update();
173 
175 }
Defines interface class ISceneAdaptor.
Defines interface IShape2DView.
Defines MaskItems classes.
Interface to adapt MaskItems coordinates (expressed in units of IntensityDataItem) to/from scene coor...
Definition: ISceneAdaptor.h:24
virtual qreal fromSceneX(qreal) const =0
convert scene x-coordinate to native mask coordinate
virtual qreal toSceneY(qreal) const =0
convert native mask y-coordinate to scene coordinate
virtual qreal fromSceneY(qreal) const =0
convert scene y-coordinate to native mask coordinate
void update_request()
virtual qreal toSceneX(qreal) const =0
convert native mask x-coordinate to scene coordinate
Main interface class for views representing MaskItems, Projections on graphics scene.
Definition: IShape2DView.h:27
virtual void onPropertyChange()
Definition: IShape2DView.h:46
virtual void addView(IShape2DView *childView, int row=0)
virtual SessionItem * parameterizedItem() const =0
virtual void onItemDestroyed()=0
virtual void onChangedX()
Definition: IShape2DView.h:44
virtual void update_view()=0
update visual appearance of view (triggered by ISceneAdaptor)
const ISceneAdaptor * m_adaptor
Definition: IShape2DView.h:67
qreal toSceneX(qreal value) const
QRectF boundingRect() const override
qreal fromSceneY(qreal value) const
void setBlockOnProperty(bool value)
void disconnectFromItem(SessionItem *item)
QPainterPath maskedShape() const
Returns the shape with all masking already applied.
bool blockOnProperty() const
void onItemPropertyChange(const QString &propertyName)
qreal fromSceneX(qreal value) const
convert scene coordinates to ColorMap plot coordinates
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override
void setSceneAdaptor(const ISceneAdaptor *adaptor)
virtual void onChangedY()
Definition: IShape2DView.h:45
qreal toSceneY(qreal value) const
bool m_block_on_property_change
Definition: IShape2DView.h:69
QRectF m_bounding_rect
Definition: IShape2DView.h:68
IShape2DView(SessionItem *item)
static QBrush getMaskBrush(bool mask_value)
static QPen getMaskPen(bool mask_value)
A base class for all mask items.
Definition: MaskItems.h:27
static bool isIsVisiblePropertyName(const QString &name)
Definition: MaskItems.cpp:105
static bool isMaskValuePropertyName(const QString &name)
Definition: MaskItems.cpp:90
void unsubscribe(const void *caller)
Cancels all subscriptions of given caller.
Definition: ModelMapper.cpp:78
void setOnItemDestroy(std::function< void(SessionItem *)> f, const void *caller=nullptr)
Definition: ModelMapper.cpp:67
void setOnPropertyChange(std::function< void(QString)> f, const void *caller=nullptr)
Definition: ModelMapper.cpp:39
Base class for a GUI data item.
Definition: SessionItem.h:204
ModelMapper * mapper()
Returns the current model mapper of this item. Creates new one if necessary.
QString const & name(EShape k)
Definition: particles.cpp:20