diff --git a/GUI/View/Fit/FitParameterDelegate.cpp b/GUI/View/Fit/FitParameterDelegate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c8c94dcf588900eac5b34bb287beb0dc0db81b72 --- /dev/null +++ b/GUI/View/Fit/FitParameterDelegate.cpp @@ -0,0 +1,130 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/View/Fit/FitParameterDelegate.cpp +//! @brief Implements class FitParameterDelegate +//! +//! @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) +// +// ************************************************************************************************ + +#include "GUI/View/Fit/FitParameterDelegate.h" +#include "GUI/Model/Session/SessionItem.h" +#include "GUI/View/PropertyEditor/CustomEditors.h" +#include "GUI/View/PropertyEditor/CustomEventFilters.h" +#include "GUI/View/PropertyEditor/PropertyEditorFactory.h" +#include <QApplication> + +FitParameterDelegate::FitParameterDelegate(QObject* parent) : QStyledItemDelegate(parent) {} + +void FitParameterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + if (GUI::View::PropertyEditorFactory::hasStringRepresentation(index)) { + QString text = GUI::View::PropertyEditorFactory::toString(index); + paintCustomLabel(painter, option, index, text); + } else + QStyledItemDelegate::paint(painter, option, index); +} + +QWidget* FitParameterDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + auto* result = createEditorFromIndex(index, parent); + + if (auto* customEditor = dynamic_cast<CustomEditor*>(result)) { + new TabFromFocusProxy(customEditor); + connect(customEditor, &CustomEditor::dataChanged, this, + &FitParameterDelegate::onCustomEditorDataChanged); + } + + if (!result) // falling back to default behaviour + result = QStyledItemDelegate::createEditor(parent, option, index); + + return result; +} + +//! Propagates changed data from the editor to the model. + +void FitParameterDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, + const QModelIndex& index) const +{ + if (!index.isValid()) + return; + + if (auto* customEditor = dynamic_cast<CustomEditor*>(editor)) + model->setData(index, customEditor->editorData()); + else + QStyledItemDelegate::setModelData(editor, model, index); +} + +//! Propagates the data change from the model to the editor (if it is still opened). + +void FitParameterDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const +{ + if (!index.isValid()) + return; + + if (auto* customEditor = dynamic_cast<CustomEditor*>(editor)) + customEditor->setData(index.data()); + else + QStyledItemDelegate::setEditorData(editor, index); +} + +//! Increases height of the row by 20% wrt the default. + +QSize FitParameterDelegate::sizeHint(const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + QSize result = QStyledItemDelegate::sizeHint(option, index); + result.setHeight(static_cast<int>(result.height() * 1.2)); + return result; +} + +//! Makes an editor occupying whole available space in a cell. If cell contains an icon +//! as a decoration (i.e. icon of material property), it will be hidden as soon as editor +//! up and running. + +void FitParameterDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + QStyledItemDelegate::updateEditorGeometry(editor, option, index); + editor->setGeometry(option.rect); +} + + +QWidget* FitParameterDelegate::createEditorFromIndex(const QModelIndex& index, + QWidget* parent) const +{ + if (index.internalPointer()) { + auto* item = static_cast<SessionItem*>(index.internalPointer()); + return GUI::View::PropertyEditorFactory::CreateEditor(*item, parent); + } + return nullptr; +} + +//! Notifies everyone that the editor has completed editing the data. + +void FitParameterDelegate::onCustomEditorDataChanged(const QVariant&) +{ + auto* editor = qobject_cast<CustomEditor*>(sender()); + ASSERT(editor); + emit commitData(editor); +} + +//! Paints custom text in a a place corresponding given index. + +void FitParameterDelegate::paintCustomLabel(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index, const QString& text) const +{ + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); // calling original method to take into accounts colors etc + opt.text = displayText(text, option.locale); // by overriding text with ours + const QWidget* widget = opt.widget; + QStyle* style = widget ? widget->style() : QApplication::style(); + style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget); +} diff --git a/GUI/View/Fit/FitParameterDelegate.h b/GUI/View/Fit/FitParameterDelegate.h new file mode 100644 index 0000000000000000000000000000000000000000..e1b5dd590e4963a3f10aa52012b8e4084ec13d01 --- /dev/null +++ b/GUI/View/Fit/FitParameterDelegate.h @@ -0,0 +1,56 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/View/Fit/FitParameterDelegate.h +//! @brief Defines class FitParameterDelegate +//! +//! @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_FIT_FITPARAMETERDELEGATE_H +#define BORNAGAIN_GUI_VIEW_FIT_FITPARAMETERDELEGATE_H + +#include <QStyledItemDelegate> + +//! The FitParameterDelegate class presents the content of SessionModel items in +//! standard QTreeView. Extents base QItemDelegate with possibility to show/edit +//! our custom QVariant's. + +class FitParameterDelegate : public QStyledItemDelegate { + Q_OBJECT +public: + FitParameterDelegate(QObject* parent); + + void paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const override; + + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const override; + + void setModelData(QWidget* editor, QAbstractItemModel* model, + const QModelIndex& index) const override; + + void setEditorData(QWidget* editor, const QModelIndex& index) const override; + + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; + + void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, + const QModelIndex& index) const override; + +protected: + virtual QWidget* createEditorFromIndex(const QModelIndex& index, QWidget* parent) const; + +public slots: + void onCustomEditorDataChanged(const QVariant&); + +private: + void paintCustomLabel(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index, const QString& text) const; +}; + +#endif // BORNAGAIN_GUI_VIEW_FIT_FITPARAMETERDELEGATE_H diff --git a/GUI/View/Fit/FitParameterWidget.cpp b/GUI/View/Fit/FitParameterWidget.cpp index eabb7952e2f004f2976c59222c3dbc9d7f16fb7f..8197ff867e0fb507e8bf57f793ee0c74bbf7e5e2 100644 --- a/GUI/View/Fit/FitParameterWidget.cpp +++ b/GUI/View/Fit/FitParameterWidget.cpp @@ -23,10 +23,10 @@ #include "GUI/Model/Group/FilterPropertyProxy.h" #include "GUI/Model/Job/JobItem.h" #include "GUI/Model/Job/JobModel.h" +#include "GUI/View/Fit/FitParameterDelegate.h" #include "GUI/View/Fit/ParameterTuningWidget.h" #include "GUI/View/Info/OverlayLabelController.h" #include "GUI/View/PropertyEditor/CustomEventFilters.h" -#include "GUI/View/PropertyEditor/SessionModelDelegate.h" #include "GUI/View/Tool/mainwindow_constants.h" #include <QAction> #include <QMenu> @@ -44,7 +44,6 @@ FitParameterWidget::FitParameterWidget(QWidget* parent) , m_removeFromFitParAction(nullptr) , m_removeFitParAction(nullptr) , m_fitParameterModel(nullptr) - , m_delegate(new SessionModelDelegate(this)) , m_keyboardFilter(new DeleteEventFilter(this)) , m_infoLabel(new OverlayLabelController(this)) { @@ -58,7 +57,7 @@ FitParameterWidget::FitParameterWidget(QWidget* parent) m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_treeView->setContextMenuPolicy(Qt::CustomContextMenu); - m_treeView->setItemDelegate(m_delegate); + m_treeView->setItemDelegate(new FitParameterDelegate(this)); m_treeView->setDragEnabled(true); m_treeView->setDragDropMode(QAbstractItemView::DragDrop); m_treeView->installEventFilter(m_keyboardFilter); diff --git a/GUI/View/Fit/FitParameterWidget.h b/GUI/View/Fit/FitParameterWidget.h index bc2ea82eabdcae0b21592f783d40cbb2330f73a8..321dfdbe53d799b7b600c77ff9e702c21a265d75 100644 --- a/GUI/View/Fit/FitParameterWidget.h +++ b/GUI/View/Fit/FitParameterWidget.h @@ -28,7 +28,6 @@ class ParameterItem; class FitParameterItem; class FitParameterLinkItem; class QItemSelection; -class SessionModelDelegate; class DeleteEventFilter; class OverlayLabelController; @@ -90,7 +89,6 @@ private: QAction* m_removeFromFitParAction; QAction* m_removeFitParAction; FitParameterProxyModel* m_fitParameterModel; - SessionModelDelegate* m_delegate; DeleteEventFilter* m_keyboardFilter; OverlayLabelController* m_infoLabel; };