BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
FormLayouter.h
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/View/SampleDesigner/FormLayouter.h
6 //! @brief Defines classes FormLayouter
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_VIEW_SAMPLEDESIGNER_FORMLAYOUTER_H
16 #define BORNAGAIN_GUI_VIEW_SAMPLEDESIGNER_FORMLAYOUTER_H
17 
20 #include <QFormLayout>
21 
22 class DoubleDescriptor;
23 class QPushButton;
24 class QString;
25 class QWidget;
27 class UIntDescriptor;
28 class VectorDescriptor;
29 
30 //! Utility class to populate a QFormLayout.
31 //!
32 //! Helps to add edit controls which operate on descriptors (DoubleDescriptor, UIntDescriptor and so
33 //! on). Also takes care of bold printed labels, the connection of labels and edit controls
34 //! (buddies), which is necessary to realize the "label shows unit of value" feature.
35 //! Connections to a given SampleEditorController are established as well.
36 class FormLayouter {
37 public:
38  //! Create a layouter which operates on the given parent widget.
39  //!
40  //! If the parent has no layout yet, a QFormLayout is installed. If the parentWidget already has
41  //! a QFormLayout, this will be used for the calls later on.
42  //! The given SampleEditorController is used to create connections e.g. when a DoubleSpinBox
43  //! value has been changed.
44  FormLayouter(QWidget* parent, SampleEditorController* ec);
45 
46  //! The layout where this layouter is operating on.
47  //!
48  //! Use this, if you want to modify the layout with means not given in here.
49  QFormLayout* layout();
50 
51  //! Convenience method to set the contents margins.
52  //!
53  //! Directly calls QFormLayout::setContentsMargins()
54  void setContentsMargins(int left, int top, int right, int bottom);
55 
56  //! Convenience method to add a widget.
57  //!
58  //! Calls QFormLayout::addRow() and returns the row of the newly added widget.
59  int addRow(QWidget* w);
60 
61  //! Convenience method to insert a widget.
62  //!
63  //! Calls QFormLayout::insertRow().
64  void insertRow(int row, QWidget* w);
65 
66  //! Add a row with a bold printed label.
67  //!
68  //! If necessary, a colon (':') is added to the label.
69  //! Returns the newly added row.
70  int addRow(const QString& label, QWidget* w);
71 
72  //! Insert a row with a bold printed label.
73  //!
74  //! If necessary, a colon (':') is added to the label.
75  void insertRow(int row, QString label, QWidget* w);
76 
77  //! Add a row with a selection.
78  //!
79  //! The whole selection is realized by adding a SelectionContainerForm. This
80  //! SelectionContainerForm is limited to contain the selection combo box and a list of double
81  //! values represented by DoubleDescriptors. To add more complex selections (e.g. with
82  //! sub-selections or different value types), this method and the SelectionContainerForm is not
83  //! sufficient. It has to be done "manually".
84  //! For more details, see SelectionContainerForm.
85  //! Returns the newly added row.
86  template <typename T>
88 
89  //! Adds a row with a bold printed label and a DoubleSpinBox.
90  //!
91  //! The DoubleSpinBox is initialized with the contents found in the descriptor (e.g. limits,
92  //! decimals, unit). The DoubleSpinBox is set as the "buddy" of the label. This is necessary to
93  //! realize the "label shows unit of value" feature. Changes of the DoubleSpinBox are signaled
94  //! to the SampleEditorController which has been overhanded in the constructor of this
95  //! FormLayouter. It is connected to SampleEditorController::setDouble(). If a different method
96  //! should be called (e.g. for a special undo functionality), this method is not sufficient. It
97  //! would have to be done "manually" or with the overload which takes a slot (see below).
98  //! Returns the newly added row.
99  int addValue(const DoubleDescriptor& d);
100 
101  //! Adds a row with a bold printed label and a DoubleSpinBox.
102  //!
103  //! Same as above, but the called slot in case of a value change has to be overhanded.
104  //! Use this only if the standard (calling SampleEditorController::setDouble()) is not
105  //! sufficient.
106  int addValue(const DoubleDescriptor& d, function<void(double)> onValueChange);
107 
108  //! Adds a row with a bold printed label and a QSpinBox.
109  //!
110  //! Right now in the sample model there is no uint value which has a unit, therefore no unit
111  //! displaying is implemented. Beside this, the same as for addValue(DoubleDescriptor) applies.
112  //! Returns the newly added row.
113  int addValue(const UIntDescriptor& d);
114 
115  //! Inserts a row with a bold printed label and a DoubleSpinBox.
116  //!
117  //! Same functionality as addValue(), please read there.
118  void insertValue(int row, const DoubleDescriptor& d);
119 
120  //! Inserts a row with a bold printed label and a DoubleSpinBox.
121  //!
122  //! Same functionality as addValue(), please read there.
123  void insertValue(int row, const DoubleDescriptor& d, function<void(double)> onValueChange);
124 
125  //! Adds a row with a bold printed label and a set of DoubleDescriptors.
126  //!
127  //! The label describes the set of the Descriptors and is located in the first column of the
128  //! layout. The DoubleSpinBoxes for each DoubleDescriptor are created as children of a newly
129  //! created widget, which is positioned in the second column of the layout. If the number of
130  //! values is greater than 1, the related labels are shown above them, to limit the necessary
131  //! space to the right. For the creation, signaling, unit handling etc. of one DoubleDescriptor
132  //! the same applies as when adding a single DoubleDesciptor with the method addValue(),
133  //! therefore please read there for more details. Returns the newly added row.
134  int addGroupOfValues(const QString& labelText, const DoubleDescriptors& values);
135 
136  //! Adds a row with a bold printed label and the 3 values of a 3D vector.
137  //!
138  //! Works the same as addGroupOfValues. The label is taken from the VectorDescriptor.
139  //! In addition, the caller can define whether the labels are above the values
140  //! (vertically=true), or whether labels and values are all placed in one row
141  //! (vertically=false).
142  int addVector(const VectorDescriptor& d, bool vertically = true);
143 
144  //! Shows or hides the widgets in a row.
145  void setRowVisible(int row, bool visible);
146 
147  //! Convenience method to remove a row.
148  //!
149  //! Calls QFormLayout::removeRow().
150  void removeRow(int row);
151 
152  //! Adds a button for structure editing.
153  //!
154  //! Creates a widget, places the given button as a child left-aligned into this widget and adds
155  //! the newly created widget as a row in the layout.
156  void addStructureEditingRow(QPushButton* button);
157 
158  //! Find a widget in the given position.
159  //!
160  //! The widget will be qobject_cast'ed to the template parameter
161  template <typename T>
162  T widgetAt(int row, QFormLayout::ItemRole role);
163 
164 private:
166  QFormLayout* m_formLayout;
167 };
168 
169 template <typename T>
171 {
172  auto* w = new SelectionContainerForm(m_formLayout->parentWidget(), d, m_ec);
173  return addRow(d.label, w);
174 }
175 
176 template <typename T>
177 T FormLayouter::widgetAt(int row, QFormLayout::ItemRole role)
178 {
179  return qobject_cast<T>(m_formLayout->itemAt(row, role)->widget());
180 }
181 
182 #endif // BORNAGAIN_GUI_VIEW_SAMPLEDESIGNER_FORMLAYOUTER_H
QList< DoubleDescriptor > DoubleDescriptors
Defines class SelectionContainerForm.
Defines class SelectionDescriptor.
Describes properties of a double value which are necessary to allow GUI representation,...
Utility class to populate a QFormLayout.
Definition: FormLayouter.h:36
int addGroupOfValues(const QString &labelText, const DoubleDescriptors &values)
Adds a row with a bold printed label and a set of DoubleDescriptors.
void addStructureEditingRow(QPushButton *button)
Adds a button for structure editing.
QFormLayout * layout()
The layout where this layouter is operating on.
QFormLayout * m_formLayout
Definition: FormLayouter.h:166
int addRow(QWidget *w)
Convenience method to add a widget.
T widgetAt(int row, QFormLayout::ItemRole role)
Find a widget in the given position.
Definition: FormLayouter.h:177
int addValue(const DoubleDescriptor &d)
Adds a row with a bold printed label and a DoubleSpinBox.
void insertValue(int row, const DoubleDescriptor &d)
Inserts a row with a bold printed label and a DoubleSpinBox.
SampleEditorController * m_ec
Definition: FormLayouter.h:165
void insertRow(int row, QWidget *w)
Convenience method to insert a widget.
int addVector(const VectorDescriptor &d, bool vertically=true)
Adds a row with a bold printed label and the 3 values of a 3D vector.
FormLayouter(QWidget *parent, SampleEditorController *ec)
Create a layouter which operates on the given parent widget.
void removeRow(int row)
Convenience method to remove a row.
void setRowVisible(int row, bool visible)
Shows or hides the widgets in a row.
void setContentsMargins(int left, int top, int right, int bottom)
Convenience method to set the contents margins.
int addSelection(const SelectionDescriptor< T > &d)
Add a row with a selection.
Definition: FormLayouter.h:170
Class to modify a sample from the layer oriented sample editor.
A widget to contain a selection, defined by a SelectionDescriptor.
Describes a selection (various possibilities and the current one).
QString label
A label text (short, no trailing colon)
Describes properties of a uint value which are necessary to allow GUI representation,...
Describes properties of a 3D vector, consisting of three double values.