Skip to content
Snippets Groups Projects
Commit c906965a authored by Matthias Puchner's avatar Matthias Puchner
Browse files

introduce WidgetMoverButton (to realize the "move layer" feature in the...

introduce WidgetMoverButton (to realize the "move layer" feature in the upcoming layer oriented sample editor)
parent 7e521c76
No related branches found
No related tags found
1 merge request!413introduce layer oriented sample editor
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/Views/SampleDesigner/WidgetMoverButton.cpp
//! @brief Implements class WidgetMoverButton
//!
//! @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/Views/SampleDesigner/WidgetMoverButton.h"
#include <QLayout>
#include <QMouseEvent>
#include <QPropertyAnimation>
WidgetMoverButton::WidgetMoverButton(QWidget* parent, QWidget* widgetToMove, int ignoreOnTop)
: QToolButton(parent), m_widgetToMove(widgetToMove), m_ignoreOnTop(ignoreOnTop)
{
setIcon(QIcon(":/images/toolbar24dark_hambar.svg"));
}
void WidgetMoverButton::mousePressEvent(QMouseEvent* event)
{
m_mouseDownY = event->globalY();
}
void WidgetMoverButton::mouseReleaseEvent(QMouseEvent* event)
{
m_started = false;
if (m_layoutToDeactivate != nullptr) {
m_layoutToDeactivate->setEnabled(true);
m_layoutToDeactivate->update();
}
emit finishedMoving(m_widgetToMove, m_dropAboveThisWidget);
}
void WidgetMoverButton::mouseMoveEvent(QMouseEvent* event)
{
int dy = event->globalY() - m_mouseDownY;
if (abs(dy) > 5 && !m_started) {
m_started = true;
m_layoutToDeactivate = m_widgetToMove->parentWidget()->layout();
m_yOfFirstRelevantWidget = m_layoutToDeactivate->itemAt(m_ignoreOnTop)->geometry().top();
m_layoutToDeactivate->setEnabled(false);
m_originalWidgetY = m_widgetToMove->y();
m_widgetToMove->raise();
emit startingToMove();
m_widgetToMove->move(m_widgetToMove->x() + 5, m_widgetToMove->y());
m_widgetToMove->resize(m_widgetToMove->width() - 10, m_widgetToMove->height());
}
if (m_started) {
// -- move the dragged widget to the new position
m_widgetToMove->move(m_widgetToMove->x(), m_originalWidgetY + dy);
// -- move other widgets to make room
m_dropAboveThisWidget = nullptr;
int yTopOfLayoutItem = m_yOfFirstRelevantWidget;
for (int i = m_ignoreOnTop; i < m_layoutToDeactivate->count(); ++i) {
auto* layoutItem = m_layoutToDeactivate->itemAt(i);
if (layoutItem->widget() == m_widgetToMove)
continue;
const bool movedWidgetIsAboveThisLayoutItem =
m_widgetToMove->y() < yTopOfLayoutItem + layoutItem->geometry().height() / 2;
if (movedWidgetIsAboveThisLayoutItem && layoutItem->widget() != nullptr
&& m_dropAboveThisWidget == nullptr)
m_dropAboveThisWidget = layoutItem->widget();
QRect r = layoutItem->geometry();
if (movedWidgetIsAboveThisLayoutItem)
r.moveTop(yTopOfLayoutItem + m_widgetToMove->height()
+ m_layoutToDeactivate->spacing());
else
r.moveTop(yTopOfLayoutItem);
if (r != layoutItem->geometry()) {
QWidget* w = layoutItem->widget();
if (w == nullptr) {
layoutItem->setGeometry(r);
} else {
QPropertyAnimation* animation = new QPropertyAnimation(w, "geometry");
animation->setDuration(100);
animation->setEasingCurve(QEasingCurve::OutQuad);
animation->setStartValue(w->geometry());
animation->setEndValue(r);
animation->start();
}
}
yTopOfLayoutItem += r.height() + m_layoutToDeactivate->spacing();
}
}
}
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/Views/SampleDesigner/WidgetMoverButton.h
//! @brief Defines class WidgetMoverButton
//!
//! @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_VIEWS_SAMPLEDESIGNER_WIDGETMOVERBUTTON_H
#define BORNAGAIN_GUI_VIEWS_SAMPLEDESIGNER_WIDGETMOVERBUTTON_H
#include <QToolButton>
//! Button to move a widget vertically in a layout.
//!
//! With this button, the "move layer" feature in the layer oriented sample editor is realized
//! (it is the button on each LayerForm).
//!
//! When pressing the button, the parent layout of the widget is deactivated, and the widget is
//! moved to the position where the pressed mouse cursor is moved.
//! When the mouse is released, the layout is again activated and a signal finishedMoving() is
//! emitted. Any reordering of the widgets in the layout then has to be handled outside - no
//! reordering is done in here.
class WidgetMoverButton : public QToolButton {
Q_OBJECT
public:
//! Create a widget mover button.
//!
//! If the widget shall not be able to be dragged on the top position, this can be defined by
//! ignoreOnTop (the number of widgets at the top of the layout which shall not be affected by
//! the reordering). In the case of the layer moving, the topmost Form (the multilayer
//! properties) shall not be part of reordering.
WidgetMoverButton(QWidget* parent, QWidget* widgetToMove, int ignoreOnTop = 0);
protected:
virtual void mousePressEvent(QMouseEvent* event) override;
virtual void mouseReleaseEvent(QMouseEvent* event) override;
virtual void mouseMoveEvent(QMouseEvent* event) override;
signals:
void startingToMove();
void finishedMoving(QWidget* widgetToMove, QWidget* moveAboveThisWidget);
private:
bool m_started = false;
int m_mouseDownY;
QLayout* m_layoutToDeactivate = nullptr;
QWidget* m_widgetToMove;
QWidget* m_dropAboveThisWidget;
int m_originalWidgetY;
int m_yOfFirstRelevantWidget;
int m_ignoreOnTop;
};
#endif // BORNAGAIN_GUI_VIEWS_SAMPLEDESIGNER_WIDGETMOVERBUTTON_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment