##// END OF EJS Templates
Wait for the end of an acquisition to validate an operation (3)...
Wait for the end of an acquisition to validate an operation (3) If an operation is to validate, waits the end of the acquisition

File last commit:

r891:dd73a5040007
r1248:7541b71e5b78
Show More
DragDropScroller.cpp
125 lines | 4.4 KiB | text/x-c | CppLexer
/ gui / src / DragAndDrop / DragDropScroller.cpp
Moves the class DragDropScroller in its own file
r891 #include "DragAndDrop/DragDropScroller.h"
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QScrollBar>
#include <QTimer>
const int SCROLL_SPEED = 5;
const int SCROLL_ZONE_SIZE = 50;
struct DragDropScroller::DragDropScrollerPrivate {
QList<QScrollArea *> m_ScrollAreas;
QScrollArea *m_CurrentScrollArea = nullptr;
std::unique_ptr<QTimer> m_Timer = nullptr;
enum class ScrollDirection { up, down, unknown };
ScrollDirection m_Direction = ScrollDirection::unknown;
explicit DragDropScrollerPrivate() : m_Timer{std::make_unique<QTimer>()}
{
m_Timer->setInterval(0);
}
};
DragDropScroller::DragDropScroller(QObject *parent)
: QObject{parent}, impl{spimpl::make_unique_impl<DragDropScrollerPrivate>()}
{
connect(impl->m_Timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer);
}
void DragDropScroller::addScrollArea(QScrollArea *scrollArea)
{
impl->m_ScrollAreas << scrollArea;
scrollArea->viewport()->setAcceptDrops(true);
}
void DragDropScroller::removeScrollArea(QScrollArea *scrollArea)
{
impl->m_ScrollAreas.removeAll(scrollArea);
scrollArea->viewport()->setAcceptDrops(false);
}
bool DragDropScroller::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::DragMove) {
auto w = static_cast<QWidget *>(obj);
if (impl->m_CurrentScrollArea && impl->m_CurrentScrollArea->isAncestorOf(w)) {
auto moveEvent = static_cast<QDragMoveEvent *>(event);
auto pos = moveEvent->pos();
if (impl->m_CurrentScrollArea->viewport() != w) {
auto globalPos = w->mapToGlobal(moveEvent->pos());
pos = impl->m_CurrentScrollArea->viewport()->mapFromGlobal(globalPos);
}
auto isInTopZone = pos.y() > impl->m_CurrentScrollArea->viewport()->size().height()
- SCROLL_ZONE_SIZE;
auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE;
if (!isInTopZone && !isInBottomZone) {
impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
impl->m_Timer->stop();
}
else if (!impl->m_Timer->isActive()) {
impl->m_Direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up
: DragDropScrollerPrivate::ScrollDirection::down;
impl->m_Timer->start();
}
}
}
else if (event->type() == QEvent::DragEnter) {
auto w = static_cast<QWidget *>(obj);
for (auto scrollArea : impl->m_ScrollAreas) {
if (impl->m_CurrentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) {
auto enterEvent = static_cast<QDragEnterEvent *>(event);
enterEvent->acceptProposedAction();
enterEvent->setDropAction(Qt::IgnoreAction);
impl->m_CurrentScrollArea = scrollArea;
break;
}
}
}
else if (event->type() == QEvent::DragLeave) {
if (impl->m_CurrentScrollArea) {
if (!QRect(QPoint(), impl->m_CurrentScrollArea->size())
.contains(impl->m_CurrentScrollArea->mapFromGlobal(QCursor::pos()))) {
impl->m_CurrentScrollArea = nullptr;
impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
impl->m_Timer->stop();
}
}
}
else if (event->type() == QEvent::Drop) {
if (impl->m_CurrentScrollArea) {
impl->m_CurrentScrollArea = nullptr;
impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
impl->m_Timer->stop();
}
}
return false;
}
void DragDropScroller::onTimer()
{
if (impl->m_CurrentScrollArea) {
auto mvt = 0;
switch (impl->m_Direction) {
case DragDropScrollerPrivate::ScrollDirection::up:
mvt = SCROLL_SPEED;
break;
case DragDropScrollerPrivate::ScrollDirection::down:
mvt = -SCROLL_SPEED;
break;
default:
break;
}
impl->m_CurrentScrollArea->verticalScrollBar()->setValue(
impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt);
}
}