BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
SelectionProperty.h
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/Model/Descriptor/SelectionProperty.h
6 //! @brief Defines class SelectionProperty
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2021
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #ifndef BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONPROPERTY_H
16 #define BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONPROPERTY_H
17 
20 
21 //! Class for representing a selection, its attributes and its accessors.
22 //!
23 //! A "selection" in this context is a class instance out of a range of possible class instances.
24 //!
25 //! Example:
26 //! A distribution can be represented by DistributionGateItem, DistributionLorentzItem and more. The
27 //! common base class is DistributionItem. To store the currently distribution, you may use a member
28 //! of DistributionItem* which than holds an instance of the currently selected distribution (e.g.
29 //! DistributionGateItem*). To select between distributions, you need a combo box filled with the
30 //! distribution names, a label for the combo box, and so on.
31 //!
32 //! This class provides many of these attributes and functionalities:
33 //! * A pointer to the common base class (given as the template argument T). The lifetime of this
34 //! pointer is handled in here.
35 //! * label: a label of e.g. a spin box
36 //! * tooltip: tooltip for e.g. a spin box
37 //! * persistent tag: a name to serialize this property. Do not change this string, since it is
38 //! serialized!
39 //! * A list of available options (e.g. the names of the distributions)
40 //! * A descriptor which provides some of the given information, as well as getters/setters.
41 //!
42 //! For the initialization of a SelectionProperty there are helper methods. They are not necessarily
43 //! to be called if they are not convenient. They are only there to help initialization e.g by using
44 //! a catalog. If no catalog exists for the given case, the initialization can be done by any means.
45 //!
46 //! This means especially that this class is **not** relying on the existence of a related catalog
47 //! class - a catalog helps but is not mandatory.
48 //!
49 //! \sa SelectionDescriptor
50 //!
51 template <typename T>
53 public:
54  ~SelectionProperty() { delete m_p; }
55 
56  //! Initialize by means of a catalog class and optional creation arguments.
57  //!
58  //! The current selection will be initialized with the first type in the catalog types. The
59  //! optional arguments are the arguments which may be necessary for the creation method in the
60  //! catalog.
61  template <typename Catalog, typename... ArgsForCreation>
62  void init(const QString& label, const QString& tooltip, const QString& persistentTag,
63  ArgsForCreation... argsForCreation)
64  {
66  initDescriptor<Catalog>(label, tooltip, Catalog::types(), argsForCreation...);
67  m_descriptor.setCurrentIndex(0);
68  }
69 
70  //! Initialize by means of a catalog class and an initializer function.
71  //!
72  //! The current selection will be initialized with the first type in the catalog types.
73  //! Each newly created item can be initialized with the given initializer method. Note that the
74  //! item creation will take place also after a call to this method, so take care that the given
75  //! initializer stays valid throughout the lifetime of this SelectionProperty instance.
76  //!
77  //! The initializer function takes two arguments: The first is the new item, the second is the
78  //! old one (if present; can be null). This is intended to maybe copy values from the old to the
79  //! new selection. The old item also can be ignored, always according to the current
80  //! needs.
81  template <typename Catalog>
82  void initWithInitializer(const QString& label, const QString& tooltip,
83  const QString& persistentTag,
84  std::function<void(T newItem, const T oldItem)> initializer)
85  {
86  m_initializer = initializer;
88 
89  initDescriptor<Catalog>(label, tooltip, Catalog::types());
90  m_descriptor.setCurrentIndex(0);
91  }
92 
93  //! Initialize by means of a catalog class, a subsection of allowed types and an initializer
94  //! function.
95  //!
96  //! Same as before, but only a subset of types available in a catalog shall be used.
97  //! The current selection will be initialized with the first type in the given types subset.
98  //! Each newly created item can be initialized with the given initializer method. Note that the
99  //! item creation will take place also after a call to this method, so take care that the given
100  //! initializer stays valid throughout the lifetime of this SelectionProperty instance.
101  //!
102  //! The initializer function takes two arguments: The first is the new item, the second is the
103  //! old one (if present; can be null). This is intended to maybe copy values from the old to the
104  //! new selection. The old item also can be ignored, always according to the current
105  //! needs.
106  template <typename Catalog>
107  void initWithInitializer(const QString& label, const QString& tooltip,
108  const QString& persistentTag,
109  const QVector<typename Catalog::Type>& types,
110  std::function<void(T newItem, const T oldItem)> initializer)
111  {
112  m_initializer = initializer;
114 
115  initDescriptor<Catalog>(label, tooltip, types);
116  m_descriptor.setCurrentIndex(0);
117  }
118 
119  //! Returns a descriptor working on this property.
121 
122  //! Cast to a descriptor working on this property.
123  operator SelectionDescriptor<T>() const { return m_descriptor; }
124 
125  //! Direct access to the stored pointer
126  T operator->() const { return m_p; }
127 
128  //! Direct access to the stored pointer
129  T get() const { return m_p; }
130 
131  //! Directly set the new item.
132  void set(T t, bool callInitializer = false)
133  {
134  if (callInitializer && m_initializer)
135  m_initializer(t, m_p);
136  delete m_p;
137  m_p = t;
138  }
139 
140  //! Directly set the new item.
141  template <typename S, typename... ArgsForConstructor>
142  S* set(ArgsForConstructor... argsForConstructor)
143  {
144  S* s = new S(argsForConstructor...);
145  if (s != nullptr && m_initializer)
146  m_initializer(s, m_p);
147  m_p = s;
148  return s;
149  }
150 
151  //! Persistent tag for serializing.
152  QString persistentTag() const { return m_persistentTag; }
153 
154 
155 private:
156  template <typename Catalog, typename... ArgsForCreation>
157  void initDescriptor(const QString& label, const QString& tooltip,
158  const QVector<typename Catalog::Type>& types,
159  ArgsForCreation... argsForCreation)
160 
161  {
162  auto setCurrentIndex = [=](int current) {
163  auto* p = Catalog::create(types[current], argsForCreation...);
164  if (m_initializer)
165  m_initializer(p, m_p);
166  m_p = p;
167  };
168 
169  m_descriptor.label = label;
170  m_descriptor.tooltip = tooltip;
171  for (const auto type : types)
172  m_descriptor.options << Catalog::uiInfo(type).menuEntry;
173  m_descriptor.currentIndexSetter = setCurrentIndex;
174  m_descriptor.currentIndexGetter = [=]() { return types.indexOf(Catalog::type(m_p)); };
175  m_descriptor.currentItem = [=] { return m_p; };
176  }
177 
178 private:
179  QString m_persistentTag; //!< Persistent tag for serializing
180  SelectionDescriptor<T> m_descriptor; //!< descriptor, holding attributes like label, tooltip
181  T m_p = nullptr; //!< Current selection
182 
183  //! initializer function. Can be empty.
184  //! The first argument is the new item, the second is the old one if present; can be null.
185  //! This is intended to maybe copy values from the old to the new selection. oldItem also can be
186  //! ignored if not relevant,
187  std::function<void(T newItem, const T oldItem)> m_initializer;
188 };
189 
190 // Extends namespace defined in GUI/Model/XML/Serialize.h
191 namespace Serialize {
192 
193 //! Serializes an item from a catalog.
194 //! Passes optional arguments to the constructor.
195 template <typename Catalog, typename... ArgsForCreation>
197  ArgsForCreation... argsForCreation);
198 
199 } // namespace Serialize
200 
201 // ************************************************************************************************
202 // Template implementation
203 // ************************************************************************************************
204 
205 template <typename Catalog, typename... ArgsForCreation>
207  ArgsForCreation... argsForCreation)
208 {
209  if (QXmlStreamWriter* w = s.xmlWriter()) {
210  typename Catalog::CatalogedType* p = d.get();
211  s.write<Catalog>(d.persistentTag(), p);
212  } else if (QXmlStreamReader* r = s.xmlReader()) {
213  typename Catalog::CatalogedType* p = nullptr;
214  s.read<Catalog>(d.persistentTag(), p, argsForCreation...);
215  d.set(p);
216  }
217 }
218 
219 #endif // BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONPROPERTY_H
Defines class SelectionDescriptor.
Defines class Streamer.
Describes a selection (various possibilities and the current one).
Class for representing a selection, its attributes and its accessors.
S * set(ArgsForConstructor... argsForConstructor)
Directly set the new item.
T m_p
Current selection.
QString m_persistentTag
Persistent tag for serializing.
void initDescriptor(const QString &label, const QString &tooltip, const QVector< typename Catalog::Type > &types, ArgsForCreation... argsForCreation)
SelectionDescriptor< T > m_descriptor
descriptor, holding attributes like label, tooltip
void initWithInitializer(const QString &label, const QString &tooltip, const QString &persistentTag, const QVector< typename Catalog::Type > &types, std::function< void(T newItem, const T oldItem)> initializer)
Initialize by means of a catalog class, a subsection of allowed types and an initializer function.
SelectionDescriptor< T > descriptor() const
Returns a descriptor working on this property.
void set(T t, bool callInitializer=false)
Directly set the new item.
T get() const
Direct access to the stored pointer.
QString persistentTag() const
Persistent tag for serializing.
void init(const QString &label, const QString &tooltip, const QString &persistentTag, ArgsForCreation... argsForCreation)
Initialize by means of a catalog class and optional creation arguments.
void initWithInitializer(const QString &label, const QString &tooltip, const QString &persistentTag, std::function< void(T newItem, const T oldItem)> initializer)
Initialize by means of a catalog class and an initializer function.
T operator->() const
Direct access to the stored pointer.
std::function< void(T newItem, const T oldItem)> m_initializer
initializer function. Can be empty. The first argument is the new item, the second is the old one if ...
Supports serialization to or deserialization from QXmlStream.
Definition: Streamer.h:36
void write(const QString &tag, typename Catalog::CatalogedType *p)
Definition: Streamer.h:82
QXmlStreamWriter * xmlWriter()
Returns stream writer or nullptr.
Definition: Streamer.h:47
QXmlStreamReader * xmlReader()
Returns stream reader or nullptr.
Definition: Streamer.h:48
void read(const QString &tag, typename Catalog::CatalogedType *&p, Args... argsForConstructor)
Definition: Streamer.h:93
Functions to serialize various data types.
Definition: SessionItem.h:339
void rwSelected(Streamer &s, SelectionProperty< typename Catalog::CatalogedType * > &d, ArgsForCreation... argsForCreation)
Serializes an item from a catalog. Passes optional arguments to the constructor.