BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
FormLayouter Class Reference

Description

Utility class to populate a QFormLayout.

Helps to add edit controls which operate on descriptors (DoubleDescriptor, UIntDescriptor and so on). Also takes care of bold printed labels, the connection of labels and edit controls (buddies), which is necessary to realize the "label shows unit of value" feature. Connections to a given SampleEditorController are established as well.

Definition at line 36 of file FormLayouter.h.

Collaboration diagram for FormLayouter:
[legend]

Public Member Functions

 FormLayouter (QWidget *parent, SampleEditorController *ec)
 Create a layouter which operates on the given parent widget. More...
 
int addGroupOfValues (const QString &labelText, const DoubleDescriptors &values)
 Adds a row with a bold printed label and a set of DoubleDescriptors. More...
 
int addRow (const QString &label, QWidget *w)
 Add a row with a bold printed label. More...
 
int addRow (QWidget *w)
 Convenience method to add a widget. More...
 
template<typename T >
int addSelection (const SelectionDescriptor< T > &d)
 Add a row with a selection. More...
 
void addStructureEditingRow (QPushButton *button)
 Adds a button for structure editing. More...
 
int addValue (const DoubleDescriptor &d)
 Adds a row with a bold printed label and a DoubleSpinBox. More...
 
int addValue (const DoubleDescriptor &d, function< void(double)> onValueChange)
 Adds a row with a bold printed label and a DoubleSpinBox. More...
 
int addValue (const UIntDescriptor &d)
 Adds a row with a bold printed label and a QSpinBox. More...
 
int addVector (const VectorDescriptor &d, bool vertically=true)
 Adds a row with a bold printed label and the 3 values of a 3D vector. More...
 
void insertRow (int row, QString label, QWidget *w)
 Insert a row with a bold printed label. More...
 
void insertRow (int row, QWidget *w)
 Convenience method to insert a widget. More...
 
void insertValue (int row, const DoubleDescriptor &d)
 Inserts a row with a bold printed label and a DoubleSpinBox. More...
 
void insertValue (int row, const DoubleDescriptor &d, function< void(double)> onValueChange)
 Inserts a row with a bold printed label and a DoubleSpinBox. More...
 
QFormLayout * layout ()
 The layout where this layouter is operating on. More...
 
void removeRow (int row)
 Convenience method to remove a row. More...
 
void setContentsMargins (int left, int top, int right, int bottom)
 Convenience method to set the contents margins. More...
 
void setRowVisible (int row, bool visible)
 Shows or hides the widgets in a row. More...
 
template<typename T >
widgetAt (int row, QFormLayout::ItemRole role)
 Find a widget in the given position. More...
 

Private Attributes

SampleEditorControllerm_ec
 
QFormLayout * m_formLayout
 

Constructor & Destructor Documentation

◆ FormLayouter()

FormLayouter::FormLayouter ( QWidget *  parent,
SampleEditorController ec 
)

Create a layouter which operates on the given parent widget.

If the parent has no layout yet, a QFormLayout is installed. If the parentWidget already has a QFormLayout, this will be used for the calls later on. The given SampleEditorController is used to create connections e.g. when a DoubleSpinBox value has been changed.

Definition at line 54 of file FormLayouter.cpp.

55  : m_ec(ec)
56 {
57  if (parent->layout() != nullptr) {
58  m_formLayout = dynamic_cast<QFormLayout*>(parent->layout());
59  if (m_formLayout == nullptr) {
60  auto* collapser =
61  GroupBoxCollapser::findInstalledCollapser(dynamic_cast<QGroupBox*>(parent));
62  if (collapser)
63  m_formLayout = dynamic_cast<QFormLayout*>(collapser->contentArea()->layout());
64  }
65  ASSERT(m_formLayout);
66  } else {
67  m_formLayout = new QFormLayout(parent);
68  m_formLayout->setFormAlignment(Qt::AlignLeft | Qt::AlignBottom);
69  m_formLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
70  }
71 }
QFormLayout * m_formLayout
Definition: FormLayouter.h:166
SampleEditorController * m_ec
Definition: FormLayouter.h:165
static GroupBoxCollapser * findInstalledCollapser(QGroupBox *groupBox)

References GroupBoxCollapser::findInstalledCollapser(), and m_formLayout.

Here is the call graph for this function:

Member Function Documentation

◆ addGroupOfValues()

int FormLayouter::addGroupOfValues ( const QString &  labelText,
const DoubleDescriptors values 
)

Adds a row with a bold printed label and a set of DoubleDescriptors.

The label describes the set of the Descriptors and is located in the first column of the layout. The DoubleSpinBoxes for each DoubleDescriptor are created as children of a newly created widget, which is positioned in the second column of the layout. If the number of values is greater than 1, the related labels are shown above them, to limit the necessary space to the right. For the creation, signaling, unit handling etc. of one DoubleDescriptor the same applies as when adding a single DoubleDesciptor with the method addValue(), therefore please read there for more details. Returns the newly added row.

Definition at line 96 of file FormLayouter.cpp.

97 {
98  auto* w = new QWidget(m_formLayout->parentWidget());
99  w->setObjectName("PropertyBaseWidget");
100  w->setAttribute(Qt::WA_StyledBackground, true);
101  w->setStyleSheet("#PropertyBaseWidget {background-color: transparent}");
102 
103  auto* gridLayout = new QGridLayout(w);
104  gridLayout->setContentsMargins(0, 0, 0, 0);
105  gridLayout->setSpacing(6);
106 
107  LayerEditorUtils::addMultiPropertyToGrid(gridLayout, 0, values, m_ec, true);
108 
109  return addRow(labelText, w);
110 }
int addRow(QWidget *w)
Convenience method to add a widget.
void addMultiPropertyToGrid(QGridLayout *m_gridLayout, int firstCol, const DoubleDescriptors &valueDescriptors, SampleEditorController *ec, bool vertically, bool addSpacer)
Create DoubleSpinBoxes for the DoubeDescriptors and connect them to SampleEditorController::setDouble...

References LayerEditorUtils::addMultiPropertyToGrid(), addRow(), m_ec, and m_formLayout.

Referenced by ParticleForm::ParticleForm().

Here is the call graph for this function:

◆ addRow() [1/2]

int FormLayouter::addRow ( const QString &  label,
QWidget *  w 
)

Add a row with a bold printed label.

If necessary, a colon (':') is added to the label. Returns the newly added row.

Definition at line 83 of file FormLayouter.cpp.

84 {
85  insertRow(m_formLayout->rowCount(), label, w);
86  return m_formLayout->rowCount() - 1;
87 }
void insertRow(int row, QWidget *w)
Convenience method to insert a widget.

References insertRow(), and m_formLayout.

Here is the call graph for this function:

◆ addRow() [2/2]

int FormLayouter::addRow ( QWidget *  w)

◆ addSelection()

template<typename T >
int FormLayouter::addSelection ( const SelectionDescriptor< T > &  d)

Add a row with a selection.

The whole selection is realized by adding a SelectionContainerForm. This SelectionContainerForm is limited to contain the selection combo box and a list of double values represented by DoubleDescriptors. To add more complex selections (e.g. with sub-selections or different value types), this method and the SelectionContainerForm is not sufficient. It has to be done "manually". For more details, see SelectionContainerForm. Returns the newly added row.

Definition at line 170 of file FormLayouter.h.

171 {
172  auto* w = new SelectionContainerForm(m_formLayout->parentWidget(), d, m_ec);
173  return addRow(d.label, w);
174 }
A widget to contain a selection, defined by a SelectionDescriptor.
QString label
A label text (short, no trailing colon)

References addRow(), SelectionDescriptor< T >::label, m_ec, and m_formLayout.

Referenced by MesoCrystalForm::MesoCrystalForm(), ParticleCompositionForm::ParticleCompositionForm(), ParticleCoreShellForm::ParticleCoreShellForm(), ParticleForm::ParticleForm(), and InterferenceForm::createInterferenceWidgets().

Here is the call graph for this function:

◆ addStructureEditingRow()

void FormLayouter::addStructureEditingRow ( QPushButton *  button)

Adds a button for structure editing.

Creates a widget, places the given button as a child left-aligned into this widget and adds the newly created widget as a row in the layout.

Definition at line 140 of file FormLayouter.cpp.

141 {
142  auto* w = new QWidget(m_formLayout->parentWidget());
143  auto* l = new QHBoxLayout(w);
144  l->setContentsMargins(0, 0, 0, 0);
145  l->setAlignment(Qt::AlignLeft);
146  l->setSizeConstraint(QLayout::SetMinimumSize);
147  l->addWidget(button);
148  l->addStretch();
149  addRow(w);
150 }

References addRow(), and m_formLayout.

Referenced by ParticleCompositionForm::ParticleCompositionForm(), and ParticleLayoutForm::ParticleLayoutForm().

Here is the call graph for this function:

◆ addValue() [1/3]

int FormLayouter::addValue ( const DoubleDescriptor d)

Adds a row with a bold printed label and a DoubleSpinBox.

The DoubleSpinBox is initialized with the contents found in the descriptor (e.g. limits, decimals, unit). The DoubleSpinBox is set as the "buddy" of the label. This is necessary to realize the "label shows unit of value" feature. Changes of the DoubleSpinBox are signaled to the SampleEditorController which has been overhanded in the constructor of this FormLayouter. It is connected to SampleEditorController::setDouble(). If a different method should be called (e.g. for a special undo functionality), this method is not sufficient. It would have to be done "manually" or with the overload which takes a slot (see below). Returns the newly added row.

Definition at line 157 of file FormLayouter.cpp.

158 {
159  insertValue(m_formLayout->rowCount(), d);
160  return m_formLayout->rowCount() - 1;
161 }
void insertValue(int row, const DoubleDescriptor &d)
Inserts a row with a bold printed label and a DoubleSpinBox.

References insertValue(), and m_formLayout.

Referenced by MesoCrystalForm::MesoCrystalForm(), MultiLayerForm::MultiLayerForm(), ParticleCompositionForm::ParticleCompositionForm(), ParticleCoreShellForm::ParticleCoreShellForm(), ParticleForm::ParticleForm(), ParticleLayoutForm::ParticleLayoutForm(), and InterferenceForm::createInterferenceWidgets().

Here is the call graph for this function:

◆ addValue() [2/3]

int FormLayouter::addValue ( const DoubleDescriptor d,
function< void(double)>  onValueChange 
)

Adds a row with a bold printed label and a DoubleSpinBox.

Same as above, but the called slot in case of a value change has to be overhanded. Use this only if the standard (calling SampleEditorController::setDouble()) is not sufficient.

Definition at line 163 of file FormLayouter.cpp.

164 {
165  insertValue(m_formLayout->rowCount(), d, onValueChange);
166  return m_formLayout->rowCount() - 1;
167 }

References insertValue(), and m_formLayout.

Here is the call graph for this function:

◆ addValue() [3/3]

int FormLayouter::addValue ( const UIntDescriptor d)

Adds a row with a bold printed label and a QSpinBox.

Right now in the sample model there is no uint value which has a unit, therefore no unit displaying is implemented. Beside this, the same as for addValue(DoubleDescriptor) applies. Returns the newly added row.

Definition at line 151 of file FormLayouter.cpp.

152 {
153  auto* editor = createSpinBox(m_formLayout->parentWidget(), d, m_ec);
154  return addRow(d.label, editor);
155 }
QString label
A label text (short, no trailing colon)
QSpinBox * createSpinBox(QWidget *parent, const UIntDescriptor &d, std::function< void(uint)> slot=nullptr)
Create a spin box with the information found in a UIntDescriptor.
Definition: WidgetUtils.cpp:24

References addRow(), GUI::Util::createSpinBox(), UIntDescriptor::label, m_ec, and m_formLayout.

Here is the call graph for this function:

◆ addVector()

int FormLayouter::addVector ( const VectorDescriptor d,
bool  vertically = true 
)

Adds a row with a bold printed label and the 3 values of a 3D vector.

Works the same as addGroupOfValues. The label is taken from the VectorDescriptor. In addition, the caller can define whether the labels are above the values (vertically=true), or whether labels and values are all placed in one row (vertically=false).

Definition at line 112 of file FormLayouter.cpp.

113 {
114  auto* w = new QWidget(m_formLayout->parentWidget());
115  w->setObjectName("PropertyBaseWidget");
116  w->setAttribute(Qt::WA_StyledBackground, true);
117  w->setStyleSheet("#PropertyBaseWidget {background-color: transparent}");
118 
119  auto* gridLayout = new QGridLayout(w);
120  gridLayout->setContentsMargins(0, 0, 0, 0);
121  gridLayout->setSpacing(6);
122 
123  LayerEditorUtils::addMultiPropertyToGrid(gridLayout, 0, {d.x, d.y, d.z}, m_ec, vertically,
124  true);
125 
126  return addRow(d.label, w);
127 }
DoubleDescriptor y
DoubleDescriptor x
QString label
A label text (short, no trailing colon)
DoubleDescriptor z

References LayerEditorUtils::addMultiPropertyToGrid(), addRow(), VectorDescriptor::label, m_ec, m_formLayout, VectorDescriptor::x, VectorDescriptor::y, and VectorDescriptor::z.

Referenced by MesoCrystalForm::MesoCrystalForm(), MultiLayerForm::MultiLayerForm(), ParticleCompositionForm::ParticleCompositionForm(), ParticleCoreShellForm::ParticleCoreShellForm(), and ParticleForm::ParticleForm().

Here is the call graph for this function:

◆ insertRow() [1/2]

void FormLayouter::insertRow ( int  row,
QString  label,
QWidget *  w 
)

Insert a row with a bold printed label.

If necessary, a colon (':') is added to the label.

Definition at line 89 of file FormLayouter.cpp.

90 {
91  if (!label.endsWith(":"))
92  label += ":";
93  m_formLayout->insertRow(row, LayerEditorUtils::createBoldLabel(label), w);
94 }
QLabel * createBoldLabel(const QString &text)

References LayerEditorUtils::createBoldLabel(), and m_formLayout.

Here is the call graph for this function:

◆ insertRow() [2/2]

void FormLayouter::insertRow ( int  row,
QWidget *  w 
)

Convenience method to insert a widget.

Calls QFormLayout::insertRow().

Definition at line 201 of file FormLayouter.cpp.

202 {
203  m_formLayout->insertRow(row, w);
204 }

References m_formLayout.

Referenced by addRow().

◆ insertValue() [1/2]

void FormLayouter::insertValue ( int  row,
const DoubleDescriptor d 
)

Inserts a row with a bold printed label and a DoubleSpinBox.

Same functionality as addValue(), please read there.

Definition at line 169 of file FormLayouter.cpp.

170 {
171  auto* ec = m_ec; // to allow copy-capture in the following lambda
172  insertValue(row, d, [ec, d](double newValue) { ec->setDouble(newValue, d); });
173 }

References m_ec, and SampleEditorController::setDouble().

Referenced by addValue().

Here is the call graph for this function:

◆ insertValue() [2/2]

void FormLayouter::insertValue ( int  row,
const DoubleDescriptor d,
function< void(double)>  onValueChange 
)

Inserts a row with a bold printed label and a DoubleSpinBox.

Same functionality as addValue(), please read there.

Definition at line 175 of file FormLayouter.cpp.

177 {
178  auto labelText = d.label;
179  if (!labelText.endsWith(":"))
180  labelText += ":";
181 
182  auto* label = LayerEditorUtils::createBoldLabel(labelText);
183  label->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
184  label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);
185 
186  auto* editor = new DoubleSpinBox(m_formLayout->parentWidget(), d);
187  QObject::connect(editor, &DoubleSpinBox::baseValueChanged, onValueChange);
188 
189  label->setBuddy(editor);
190 
191  LayerEditorUtils::updateLabelUnit(label, editor);
192  m_formLayout->insertRow(row, label, editor);
193 }
QString label
A label text (short, no trailing colon)
SpinBox for DoubleDescriptors, supporting units.
Definition: DoubleSpinBox.h:22
void baseValueChanged(double newBaseValue)
Emitted whenever the value changes.
void updateLabelUnit(QLabel *label)

References DoubleSpinBox::baseValueChanged(), LayerEditorUtils::createBoldLabel(), DoubleDescriptor::label, m_formLayout, and LayerEditorUtils::updateLabelUnit().

Here is the call graph for this function:

◆ layout()

QFormLayout * FormLayouter::layout ( )

The layout where this layouter is operating on.

Use this, if you want to modify the layout with means not given in here.

Definition at line 73 of file FormLayouter.cpp.

74 {
75  return m_formLayout;
76 }

References m_formLayout.

Referenced by MesoCrystalForm::MesoCrystalForm(), ParticleCompositionForm::ParticleCompositionForm(), ParticleLayoutForm::ParticleLayoutForm(), and InterferenceForm::onInterferenceTypeChanged().

◆ removeRow()

void FormLayouter::removeRow ( int  row)

Convenience method to remove a row.

Calls QFormLayout::removeRow().

Definition at line 135 of file FormLayouter.cpp.

136 {
137  m_formLayout->removeRow(row);
138 }

References m_formLayout.

◆ setContentsMargins()

void FormLayouter::setContentsMargins ( int  left,
int  top,
int  right,
int  bottom 
)

Convenience method to set the contents margins.

Directly calls QFormLayout::setContentsMargins()

Definition at line 78 of file FormLayouter.cpp.

79 {
80  m_formLayout->setContentsMargins(left, top, right, bottom);
81 }

References m_formLayout.

Referenced by InterferenceForm::InterferenceForm(), MesoCrystalForm::MesoCrystalForm(), MultiLayerForm::MultiLayerForm(), ParticleCompositionForm::ParticleCompositionForm(), ParticleCoreShellForm::ParticleCoreShellForm(), and ParticleLayoutForm::ParticleLayoutForm().

◆ setRowVisible()

void FormLayouter::setRowVisible ( int  row,
bool  visible 
)

Shows or hides the widgets in a row.

Definition at line 129 of file FormLayouter.cpp.

130 {
131  m_formLayout->itemAt(row, QFormLayout::LabelRole)->widget()->setVisible(visible);
132  m_formLayout->itemAt(row, QFormLayout::FieldRole)->widget()->setVisible(visible);
133 }

References m_formLayout.

◆ widgetAt()

template<typename T >
T FormLayouter::widgetAt ( int  row,
QFormLayout::ItemRole  role 
)

Find a widget in the given position.

The widget will be qobject_cast'ed to the template parameter

Definition at line 177 of file FormLayouter.h.

178 {
179  return qobject_cast<T>(m_formLayout->itemAt(row, role)->widget());
180 }

References m_formLayout.

Referenced by ParticleLayoutForm::ParticleLayoutForm().

Member Data Documentation

◆ m_ec

SampleEditorController* FormLayouter::m_ec
private

Definition at line 165 of file FormLayouter.h.

Referenced by addGroupOfValues(), addSelection(), addValue(), addVector(), and insertValue().

◆ m_formLayout


The documentation for this class was generated from the following files: