// ************************************************************************************************ // // BornAgain: simulate and fit reflection and scattering // //! @file GUI/View/Sample/HeinzFormLayout.h //! @brief Defines class HeinzFormLayout. //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) //! @copyright Forschungszentrum Jülich GmbH 2021 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) // // ************************************************************************************************ #ifndef BORNAGAIN_GUI_VIEW_SAMPLE_HEINZFORMLAYOUT_H #define BORNAGAIN_GUI_VIEW_SAMPLE_HEINZFORMLAYOUT_H #include "GUI/View/Sample/PolyForm.h" #include <QFormLayout> class SampleEditorController; class VectorProperty; //! Extends QFormLayout, for use in SampleDesigner. //! //! Helps to add edit controls which operate on Properties (DoubleProperty, VectorProperty, //! PolyItem). 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. //! Establishes connections to the SampleEditorController. class HeinzFormLayout : public QFormLayout { public: //! 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 DSpinBox //! value has been changed. HeinzFormLayout(SampleEditorController* ec); //! Insert a row with a bold printed label. //! //! If necessary, a colon (':') is added to the label. void insertRow(int row, QString label, QWidget* w); void insertRow(int row, QWidget* w); void addBoldRow(const QString& label, QWidget* w); //! Add a row with a selection. //! //! The whole selection is realized by adding a PolyForm. This //! PolyForm is limited to contain the selection combo box and a list of double //! values represented by DoubleProperties. To add more complex selections (e.g. with //! sub-selections or different value types), this method and the PolyForm is not //! sufficient. It has to be done "manually". //! For more details, see PolyForm. //! Returns the newly added row. template <typename B, typename C> void addSelection(PolyPtr<B, C>& d) { addBoldRow(d.piLabel(), new PolyForm(QFormLayout::parentWidget(), d, m_ec)); } //! Adds a row with a bold printed label and a DSpinBox. //! //! The DSpinBox is initialized with the contents found in the DoubleProperty (e.g. limits, //! decimals, unit). The DSpinBox is set as the "buddy" of the label. This is necessary to //! realize the "label shows unit of value" feature. Changes of the DSpinBox are signaled //! to the SampleEditorController which has been overhanded in the constructor of this. //! 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. void addValue(DoubleProperty& d); //! Adds a row with a bold printed label and a DSpinBox. //! //! 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. void addValue(DoubleProperty& d, std::function<void(double)> onValueChange); //! Inserts a row with a bold printed label and a DSpinBox. //! //! Same functionality as addValue(), please read there. void insertValue(int row, DoubleProperty& d); //! Inserts a row with a bold printed label and a DSpinBox. //! //! Same functionality as addValue(), please read there. void insertValue(int row, DoubleProperty& d, std::function<void(double)> onValueChange); //! Adds a row with a bold printed label and a set of DoubleProperties. //! //! The label describes the set of the DoubleProperties and is located in the first column of //! the layout. The DSpinBoxes for each DoubleProperty 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 DoubleProperty //! the same applies as when adding a single DoubleProperty with the method addValue(), //! therefore please read there for more details. Returns the newly added row. void addGroupOfValues(const QString& labelText, const DoubleProperties& values); //! 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 VectorProperty. //! 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). void addVector(VectorProperty& d, bool vertically = true); //! 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. void addStructureEditingRow(QPushButton* button); //! Find a widget in the given position. template <typename T> T widgetAt(int row, QFormLayout::ItemRole role) { return qobject_cast<T>(QFormLayout::itemAt(row, role)->widget()); } private: SampleEditorController* m_ec; }; #endif // BORNAGAIN_GUI_VIEW_SAMPLE_HEINZFORMLAYOUT_H