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

Description

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.

Definition at line 35 of file WidgetMoverButton.h.

Inheritance diagram for WidgetMoverButton:
[legend]
Collaboration diagram for WidgetMoverButton:
[legend]

Signals

void finishedMoving (QWidget *widgetToMove, QWidget *moveAboveThisWidget)
 
void startingToMove ()
 

Public Member Functions

 WidgetMoverButton (QWidget *parent, QWidget *widgetToMove, int ignoreOnTop=0)
 Create a widget mover button. More...
 

Protected Member Functions

void mouseMoveEvent (QMouseEvent *event) override
 
void mousePressEvent (QMouseEvent *event) override
 
void mouseReleaseEvent (QMouseEvent *event) override
 

Private Member Functions

void scrollParent (bool up)
 

Private Attributes

QMap< QWidget *, QPropertyAnimation * > m_animations
 
QTimer m_dragScrollTimer
 
QWidget * m_dropAboveThisWidget
 
int m_globalMouseDownY
 
QPoint m_hotSpot
 The mouse-down coordinates in the widget to move. More...
 
int m_ignoreOnTop
 
QLayout * m_layoutToDeactivate = nullptr
 
int m_originalWidgetY
 
QScrollArea * m_scrollArea
 
bool m_started = false
 
QWidget * m_widgetToMove
 
int m_yOfFirstRelevantWidget
 

Constructor & Destructor Documentation

◆ WidgetMoverButton()

WidgetMoverButton::WidgetMoverButton ( QWidget *  parent,
QWidget *  widgetToMove,
int  ignoreOnTop = 0 
)

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 sample properties) shall not be part of reordering.

Definition at line 23 of file WidgetMoverButton.cpp.

24  : QToolButton(parent)
25  , m_widgetToMove(widgetToMove)
26  , m_dropAboveThisWidget(nullptr)
27  , m_ignoreOnTop(ignoreOnTop)
28  , m_scrollArea(nullptr)
29 {
30  setIcon(QIcon(":/images/move_up_down.svg"));
31  m_dragScrollTimer.setSingleShot(false);
32 }
QScrollArea * m_scrollArea
QWidget * m_dropAboveThisWidget

References m_dragScrollTimer.

Member Function Documentation

◆ finishedMoving

void WidgetMoverButton::finishedMoving ( QWidget *  widgetToMove,
QWidget *  moveAboveThisWidget 
)
signal

◆ mouseMoveEvent()

void WidgetMoverButton::mouseMoveEvent ( QMouseEvent *  event)
overrideprotected

Definition at line 67 of file WidgetMoverButton.cpp.

68 {
69  int dy = event->globalY() - m_globalMouseDownY;
70  if (abs(dy) > 5 && !m_started) {
71  m_started = true;
72 
73  m_layoutToDeactivate = m_widgetToMove->parentWidget()->layout();
74 
75  m_yOfFirstRelevantWidget = m_layoutToDeactivate->itemAt(m_ignoreOnTop)->geometry().top();
76  m_layoutToDeactivate->setEnabled(false);
78  m_widgetToMove->raise();
79  emit startingToMove();
80  m_widgetToMove->move(m_widgetToMove->x() + 5, m_widgetToMove->y());
81  m_widgetToMove->resize(m_widgetToMove->width() - 10, m_widgetToMove->height());
82  }
83 
84  if (m_started) {
85  // -- move the dragged widget to the new position
86  QPoint newPos =
87  m_widgetToMove->parentWidget()->mapFromGlobal(event->globalPos()) - m_hotSpot;
88  m_widgetToMove->move(m_widgetToMove->x(), newPos.y());
89 
90  // -- move other widgets to make room
91  m_dropAboveThisWidget = nullptr;
92  int yTopOfLayoutItem = m_yOfFirstRelevantWidget;
93 
94  for (int i = m_ignoreOnTop; i < m_layoutToDeactivate->count(); ++i) {
95  auto* layoutItem = m_layoutToDeactivate->itemAt(i);
96  if (layoutItem->widget() == m_widgetToMove)
97  continue;
98 
99  const bool movedWidgetIsAboveThisLayoutItem =
100  m_widgetToMove->y() < yTopOfLayoutItem + layoutItem->geometry().height() / 2;
101  if (movedWidgetIsAboveThisLayoutItem && layoutItem->widget() != nullptr
102  && m_dropAboveThisWidget == nullptr)
103  m_dropAboveThisWidget = layoutItem->widget();
104 
105  QRect r = layoutItem->geometry();
106  if (movedWidgetIsAboveThisLayoutItem)
107  r.moveTop(yTopOfLayoutItem + m_widgetToMove->height()
108  + m_layoutToDeactivate->spacing());
109  else
110  r.moveTop(yTopOfLayoutItem);
111 
112  if (r != layoutItem->geometry()) {
113  QWidget* w = layoutItem->widget();
114  if (w == nullptr)
115  layoutItem->setGeometry(r);
116  else if (!m_animations.contains(w)) {
117  auto* animation = new QPropertyAnimation(w, "geometry");
118  animation->setDuration(100);
119  animation->setEasingCurve(QEasingCurve::OutQuad);
120  animation->setStartValue(w->geometry());
121  animation->setEndValue(r);
122  animation->start();
123  m_animations[w] = animation;
124  } else {
125  auto* animation = m_animations[w];
126  if (animation->endValue() != r) {
127  animation->stop();
128  animation->setStartValue(w->geometry());
129  animation->setEndValue(r);
130  animation->start();
131  }
132  }
133  }
134 
135  yTopOfLayoutItem += r.height() + m_layoutToDeactivate->spacing();
136  }
137 
138  // -- check whether scrolling is necessary
139  QPoint parPos = m_scrollArea->mapFromGlobal(mapToGlobal(event->pos()));
140  if (parPos.y() < 20) {
141  m_dragScrollTimer.setInterval(10);
142  m_dragScrollTimer.disconnect();
143  connect(&m_dragScrollTimer, &QTimer::timeout, [=]() { scrollParent(true); });
144  m_dragScrollTimer.start();
145  } else if (parPos.y() > m_scrollArea->height() - 20) {
146  m_dragScrollTimer.setInterval(10);
147  m_dragScrollTimer.disconnect();
148  connect(&m_dragScrollTimer, &QTimer::timeout, [=]() { scrollParent(false); });
149  m_dragScrollTimer.start();
150  } else
151  m_dragScrollTimer.stop();
152  }
153 }
QLayout * m_layoutToDeactivate
QMap< QWidget *, QPropertyAnimation * > m_animations
void scrollParent(bool up)
QPoint m_hotSpot
The mouse-down coordinates in the widget to move.

References m_animations, m_dragScrollTimer, m_dropAboveThisWidget, m_globalMouseDownY, m_hotSpot, m_ignoreOnTop, m_layoutToDeactivate, m_originalWidgetY, m_scrollArea, m_started, m_widgetToMove, m_yOfFirstRelevantWidget, scrollParent(), and startingToMove().

Here is the call graph for this function:

◆ mousePressEvent()

void WidgetMoverButton::mousePressEvent ( QMouseEvent *  event)
overrideprotected

Definition at line 34 of file WidgetMoverButton.cpp.

35 {
36  if (m_scrollArea == nullptr) {
37  QWidget* p = parentWidget();
38  do {
39  m_scrollArea = dynamic_cast<QScrollArea*>(p);
40  p = p->parentWidget();
41  } while (p != nullptr && m_scrollArea == nullptr);
42  }
43 
44  ASSERT(m_scrollArea);
45  m_globalMouseDownY = event->globalY();
46  m_hotSpot = event->globalPos()
47  - m_widgetToMove->parentWidget()->mapToGlobal(m_widgetToMove->geometry().topLeft());
48 }

References m_globalMouseDownY, m_hotSpot, m_scrollArea, and m_widgetToMove.

◆ mouseReleaseEvent()

void WidgetMoverButton::mouseReleaseEvent ( QMouseEvent *  event)
overrideprotected

Definition at line 50 of file WidgetMoverButton.cpp.

51 {
52  if (!m_started)
53  return;
54 
55  qDeleteAll(m_animations.values());
56  m_animations.clear();
57 
58  m_dragScrollTimer.stop();
59  m_started = false;
60  if (m_layoutToDeactivate != nullptr) {
61  m_layoutToDeactivate->setEnabled(true);
62  m_layoutToDeactivate->update();
63  }
65 }
void finishedMoving(QWidget *widgetToMove, QWidget *moveAboveThisWidget)

References finishedMoving(), m_animations, m_dragScrollTimer, m_dropAboveThisWidget, m_layoutToDeactivate, m_started, and m_widgetToMove.

◆ scrollParent()

void WidgetMoverButton::scrollParent ( bool  up)
private

Definition at line 155 of file WidgetMoverButton.cpp.

156 {
157  auto* scrollbar = m_scrollArea->verticalScrollBar();
158  if (!scrollbar->isVisible())
159  return;
160 
161  const int oldScrollValue = scrollbar->value();
162  scrollbar->setValue(oldScrollValue + (up ? -5 : 5));
163 
164  // move the dragged widget to the new position to avoid jitter effects
165  // use the real change of value, not +/-5: scrolling may have been unsuccessful
166  m_widgetToMove->move(m_widgetToMove->x(),
167  m_widgetToMove->y() + scrollbar->value() - oldScrollValue);
168 }

References m_scrollArea, and m_widgetToMove.

Referenced by mouseMoveEvent().

◆ startingToMove

void WidgetMoverButton::startingToMove ( )
signal

Member Data Documentation

◆ m_animations

QMap<QWidget*, QPropertyAnimation*> WidgetMoverButton::m_animations
private

Definition at line 70 of file WidgetMoverButton.h.

Referenced by mouseMoveEvent(), and mouseReleaseEvent().

◆ m_dragScrollTimer

QTimer WidgetMoverButton::m_dragScrollTimer
private

Definition at line 67 of file WidgetMoverButton.h.

Referenced by WidgetMoverButton(), mouseMoveEvent(), and mouseReleaseEvent().

◆ m_dropAboveThisWidget

QWidget* WidgetMoverButton::m_dropAboveThisWidget
private

Definition at line 63 of file WidgetMoverButton.h.

Referenced by mouseMoveEvent(), and mouseReleaseEvent().

◆ m_globalMouseDownY

int WidgetMoverButton::m_globalMouseDownY
private

Definition at line 60 of file WidgetMoverButton.h.

Referenced by mouseMoveEvent(), and mousePressEvent().

◆ m_hotSpot

QPoint WidgetMoverButton::m_hotSpot
private

The mouse-down coordinates in the widget to move.

Definition at line 69 of file WidgetMoverButton.h.

Referenced by mouseMoveEvent(), and mousePressEvent().

◆ m_ignoreOnTop

int WidgetMoverButton::m_ignoreOnTop
private

Definition at line 66 of file WidgetMoverButton.h.

Referenced by mouseMoveEvent().

◆ m_layoutToDeactivate

QLayout* WidgetMoverButton::m_layoutToDeactivate = nullptr
private

Definition at line 61 of file WidgetMoverButton.h.

Referenced by mouseMoveEvent(), and mouseReleaseEvent().

◆ m_originalWidgetY

int WidgetMoverButton::m_originalWidgetY
private

Definition at line 64 of file WidgetMoverButton.h.

Referenced by mouseMoveEvent().

◆ m_scrollArea

QScrollArea* WidgetMoverButton::m_scrollArea
private

Definition at line 68 of file WidgetMoverButton.h.

Referenced by mouseMoveEvent(), mousePressEvent(), and scrollParent().

◆ m_started

bool WidgetMoverButton::m_started = false
private

Definition at line 59 of file WidgetMoverButton.h.

Referenced by mouseMoveEvent(), and mouseReleaseEvent().

◆ m_widgetToMove

QWidget* WidgetMoverButton::m_widgetToMove
private

◆ m_yOfFirstRelevantWidget

int WidgetMoverButton::m_yOfFirstRelevantWidget
private

Definition at line 65 of file WidgetMoverButton.h.

Referenced by mouseMoveEvent().


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